reworking EditPage to use the content object - work in horrible progress
[mediawiki.git] / resources / mediawiki.action / mediawiki.action.watch.ajax.js
blob00fcbb3e1edaad3b108de7ba5b048daa2b4d1a7c
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 ) {
7 /**
8  * Update the link text, link href attribute and (if applicable)
9  * "loading" class.
10  *
11  * @param $link {jQuery} Anchor tag of (un)watch link
12  * @param action {String} One of 'watch', 'unwatch'.
13  * @param state {String} [optional] 'idle' or 'loading'. Default is 'idle'.
14  */
15 function updateWatchLink( $link, action, state ) {
16         // message keys 'watch', 'watching', 'unwatch' or 'unwatching'.
17         var     msgKey = state === 'loading' ? action + 'ing' : action,
18                 accesskeyTip = $link.attr( 'title' ).match( mw.util.tooltipAccessKeyRegexp ),
19                 $li = $link.closest( 'li' );
21         $link
22                 .text( mw.msg( msgKey ) )
23                 .attr( 'title', mw.msg( 'tooltip-ca-' + action ) +
24                         ( accesskeyTip ? ' ' + accesskeyTip[0] : '' )
25                 )
26                 .attr( 'href', mw.util.wikiScript() + '?' + $.param({
27                                 title: mw.config.get( 'wgPageName' ),
28                                 action: action
29                         })
30                 );
32         // Special case for vector icon
33         if ( $li.hasClass( 'icon' ) ) {
34                 if ( state === 'loading' ) {
35                         $link.addClass( 'loading' );
36                 } else {
37                         $link.removeClass( 'loading' );
38                 }
39         }
42 /**
43  * @todo This should be moved somewhere more accessible.
44  * @param url {String}
45  * @return {String} The extracted action, defaults to 'view'.
46  */
47 function mwUriGetAction( url ) {
48         var     actionPaths = mw.config.get( 'wgActionPaths' ),
49                 key, parts, m, action;
51         // @todo: Does MediaWiki give action path or query param
52         // precedence ? If the former, move this to the bottom
53         action = mw.util.getParamValue( 'action', url );
54         if ( action !== null ) {
55                 return action;
56         }
58         for ( key in actionPaths ) {
59                 if ( actionPaths.hasOwnProperty( key ) ) {
60                         parts = actionPaths[key].split( '$1' );
61                         for ( i = 0; i < parts.length; i += 1 ) {
62                                 parts[i] = $.escapeRE( parts[i] );
63                         }
64                         m = new RegExp( parts.join( '(.+)' ) ).exec( url );
65                         if ( m && m[1] ) {
66                                 return key;
67                         }
68                 
69                 }
70         }
72         return 'view';
75 $( document ).ready( function() {
76         var $links = $( '.mw-watchlink a, a.mw-watchlink, ' +
77                 '#ca-watch a, #ca-unwatch a, #mw-unwatch-link1, ' +
78                 '#mw-unwatch-link2, #mw-watch-link2, #mw-watch-link1' );
80         // Allowing people to add inline animated links is a little scary
81         $links = $links.filter( ':not( #bodyContent *, #content * )' );
83         $links.click( function( e ) {
84                 var     $link, api,
85                         action = mwUriGetAction( this.href );
87                 if ( action !== 'watch' && action !== 'unwatch' ) {
88                         // Could not extract target action from link url,
89                         // let native browsing handle it further
90                         return true;
91                 }
92                 e.preventDefault();
93                 e.stopPropagation();
94                 
95                 $link = $( this );
97                 updateWatchLink( $link, action, 'loading' );
99                 api = new mw.Api();
100                 api[action](
101                         mw.config.get( 'wgPageName' ),
102                         // Success
103                         function( watchResponse ) {
104                                 var     otherAction = action === 'watch' ? 'unwatch' : 'watch',
105                                         $li = $link.closest( 'li' );
107                                 mw.util.jsMessage( watchResponse.message, 'ajaxwatch' );
109                                 // Set link to opposite
110                                 updateWatchLink( $link, otherAction );
112                                 // Most common ID style
113                                 if ( $li.prop( 'id' ) === 'ca-' + otherAction || $li.prop( 'id' ) === 'ca-' + action ) {
114                                         $li.prop( 'id', 'ca-' + otherAction );
115                                 }
116                                 
117                                 // Bug 12395 - update the watch checkbox on edit pages when the
118                                 // page is watched or unwatched via the tab.
119                                 if ( watchResponse.watched !== undefined ) {
120                                         $( '#wpWatchthis' ).prop( 'checked', true );
121                                 } else {
122                                         $( '#wpWatchthis' ).removeProp( 'checked' );
123                                 }
124                         },
125                         // Error
126                         function(){             
128                                 // Reset link to non-loading mode
129                                 updateWatchLink( $link, action );
130                                 
131                                 // Format error message
132                                 var cleanTitle = mw.config.get( 'wgPageName' ).replace( /_/g, ' ' );
133                                 var link = mw.html.element(
134                                         'a', {
135                                                 'href': mw.util.wikiGetlink( mw.config.get( 'wgPageName' ) ),
136                                                 'title': cleanTitle
137                                         }, cleanTitle
138                                 );
139                                 var html = mw.msg( 'watcherrortext', link );
140                                 
141                                 // Report to user about the error
142                                 mw.util.jsMessage( html, 'ajaxwatch' );
144                         }
145                 );
146         });
150 })( jQuery, mediaWiki );