[mediawiki.action.watch.ajax.js] Rewrite using mw.Api and fixes bug 27146
[lhc/web/wiklou.git] / resources / mediawiki.action / mediawiki.action.watch.ajax.js
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 /**
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' );
20
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 );
31
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 }
40 }
41
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;
50
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 }
57
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 }
71
72 return 'view';
73 }
74
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' );
79
80 // Allowing people to add inline animated links is a little scary
81 $links = $links.filter( ':not( #bodyContent *, #content * )' );
82
83 $links.click( function( e ) {
84 var $link, api,
85 action = mwUriGetAction( this.href );
86
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 );
96
97 updateWatchLink( $link, action, 'loading' );
98
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' );
106
107 mw.util.jsMessage( watchResponse.message, 'ajaxwatch' );
108
109 // Set link to opposite
110 updateWatchLink( $link, otherAction );
111
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(){
127
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' );
143
144 }
145 );
146 });
147
148 });
149
150 })( jQuery, mediaWiki );