Commit 5eece4b6581243c0591e594cf06721de8a1a7480

Authored by Victor Costa
1 parent a9c7c1d9
Exists in master

comment_paragraph: refactoring

controllers/profile/comment_paragraph_plugin_profile_controller.rb
@@ -8,6 +8,7 @@ class CommentParagraphPluginProfileController < ProfileController @@ -8,6 +8,7 @@ class CommentParagraphPluginProfileController < ProfileController
8 @comments = article.comments.without_spam.in_paragraph(@paragraph_uuid) 8 @comments = article.comments.without_spam.in_paragraph(@paragraph_uuid)
9 @comments_count = @comments.count 9 @comments_count = @comments.count
10 @comments = @comments.without_reply 10 @comments = @comments.without_reply
  11 + render :partial => 'comment/comment.html.erb', :collection => @comments
11 end 12 end
12 13
13 end 14 end
db/migrate/20141223184902_add_paragraph_uuid_to_comments.rb
1 class AddParagraphUuidToComments < ActiveRecord::Migration 1 class AddParagraphUuidToComments < ActiveRecord::Migration
2 def change 2 def change
3 - add_column :comments, :paragraph_uuid, :string unless column_exists?(:comments, :paragraph_uuid) 3 + add_column :comments, :paragraph_uuid
4 add_index :comments, :paragraph_uuid 4 add_index :comments, :paragraph_uuid
5 end 5 end
6 end 6 end
lib/comment_paragraph_plugin.rb
@@ -40,55 +40,6 @@ class CommentParagraphPlugin &lt; Noosfero::Plugin @@ -40,55 +40,6 @@ class CommentParagraphPlugin &lt; Noosfero::Plugin
40 true 40 true
41 end 41 end
42 42
43 -# def cms_controller_filters  
44 -# block = proc do  
45 -# if params['commit'] == 'Save'  
46 -#  
47 -# settings = Noosfero::Plugin::Settings.new(environment, CommentParagraphPlugin, params[:settings])  
48 -#  
49 -# extend CommentParagraphPlugin::CommentParagraphHelper  
50 -# if !@article.id.blank? && self.auto_marking_enabled?(settings, @article.class.name)  
51 -#  
52 -# parsed_paragraphs = []  
53 -# paragraph_uuid = 0  
54 -#  
55 -# doc = Hpricot(@article.body)  
56 -# paragraphs = doc.search("/*").each do |paragraph|  
57 -#  
58 -# if paragraph.to_html =~ /^<div(.*)paragraph_comment(.*)$/ || paragraph.t o_html =~ /^<p>\W<\/p>$/  
59 -# parsed_paragraphs << paragraph.to_html  
60 -# else  
61 -# if paragraph.to_html =~ /^(<div|<table|<p|<ul).*/  
62 -# parsed_paragraphs << CommentParagraphPlugin.parse_paragraph(paragraph.to_html, paragraph_uuid)  
63 -# else  
64 -# parsed_paragraphs << paragraph.to_html  
65 -# end  
66 -# end  
67 -#  
68 -# paragraph_uuid += 1  
69 -#  
70 -# end  
71 -#  
72 -# @article.body = parsed_paragraphs.join()  
73 -# @article.save  
74 -#  
75 -# end  
76 -# end  
77 -# end  
78 -#  
79 -# { :type => 'after_filter',  
80 -# :method_name => 'new',  
81 -# :block => block }  
82 -# end  
83 -  
84 -  
85 - def self.parse_paragraph( paragraph_content, paragraph_uuid )  
86 - "<div class='macro article_comments paragraph_comment' " +  
87 - "data-macro='comment_paragraph_plugin/allow_comment' " +  
88 - "data-macro-paragraph_uuid='#{paragraph_uuid}'>#{paragraph_content}</div>\r\n" +  
89 - "<p>&nbsp;</p>"  
90 - end  
91 -  
92 end 43 end
93 44
94 require_dependency 'comment_paragraph_plugin/macros/allow_comment' 45 require_dependency 'comment_paragraph_plugin/macros/allow_comment'
lib/ext/article.rb
1 require_dependency 'article' 1 require_dependency 'article'
2 2
  3 +#FIXME should be specific to TextArticle?
3 class Article 4 class Article
4 5
5 has_many :paragraph_comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc', :conditions => [ 'paragraph_uuid IS NOT NULL'] 6 has_many :paragraph_comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc', :conditions => [ 'paragraph_uuid IS NOT NULL']
6 7
7 - # validate :body_change_with_comments  
8 -  
9 before_save :parse_html 8 before_save :parse_html
10 9
11 - def body_change_with_comments  
12 - if body && body_changed? && !self.comments.empty?  
13 - paragraphs_with_comments = self.comments.where("paragraph_uuid IS NOT NULL")  
14 - errors[:base] << (N_('You are unable to change the body of the article when paragraphs are commented')) unless (paragraphs_with_comments).empty?  
15 - end 10 + def parse_paragraph(paragraph_content, paragraph_uuid)
  11 + "<div class='macro article_comments paragraph_comment' " +
  12 + "data-macro='comment_paragraph_plugin/allow_comment' " +
  13 + "data-macro-paragraph_uuid='#{paragraph_uuid}'>#{paragraph_content}</div>\r\n" +
  14 + "<p>&nbsp;</p>"
