diff --git a/data/System/MetaCommentPlugin.txt b/data/System/MetaCommentPlugin.txt index 7476c9c..aa5af10 100644 --- a/data/System/MetaCommentPlugin.txt +++ b/data/System/MetaCommentPlugin.txt @@ -1,4 +1,4 @@ -%META:TOPICINFO{author="ProjectContributor" comment="" date="1425048174" format="1.1" version="1"}% +%META:TOPICINFO{author="ProjectContributor" comment="" date="1574759516" format="1.1" version="1"}% ---+!! MetaCommentPlugin %FORMFIELD{"Description"}% @@ -182,6 +182,7 @@ Parameters: * skip: number of comments to skip in the list, useful for pagination * limit: maximum number of comments to list, useful for pagination * singular: title used when only one comment is present, defaults to =One comment= + * rev, revision: specify the version of the topic to render its comments, defaults to most recent revision * plural: title when there are more than one comment, defaults to ="$count comments= * mindate: minimum date of a comment to be displayed * maxdate: maximum date of a comment to be displayed @@ -263,6 +264,10 @@ The parameters =THEWEB=, =WHERE= and =LIMIT= are optional where %$DEPENDENCIES% ---++ Change History +%TABLE{columnwidths="7em" tablewidth="100%"}% +| 26 Nov 2019: | 5.10 - added rev parameter to display comments of previous revisions of a topic; \ + added "delete all", "approve all", "mark all" features to moderate comments in bunches; \ + improved [[Foswiki:Extensions/SolrPlugin][SolrPlugin]] integration | | 28 May 2018: | 5.03 - depend on new [[Foswiki:Extensions/TopicTitlePlugin][TopicTitlePlugin]] | | 05 Mar 2018: | 5.01 - cleaned up templates | | 16 Jan 2017: | 5.00 - implemented a registerCommentHandler() api to let other plugins interact with comment changes | @@ -311,10 +316,10 @@ The parameters =THEWEB=, =WHERE= and =LIMIT= are optional where fixed recoding of received data to the site's own charset; \ improved the way photos are gathered | -%META:FILEATTACHMENT{name="MetaCommentSnap1.jpeg" attachment="MetaCommentSnap1.jpeg" attr="h" comment="" date="1425048174" path="MetaCommentSnap1.jpeg" size="51144" user="ProjectContributor" version="1"}% +%META:FILEATTACHMENT{name="MetaCommentSnap1.jpeg" attachment="MetaCommentSnap1.jpeg" attr="h" comment="" date="1574759516" path="MetaCommentSnap1.jpeg" size="51144" user="ProjectContributor" version="1"}% %META:FORM{name="PackageForm"}% %META:FIELD{name="Author" title="Author" value="Foswiki:Main/MichaelDaum"}% -%META:FIELD{name="Copyright" title="Copyright" value="2009-2017, Michael Daum http://michaeldaumconsulting.com"}% +%META:FIELD{name="Copyright" title="Copyright" value="2009-2019, Michael Daum http://michaeldaumconsulting.com"}% %META:FIELD{name="Description" title="Description" value="%25$SHORTDESCRIPTION%25"}% %META:FIELD{name="Home" title="Home" value="https://foswiki.org/Extensions/MetaCommentPlugin"}% %META:FIELD{name="License" title="License" value="[[http://www.gnu.org/licenses/gpl.html][GPL (Gnu General Public License)]]"}% diff --git a/lib/Foswiki/Plugins/MetaCommentPlugin.pm b/lib/Foswiki/Plugins/MetaCommentPlugin.pm index 3f26f75..40a3bdc 100644 --- a/lib/Foswiki/Plugins/MetaCommentPlugin.pm +++ b/lib/Foswiki/Plugins/MetaCommentPlugin.pm @@ -1,6 +1,6 @@ # Plugin for Foswiki - The Free and Open Source Wiki, http://foswiki.org/ # -# Copyright (C) 2009-2018 Michael Daum http://michaeldaumconsulting.com +# Copyright (C) 2009-2019 Michael Daum http://michaeldaumconsulting.com # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -19,8 +19,8 @@ use Foswiki::Func (); use Foswiki::Plugins (); use Foswiki::Contrib::JsonRpcContrib (); -our $VERSION = '5.03'; -our $RELEASE = '28 May 2018'; +our $VERSION = '5.10'; +our $RELEASE = '26 Nov 2019'; our $SHORTDESCRIPTION = 'An easy to use comment system'; our $NO_PREFS_IN_TOPIC = 1; our $core; @@ -55,6 +55,18 @@ sub initPlugin { return getCore(shift)->jsonRpcDeleteComment(@_); }); + Foswiki::Contrib::JsonRpcContrib::registerMethod("MetaCommentPlugin", "deleteAllComments", sub { + return getCore(shift)->jsonRpcDeleteAllComments(@_); + }); + + Foswiki::Contrib::JsonRpcContrib::registerMethod("MetaCommentPlugin", "approveAllComments", sub { + return getCore(shift)->jsonRpcApproveAllComments(@_); + }); + + Foswiki::Contrib::JsonRpcContrib::registerMethod("MetaCommentPlugin", "markAllComments", sub { + return getCore(shift)->jsonRpcMarkAllComments(@_); + }); + Foswiki::Contrib::JsonRpcContrib::registerMethod("MetaCommentPlugin", "markComment", sub { return getCore(shift)->jsonRpcMarkComment(@_); }); diff --git a/lib/Foswiki/Plugins/MetaCommentPlugin/Core.pm b/lib/Foswiki/Plugins/MetaCommentPlugin/Core.pm index b95d266..5ff7b46 100644 --- a/lib/Foswiki/Plugins/MetaCommentPlugin/Core.pm +++ b/lib/Foswiki/Plugins/MetaCommentPlugin/Core.pm @@ -1,6 +1,6 @@ # Plugin for Foswiki - The Free and Open Source Wiki, http://foswiki.org/ # -# Copyright (C) 2009-2018 Michael Daum http://michaeldaumconsulting.com +# Copyright (C) 2009-2019 Michael Daum http://michaeldaumconsulting.com # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License @@ -72,7 +72,8 @@ sub jsonRpcGetComment { throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Access denied") unless Foswiki::Func::checkAccessPermission("VIEW", $this->{wikiName}, undef, $topic, $web); - my ($meta, $text) = Foswiki::Func::readTopic($web, $topic); + my $rev = $request->param('rev'); + my ($meta, $text) = Foswiki::Func::readTopic($web, $topic, $rev); my $id = $request->param('comment_id') || ''; my $comment = $meta->get('COMMENT', $id); @@ -232,7 +233,7 @@ sub jsonRpcUpdateComment { my $fingerPrint = getFingerPrint($this->{wikiName}); - throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Acccess denied") + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Access denied") unless $isModerator || $fingerPrint eq ($comment->{fingerPrint}||''); my $title = $request->param('title') || ''; @@ -318,6 +319,129 @@ sub jsonRpcDeleteComment { return; } +############################################################################## +sub jsonRpcDeleteAllComments { + my ($this, $request) = @_; + + my $web = $this->{baseWeb}; + my $topic = $this->{baseTopic}; + + throw Foswiki::Contrib::JsonRpcContrib::Error(404, "Topic $web.$topic does not exist") + unless Foswiki::Func::topicExists($web, $topic); + + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Access denied") + unless Foswiki::Func::checkAccessPermission("VIEW", $this->{wikiName}, undef, $topic, $web); + + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Access denied") + unless Foswiki::Func::checkAccessPermission('COMMENT', $this->{wikiName}, undef, $topic, $web) || + Foswiki::Func::checkAccessPermission('CHANGE', $this->{wikiName}, undef, $topic, $web); + + my ($meta, $text) = Foswiki::Func::readTopic($web, $topic); + my $isModerator = $this->isModerator($web, $topic, $meta); + + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Discussion closed") + unless $isModerator || (Foswiki::Func::getPreferencesValue("COMMENTSTATE")||'open') ne 'closed'; + + my $fingerPrint = getFingerPrint($this->{wikiName}); + + # check all comments + foreach my $comment ($meta->find('COMMENT')) { + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Acccess denied") + unless $isModerator || $fingerPrint eq ($comment->{fingerPrint}||''); + } + + # remove all comments + $meta->remove('COMMENT'); + + Foswiki::Func::saveTopic($web, $topic, $meta, $text, {ignorepermissions=>1, minor=>1}) unless DRY; + $this->triggerEvent("commentdeleteall", $web, $topic); + + return; +} + +############################################################################## +sub jsonRpcApproveAllComments { + my ($this, $request) = @_; + + my $web = $this->{baseWeb}; + my $topic = $this->{baseTopic}; + + throw Foswiki::Contrib::JsonRpcContrib::Error(404, "Topic $web.$topic does not exist") + unless Foswiki::Func::topicExists($web, $topic); + + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Access denied") + unless Foswiki::Func::checkAccessPermission("VIEW", $this->{wikiName}, undef, $topic, $web); + + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Access denied") + unless Foswiki::Func::checkAccessPermission('COMMENT', $this->{wikiName}, undef, $topic, $web) || + Foswiki::Func::checkAccessPermission('CHANGE', $this->{wikiName}, undef, $topic, $web); + + my ($meta, $text) = Foswiki::Func::readTopic($web, $topic); + my $isModerator = $this->isModerator($web, $topic, $meta); + + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Discussion closed") + unless $isModerator || (Foswiki::Func::getPreferencesValue("COMMENTSTATE")||'open') ne 'closed'; + + my $fingerPrint = getFingerPrint($this->{wikiName}); + + # check all comments + foreach my $comment ($meta->find('COMMENT')) { + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Acccess denied") + unless $isModerator || $fingerPrint eq ($comment->{fingerPrint}||''); + } + + # approve all comments + foreach my $comment ($meta->find('COMMENT')) { + $comment->{state} = "approved"; + } + + Foswiki::Func::saveTopic($web, $topic, $meta, $text, {ignorepermissions=>1, minor=>1}) unless DRY; + $this->triggerEvent("commentapproveall", $web, $topic); + + return; +} +############################################################################## +sub jsonRpcMarkAllComments { + my ($this, $request) = @_; + + my $web = $this->{baseWeb}; + my $topic = $this->{baseTopic}; + + throw Foswiki::Contrib::JsonRpcContrib::Error(404, "Topic $web.$topic does not exist") + unless Foswiki::Func::topicExists($web, $topic); + + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Access denied") + unless Foswiki::Func::checkAccessPermission("VIEW", $this->{wikiName}, undef, $topic, $web); + + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Access denied") + unless Foswiki::Func::checkAccessPermission('COMMENT', $this->{wikiName}, undef, $topic, $web) || + Foswiki::Func::checkAccessPermission('CHANGE', $this->{wikiName}, undef, $topic, $web); + + my ($meta, $text) = Foswiki::Func::readTopic($web, $topic); + my $isModerator = $this->isModerator($web, $topic, $meta); + + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Discussion closed") + unless $isModerator || (Foswiki::Func::getPreferencesValue("COMMENTSTATE")||'open') ne 'closed'; + + my $fingerPrint = getFingerPrint($this->{wikiName}); + + # check all comments + foreach my $comment ($meta->find('COMMENT')) { + throw Foswiki::Contrib::JsonRpcContrib::Error(401, "Acccess denied") + unless $isModerator || $fingerPrint eq ($comment->{fingerPrint}||''); + } + + # mark all comments + foreach my $comment ($meta->find('COMMENT')) { + $this->markComment($comment); + } + + Foswiki::Func::saveTopic($web, $topic, $meta, $text, {ignorepermissions=>1, minor=>1}) unless DRY; + $this->triggerEvent("commentmarkall", $web, $topic); + + return; +} + ############################################################################## sub jsonRpcMarkComment { my ($this, $request) = @_; @@ -381,6 +505,20 @@ sub isModerator { return 0; } +############################################################################## +sub isModerated { + my ($this, $web, $topic, $meta) = @_; + + ($meta) = Foswiki::Func::readTopic($web, $topic) unless defined $meta; + + my $prefs = $this->{session}->{prefs}->loadPreferences($meta); + my $isModerated = $prefs->get("COMMENTMODERATION"); + $isModerated = $prefs->getLocal("COMMENTMODERATION") unless defined $isModerated; + $isModerated = Foswiki::Func::getPreferencesValue("COMMENTMODERATION", $web) unless defined $isModerated; + + return Foswiki::Func::isTrue($isModerated, 0); +} + ############################################################################## sub METACOMMENTS { my ($this, $params, $topic, $web) = @_; @@ -431,9 +569,10 @@ sub METACOMMENTS { $params->{threaded} = 'off' unless defined $params->{threaded}; $params->{isclosed} = ((Foswiki::Func::getPreferencesValue("COMMENTSTATE")||'open') eq 'closed')?1:0; + $params->{rev} //= $params->{revision}; # get all comments data - my ($meta) = Foswiki::Func::readTopic($theWeb, $theTopic); + my ($meta) = Foswiki::Func::readTopic($theWeb, $theTopic, $params->{rev}); my $comments = $this->getComments($theWeb, $theTopic, $meta, $params); return '' unless $comments; @@ -465,11 +604,11 @@ sub METACOMMENTS { ); # oh well - $result =~ s/\$perce?nt/\%/go; - $result =~ s/\$nop//go; - $result =~ s/\$n/\n/go; - $result =~ s/\$dollar/\$/go; - $result =~ s/\\\\/\\/go; + $result =~ s/\$perce?nt/\%/g; + $result =~ s/\$nop//g; + $result =~ s/\$n/\n/g; + $result =~ s/\$dollar/\$/g; + $result =~ s/\\\\/\\/g; return $result; } @@ -478,17 +617,17 @@ sub METACOMMENTS { sub getComments { my ($this, $web, $topic, $meta, $params) = @_; - ($meta) = Foswiki::Func::readTopic($web, $topic) unless defined $meta; + ($meta) = Foswiki::Func::readTopic($web, $topic, $params->{rev}) unless defined $meta; my $isModerator = $this->isModerator($web, $topic, $meta); - #writeDebug("called getComments"); + writeDebug("called getComments web=$web"); my @topics = (); if (defined $params->{search}) { @topics = $this->getTopics($web, $params->{search}, $params); } else { - return undef unless Foswiki::Func::checkAccessPermission('VIEW', $this->{wikiName}, undef, $topic, $web); + return unless Foswiki::Func::checkAccessPermission('VIEW', $this->{wikiName}, undef, $topic, $web); push @topics, $topic; } @@ -496,13 +635,13 @@ sub getComments { my %comments = (); foreach my $thisTopic (@topics) { - my ($meta) = Foswiki::Func::readTopic($web, $thisTopic); + ($meta) = Foswiki::Func::readTopic($web, $thisTopic, $params->{rev}); my $isModerated = $this->isModerated($web, $thisTopic, $meta); my @comments = $meta->find('COMMENT'); foreach my $comment (@comments) { my $id = $comment->{name}; - #writeDebug("id=$id, moderation=$params->{moderation}, isModerator=$isModerator, author=$comment->{author}, wikiName=$this->{wikiName}, state=$comment->{state}, isclosed=$params->{isclosed}"); + writeDebug("id=$id, moderation=$params->{moderation}, isModerator=$isModerator, author=$comment->{author}, wikiName=$this->{wikiName}, state=$comment->{state}, isclosed=$params->{isclosed}"); next if $params->{author} && $comment->{author} !~ /$params->{author}/; next if $params->{mindate} && $comment->{date} < $params->{mindate}; next if $params->{maxdate} && $comment->{date} > $params->{maxdate}; @@ -529,7 +668,7 @@ sub getComments { $comment->{topic} = $thisTopic; $comment->{web} = $web; - #writeDebug("adding $id"); + writeDebug("adding $id"); $comments{$thisTopic.'::'.$id} = $comment; } } @@ -583,7 +722,6 @@ sub getTopics_DBQUERY { my $search = new Foswiki::Contrib::DBCacheContrib::Search($where); return unless $search; - my $db = Foswiki::Plugins::DBCachePlugin::getDB($web); my @topicNames = $db->getKeys(); my @selectedTopics = (); @@ -761,10 +899,10 @@ sub expandVariables { $text =~ s/\$$key\b/$val/g; } -# $text =~ s/\$perce?nt/\%/go; -# $text =~ s/\$nop//go; -# $text =~ s/\$n/\n/go; -# $text =~ s/\$dollar/\$/go; +# $text =~ s/\$perce?nt/\%/g; +# $text =~ s/\$nop//g; +# $text =~ s/\$n/\n/g; +# $text =~ s/\$dollar/\$/g; return $text; } @@ -773,7 +911,10 @@ sub expandVariables { sub triggerEvent { my ($this, $eventName, $web, $topic, $comment) = @_; - my $message = "state=$comment->{state} title=".($comment->{title}||'').' text='.substr($comment->{text}, 0, 200); + my $message = ""; + if ($comment) { + $message = "state=$comment->{state} title=".($comment->{title}||'').' text='.substr($comment->{text}, 0, 200); + } if (defined &Foswiki::Func::writeEvent) { Foswiki::Func::writeEvent($eventName, $message); @@ -787,7 +928,7 @@ sub triggerEvent { writeDebug("executing $function"); try { - no strict 'refs'; + no strict 'refs'; ## no critics $result = &$function($eventName, $web, $topic, $comment, $commentHandler->{options}); use strict 'refs'; } catch Error::Simple with { @@ -798,20 +939,6 @@ sub triggerEvent { } } -############################################################################## -sub isModerated { - my ($this, $web, $topic, $meta) = @_; - - ($meta) = Foswiki::Func::readTopic($web, $topic) unless defined $meta; - - my $prefs = $this->{session}->{prefs}->loadPreferences($meta); - my $isModerated = $prefs->get("COMMENTMODERATION"); - $isModerated = $prefs->getLocal("COMMENTMODERATION") unless defined $isModerated; - $isModerated = Foswiki::Func::getPreferencesValue("COMMENTMODERATION", $web) unless defined $isModerated; - - return Foswiki::Func::isTrue($isModerated, 0); -} - ############################################################################## sub afterLikeHandler { my ($this, $web, $topic, $type, $id, $user, $likes, $dislikes) = @_; @@ -849,6 +976,8 @@ sub solrIndexTopicHandler { foreach my $comment (@comments) { + $indexer->log("Indexing comment $comment->{name} at $web.$topic"); + # set doc fields my $createDate = Foswiki::Func::formatTime($comment->{date}, 'iso', 'gmtime'); my $date = defined($comment->{modified}) ? Foswiki::Func::formatTime($comment->{modified}, 'iso', 'gmtime') : $createDate; @@ -871,11 +1000,13 @@ sub solrIndexTopicHandler { $commentDoc->add_fields( 'id' => $id, 'name' => $comment->{name}, - 'type' => 'comment', + 'type' => 'metadata', + 'form' => 'Comment', 'web' => $web, 'topic' => $topic, 'webtopic' => $webtopic, 'author' => $comment->{author}, + 'author_title' => Foswiki::Func::getTopicTitle($Foswiki::cfg{UsersWebName}, $comment->{author}), # 'author_url' => $comment->{author_url}, 'contributor' => $comment->{author}, 'date' => $date, @@ -888,6 +1019,7 @@ sub solrIndexTopicHandler { 'container_id' => $web . '.' . $topic, 'container_url' => Foswiki::Func::getViewUrl($web, $topic), 'container_title' => Foswiki::Func::getTopicTitle($web, $topic, undef, $meta), + 'field_TopicType_lst' => 'Comment', ); my $contentLanguage = $indexer->getContentLanguage($web, $topic); @@ -910,9 +1042,12 @@ sub solrIndexTopicHandler { $commentDoc->add_fields(@aclFields) if @aclFields; } + $doc->add_fields('contributor' => $comment->{author}); + + # SMELL: why these two $doc->add_fields('catchall' => $title); $doc->add_fields('catchall' => $comment->{text}); - $doc->add_fields('contributor' => $comment->{author}); + # add the document to the index try { diff --git a/pub/System/MetaCommentPlugin/metacomment.uncompressed.css b/pub/System/MetaCommentPlugin/metacomment.uncompressed.css index 20a13f1..4f94e63 100644 --- a/pub/System/MetaCommentPlugin/metacomment.uncompressed.css +++ b/pub/System/MetaCommentPlugin/metacomment.uncompressed.css @@ -2,11 +2,20 @@ margin:1.3846em 0em 0em; } +.cmtGlobalControls a { + float:left; + text-decoration:none; + padding:2px 2px 0px 2px; + margin:0 1em 0 0; +} + .cmtRssFeed { float:right; text-decoration:none; padding:2px 2px 0px 2px; + margin:0 0 0 1em; } +.cmtDeleteAll:hover, .cmtRssFeed:hover { background-color:#eee; color:inherit; @@ -17,6 +26,16 @@ margin:1em 0em; /* 18px 0px */ } +.cmtCommentsContainer .cmtApproveAll, +.cmtCommentsContainer .cmtDeleteAll { + display:none; +} + +.cmtCommentsIsModerator .cmtApproveAll, +.cmtCommentsIsModerator .cmtDeleteAll { + display:inline; +} + .cmtCommentContainer { margin:1.3846em 0em; padding:1.3076em 1.3846em; @@ -104,6 +123,9 @@ a.cmtPermLink, .cmtStyle_insidetab .cmtAddComment h2 { display:none; } +h2.cmtCounter .jqTwisty { + margin-left:0.5em; +} .cmtStyle_insidetab .twistyPlugin { display:none; /* switched on by js */ diff --git a/pub/System/MetaCommentPlugin/metacomment.uncompressed.js b/pub/System/MetaCommentPlugin/metacomment.uncompressed.js index 04c63d1..cc3c0d5 100644 --- a/pub/System/MetaCommentPlugin/metacomment.uncompressed.js +++ b/pub/System/MetaCommentPlugin/metacomment.uncompressed.js @@ -2,7 +2,7 @@ Foswiki - The Free and Open Source Wiki, http://foswiki.org/ -(c)opyright 2010-2015 Michael Daum http://michaeldaumconsulting.com +(c)opyright 2010-2019 Michael Daum http://michaeldaumconsulting.com are listed in the AUTHORS file in the root of this distribution. NOTE: Please extend that file, not this notice. @@ -20,7 +20,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. As per the GPL, removal of this notice is prohibited. */ -'use strict'; +"use strict"; jQuery(function($) { var doneLoadDialogs = false; @@ -30,7 +30,6 @@ jQuery(function($) { defaults = { topic: foswiki.getPreference("TOPIC"), web: foswiki.getPreference("WEB"), - submitMessage: "Submitting comment", updateMessage: "Updating comment", deleteMessage: "Deleting comment", approveMessage: "Approving comment", @@ -90,122 +89,22 @@ jQuery(function($) { } ); - /* ajaxify add and reply forms ******************************************/ - $(".cmtAddCommentForm, .cmtReplyCommentForm").livequery(function() { - var $form = $(this); + /* ajaxify forms ********************************************************/ + $(".cmtJsonRpcForm").livequery(function() { + var $form = $(this), msg = $form.data("message"); $form.ajaxForm({ - dataType:"json", - beforeSubmit: function() { - $("#cmtReplyComment").dialog("close"); - $.blockUI({ - message:"

