Various fixes to job running code in Wiki.php
[mediawiki.git] / resources / mediawiki.page / mediawiki.page.watch.ajax.js
blobef287c4324f4d436f1fe26afecb03fcb73e86494
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, $ ) {
6         /**
7          * The name of the page to watch or unwatch.
8          */
9         var title = mw.config.get( 'wgRelevantPageName', mw.config.get( 'wgPageName' ) );
11         /**
12          * Update the link text, link href attribute and (if applicable)
13          * "loading" class.
14          *
15          * @param $link {jQuery} Anchor tag of (un)watch link.
16          * @param action {String} One of 'watch', 'unwatch'.
17          * @param state {String} [optional] 'idle' or 'loading'. Default is 'idle'.
18          */
19         function updateWatchLink( $link, action, state ) {
20                 var accesskeyTip, msgKey, $li, otherAction;
22                 // message keys 'watch', 'watching', 'unwatch' or 'unwatching'.
23                 msgKey = state === 'loading' ? action + 'ing' : action;
24                 otherAction = action === 'watch' ? 'unwatch' : 'watch';
25                 accesskeyTip = $link.attr( 'title' ).match( mw.util.tooltipAccessKeyRegexp );
26                 $li = $link.closest( 'li' );
28                 /**
29                  * Trigger a 'watchpage' event for this List item.
30                  * Announce the otherAction value as the first param.
31                  * Used to monitor the state of watch link.
32                  * TODO: Revise when system wide hooks are implemented
33                  */
34                 if ( state === undefined ) {
35                         $li.trigger( 'watchpage.mw', otherAction );
36                 }
38                 $link
39                         .text( mw.msg( msgKey ) )
40                         .attr( 'title', mw.msg( 'tooltip-ca-' + action ) +
41                                 ( accesskeyTip ? ' ' + accesskeyTip[0] : '' )
42                         )
43                         .attr( 'href', mw.util.wikiScript() + '?' + $.param( {
44                                         title: title,
45                                         action: action
46                                 } )
47                         );
49                 // Most common ID style
50                 if ( $li.prop( 'id' ) === 'ca-' + otherAction ) {
51                         $li.prop( 'id', 'ca-' + action );
52                 }
54                 // Special case for vector icon
55                 if ( $li.hasClass( 'icon' ) ) {
56                         if ( state === 'loading' ) {
57                                 $link.addClass( 'loading' );
58                         } else {
59                                 $link.removeClass( 'loading' );
60                         }
61                 }
62         }
64         /**
65          * @todo This should be moved somewhere more accessible.
66          * @param url {String}
67          * @return {String} The extracted action, defaults to 'view'.
68          */
69         function mwUriGetAction( url ) {
70                 var action, actionPaths, key, i, m, parts;
72                 actionPaths = mw.config.get( 'wgActionPaths' );
74                 // @todo Does MediaWiki give action path or query param
75                 // precedence ? If the former, move this to the bottom
76                 action = mw.util.getParamValue( 'action', url );
77                 if ( action !== null ) {
78                         return action;
79                 }
81                 for ( key in actionPaths ) {
82                         if ( actionPaths.hasOwnProperty( key ) ) {
83                                 parts = actionPaths[key].split( '$1' );
84                                 for ( i = 0; i < parts.length; i += 1 ) {
85                                         parts[i] = $.escapeRE( parts[i] );
86                                 }
87                                 m = new RegExp( parts.join( '(.+)' ) ).exec( url );
88                                 if ( m && m[1] ) {
89                                         return key;
90                                 }
92                         }
93                 }
95                 return 'view';
96         }
98         // Expose local methods
99         mw.page.watch = {
100                 updateWatchLink: updateWatchLink
101         };
103         $( function () {
104                 var $links = $( '.mw-watchlink a, a.mw-watchlink, ' +
105                         '#ca-watch a, #ca-unwatch a, #mw-unwatch-link1, ' +
106                         '#mw-unwatch-link2, #mw-watch-link2, #mw-watch-link1' );
108                 // Allowing people to add inline animated links is a little scary
109                 $links = $links.filter( ':not( #bodyContent *, #content * )' );
111                 $links.click( function ( e ) {
112                         var action, api, $link;
114                         action = mwUriGetAction( this.href );
116                         if ( action !== 'watch' && action !== 'unwatch' ) {
117                                 // Could not extract target action from link url,
118                                 // let native browsing handle it further
119                                 return true;
120                         }
121                         e.preventDefault();
122                         e.stopPropagation();
124                         $link = $( this );
126                         updateWatchLink( $link, action, 'loading' );
128                         api = new mw.Api();
129                         api[action]( title )
130                         .done( function ( watchResponse ) {
131                                 var otherAction;
133                                 otherAction = action === 'watch' ? 'unwatch' : 'watch';
135                                 mw.notify( $.parseHTML( watchResponse.message ), {
136                                         tag: 'watch-self'
137                                 } );
139                                 // Set link to opposite
140                                 updateWatchLink( $link, otherAction );
142                                 // Bug 12395 - update the watch checkbox on edit pages when the
143                                 // page is watched or unwatched via the tab.
144                                 if ( watchResponse.watched !== undefined ) {
145                                         $( '#wpWatchthis' ).prop( 'checked', true );
146                                 } else {
147                                         $( '#wpWatchthis' ).prop( 'checked', false );
148                                 }
149                         } )
150                         .fail( function () {
151                                 var cleanTitle, msg, 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.getUrl( title ),
161                                                 title: cleanTitle
162                                         }, cleanTitle
163                                 );
164                                 msg = mw.message( 'watcherrortext', link );
166                                 // Report to user about the error
167                                 mw.notify( msg, { tag: 'watch-self' } );
168                         } );
169                 } );
170         } );
172 }( mediaWiki, jQuery ) );