Localisation updates from http://translatewiki.net.
[mediawiki.git] / resources / mediawiki.page / mediawiki.page.watch.ajax.js
blobd3f84336d51535d6ab979a631ee2802244839a8e
1 /**
2  * Animate watch/unwatch links to use asynchronous API requests to
3  * watch pages, rather than navigating to a different URI.
4  */
5 ( function ( $, mw, undefined ) {
6         /**
7          * The name of the page to watch or unwatch.
8          */
9         var title = mw.config.get( 'wgRelevantPageName', mw.config.get( 'wgPageName' ) );
11         // Expose local methods
12         mw.page.watch = {
13                 'updateWatchLink': updateWatchLink
14         };
15         /**
16          * Update the link text, link href attribute and (if applicable)
17          * "loading" class.
18          *
19          * @param $link {jQuery} Anchor tag of (un)watch link.
20          * @param action {String} One of 'watch', 'unwatch'.
21          * @param state {String} [optional] 'idle' or 'loading'. Default is 'idle'.
22          */
23         function updateWatchLink( $link, action, state ) {
24                 var accesskeyTip, msgKey, $li, otherAction;
26                 // message keys 'watch', 'watching', 'unwatch' or 'unwatching'.
27                 msgKey = state === 'loading' ? action + 'ing' : action;
28                 otherAction = action === 'watch' ? 'unwatch' : 'watch';
29                 accesskeyTip = $link.attr( 'title' ).match( mw.util.tooltipAccessKeyRegexp );
30                 $li = $link.closest( 'li' );
31                 /**
32                  * Trigger a 'watchpage' event for this List item.
33                  * Announce the otherAction value as the first param.
34                  * Used to monitor the state of watch link.
35                  * TODO: Revise when system wide hooks are implemented
36                  */
37                 if( state === undefined ) {
38                         $li.trigger( 'watchpage.mw', otherAction );
39                 }
41                 $link
42                         .text( mw.msg( msgKey ) )
43                         .attr( 'title', mw.msg( 'tooltip-ca-' + action ) +
44                                 ( accesskeyTip ? ' ' + accesskeyTip[0] : '' )
45                         )
46                         .attr( 'href', mw.util.wikiScript() + '?' + $.param({
47                                         title: title,
48                                         action: action
49                                 })
50                         );
52                 // Most common ID style
53                 if ( $li.prop( 'id' ) === 'ca-' + otherAction ) {
54                         $li.prop( 'id', 'ca-' + action );
55                 }
57                 // Special case for vector icon
58                 if ( $li.hasClass( 'icon' ) ) {
59                         if ( state === 'loading' ) {
60                                 $link.addClass( 'loading' );
61                         } else {
62                                 $link.removeClass( 'loading' );
63                         }
64                 }
65         }
67         /**
68          * @todo This should be moved somewhere more accessible.
69          * @param url {String}
70          * @return {String} The extracted action, defaults to 'view'.
71          */
72         function mwUriGetAction( url ) {
73                 var action, actionPaths, key, i, m, parts;
75                 actionPaths = mw.config.get( 'wgActionPaths' );
77                 // @todo: Does MediaWiki give action path or query param
78                 // precedence ? If the former, move this to the bottom
79                 action = mw.util.getParamValue( 'action', url );
80                 if ( action !== null ) {
81                         return action;
82                 }
84                 for ( key in actionPaths ) {
85                         if ( actionPaths.hasOwnProperty( key ) ) {
86                                 parts = actionPaths[key].split( '$1' );
87                                 for ( i = 0; i < parts.length; i += 1 ) {
88                                         parts[i] = $.escapeRE( parts[i] );
89                                 }
90                                 m = new RegExp( parts.join( '(.+)' ) ).exec( url );
91                                 if ( m && m[1] ) {
92                                         return key;
93                                 }
95                         }
96                 }
98                 return 'view';
99         }
101         $( document ).ready( function () {
102                 var $links = $( '.mw-watchlink a, a.mw-watchlink, ' +
103                         '#ca-watch a, #ca-unwatch a, #mw-unwatch-link1, ' +
104                         '#mw-unwatch-link2, #mw-watch-link2, #mw-watch-link1' );
106                 // Allowing people to add inline animated links is a little scary
107                 $links = $links.filter( ':not( #bodyContent *, #content * )' );
109                 $links.click( function ( e ) {
110                         var action, api, $link;
112                         action = mwUriGetAction( this.href );
114                         if ( action !== 'watch' && action !== 'unwatch' ) {
115                                 // Could not extract target action from link url,
116                                 // let native browsing handle it further
117                                 return true;
118                         }
119                         e.preventDefault();
120                         e.stopPropagation();
122                         $link = $( this );
124                         updateWatchLink( $link, action, 'loading' );
126                         api = new mw.Api();
127                         api[action](
128                                 title,
129                                 // Success
130                                 function ( watchResponse ) {
131                                         var $li, otherAction;
133                                         otherAction = action === 'watch' ? 'unwatch' : 'watch';
134                                         $li = $link.closest( 'li' );
136                                         mw.util.jsMessage( watchResponse.message, 'ajaxwatch' );
138                                         // Set link to opposite
139                                         updateWatchLink( $link, otherAction );
141                                         // Bug 12395 - update the watch checkbox on edit pages when the
142                                         // page is watched or unwatched via the tab.
143                                         if ( watchResponse.watched !== undefined ) {
144                                                 $( '#wpWatchthis' ).prop( 'checked', true );
145                                         } else {
146                                                 $( '#wpWatchthis' ).removeProp( 'checked' );
147                                         }
148                                 },
149                                 // Error
150                                 function () {
151                                         var cleanTitle, html, link;
153                                         // Reset link to non-loading mode
154                                         updateWatchLink( $link, action );
156                                         // Format error message
157                                         cleanTitle = title.replace( /_/g, ' ' );
158                                         link = mw.html.element(
159                                                 'a', {
160                                                         href: mw.util.wikiGetlink( title ),
161                                                         title: cleanTitle
162                                                 }, cleanTitle
163                                         );
164                                         html = mw.msg( 'watcherrortext', link );
166                                         // Report to user about the error
167                                         mw.util.jsMessage( html, 'ajaxwatch' );
169                                 }
170                         );
171                 });
172         });
174 }( jQuery, mediaWiki ) );