summaryrefslogtreecommitdiff
path: root/resources/mediawiki.action/mediawiki.action.watch.ajax.js
diff options
context:
space:
mode:
Diffstat (limited to 'resources/mediawiki.action/mediawiki.action.watch.ajax.js')
-rw-r--r--resources/mediawiki.action/mediawiki.action.watch.ajax.js271
1 files changed, 126 insertions, 145 deletions
diff --git a/resources/mediawiki.action/mediawiki.action.watch.ajax.js b/resources/mediawiki.action/mediawiki.action.watch.ajax.js
index 93aa29c9..f5f09f52 100644
--- a/resources/mediawiki.action/mediawiki.action.watch.ajax.js
+++ b/resources/mediawiki.action/mediawiki.action.watch.ajax.js
@@ -1,174 +1,155 @@
/**
* Animate watch/unwatch links to use asynchronous API requests to
- * watch pages, rather than clicking on links. Requires jQuery.
+ * watch pages, rather than navigating to a different URI.
*/
-( function( $ ) {
-var $links;
-
-var setLinkText = function( $link, action ) {
- if ( action == 'watch' || action == 'unwatch' ) {
- // save the accesskey from the title
- var keyCommand = $link.attr( 'title' ).match( /\[.*?\]$/ ) ? $link.attr( 'title' ).match( /\[.*?\]$/ )[0] : '';
- $link.attr( 'title', mw.msg( 'tooltip-ca-' + action ) + ' ' + keyCommand );
- }
- if ( $link.data( 'icon' ) ) {
- $link.attr( 'alt', mw.msg( action ) );
- if ( action == 'watching' || action == 'unwatching' ) {
+( 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 ) {
+ // message keys 'watch', 'watching', 'unwatch' or 'unwatching'.
+ var 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' );
}
- } else {
- $link.html( mw.msg( action ) );
}
-};
-
-var errorHandler = function( $link ) {
-
- // Reset link text to whatever it was before we switching it to the '(un)watch'+ing message.
- setLinkText( $link, $link.data( 'action' ) );
-
- // Format error message
- var cleanTitle = mw.config.get( 'wgPageName' ).replace( /_/g, ' ' );
- var link = mw.html.element(
- 'a', {
- 'href': mw.util.wikiGetlink( mw.config.get( 'wgPageName' ) ),
- 'title': cleanTitle
- }, cleanTitle
- );
- var msg = mw.msg( 'watcherrortext', link );
-
- // Report to user about the error
- mw.util.jsMessage( msg, 'watch' );
-};
+}
/**
- * Process the result of the API watch action.
- *
- * @param response Data object from API request.
- * @param $link jQuery object of the watch link.
- * @return Boolean true on success, false otherwise.
+ * @todo This should be moved somewhere more accessible.
+ * @param url {String}
+ * @return {String} The extracted action, defaults to 'view'.
*/
-var processResult = function( response, $link ) {
-
- if ( ( 'error' in response ) || !response.watch ) {
- errorHandler( $link );
- return false;
+function mwUriGetAction( url ) {
+ var actionPaths = mw.config.get( 'wgActionPaths' ),
+ key, parts, m, action;
+
+ // @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;
}
- var watchResponse = response.watch;
-
- // To ensure we set the same status for all watch links with the
- // same target we trigger a custom event on *all* watch links.
- if ( watchResponse.watched !== undefined ) {
- $links.trigger( 'mw-ajaxwatch', [watchResponse.title, 'watch', $link] );
- } else if ( watchResponse.unwatched !== undefined ) {
- $links.trigger( 'mw-ajaxwatch', [watchResponse.title, 'unwatch', $link] );
- } else {
- // Either we got an error code or it just plain broke.
- window.location.href = $link[0].href;
- return false;
+ 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;
+ }
+
+ }
}
- mw.util.jsMessage( watchResponse.message, 'watch' );
-
- // Bug 12395 - update the watch checkbox on edit pages when the
- // page is watched or unwatched via the tab.
- if ( watchResponse.watched !== undefined ) {
- $( '#wpWatchthis' ).attr( 'checked', 'checked' );
- } else {
- $( '#wpWatchthis' ).removeAttr( 'checked' );
- }
- return true;
-};
+ return 'view';
+}
$( document ).ready( function() {
- $links = $( '.mw-watchlink a, a.mw-watchlink' );
- // BC with older skins
- $links = $links
- .add( '#ca-watch a, #ca-unwatch a, a#mw-unwatch-link1, ' +
- 'a#mw-unwatch-link2, a#mw-watch-link2, a#mw-watch-link1' );
- // allowing people to add inline animated links is a little scary
- $links = $links.filter( ':not( #bodyContent *, #content * )' );
+ 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' );
- $links.each( function() {
- var $link = $( this );
- var link = this;
- $link
- .data( 'icon', $link.closest( 'li' ).hasClass( 'icon' ) )
- .data( 'action', mw.util.getParamValue( 'action', link.href ) == 'unwatch' ? 'unwatch' : 'watch' );
- var title = mw.util.getParamValue( 'title', link.href );
- $link.data( 'target', title.replace( /_/g, ' ' ) );
- });
+ // Allowing people to add inline animated links is a little scary
+ $links = $links.filter( ':not( #bodyContent *, #content * )' );
- $links.click( function( event ) {
- var $link = $( this );
+ $links.click( function( e ) {
+ var $link, api,
+ action = mwUriGetAction( this.href );
- if ( !mw.config.get( 'wgEnableWriteAPI' ) ) {
- // Lazy initialization so we don't toss up
- // ActiveX warnings on initial page load
- // for IE 6 users with security settings.
- $links.unbind( 'click' );
+ if ( action !== 'watch' && action !== 'unwatch' ) {
+ // Could not extract target action from link url,
+ // let native browsing handle it further
return true;
}
-
- setLinkText( $link, $link.data( 'action' ) + 'ing' );
-
- var reqData = {
- 'action': 'watch',
- 'format': 'json',
- 'title': $link.data( 'target' ),
- 'token': mw.user.tokens.get( 'watchToken' ),
- // API return contains a localized data.watch.message string.
- 'uselang': mw.config.get( 'wgUserLanguage' )
- };
-
- if ( $link.data( 'action' ) == 'unwatch' ) {
- reqData.unwatch = '';
- }
-
- $.ajax({
- url: mw.util.wikiScript( 'api' ),
- dataType: 'json',
- type: 'POST',
- data: reqData,
- success: function( data, textStatus, xhr ) {
- processResult( data, $link );
+ e.preventDefault();
+ e.stopPropagation();
+
+ $link = $( this );
+
+ updateWatchLink( $link, action, 'loading' );
+
+ api = new mw.Api();
+ api[action](
+ title,
+ // Success
+ function( watchResponse ) {
+ var 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(){
- processResult( {}, $link );
- }
- });
+ // Error
+ function(){
+
+ // Reset link to non-loading mode
+ updateWatchLink( $link, action );
+
+ // Format error message
+ var cleanTitle = title.replace( /_/g, ' ' );
+ var link = mw.html.element(
+ 'a', {
+ 'href': mw.util.wikiGetlink( title ),
+ 'title': cleanTitle
+ }, cleanTitle
+ );
+ var html = mw.msg( 'watcherrortext', link );
+
+ // Report to user about the error
+ mw.util.jsMessage( html, 'ajaxwatch' );
- return false;
- });
-
- // When a request returns, a custom event 'mw-ajaxwatch' is triggered
- // on *all* watch links, so they can be updated if necessary
- $links.bind( 'mw-ajaxwatch', function( event, target, action, $link ) {
- var foo = $link.data( 'target' );
- if ( $link.data( 'target' ) == target ) {
- var otheraction = action == 'watch'
- ? 'unwatch'
- : 'watch';
-
- $link.data( 'action', otheraction );
- setLinkText( $link, otheraction );
- $link.attr( 'href',
- mw.config.get( 'wgScript' )
- + '?title=' + mw.util.wikiUrlencode( mw.config.get( 'wgPageName' ) )
- + '&action=' + otheraction
- );
- if ( $link.closest( 'li' ).attr( 'id' ) == 'ca-' + action ) {
- $link.closest( 'li' ).attr( 'id', 'ca-' + otheraction );
- // update the link text with the new message
- $link.text( mw.msg( otheraction ) );
}
- }
-
- return false;
+ );
});
});
-})( jQuery );
+})( jQuery, mediaWiki );