From 40dff673debeb93297a673c91eeb74d4d102739e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Thiemo=20M=C3=A4ttig?= Date: Thu, 6 Feb 2014 15:33:01 +0100 Subject: [PATCH] mediawiki.page.watch.ajax: Fail early if updateWatchLink is called wrong If the exposed function is called from a gadget or user script but no watch/unwatch link was found the function fails even if the first parameter is a valid jQuery object as required by the documentation. $link.attr(...) returns null and null.match(...) fails. A very simple example why this can happen is as follows: mw.page.watch.updateWatchLink( $( '#ca-watch a' ), 'watch', 'loading' ); mw.page.watch.updateWatchLink( $( '#ca-watch a.loading' ), 'unwatch' ); (starts the spinning loading animation and tries to stop it afterwards but may fail if something went wrong, e.g. the user clicked the star). The action parameter needs to be checked because it is used to build an ID and a message key. Bad values turn the page in an unrecoverable state (the watch link gets an empty action=, the label turns into something and no script can recover that broken state since the ID turned into whatever). While such a check is not necesarry in most cases it is here, because the function is exposed. Change-Id: I6ee9a7ee6b7c0fc7a5444674afd1ed6f8cacc858 --- .../mediawiki.page/mediawiki.page.watch.ajax.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/resources/mediawiki.page/mediawiki.page.watch.ajax.js b/resources/mediawiki.page/mediawiki.page.watch.ajax.js index 998a8c2a6b..1041e7f9f3 100644 --- a/resources/mediawiki.page/mediawiki.page.watch.ajax.js +++ b/resources/mediawiki.page/mediawiki.page.watch.ajax.js @@ -19,6 +19,16 @@ function updateWatchLink( $link, action, state ) { var accesskeyTip, msgKey, $li, otherAction; + // A valid but empty jQuery object shouldn't throw a TypeError + if ( !$link.length ) { + return; + } + + // Invalid actions shouldn't silently turn the page in an unrecoverable state + if ( action !== 'watch' && action !== 'unwatch' ) { + throw new Error( 'Invalid action' ); + } + // message keys 'watch', 'watching', 'unwatch' or 'unwatching'. msgKey = state === 'loading' ? action + 'ing' : action; otherAction = action === 'watch' ? 'unwatch' : 'watch'; @@ -69,8 +79,6 @@ function mwUriGetAction( url ) { var action, actionPaths, key, i, m, parts; - actionPaths = mw.config.get( 'wgActionPaths' ); - // TODO: Does MediaWiki give action path or query param // precedence ? If the former, move this to the bottom action = mw.util.getParamValue( 'action', url ); @@ -78,6 +86,7 @@ return action; } + actionPaths = mw.config.get( 'wgActionPaths' ); for ( key in actionPaths ) { if ( actionPaths.hasOwnProperty( key ) ) { parts = actionPaths[key].split( '$1' ); -- 2.20.1