Support AJAX watch in skins that use a different class structure
authorKunal Mehta <legoktm@member.fsf.org>
Tue, 15 Aug 2017 20:34:55 +0000 (13:34 -0700)
committerKunal Mehta <legoktm@member.fsf.org>
Wed, 16 Aug 2017 02:12:53 +0000 (19:12 -0700)
Skipping links that are in #bodyContent or #content doesn't work for
skins like Timeless. Instead of trying to filter based on those classes,
have SkinTemplate set a data-mw=interface attribute on the <a> element,
and filter based on that. The Sanitizer prevents any data-mw attributes
being set by users, so it must have been created by MediaWiki, and
therefore safe to use.

If no link meets that criteria, then it will fallback to trying to find
a link using the old criteria of not being in #bodyContent or #content.

Bug: T173279
Change-Id: I1688a499dda40428dd514230b78ccded0d228ca3

includes/skins/SkinTemplate.php
resources/src/mediawiki/page/watch.js

index f49d46c..5ad1b11 100644 (file)
@@ -1080,7 +1080,12 @@ class SkinTemplate extends Skin {
                                                ),
                                                // uses 'watch' or 'unwatch' message
                                                'text' => $this->msg( $mode )->text(),
-                                               'href' => $title->getLocalURL( [ 'action' => $mode ] )
+                                               'href' => $title->getLocalURL( [ 'action' => $mode ] ),
+                                               // Set a data-mw=interface attribute, which the mediawiki.page.ajax
+                                               // module will look for to make sure it's a trusted link
+                                               'data' => [
+                                                       'mw' => 'interface',
+                                               ],
                                        ];
                                }
                        }
index 6322ccd..e56e807 100644 (file)
        );
 
        $( function () {
-               var $links = $( '.mw-watchlink a, a.mw-watchlink' );
-               // Restrict to core interfaces, ignore user-generated content
-               $links = $links.filter( ':not( #bodyContent *, #content * )' );
+               var $links = $( '.mw-watchlink a[data-mw="interface"], a.mw-watchlink[data-mw="interface"]' );
+               if ( !$links.length ) {
+                       // Fallback to the class-based exclusion method for backwards-compatibility
+                       $links = $( '.mw-watchlink a, a.mw-watchlink' );
+                       // Restrict to core interfaces, ignore user-generated content
+                       $links = $links.filter( ':not( #bodyContent *, #content * )' );
+               }
 
                $links.click( function ( e ) {
                        var mwTitle, action, api, $link;