Commit 83c9071a91deff6bd249f0494ba7dc4931a636d7
1 parent
ba18cb88
Exists in
master
and in
29 other branches
Add comment_paragraph
Showing
34 changed files
with
1746 additions
and
0 deletions
Show diff stats
plugins/comment_paragraph/controllers/comment_paragraph_plugin_admin_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,12 @@ |
1 | +class CommentParagraphPluginAdminController < AdminController | |
2 | + append_view_path File.join(File.dirname(__FILE__) + '/../views') | |
3 | + | |
4 | + def index | |
5 | + @settings = Noosfero::Plugin::Settings.new(environment, CommentParagraphPlugin, params[:settings]) | |
6 | + if request.post? | |
7 | + @settings.save! | |
8 | + session[:notice] = _('Settings successfuly saved') | |
9 | + end | |
10 | + end | |
11 | + | |
12 | +end | ... | ... |
plugins/comment_paragraph/controllers/myprofile/comment_paragraph_plugin_myprofile_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,18 @@ |
1 | +class CommentParagraphPluginMyprofileController < MyProfileController | |
2 | + | |
3 | + before_filter :check_permission | |
4 | + | |
5 | + def toggle_activation | |
6 | + @article.comment_paragraph_plugin_activate = !@article.comment_paragraph_plugin_activate | |
7 | + @article.save! | |
8 | + redirect_to @article.view_url | |
9 | + end | |
10 | + | |
11 | + protected | |
12 | + | |
13 | + def check_permission | |
14 | + @article = profile.articles.find(params[:id]) | |
15 | + render_access_denied unless @article.comment_paragraph_plugin_enabled? && @article.allow_edit?(user) | |
16 | + end | |
17 | + | |
18 | +end | ... | ... |
plugins/comment_paragraph/controllers/profile/comment_paragraph_plugin_profile_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,14 @@ |
1 | +class CommentParagraphPluginProfileController < ProfileController | |
2 | + append_view_path File.join(File.dirname(__FILE__) + '/../../views') | |
3 | + | |
4 | + def view_comments | |
5 | + @article_id = params[:article_id] | |
6 | + @paragraph_uuid = params[:paragraph_uuid] | |
7 | + article = profile.articles.find(@article_id) | |
8 | + @comments = article.comments.without_spam.in_paragraph(@paragraph_uuid) | |
9 | + @comments_count = @comments.count | |
10 | + @comments = @comments.without_reply | |
11 | + render :partial => 'comment/comment.html.erb', :collection => @comments | |
12 | + end | |
13 | + | |
14 | +end | ... | ... |
plugins/comment_paragraph/controllers/public/comment_paragraph_plugin_public_controller.rb
0 → 100644
... | ... | @@ -0,0 +1,9 @@ |
1 | +class CommentParagraphPluginPublicController < PublicController | |
2 | + append_view_path File.join(File.dirname(__FILE__) + '/../views') | |
3 | + | |
4 | + def comment_paragraph | |
5 | + @comment = Comment.find(params[:id]) | |
6 | + render :json => { :paragraph_uuid => @comment.paragraph_uuid } | |
7 | + end | |
8 | + | |
9 | +end | ... | ... |
plugins/comment_paragraph/db/migrate/20141223184902_add_paragraph_uuid_to_comments.rb
0 → 100644
plugins/comment_paragraph/lib/comment_paragraph_plugin.rb
0 → 100644
... | ... | @@ -0,0 +1,60 @@ |
1 | +class CommentParagraphPlugin < Noosfero::Plugin | |
2 | + | |
3 | + def self.plugin_name | |
4 | + "Comment Paragraph" | |
5 | + end | |
6 | + | |
7 | + def self.plugin_description | |
8 | + _("A plugin that display comments divided by paragraphs.") | |
9 | + end | |
10 | + | |
11 | + def unavailable_comments(scope) | |
12 | + scope.without_paragraph | |
13 | + end | |
14 | + | |
15 | + def comment_form_extra_contents(args) | |
16 | + comment = args[:comment] | |
17 | + paragraph_uuid = comment.paragraph_uuid || args[:paragraph_uuid] | |
18 | + proc { | |
19 | + arr = [] | |
20 | + arr << hidden_field_tag('comment[id]', comment.id) | |
21 | + arr << hidden_field_tag('comment[paragraph_uuid]', paragraph_uuid) if paragraph_uuid | |
22 | + arr << hidden_field_tag('comment[comment_paragraph_selected_area]', comment.comment_paragraph_selected_area) unless comment.comment_paragraph_selected_area.blank? | |
23 | + arr << hidden_field_tag('comment[comment_paragraph_selected_content]', comment.comment_paragraph_selected_content) unless comment.comment_paragraph_selected_content.blank? | |
24 | + arr | |
25 | + } | |
26 | + end | |
27 | + | |
28 | + def comment_extra_contents(args) | |
29 | + comment = args[:comment] | |
30 | + proc { | |
31 | + render :file => 'comment_paragraph_plugin_profile/comment_extra', :locals => {:comment => comment} | |
32 | + } | |
33 | + end | |
34 | + | |
35 | + def js_files | |
36 | + ['comment_paragraph_macro', 'rangy-core', 'rangy-cssclassapplier', 'rangy-serializer'] | |
37 | + end | |
38 | + | |
39 | + def stylesheet? | |
40 | + true | |
41 | + end | |
42 | + | |
43 | + def self.activation_mode_default_setting | |
44 | + 'manual' | |
45 | + end | |
46 | + | |
47 | + def article_extra_toolbar_buttons(article) | |
48 | + user = context.send :user | |
49 | + return [] if !article.comment_paragraph_plugin_enabled? || !article.allow_edit?(user) | |
50 | + { | |
51 | + :title => article.comment_paragraph_plugin_activated? ? _('Deactivate Comments') : _('Activate Comments'), | |
52 | + :url => {:controller => 'comment_paragraph_plugin_myprofile', :profile => article.profile.identifier, :action => 'toggle_activation', :id => article.id}, | |
53 | + :icon => :toggle_comment_paragraph | |
54 | + } | |
55 | + | |
56 | + end | |
57 | + | |
58 | +end | |
59 | + | |
60 | +require_dependency 'comment_paragraph_plugin/macros/allow_comment' | ... | ... |
plugins/comment_paragraph/lib/comment_paragraph_plugin/macros/allow_comment.rb
0 → 100644
... | ... | @@ -0,0 +1,23 @@ |
1 | +ActionView::Base.sanitized_allowed_attributes += ['data-macro', 'data-macro-paragraph_uuid'] | |
2 | + | |
3 | +class CommentParagraphPlugin::AllowComment < Noosfero::Plugin::Macro | |
4 | + | |
5 | + def self.configuration | |
6 | + { :params => [] } | |
7 | + end | |
8 | + | |
9 | + def parse(params, inner_html, source) | |
10 | + paragraph_uuid = params[:paragraph_uuid] | |
11 | + article = source | |
12 | + count = article.paragraph_comments.without_spam.in_paragraph(paragraph_uuid).count | |
13 | + | |
14 | + proc { | |
15 | + if controller.kind_of?(ContentViewerController) && article.comment_paragraph_plugin_activated? | |
16 | + render :partial => 'comment_paragraph_plugin_profile/comment_paragraph', | |
17 | + :locals => {:paragraph_uuid => paragraph_uuid, :article_id => article.id, :inner_html => inner_html, :count => count, :profile_identifier => article.profile.identifier } | |
18 | + else | |
19 | + inner_html | |
20 | + end | |
21 | + } | |
22 | + end | |
23 | +end | ... | ... |
... | ... | @@ -0,0 +1,62 @@ |
1 | +require_dependency 'article' | |
2 | + | |
3 | +class Article | |
4 | + | |
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 | + | |
7 | + before_save :comment_paragraph_plugin_parse_html | |
8 | + | |
9 | + settings_items :comment_paragraph_plugin_activate, :type => :boolean, :default => false | |
10 | + | |
11 | + def comment_paragraph_plugin_enabled? | |
12 | + environment.plugin_enabled?(CommentParagraphPlugin) && self.kind_of?(TextArticle) | |
13 | + end | |
14 | + | |
15 | + def comment_paragraph_plugin_activated? | |
16 | + comment_paragraph_plugin_activate && comment_paragraph_plugin_enabled? | |
17 | + end | |
18 | + | |
19 | + def cache_key_with_comment_paragraph(params = {}, user = nil, language = 'en') | |
20 | + cache_key_without_comment_paragraph(params, user, language) + (user.present? ? '-logged_in-': '-not_logged-') | |
21 | + end | |
22 | + | |
23 | + alias_method_chain :cache_key, :comment_paragraph | |
24 | + | |
25 | + def comment_paragraph_plugin_paragraph_content(paragraph_uuid) | |
26 | + doc = Nokogiri::HTML(body) | |
27 | + paragraph = doc.css("[data-macro-paragraph_uuid='#{paragraph_uuid}']").first | |
28 | + paragraph.present? ? paragraph.text : nil | |
29 | + end | |
30 | + | |
31 | + protected | |
32 | + | |
33 | + def comment_paragraph_plugin_parse_html | |
34 | + comment_paragraph_plugin_set_initial_value unless persisted? | |
35 | + return unless comment_paragraph_plugin_activated? | |
36 | + if body && (body_changed? || setting_changed?(:comment_paragraph_plugin_activate)) | |
37 | + updated = body_changed? ? body_change[1] : body | |
38 | + doc = Nokogiri::HTML(updated) | |
39 | + doc.css('li, body > div, body > span, body > p').each do |paragraph| | |
40 | + next if paragraph.css('[data-macro="comment_paragraph_plugin/allow_comment"]').present? || paragraph.content.blank? | |
41 | + | |
42 | + commentable = Nokogiri::XML::Node.new("span", doc) | |
43 | + commentable['class'] = "macro article_comments paragraph_comment #{paragraph['class']}" | |
44 | + commentable['data-macro'] = 'comment_paragraph_plugin/allow_comment' | |
45 | + commentable['data-macro-paragraph_uuid'] = SecureRandom.uuid | |
46 | + commentable.inner_html = paragraph.inner_html | |
47 | + paragraph.inner_html = commentable | |
48 | + end | |
49 | + self.body = doc.at('body').inner_html | |
50 | + end | |
51 | + end | |
52 | + | |
53 | + def comment_paragraph_plugin_set_initial_value | |
54 | + self.comment_paragraph_plugin_activate = comment_paragraph_plugin_enabled? && | |
55 | + comment_paragraph_plugin_settings.activation_mode == 'auto' | |
56 | + end | |
57 | + | |
58 | + def comment_paragraph_plugin_settings | |
59 | + @comment_paragraph_plugin_settings ||= Noosfero::Plugin::Settings.new(environment, CommentParagraphPlugin) | |
60 | + end | |
61 | + | |
62 | +end | ... | ... |
... | ... | @@ -0,0 +1,22 @@ |
1 | +require_dependency 'comment' | |
2 | + | |
3 | +class Comment | |
4 | + | |
5 | + scope :without_paragraph, :conditions => {:paragraph_uuid => nil } | |
6 | + | |
7 | + settings_items :comment_paragraph_selected_area, :type => :string | |
8 | + settings_items :comment_paragraph_selected_content, :type => :string | |
9 | + | |
10 | + scope :in_paragraph, proc { |paragraph_uuid| { | |
11 | + :conditions => ['paragraph_uuid = ?', paragraph_uuid] | |
12 | + } | |
13 | + } | |
14 | + | |
15 | + attr_accessible :paragraph_uuid, :comment_paragraph_selected_area, :id, :comment_paragraph_selected_content | |
16 | + | |
17 | + before_validation do |comment| | |
18 | + comment.comment_paragraph_selected_area = nil if comment.comment_paragraph_selected_area.blank? | |
19 | + comment.comment_paragraph_selected_content = nil if comment_paragraph_selected_content.blank? | |
20 | + end | |
21 | + | |
22 | +end | ... | ... |
... | ... | @@ -0,0 +1,11 @@ |
1 | +require_dependency 'tinymce_helper' | |
2 | + | |
3 | +module TinymceHelper | |
4 | + | |
5 | + def tinymce_init_js_with_comment_paragraph(options = {}) | |
6 | + options = options.merge(:keep_styles => false) if environment.plugin_enabled?(CommentParagraphPlugin) | |
7 | + tinymce_init_js_without_comment_paragraph(options) | |
8 | + end | |
9 | + | |
10 | + alias_method_chain :tinymce_init_js, :comment_paragraph | |
11 | +end | ... | ... |
... | ... | @@ -0,0 +1,69 @@ |
1 | +# SOME DESCRIPTIVE TITLE. | |
2 | +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
3 | +# This file is distributed under the same license as the PACKAGE package. | |
4 | +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
5 | +# | |
6 | +msgid "" | |
7 | +msgstr "" | |
8 | +"Project-Id-Version: 1.2~rc1-2843-g999a037\n" | |
9 | +"POT-Creation-Date: 2015-08-06 08:53-0300\n" | |
10 | +"PO-Revision-Date: 2015-03-03 07:41-0300\n" | |
11 | +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | |
12 | +"Language-Team: LANGUAGE <LL@li.org>\n" | |
13 | +"Language: \n" | |
14 | +"MIME-Version: 1.0\n" | |
15 | +"Content-Type: text/plain; charset=UTF-8\n" | |
16 | +"Content-Transfer-Encoding: 8bit\n" | |
17 | +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" | |
18 | + | |
19 | +#: plugins/comment_paragraph/controllers/comment_paragraph_plugin_admin_controller.rb:8 | |
20 | +msgid "Settings successfuly saved" | |
21 | +msgstr "" | |
22 | + | |
23 | +#: plugins/comment_paragraph/lib/comment_paragraph_plugin.rb:8 | |
24 | +msgid "A plugin that display comments divided by paragraphs." | |
25 | +msgstr "" | |
26 | + | |
27 | +#: plugins/comment_paragraph/lib/comment_paragraph_plugin.rb:50 | |
28 | +msgid "Deactivate Comments" | |
29 | +msgstr "" | |
30 | + | |
31 | +#: plugins/comment_paragraph/lib/comment_paragraph_plugin.rb:50 | |
32 | +msgid "Activate Comments" | |
33 | +msgstr "" | |
34 | + | |
35 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:2 | |
36 | +msgid "Comment Paragraph Plugin Settings" | |
37 | +msgstr "" | |
38 | + | |
39 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:7 | |
40 | +msgid "Activation Mode" | |
41 | +msgstr "" | |
42 | + | |
43 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:10 | |
44 | +msgid "Auto" | |
45 | +msgstr "" | |
46 | + | |
47 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:11 | |
48 | +msgid "(all text articles will be activated by default)" | |
49 | +msgstr "" | |
50 | + | |
51 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:15 | |
52 | +msgid "Manual" | |
53 | +msgstr "" | |
54 | + | |
55 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:16 | |
56 | +msgid "(click on \"Activate Comment Paragraph\" )" | |
57 | +msgstr "" | |
58 | + | |
59 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:21 | |
60 | +msgid "Save" | |
61 | +msgstr "" | |
62 | + | |
63 | +#: plugins/comment_paragraph/views/tasks/_approve_comment_accept_details.html.erb:2 | |
64 | +msgid "Title: " | |
65 | +msgstr "" | |
66 | + | |
67 | +#: plugins/comment_paragraph/views/tasks/_approve_comment_accept_details.html.erb:11 | |
68 | +msgid "Paragraph: " | |
69 | +msgstr "" | ... | ... |
... | ... | @@ -0,0 +1,69 @@ |
1 | +# SOME DESCRIPTIVE TITLE. | |
2 | +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER | |
3 | +# This file is distributed under the same license as the PACKAGE package. | |
4 | +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. | |
5 | +# | |
6 | +msgid "" | |
7 | +msgstr "" | |
8 | +"Project-Id-Version: 1.2~rc1-2843-g999a037\n" | |
9 | +"POT-Creation-Date: 2015-08-06 08:53-0300\n" | |
10 | +"PO-Revision-Date: 2015-03-03 07:41-0300\n" | |
11 | +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | |
12 | +"Language-Team: LANGUAGE <LL@li.org>\n" | |
13 | +"Language: \n" | |
14 | +"MIME-Version: 1.0\n" | |
15 | +"Content-Type: text/plain; charset=UTF-8\n" | |
16 | +"Content-Transfer-Encoding: 8bit\n" | |
17 | +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" | |
18 | + | |
19 | +#: plugins/comment_paragraph/controllers/comment_paragraph_plugin_admin_controller.rb:8 | |
20 | +msgid "Settings successfuly saved" | |
21 | +msgstr "Configurações salvas com sucesso" | |
22 | + | |
23 | +#: plugins/comment_paragraph/lib/comment_paragraph_plugin.rb:8 | |
24 | +msgid "A plugin that display comments divided by paragraphs." | |
25 | +msgstr "Um plugin que mostra os comentários por paragráfos" | |
26 | + | |
27 | +#: plugins/comment_paragraph/lib/comment_paragraph_plugin.rb:50 | |
28 | +msgid "Deactivate Comments" | |
29 | +msgstr "Desativar Comentários" | |
30 | + | |
31 | +#: plugins/comment_paragraph/lib/comment_paragraph_plugin.rb:50 | |
32 | +msgid "Activate Comments" | |
33 | +msgstr "Ativar Comentários" | |
34 | + | |
35 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:2 | |
36 | +msgid "Comment Paragraph Plugin Settings" | |
37 | +msgstr "Configurações do Plugin de Comentário por Parágrafos" | |
38 | + | |
39 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:7 | |
40 | +msgid "Activation Mode" | |
41 | +msgstr "Modo de Ativação" | |
42 | + | |
43 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:10 | |
44 | +msgid "Auto" | |
45 | +msgstr "Automático" | |
46 | + | |
47 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:11 | |
48 | +msgid "(all text articles will be activated by default)" | |
49 | +msgstr "(todos os artigos de texto serão ativados por padrão)" | |
50 | + | |
51 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:15 | |
52 | +msgid "Manual" | |
53 | +msgstr "Manual" | |
54 | + | |
55 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:16 | |
56 | +msgid "(click on \"Activate Comment Paragraph\" )" | |
57 | +msgstr "(clicar em \"Ativar Comentário por Parágrafo\")" | |
58 | + | |
59 | +#: plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb:21 | |
60 | +msgid "Save" | |
61 | +msgstr "Salvar" | |
62 | + | |
63 | +#: plugins/comment_paragraph/views/tasks/_approve_comment_accept_details.html.erb:2 | |
64 | +msgid "Title: " | |
65 | +msgstr "Título: " | |
66 | + | |
67 | +#: plugins/comment_paragraph/views/tasks/_approve_comment_accept_details.html.erb:11 | |
68 | +msgid "Paragraph: " | |
69 | +msgstr "Parágrafo: " | ... | ... |
plugins/comment_paragraph/public/comment_paragraph_macro.js
0 → 100644
... | ... | @@ -0,0 +1,237 @@ |
1 | +jQuery(document).ready(function($) { | |
2 | + //Quit if does not detect a comment for that plugin | |
3 | + if($('.comment_paragraph').size() < 1) | |
4 | + return; | |
5 | + | |
6 | + $(document).keyup(function(e) { | |
7 | + // on press ESC key... | |
8 | + if (e.which == 27) { | |
9 | + hideCommentBox(); | |
10 | + } | |
11 | + }); | |
12 | + | |
13 | + $('.display-comment-form').unbind(); | |
14 | + $('.display-comment-form').click(function(){ | |
15 | + var $button = $(this); | |
16 | + showBox($button.parents('.post_comment_box')); | |
17 | + $($button).hide(); | |
18 | + $button.closest('.page-comment-form').find('input').first().focus(); | |
19 | + return false; | |
20 | + }); | |
21 | + | |
22 | + //Clears all old selected_area and selected_content after submit comment | |
23 | + $('[name|=commit]').click(function(){ | |
24 | + $('.selected_area').val(""); | |
25 | + $('.selected_content').val(""); | |
26 | + }); | |
27 | + | |
28 | + //hide comments when click outside | |
29 | + $('body').click(function(event){ | |
30 | + if ($(event.target).closest('.comment-paragraph-plugin, #comment-bubble').length === 0) { | |
31 | + hideCommentBox(); | |
32 | + $('#comment-bubble').removeClass('visible'); | |
33 | + hideAllSelectedAreasExcept(); | |
34 | + } | |
35 | + }); | |
36 | + | |
37 | + function hideCommentBox() { | |
38 | + $("div.side-comment").hide(); | |
39 | + $('.comment-paragraph-plugin').removeClass('comment-paragraph-slide-left'); | |
40 | + $('.comments').removeClass('selected'); | |
41 | + } | |
42 | + | |
43 | + function showBox(div){ | |
44 | + if(div.hasClass('closed')) { | |
45 | + div.removeClass('closed'); | |
46 | + div.addClass('opened'); | |
47 | + } | |
48 | + } | |
49 | + | |
50 | + rangy.init(); | |
51 | + cssApplier = rangy.createCssClassApplier("commented-area", {normalize: false}); | |
52 | + cssApplierSelected = rangy.createCssClassApplier("commented-area-selected", {normalize: false}); | |
53 | + | |
54 | + //Add marked text bubble | |
55 | + $("body").append('\ | |
56 | + <a id="comment-bubble">\ | |
57 | + <div align="center" class="triangle-right" >Comentar</div>\ | |
58 | + </a>'); | |
59 | + | |
60 | + $('.comment-paragraph-plugin .side-comments-counter').click(function(){ | |
61 | + var container = $(this).closest('.comment-paragraph-plugin'); | |
62 | + var paragraphId = container.data('paragraph'); | |
63 | + hideAllSelectedAreasExcept(paragraphId); | |
64 | + hideCommentBox(); | |
65 | + $('#comment-bubble').removeClass('visible'); | |
66 | + container.addClass('comment-paragraph-slide-left selected'); | |
67 | + container.find('.side-comment').show(); | |
68 | + if(!$('body').hasClass('logged-in') && $('meta[name="profile.allow_unauthenticated_comments"]').length == 0) { | |
69 | + container.addClass('require-login-popup'); | |
70 | + } | |
71 | + //Loads the comments | |
72 | + var url = container.find('.side-comment').data('comment_paragraph_url'); | |
73 | + $.ajax(url).done(function(data) { | |
74 | + container.find('.article-comments-list').html(data); | |
75 | + if(container.find('.article-comment').length==0 || container.find('.selected_area').length) { | |
76 | + container.find('.post_comment_box a.display-comment-form').click(); | |
77 | + } else { | |
78 | + container.find('.post_comment_box').removeClass('opened'); | |
79 | + container.find('.post_comment_box').addClass('closed'); | |
80 | + container.find('.display-comment-form').show(); | |
81 | + } | |
82 | + }); | |
83 | + }); | |
84 | + | |
85 | + | |
86 | + $('#comment-bubble').click(function(event){ | |
87 | + var paragraph = $("#comment-bubble").data("paragraph"); | |
88 | + $('#comment-paragraph-plugin_' + paragraph).find('.side-comments-counter').click(); | |
89 | + }); | |
90 | + | |
91 | + function hideAllSelectedAreasExcept(clickedParagraph, areaClass) { | |
92 | + if(!areaClass) { | |
93 | + areaClass = '.commented-area'; | |
94 | + } | |
95 | + $(".comment_paragraph").each(function(){ | |
96 | + paragraph = $(this).closest('.comment-paragraph-plugin').data('paragraph'); | |
97 | + if(paragraph != clickedParagraph){ | |
98 | + $(this).find(areaClass).contents().unwrap(); | |
99 | + $(this).html($(this).html()); //XXX: workaround to prevent creation of text nodes | |
100 | + } | |
101 | + }); | |
102 | + } | |
103 | + | |
104 | + function getSelectionText() { | |
105 | + var text = ""; | |
106 | + if (window.getSelection) { | |
107 | + text = window.getSelection().toString(); | |
108 | + } else if (document.selection && document.selection.type != "Control") { | |
109 | + text = document.selection.createRange().text; | |
110 | + } | |
111 | + return text; | |
112 | + } | |
113 | + | |
114 | + function clearSelection() { | |
115 | + if ( document.selection ) { | |
116 | + document.selection.empty(); | |
117 | + } else if ( window.getSelection ) { | |
118 | + window.getSelection().removeAllRanges(); | |
119 | + } | |
120 | + } | |
121 | + | |
122 | + function setCommentBubblePosition(posX, posY) { | |
123 | + $("#comment-bubble").css({ | |
124 | + top: (posY - 80), | |
125 | + left: (posX - 70) | |
126 | + }); | |
127 | + } | |
128 | + | |
129 | + //highlight area from the paragraph | |
130 | + $('.comment_paragraph').mouseup(function(event) { | |
131 | + | |
132 | + hideCommentBox(); | |
133 | + | |
134 | + //Don't do anything if there is no selected text | |
135 | + if (getSelectionText().length == 0) { | |
136 | + return; | |
137 | + } | |
138 | + | |
139 | + var container = $(this).closest('.comment-paragraph-plugin'); | |
140 | + var paragraphId = container.data('paragraph'); | |
141 | + | |
142 | + setCommentBubblePosition( event.pageX, event.pageY ); | |
143 | + | |
144 | + //Prepare to open the div | |
145 | + $("#comment-bubble").data("paragraph", paragraphId); | |
146 | + $("#comment-bubble").addClass('visible'); | |
147 | + | |
148 | + var rootElement = $(this).get(0); | |
149 | + | |
150 | + //Maybe it is needed to handle exceptions here | |
151 | + try { | |
152 | + var selObj = rangy.getSelection(); | |
153 | + var selected_area = rangy.serializeSelection(selObj, true, rootElement); | |
154 | + } catch(e) { | |
155 | + return; | |
156 | + } | |
157 | + form = container.find('.post_comment_box').find('form'); | |
158 | + | |
159 | + //Register the area that has been selected at input.selected_area | |
160 | + if (form.find('input.selected_area').length === 0){ | |
161 | + $('<input>').attr({ | |
162 | + class: 'selected_area', | |
163 | + type: 'hidden', | |
164 | + name: 'comment[comment_paragraph_selected_area]', | |
165 | + value: selected_area | |
166 | + }).appendTo(form) | |
167 | + }else{ | |
168 | + form.find('input.selected_area').val(selected_area) | |
169 | + } | |
170 | + //Register the content being selected at input.comment_paragraph_selected_content | |
171 | + var selected_content = getSelectionText(); | |
172 | + if (form.find('input.selected_content').length === 0){ | |
173 | + $('<input>').attr({ | |
174 | + class: 'selected_content', | |
175 | + type: 'hidden', | |
176 | + name: 'comment[comment_paragraph_selected_content]', | |
177 | + value: selected_content | |
178 | + }).appendTo(form) | |
179 | + }else{ | |
180 | + form.find('input.selected_content').val(selected_content) | |
181 | + } | |
182 | + rootElement.focus(); | |
183 | + cssApplierSelected.toggleSelection(); | |
184 | + clearSelection(); | |
185 | + | |
186 | + //set a one time handler to prevent multiple selections | |
187 | + var fn = function() { | |
188 | + hideAllSelectedAreasExcept(null, '.commented-area-selected'); | |
189 | + $('.comment-paragraph-plugin').off('mousedown', '.comment_paragraph', fn); | |
190 | + } | |
191 | + $('.comment-paragraph-plugin').on('mousedown', '.comment_paragraph', fn); | |
192 | + }); | |
193 | + | |
194 | + function processAnchor(){ | |
195 | + var anchor = window.location.hash; | |
196 | + if(anchor.length==0) return; | |
197 | + var val = anchor.split('-'); //anchor format = #comment-\d+ | |
198 | + if(val.length!=2 || val[0]!='#comment') return; | |
199 | + if($('.comment-paragraph-plugin').length==0) return; | |
200 | + var comment_id = val[1]; | |
201 | + if(!/^\d+$/.test(comment_id)) return; //test for integer | |
202 | + | |
203 | + var url = '/plugin/comment_paragraph/public/comment_paragraph/'+comment_id; | |
204 | + $.ajax(url).done(function(data) { | |
205 | + var button = $('#comment-paragraph-plugin_' + data.paragraph_uuid + ' .side-comments-counter').click(); | |
206 | + $('body').animate({scrollTop: parseInt(button.offset().top)}, 500); | |
207 | + button.click(); | |
208 | + }); | |
209 | + } | |
210 | + | |
211 | + processAnchor(); | |
212 | + | |
213 | + $(document).on('mouseenter', 'li.article-comment', function() { | |
214 | + hideAllSelectedAreasExcept(null, '.commented-area-selected'); | |
215 | + var selected_area = $(this).find('input.paragraph_comment_area').val(); | |
216 | + var container = $(this).closest('.comment-paragraph-plugin'); | |
217 | + var rootElement = container.find('.comment_paragraph')[0]; | |
218 | + | |
219 | + if(selected_area != ""){ | |
220 | + rangy.deserializeSelection(selected_area, rootElement); | |
221 | + cssApplier.toggleSelection(); | |
222 | + } | |
223 | + }); | |
224 | + | |
225 | + $(document).on('mouseleave', 'li.article-comment', function() { | |
226 | + hideAllSelectedAreasExcept(); | |
227 | + | |
228 | + var container = $(this).closest('.comment-paragraph-plugin'); | |
229 | + var selected_area = container.find('input.selected_area').val(); | |
230 | + var rootElement = container.find('.comment_paragraph')[0]; | |
231 | + if(selected_area != ""){ | |
232 | + rangy.deserializeSelection(selected_area, rootElement); | |
233 | + cssApplierSelected.toggleSelection(); | |
234 | + } | |
235 | + clearSelection(); | |
236 | + }); | |
237 | +}); | ... | ... |
364 Bytes
... | ... | @@ -0,0 +1,94 @@ |
1 | +/* | |
2 | + Rangy, a cross-browser JavaScript range and selection library | |
3 | + http://code.google.com/p/rangy/ | |
4 | + | |
5 | + Copyright 2012, Tim Down | |
6 | + Licensed under the MIT license. | |
7 | + Version: 1.2.3 | |
8 | + Build date: 26 February 2012 | |
9 | +*/ | |
10 | +window.rangy=function(){function l(p,u){var w=typeof p[u];return w=="function"||!!(w=="object"&&p[u])||w=="unknown"}function K(p,u){return!!(typeof p[u]=="object"&&p[u])}function H(p,u){return typeof p[u]!="undefined"}function I(p){return function(u,w){for(var B=w.length;B--;)if(!p(u,w[B]))return false;return true}}function z(p){return p&&A(p,x)&&v(p,t)}function C(p){window.alert("Rangy not supported in your browser. Reason: "+p);c.initialized=true;c.supported=false}function N(){if(!c.initialized){var p, | |
11 | +u=false,w=false;if(l(document,"createRange")){p=document.createRange();if(A(p,n)&&v(p,i))u=true;p.detach()}if((p=K(document,"body")?document.body:document.getElementsByTagName("body")[0])&&l(p,"createTextRange")){p=p.createTextRange();if(z(p))w=true}!u&&!w&&C("Neither Range nor TextRange are implemented");c.initialized=true;c.features={implementsDomRange:u,implementsTextRange:w};u=k.concat(f);w=0;for(p=u.length;w<p;++w)try{u[w](c)}catch(B){K(window,"console")&&l(window.console,"log")&&window.console.log("Init listener threw an exception. Continuing.", | |
12 | +B)}}}function O(p){this.name=p;this.supported=this.initialized=false}var i=["startContainer","startOffset","endContainer","endOffset","collapsed","commonAncestorContainer","START_TO_START","START_TO_END","END_TO_START","END_TO_END"],n=["setStart","setStartBefore","setStartAfter","setEnd","setEndBefore","setEndAfter","collapse","selectNode","selectNodeContents","compareBoundaryPoints","deleteContents","extractContents","cloneContents","insertNode","surroundContents","cloneRange","toString","detach"], | |
13 | +t=["boundingHeight","boundingLeft","boundingTop","boundingWidth","htmlText","text"],x=["collapse","compareEndPoints","duplicate","getBookmark","moveToBookmark","moveToElementText","parentElement","pasteHTML","select","setEndPoint","getBoundingClientRect"],A=I(l),q=I(K),v=I(H),c={version:"1.2.3",initialized:false,supported:true,util:{isHostMethod:l,isHostObject:K,isHostProperty:H,areHostMethods:A,areHostObjects:q,areHostProperties:v,isTextRange:z},features:{},modules:{},config:{alertOnWarn:false,preferTextRange:false}}; | |
14 | +c.fail=C;c.warn=function(p){p="Rangy warning: "+p;if(c.config.alertOnWarn)window.alert(p);else typeof window.console!="undefined"&&typeof window.console.log!="undefined"&&window.console.log(p)};if({}.hasOwnProperty)c.util.extend=function(p,u){for(var w in u)if(u.hasOwnProperty(w))p[w]=u[w]};else C("hasOwnProperty not supported");var f=[],k=[];c.init=N;c.addInitListener=function(p){c.initialized?p(c):f.push(p)};var r=[];c.addCreateMissingNativeApiListener=function(p){r.push(p)};c.createMissingNativeApi= | |
15 | +function(p){p=p||window;N();for(var u=0,w=r.length;u<w;++u)r[u](p)};O.prototype.fail=function(p){this.initialized=true;this.supported=false;throw Error("Module '"+this.name+"' failed to load: "+p);};O.prototype.warn=function(p){c.warn("Module "+this.name+": "+p)};O.prototype.createError=function(p){return Error("Error in Rangy "+this.name+" module: "+p)};c.createModule=function(p,u){var w=new O(p);c.modules[p]=w;k.push(function(B){u(B,w);w.initialized=true;w.supported=true})};c.requireModules=function(p){for(var u= | |
16 | +0,w=p.length,B,V;u<w;++u){V=p[u];B=c.modules[V];if(!B||!(B instanceof O))throw Error("Module '"+V+"' not found");if(!B.supported)throw Error("Module '"+V+"' not supported");}};var L=false;q=function(){if(!L){L=true;c.initialized||N()}};if(typeof window=="undefined")C("No window found");else if(typeof document=="undefined")C("No document found");else{l(document,"addEventListener")&&document.addEventListener("DOMContentLoaded",q,false);if(l(window,"addEventListener"))window.addEventListener("load", | |
17 | +q,false);else l(window,"attachEvent")?window.attachEvent("onload",q):C("Window does not have required addEventListener or attachEvent method");return c}}(); | |
18 | +rangy.createModule("DomUtil",function(l,K){function H(c){for(var f=0;c=c.previousSibling;)f++;return f}function I(c,f){var k=[],r;for(r=c;r;r=r.parentNode)k.push(r);for(r=f;r;r=r.parentNode)if(v(k,r))return r;return null}function z(c,f,k){for(k=k?c:c.parentNode;k;){c=k.parentNode;if(c===f)return k;k=c}return null}function C(c){c=c.nodeType;return c==3||c==4||c==8}function N(c,f){var k=f.nextSibling,r=f.parentNode;k?r.insertBefore(c,k):r.appendChild(c);return c}function O(c){if(c.nodeType==9)return c; | |
19 | +else if(typeof c.ownerDocument!="undefined")return c.ownerDocument;else if(typeof c.document!="undefined")return c.document;else if(c.parentNode)return O(c.parentNode);else throw Error("getDocument: no document found for node");}function i(c){if(!c)return"[No node]";return C(c)?'"'+c.data+'"':c.nodeType==1?"<"+c.nodeName+(c.id?' id="'+c.id+'"':"")+">["+c.childNodes.length+"]":c.nodeName}function n(c){this._next=this.root=c}function t(c,f){this.node=c;this.offset=f}function x(c){this.code=this[c]; | |
20 | +this.codeName=c;this.message="DOMException: "+this.codeName}var A=l.util;A.areHostMethods(document,["createDocumentFragment","createElement","createTextNode"])||K.fail("document missing a Node creation method");A.isHostMethod(document,"getElementsByTagName")||K.fail("document missing getElementsByTagName method");var q=document.createElement("div");A.areHostMethods(q,["insertBefore","appendChild","cloneNode"])||K.fail("Incomplete Element implementation");A.isHostProperty(q,"innerHTML")||K.fail("Element is missing innerHTML property"); | |
21 | +q=document.createTextNode("test");A.areHostMethods(q,["splitText","deleteData","insertData","appendData","cloneNode"])||K.fail("Incomplete Text Node implementation");var v=function(c,f){for(var k=c.length;k--;)if(c[k]===f)return true;return false};n.prototype={_current:null,hasNext:function(){return!!this._next},next:function(){var c=this._current=this._next,f;if(this._current)if(f=c.firstChild)this._next=f;else{for(f=null;c!==this.root&&!(f=c.nextSibling);)c=c.parentNode;this._next=f}return this._current}, | |
22 | +detach:function(){this._current=this._next=this.root=null}};t.prototype={equals:function(c){return this.node===c.node&this.offset==c.offset},inspect:function(){return"[DomPosition("+i(this.node)+":"+this.offset+")]"}};x.prototype={INDEX_SIZE_ERR:1,HIERARCHY_REQUEST_ERR:3,WRONG_DOCUMENT_ERR:4,NO_MODIFICATION_ALLOWED_ERR:7,NOT_FOUND_ERR:8,NOT_SUPPORTED_ERR:9,INVALID_STATE_ERR:11};x.prototype.toString=function(){return this.message};l.dom={arrayContains:v,isHtmlNamespace:function(c){var f;return typeof c.namespaceURI== | |
23 | +"undefined"||(f=c.namespaceURI)===null||f=="http://www.w3.org/1999/xhtml"},parentElement:function(c){c=c.parentNode;return c.nodeType==1?c:null},getNodeIndex:H,getNodeLength:function(c){var f;return C(c)?c.length:(f=c.childNodes)?f.length:0},getCommonAncestor:I,isAncestorOf:function(c,f,k){for(f=k?f:f.parentNode;f;)if(f===c)return true;else f=f.parentNode;return false},getClosestAncestorIn:z,isCharacterDataNode:C,insertAfter:N,splitDataNode:function(c,f){var k=c.cloneNode(false);k.deleteData(0,f); | |
24 | +c.deleteData(f,c.length-f);N(k,c);return k},getDocument:O,getWindow:function(c){c=O(c);if(typeof c.defaultView!="undefined")return c.defaultView;else if(typeof c.parentWindow!="undefined")return c.parentWindow;else throw Error("Cannot get a window object for node");},getIframeWindow:function(c){if(typeof c.contentWindow!="undefined")return c.contentWindow;else if(typeof c.contentDocument!="undefined")return c.contentDocument.defaultView;else throw Error("getIframeWindow: No Window object found for iframe element"); | |
25 | +},getIframeDocument:function(c){if(typeof c.contentDocument!="undefined")return c.contentDocument;else if(typeof c.contentWindow!="undefined")return c.contentWindow.document;else throw Error("getIframeWindow: No Document object found for iframe element");},getBody:function(c){return A.isHostObject(c,"body")?c.body:c.getElementsByTagName("body")[0]},getRootContainer:function(c){for(var f;f=c.parentNode;)c=f;return c},comparePoints:function(c,f,k,r){var L;if(c==k)return f===r?0:f<r?-1:1;else if(L=z(k, | |
26 | +c,true))return f<=H(L)?-1:1;else if(L=z(c,k,true))return H(L)<r?-1:1;else{f=I(c,k);c=c===f?f:z(c,f,true);k=k===f?f:z(k,f,true);if(c===k)throw Error("comparePoints got to case 4 and childA and childB are the same!");else{for(f=f.firstChild;f;){if(f===c)return-1;else if(f===k)return 1;f=f.nextSibling}throw Error("Should not be here!");}}},inspectNode:i,fragmentFromNodeChildren:function(c){for(var f=O(c).createDocumentFragment(),k;k=c.firstChild;)f.appendChild(k);return f},createIterator:function(c){return new n(c)}, | |
27 | +DomPosition:t};l.DOMException=x}); | |
28 | +rangy.createModule("DomRange",function(l){function K(a,e){return a.nodeType!=3&&(g.isAncestorOf(a,e.startContainer,true)||g.isAncestorOf(a,e.endContainer,true))}function H(a){return g.getDocument(a.startContainer)}function I(a,e,j){if(e=a._listeners[e])for(var o=0,E=e.length;o<E;++o)e[o].call(a,{target:a,args:j})}function z(a){return new Z(a.parentNode,g.getNodeIndex(a))}function C(a){return new Z(a.parentNode,g.getNodeIndex(a)+1)}function N(a,e,j){var o=a.nodeType==11?a.firstChild:a;if(g.isCharacterDataNode(e))j== | |
29 | +e.length?g.insertAfter(a,e):e.parentNode.insertBefore(a,j==0?e:g.splitDataNode(e,j));else j>=e.childNodes.length?e.appendChild(a):e.insertBefore(a,e.childNodes[j]);return o}function O(a){for(var e,j,o=H(a.range).createDocumentFragment();j=a.next();){e=a.isPartiallySelectedSubtree();j=j.cloneNode(!e);if(e){e=a.getSubtreeIterator();j.appendChild(O(e));e.detach(true)}if(j.nodeType==10)throw new S("HIERARCHY_REQUEST_ERR");o.appendChild(j)}return o}function i(a,e,j){var o,E;for(j=j||{stop:false};o=a.next();)if(a.isPartiallySelectedSubtree())if(e(o)=== | |
30 | +false){j.stop=true;return}else{o=a.getSubtreeIterator();i(o,e,j);o.detach(true);if(j.stop)return}else for(o=g.createIterator(o);E=o.next();)if(e(E)===false){j.stop=true;return}}function n(a){for(var e;a.next();)if(a.isPartiallySelectedSubtree()){e=a.getSubtreeIterator();n(e);e.detach(true)}else a.remove()}function t(a){for(var e,j=H(a.range).createDocumentFragment(),o;e=a.next();){if(a.isPartiallySelectedSubtree()){e=e.cloneNode(false);o=a.getSubtreeIterator();e.appendChild(t(o));o.detach(true)}else a.remove(); | |
31 | +if(e.nodeType==10)throw new S("HIERARCHY_REQUEST_ERR");j.appendChild(e)}return j}function x(a,e,j){var o=!!(e&&e.length),E,T=!!j;if(o)E=RegExp("^("+e.join("|")+")$");var m=[];i(new q(a,false),function(s){if((!o||E.test(s.nodeType))&&(!T||j(s)))m.push(s)});return m}function A(a){return"["+(typeof a.getName=="undefined"?"Range":a.getName())+"("+g.inspectNode(a.startContainer)+":"+a.startOffset+", "+g.inspectNode(a.endContainer)+":"+a.endOffset+")]"}function q(a,e){this.range=a;this.clonePartiallySelectedTextNodes= | |
32 | +e;if(!a.collapsed){this.sc=a.startContainer;this.so=a.startOffset;this.ec=a.endContainer;this.eo=a.endOffset;var j=a.commonAncestorContainer;if(this.sc===this.ec&&g.isCharacterDataNode(this.sc)){this.isSingleCharacterDataNode=true;this._first=this._last=this._next=this.sc}else{this._first=this._next=this.sc===j&&!g.isCharacterDataNode(this.sc)?this.sc.childNodes[this.so]:g.getClosestAncestorIn(this.sc,j,true);this._last=this.ec===j&&!g.isCharacterDataNode(this.ec)?this.ec.childNodes[this.eo-1]:g.getClosestAncestorIn(this.ec, | |
33 | +j,true)}}}function v(a){this.code=this[a];this.codeName=a;this.message="RangeException: "+this.codeName}function c(a,e,j){this.nodes=x(a,e,j);this._next=this.nodes[0];this._position=0}function f(a){return function(e,j){for(var o,E=j?e:e.parentNode;E;){o=E.nodeType;if(g.arrayContains(a,o))return E;E=E.parentNode}return null}}function k(a,e){if(G(a,e))throw new v("INVALID_NODE_TYPE_ERR");}function r(a){if(!a.startContainer)throw new S("INVALID_STATE_ERR");}function L(a,e){if(!g.arrayContains(e,a.nodeType))throw new v("INVALID_NODE_TYPE_ERR"); | |
34 | +}function p(a,e){if(e<0||e>(g.isCharacterDataNode(a)?a.length:a.childNodes.length))throw new S("INDEX_SIZE_ERR");}function u(a,e){if(h(a,true)!==h(e,true))throw new S("WRONG_DOCUMENT_ERR");}function w(a){if(D(a,true))throw new S("NO_MODIFICATION_ALLOWED_ERR");}function B(a,e){if(!a)throw new S(e);}function V(a){return!!a.startContainer&&!!a.endContainer&&!(!g.arrayContains(ba,a.startContainer.nodeType)&&!h(a.startContainer,true))&&!(!g.arrayContains(ba,a.endContainer.nodeType)&&!h(a.endContainer, | |
35 | +true))&&a.startOffset<=(g.isCharacterDataNode(a.startContainer)?a.startContainer.length:a.startContainer.childNodes.length)&&a.endOffset<=(g.isCharacterDataNode(a.endContainer)?a.endContainer.length:a.endContainer.childNodes.length)}function J(a){r(a);if(!V(a))throw Error("Range error: Range is no longer valid after DOM mutation ("+a.inspect()+")");}function ca(){}function Y(a){a.START_TO_START=ia;a.START_TO_END=la;a.END_TO_END=ra;a.END_TO_START=ma;a.NODE_BEFORE=na;a.NODE_AFTER=oa;a.NODE_BEFORE_AND_AFTER= | |
36 | +pa;a.NODE_INSIDE=ja}function W(a){Y(a);Y(a.prototype)}function da(a,e){return function(){J(this);var j=this.startContainer,o=this.startOffset,E=this.commonAncestorContainer,T=new q(this,true);if(j!==E){j=g.getClosestAncestorIn(j,E,true);o=C(j);j=o.node;o=o.offset}i(T,w);T.reset();E=a(T);T.detach();e(this,j,o,j,o);return E}}function fa(a,e,j){function o(m,s){return function(y){r(this);L(y,$);L(d(y),ba);y=(m?z:C)(y);(s?E:T)(this,y.node,y.offset)}}function E(m,s,y){var F=m.endContainer,Q=m.endOffset; | |
37 | +if(s!==m.startContainer||y!==m.startOffset){if(d(s)!=d(F)||g.comparePoints(s,y,F,Q)==1){F=s;Q=y}e(m,s,y,F,Q)}}function T(m,s,y){var F=m.startContainer,Q=m.startOffset;if(s!==m.endContainer||y!==m.endOffset){if(d(s)!=d(F)||g.comparePoints(s,y,F,Q)==-1){F=s;Q=y}e(m,F,Q,s,y)}}a.prototype=new ca;l.util.extend(a.prototype,{setStart:function(m,s){r(this);k(m,true);p(m,s);E(this,m,s)},setEnd:function(m,s){r(this);k(m,true);p(m,s);T(this,m,s)},setStartBefore:o(true,true),setStartAfter:o(false,true),setEndBefore:o(true, | |
38 | +false),setEndAfter:o(false,false),collapse:function(m){J(this);m?e(this,this.startContainer,this.startOffset,this.startContainer,this.startOffset):e(this,this.endContainer,this.endOffset,this.endContainer,this.endOffset)},selectNodeContents:function(m){r(this);k(m,true);e(this,m,0,m,g.getNodeLength(m))},selectNode:function(m){r(this);k(m,false);L(m,$);var s=z(m);m=C(m);e(this,s.node,s.offset,m.node,m.offset)},extractContents:da(t,e),deleteContents:da(n,e),canSurroundContents:function(){J(this);w(this.startContainer); | |
39 | +w(this.endContainer);var m=new q(this,true),s=m._first&&K(m._first,this)||m._last&&K(m._last,this);m.detach();return!s},detach:function(){j(this)},splitBoundaries:function(){J(this);var m=this.startContainer,s=this.startOffset,y=this.endContainer,F=this.endOffset,Q=m===y;g.isCharacterDataNode(y)&&F>0&&F<y.length&&g.splitDataNode(y,F);if(g.isCharacterDataNode(m)&&s>0&&s<m.length){m=g.splitDataNode(m,s);if(Q){F-=s;y=m}else y==m.parentNode&&F>=g.getNodeIndex(m)&&F++;s=0}e(this,m,s,y,F)},normalizeBoundaries:function(){J(this); | |
40 | +var m=this.startContainer,s=this.startOffset,y=this.endContainer,F=this.endOffset,Q=function(U){var R=U.nextSibling;if(R&&R.nodeType==U.nodeType){y=U;F=U.length;U.appendData(R.data);R.parentNode.removeChild(R)}},qa=function(U){var R=U.previousSibling;if(R&&R.nodeType==U.nodeType){m=U;var sa=U.length;s=R.length;U.insertData(0,R.data);R.parentNode.removeChild(R);if(m==y){F+=s;y=m}else if(y==U.parentNode){R=g.getNodeIndex(U);if(F==R){y=U;F=sa}else F>R&&F--}}},ga=true;if(g.isCharacterDataNode(y))y.length== | |
41 | +F&&Q(y);else{if(F>0)(ga=y.childNodes[F-1])&&g.isCharacterDataNode(ga)&&Q(ga);ga=!this.collapsed}if(ga)if(g.isCharacterDataNode(m))s==0&&qa(m);else{if(s<m.childNodes.length)(Q=m.childNodes[s])&&g.isCharacterDataNode(Q)&&qa(Q)}else{m=y;s=F}e(this,m,s,y,F)},collapseToPoint:function(m,s){r(this);k(m,true);p(m,s);if(m!==this.startContainer||s!==this.startOffset||m!==this.endContainer||s!==this.endOffset)e(this,m,s,m,s)}});W(a)}function ea(a){a.collapsed=a.startContainer===a.endContainer&&a.startOffset=== | |
42 | +a.endOffset;a.commonAncestorContainer=a.collapsed?a.startContainer:g.getCommonAncestor(a.startContainer,a.endContainer)}function ha(a,e,j,o,E){var T=a.startContainer!==e||a.startOffset!==j,m=a.endContainer!==o||a.endOffset!==E;a.startContainer=e;a.startOffset=j;a.endContainer=o;a.endOffset=E;ea(a);I(a,"boundarychange",{startMoved:T,endMoved:m})}function M(a){this.startContainer=a;this.startOffset=0;this.endContainer=a;this.endOffset=0;this._listeners={boundarychange:[],detach:[]};ea(this)}l.requireModules(["DomUtil"]); | |
43 | +var g=l.dom,Z=g.DomPosition,S=l.DOMException;q.prototype={_current:null,_next:null,_first:null,_last:null,isSingleCharacterDataNode:false,reset:function(){this._current=null;this._next=this._first},hasNext:function(){return!!this._next},next:function(){var a=this._current=this._next;if(a){this._next=a!==this._last?a.nextSibling:null;if(g.isCharacterDataNode(a)&&this.clonePartiallySelectedTextNodes){if(a===this.ec)(a=a.cloneNode(true)).deleteData(this.eo,a.length-this.eo);if(this._current===this.sc)(a= | |
44 | +a.cloneNode(true)).deleteData(0,this.so)}}return a},remove:function(){var a=this._current,e,j;if(g.isCharacterDataNode(a)&&(a===this.sc||a===this.ec)){e=a===this.sc?this.so:0;j=a===this.ec?this.eo:a.length;e!=j&&a.deleteData(e,j-e)}else a.parentNode&&a.parentNode.removeChild(a)},isPartiallySelectedSubtree:function(){return K(this._current,this.range)},getSubtreeIterator:function(){var a;if(this.isSingleCharacterDataNode){a=this.range.cloneRange();a.collapse()}else{a=new M(H(this.range));var e=this._current, | |
45 | +j=e,o=0,E=e,T=g.getNodeLength(e);if(g.isAncestorOf(e,this.sc,true)){j=this.sc;o=this.so}if(g.isAncestorOf(e,this.ec,true)){E=this.ec;T=this.eo}ha(a,j,o,E,T)}return new q(a,this.clonePartiallySelectedTextNodes)},detach:function(a){a&&this.range.detach();this.range=this._current=this._next=this._first=this._last=this.sc=this.so=this.ec=this.eo=null}};v.prototype={BAD_BOUNDARYPOINTS_ERR:1,INVALID_NODE_TYPE_ERR:2};v.prototype.toString=function(){return this.message};c.prototype={_current:null,hasNext:function(){return!!this._next}, | |
46 | +next:function(){this._current=this._next;this._next=this.nodes[++this._position];return this._current},detach:function(){this._current=this._next=this.nodes=null}};var $=[1,3,4,5,7,8,10],ba=[2,9,11],aa=[1,3,4,5,7,8,10,11],b=[1,3,4,5,7,8],d=g.getRootContainer,h=f([9,11]),D=f([5,6,10,12]),G=f([6,10,12]),P=document.createElement("style"),X=false;try{P.innerHTML="<b>x</b>";X=P.firstChild.nodeType==3}catch(ta){}l.features.htmlParsingConforms=X;var ka=["startContainer","startOffset","endContainer","endOffset", | |
47 | +"collapsed","commonAncestorContainer"],ia=0,la=1,ra=2,ma=3,na=0,oa=1,pa=2,ja=3;ca.prototype={attachListener:function(a,e){this._listeners[a].push(e)},compareBoundaryPoints:function(a,e){J(this);u(this.startContainer,e.startContainer);var j=a==ma||a==ia?"start":"end",o=a==la||a==ia?"start":"end";return g.comparePoints(this[j+"Container"],this[j+"Offset"],e[o+"Container"],e[o+"Offset"])},insertNode:function(a){J(this);L(a,aa);w(this.startContainer);if(g.isAncestorOf(a,this.startContainer,true))throw new S("HIERARCHY_REQUEST_ERR"); | |
48 | +this.setStartBefore(N(a,this.startContainer,this.startOffset))},cloneContents:function(){J(this);var a,e;if(this.collapsed)return H(this).createDocumentFragment();else{if(this.startContainer===this.endContainer&&g.isCharacterDataNode(this.startContainer)){a=this.startContainer.cloneNode(true);a.data=a.data.slice(this.startOffset,this.endOffset);e=H(this).createDocumentFragment();e.appendChild(a);return e}else{e=new q(this,true);a=O(e);e.detach()}return a}},canSurroundContents:function(){J(this);w(this.startContainer); | |
49 | +w(this.endContainer);var a=new q(this,true),e=a._first&&K(a._first,this)||a._last&&K(a._last,this);a.detach();return!e},surroundContents:function(a){L(a,b);if(!this.canSurroundContents())throw new v("BAD_BOUNDARYPOINTS_ERR");var e=this.extractContents();if(a.hasChildNodes())for(;a.lastChild;)a.removeChild(a.lastChild);N(a,this.startContainer,this.startOffset);a.appendChild(e);this.selectNode(a)},cloneRange:function(){J(this);for(var a=new M(H(this)),e=ka.length,j;e--;){j=ka[e];a[j]=this[j]}return a}, | |
50 | +toString:function(){J(this);var a=this.startContainer;if(a===this.endContainer&&g.isCharacterDataNode(a))return a.nodeType==3||a.nodeType==4?a.data.slice(this.startOffset,this.endOffset):"";else{var e=[];a=new q(this,true);i(a,function(j){if(j.nodeType==3||j.nodeType==4)e.push(j.data)});a.detach();return e.join("")}},compareNode:function(a){J(this);var e=a.parentNode,j=g.getNodeIndex(a);if(!e)throw new S("NOT_FOUND_ERR");a=this.comparePoint(e,j);e=this.comparePoint(e,j+1);return a<0?e>0?pa:na:e>0? | |
51 | +oa:ja},comparePoint:function(a,e){J(this);B(a,"HIERARCHY_REQUEST_ERR");u(a,this.startContainer);if(g.comparePoints(a,e,this.startContainer,this.startOffset)<0)return-1;else if(g.comparePoints(a,e,this.endContainer,this.endOffset)>0)return 1;return 0},createContextualFragment:X?function(a){var e=this.startContainer,j=g.getDocument(e);if(!e)throw new S("INVALID_STATE_ERR");var o=null;if(e.nodeType==1)o=e;else if(g.isCharacterDataNode(e))o=g.parentElement(e);o=o===null||o.nodeName=="HTML"&&g.isHtmlNamespace(g.getDocument(o).documentElement)&& | |
52 | +g.isHtmlNamespace(o)?j.createElement("body"):o.cloneNode(false);o.innerHTML=a;return g.fragmentFromNodeChildren(o)}:function(a){r(this);var e=H(this).createElement("body");e.innerHTML=a;return g.fragmentFromNodeChildren(e)},toHtml:function(){J(this);var a=H(this).createElement("div");a.appendChild(this.cloneContents());return a.innerHTML},intersectsNode:function(a,e){J(this);B(a,"NOT_FOUND_ERR");if(g.getDocument(a)!==H(this))return false;var j=a.parentNode,o=g.getNodeIndex(a);B(j,"NOT_FOUND_ERR"); | |
53 | +var E=g.comparePoints(j,o,this.endContainer,this.endOffset);j=g.comparePoints(j,o+1,this.startContainer,this.startOffset);return e?E<=0&&j>=0:E<0&&j>0},isPointInRange:function(a,e){J(this);B(a,"HIERARCHY_REQUEST_ERR");u(a,this.startContainer);return g.comparePoints(a,e,this.startContainer,this.startOffset)>=0&&g.comparePoints(a,e,this.endContainer,this.endOffset)<=0},intersectsRange:function(a,e){J(this);if(H(a)!=H(this))throw new S("WRONG_DOCUMENT_ERR");var j=g.comparePoints(this.startContainer, | |
54 | +this.startOffset,a.endContainer,a.endOffset),o=g.comparePoints(this.endContainer,this.endOffset,a.startContainer,a.startOffset);return e?j<=0&&o>=0:j<0&&o>0},intersection:function(a){if(this.intersectsRange(a)){var e=g.comparePoints(this.startContainer,this.startOffset,a.startContainer,a.startOffset),j=g.comparePoints(this.endContainer,this.endOffset,a.endContainer,a.endOffset),o=this.cloneRange();e==-1&&o.setStart(a.startContainer,a.startOffset);j==1&&o.setEnd(a.endContainer,a.endOffset);return o}return null}, | |
55 | +union:function(a){if(this.intersectsRange(a,true)){var e=this.cloneRange();g.comparePoints(a.startContainer,a.startOffset,this.startContainer,this.startOffset)==-1&&e.setStart(a.startContainer,a.startOffset);g.comparePoints(a.endContainer,a.endOffset,this.endContainer,this.endOffset)==1&&e.setEnd(a.endContainer,a.endOffset);return e}else throw new v("Ranges do not intersect");},containsNode:function(a,e){return e?this.intersectsNode(a,false):this.compareNode(a)==ja},containsNodeContents:function(a){return this.comparePoint(a, | |
56 | +0)>=0&&this.comparePoint(a,g.getNodeLength(a))<=0},containsRange:function(a){return this.intersection(a).equals(a)},containsNodeText:function(a){var e=this.cloneRange();e.selectNode(a);var j=e.getNodes([3]);if(j.length>0){e.setStart(j[0],0);a=j.pop();e.setEnd(a,a.length);a=this.containsRange(e);e.detach();return a}else return this.containsNodeContents(a)},createNodeIterator:function(a,e){J(this);return new c(this,a,e)},getNodes:function(a,e){J(this);return x(this,a,e)},getDocument:function(){return H(this)}, | |
57 | +collapseBefore:function(a){r(this);this.setEndBefore(a);this.collapse(false)},collapseAfter:function(a){r(this);this.setStartAfter(a);this.collapse(true)},getName:function(){return"DomRange"},equals:function(a){return M.rangesEqual(this,a)},isValid:function(){return V(this)},inspect:function(){return A(this)}};fa(M,ha,function(a){r(a);a.startContainer=a.startOffset=a.endContainer=a.endOffset=null;a.collapsed=a.commonAncestorContainer=null;I(a,"detach",null);a._listeners=null});l.rangePrototype=ca.prototype; | |
58 | +M.rangeProperties=ka;M.RangeIterator=q;M.copyComparisonConstants=W;M.createPrototypeRange=fa;M.inspect=A;M.getRangeDocument=H;M.rangesEqual=function(a,e){return a.startContainer===e.startContainer&&a.startOffset===e.startOffset&&a.endContainer===e.endContainer&&a.endOffset===e.endOffset};l.DomRange=M;l.RangeException=v}); | |
59 | +rangy.createModule("WrappedRange",function(l){function K(i,n,t,x){var A=i.duplicate();A.collapse(t);var q=A.parentElement();z.isAncestorOf(n,q,true)||(q=n);if(!q.canHaveHTML)return new C(q.parentNode,z.getNodeIndex(q));n=z.getDocument(q).createElement("span");var v,c=t?"StartToStart":"StartToEnd";do{q.insertBefore(n,n.previousSibling);A.moveToElementText(n)}while((v=A.compareEndPoints(c,i))>0&&n.previousSibling);c=n.nextSibling;if(v==-1&&c&&z.isCharacterDataNode(c)){A.setEndPoint(t?"EndToStart":"EndToEnd", | |
60 | +i);if(/[\r\n]/.test(c.data)){q=A.duplicate();t=q.text.replace(/\r\n/g,"\r").length;for(t=q.moveStart("character",t);q.compareEndPoints("StartToEnd",q)==-1;){t++;q.moveStart("character",1)}}else t=A.text.length;q=new C(c,t)}else{c=(x||!t)&&n.previousSibling;q=(t=(x||t)&&n.nextSibling)&&z.isCharacterDataNode(t)?new C(t,0):c&&z.isCharacterDataNode(c)?new C(c,c.length):new C(q,z.getNodeIndex(n))}n.parentNode.removeChild(n);return q}function H(i,n){var t,x,A=i.offset,q=z.getDocument(i.node),v=q.body.createTextRange(), | |
61 | +c=z.isCharacterDataNode(i.node);if(c){t=i.node;x=t.parentNode}else{t=i.node.childNodes;t=A<t.length?t[A]:null;x=i.node}q=q.createElement("span");q.innerHTML="&#feff;";t?x.insertBefore(q,t):x.appendChild(q);v.moveToElementText(q);v.collapse(!n);x.removeChild(q);if(c)v[n?"moveStart":"moveEnd"]("character",A);return v}l.requireModules(["DomUtil","DomRange"]);var I,z=l.dom,C=z.DomPosition,N=l.DomRange;if(l.features.implementsDomRange&&(!l.features.implementsTextRange||!l.config.preferTextRange)){(function(){function i(f){for(var k= | |
62 | +t.length,r;k--;){r=t[k];f[r]=f.nativeRange[r]}}var n,t=N.rangeProperties,x,A;I=function(f){if(!f)throw Error("Range must be specified");this.nativeRange=f;i(this)};N.createPrototypeRange(I,function(f,k,r,L,p){var u=f.endContainer!==L||f.endOffset!=p;if(f.startContainer!==k||f.startOffset!=r||u){f.setEnd(L,p);f.setStart(k,r)}},function(f){f.nativeRange.detach();f.detached=true;for(var k=t.length,r;k--;){r=t[k];f[r]=null}});n=I.prototype;n.selectNode=function(f){this.nativeRange.selectNode(f);i(this)}; | |
63 | +n.deleteContents=function(){this.nativeRange.deleteContents();i(this)};n.extractContents=function(){var f=this.nativeRange.extractContents();i(this);return f};n.cloneContents=function(){return this.nativeRange.cloneContents()};n.surroundContents=function(f){this.nativeRange.surroundContents(f);i(this)};n.collapse=function(f){this.nativeRange.collapse(f);i(this)};n.cloneRange=function(){return new I(this.nativeRange.cloneRange())};n.refresh=function(){i(this)};n.toString=function(){return this.nativeRange.toString()}; | |
64 | +var q=document.createTextNode("test");z.getBody(document).appendChild(q);var v=document.createRange();v.setStart(q,0);v.setEnd(q,0);try{v.setStart(q,1);x=true;n.setStart=function(f,k){this.nativeRange.setStart(f,k);i(this)};n.setEnd=function(f,k){this.nativeRange.setEnd(f,k);i(this)};A=function(f){return function(k){this.nativeRange[f](k);i(this)}}}catch(c){x=false;n.setStart=function(f,k){try{this.nativeRange.setStart(f,k)}catch(r){this.nativeRange.setEnd(f,k);this.nativeRange.setStart(f,k)}i(this)}; | |
65 | +n.setEnd=function(f,k){try{this.nativeRange.setEnd(f,k)}catch(r){this.nativeRange.setStart(f,k);this.nativeRange.setEnd(f,k)}i(this)};A=function(f,k){return function(r){try{this.nativeRange[f](r)}catch(L){this.nativeRange[k](r);this.nativeRange[f](r)}i(this)}}}n.setStartBefore=A("setStartBefore","setEndBefore");n.setStartAfter=A("setStartAfter","setEndAfter");n.setEndBefore=A("setEndBefore","setStartBefore");n.setEndAfter=A("setEndAfter","setStartAfter");v.selectNodeContents(q);n.selectNodeContents= | |
66 | +v.startContainer==q&&v.endContainer==q&&v.startOffset==0&&v.endOffset==q.length?function(f){this.nativeRange.selectNodeContents(f);i(this)}:function(f){this.setStart(f,0);this.setEnd(f,N.getEndOffset(f))};v.selectNodeContents(q);v.setEnd(q,3);x=document.createRange();x.selectNodeContents(q);x.setEnd(q,4);x.setStart(q,2);n.compareBoundaryPoints=v.compareBoundaryPoints(v.START_TO_END,x)==-1&v.compareBoundaryPoints(v.END_TO_START,x)==1?function(f,k){k=k.nativeRange||k;if(f==k.START_TO_END)f=k.END_TO_START; | |
67 | +else if(f==k.END_TO_START)f=k.START_TO_END;return this.nativeRange.compareBoundaryPoints(f,k)}:function(f,k){return this.nativeRange.compareBoundaryPoints(f,k.nativeRange||k)};if(l.util.isHostMethod(v,"createContextualFragment"))n.createContextualFragment=function(f){return this.nativeRange.createContextualFragment(f)};z.getBody(document).removeChild(q);v.detach();x.detach()})();l.createNativeRange=function(i){i=i||document;return i.createRange()}}else if(l.features.implementsTextRange){I=function(i){this.textRange= | |
68 | +i;this.refresh()};I.prototype=new N(document);I.prototype.refresh=function(){var i,n,t=this.textRange;i=t.parentElement();var x=t.duplicate();x.collapse(true);n=x.parentElement();x=t.duplicate();x.collapse(false);t=x.parentElement();n=n==t?n:z.getCommonAncestor(n,t);n=n==i?n:z.getCommonAncestor(i,n);if(this.textRange.compareEndPoints("StartToEnd",this.textRange)==0)n=i=K(this.textRange,n,true,true);else{i=K(this.textRange,n,true,false);n=K(this.textRange,n,false,false)}this.setStart(i.node,i.offset); | |
69 | +this.setEnd(n.node,n.offset)};N.copyComparisonConstants(I);var O=function(){return this}();if(typeof O.Range=="undefined")O.Range=I;l.createNativeRange=function(i){i=i||document;return i.body.createTextRange()}}if(l.features.implementsTextRange)I.rangeToTextRange=function(i){if(i.collapsed)return H(new C(i.startContainer,i.startOffset),true);else{var n=H(new C(i.startContainer,i.startOffset),true),t=H(new C(i.endContainer,i.endOffset),false);i=z.getDocument(i.startContainer).body.createTextRange(); | |
70 | +i.setEndPoint("StartToStart",n);i.setEndPoint("EndToEnd",t);return i}};I.prototype.getName=function(){return"WrappedRange"};l.WrappedRange=I;l.createRange=function(i){i=i||document;return new I(l.createNativeRange(i))};l.createRangyRange=function(i){i=i||document;return new N(i)};l.createIframeRange=function(i){return l.createRange(z.getIframeDocument(i))};l.createIframeRangyRange=function(i){return l.createRangyRange(z.getIframeDocument(i))};l.addCreateMissingNativeApiListener(function(i){i=i.document; | |
71 | +if(typeof i.createRange=="undefined")i.createRange=function(){return l.createRange(this)};i=i=null})}); | |
72 | +rangy.createModule("WrappedSelection",function(l,K){function H(b){return(b||window).getSelection()}function I(b){return(b||window).document.selection}function z(b,d,h){var D=h?"end":"start";h=h?"start":"end";b.anchorNode=d[D+"Container"];b.anchorOffset=d[D+"Offset"];b.focusNode=d[h+"Container"];b.focusOffset=d[h+"Offset"]}function C(b){b.anchorNode=b.focusNode=null;b.anchorOffset=b.focusOffset=0;b.rangeCount=0;b.isCollapsed=true;b._ranges.length=0}function N(b){var d;if(b instanceof k){d=b._selectionNativeRange; | |
73 | +if(!d){d=l.createNativeRange(c.getDocument(b.startContainer));d.setEnd(b.endContainer,b.endOffset);d.setStart(b.startContainer,b.startOffset);b._selectionNativeRange=d;b.attachListener("detach",function(){this._selectionNativeRange=null})}}else if(b instanceof r)d=b.nativeRange;else if(l.features.implementsDomRange&&b instanceof c.getWindow(b.startContainer).Range)d=b;return d}function O(b){var d=b.getNodes(),h;a:if(!d.length||d[0].nodeType!=1)h=false;else{h=1;for(var D=d.length;h<D;++h)if(!c.isAncestorOf(d[0], | |
74 | +d[h])){h=false;break a}h=true}if(!h)throw Error("getSingleElementFromRange: range "+b.inspect()+" did not consist of a single element");return d[0]}function i(b,d){var h=new r(d);b._ranges=[h];z(b,h,false);b.rangeCount=1;b.isCollapsed=h.collapsed}function n(b){b._ranges.length=0;if(b.docSelection.type=="None")C(b);else{var d=b.docSelection.createRange();if(d&&typeof d.text!="undefined")i(b,d);else{b.rangeCount=d.length;for(var h,D=c.getDocument(d.item(0)),G=0;G<b.rangeCount;++G){h=l.createRange(D); | |
75 | +h.selectNode(d.item(G));b._ranges.push(h)}b.isCollapsed=b.rangeCount==1&&b._ranges[0].collapsed;z(b,b._ranges[b.rangeCount-1],false)}}}function t(b,d){var h=b.docSelection.createRange(),D=O(d),G=c.getDocument(h.item(0));G=c.getBody(G).createControlRange();for(var P=0,X=h.length;P<X;++P)G.add(h.item(P));try{G.add(D)}catch(ta){throw Error("addRange(): Element within the specified Range could not be added to control selection (does it have layout?)");}G.select();n(b)}function x(b,d,h){this.nativeSelection= | |
76 | +b;this.docSelection=d;this._ranges=[];this.win=h;this.refresh()}function A(b,d){var h=c.getDocument(d[0].startContainer);h=c.getBody(h).createControlRange();for(var D=0,G;D<rangeCount;++D){G=O(d[D]);try{h.add(G)}catch(P){throw Error("setRanges(): Element within the one of the specified Ranges could not be added to control selection (does it have layout?)");}}h.select();n(b)}function q(b,d){if(b.anchorNode&&c.getDocument(b.anchorNode)!==c.getDocument(d))throw new L("WRONG_DOCUMENT_ERR");}function v(b){var d= | |
77 | +[],h=new p(b.anchorNode,b.anchorOffset),D=new p(b.focusNode,b.focusOffset),G=typeof b.getName=="function"?b.getName():"Selection";if(typeof b.rangeCount!="undefined")for(var P=0,X=b.rangeCount;P<X;++P)d[P]=k.inspect(b.getRangeAt(P));return"["+G+"(Ranges: "+d.join(", ")+")(anchor: "+h.inspect()+", focus: "+D.inspect()+"]"}l.requireModules(["DomUtil","DomRange","WrappedRange"]);l.config.checkSelectionRanges=true;var c=l.dom,f=l.util,k=l.DomRange,r=l.WrappedRange,L=l.DOMException,p=c.DomPosition,u,w, | |
78 | +B=l.util.isHostMethod(window,"getSelection"),V=l.util.isHostObject(document,"selection"),J=V&&(!B||l.config.preferTextRange);if(J){u=I;l.isSelectionValid=function(b){b=(b||window).document;var d=b.selection;return d.type!="None"||c.getDocument(d.createRange().parentElement())==b}}else if(B){u=H;l.isSelectionValid=function(){return true}}else K.fail("Neither document.selection or window.getSelection() detected.");l.getNativeSelection=u;B=u();var ca=l.createNativeRange(document),Y=c.getBody(document), | |
79 | +W=f.areHostObjects(B,f.areHostProperties(B,["anchorOffset","focusOffset"]));l.features.selectionHasAnchorAndFocus=W;var da=f.isHostMethod(B,"extend");l.features.selectionHasExtend=da;var fa=typeof B.rangeCount=="number";l.features.selectionHasRangeCount=fa;var ea=false,ha=true;f.areHostMethods(B,["addRange","getRangeAt","removeAllRanges"])&&typeof B.rangeCount=="number"&&l.features.implementsDomRange&&function(){var b=document.createElement("iframe");b.frameBorder=0;b.style.position="absolute";b.style.left= | |
80 | +"-10000px";Y.appendChild(b);var d=c.getIframeDocument(b);d.open();d.write("<html><head></head><body>12</body></html>");d.close();var h=c.getIframeWindow(b).getSelection(),D=d.documentElement.lastChild.firstChild;d=d.createRange();d.setStart(D,1);d.collapse(true);h.addRange(d);ha=h.rangeCount==1;h.removeAllRanges();var G=d.cloneRange();d.setStart(D,0);G.setEnd(D,2);h.addRange(d);h.addRange(G);ea=h.rangeCount==2;d.detach();G.detach();Y.removeChild(b)}();l.features.selectionSupportsMultipleRanges=ea; | |
81 | +l.features.collapsedNonEditableSelectionsSupported=ha;var M=false,g;if(Y&&f.isHostMethod(Y,"createControlRange")){g=Y.createControlRange();if(f.areHostProperties(g,["item","add"]))M=true}l.features.implementsControlRange=M;w=W?function(b){return b.anchorNode===b.focusNode&&b.anchorOffset===b.focusOffset}:function(b){return b.rangeCount?b.getRangeAt(b.rangeCount-1).collapsed:false};var Z;if(f.isHostMethod(B,"getRangeAt"))Z=function(b,d){try{return b.getRangeAt(d)}catch(h){return null}};else if(W)Z= | |
82 | +function(b){var d=c.getDocument(b.anchorNode);d=l.createRange(d);d.setStart(b.anchorNode,b.anchorOffset);d.setEnd(b.focusNode,b.focusOffset);if(d.collapsed!==this.isCollapsed){d.setStart(b.focusNode,b.focusOffset);d.setEnd(b.anchorNode,b.anchorOffset)}return d};l.getSelection=function(b){b=b||window;var d=b._rangySelection,h=u(b),D=V?I(b):null;if(d){d.nativeSelection=h;d.docSelection=D;d.refresh(b)}else{d=new x(h,D,b);b._rangySelection=d}return d};l.getIframeSelection=function(b){return l.getSelection(c.getIframeWindow(b))}; | |
83 | +g=x.prototype;if(!J&&W&&f.areHostMethods(B,["removeAllRanges","addRange"])){g.removeAllRanges=function(){this.nativeSelection.removeAllRanges();C(this)};var S=function(b,d){var h=k.getRangeDocument(d);h=l.createRange(h);h.collapseToPoint(d.endContainer,d.endOffset);b.nativeSelection.addRange(N(h));b.nativeSelection.extend(d.startContainer,d.startOffset);b.refresh()};g.addRange=fa?function(b,d){if(M&&V&&this.docSelection.type=="Control")t(this,b);else if(d&&da)S(this,b);else{var h;if(ea)h=this.rangeCount; | |
84 | +else{this.removeAllRanges();h=0}this.nativeSelection.addRange(N(b));this.rangeCount=this.nativeSelection.rangeCount;if(this.rangeCount==h+1){if(l.config.checkSelectionRanges)if((h=Z(this.nativeSelection,this.rangeCount-1))&&!k.rangesEqual(h,b))b=new r(h);this._ranges[this.rangeCount-1]=b;z(this,b,aa(this.nativeSelection));this.isCollapsed=w(this)}else this.refresh()}}:function(b,d){if(d&&da)S(this,b);else{this.nativeSelection.addRange(N(b));this.refresh()}};g.setRanges=function(b){if(M&&b.length> | |
85 | +1)A(this,b);else{this.removeAllRanges();for(var d=0,h=b.length;d<h;++d)this.addRange(b[d])}}}else if(f.isHostMethod(B,"empty")&&f.isHostMethod(ca,"select")&&M&&J){g.removeAllRanges=function(){try{this.docSelection.empty();if(this.docSelection.type!="None"){var b;if(this.anchorNode)b=c.getDocument(this.anchorNode);else if(this.docSelection.type=="Control"){var d=this.docSelection.createRange();if(d.length)b=c.getDocument(d.item(0)).body.createTextRange()}if(b){b.body.createTextRange().select();this.docSelection.empty()}}}catch(h){}C(this)}; | |
86 | +g.addRange=function(b){if(this.docSelection.type=="Control")t(this,b);else{r.rangeToTextRange(b).select();this._ranges[0]=b;this.rangeCount=1;this.isCollapsed=this._ranges[0].collapsed;z(this,b,false)}};g.setRanges=function(b){this.removeAllRanges();var d=b.length;if(d>1)A(this,b);else d&&this.addRange(b[0])}}else{K.fail("No means of selecting a Range or TextRange was found");return false}g.getRangeAt=function(b){if(b<0||b>=this.rangeCount)throw new L("INDEX_SIZE_ERR");else return this._ranges[b]}; | |
87 | +var $;if(J)$=function(b){var d;if(l.isSelectionValid(b.win))d=b.docSelection.createRange();else{d=c.getBody(b.win.document).createTextRange();d.collapse(true)}if(b.docSelection.type=="Control")n(b);else d&&typeof d.text!="undefined"?i(b,d):C(b)};else if(f.isHostMethod(B,"getRangeAt")&&typeof B.rangeCount=="number")$=function(b){if(M&&V&&b.docSelection.type=="Control")n(b);else{b._ranges.length=b.rangeCount=b.nativeSelection.rangeCount;if(b.rangeCount){for(var d=0,h=b.rangeCount;d<h;++d)b._ranges[d]= | |
88 | +new l.WrappedRange(b.nativeSelection.getRangeAt(d));z(b,b._ranges[b.rangeCount-1],aa(b.nativeSelection));b.isCollapsed=w(b)}else C(b)}};else if(W&&typeof B.isCollapsed=="boolean"&&typeof ca.collapsed=="boolean"&&l.features.implementsDomRange)$=function(b){var d;d=b.nativeSelection;if(d.anchorNode){d=Z(d,0);b._ranges=[d];b.rangeCount=1;d=b.nativeSelection;b.anchorNode=d.anchorNode;b.anchorOffset=d.anchorOffset;b.focusNode=d.focusNode;b.focusOffset=d.focusOffset;b.isCollapsed=w(b)}else C(b)};else{K.fail("No means of obtaining a Range or TextRange from the user's selection was found"); | |
89 | +return false}g.refresh=function(b){var d=b?this._ranges.slice(0):null;$(this);if(b){b=d.length;if(b!=this._ranges.length)return false;for(;b--;)if(!k.rangesEqual(d[b],this._ranges[b]))return false;return true}};var ba=function(b,d){var h=b.getAllRanges(),D=false;b.removeAllRanges();for(var G=0,P=h.length;G<P;++G)if(D||d!==h[G])b.addRange(h[G]);else D=true;b.rangeCount||C(b)};g.removeRange=M?function(b){if(this.docSelection.type=="Control"){var d=this.docSelection.createRange();b=O(b);var h=c.getDocument(d.item(0)); | |
90 | +h=c.getBody(h).createControlRange();for(var D,G=false,P=0,X=d.length;P<X;++P){D=d.item(P);if(D!==b||G)h.add(d.item(P));else G=true}h.select();n(this)}else ba(this,b)}:function(b){ba(this,b)};var aa;if(!J&&W&&l.features.implementsDomRange){aa=function(b){var d=false;if(b.anchorNode)d=c.comparePoints(b.anchorNode,b.anchorOffset,b.focusNode,b.focusOffset)==1;return d};g.isBackwards=function(){return aa(this)}}else aa=g.isBackwards=function(){return false};g.toString=function(){for(var b=[],d=0,h=this.rangeCount;d< | |
91 | +h;++d)b[d]=""+this._ranges[d];return b.join("")};g.collapse=function(b,d){q(this,b);var h=l.createRange(c.getDocument(b));h.collapseToPoint(b,d);this.removeAllRanges();this.addRange(h);this.isCollapsed=true};g.collapseToStart=function(){if(this.rangeCount){var b=this._ranges[0];this.collapse(b.startContainer,b.startOffset)}else throw new L("INVALID_STATE_ERR");};g.collapseToEnd=function(){if(this.rangeCount){var b=this._ranges[this.rangeCount-1];this.collapse(b.endContainer,b.endOffset)}else throw new L("INVALID_STATE_ERR"); | |
92 | +};g.selectAllChildren=function(b){q(this,b);var d=l.createRange(c.getDocument(b));d.selectNodeContents(b);this.removeAllRanges();this.addRange(d)};g.deleteFromDocument=function(){if(M&&V&&this.docSelection.type=="Control"){for(var b=this.docSelection.createRange(),d;b.length;){d=b.item(0);b.remove(d);d.parentNode.removeChild(d)}this.refresh()}else if(this.rangeCount){b=this.getAllRanges();this.removeAllRanges();d=0;for(var h=b.length;d<h;++d)b[d].deleteContents();this.addRange(b[h-1])}};g.getAllRanges= | |
93 | +function(){return this._ranges.slice(0)};g.setSingleRange=function(b){this.setRanges([b])};g.containsNode=function(b,d){for(var h=0,D=this._ranges.length;h<D;++h)if(this._ranges[h].containsNode(b,d))return true;return false};g.toHtml=function(){var b="";if(this.rangeCount){b=k.getRangeDocument(this._ranges[0]).createElement("div");for(var d=0,h=this._ranges.length;d<h;++d)b.appendChild(this._ranges[d].cloneContents());b=b.innerHTML}return b};g.getName=function(){return"WrappedSelection"};g.inspect= | |
94 | +function(){return v(this)};g.detach=function(){this.win=this.anchorNode=this.focusNode=this.win._rangySelection=null};x.inspect=v;l.Selection=x;l.selectionPrototype=g;l.addCreateMissingNativeApiListener(function(b){if(typeof b.getSelection=="undefined")b.getSelection=function(){return l.getSelection(this)};b=null})}); | |
0 | 95 | \ No newline at end of file | ... | ... |
plugins/comment_paragraph/public/rangy-cssclassapplier.js
0 → 100644
... | ... | @@ -0,0 +1,32 @@ |
1 | +/* | |
2 | + CSS Class Applier module for Rangy. | |
3 | + Adds, removes and toggles CSS classes on Ranges and Selections | |
4 | + | |
5 | + Part of Rangy, a cross-browser JavaScript range and selection library | |
6 | + http://code.google.com/p/rangy/ | |
7 | + | |
8 | + Depends on Rangy core. | |
9 | + | |
10 | + Copyright 2012, Tim Down | |
11 | + Licensed under the MIT license. | |
12 | + Version: 1.2.3 | |
13 | + Build date: 26 February 2012 | |
14 | +*/ | |
15 | +rangy.createModule("CssClassApplier",function(i,v){function r(a,b){return a.className&&RegExp("(?:^|\\s)"+b+"(?:\\s|$)").test(a.className)}function s(a,b){if(a.className)r(a,b)||(a.className+=" "+b);else a.className=b}function o(a){return a.split(/\s+/).sort().join(" ")}function w(a,b){return o(a.className)==o(b.className)}function x(a){for(var b=a.parentNode;a.hasChildNodes();)b.insertBefore(a.firstChild,a);b.removeChild(a)}function y(a,b){var c=a.cloneRange();c.selectNodeContents(b);var d=c.intersection(a); | |
16 | +d=d?d.toString():"";c.detach();return d!=""}function z(a){return a.getNodes([3],function(b){return y(a,b)})}function A(a,b){if(a.attributes.length!=b.attributes.length)return false;for(var c=0,d=a.attributes.length,e,f;c<d;++c){e=a.attributes[c];f=e.name;if(f!="class"){f=b.attributes.getNamedItem(f);if(e.specified!=f.specified)return false;if(e.specified&&e.nodeValue!==f.nodeValue)return false}}return true}function B(a,b){for(var c=0,d=a.attributes.length,e;c<d;++c){e=a.attributes[c].name;if(!(b&& | |
17 | +h.arrayContains(b,e))&&a.attributes[c].specified&&e!="class")return true}return false}function C(a){var b;return a&&a.nodeType==1&&((b=a.parentNode)&&b.nodeType==9&&b.designMode=="on"||k(a)&&!k(a.parentNode))}function D(a){return(k(a)||a.nodeType!=1&&k(a.parentNode))&&!C(a)}function E(a){return a&&a.nodeType==1&&!M.test(p(a,"display"))}function N(a){if(a.data.length==0)return true;if(O.test(a.data))return false;switch(p(a.parentNode,"whiteSpace")){case "pre":case "pre-wrap":case "-moz-pre-wrap":return false; | |
18 | +case "pre-line":if(/[\r\n]/.test(a.data))return false}return E(a.previousSibling)||E(a.nextSibling)}function m(a,b,c,d){var e,f=c==0;if(h.isAncestorOf(b,a))return a;if(h.isCharacterDataNode(b))if(c==0){c=h.getNodeIndex(b);b=b.parentNode}else if(c==b.length){c=h.getNodeIndex(b)+1;b=b.parentNode}else throw v.createError("splitNodeAt should not be called with offset in the middle of a data node ("+c+" in "+b.data);var g;g=b;var j=c;g=h.isCharacterDataNode(g)?j==0?!!g.previousSibling:j==g.length?!!g.nextSibling: | |
19 | +true:j>0&&j<g.childNodes.length;if(g){if(!e){e=b.cloneNode(false);for(e.id&&e.removeAttribute("id");f=b.childNodes[c];)e.appendChild(f);h.insertAfter(e,b)}return b==a?e:m(a,e.parentNode,h.getNodeIndex(e),d)}else if(a!=b){e=b.parentNode;b=h.getNodeIndex(b);f||b++;return m(a,e,b,d)}return a}function F(a){var b=a?"nextSibling":"previousSibling";return function(c,d){var e=c.parentNode,f=c[b];if(f){if(f&&f.nodeType==3)return f}else if(d)if((f=e[b])&&f.nodeType==1&&e.tagName==f.tagName&&w(e,f)&&A(e,f))return f[a? | |
20 | +"firstChild":"lastChild"];return null}}function t(a){this.firstTextNode=(this.isElementMerge=a.nodeType==1)?a.lastChild:a;this.textNodes=[this.firstTextNode]}function q(a,b,c){this.cssClass=a;var d,e,f=null;if(typeof b=="object"&&b!==null){c=b.tagNames;f=b.elementProperties;for(d=0;e=P[d++];)if(b.hasOwnProperty(e))this[e]=b[e];d=b.normalize}else d=b;this.normalize=typeof d=="undefined"?true:d;this.attrExceptions=[];d=document.createElement(this.elementTagName);this.elementProperties={};for(var g in f)if(f.hasOwnProperty(g)){if(G.hasOwnProperty(g))g= | |
21 | +G[g];d[g]=f[g];this.elementProperties[g]=d[g];this.attrExceptions.push(g)}this.elementSortedClassName=this.elementProperties.hasOwnProperty("className")?o(this.elementProperties.className+" "+a):a;this.applyToAnyTagName=false;a=typeof c;if(a=="string")if(c=="*")this.applyToAnyTagName=true;else this.tagNames=c.toLowerCase().replace(/^\s\s*/,"").replace(/\s\s*$/,"").split(/\s*,\s*/);else if(a=="object"&&typeof c.length=="number"){this.tagNames=[];d=0;for(a=c.length;d<a;++d)if(c[d]=="*")this.applyToAnyTagName= | |
22 | +true;else this.tagNames.push(c[d].toLowerCase())}else this.tagNames=[this.elementTagName]}i.requireModules(["WrappedSelection","WrappedRange"]);var h=i.dom,H=function(){function a(b,c,d){return c&&d?" ":""}return function(b,c){if(b.className)b.className=b.className.replace(RegExp("(?:^|\\s)"+c+"(?:\\s|$)"),a)}}(),p;if(typeof window.getComputedStyle!="undefined")p=function(a,b){return h.getWindow(a).getComputedStyle(a,null)[b]};else if(typeof document.documentElement.currentStyle!="undefined")p=function(a, | |
23 | +b){return a.currentStyle[b]};else v.fail("No means of obtaining computed style properties found");var k;(function(){k=typeof document.createElement("div").isContentEditable=="boolean"?function(a){return a&&a.nodeType==1&&a.isContentEditable}:function(a){if(!a||a.nodeType!=1||a.contentEditable=="false")return false;return a.contentEditable=="true"||k(a.parentNode)}})();var M=/^inline(-block|-table)?$/i,O=/[^\r\n\t\f \u200B]/,Q=F(false),R=F(true);t.prototype={doMerge:function(){for(var a=[],b,c,d=0, | |
24 | +e=this.textNodes.length;d<e;++d){b=this.textNodes[d];c=b.parentNode;a[d]=b.data;if(d){c.removeChild(b);c.hasChildNodes()||c.parentNode.removeChild(c)}}return this.firstTextNode.data=a=a.join("")},getLength:function(){for(var a=this.textNodes.length,b=0;a--;)b+=this.textNodes[a].length;return b},toString:function(){for(var a=[],b=0,c=this.textNodes.length;b<c;++b)a[b]="'"+this.textNodes[b].data+"'";return"[Merge("+a.join(",")+")]"}};var P=["elementTagName","ignoreWhiteSpace","applyToEditableOnly"], | |
25 | +G={"class":"className"};q.prototype={elementTagName:"span",elementProperties:{},ignoreWhiteSpace:true,applyToEditableOnly:false,hasClass:function(a){return a.nodeType==1&&h.arrayContains(this.tagNames,a.tagName.toLowerCase())&&r(a,this.cssClass)},getSelfOrAncestorWithClass:function(a){for(;a;){if(this.hasClass(a,this.cssClass))return a;a=a.parentNode}return null},isModifiable:function(a){return!this.applyToEditableOnly||D(a)},isIgnorableWhiteSpaceNode:function(a){return this.ignoreWhiteSpace&&a&& | |
26 | +a.nodeType==3&&N(a)},postApply:function(a,b,c){for(var d=a[0],e=a[a.length-1],f=[],g,j=d,I=e,J=0,K=e.length,n,L,l=0,u=a.length;l<u;++l){n=a[l];if(L=Q(n,!c)){if(!g){g=new t(L);f.push(g)}g.textNodes.push(n);if(n===d){j=g.firstTextNode;J=j.length}if(n===e){I=g.firstTextNode;K=g.getLength()}}else g=null}if(a=R(e,!c)){if(!g){g=new t(e);f.push(g)}g.textNodes.push(a)}if(f.length){l=0;for(u=f.length;l<u;++l)f[l].doMerge();b.setStart(j,J);b.setEnd(I,K)}},createContainer:function(a){a=a.createElement(this.elementTagName); | |
27 | +i.util.extend(a,this.elementProperties);s(a,this.cssClass);return a},applyToTextNode:function(a){var b=a.parentNode;if(b.childNodes.length==1&&h.arrayContains(this.tagNames,b.tagName.toLowerCase()))s(b,this.cssClass);else{b=this.createContainer(h.getDocument(a));a.parentNode.insertBefore(b,a);b.appendChild(a)}},isRemovable:function(a){var b;if(b=a.tagName.toLowerCase()==this.elementTagName){if(b=o(a.className)==this.elementSortedClassName){var c;a:{b=this.elementProperties;for(c in b)if(b.hasOwnProperty(c)&& | |
28 | +a[c]!==b[c]){c=false;break a}c=true}b=c&&!B(a,this.attrExceptions)&&this.isModifiable(a)}b=b}return b},undoToTextNode:function(a,b,c){if(!b.containsNode(c)){a=b.cloneRange();a.selectNode(c);if(a.isPointInRange(b.endContainer,b.endOffset)){m(c,b.endContainer,b.endOffset,[b]);b.setEndAfter(c)}if(a.isPointInRange(b.startContainer,b.startOffset))c=m(c,b.startContainer,b.startOffset,[b])}this.isRemovable(c)?x(c):H(c,this.cssClass)},applyToRange:function(a){a.splitBoundaries();var b=z(a);if(b.length){for(var c, | |
29 | +d=0,e=b.length;d<e;++d){c=b[d];!this.isIgnorableWhiteSpaceNode(c)&&!this.getSelfOrAncestorWithClass(c)&&this.isModifiable(c)&&this.applyToTextNode(c)}a.setStart(b[0],0);c=b[b.length-1];a.setEnd(c,c.length);this.normalize&&this.postApply(b,a,false)}},applyToSelection:function(a){a=a||window;a=i.getSelection(a);var b,c=a.getAllRanges();a.removeAllRanges();for(var d=c.length;d--;){b=c[d];this.applyToRange(b);a.addRange(b)}},undoToRange:function(a){a.splitBoundaries();var b=z(a),c,d,e=b[b.length-1];if(b.length){for(var f= | |
30 | +0,g=b.length;f<g;++f){c=b[f];(d=this.getSelfOrAncestorWithClass(c))&&this.isModifiable(c)&&this.undoToTextNode(c,a,d);a.setStart(b[0],0);a.setEnd(e,e.length)}this.normalize&&this.postApply(b,a,true)}},undoToSelection:function(a){a=a||window;a=i.getSelection(a);var b=a.getAllRanges(),c;a.removeAllRanges();for(var d=0,e=b.length;d<e;++d){c=b[d];this.undoToRange(c);a.addRange(c)}},getTextSelectedByRange:function(a,b){var c=b.cloneRange();c.selectNodeContents(a);var d=c.intersection(b);d=d?d.toString(): | |
31 | +"";c.detach();return d},isAppliedToRange:function(a){if(a.collapsed)return!!this.getSelfOrAncestorWithClass(a.commonAncestorContainer);else{for(var b=a.getNodes([3]),c=0,d;d=b[c++];)if(!this.isIgnorableWhiteSpaceNode(d)&&y(a,d)&&this.isModifiable(d)&&!this.getSelfOrAncestorWithClass(d))return false;return true}},isAppliedToSelection:function(a){a=a||window;a=i.getSelection(a).getAllRanges();for(var b=a.length;b--;)if(!this.isAppliedToRange(a[b]))return false;return true},toggleRange:function(a){this.isAppliedToRange(a)? | |
32 | +this.undoToRange(a):this.applyToRange(a)},toggleSelection:function(a){this.isAppliedToSelection(a)?this.undoToSelection(a):this.applyToSelection(a)},detach:function(){}};q.util={hasClass:r,addClass:s,removeClass:H,hasSameClasses:w,replaceWithOwnChildren:x,elementsHaveSameNonClassAttributes:A,elementHasNonClassAttributes:B,splitNodeAt:m,isEditableElement:k,isEditingHost:C,isEditable:D};i.CssClassApplier=q;i.createCssClassApplier=function(a,b,c){return new q(a,b,c)}}); | |
0 | 33 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,23 @@ |
1 | +/* | |
2 | + Serializer module for Rangy. | |
3 | + Serializes Ranges and Selections. An example use would be to store a user's selection on a particular page in a | |
4 | + cookie or local storage and restore it on the user's next visit to the same page. | |
5 | + | |
6 | + Part of Rangy, a cross-browser JavaScript range and selection library | |
7 | + http://code.google.com/p/rangy/ | |
8 | + | |
9 | + Depends on Rangy core. | |
10 | + | |
11 | + Copyright 2012, Tim Down | |
12 | + Licensed under the MIT license. | |
13 | + Version: 1.2.3 | |
14 | + Build date: 26 February 2012 | |
15 | +*/ | |
16 | +rangy.createModule("Serializer",function(g,n){function o(c,a){a=a||[];var b=c.nodeType,e=c.childNodes,d=e.length,f=[b,c.nodeName,d].join(":"),h="",k="";switch(b){case 3:h=c.nodeValue.replace(/</g,"<").replace(/>/g,">");break;case 8:h="<!--"+c.nodeValue.replace(/</g,"<").replace(/>/g,">")+"--\>";break;default:h="<"+f+">";k="</>";break}h&&a.push(h);for(b=0;b<d;++b)o(e[b],a);k&&a.push(k);return a}function j(c){c=o(c).join("");return u(c).toString(16)}function l(c,a,b){var e=[],d=c;for(b= | |
17 | +b||i.getDocument(c).documentElement;d&&d!=b;){e.push(i.getNodeIndex(d,true));d=d.parentNode}return e.join("/")+":"+a}function m(c,a,b){if(a)b||i.getDocument(a);else{b=b||document;a=b.documentElement}c=c.split(":");a=a;b=c[0]?c[0].split("/"):[];for(var e=b.length,d;e--;){d=parseInt(b[e],10);if(d<a.childNodes.length)a=a.childNodes[parseInt(b[e],10)];else throw n.createError("deserializePosition failed: node "+i.inspectNode(a)+" has no child with index "+d+", "+e);}return new i.DomPosition(a,parseInt(c[1], | |
18 | +10))}function p(c,a,b){b=b||g.DomRange.getRangeDocument(c).documentElement;if(!i.isAncestorOf(b,c.commonAncestorContainer,true))throw Error("serializeRange: range is not wholly contained within specified root node");c=l(c.startContainer,c.startOffset,b)+","+l(c.endContainer,c.endOffset,b);a||(c+="{"+j(b)+"}");return c}function q(c,a,b){if(a)b=b||i.getDocument(a);else{b=b||document;a=b.documentElement}c=/^([^,]+),([^,\{]+)({([^}]+)})?$/.exec(c);var e=c[4],d=j(a);if(e&&e!==j(a))throw Error("deserializeRange: checksums of serialized range root node ("+ | |
19 | +e+") and target root node ("+d+") do not match");e=m(c[1],a,b);a=m(c[2],a,b);b=g.createRange(b);b.setStart(e.node,e.offset);b.setEnd(a.node,a.offset);return b}function r(c,a,b){if(a)b||i.getDocument(a);else{b=b||document;a=b.documentElement}c=/^([^,]+),([^,]+)({([^}]+)})?$/.exec(c)[3];return!c||c===j(a)}function s(c,a,b){c=c||g.getSelection();c=c.getAllRanges();for(var e=[],d=0,f=c.length;d<f;++d)e[d]=p(c[d],a,b);return e.join("|")}function t(c,a,b){if(a)b=b||i.getWindow(a);else{b=b||window;a=b.document.documentElement}c= | |
20 | +c.split("|");for(var e=g.getSelection(b),d=[],f=0,h=c.length;f<h;++f)d[f]=q(c[f],a,b.document);e.setRanges(d);return e}g.requireModules(["WrappedSelection","WrappedRange"]);if(typeof encodeURIComponent=="undefined"||typeof decodeURIComponent=="undefined")n.fail("Global object is missing encodeURIComponent and/or decodeURIComponent method");var u=function(){var c=null;return function(a){for(var b=[],e=0,d=a.length,f;e<d;++e){f=a.charCodeAt(e);if(f<128)b.push(f);else f<2048?b.push(f>>6|192,f&63|128): | |
21 | +b.push(f>>12|224,f>>6&63|128,f&63|128)}a=-1;if(!c){e=[];d=0;for(var h;d<256;++d){h=d;for(f=8;f--;)if((h&1)==1)h=h>>>1^3988292384;else h>>>=1;e[d]=h>>>0}c=e}e=c;d=0;for(f=b.length;d<f;++d){h=(a^b[d])&255;a=a>>>8^e[h]}return(a^-1)>>>0}}(),i=g.dom;g.serializePosition=l;g.deserializePosition=m;g.serializeRange=p;g.deserializeRange=q;g.canDeserializeRange=r;g.serializeSelection=s;g.deserializeSelection=t;g.canDeserializeSelection=function(c,a,b){var e;if(a)e=b?b.document:i.getDocument(a);else{b=b||window; | |
22 | +a=b.document.documentElement}c=c.split("|");b=0;for(var d=c.length;b<d;++b)if(!r(c[b],a,e))return false;return true};g.restoreSelectionFromCookie=function(c){c=c||window;var a;a:{a=c.document.cookie.split(/[;,]/);for(var b=0,e=a.length,d;b<e;++b){d=a[b].split("=");if(d[0].replace(/^\s+/,"")=="rangySerializedSelection")if(d=d[1]){a=decodeURIComponent(d.replace(/\s+$/,""));break a}}a=null}a&&t(a,c.doc)};g.saveSelectionCookie=function(c,a){c=c||window;a=typeof a=="object"?a:{};var b=a.expires?";expires="+ | |
23 | +a.expires.toUTCString():"",e=a.path?";path="+a.path:"",d=a.domain?";domain="+a.domain:"",f=a.secure?";secure":"",h=s(g.getSelection(c));c.document.cookie=encodeURIComponent("rangySerializedSelection")+"="+encodeURIComponent(h)+b+e+d+f};g.getElementChecksum=j}); | |
0 | 24 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,372 @@ |
1 | +#content #article-toolbar .icon-toggle_comment_paragraph { | |
2 | + top: -71px; | |
3 | + border: 0; | |
4 | + background-color: transparent; | |
5 | + color: gray; | |
6 | +} | |
7 | +#content #article-toolbar .icon-toggle_comment_paragraph:hover { | |
8 | + color: black; | |
9 | +} | |
10 | + | |
11 | +.icon-toggle_comment_paragraph{ | |
12 | + background-image: url('/plugins/comment_paragraph/images/internet-group-chat.png'); | |
13 | +} | |
14 | + | |
15 | +#comment-bubble.visible { | |
16 | + visibility: visible; | |
17 | +} | |
18 | +#comment-bubble { | |
19 | + transition: top 0.15s ease-in-out; | |
20 | + top: 0; | |
21 | + left: 0; | |
22 | + position: absolute; | |
23 | + width: 90px; | |
24 | + text-decoration: none; | |
25 | + visibility: hidden; | |
26 | + cursor: pointer; | |
27 | +} | |
28 | + | |
29 | +div.article-comments-list-more{ | |
30 | + width: 100%; | |
31 | + text-align: center; | |
32 | + font-size: 20px; | |
33 | + margin-bottom: 5px; | |
34 | +} | |
35 | + | |
36 | +.popBox_comment_paragraph { | |
37 | + z-index: 2; | |
38 | + background: #cccccc; | |
39 | + width: 60px; | |
40 | + padding: 0.3em; | |
41 | + position: absolute;border: 1px solid gray; | |
42 | +} | |
43 | + | |
44 | +.span_comment_paragraph { | |
45 | + color: red; | |
46 | + font-weight: bold; | |
47 | +} | |
48 | + | |
49 | +.comment-paragraph-plugin .commented-area { | |
50 | + background-color: lightseagreen; | |
51 | + color: white; | |
52 | +} | |
53 | + | |
54 | +.comment-paragraph-plugin .commented-area-selected { | |
55 | + background-color: rgb(255, 86, 86); | |
56 | + color: white; | |
57 | +} | |
58 | + | |
59 | +.comment_paragraph ::selection { | |
60 | + background-color: lightseagreen; /* WebKit/Blink Browsers */ | |
61 | + color: white; | |
62 | +} | |
63 | + | |
64 | +.comment_paragraph ::-moz-selection { | |
65 | + background-color: lightseagreen; /* Gecko Browsers */ | |
66 | + color: white; | |
67 | +} | |
68 | + | |
69 | +.comment_paragraph{ | |
70 | + display: table-cell; | |
71 | + width: 97%; | |
72 | +} | |
73 | + | |
74 | +.triangle-right { | |
75 | + position:relative; | |
76 | + padding:15px; | |
77 | + margin:1em 0 3em; | |
78 | + color:#fff; | |
79 | + background:#717171; /* default background for browsers without gradient support */ | |
80 | + /* css3 */ | |
81 | + background:-webkit-gradient(linear, 0 0, 0 100%, from(#717171), to(#1F1F1F)); | |
82 | + background:-moz-linear-gradient(#717171, #1F1F1F); | |
83 | + background:-o-linear-gradient(#717171, #1F1F1F); | |
84 | + background: linear-gradient(#717171, #1F1F1F); | |
85 | + -webkit-border-radius:8px; | |
86 | + -moz-border-radius:8px; | |
87 | + border-radius:8px; | |
88 | + font-weight: bold; | |
89 | +} | |
90 | + | |
91 | +.triangle-right:after { | |
92 | + content: ""; | |
93 | + position: absolute; | |
94 | + bottom: -20px; | |
95 | + left: 50px; | |
96 | + border-width: 20px 0 0 20px; | |
97 | + border-style: solid; | |
98 | + border-color: #1F1F1F transparent; | |
99 | + display: block; | |
100 | + width: 0; | |
101 | +} | |
102 | + | |
103 | +.triangle-border { | |
104 | + position: relative; | |
105 | + padding: 15px; | |
106 | + margin: 1em 0 3em; | |
107 | + border: 5px solid #5a8f00; | |
108 | + color: #333; | |
109 | + background: #fff; | |
110 | + -webkit-border-radius: 10px; | |
111 | + -moz-border-radius: 10px; | |
112 | + border-radius: 10px; | |
113 | +} | |
114 | + | |
115 | +.side-comment .comment-header { | |
116 | + position: absolute; | |
117 | + width: 150px; | |
118 | + right: 0; | |
119 | + top: 0; | |
120 | + zoom: 0.8; | |
121 | + -moz-transform: scale(0.8); | |
122 | +} | |
123 | + | |
124 | +.side-comment .comment-created-at{display: none;} | |
125 | +.side-comment #comment_title, .side-comment .comment_title{display: none;} | |
126 | +.side-comment label[for="comment_title"] {display: none;} | |
127 | + | |
128 | +.side-comment { | |
129 | + border-style: solid; | |
130 | + border-width: 1px; | |
131 | + border-color: #e7e7e7; | |
132 | + padding: 5px; | |
133 | + background-color: whitesmoke; | |
134 | + width: 280px; | |
135 | + display: none; | |
136 | +} | |
137 | + | |
138 | +#content .side-comment .comment-balloon div[class^='comment-wrapper-']{ | |
139 | + background: none; | |
140 | +} | |
141 | + | |
142 | +.side-comment{ | |
143 | + z-index: 199; | |
144 | + box-shadow: 0px 0px 20px #b8b8b8; | |
145 | +} | |
146 | + | |
147 | +.side-comments-counter-container { | |
148 | + display: table-cell; | |
149 | + vertical-align: middle; | |
150 | + padding-left: 10px; | |
151 | +} | |
152 | + | |
153 | +.side-comments-counter { | |
154 | + position: relative; | |
155 | + width: 20px; | |
156 | + height: 19px; | |
157 | + padding: 0px; | |
158 | + background: #b5b5b5; | |
159 | + -webkit-border-radius: 2px; | |
160 | + -moz-border-radius: 2px; | |
161 | + border-radius: 2px; | |
162 | + cursor: pointer; | |
163 | + z-index: 1; | |
164 | + display: inline-block; | |
165 | + font-weight: bold; | |
166 | + color: white; | |
167 | + text-align: center; | |
168 | + opacity: 0.7; | |
169 | +} | |
170 | + | |
171 | +.comment-paragraph-plugin .loading { | |
172 | + height: 40px; | |
173 | + background-position: center 0; | |
174 | +} | |
175 | + | |
176 | +.side-comments-counter:hover { | |
177 | + background-color: rgb(117, 192, 117); | |
178 | +} | |
179 | +.side-comments-counter:hover:after { | |
180 | + border-color: rgb(117, 192, 117) transparent; | |
181 | +} | |
182 | + | |
183 | +.comments.selected .side-comments-counter, .comments.selected .side-comments-counter:after { | |
184 | + opacity: 1; | |
185 | +} | |
186 | + | |
187 | +.side-comments-counter:after { | |
188 | + content: ""; | |
189 | + position: absolute; | |
190 | + bottom: -9px; | |
191 | + left: 5px; | |
192 | + border-style: solid; | |
193 | + border-width: 10px 5px 0; | |
194 | + border-color: #b5b5b5 transparent; | |
195 | + display: block; | |
196 | + width: 0; | |
197 | +} | |
198 | + | |
199 | +.comment-count-container { | |
200 | + position: relative; | |
201 | + top: 3px; | |
202 | +} | |
203 | + | |
204 | +.article-comment-inner {border-bottom: 1px solid #ececec;} | |
205 | + | |
206 | +#article .side-comment .comment-replies .article-comment{background: white; border: 0px; border-top: 1px solid #ddd;} | |
207 | + | |
208 | +.comment-replies .comment-from-owner.comment-content {background: none;} | |
209 | + | |
210 | +.side-comment .comment-balloon-content { | |
211 | + margin: 0; | |
212 | +} | |
213 | + | |
214 | +#article .side-comment .article-comments-list { | |
215 | + margin: 0; | |
216 | + overflow-y: auto; | |
217 | + overflow-x: hidden; | |
218 | + max-height: 400px; | |
219 | + border-bottom: 1px solid rgb(240, 240, 240); | |
220 | +} | |
221 | +#article .side-comment .article-comments-list .article-comment { | |
222 | + margin: 0; | |
223 | +} | |
224 | +.side-comment .comment-details { | |
225 | + margin: 0; | |
226 | + padding: 0; | |
227 | +} | |
228 | +.side-comment .comment-text { | |
229 | + padding: 0; | |
230 | + width: 98%; | |
231 | + text-align: justify; | |
232 | + overflow: visible; | |
233 | + color: rgb(107, 107, 107); | |
234 | +} | |
235 | +.side-comment .comment-text p { | |
236 | + margin: 0; | |
237 | +} | |
238 | +#content #article .article-body .side-comment img { | |
239 | + max-width: 30px; | |
240 | +} | |
241 | +#content #article .article-body .side-comment span.comment-info { | |
242 | + position: relative; | |
243 | + top: -10px; | |
244 | + left: 36px; | |
245 | + line-height: 0; | |
246 | + font-weight: bold; | |
247 | + font-size: 12px; | |
248 | + color: rgb(80, 80, 80); | |
249 | +} | |
250 | +.side-comment .comment-wrapper-1 { | |
251 | + margin-left: 36px; | |
252 | +} | |
253 | +#article .side-comment .comment-picture { | |
254 | + width: 100%; | |
255 | + height: auto; | |
256 | + margin-top: 8px; | |
257 | + max-width: none; | |
258 | +} | |
259 | +#article .side-comment .article-comment .comment-details > h4 { | |
260 | + display: none; | |
261 | +} | |
262 | +.side-comment .formlabel[for='comment_body'] { | |
263 | + display: none; | |
264 | +} | |
265 | +.side-comment .comment_form p { | |
266 | + display: none; | |
267 | +} | |
268 | + | |
269 | +.side-comment .post_comment_box.opened { | |
270 | + padding-bottom: 15px; | |
271 | +} | |
272 | + | |
273 | +.side-comment .comment-count-container { | |
274 | + bg-color: #b3b2d4; | |
275 | +} | |
276 | + | |
277 | +.side-comment textarea { | |
278 | + height: 50px; | |
279 | +} | |
280 | + | |
281 | +.single-border{ | |
282 | + border-style: solid; | |
283 | + border-width: 2px; | |
284 | +} | |
285 | + | |
286 | +.comment-paragraph-plugin .comments { | |
287 | + position: relative; | |
288 | + display: table; | |
289 | +} | |
290 | + | |
291 | +.comments .comment_paragraph:hover, .comments.selected .comment_paragraph { | |
292 | + background-color: rgb(236, 236, 236); | |
293 | +} | |
294 | + | |
295 | +.side-comment { | |
296 | + position: absolute; | |
297 | + right: -296px; | |
298 | + top: 0px; | |
299 | + background-color: white; | |
300 | + z-index: 199; | |
301 | +} | |
302 | + | |
303 | +.comment-paragraph-plugin.comment-paragraph-slide-left { | |
304 | + position: relative; | |
305 | + width: 80%; | |
306 | +} | |
307 | +.comment-paragraph-plugin { | |
308 | + width: 100%; | |
309 | + transition: width 0.3s ease-in-out; | |
310 | +} | |
311 | + | |
312 | +.comment-paragraph-plugin .post_comment_box { | |
313 | + text-align: center; | |
314 | + padding: 5px 5px 0 5px; | |
315 | +} | |
316 | +.comment-paragraph-plugin .comment-details .menu-submenu { | |
317 | + right: 21px; | |
318 | + top: -1px; | |
319 | +} | |
320 | + | |
321 | +.comment-paragraph-plugin .comment_reply.post_comment_box form { | |
322 | + padding-left: 0; | |
323 | + padding-right: 10px; | |
324 | + margin-left: -36px; | |
325 | +} | |
326 | + | |
327 | +.comment-paragraph-plugin .no-comments-yet .comment-count { | |
328 | + display: none; | |
329 | +} | |
330 | + | |
331 | +.comment-paragraph-plugin .no-comments-yet:after { | |
332 | + content: "+"; | |
333 | +} | |
334 | +#content .comment-paragraph-plugin .no-comments-yet { | |
335 | + font-size: 100%; | |
336 | + opacity: 1; | |
337 | +} | |
338 | + | |
339 | +#content .comment-paragraph-plugin .display-comment-form { | |
340 | + text-decoration: none; | |
341 | + color: gray; | |
342 | +} | |
343 | + | |
344 | +#content .comment-paragraph-plugin .display-comment-form:hover { | |
345 | + color: rgb(95, 95, 95); | |
346 | +} | |
347 | + | |
348 | +#content .comment-paragraph-plugin .side-comment .article-comments-list .comment-replies .comment-replies { | |
349 | + padding-left: 0; | |
350 | +} | |
351 | +#content .comment-paragraph-plugin .side-comment .article-comments-list .comment-replies { | |
352 | + padding-left: 25px; | |
353 | +} | |
354 | + | |
355 | +#content .comment-paragraph-plugin #cancel-comment, #content .comment-paragraph-plugin .icon-add { | |
356 | + background: none; | |
357 | + border: none; | |
358 | +} | |
359 | +#content .comment-paragraph-plugin #cancel-comment:hover, #content .comment-paragraph-plugin .icon-add:hover { | |
360 | + background: none; | |
361 | + color: black; | |
362 | + border: none; | |
363 | +} | |
364 | +#content .comment-paragraph-plugin .button-bar { | |
365 | + margin: 5px 0; | |
366 | +} | |
367 | + | |
368 | +li span[data-macro="comment_paragraph_plugin/allow_comment"] { | |
369 | + display: inline-block; | |
370 | + vertical-align: top; | |
371 | + min-height: 30px; | |
372 | +} | ... | ... |
plugins/comment_paragraph/test/functional/comment_paragraph_plugin_admin_controller_test.rb
0 → 100644
... | ... | @@ -0,0 +1,38 @@ |
1 | +require_relative '../../../../test/test_helper' | |
2 | +require_relative '../../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 | + attr_reader :plugin_settings, :environment | |
18 | + | |
19 | + should 'access index action' do | |
20 | + get :index | |
21 | + assert_response :success | |
22 | + end | |
23 | + | |
24 | + should 'update comment paragraph plugin settings' do | |
25 | + assert_not_equal 'auto', plugin_settings.get_setting(:activation_mode) | |
26 | + post :index, :settings => { :activation_mode => 'auto' } | |
27 | + environment.reload | |
28 | + assert_equal 'auto', plugin_settings.get_setting(:activation_mode) | |
29 | + end | |
30 | + | |
31 | + should 'get article types previously selected' do | |
32 | + plugin_settings.activation_mode = 'manual' | |
33 | + plugin_settings.save! | |
34 | + get :index | |
35 | + assert_tag :input, :attributes => { :value => 'manual', :checked => 'checked' } | |
36 | + end | |
37 | + | |
38 | +end | ... | ... |
plugins/comment_paragraph/test/functional/comment_paragraph_plugin_myprofile_controller_test.rb
0 → 100644
... | ... | @@ -0,0 +1,35 @@ |
1 | +require_relative '../test_helper' | |
2 | + | |
3 | +class CommentParagraphPluginMyprofileControllerTest < ActionController::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @environment = Environment.default | |
7 | + @environment.enable_plugin(CommentParagraphPlugin) | |
8 | + @profile = fast_create(Profile) | |
9 | + @user = create_user_with_permission('testuser', 'post_content', @profile) | |
10 | + login_as(@user.identifier) | |
11 | + @article = fast_create(TextArticle, :profile_id => profile.id, :author_id => @user.id) | |
12 | + end | |
13 | + | |
14 | + attr_reader :article, :profile, :user, :environment | |
15 | + | |
16 | + should 'toggle comment paragraph activation' do | |
17 | + assert !article.comment_paragraph_plugin_activate | |
18 | + get :toggle_activation, :id => article.id, :profile => profile.identifier | |
19 | + assert article.reload.comment_paragraph_plugin_activate | |
20 | + assert_redirected_to article.view_url | |
21 | + end | |
22 | + | |
23 | + should 'deny access to toggle activation for forbidden users' do | |
24 | + login_as(create_user('anotheruser').login) | |
25 | + get :toggle_activation, :id => article.id, :profile => profile.identifier | |
26 | + assert_response :forbidden | |
27 | + end | |
28 | + | |
29 | + should 'deny access to toggle activation if plugin is not enabled' do | |
30 | + environment.disable_plugin(CommentParagraphPlugin) | |
31 | + get :toggle_activation, :id => article.id, :profile => profile.identifier | |
32 | + assert_response :forbidden | |
33 | + end | |
34 | + | |
35 | +end | ... | ... |
plugins/comment_paragraph/test/functional/comment_paragraph_plugin_profile_controller_test.rb
0 → 100644
... | ... | @@ -0,0 +1,42 @@ |
1 | +require_relative '../test_helper' | |
2 | +require_relative '../../controllers/profile/comment_paragraph_plugin_profile_controller' | |
3 | + | |
4 | +# Re-raise errors caught by the controller. | |
5 | +class CommentParagraphPluginProfileController; def rescue_action(e) raise e end; end | |
6 | + | |
7 | +class CommentParagraphPluginProfileControllerTest < ActionController::TestCase | |
8 | + | |
9 | + def setup | |
10 | + @profile = create_user('testuser').person | |
11 | + @article = profile.articles.build(:name => 'test') | |
12 | + @article.save! | |
13 | + end | |
14 | + attr_reader :article, :profile | |
15 | + | |
16 | + should 'be able to show paragraph comments' do | |
17 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_uuid => 0) | |
18 | + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_uuid => 0 | |
19 | + assert_select "#comment-#{comment.id}" | |
20 | + end | |
21 | + | |
22 | + should 'do not show global comments' do | |
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) | |
25 | + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_uuid => 0 | |
26 | + assert_select "#comment-#{global_comment.id}", 0 | |
27 | + assert_select "#comment-#{comment.id}" | |
28 | + end | |
29 | + | |
30 | + should 'be able to show all comments of a paragraph' do | |
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) | |
35 | + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :paragraph_uuid => 0 | |
36 | + assert_match /a comment/, @response.body | |
37 | + assert_match /b comment/, @response.body | |
38 | + assert_match /c comment/, @response.body | |
39 | + assert_match /d comment/, @response.body | |
40 | + end | |
41 | + | |
42 | +end | ... | ... |
plugins/comment_paragraph/test/functional/comment_paragraph_plugin_public_controller_test.rb
0 → 100644
... | ... | @@ -0,0 +1,29 @@ |
1 | +require_relative '../test_helper' | |
2 | +require_relative '../../controllers/public/comment_paragraph_plugin_public_controller' | |
3 | + | |
4 | + | |
5 | +# Re-raise errors caught by the controller. | |
6 | +class CommentParagraphPluginPublicController; def rescue_action(e) raise e end; end | |
7 | + | |
8 | +class CommentParagraphPluginPublicControllerTest < ActionController::TestCase | |
9 | + | |
10 | + def setup | |
11 | + @profile = create_user('testuser').person | |
12 | + @article = profile.articles.create!(:name => 'test') | |
13 | + end | |
14 | + attr_reader :article, :profile | |
15 | + | |
16 | + should 'be able to return paragraph_uuid for a comment' do | |
17 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :paragraph_uuid => 0) | |
18 | + cid = comment.id | |
19 | + xhr :get, :comment_paragraph, :id => cid | |
20 | + assert_equal({'paragraph_uuid' => '0'}, ActiveSupport::JSON.decode(@response.body)) | |
21 | + end | |
22 | + | |
23 | + should 'return paragraph_uuid=null for a global comment' do | |
24 | + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala' ) | |
25 | + xhr :get, :comment_paragraph, :id => comment.id | |
26 | + assert_equal({'paragraph_uuid' => nil}, ActiveSupport::JSON.decode(@response.body)) | |
27 | + end | |
28 | + | |
29 | +end | ... | ... |
plugins/comment_paragraph/test/functional/content_viewer_controller_test.rb
0 → 100644
... | ... | @@ -0,0 +1,29 @@ |
1 | +require_relative '../test_helper' | |
2 | + | |
3 | +class ContentViewerController | |
4 | + append_view_path File.join(File.dirname(__FILE__) + '/../../views') | |
5 | + def rescue_action(e) | |
6 | + raise e | |
7 | + end | |
8 | +end | |
9 | + | |
10 | +class ContentViewerControllerTest < ActionController::TestCase | |
11 | + | |
12 | + def setup | |
13 | + @environment = Environment.default | |
14 | + @environment.enable_plugin(CommentParagraphPlugin) | |
15 | + @profile = fast_create(Community) | |
16 | + @page = fast_create(TextArticle, :profile_id => @profile.id, :body => "<p>inner text</p>") | |
17 | + @page.comment_paragraph_plugin_activate = true | |
18 | + @page.save! | |
19 | + end | |
20 | + | |
21 | + attr_reader :page | |
22 | + | |
23 | + should 'parse article body and render comment paragraph view' do | |
24 | + comment1 = fast_create(Comment, :paragraph_uuid => 0, :source_id => page.id) | |
25 | + get :view_page, @page.url | |
26 | + assert_tag 'div', :attributes => {:class => 'comment_paragraph'} | |
27 | + end | |
28 | + | |
29 | +end | ... | ... |
... | ... | @@ -0,0 +1,5 @@ |
1 | +require_relative '../../../test/test_helper' | |
2 | + | |
3 | +def assert_mark_paragraph(html, tag, content) | |
4 | + assert_tag_in_string html, :tag => tag, :child => {:tag => 'span', :attributes => {'data-macro'=>"comment_paragraph_plugin/allow_comment"}, :content => content} | |
5 | +end | ... | ... |
plugins/comment_paragraph/test/unit/allow_comment_test.rb
0 → 100644
... | ... | @@ -0,0 +1,49 @@ |
1 | +require_relative '../test_helper' | |
2 | + | |
3 | +class AllowCommentTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + @macro = CommentParagraphPlugin::AllowComment.new | |
7 | + @environment = Environment.default | |
8 | + @environment.enable_plugin(CommentParagraphPlugin) | |
9 | + | |
10 | + @profile = fast_create(Community) | |
11 | + | |
12 | + @article = fast_create(TextArticle, :profile_id => profile.id, :body => 'inner') | |
13 | + @article.comment_paragraph_plugin_activate = true | |
14 | + @article.save! | |
15 | + | |
16 | + @comment = fast_create(Comment, :paragraph_uuid => 1, :source_id => article.id) | |
17 | + @controller = mock | |
18 | + end | |
19 | + | |
20 | + attr_reader :macro, :profile, :article, :controller, :comment, :environment | |
21 | + | |
22 | + should 'have a configuration' do | |
23 | + assert CommentParagraphPlugin::AllowComment.configuration | |
24 | + end | |
25 | + | |
26 | + should 'parse contents to include comment paragraph view' do | |
27 | + content = macro.parse({:paragraph_uuid => comment.paragraph_uuid}, article.body, article) | |
28 | + controller.expects(:kind_of?).with(ContentViewerController).returns(true) | |
29 | + | |
30 | + expects(:render).with({:partial => 'comment_paragraph_plugin_profile/comment_paragraph', :locals => {:paragraph_uuid => comment.paragraph_uuid, :article_id => article.id, :inner_html => article.body, :count => 1, :profile_identifier => profile.identifier} }) | |
31 | + instance_eval(&content) | |
32 | + end | |
33 | + | |
34 | + should 'not parse contents outside content viewer controller' do | |
35 | + article = fast_create(TextArticle, :profile_id => profile.id, :body => 'inner') | |
36 | + content = macro.parse({:paragraph_uuid => comment.paragraph_uuid}, article.body, article) | |
37 | + controller.expects(:kind_of?).with(ContentViewerController).returns(false) | |
38 | + assert_equal 'inner', instance_eval(&content) | |
39 | + end | |
40 | + | |
41 | + should 'not parse contents if comment_paragraph is not activated' do | |
42 | + article = fast_create(TextArticle, :profile_id => profile.id, :body => 'inner') | |
43 | + article.expects(:comment_paragraph_plugin_activated?).returns(false) | |
44 | + content = macro.parse({:paragraph_uuid => comment.paragraph_uuid}, article.body, article) | |
45 | + controller.expects(:kind_of?).with(ContentViewerController).returns(true) | |
46 | + assert_equal 'inner', instance_eval(&content) | |
47 | + end | |
48 | + | |
49 | +end | ... | ... |
... | ... | @@ -0,0 +1,173 @@ |
1 | +require_relative '../test_helper' | |
2 | +require 'benchmark' | |
3 | + | |
4 | +class ArticleTest < ActiveSupport::TestCase | |
5 | + | |
6 | + def setup | |
7 | + @profile = fast_create(Community) | |
8 | + @article = fast_create(TextArticle, :profile_id => profile.id) | |
9 | + @environment = Environment.default | |
10 | + @environment.enable_plugin(CommentParagraphPlugin) | |
11 | + end | |
12 | + | |
13 | + attr_reader :article, :environment, :profile | |
14 | + | |
15 | + should 'return paragraph comments from article' do | |
16 | + comment1 = fast_create(Comment, :paragraph_uuid => 1, :source_id => article.id) | |
17 | + comment2 = fast_create(Comment, :paragraph_uuid => nil, :source_id => article.id) | |
18 | + assert_equal [comment1], article.paragraph_comments | |
19 | + end | |
20 | + | |
21 | + should 'allow save if comment paragraph macro is not removed for paragraph with comments' do | |
22 | + article.body = "<div class=\"macro\" data-macro-paragraph_uuid=0></div>" | |
23 | + comment1 = fast_create(Comment, :paragraph_uuid => 0, :source_id => article.id) | |
24 | + assert article.save | |
25 | + end | |
26 | + | |
27 | + should 'not parse html if the plugin is not enabled' do | |
28 | + article.body = "<p>paragraph 1</p><p>paragraph 2</p>" | |
29 | + environment.disable_plugin(CommentParagraphPlugin) | |
30 | + assert !environment.plugin_enabled?(CommentParagraphPlugin) | |
31 | + article.save! | |
32 | + assert_equal "<p>paragraph 1</p><p>paragraph 2</p>", article.body | |
33 | + end | |
34 | + | |
35 | + should 'parse html if the plugin is not enabled' do | |
36 | + article.body = "<p>paragraph 1</p><div>div 1</div><span>span 1</span>" | |
37 | + article.comment_paragraph_plugin_activate = true | |
38 | + article.save! | |
39 | + assert_mark_paragraph article.body, 'p', 'paragraph 1' | |
40 | + assert_mark_paragraph article.body, 'div', 'div 1' | |
41 | + assert_mark_paragraph article.body, 'span', 'span 1' | |
42 | + end | |
43 | + | |
44 | + should 'parse html li when activate comment paragraph' do | |
45 | + article.body = '<ul><li class="custom_class">item1</li><li>item2</li></ul>' | |
46 | + article.comment_paragraph_plugin_activate = true | |
47 | + article.save! | |
48 | + assert_mark_paragraph article.body, 'li', 'item1' | |
49 | + assert_mark_paragraph article.body, 'li', 'item2' | |
50 | + end | |
51 | + | |
52 | + should 'parse inner html li when activate comment paragraph' do | |
53 | + article.body = '<div><ul><li class="custom_class">item1</li><li>item2</li></ul><div>' | |
54 | + article.comment_paragraph_plugin_activate = true | |
55 | + article.save! | |
56 | + assert_mark_paragraph article.body, 'li', 'item1' | |
57 | + assert_mark_paragraph article.body, 'li', 'item2' | |
58 | + end | |
59 | + | |
60 | + should 'do not remove macro div when disable comment paragraph' do | |
61 | + article.body = "<p>paragraph 1</p>" | |
62 | + article.comment_paragraph_plugin_activate = true | |
63 | + article.save! | |
64 | + assert_mark_paragraph article.body, 'p', 'paragraph 1' | |
65 | + article.comment_paragraph_plugin_activate = false | |
66 | + article.save! | |
67 | + assert_mark_paragraph article.body, 'p', 'paragraph 1' | |
68 | + end | |
69 | + | |
70 | + should 'parse html when activate comment paragraph' do | |
71 | + article.body = "<p>paragraph 1</p><p>paragraph 2</p>" | |
72 | + article.comment_paragraph_plugin_activate = false | |
73 | + article.save! | |
74 | + assert_equal "<p>paragraph 1</p><p>paragraph 2</p>", article.body | |
75 | + article.comment_paragraph_plugin_activate = true | |
76 | + article.save! | |
77 | + | |
78 | + assert_mark_paragraph article.body, 'p', 'paragraph 1' | |
79 | + assert_mark_paragraph article.body, 'p', 'paragraph 2' | |
80 | + end | |
81 | + | |
82 | + should 'parse html when add new paragraph' do | |
83 | + article.body = "<p>paragraph 1</p>" | |
84 | + article.comment_paragraph_plugin_activate = true | |
85 | + article.save! | |
86 | + assert_mark_paragraph article.body, 'p', 'paragraph 1' | |
87 | + | |
88 | + article.body += "<p>paragraph 2</p>" | |
89 | + article.save! | |
90 | + assert_mark_paragraph article.body, 'p', 'paragraph 1' | |
91 | + assert_mark_paragraph article.body, 'p', 'paragraph 2' | |
92 | + end | |
93 | + | |
94 | + should 'keep already marked paragraph attributes when add new paragraph' do | |
95 | + article.body = "<p>paragraph 1</p>" | |
96 | + article.comment_paragraph_plugin_activate = true | |
97 | + article.save! | |
98 | + assert_mark_paragraph article.body, 'p', 'paragraph 1' | |
99 | + uuid = Nokogiri::HTML(article.body).at('p span.paragraph_comment')['data-macro-paragraph_uuid'] | |
100 | + | |
101 | + article.body += "<p>paragraph 2</p>" | |
102 | + article.save! | |
103 | + assert_mark_paragraph article.body, 'p', 'paragraph 1' | |
104 | + new_uuid = Nokogiri::HTML(article.body).at('p span.paragraph_comment')['data-macro-paragraph_uuid'] | |
105 | + assert_equal uuid, new_uuid | |
106 | + end | |
107 | + | |
108 | + should 'not parse empty element' do | |
109 | + article.body = '<div></div>' | |
110 | + article.comment_paragraph_plugin_activate = true | |
111 | + article.save! | |
112 | + assert_equal '<div></div>', article.body | |
113 | + end | |
114 | + | |
115 | + should 'be enabled if plugin is enabled and article is a kind of TextArticle' do | |
116 | + assert article.comment_paragraph_plugin_enabled? | |
117 | + end | |
118 | + | |
119 | + should 'not be enabled if plugin is not enabled' do | |
120 | + environment.disable_plugin(CommentParagraphPlugin) | |
121 | + assert !article.comment_paragraph_plugin_enabled? | |
122 | + end | |
123 | + | |
124 | + should 'not be enabled if article if not a kind of TextArticle' do | |
125 | + article = fast_create(Article, :profile_id => profile.id) | |
126 | + assert !article.comment_paragraph_plugin_enabled? | |
127 | + end | |
128 | + | |
129 | + should 'not be activated by default' do | |
130 | + article = fast_create(TextArticle, :profile_id => profile.id) | |
131 | + assert !article.comment_paragraph_plugin_activated? | |
132 | + end | |
133 | + | |
134 | + should 'be activated by default if it is enabled and activation mode is auto' do | |
135 | + settings = Noosfero::Plugin::Settings.new(environment, CommentParagraphPlugin) | |
136 | + settings.activation_mode = 'auto' | |
137 | + settings.save! | |
138 | + article = TextArticle.create!(:profile => profile, :name => 'title') | |
139 | + assert article.comment_paragraph_plugin_activated? | |
140 | + end | |
141 | + | |
142 | + should 'be activated when forced' do | |
143 | + article.comment_paragraph_plugin_activate = true | |
144 | + assert article.comment_paragraph_plugin_activated? | |
145 | + end | |
146 | + | |
147 | + should 'not be activated if plugin is not enabled' do | |
148 | + article.comment_paragraph_plugin_activate = true | |
149 | + environment.disable_plugin(CommentParagraphPlugin) | |
150 | + assert !article.comment_paragraph_plugin_enabled? | |
151 | + end | |
152 | + | |
153 | + should 'append not_logged to cache key when user is not logged in' do | |
154 | + assert_match /-not_logged-/, article.cache_key | |
155 | + end | |
156 | + | |
157 | + should 'append logged_in to cache key when user is logged in' do | |
158 | + assert_match /-logged_in-/, article.cache_key({}, fast_create(Person)) | |
159 | + end | |
160 | + | |
161 | + should 'return paragraph content passing paragraph uuid' do | |
162 | + uuid = 0 | |
163 | + article.body = "<div class=\"macro\" data-macro-paragraph_uuid=#{uuid}>paragraph content</div>" | |
164 | + assert_equal 'paragraph content', article.comment_paragraph_plugin_paragraph_content(uuid) | |
165 | + end | |
166 | + | |
167 | + should 'return nil as paragraph content when paragraph uuid is not found' do | |
168 | + uuid = 0 | |
169 | + article.body = "<div class=\"macro\" data-macro-paragraph_uuid=#{uuid}>paragraph content</div>" | |
170 | + assert_equal nil, article.comment_paragraph_plugin_paragraph_content(1) | |
171 | + end | |
172 | + | |
173 | +end | ... | ... |
plugins/comment_paragraph/test/unit/comment_paragraph_plugin_test.rb
0 → 100644
... | ... | @@ -0,0 +1,87 @@ |
1 | +require_relative '../test_helper' | |
2 | +include ActionView::Helpers::FormTagHelper | |
3 | + | |
4 | +class CommentParagraphPluginTest < ActiveSupport::TestCase | |
5 | + | |
6 | + def setup | |
7 | + @environment = Environment.default | |
8 | + @user = create_user('testuser').person | |
9 | + context = mock() | |
10 | + context.stubs(:user).returns(@user) | |
11 | + @plugin = CommentParagraphPlugin.new(context) | |
12 | + end | |
13 | + | |
14 | + attr_reader :environment, :plugin, :user | |
15 | + | |
16 | + should 'have a name' do | |
17 | + assert_not_equal Noosfero::Plugin.plugin_name, CommentParagraphPlugin::plugin_name | |
18 | + end | |
19 | + | |
20 | + should 'describe yourself' do | |
21 | + assert_not_equal Noosfero::Plugin.plugin_description, CommentParagraphPlugin::plugin_description | |
22 | + end | |
23 | + | |
24 | + should 'have a js file' do | |
25 | + assert !plugin.js_files.blank? | |
26 | + end | |
27 | + | |
28 | + should 'have stylesheet' do | |
29 | + assert plugin.stylesheet? | |
30 | + end | |
31 | + | |
32 | + should 'not add comment_paragraph_selected_area if comment_paragraph_selected_area is blank' do | |
33 | + comment = Comment.new | |
34 | + comment.comment_paragraph_selected_area = "" | |
35 | + comment.paragraph_uuid = 2 | |
36 | + cpp = CommentParagraphPlugin.new | |
37 | + prok = cpp.comment_form_extra_contents({:comment=>comment, :paragraph_uuid=>4}) | |
38 | + assert_nil /comment_paragraph_selected_area/.match(prok.call.inspect) | |
39 | + end | |
40 | + | |
41 | + should 'display button to toggle comment paragraph for users which can edit the article' do | |
42 | + profile = fast_create(Profile) | |
43 | + article = fast_create(Article, :profile_id => profile.id) | |
44 | + article.expects(:comment_paragraph_plugin_enabled?).returns(true) | |
45 | + article.expects(:allow_edit?).with(user).returns(true) | |
46 | + | |
47 | + assert_not_equal [], plugin.article_extra_toolbar_buttons(article) | |
48 | + end | |
49 | + | |
50 | + should 'not display button to toggle comment paragraph for users which can not edit the article' do | |
51 | + profile = fast_create(Profile) | |
52 | + article = fast_create(Article, :profile_id => profile.id) | |
53 | + article.expects(:comment_paragraph_plugin_enabled?).returns(true) | |
54 | + article.expects(:allow_edit?).with(user).returns(false) | |
55 | + | |
56 | + assert_equal [], plugin.article_extra_toolbar_buttons(article) | |
57 | + end | |
58 | + | |
59 | + should 'not display button to toggle comment paragraph if plugin is not enabled' do | |
60 | + profile = fast_create(Profile) | |
61 | + article = fast_create(Article, :profile_id => profile.id) | |
62 | + article.expects(:comment_paragraph_plugin_enabled?).returns(false) | |
63 | + | |
64 | + assert_equal [], plugin.article_extra_toolbar_buttons(article) | |
65 | + end | |
66 | + | |
67 | + should 'display Activate Comments title if comment paragraph plugin is activated' do | |
68 | + profile = fast_create(Profile) | |
69 | + article = fast_create(Article, :profile_id => profile.id) | |
70 | + article.expects(:comment_paragraph_plugin_enabled?).returns(true) | |
71 | + article.expects(:allow_edit?).with(user).returns(true) | |
72 | + article.expects(:comment_paragraph_plugin_activated?).returns(false) | |
73 | + | |
74 | + assert_equal 'Activate Comments', plugin.article_extra_toolbar_buttons(article)[:title] | |
75 | + end | |
76 | + | |
77 | + should 'display Deactivate Comments title if comment paragraph plugin is deactivated' do | |
78 | + profile = fast_create(Profile) | |
79 | + article = fast_create(Article, :profile_id => profile.id) | |
80 | + article.expects(:comment_paragraph_plugin_enabled?).returns(true) | |
81 | + article.expects(:allow_edit?).with(user).returns(true) | |
82 | + article.expects(:comment_paragraph_plugin_activated?).returns(true) | |
83 | + | |
84 | + assert_equal 'Deactivate Comments', plugin.article_extra_toolbar_buttons(article)[:title] | |
85 | + end | |
86 | + | |
87 | +end | ... | ... |
... | ... | @@ -0,0 +1,26 @@ |
1 | +require_relative '../test_helper' | |
2 | + | |
3 | +class CommentTest < ActiveSupport::TestCase | |
4 | + | |
5 | + def setup | |
6 | + profile = fast_create(Community) | |
7 | + @article = fast_create(Article, :profile_id => profile.id) | |
8 | + end | |
9 | + | |
10 | + attr_reader :article | |
11 | + | |
12 | + should 'return comments that belongs to a specified paragraph' do | |
13 | + comment1 = fast_create(Comment, :paragraph_uuid => '1', :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') | |
17 | + end | |
18 | + | |
19 | + should 'return comments that do not belongs to any paragraph' do | |
20 | + comment1 = fast_create(Comment, :paragraph_uuid => '1', :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) | |
23 | + assert_equal [comment2], article.comments.without_paragraph | |
24 | + end | |
25 | + | |
26 | +end | ... | ... |
plugins/comment_paragraph/test/unit/tinymce_helper_test.rb
0 → 100644
... | ... | @@ -0,0 +1,27 @@ |
1 | +require_relative '../test_helper' | |
2 | + | |
3 | +class TinymceHelperTest < ActiveSupport::TestCase | |
4 | + | |
5 | + include TinymceHelper | |
6 | + | |
7 | + def setup | |
8 | + expects(:top_url).returns('/') | |
9 | + expects(:tinymce_language).returns('en') | |
10 | + @plugins = mock | |
11 | + @plugins.expects(:dispatch).returns([]).at_least_once | |
12 | + @environment = Environment.default | |
13 | + end | |
14 | + | |
15 | + attr_accessor :top_url, :environment | |
16 | + | |
17 | + should 'set keep_styles to false in tinymce options' do | |
18 | + environment.enable_plugin(CommentParagraphPlugin) | |
19 | + assert_match /"keep_styles":false/, tinymce_init_js | |
20 | + end | |
21 | + | |
22 | + should 'do not set keep_styles to false when plugin is not enabled' do | |
23 | + environment.disable_plugin(CommentParagraphPlugin) | |
24 | + assert_no_match /"keep_styles":false/, tinymce_init_js | |
25 | + end | |
26 | + | |
27 | +end | ... | ... |
plugins/comment_paragraph/views/comment_paragraph_plugin_admin/index.html.erb
0 → 100644
... | ... | @@ -0,0 +1,25 @@ |
1 | +<div class="comment-paragraph-plugin-settings"> | |
2 | + <h1><%= _("Comment Paragraph Plugin Settings") %></h1> | |
3 | + | |
4 | + <%= form_for(:settings) do |f| %> | |
5 | + | |
6 | + <div class="activation-mode"> | |
7 | + <h4><%= _('Activation Mode') %></h4> | |
8 | + <div class="auto"> | |
9 | + <%= f.radio_button(:activation_mode, 'auto') %> | |
10 | + <span class="name"><strong><%= _('Auto') %></strong></span> | |
11 | + <span class="detail"><%= _('(all text articles will be activated by default)') %></span> | |
12 | + </div> | |
13 | + <div class="manual"> | |
14 | + <%= f.radio_button(:activation_mode, 'manual') %> | |
15 | + <span class="name"><strong><%= _('Manual') %></strong></span> | |
16 | + <span class="detail"><%= _('(click on "Activate Comment Paragraph" )') %></span> | |
17 | + </div> | |
18 | + </div> | |
19 | + | |
20 | + <% button_bar do %> | |
21 | + <%= submit_button(:save, _('Save'), :cancel => {:controller => 'plugins', :action => 'index'}) %> | |
22 | + <% end %> | |
23 | + | |
24 | + <% end %> | |
25 | +</div> | ... | ... |
plugins/comment_paragraph/views/comment_paragraph_plugin_profile/_comment_paragraph.html.erb
0 → 100644
... | ... | @@ -0,0 +1,24 @@ |
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 %> | |
4 | + </div> | |
5 | + <div class="side-comments-counter-container"> | |
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> | |
10 | + </div> | |
11 | + </div> | |
12 | + | |
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> | |
23 | + </div> | |
24 | +</div> | ... | ... |
plugins/comment_paragraph/views/comment_paragraph_plugin_profile/comment_extra.html.erb
0 → 100644
... | ... | @@ -0,0 +1,3 @@ |
1 | +<input type="hidden" value="<%= comment.comment_paragraph_selected_area%>" class="paragraph_comment_area" /> | |
2 | +<input type="hidden" value="<%= comment.paragraph_uuid%>" class="paragraph_uuid" /> | |
3 | +<input type="hidden" value="<%= comment.comment_paragraph_selected_content%>" class="paragraph_selected_content" /> | ... | ... |
plugins/comment_paragraph/views/tasks/_approve_comment_accept_details.html.erb
0 → 100644
... | ... | @@ -0,0 +1,17 @@ |
1 | +<p> | |
2 | + <b><%= _('Title: ') %></b> | |
3 | + <%= task.comment.title %> | |
4 | +</p> | |
5 | +<p> | |
6 | + <%= task.comment.body %> | |
7 | +</p> | |
8 | + | |
9 | +<% if task.comment.paragraph_uuid.present? %> | |
10 | +<div> | |
11 | + <b><%= _('Paragraph: ') %></b> | |
12 | + <div> | |
13 | + <% #FIXME save paragraph content in before_save callback %> | |
14 | + <%= task.comment.source.comment_paragraph_plugin_paragraph_content(task.comment.paragraph_uuid) %> | |
15 | + </div> | |
16 | +</div> | |
17 | +<% end %> | ... | ... |