16 end 15 end
17 - 16 +
18 def parse_html 17 def parse_html
19 - if body && body_changed? 18 + if body && body_changed?
20 parsed_paragraphs = [] 19 parsed_paragraphs = []
21 updated = body_change[1] 20 updated = body_change[1]
22 doc = Hpricot(updated) 21 doc = Hpricot(updated)
23 - paragraphs = doc.search("/*").each do |paragraph|  
24 - uuid = SecureRandom.uuid 22 + doc.search("/*").each do |paragraph|
25 if paragraph.to_html =~ /^<div(.*)paragraph_comment(.*)$/ || paragraph.to_html =~ /^<p>\W<\/p>$/ 23 if paragraph.to_html =~ /^<div(.*)paragraph_comment(.*)$/ || paragraph.to_html =~ /^<p>\W<\/p>$/
26 parsed_paragraphs << paragraph.to_html 24 parsed_paragraphs << paragraph.to_html
27 else 25 else
28 if paragraph.to_html =~ /^(<div|<table|<p|<ul).*/ 26 if paragraph.to_html =~ /^(<div|<table|<p|<ul).*/
29 - parsed_paragraphs << CommentParagraphPlugin.parse_paragraph(paragraph.to_html, uuid) 27 + parsed_paragraphs << parse_paragraph(paragraph.to_html, SecureRandom.uuid)
30 else 28 else
31 parsed_paragraphs << paragraph.to_html 29 parsed_paragraphs << paragraph.to_html
32 end 30 end
33 end 31 end
34 end 32 end
35 self.body = parsed_paragraphs.join() 33 self.body = parsed_paragraphs.join()
36 - #@article.save  
37 end 34 end
38 end 35 end
39 -  
40 - 36 +
41 end 37 end
public/comment_paragraph_macro.js
1 var comment_paragraph_anchor; 1 var comment_paragraph_anchor;
2 -var lastSelectedArea = [];  
3 -var original_paragraphs = [];  
4 -var originalArticleHeight = 0  
5 -  
6 -function setPlusIfZeroComments($){  
7 - $('.comment-count').each(function(){  
8 - var commentCount = $(this).text().trim();  
9 - if(commentCount=='0')  
10 - $(this).text("+");  
11 - });  
12 -}  
13 2
14 jQuery(document).ready(function($) { 3 jQuery(document).ready(function($) {
15 //Quit if does not detect a comment for that plugin 4 //Quit if does not detect a comment for that plugin
16 if($('.comment_paragraph').size() < 1) 5 if($('.comment_paragraph').size() < 1)
17 return; 6 return;
18 7
19 - originalArticleHeight = $('.article-body').height();  
20 -  
21 - all_paragraphs = $('.comment_paragraph');  
22 - all_paragraphs.each( function(paragraph) {  
23 - var paragraph_uuid = $( all_paragraphs.get(paragraph) ).attr('data-paragraph');  
24 - var paragraph_content = all_paragraphs.get(paragraph).innerHTML;  
25 - original_paragraphs.push( { id: paragraph_uuid, content: paragraph_content } );  
26 - });  
27 -  
28 $(document).keyup(function(e) { 8 $(document).keyup(function(e) {
29 // on press ESC key... 9 // on press ESC key...
30 if (e.which == 27) { 10 if (e.which == 27) {
31 - // closing side comment box  
32 hideCommentBox(); 11 hideCommentBox();
33 } 12 }
34 }); 13 });
35 14
36 - setPlusIfZeroComments($);  
37 $('.display-comment-form').unbind(); 15 $('.display-comment-form').unbind();
38 $('.display-comment-form').click(function(){ 16 $('.display-comment-form').click(function(){
39 var $button = $(this); 17 var $button = $(this);
@@ -49,15 +27,16 @@ jQuery(document).ready(function($) { @@ -49,15 +27,16 @@ jQuery(document).ready(function($) {
49 $('.selected_content').val(""); 27 $('.selected_content').val("");
50 }); 28 });
51 29
52 - $('#cancel-comment').die();  
53 - $(document.body).on("click", '#cancel-comment', function(){  
54 - hideCommentBox();  
55 - return false; 30 + //hide comments when click outside
  31 + $('body').click(function(event){
  32 + if ($(event.target).closest('.comment-paragraph-plugin, #comment-bubble').length === 0) {
  33 + hideCommentBox();
  34 + }
56 }); 35 });
57 36
58 function hideCommentBox() { 37 function hideCommentBox() {
59 $("div.side-comment").hide(); 38 $("div.side-comment").hide();
60 - $('.article-body').removeClass('comment-paragraph-slide-left'); 39 + $('.comment-paragraph-plugin').removeClass('comment-paragraph-slide-left');
61 $('.comments').removeClass('selected'); 40 $('.comments').removeClass('selected');
62 } 41 }
63 42
@@ -76,60 +55,40 @@ jQuery(document).ready(function($) { @@ -76,60 +55,40 @@ jQuery(document).ready(function($) {
76 <div align="center" class="triangle-right" >Comentar</div>\ 55 <div align="center" class="triangle-right" >Comentar</div>\
77 </a>'); 56 </a>');
78 57
79 - $('.side-comments-counter').click(function(){  
80 - var paragraphId = $(this).data('paragraph');  
81 - hideAllCommentsExcept(paragraphId); 58 + $('.comment-paragraph-plugin .side-comments-counter').click(function(){
  59 + var container = $(this).closest('.comment-paragraph-plugin');
  60 + var paragraphId = container.data('paragraph');
82 hideAllSelectedAreasExcept(paragraphId); 61 hideAllSelectedAreasExcept(paragraphId);
83 hideCommentBox(); 62 hideCommentBox();
84 - $(this).closest('.comments').addClass('selected');  
85 - $('.article-body').addClass('comment-paragraph-slide-left');  
86 - $('#side_comment_' + paragraphId).show(); 63 + container.addClass('comment-paragraph-slide-left selected');
  64 + container.find('.side-comment').show();
87 $('#comment-bubble').removeClass('visible'); 65 $('#comment-bubble').removeClass('visible');
88 //Loads the comments 66 //Loads the comments
89 - var url = $('#link_to_ajax_comments_' + paragraphId).data('url');  
90 - $.ajax({  
91 - dataType: "script",  
92 - url: url  
93 - }).done(function() {  
94 - var button = $('#page-comment-form-' + paragraphId + ' a').get(0);  
95 - button.click(); 67 + var url = container.find('.side-comment').data('comment_paragraph_url');
  68 + $.ajax(url).done(function(data) {
  69 + container.find('.article-comments-list').html(data);
  70 + if(container.find('.article-comment').length==0) {
  71 + container.find('.post_comment_box a.display-comment-form').click();
  72 + } else {
  73 + container.find('.post_comment_box').removeClass('opened');
  74 + container.find('.post_comment_box').addClass('closed');
  75 + container.find('.display-comment-form').show();
  76 + }
96 }); 77 });
97 }); 78 });
98 79
99 80
100 $('#comment-bubble').click(function(event){ 81 $('#comment-bubble').click(function(event){
101 - $(this).hide();  
102 - if($('.comment-paragraph-slide-left').size()==0){  
103 - $('.article-body').addClass('comment-paragraph-slide-left');  
104 - }  
105 - var url = $("#comment-bubble").data('url');  
106 - var paragraphId = $("#comment-bubble").data("paragraphId");  
107 - hideAllCommentsExcept(paragraphId);  
108 - $('#side_comment_' + paragraphId).show();  
109 - $.ajax({  
110 - dataType: "script",  
111 - url: url  
112 - }).done(function() {  
113 - var button = $('#page-comment-form-' + paragraphId + ' a').get(0);  
114 - button.click();  
115 - }); 82 + var paragraph = $("#comment-bubble").data("paragraph");
  83 + $('#comment-paragraph-plugin_' + paragraph).find('.side-comments-counter').click();
116 }); 84 });
117 85
118 - function hideAllCommentsExcept(clickedParagraph){  
119 - $(".side-comment").each(function(){  
120 - paragraph = $(this).data('paragraph');  
121 - if(paragraph != clickedParagraph){  
122 - $(this).hide();  
123 - //$(this).find().hide();  
124 - }  
125 - });  
126 - }  
127 -  
128 function hideAllSelectedAreasExcept(clickedParagraph){ 86 function hideAllSelectedAreasExcept(clickedParagraph){
129 $(".comment_paragraph").each(function(){ 87 $(".comment_paragraph").each(function(){
130 - paragraph = $(this).data('paragraph'); 88 + paragraph = $(this).closest('.comment-paragraph-plugin').data('paragraph');
131 if(paragraph != clickedParagraph){ 89 if(paragraph != clickedParagraph){
132 $(this).find(".commented-area").contents().unwrap(); 90 $(this).find(".commented-area").contents().unwrap();
  91 + $(this).html($(this).html()); //XXX: workaround to prevent creation of text nodes
133 } 92 }
134 }); 93 });
135 } 94 }
@@ -154,23 +113,20 @@ jQuery(document).ready(function($) { @@ -154,23 +113,20 @@ jQuery(document).ready(function($) {
154 //highlight area from the paragraph 113 //highlight area from the paragraph
155 $('.comment_paragraph').mouseup(function(event) { 114 $('.comment_paragraph').mouseup(function(event) {
156 115
157 - if($('.comment-paragraph-slide-left').size() > 0){  
158 - hideCommentBox();  
159 - } 116 + hideCommentBox();
160 117
161 //Don't do anything if there is no selected text 118 //Don't do anything if there is no selected text
162 if (getSelectionText().length == 0) { 119 if (getSelectionText().length == 0) {
163 return; 120 return;
164 } 121 }
165 122
166 - var paragraphId = $(this).data('paragraph'); 123 + var container = $(this).closest('.comment-paragraph-plugin');
  124 + var paragraphId = container.data('paragraph');
167 125
168 setCommentBubblePosition( event.pageX, event.pageY ); 126 setCommentBubblePosition( event.pageX, event.pageY );
169 127
170 //Prepare to open the div 128 //Prepare to open the div
171 - var url = $('#link_to_ajax_comments_' + paragraphId).data('url');  
172 - $("#comment-bubble").data("url", url);  
173 - $("#comment-bubble").data("paragraphId", paragraphId); 129 + $("#comment-bubble").data("paragraph", paragraphId);
174 $("#comment-bubble").addClass('visible'); 130 $("#comment-bubble").addClass('visible');
175 131
176 var rootElement = $(this).get(0); 132 var rootElement = $(this).get(0);
@@ -182,9 +138,9 @@ jQuery(document).ready(function($) { @@ -182,9 +138,9 @@ jQuery(document).ready(function($) {
182 } catch(e) { 138 } catch(e) {
183 return; 139 return;
184 } 140 }
185 - form = $('#page-comment-form-' + paragraphId).find('form'); 141 + form = container.find('.post_comment_box').find('form');
186 142
187 - //Register the area the has been selected at input.selected_area 143 + //Register the area that has been selected at input.selected_area
188 if (form.find('input.selected_area').length === 0){ 144 if (form.find('input.selected_area').length === 0){
189 $('<input>').attr({ 145 $('<input>').attr({
190 class: 'selected_area', 146 class: 'selected_area',
@@ -216,16 +172,15 @@ jQuery(document).ready(function($) { @@ -216,16 +172,15 @@ jQuery(document).ready(function($) {
216 if(anchor.length==0) return; 172 if(anchor.length==0) return;
217 var val = anchor.split('-'); //anchor format = #comment-\d+ 173 var val = anchor.split('-'); //anchor format = #comment-\d+
218 if(val.length!=2 || val[0]!='#comment') return; 174 if(val.length!=2 || val[0]!='#comment') return;
219 - if($('div[data-macro=comment_paragraph_plugin\\/allow_comment]').length==0) return; //comment_paragraph_plugin/allow_comment div must exists 175 + if($('.comment-paragraph-plugin').length==0) return;
220 var comment_id = val[1]; 176 var comment_id = val[1];
221 if(!/^\d+$/.test(comment_id)) return; //test for integer 177 if(!/^\d+$/.test(comment_id)) return; //test for integer
222 comment_paragraph_anchor = anchor; 178 comment_paragraph_anchor = anchor;
  179 +
223 var url = '/plugin/comment_paragraph/public/comment_paragraph/'+comment_id; 180 var url = '/plugin/comment_paragraph/public/comment_paragraph/'+comment_id;
224 - $.ajax({  
225 - dataType: "script",  
226 - url: url  
227 - }).done(function() {  
228 - var button = $('#page-comment-form-' + comment_id + ' a').get(0) 181 + $.ajax(url).done(function(data) {
  182 + var button = $('#comment-paragraph-plugin_' + data.paragraph_uuid + ' .side-comments-counter').click();
  183 + $('body').animate({scrollTop: parseInt(button.offset().top)}, 500);
229 button.click(); 184 button.click();
230 }); 185 });
231 } 186 }
@@ -234,8 +189,8 @@ jQuery(document).ready(function($) { @@ -234,8 +189,8 @@ jQuery(document).ready(function($) {
234 189
235 $(document).on('mouseenter', 'li.article-comment', function() { 190 $(document).on('mouseenter', 'li.article-comment', function() {
236 var selected_area = $(this).find('input.paragraph_comment_area').val(); 191 var selected_area = $(this).find('input.paragraph_comment_area').val();
237 - var paragraph_uuid = $(this).find('input.paragraph_uuid').val();  
238 - var rootElement = $('#comment_paragraph_' + paragraph_uuid).get(0); 192 + var container = $(this).closest('.comment-paragraph-plugin');
  193 + var rootElement = container.find('.comment_paragraph')[0];
239 194
240 if(selected_area != ""){ 195 if(selected_area != ""){
241 rangy.deserializeSelection(selected_area, rootElement); 196 rangy.deserializeSelection(selected_area, rootElement);
@@ -244,30 +199,6 @@ jQuery(document).ready(function($) { @@ -244,30 +199,6 @@ jQuery(document).ready(function($) {
244 }); 199 });
245 200
246 $(document).on('mouseleave', 'li.article-comment', function() { 201 $(document).on('mouseleave', 'li.article-comment', function() {
247 - var paragraph_uuid = $(this).find('input.paragraph_uuid').val();  
248 - var rootElement = $('#comment_paragraph_'+ paragraph_uuid).get(0);  
249 -  
250 - original_paragraphs.each( function(paragraph) {  
251 - if (paragraph.id == paragraph_uuid) {  
252 - rootElement.innerHTML = paragraph.content;  
253 - }  
254 - }); 202 + hideAllSelectedAreasExcept();
255 }); 203 });
256 -  
257 - function toggleParagraph(paragraph) {  
258 - var div = $('div.comments_list_toggle_paragraph_'+paragraph);  
259 - var visible = div.is(':visible');  
260 - if(!visible)  
261 - $('div.comment-paragraph-loading-' + paragraph).addClass('comment-button-loading');  
262 - div.toggle('fast');  
263 - return visible;  
264 - }  
265 -  
266 - function loadCompleted(paragraph) {  
267 - $('div.comment-paragraph-loading-'+paragraph).removeClass('comment-button-loading')  
268 - if(comment_paragraph_anchor) {  
269 - $.scrollTo($(comment_paragraph_anchor));  
270 - comment_paragraph_anchor = null;  
271 - }  
272 - }  
273 }); 204 });
public/style.css
@@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
9 width: 90px; 9 width: 90px;
10 text-decoration: none; 10 text-decoration: none;
11 visibility: hidden; 11 visibility: hidden;
  12 + cursor: pointer;
12 } 13 }
13 14
14 div.article-comments-list-more{ 15 div.article-comments-list-more{
@@ -99,21 +100,17 @@ div.article-comments-list-more{ @@ -99,21 +100,17 @@ div.article-comments-list-more{
99 } 100 }
100 101
101 .side-comment .comment-created-at{display: none;} 102 .side-comment .comment-created-at{display: none;}
102 -.side-comment #comment_title{display: none;}  
103 -.side-comment .comment_title{display: none;} 103 +.side-comment #comment_title, .side-comment .comment_title{display: none;}
104 .side-comment label[for="comment_title"] {display: none;} 104 .side-comment label[for="comment_title"] {display: none;}
105 105
106 -div[class^='comments_list_toggle_paragraph_'] {  
107 - border-style: solid;  
108 - border-width: 1px;  
109 - border-color: #e7e7e7;  
110 - padding: 5px;  
111 - background-color: whitesmoke;  
112 - width: 280px;  
113 -}  
114 -  
115 -div[class^='comment-paragraph-loading-'] {  
116 - z-index: 99; 106 +.side-comment {
  107 + border-style: solid;
  108 + border-width: 1px;
  109 + border-color: #e7e7e7;
  110 + padding: 5px;
  111 + background-color: whitesmoke;
  112 + width: 280px;
  113 + display: none;
117 } 114 }
118 115
119 #content .side-comment .comment-balloon div[class^='comment-wrapper-']{ 116 #content .side-comment .comment-balloon div[class^='comment-wrapper-']{
@@ -172,12 +169,12 @@ div[class^=&#39;comment-paragraph-loading-&#39;] { @@ -172,12 +169,12 @@ div[class^=&#39;comment-paragraph-loading-&#39;] {
172 left: 5px; 169 left: 5px;
173 border-style: solid; 170 border-style: solid;
174 border-width: 10px 5px 0; 171 border-width: 10px 5px 0;
175 - border-color: #bdbdbd transparent; 172 + border-color: #b5b5b5 transparent;
176 display: block; 173 display: block;
177 width: 0; 174 width: 0;
178 } 175 }
179 176
180 -.comment-count{ 177 +.comment-count-container {
181 position: relative; 178 position: relative;
182 top: 3px; 179 top: 3px;
183 } 180 }
@@ -231,9 +228,6 @@ div[class^=&#39;comment-paragraph-loading-&#39;] { @@ -231,9 +228,6 @@ div[class^=&#39;comment-paragraph-loading-&#39;] {
231 .side-comment .comment-wrapper-1 { 228 .side-comment .comment-wrapper-1 {
232 margin-left: 36px; 229 margin-left: 36px;
233 } 230 }
234 -#article .side-comment .article-comments-list .comment-replies {  
235 - padding-left: 25px;  
236 -}  
237 #article .side-comment .comment-picture { 231 #article .side-comment .comment-picture {
238 width: 100%; 232 width: 100%;
239 height: auto; 233 height: auto;
@@ -246,9 +240,6 @@ div[class^=&#39;comment-paragraph-loading-&#39;] { @@ -246,9 +240,6 @@ div[class^=&#39;comment-paragraph-loading-&#39;] {
246 .side-comment .formlabel[for='comment_body'] { 240 .side-comment .formlabel[for='comment_body'] {
247 display: none; 241 display: none;
248 } 242 }
249 -.side-comment > div > div {  
250 - background: #FFFFFF;  
251 -}  
252 .side-comment .comment_form p { 243 .side-comment .comment_form p {
253 display: none; 244 display: none;
254 } 245 }
@@ -257,7 +248,7 @@ div[class^=&#39;comment-paragraph-loading-&#39;] { @@ -257,7 +248,7 @@ div[class^=&#39;comment-paragraph-loading-&#39;] {
257 padding-bottom: 15px; 248 padding-bottom: 15px;
258 } 249 }
259 250
260 -.side-comment .comment-count { 251 +.side-comment .comment-count-container {
261 bg-color: #b3b2d4; 252 bg-color: #b3b2d4;
262 } 253 }
263 254
@@ -265,22 +256,12 @@ div[class^=&#39;comment-paragraph-loading-&#39;] { @@ -265,22 +256,12 @@ div[class^=&#39;comment-paragraph-loading-&#39;] {
265 height: 50px; 256 height: 50px;
266 } 257 }
267 258
268 -.comment-paragraph-comments{  
269 - background: lightblue;  
270 - padding: 5px;  
271 - width: 150px;  
272 - margin-top: 10px;  
273 - color: white;  
274 - font-weight: bold;  
275 - text-align: center;  
276 -}  
277 -  
278 .single-border{ 259 .single-border{
279 border-style: solid; 260 border-style: solid;
280 border-width: 2px; 261 border-width: 2px;
281 } 262 }
282 263
283 -.comment-paragraph-slide-left .comments { 264 +.comment-paragraph-plugin .comments {
284 position: relative; 265 position: relative;
285 display: table; 266 display: table;
286 } 267 }
@@ -289,7 +270,7 @@ div[class^=&#39;comment-paragraph-loading-&#39;] { @@ -289,7 +270,7 @@ div[class^=&#39;comment-paragraph-loading-&#39;] {
289 background-color: rgb(236, 236, 236); 270 background-color: rgb(236, 236, 236);
290 } 271 }
291 272
292 -.comment-paragraph-group-comments{ 273 +.side-comment {
293 position: absolute; 274 position: absolute;
294 right: -296px; 275 right: -296px;
295 top: 0px; 276 top: 0px;
@@ -297,11 +278,11 @@ div[class^=&#39;comment-paragraph-loading-&#39;] { @@ -297,11 +278,11 @@ div[class^=&#39;comment-paragraph-loading-&#39;] {
297 z-index: 199; 278 z-index: 199;
298 } 279 }
299 280
300 -.article-body.comment-paragraph-slide-left { 281 +.comment-paragraph-plugin.comment-paragraph-slide-left {
301 position: relative; 282 position: relative;
302 width: 80%; 283 width: 80%;
303 } 284 }
304 -.article-body { 285 +.comment-paragraph-plugin {
305 width: 100%; 286 width: 100%;
306 transition: width 0.3s ease-in-out; 287 transition: width 0.3s ease-in-out;
307 } 288 }
@@ -320,3 +301,44 @@ div[class^=&#39;comment-paragraph-loading-&#39;] { @@ -320,3 +301,44 @@ div[class^=&#39;comment-paragraph-loading-&#39;] {
320 padding-right: 10px; 301 padding-right: 10px;
321 margin-left: -36px; 302 margin-left: -36px;
322 } 303 }
  304 +
  305 +.comment-paragraph-plugin .no-comments-yet .comment-count {
  306 + display: none;
  307 +}
  308 +
  309 +.comment-paragraph-plugin .no-comments-yet:after {
  310 + content: "+";
  311 +}
  312 +#content .comment-paragraph-plugin .no-comments-yet {
  313 + font-size: 100%;
  314 + opacity: 1;
  315 +}
  316 +
  317 +#content .comment-paragraph-plugin .display-comment-form {
  318 + text-decoration: none;
  319 + color: gray;
  320 +}
  321 +
  322 +#content .comment-paragraph-plugin .display-comment-form:hover {
  323 + color: rgb(95, 95, 95);
  324 +}
  325 +
  326 +#content .comment-paragraph-plugin .side-comment .article-comments-list .comment-replies .comment-replies {
  327 + padding-left: 0;
  328 +}
  329 +#content .comment-paragraph-plugin .side-comment .article-comments-list .comment-replies {
  330 + padding-left: 25px;
  331 +}
  332 +
  333 +#content .comment-paragraph-plugin #cancel-comment, #content .comment-paragraph-plugin .icon-add {
  334 + background: none;
  335 + border: none;
  336 +}
  337 +#content .comment-paragraph-plugin #cancel-comment:hover, #content .comment-paragraph-plugin .icon-add:hover {
  338 + background: none;
  339 + color: black;
  340 + border: none;
  341 +}
  342 +#content .comment-paragraph-plugin .button-bar {
  343 + margin: 5px 0;
  344 +}
test/functional/comment_paragraph_plugin_admin_controller_test.rb 0 → 100644
@@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
  1 +require File.dirname(__FILE__) + '/../../../../test/test_helper'
  2 +require File.dirname(__FILE__) + '/../../controllers/comment_paragraph_plugin_admin_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class CommentParagraphPluginAdminController; def rescue_action(e) raise e end; end
  6 +
  7 +class CommentParagraphPluginAdminControllerTest < ActionController::TestCase
  8 +
  9 + def setup
  10 + @environment = Environment.default
  11 + user_login = create_admin_user(@environment)
  12 + login_as(user_login)
  13 + @environment.enabled_plugins = ['CommentParagraphPlugin']
  14 + @environment.save!
  15 + @plugin_settings = Noosfero::Plugin::Settings.new(@environment, CommentParagraphPlugin)
  16 + end
  17 +
  18 + should 'access index action' do
  19 + get :index
  20 + assert_template 'index'
  21 + assert_response :success
  22 + end
  23 +
  24 + should 'update comment paragraph plugin settings' do
  25 + assert_nil @plugin_settings.get_setting(:auto_marking_article_types)
  26 + post :index, :settings => { :auto_marking_article_types => ['TinyMceArticle'] }
  27 + @environment.reload
  28 + assert_not_nil @plugin_settings.get_setting(:auto_marking_article_types)
  29 + end
  30 +
  31 + should 'get article types previously selected' do
  32 + post :index, :settings => { :auto_marking_article_types => ['TinyMceArticle', 'TextileArticle'] }
  33 + get :index
  34 + assert_tag :input, :attributes => { :value => 'TinyMceArticle' }
  35 + assert_tag :input, :attributes => { :value => 'TextileArticle' }
  36 + end
  37 +
  38 +end
test/functional/comment_paragraph_plugin_profile_controller_test.rb
@@ -7,39 +7,31 @@ class CommentParagraphPluginProfileController; def rescue_action(e) raise e end; @@ -7,39 +7,31 @@ class CommentParagraphPluginProfileController; def rescue_action(e) raise e end;
7 class CommentParagraphPluginProfileControllerTest < ActionController::TestCase 7 class CommentParagraphPluginProfileControllerTest < ActionController::TestCase
8 8
9 def setup 9 def setup
10 - @controller = CommentParagraphPluginProfileController.new  
11 - @request = ActionController::TestRequest.new  
12 - @response = ActionController::TestResponse.new  
13 -  
14 @profile = create_user('testuser').person 10 @profile = create_user('testuser').person
15 @article = profile.articles.build(:name => 'test') 11 @article = profile.articles.build(:name => 'test')
16 @article.save! 12 @article.save!
17 end 13 end
18 - attr_reader :article  
19 - attr_reader :profile 14 + attr_reader :article, :profile
20 15
21 should 'be able to show paragraph comments' do 16 should 'be able to show paragraph comments' do
22 comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_uuid => 0) 17 comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_uuid => 0)
23 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_uuid => 0 18 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_uuid => 0
24 - assert_template 'comment_paragraph_plugin_profile/view_comments'  
25 - assert_match /comments_list_paragraph_0/, @response.body  
26 - assert_match /\"comment-count-0\", \"1\"/, @response.body 19 + assert_select "#comment-#{comment.id}"
27 end 20 end
28 21
29 should 'do not show global comments' do 22 should 'do not show global comments' do
30 - fast_create(Comment, :source_id => article, :author_id => profile, :title => 'global comment', :body => 'global', :paragraph_uuid => nil)  
31 - fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_uuid => 0) 23 + global_comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'global comment', :body => 'global', :paragraph_uuid => nil)
  24 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_uuid => 0)
32 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_uuid => 0 25 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_uuid => 0
33 - assert_template 'comment_paragraph_plugin_profile/view_comments'  
34 - assert_match /comments_list_paragraph_0/, @response.body  
35 - assert_match /\"comment-count-0\", \"1\"/, @response.body 26 + assert_select "#comment-#{global_comment.id}", 0
  27 + assert_select "#comment-#{comment.id}"
36 end 28 end
37 29
38 should 'be able to show all comments of a paragraph' do 30 should 'be able to show all comments of a paragraph' do
39 - comment1 = fast_create(Comment, :created_at => Time.now - 1.days, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'a comment', :paragraph_uuid => 0)  
40 - comment2 = fast_create(Comment, :created_at => Time.now - 2.days, :source_id => article, :author_id => profile, :title => 'b comment', :body => 'b comment', :paragraph_uuid => 0)  
41 - comment3 = fast_create(Comment, :created_at => Time.now - 3.days, :source_id => article, :author_id => profile, :title => 'c comment', :body => 'c comment', :paragraph_uuid => 0)  
42 - comment4 = fast_create(Comment, :created_at => Time.now - 4.days, :source_id => article, :author_id => profile, :title => 'd comment', :body => 'd comment', :paragraph_uuid => 0) 31 + fast_create(Comment, :created_at => Time.now - 1.days, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'a comment', :paragraph_uuid => 0)
  32 + fast_create(Comment, :created_at => Time.now - 2.days, :source_id => article, :author_id => profile, :title => 'b comment', :body => 'b comment', :paragraph_uuid => 0)
  33 + fast_create(Comment, :created_at => Time.now - 3.days, :source_id => article, :author_id => profile, :title => 'c comment', :body => 'c comment', :paragraph_uuid => 0)
  34 + fast_create(Comment, :created_at => Time.now - 4.days, :source_id => article, :author_id => profile, :title => 'd comment', :body => 'd comment', :paragraph_uuid => 0)
43 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_uuid => 0 35 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_uuid => 0
44 assert_match /a comment/, @response.body 36 assert_match /a comment/, @response.body
45 assert_match /b comment/, @response.body 37 assert_match /b comment/, @response.body
test/functional/comment_paragraph_plugin_public_controller_test.rb
@@ -8,30 +8,23 @@ class CommentParagraphPluginPublicController; def rescue_action(e) raise e end; @@ -8,30 +8,23 @@ class CommentParagraphPluginPublicController; def rescue_action(e) raise e end;
8 class CommentParagraphPluginPublicControllerTest < ActionController::TestCase 8 class CommentParagraphPluginPublicControllerTest < ActionController::TestCase
9 9
10 def setup 10 def setup
11 - @controller = CommentParagraphPluginPublicController.new  
12 - @request = ActionController::TestRequest.new  
13 - @response = ActionController::TestResponse.new  
14 -  
15 @profile = create_user('testuser').person 11 @profile = create_user('testuser').person
16 @article = profile.articles.build(:name => 'test') 12 @article = profile.articles.build(:name => 'test')
17 @article.save! 13 @article.save!
18 end 14 end
19 - attr_reader :article  
20 - attr_reader :profile  
21 - 15 + attr_reader :article, :profile
22 16
23 should 'be able to return paragraph_uuid for a comment' do 17 should 'be able to return paragraph_uuid for a comment' do
24 comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_uuid => 0) 18 comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_uuid => 0)
25 cid = comment.id 19 cid = comment.id
26 xhr :get, :comment_paragraph, :id => cid 20 xhr :get, :comment_paragraph, :id => cid
27 - assert_match /\{\"paragraph_uuid\":0\}/, @response.body 21 + assert_equal({'paragraph_uuid' => '0'}, ActiveSupport::JSON.decode(@response.body))
28 end 22 end
29 23
30 should 'return paragraph_uuid=null for a global comment' do 24 should 'return paragraph_uuid=null for a global comment' do
31 comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala' ) 25 comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala' )
32 xhr :get, :comment_paragraph, :id => comment.id 26 xhr :get, :comment_paragraph, :id => comment.id
33 - assert_match /\{\"paragraph_uuid\":null\}/, @response.body 27 + assert_equal({'paragraph_uuid' => nil}, ActiveSupport::JSON.decode(@response.body))
34 end 28 end
35 29
36 -  
37 end 30 end
test/functional/comment_paragraph_plugin_test.rb
@@ -1,38 +0,0 @@ @@ -1,38 +0,0 @@
1 -require File.dirname(__FILE__) + '/../../../../test/test_helper'  
2 -require File.dirname(__FILE__) + '/../../controllers/comment_paragraph_plugin_admin_controller'  
3 -  
4 -# Re-raise errors caught by the controller.  
5 -class CommentParagraphPluginAdminController; def rescue_action(e) raise e end; end  
6 -  
7 -class CommentParagraphPluginAdminControllerTest < ActionController::TestCase  
8 -  
9 - def setup  
10 - @environment = Environment.default  
11 - user_login = create_admin_user(@environment)  
12 - login_as(user_login)  
13 - @environment.enabled_plugins = ['CommentParagraphPlugin']  
14 - @environment.save!  
15 - @plugin_settings = Noosfero::Plugin::Settings.new(@environment, CommentParagraphPlugin)  
16 - end  
17 -  
18 - should 'access index action' do  
19 - get :index  
20 - assert_template 'index'  
21 - assert_response :success  
22 - end  
23 -  
24 - should 'update comment paragraph plugin settings' do  
25 - assert_nil @plugin_settings.get_setting(:auto_marking_article_types)  
26 - post :index, :settings => { :auto_marking_article_types => ['TinyMceArticle'] }  
27 - @environment.reload  
28 - assert_not_nil @plugin_settings.get_setting(:auto_marking_article_types)  
29 - end  
30 -  
31 - should 'get article types previously selected' do  
32 - post :index, :settings => { :auto_marking_article_types => ['TinyMceArticle', 'TextileArticle'] }  
33 - get :index  
34 - assert_tag :input, :attributes => { :value => 'TinyMceArticle' }  
35 - assert_tag :input, :attributes => { :value => 'TextileArticle' }  
36 - end  
37 -  
38 -end  
test/unit/article_test.rb
@@ -22,5 +22,4 @@ class ArticleTest &lt; ActiveSupport::TestCase @@ -22,5 +22,4 @@ class ArticleTest &lt; ActiveSupport::TestCase
22 assert article.save 22 assert article.save
23 end 23 end
24 24
25 -  
26 end 25 end
test/unit/comment_test.rb
@@ -10,16 +10,16 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -10,16 +10,16 @@ class CommentTest &lt; ActiveSupport::TestCase
10 attr_reader :article 10 attr_reader :article
11 11
12 should 'return comments that belongs to a specified paragraph' do 12 should 'return comments that belongs to a specified paragraph' do
13 - comment1 = fast_create(Comment, :paragraph_uuid => 1, :source_id => article.id) 13 + comment1 = fast_create(Comment, :paragraph_uuid => '1', :source_id => article.id)
14 comment2 = fast_create(Comment, :paragraph_uuid => nil, :source_id => article.id) 14 comment2 = fast_create(Comment, :paragraph_uuid => nil, :source_id => article.id)
15 - comment3 = fast_create(Comment, :paragraph_uuid => 2, :source_id => article.id)  
16 - assert_equal [comment1], article.comments.in_paragraph(1) 15 + comment3 = fast_create(Comment, :paragraph_uuid => '2', :source_id => article.id)
  16 + assert_equal [comment1], article.comments.in_paragraph('1')
17 end 17 end
18 18
19 should 'return comments that do not belongs to any paragraph' do 19 should 'return comments that do not belongs to any paragraph' do
20 - comment1 = fast_create(Comment, :paragraph_uuid => 1, :source_id => article.id) 20 + comment1 = fast_create(Comment, :paragraph_uuid => '1', :source_id => article.id)
21 comment2 = fast_create(Comment, :paragraph_uuid => nil, :source_id => article.id) 21 comment2 = fast_create(Comment, :paragraph_uuid => nil, :source_id => article.id)
22 - comment3 = fast_create(Comment, :paragraph_uuid => 2, :source_id => article.id) 22 + comment3 = fast_create(Comment, :paragraph_uuid => '2', :source_id => article.id)
23 assert_equal [comment2], article.comments.without_paragraph 23 assert_equal [comment2], article.comments.without_paragraph
24 end 24 end
25 25
views/comment_paragraph_plugin_profile/_comment_paragraph.html.erb
1 -<div class="comment-paragraph-plugin comments">  
2 - <div class="comment_paragraph" id="comment_paragraph_<%= paragraph_uuid %>" data-paragraph="<%= paragraph_uuid %>"> 1 +<div class="comment-paragraph-plugin comments" id="comment-paragraph-plugin_<%= paragraph_uuid %>" data-paragraph="<%= paragraph_uuid %>">
  2 + <div class="comment_paragraph">
3 <%= inner_html %> 3 <%= inner_html %>
4 </div> 4 </div>
5 <div class="side-comments-counter-container"> 5 <div class="side-comments-counter-container">
6 - <div class="side-comments-counter" id="side_comments_counter_<%= paragraph_uuid %>" data-paragraph="<%= paragraph_uuid %>">  
7 - <span id="comment-count-<%= paragraph_uuid %>" class='comment-count'>  
8 - <%= count %> 6 + <div class="side-comments-counter">
  7 + <span class='comment-count-container <%= count==0 ? 'no-comments-yet':'' %>'>
  8 + <span class="comment-count"><%= count %></span>
9 </span> 9 </span>
10 </div> 10 </div>
11 </div> 11 </div>
12 -<div class="comment-paragraph-group-comments">  
13 - <%=  
14 - url = { :profile => profile_identifier, :controller => 'comment_paragraph_plugin_profile', :action => 'view_comments', :paragraph_uuid => paragraph_uuid, :article_id => article_id}  
15 - link_to_remote(  
16 - '',  
17 - {  
18 - :url => url,  
19 - :method => :post,  
20 - :condition => "!toggleParagraph(#{paragraph_uuid})",  
21 - :complete => "loadCompleted(#{paragraph_uuid})"  
22 - },  
23 - {  
24 - :id => "link_to_ajax_comments_#{paragraph_uuid}",  
25 - :'data-url' => url_for(url)  
26 - }  
27 - )%>  
28 12
29 - <div class="side-comment" id="side_comment_<%= paragraph_uuid %>" data-paragraph="<%= paragraph_uuid %>" style="display:none">  
30 - <div class="comment-paragraph-loading-<%= paragraph_uuid %>">  
31 - <div class="comments_list_toggle_paragraph_<%= paragraph_uuid %>" >  
32 - <div class="article-comments-list" id="comments_list_paragraph_<%= paragraph_uuid %>">  
33 - <div class="loading"></div>  
34 - </div>  
35 - <div class ="article-comments-list-more" id="comments_list_paragraph_<%= paragraph_uuid %>_more"></div>  
36 - <div id="page-comment-form-<%= paragraph_uuid %>" class='post_comment_box closed'>  
37 - <%= render :partial => 'comment/comment_form', :locals => {:comment => Comment.new, :display_link => true, :cancel_triggers_hide => true, :paragraph_uuid => paragraph_uuid}%>  
38 - </div>  
39 - </div>  
40 - </div> 13 + <% load_comments_url = url_for({:profile => profile_identifier, :controller => 'comment_paragraph_plugin_profile', :action => 'view_comments', :paragraph_uuid => paragraph_uuid, :article_id => article_id}) %>
  14 +
  15 + <div class="side-comment" data-comment_paragraph_url="<%= load_comments_url %>">
  16 + <div class="article-comments-list">
  17 + <div class="loading"></div>
  18 + </div>
  19 + <div class ="article-comments-list-more"></div>
  20 + <div class='post_comment_box closed'>
  21 + <%= render :partial => 'comment/comment_form', :locals => {:comment => Comment.new, :display_link => true, :cancel_triggers_hide => true, :paragraph_uuid => paragraph_uuid}%>
  22 + </div>
41 </div> 23 </div>
42 </div> 24 </div>
43 -</div>  
44 -  
45 -  
46 -  
47 -  
48 -  
views/comment_paragraph_plugin_profile/view_comments.rjs
@@ -1,2 +0,0 @@ @@ -1,2 +0,0 @@
1 -page.replace_html "comments_list_paragraph_#{@paragraph_uuid}", :partial => 'comment/comment.html.erb', :collection => @comments  
2 -page.replace_html "comment-count-#{@paragraph_uuid}", @comments_count