From: Rob Moen Date: Tue, 19 Jun 2012 23:00:57 +0000 (-0700) Subject: Move action.watch to a more suitable place and expose updateWatchLink X-Git-Tag: 1.31.0-rc.0~23274^2 X-Git-Url: https://git.cyclocoop.org/%242?a=commitdiff_plain;h=2e089a4e58b602fc97683e71c352e642411d68d6;p=lhc%2Fweb%2Fwiklou.git Move action.watch to a more suitable place and expose updateWatchLink method in mw.page.watch. Update method to toggle watch, unwatch list item id attribute. Patchset 2- Expose method with less code duplication, restore comments, cleanup whitespace. Patchset 3-5 Whitespace cleanup Patchset 6 - Trigger a watch event on the updated li Patchset 7 - Only trigger watch event if not updating state, announce opposite of icon action, to properly indicate action taken. Patchset 8 - Cleanup spacing and comments issues, change event namespace. Patchset 9 - actually add the change Change-Id: I591f9f847db391c5d1477dc2ed41de54ec266261 --- diff --git a/includes/OutputPage.php b/includes/OutputPage.php index 35b2f38580..7f0a4e2d21 100644 --- a/includes/OutputPage.php +++ b/includes/OutputPage.php @@ -2470,7 +2470,7 @@ $templates wfRunHooks( 'AjaxAddScript', array( &$this ) ); if( $wgAjaxWatch && $this->getUser()->isLoggedIn() ) { - $this->addModules( 'mediawiki.action.watch.ajax' ); + $this->addModules( 'mediawiki.page.watch.ajax' ); } if ( $wgEnableMWSuggest && !$this->getUser()->getOption( 'disablesuggest', false ) ) { diff --git a/resources/Resources.php b/resources/Resources.php index fb6f2ff33a..26d73c5182 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -655,22 +655,6 @@ return array( 'mediawiki.action.view.rightClickEdit' => array( 'scripts' => 'resources/mediawiki.action/mediawiki.action.view.rightClickEdit.js', ), - 'mediawiki.action.watch.ajax' => array( - 'scripts' => 'resources/mediawiki.action/mediawiki.action.watch.ajax.js', - 'dependencies' => array( - 'mediawiki.api.watch', - 'mediawiki.util', - ), - 'messages' => array( - 'watch', - 'unwatch', - 'watching', - 'unwatching', - 'tooltip-ca-watch', - 'tooltip-ca-unwatch', - 'watcherrortext', - ), - ), /* MediaWiki Language */ @@ -770,7 +754,23 @@ return array( ), 'position' => 'top', ), - + 'mediawiki.page.watch.ajax' => array( + 'scripts' => 'resources/mediawiki.page/mediawiki.page.watch.ajax.js', + 'dependencies' => array( + 'mediawiki.page.startup', + 'mediawiki.api.watch', + 'mediawiki.util' + ), + 'messages' => array( + 'watch', + 'unwatch', + 'watching', + 'unwatching', + 'tooltip-ca-watch', + 'tooltip-ca-unwatch', + 'watcherrortext', + ), + ), /* MediaWiki Special pages */ diff --git a/resources/mediawiki.action/mediawiki.action.watch.ajax.js b/resources/mediawiki.action/mediawiki.action.watch.ajax.js deleted file mode 100644 index 090e4c3d1e..0000000000 --- a/resources/mediawiki.action/mediawiki.action.watch.ajax.js +++ /dev/null @@ -1,161 +0,0 @@ -/** - * Animate watch/unwatch links to use asynchronous API requests to - * watch pages, rather than navigating to a different URI. - */ -( function ( $, mw, undefined ) { - - /** - * The name of the page to watch or unwatch. - */ - var title = mw.config.get( 'wgRelevantPageName', mw.config.get( 'wgPageName' ) ); - - /** - * Update the link text, link href attribute and (if applicable) - * "loading" class. - * - * @param $link {jQuery} Anchor tag of (un)watch link. - * @param action {String} One of 'watch', 'unwatch'. - * @param state {String} [optional] 'idle' or 'loading'. Default is 'idle'. - */ - function updateWatchLink( $link, action, state ) { - var accesskeyTip, msgKey, $li; - - // message keys 'watch', 'watching', 'unwatch' or 'unwatching'. - msgKey = state === 'loading' ? action + 'ing' : action; - accesskeyTip = $link.attr( 'title' ).match( mw.util.tooltipAccessKeyRegexp ); - $li = $link.closest( 'li' ); - - $link - .text( mw.msg( msgKey ) ) - .attr( 'title', mw.msg( 'tooltip-ca-' + action ) + - ( accesskeyTip ? ' ' + accesskeyTip[0] : '' ) - ) - .attr( 'href', mw.util.wikiScript() + '?' + $.param({ - title: title, - action: action - }) - ); - - // Special case for vector icon - if ( $li.hasClass( 'icon' ) ) { - if ( state === 'loading' ) { - $link.addClass( 'loading' ); - } else { - $link.removeClass( 'loading' ); - } - } - } - - /** - * @todo This should be moved somewhere more accessible. - * @param url {String} - * @return {String} The extracted action, defaults to 'view'. - */ - 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 ); - if ( action !== null ) { - return action; - } - - for ( key in actionPaths ) { - if ( actionPaths.hasOwnProperty( key ) ) { - parts = actionPaths[key].split( '$1' ); - for ( i = 0; i < parts.length; i += 1 ) { - parts[i] = $.escapeRE( parts[i] ); - } - m = new RegExp( parts.join( '(.+)' ) ).exec( url ); - if ( m && m[1] ) { - return key; - } - - } - } - - return 'view'; - } - - $( document ).ready( function () { - var $links = $( '.mw-watchlink a, a.mw-watchlink, ' + - '#ca-watch a, #ca-unwatch a, #mw-unwatch-link1, ' + - '#mw-unwatch-link2, #mw-watch-link2, #mw-watch-link1' ); - - // Allowing people to add inline animated links is a little scary - $links = $links.filter( ':not( #bodyContent *, #content * )' ); - - $links.click( function ( e ) { - var action, api, $link; - - action = mwUriGetAction( this.href ); - - if ( action !== 'watch' && action !== 'unwatch' ) { - // Could not extract target action from link url, - // let native browsing handle it further - return true; - } - e.preventDefault(); - e.stopPropagation(); - - $link = $( this ); - - updateWatchLink( $link, action, 'loading' ); - - api = new mw.Api(); - api[action]( - title, - // Success - function ( watchResponse ) { - var $li, otherAction; - - otherAction = action === 'watch' ? 'unwatch' : 'watch'; - $li = $link.closest( 'li' ); - - mw.util.jsMessage( watchResponse.message, 'ajaxwatch' ); - - // Set link to opposite - updateWatchLink( $link, otherAction ); - - // Most common ID style - if ( $li.prop( 'id' ) === 'ca-' + otherAction || $li.prop( 'id' ) === 'ca-' + action ) { - $li.prop( 'id', 'ca-' + otherAction ); - } - - // Bug 12395 - update the watch checkbox on edit pages when the - // page is watched or unwatched via the tab. - if ( watchResponse.watched !== undefined ) { - $( '#wpWatchthis' ).prop( 'checked', true ); - } else { - $( '#wpWatchthis' ).removeProp( 'checked' ); - } - }, - // Error - function () { - var cleanTitle, html, link; - - // Reset link to non-loading mode - updateWatchLink( $link, action ); - - // Format error message - cleanTitle = title.replace( /_/g, ' ' ); - link = mw.html.element( - 'a', { - href: mw.util.wikiGetlink( title ), - title: cleanTitle - }, cleanTitle - ); - html = mw.msg( 'watcherrortext', link ); - - // Report to user about the error - mw.util.jsMessage( html, 'ajaxwatch' ); - - } - ); - }); - }); - -}( jQuery, mediaWiki ) ); diff --git a/resources/mediawiki.page/mediawiki.page.watch.ajax.js b/resources/mediawiki.page/mediawiki.page.watch.ajax.js new file mode 100644 index 0000000000..114ea8c5e8 --- /dev/null +++ b/resources/mediawiki.page/mediawiki.page.watch.ajax.js @@ -0,0 +1,174 @@ +/** + * Animate watch/unwatch links to use asynchronous API requests to + * watch pages, rather than navigating to a different URI. + */ +( function ( $, mw, undefined ) { + /** + * The name of the page to watch or unwatch. + */ + var title = mw.config.get( 'wgRelevantPageName', mw.config.get( 'wgPageName' ) ); + + // Expose local methods + mw.page.watch = { + 'updateWatchLink': updateWatchLink + }; + /** + * Update the link text, link href attribute and (if applicable) + * "loading" class. + * + * @param $link {jQuery} Anchor tag of (un)watch link. + * @param action {String} One of 'watch', 'unwatch'. + * @param state {String} [optional] 'idle' or 'loading'. Default is 'idle'. + */ + function updateWatchLink( $link, action, state ) { + var accesskeyTip, msgKey, $li, otherAction; + + // message keys 'watch', 'watching', 'unwatch' or 'unwatching'. + msgKey = state === 'loading' ? action + 'ing' : action; + otherAction = action === 'watch' ? 'unwatch' : 'watch'; + accesskeyTip = $link.attr( 'title' ).match( mw.util.tooltipAccessKeyRegexp ); + $li = $link.closest( 'li' ); + /** + * Trigger a 'watch' event for this List item. + * Announce the otherAction value as the first param. + * Used to monitor the state of watch link. + * TODO: Revise when system wide hooks are implemented + */ + if( state === undefined ) { + $li.trigger( 'watch.mw', otherAction ); + } + + $link + .text( mw.msg( msgKey ) ) + .attr( 'title', mw.msg( 'tooltip-ca-' + action ) + + ( accesskeyTip ? ' ' + accesskeyTip[0] : '' ) + ) + .attr( 'href', mw.util.wikiScript() + '?' + $.param({ + title: title, + action: action + }) + ); + + // Most common ID style + if ( $li.prop( 'id' ) === 'ca-' + otherAction ) { + $li.prop( 'id', 'ca-' + action ); + } + + // Special case for vector icon + if ( $li.hasClass( 'icon' ) ) { + if ( state === 'loading' ) { + $link.addClass( 'loading' ); + } else { + $link.removeClass( 'loading' ); + } + } + } + + /** + * @todo This should be moved somewhere more accessible. + * @param url {String} + * @return {String} The extracted action, defaults to 'view'. + */ + 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 ); + if ( action !== null ) { + return action; + } + + for ( key in actionPaths ) { + if ( actionPaths.hasOwnProperty( key ) ) { + parts = actionPaths[key].split( '$1' ); + for ( i = 0; i < parts.length; i += 1 ) { + parts[i] = $.escapeRE( parts[i] ); + } + m = new RegExp( parts.join( '(.+)' ) ).exec( url ); + if ( m && m[1] ) { + return key; + } + + } + } + + return 'view'; + } + + $( document ).ready( function () { + var $links = $( '.mw-watchlink a, a.mw-watchlink, ' + + '#ca-watch a, #ca-unwatch a, #mw-unwatch-link1, ' + + '#mw-unwatch-link2, #mw-watch-link2, #mw-watch-link1' ); + + // Allowing people to add inline animated links is a little scary + $links = $links.filter( ':not( #bodyContent *, #content * )' ); + + $links.click( function ( e ) { + var action, api, $link; + + action = mwUriGetAction( this.href ); + + if ( action !== 'watch' && action !== 'unwatch' ) { + // Could not extract target action from link url, + // let native browsing handle it further + return true; + } + e.preventDefault(); + e.stopPropagation(); + + $link = $( this ); + + updateWatchLink( $link, action, 'loading' ); + + api = new mw.Api(); + api[action]( + title, + // Success + function ( watchResponse ) { + var $li, otherAction; + + otherAction = action === 'watch' ? 'unwatch' : 'watch'; + $li = $link.closest( 'li' ); + + mw.util.jsMessage( watchResponse.message, 'ajaxwatch' ); + + // Set link to opposite + updateWatchLink( $link, otherAction ); + + // Bug 12395 - update the watch checkbox on edit pages when the + // page is watched or unwatched via the tab. + if ( watchResponse.watched !== undefined ) { + $( '#wpWatchthis' ).prop( 'checked', true ); + } else { + $( '#wpWatchthis' ).removeProp( 'checked' ); + } + }, + // Error + function () { + var cleanTitle, html, link; + + // Reset link to non-loading mode + updateWatchLink( $link, action ); + + // Format error message + cleanTitle = title.replace( /_/g, ' ' ); + link = mw.html.element( + 'a', { + href: mw.util.wikiGetlink( title ), + title: cleanTitle + }, cleanTitle + ); + html = mw.msg( 'watcherrortext', link ); + + // Report to user about the error + mw.util.jsMessage( html, 'ajaxwatch' ); + + } + ); + }); + }); + +}( jQuery, mediaWiki ) );