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