"+opts.submitMessage+" ...

", - fadeIn: 0, - fadeOut: 0 - }); - }, - success: function(data) { - if(data.error) { - $.unblockUI(); - $.pnotify({ - text: "Error: "+data.error.message, - type:"error" - }); - } else { - loadComments(); + beforeSerialize: function() { + if (typeof(foswikiStrikeOne) !== 'undefined') { + foswikiStrikeOne($form[0]); } }, - error: function(xhr) { - var data = $.parseJSON(xhr.responseText); - $.unblockUI(); - $.pnotify({ - text: "Error: "+data.error.message, - type:"error" - }); - } - }); - }); - - /* ajaxify update form **************************************************/ - $(".cmtUpdateCommentForm").livequery(function() { - var $form = $(this); - - $form.ajaxForm({ - dataType:"json", - beforeSubmit: function() { - $("#cmtUpdateComment").dialog("close"); - $.blockUI({ - message:"

"+opts.updateMessage+" ...

", - fadeIn: 0, - fadeOut: 0 - }); - }, - success: function(data) { - if(data.error) { - $.unblockUI(); - $.pnotify({ - text: "Error: "+data.error.message, - type:"error" - }); - } else { - loadComments(); - } - }, - error: function(xhr) { - var data = $.parseJSON(xhr.responseText); - $.unblockUI(); - $.pnotify({ - text: "Error: "+data.error.message, - type:"error" - }); - } - }); - }); - - /* ajaxify confirm delete form ******************************************/ - $(".cmtConfirmDeleteForm").livequery(function() { - var $form = $(this); - - $form.ajaxForm({ beforeSubmit: function() { - $("#cmtConfirmDelete").dialog("close"); - $.blockUI({ - message:"

