addressing feedback on the watch/unwatch javascript changes introduced in r56924
[lhc/web/wiklou.git] / skins / common / ajaxwatch.js
1 // dependencies:
2 // * ajax.js:
3 /*extern sajax_init_object, sajax_do_call */
4 // * wikibits.js:
5 /*extern changeText, akeytt, hookEvent, jsMsg */
6
7 // These should have been initialized in the generated js
8 /*extern wgAjaxWatch, wgPageName */
9
10 if(typeof wgAjaxWatch === "undefined" || !wgAjaxWatch) {
11 var wgAjaxWatch = {
12 watchMsg: "Watch",
13 unwatchMsg: "Unwatch",
14 watchingMsg: "Watching...",
15 unwatchingMsg: "Unwatching..."
16 };
17 }
18
19 wgAjaxWatch.supported = true; // supported on current page and by browser
20 wgAjaxWatch.watching = false; // currently watching page
21 wgAjaxWatch.inprogress = false; // ajax request in progress
22 wgAjaxWatch.timeoutID = null; // see wgAjaxWatch.ajaxCall
23 wgAjaxWatch.watchLinks = []; // "watch"/"unwatch" links
24 wgAjaxWatch.iconMode = false; // new icon driven functionality
25 wgAjaxWatch.imgBasePath = ""; // base img path derived from icons on load
26
27 wgAjaxWatch.setLinkText = function(newText) {
28 if( wgAjaxWatch.iconMode ) {
29 for ( i = 0; i < wgAjaxWatch.watchLinks.length; i++ ) {
30 wgAjaxWatch.watchLinks[i].firstChild.alt = newText;
31 if( newText==wgAjaxWatch.watchingMsg || newText==wgAjaxWatch.unwatchingMsg ) {
32 wgAjaxWatch.watchLinks[i].firstChild.src = wgAjaxWatch.imgBasePath
33 + "/common/images/spinner.gif";
34 } else if( newText==wgAjaxWatch.watchMsg ) {
35 wgAjaxWatch.watchLinks[i].firstChild.src = wgAjaxWatch.imgBasePath
36 + "/vector/images/watch_off.gif";
37 } else if( newText==wgAjaxWatch.unwatchMsg ) {
38 wgAjaxWatch.watchLinks[i].firstChild.src = wgAjaxWatch.imgBasePath
39 + "/vector/images/watch_on.gif";
40 }
41 }
42 } else{
43 for ( i = 0; i < wgAjaxWatch.watchLinks.length; i++ ) {
44 changeText( wgAjaxWatch.watchLinks[i], newText );
45 }
46 }
47 };
48
49 wgAjaxWatch.setLinkID = function(newId) {
50 // We can only set the first one
51 wgAjaxWatch.watchLinks[0].parentNode.setAttribute( 'id', newId );
52 akeytt(newId); // update tooltips for Monobook
53 };
54
55 wgAjaxWatch.setHref = function( string ) {
56 for( i = 0; i < wgAjaxWatch.watchLinks.length; i++ ) {
57 if( string == 'watch' ) {
58 wgAjaxWatch.watchLinks[i].href = wgAjaxWatch.watchLinks[i].href
59 .replace( /&action=unwatch/, '&action=watch' );
60 } else if( string == 'unwatch' ) {
61 wgAjaxWatch.watchLinks[i].href = wgAjaxWatch.watchLinks[i].href
62 .replace( /&action=watch/, '&action=unwatch' );
63 }
64 }
65 }
66
67 wgAjaxWatch.ajaxCall = function() {
68 if(!wgAjaxWatch.supported) {
69 return true;
70 } else if (wgAjaxWatch.inprogress) {
71 return false;
72 }
73 if(!wfSupportsAjax()) {
74 // Lazy initialization so we don't toss up
75 // ActiveX warnings on initial page load
76 // for IE 6 users with security settings.
77 wgAjaxWatch.supported = false;
78 return true;
79 }
80
81 wgAjaxWatch.inprogress = true;
82 wgAjaxWatch.setLinkText( wgAjaxWatch.watching
83 ? wgAjaxWatch.unwatchingMsg : wgAjaxWatch.watchingMsg);
84 sajax_do_call(
85 "wfAjaxWatch",
86 [wgPageName, (wgAjaxWatch.watching ? "u" : "w")],
87 wgAjaxWatch.processResult
88 );
89 // if the request isn't done in 10 seconds, allow user to try again
90 wgAjaxWatch.timeoutID = window.setTimeout(
91 function() { wgAjaxWatch.inprogress = false; },
92 10000
93 );
94 return false;
95 };
96
97 wgAjaxWatch.processResult = function(request) {
98 if(!wgAjaxWatch.supported) {
99 return;
100 }
101 var response = request.responseText;
102 if( response.match(/^<w#>/) ) {
103 wgAjaxWatch.watching = true;
104 wgAjaxWatch.setLinkText(wgAjaxWatch.unwatchMsg);
105 wgAjaxWatch.setLinkID("ca-unwatch");
106 wgAjaxWatch.setHref( 'unwatch' );
107 } else if( response.match(/^<u#>/) ) {
108 wgAjaxWatch.watching = false;
109 wgAjaxWatch.setLinkText(wgAjaxWatch.watchMsg);
110 wgAjaxWatch.setLinkID("ca-watch");
111 wgAjaxWatch.setHref( 'watch' );
112 } else {
113 // Either we got a <err#> error code or it just plain broke.
114 window.location.href = wgAjaxWatch.watchLinks[0].href;
115 return;
116 }
117 jsMsg( response.substr(4), 'watch' );
118 wgAjaxWatch.inprogress = false;
119 if(wgAjaxWatch.timeoutID) {
120 window.clearTimeout(wgAjaxWatch.timeoutID);
121 }
122 // Bug 12395 - avoid some watch link confusion on edit
123 var watchthis = document.getElementById("wpWatchthis");
124 if( watchthis && response.match(/^<[uw]#>/) ) {
125 watchthis.checked = response.match(/^<w#>/) ? "checked" : "";
126 }
127 return;
128 };
129
130 wgAjaxWatch.onLoad = function() {
131 // This document structure hardcoding sucks. We should make a class and
132 // toss all this out the window.
133
134 var el1 = document.getElementById("ca-unwatch");
135 var el2 = null;
136 if ( !el1 ) {
137 el1 = document.getElementById("mw-unwatch-link1");
138 el2 = document.getElementById("mw-unwatch-link2");
139 }
140 if( el1 ) {
141 wgAjaxWatch.watching = true;
142 } else {
143 wgAjaxWatch.watching = false;
144 el1 = document.getElementById("ca-watch");
145 if ( !el1 ) {
146 el1 = document.getElementById("mw-watch-link1");
147 el2 = document.getElementById("mw-watch-link2");
148 }
149 if( !el1 ) {
150 wgAjaxWatch.supported = false;
151 return;
152 }
153 }
154
155 // If we're using the icon, add rollover affects
156 try{
157 if( el1.firstChild.firstChild.tagName.match( /img/i ) ) {
158 wgAjaxWatch.iconMode = true;
159 wgAjaxWatch.imgBasePath = el1.firstChild.firstChild.src
160 .replace( /\/vector\/images\/watch_(off|on).gif/, "" );
161 el1.firstChild.onmouseover = function( e ) {
162 this.firstChild.src = wgAjaxWatch.imgBasePath
163 + "/vector/images/watch_over.gif";
164 }
165 el1.firstChild.onmouseout = function( e ) {
166 this.firstChild.src = wgAjaxWatch.imgBasePath
167 + "/vector/images/watch_" + ( wgAjaxWatch.watching ? "on.gif" : "off.gif");
168 }
169 }
170 } catch( e ) {
171 // not using the icon
172 }
173
174
175 // The id can be either for the parent (Monobook-based) or the element
176 // itself (non-Monobook)
177 wgAjaxWatch.watchLinks.push( el1.tagName.toLowerCase() == "a"
178 ? el1 : el1.firstChild );
179
180 if( el2 ) {
181 wgAjaxWatch.watchLinks.push( el2 );
182 }
183
184 // I couldn't get for (watchLink in wgAjaxWatch.watchLinks) to work, if
185 // you can be my guest.
186 for( i = 0; i < wgAjaxWatch.watchLinks.length; i++ ) {
187 wgAjaxWatch.watchLinks[i].onclick = wgAjaxWatch.ajaxCall;
188 }
189 return;
190 };
191
192 hookEvent("load", wgAjaxWatch.onLoad);