SpecialUnwatchedpages: Ajaxify watch links
authorEranroz <eranroz89@gmail.com>
Mon, 30 Apr 2012 18:58:27 +0000 (21:58 +0300)
committereranroz <eranroz89@gmail.com>
Fri, 16 May 2014 04:04:29 +0000 (07:04 +0300)
Add user friendly handling to watch pages from Special:UnwatchedPages
using ajax. Emits a notification message upon completion of the action
and strikes through the list item.

Bug: 17367
Change-Id: Ie32cc54abb6f888a433f7f18ef5ad747a80d7187

includes/specials/SpecialUnwatchedpages.php
languages/i18n/en.json
languages/i18n/qqq.json
resources/Resources.php
resources/src/mediawiki.special/mediawiki.special.unwatchedPages.css [new file with mode: 0644]
resources/src/mediawiki.special/mediawiki.special.unwatchedPages.js [new file with mode: 0644]

index ec2e7f5..fe0638e 100644 (file)
@@ -70,6 +70,14 @@ class UnwatchedpagesPage extends QueryPage {
                return array( 'page_namespace', 'page_title' );
        }
 
+       /**
+        * Add the JS
+        */
+       public function execute( $par ) {
+               parent::execute( $par );
+               $this->getOutput()->addModules( 'mediawiki.special.unwatchedPages' );
+       }
+
        /**
         * @param Skin $skin
         * @param object $result Result row
@@ -91,7 +99,7 @@ class UnwatchedpagesPage extends QueryPage {
                $wlink = Linker::linkKnown(
                        $nt,
                        $this->msg( 'watch' )->escaped(),
-                       array(),
+                       array( 'class' => 'mw-watch-link' ),
                        array( 'action' => 'watch', 'token' => $token )
                );
 
index 399c932..27a08c4 100644 (file)
        "watchnologin": "Not logged in",
        "addwatch": "Add to watchlist",
        "addedwatchtext": "The page \"[[:$1]]\" has been added to your [[Special:Watchlist|watchlist]].\nFuture changes to this page and its associated talk page will be listed there.",
+       "addedwatchtext-short": "The page \"$1\" has been added to your watchlist.",
        "removewatch": "Remove from watchlist",
        "removedwatchtext": "The page \"[[:$1]]\" has been removed from [[Special:Watchlist|your watchlist]].",
+       "removedwatchtext-short": "The page \"$1\" has been removed from your watchlist.",
        "watch": "Watch",
        "watchthispage": "Watch this page",
        "unwatch": "Unwatch",
index 8f46025..40cdbd2 100644 (file)
        "watchnologin": "Used as error page title.\n\nThe error message for this title is:\n* {{msg-mw|Watchnologintext}}\n{{Identical|Not logged in}}",
        "addwatch": "Link to a dialog box, displayed at the end of the list of categories at the foot of each page.\n\nSee also:\n* {{msg-mw|Removewatch}}",
        "addedwatchtext": "Explanation shown when clicking on the {{msg-mw|Watch}} tab. Parameters:\n* $1 - page title\nSee also:\n* {{msg-mw|Addedwatch}}",
+       "addedwatchtext-short": "Explanation shown when watching item from Special:UnwatchedPages",
        "removewatch": "Link to a dialog box, displayed at the end of the list of categories at the foot of each page.\n\nSee also:\n* {{msg-mw|Addwatch}}",
        "removedwatchtext": "After a page has been removed from a user's watchlist by clicking the {{msg-mw|Unwatch}} tab at the top of an article, this message appears just below the title of the article.\n\nParameters:\n* $1 - the title of the article\nSee also:\n* {{msg-mw|Removedwatch}}\n* {{msg-mw|Addedwatchtext}}",
+       "removedwatchtext-short": "Explanation shown when unwatching item from Special:UnwatchedPages",
        "watch": "{{doc-actionlink}}\nName of the Watch tab. Should be in the imperative mood.\n\nSee also:\n* {{msg-mw|Watch}}\n* {{msg-mw|Accesskey-ca-watch}}\n* {{msg-mw|Tooltip-ca-watch}}",
        "watchthispage": "Used as link text.\n\nSee also:\n* {{msg-mw|Unwatchthispage|link text}}\n* {{msg-mw|Notanarticle|error message}}\n{{Identical|Watch this page}}",
        "unwatch": "{{doc-actionlink}}\nLabel of \"Unwatch\" tab.\n\nSee also:\n* {{msg-mw|Unwatch}}\n* {{msg-mw|Accesskey-ca-unwatch}}\n* {{msg-mw|Tooltip-ca-unwatch}}",
index abc1661..f638eea 100644 (file)
@@ -1298,6 +1298,25 @@ return array(
                        'jquery.throttle-debounce',
                ),
        ),
+       'mediawiki.special.unwatchedPages' => array(
+               'scripts' => 'resources/src/mediawiki.special/mediawiki.special.unwatchedPages.js',
+               'styles' => 'resources/src/mediawiki.special/mediawiki.special.unwatchedPages.css',
+               'messages' => array(
+                       'addedwatchtext-short',
+                       'removedwatchtext-short',
+                       'unwatch',
+                       'unwatching',
+                       'watch',
+                       'watcherrortext',
+                       'watching',
+               ),
+               'dependencies' => array(
+                       'mediawiki.api',
+                       'mediawiki.api.watch',
+                       'mediawiki.notify',
+                       'mediawiki.Title'
+               ),
+       ),
        'mediawiki.special.javaScriptTest' => array(
                'scripts' => 'resources/src/mediawiki.special/mediawiki.special.javaScriptTest.js',
                'messages' => array_merge( Skin::getSkinNameMessages(), array(
diff --git a/resources/src/mediawiki.special/mediawiki.special.unwatchedPages.css b/resources/src/mediawiki.special/mediawiki.special.unwatchedPages.css
new file mode 100644 (file)
index 0000000..054f45f
--- /dev/null
@@ -0,0 +1,9 @@
+.mw-watched-item {
+       text-decoration: line-through;
+}
+
+.mw-watch-link-disabled {
+       pointer-events: none;
+       /* Fallback for older browsers not supporting pointer-events: none */
+       cursor: default;
+}
diff --git a/resources/src/mediawiki.special/mediawiki.special.unwatchedPages.js b/resources/src/mediawiki.special/mediawiki.special.unwatchedPages.js
new file mode 100644 (file)
index 0000000..a2c2228
--- /dev/null
@@ -0,0 +1,52 @@
+/*!
+ * JavaScript for Special:UnwatchedPages
+ */
+( function ( mw, $ ) {
+       $( function () {
+               $( 'a.mw-watch-link' ).click( function ( e ) {
+                       var promise,
+                               api = new mw.Api(),
+                               $link = $( this ),
+                               $subjectLink = $link.parents( 'li' ).children( 'a' ).eq( 0 ),
+                               title = mw.util.getParamValue( 'title', $link.attr( 'href' ) );
+                       // nice format
+                       title = mw.Title.newFromText( title ).toText();
+                       // Disable link whilst we're busy to avoid double handling
+                       if ( $link.data( 'mwDisabled' ) ) {
+                               // mw-watch-link-disabled disables pointer-events which prevents the click event
+                               // from happening in the first place. In older browsers we kill the event here.
+                               return false;
+                       }
+                       $link.data( 'mwDisabled', true ).addClass( 'mw-watch-link-disabled' );
+
+                       // Use the class to determine whether to watch or unwatch
+                       if ( !$subjectLink.hasClass( 'mw-watched-item' ) ) {
+                               $link.text( mw.msg( 'watching' ) );
+                               promise = api.watch( title ).done( function () {
+                                       $subjectLink.addClass( 'mw-watched-item' );
+                                       $link.text( mw.msg( 'unwatch' ) );
+                                       mw.notify( mw.msg( 'addedwatchtext-short', title ) );
+                               } ).fail( function () {
+                                       $link.text( mw.msg( 'watch' ) );
+                                       mw.notify( mw.msg( 'watcherrortext', title ) );
+                               } );
+                       } else {
+                               $link.text( mw.msg( 'unwatching' ) );
+                               promise = api.unwatch( title ).done( function () {
+                                       $subjectLink.removeClass( 'mw-watched-item' );
+                                       $link.text( mw.msg( 'watch' ) );
+                                       mw.notify( mw.msg( 'removedwatchtext-short', title ) );
+                               } ).fail( function () {
+                                       $link.text( mw.msg( 'unwatch' ) );
+                                       mw.notify( mw.msg( 'watcherrortext', title ) );
+                               } );
+                       }
+
+                       promise.always( function () {
+                               $link.data( 'mwDisabled', false ).removeClass( 'mw-watch-link-disabled' );
+                       } );
+
+                       e.preventDefault();
+               } );
+       } );
+}( mediaWiki, jQuery ) );