"+opts.deleteMessage+" ...

", - fadeIn: 0, - fadeOut: 0 - }); - }, - success: function(data) { - if(data.error) { - $.unblockUI(); - $.pnotify({ - text: "Error: "+data.error.message, - type:"error" - }); - } else { - loadComments(); + if ($form.is(".cmtModalForm")) { + $form.parent().dialog("close"); } - }, - error: function(xhr) { - var data = $.parseJSON(xhr.responseText); - $.unblockUI(); - $.pnotify({ - text: "Error: "+data.error.message, - type:"error" - }); - } - }); - }); - - /* ajaxify confirm approve form *****************************************/ - $(".cmtConfirmApproveForm").livequery(function() { - var $form = $(this); - - $form.ajaxForm({ - beforeSubmit: function() { - $("#cmtConfirmApprove").dialog("close"); $.blockUI({ - message:"

"+opts.approveMessage+" ...

", + message:"

"+msg+" ...

", fadeIn: 0, fadeOut: 0 }); @@ -303,9 +202,21 @@ jQuery(function($) { return false; }); + /* add delete/approve/mark all behaviour ******************************************/ + $this.find(".cmtDeleteAll, .cmtApproveAll, .cmtMarkAll").click(function() { + var id = $(this).attr("href"); + + loadDialogs(function() { + $(id).dialog("open"); + }); + + return false; + }); + /* add "mark as read" behaviour *************************************************/ $this.find(".cmtMark").click(function() { - var $this = $(this), + var $this = $(this), + msg = $this.data("message"), $comment = $this.parents(".cmtComment:first"), commentOpts = $.extend({}, $comment.metadata()); @@ -317,7 +228,7 @@ jQuery(function($) { "comment_id": commentOpts.comment_id }, beforeSubmit: function() { - $.blockUI({ message:"

"+opts.markingMessage+" ...

"}); + $.blockUI({ message:"

"+msg+" ...

"}); }, success: function() { $.unblockUI(); diff --git a/templates/metacomments.tmpl b/templates/metacomments.tmpl index 3a1222b..fde6c74 100644 --- a/templates/metacomments.tmpl +++ b/templates/metacomments.tmpl @@ -3,12 +3,7 @@ }% %TMPL:DEF{"metacomments"}% %CLEAR% -
+
%TMPL:P{"comments::topbar"}%%{}% %IF{"$COMMENTFORMAT=~'reverse|insidetab' and $COMMENTSTATE!='closed'" then="$percntTMPL:P{\"comments::add::simple\"}$percnt" @@ -21,7 +16,7 @@ %{ ################################################################################ metacomments::init - loads all required css and js }% -%TMPL:DEF{"metacomments::init"}% +%TMPL:DEF{"metacomments::init"}% %ADDTOZONE{ "head" id="METACOMMENTPLUGIN::CSS" @@ -30,34 +25,46 @@ "script" id="METACOMMENTPLUGIN::JS" requires="JQUERYPLUGIN::UI, JQUERYPLUGIN::FORM, JQUERYPLUGIN::JSONRPC, JQUERYPLUGIN::PNOTIFY, JQUERYPLUGIN::SCROLLTO" - text="" + text="" }%%{}%%TMPL:END% %{ ################################################################################ metacomments::dialog - loads all required dialogs }% -%TMPL:DEF{"comments::dialogs"}%%IF{"$COMMENTSTATE!='closed'" - then="$percntTMPL:P{\"comments::confirmdelete\"}$percnt%{}% - $percntTMPL:P{\"comments::confirmapprove\"}$percnt%{}% - $percntTMPL:P{\"comments::updater\"}$percnt%{}% - $percntTMPL:P{\"comments::replier\"}$percnt" -}%%TMPL:END% - +%TMPL:DEF{"comments::dialogs"}%%{}% +%TMPL:P{"comments::confirmdelete"}%%{}% +%TMPL:P{"comments::confirmdeleteall"}%%{}% +%TMPL:P{"comments::confirmapproveall"}%%{}% +%TMPL:P{"comments::confirmmarkall"}%%{}% +%TMPL:P{"comments::confirmapprove"}%%{}% +%TMPL:P{"comments::updater"}%%{}% +%TMPL:P{"comments::replier"}% +%{}%%TMPL:END% %{ ################################################################################ comments::topbar - renders the number of comments }% %TMPL:DEF{"comments::topbar"}%%{}% %METACOMMENTS{ - header="%JQICON{"feed"}% RSS

$count

" + rev="%URLPARAM{"rev"}%" + header="$percntTMPL:P{\"comments::topbar::rss\"}$percnt

$count $percntTMPL:P{\"comments::topbar::toggle\"}$percnt

" singular="%MAKETEXT{"One comment"}%" plural="%MAKETEXT{"[_1] comments" args="$count"}%" limit="1" template="" - %IF{"'%TMPL:P{"comments::format"}%' = 'threaded'" then="threaded=\"on\"" else="threaded=\"off\""}% - %IF{"$COMMENTMODERATION='on'" then="moderation=\"on\"" else="moderation=\"off\""}% + threaded="%IF{"'%TMPL:P{"comments::format"}%'='threaded'" + then="on" + else="off" + }%" + moderation="%IF{"$COMMENTMODERATION='on'" + then="on" + else="off" + }%" }%%CLEAR%%{}%%TMPL:END% +%TMPL:DEF{"comments::topbar::rss"}%%JQICON{"fa-rss"}% RSS%TMPL:END% +%TMPL:DEF{"comments::topbar::toggle"}%%JQICON{"fa-gear"}%%TMPL:END% + %{ ################################################################################ comments::add::denied - display a message why somebody can't comment }% @@ -117,12 +124,29 @@ comments::list - renders a list of available comments }% %TMPL:DEF{"comments::list"}%%METACOMMENTS{ + rev="%URLPARAM{"rev"}%" template="comments::format::%TMPL:P{"comments::format"}%" subtemplate="comments::format::%TMPL:P{"comments::format"}%::subcomment" %IF{"'%TMPL:P{"comments::format"}%' = 'threaded'" then="threaded=\"on\""}% %IF{"'%TMPL:P{"comments::format"}%' =~ 'reverse|insidetab'" then="reverse=\"on\""}% %IF{"$COMMENTMODERATION='on'" then="moderation=\"on\"" else="moderation=\"off\""}% -}%%TMPL:END% + header="
$percntTMPL:P{\"comments::list::controls\"}$percnt" + footer="
" +}%%CLEAR%%TMPL:END% + +%{ ################################################################################ + comments::list::controls - renders a list controls operating on all comments +}% +%TMPL:DEF{"comments::list::controls"}%
+%TMPL:P{"comments::list::controls::markall"}%%{}% +%TMPL:P{"comments::list::controls::approveall"}%%{}% +%TMPL:P{"comments::list::controls::deleteall"}%%{}% +%CLEAR% +
%TMPL:END% + +%TMPL:DEF{"comments::list::controls::markall"}%%JQICON{"fa-exclamation-circle"}% %MAKETEXT{"Mark as read"}%%TMPL:END% +%TMPL:DEF{"comments::list::controls::approveall"}%%JQICON{"fa-certificate"}% %MAKETEXT{"Approve all"}%%TMPL:END% +%TMPL:DEF{"comments::list::controls::deleteall"}%%JQICON{"fa-trash"}% %MAKETEXT{"Delete all"}%%TMPL:END% %{ ################################################################################ comments::format::linear - format one comment in linear format @@ -134,44 +158,83 @@ "comment::photo" web="%USERSWEB%" topic="%USERINFO{"$author" format="$wikiname"}%" - }%%IF{"'%ENCODE{"$title" type="entity"}%'!=''" - then="

%ENCODE{"$title" type="entity"}%

" - }%
$n$text
- %TMPL:P{"comments::controls"}%%{}% - $percntIF{"$COMMENTMODERATION='on' and not('$state'=~'\bapproved\b')" - then="
(%MAKETEXT{"needs approval"}%)
" - }$percnt%{}% - - %IF{"istopic '%USERSWEB%.$author'" then="[[%USERSWEB%.$author]]" else="%IF{"'$authorurl'!=''" then="[[$authorurl][%ENCODE{"$author" type="safe"}%]]" else="%ENCODE{"$author" type="safe"}%"}%"}% - | - $date - %IF{"context authenticated and $isnew and '%WEB%.%TOPIC%' allows change" - then=" | %JQICON{"fa-exclamation-circle"}% %MAKETEXT{"new"}%" - }%%IF{"context authenticated and $isupdated and '%WEB%.%TOPIC%' allows change" - then=" | %JQICON{"fa-exclamation-circle"}% %MAKETEXT{"updated"}%" - }%%IF{"$COMMENTVOTING!='off' and context LikePluginEnabled" - then="$dollarpercntLIKE{header=\\" | \\" theme=\\"simple\\" showlabel=\\"off\\" type=\\"COMMENT\\" id=\\"$id\\"}$dollarpercnt" - }%%IF{"$COMMENTPERMLINK!='off'" - then=" | %MAKETEXT{"permlink"}%" - }%%{}% - - %CLEAR% + }%%{}% + %TMPL:P{"comment::title"}%%{}% + %TMPL:P{"comment::text"}%%{}% + %TMPL:P{"comment::controls"}%%{}% + %TMPL:P{"comment::approval"}%%{}% + %TMPL:P{"comment::info"}%%CLEAR%
%TMPL:END% %{ ################################################################################ - comments::controls - renders the comment tools + comment::info - renders a line of infos for a comment +}% +%TMPL:DEF{"comment::info"}% + %TMPL:P{"comment::info::author"}%%{}% + %TMPL:P{"comment::info::date"}%%{}% + %TMPL:P{"comment::info::mark"}%%{}% + %TMPL:P{"comment::info::vote"}%%{}% + %TMPL:P{"comment::info::permalink"}%%{}% +%TMPL:END% + +%TMPL:DEF{"comment::info::author"}%%IF{"istopic + '%USERSWEB%.$author'" + then="[[%USERSWEB%.$author]]" + else="%IF{"'$authorurl'!=''" + then="[[$authorurl][%ENCODE{"$author" type="safe"}%]]" + else="%ENCODE{"$author" type="safe"}%" + }%" +}% | %TMPL:END% + +%TMPL:DEF{"comment::info::date"}%$date%TMPL:END% + +%TMPL:DEF{"comment::info::mark"}%%IF{"context authenticated and context canComment and $isnew and '%WEB%.%TOPIC%' allows change" + then=" | %JQICON{"fa-exclamation-circle"}% %MAKETEXT{"new"}%" + }%%IF{"context authenticated and $isupdated and '%WEB%.%TOPIC%' allows change" + then=" | %JQICON{"fa-exclamation-circle"}% %MAKETEXT{"updated"}%" +}%%TMPL:END% + +%TMPL:DEF{"comment::info::vote"}%%IF{"$COMMENTVOTING!='off' and context LikePluginEnabled" + then="$dollarpercntLIKE{header=\\" | \\" theme=\\"simple\\" showlabel=\\"off\\" type=\\"COMMENT\\" id=\\"$id\\"}$dollarpercnt" +}%%TMPL:END% + +%TMPL:DEF{"comment::info::permalink"}%%IF{"$COMMENTPERMLINK!='off'" + then=" | %MAKETEXT{"permlink"}%" +}%%TMPL:END% + +%{ ################################################################################ + comment::title - renders the comment title +}% +%TMPL:DEF{"comment::title"}%%IF{"'%ENCODE{"$title" type="entity"}%'!=''" + then="

%ENCODE{"$title" type="entity"}%

" +}%%TMPL:END% + +%{ ################################################################################ + comment::text - renders the comment text +}% +%TMPL:DEF{"comment::text"}%
$n$text
%TMPL:END% + +%{ ################################################################################ + comment::approval - renders a note when this comment needs approval +}% +%TMPL:DEF{"comment::approval"}%$percntIF{"$COMMENTMODERATION='on' and '$state'=~'\bunapproved\b'" + then="
(%MAKETEXT{"needs approval"}%)
" +}$percnt%TMPL:END% + +%{ ################################################################################ + comment::controls - renders the comment tools }% -%TMPL:DEF{"comments::controls"}%
+%TMPL:DEF{"comment::controls"}%
%IF{"context canComment and $COMMENTSTATE!='closed' and not ('%TMPL:P{"comments::format"}%' =~ 'reverse|insidetab')" - then="%JQICON{"comment"}%" + then="%JQICON{"fa-comment"}%" }%%IF{"($ismoderator or '%ENCODE{"$author" type="safe"}%'='%WIKINAME%') and $COMMENTSTATE!='closed'" - then="%JQICON{"pencil"}%" + then="%JQICON{"fa-pencil"}%" }%%IF{"$COMMENTMODERATION='on' and $ismoderator and '$state'=~'\bunapproved\b'" - then="%JQICON{"medal_gold_1"}%" + then="%JQICON{"fa-certificate"}%" }%%IF{"($ismoderator or '%ENCODE{"$author" type="safe"}%'='%WIKINAME%') and $COMMENTSTATE!='closed'" - then="%JQICON{"bin"}%" + then="%JQICON{"fa-trash"}%" }%%{}%
%TMPL:END% @@ -190,28 +253,12 @@ "comment::photo" web="%USERSWEB%" topic="%USERINFO{"$author" format="$wikiname"}%" - }%%IF{"'%ENCODE{"$title" type="entity"}%'!=''" - then="

%ENCODE{"$title" type="entity"}%

" - }%
$n$text
- %TMPL:P{"comments::controls"}%%{}% - $percntIF{"$COMMENTMODERATION='on' and '$state'=~'\bunapproved\b'" - then="
(%MAKETEXT{"needs approval"}%)
" - }$percnt%{}% - - %IF{"istopic '%USERSWEB%.$author'" then="[[%USERSWEB%.$author]]" else="%IF{"'$authorurl'!=''" then="[[$authorurl][%ENCODE{"$author" type="safe"}%]]" else="%ENCODE{"$author" type="safe"}%"}%"}% - | - $date - %IF{"context authenticated and context canComment and $isnew and '%WEB%.%TOPIC%' allows change" - then=" | %JQICON{"fa-exclamation-circle"}% %MAKETEXT{"new"}%" - }%%IF{"context authenticated and $isupdated and '%WEB%.%TOPIC%' allows change" - then=" | %JQICON{"fa-exclamation-circle"}% %MAKETEXT{"updated"}%" - }%%IF{"$COMMENTVOTING!='off' and context LikePluginEnabled" - then="$dollarpercntLIKE{header=\\" | \\" theme=\\"simple\\" showlabel=\\"off\\" type=\\"COMMENT\\" id=\\"$id\\"}$dollarpercnt" - }%%IF{"$COMMENTPERMLINK!='off'" - then=" | %MAKETEXT{"permlink"}%" - }%%{}% - - %CLEAR% + }%%{}% + %TMPL:P{"comment::title"}%%{}% + %TMPL:P{"comment::text"}%%{}% + %TMPL:P{"comment::controls"}%%{}% + %TMPL:P{"comment::approval"}%%{}% + %TMPL:P{"comment::info"}%%CLEAR%
$subcomments %TMPL:END% @@ -231,29 +278,13 @@ "comment::photo" web="%USERSWEB%" topic="%USERINFO{"$author" format="$wikiname"}%" - }%%IF{"'%ENCODE{"$title" type="entity"}%'!=''" - then="

%ENCODE{"$title" type="entity"}%

" }%%{}% -
$n$text
- %TMPL:P{"comments::controls"}%%{}% - $percntIF{"$COMMENTMODERATION='on' and '$state'=~'\bunapproved\b'" - then="
(%MAKETEXT{"needs approval"}%)
" - }$percnt%{}% - - %IF{"istopic '%USERSWEB%.$author'" then="[[%USERSWEB%.$author]]" else="%IF{"'$authorurl'!=''" then="[[$authorurl][%ENCODE{"$author" type="safe"}%]]" else="%ENCODE{"$author" type="safe"}%"}%"}% - | - $date - %IF{"context authenticated and $isnew and '%WEB%.%TOPIC%' allows change" - then=" | %JQICON{"fa-exclamation-circle"}% %MAKETEXT{"new"}%" - }%%IF{"context authenticated and $isupdated and '%WEB%.%TOPIC%' allows change" - then=" | %JQICON{"fa-exclamation-circle"}% %MAKETEXT{"updated"}%" - }%%IF{"$COMMENTVOTING!='off' and context LikePluginEnabled" - then="$dollarpercntLIKE{header=\\" | \\" theme=\\"simple\\" showlabel=\\"off\\" type=\\"COMMENT\\" id=\\"$id\\"}$dollarpercnt" - }%%IF{"$COMMENTPERMLINK!='off'" - then=" | %MAKETEXT{"permlink"}%" - }%%{}% - - %CLEAR% + %TMPL:P{"comment::title"}%%{}% + %TMPL:P{"comment::title"}%%{}% + %TMPL:P{"comment::text"}%%{}% + %TMPL:P{"comment::controls"}%%{}% + %TMPL:P{"comment::approval"}%%{}% + %TMPL:P{"comment::info"}%%CLEAR% %TMPL:END% @@ -262,8 +293,8 @@ %{ ################################################################################ comments::confirmdelete - dialog to confirm a delete }% -%TMPL:DEF{"comments::confirmdelete"}%