* (bug 10397) Fix AJAX watch error fallback when we receive a bogus result
[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
25 wgAjaxWatch.setLinkText = function(newText) {
26 for (i = 0; i < wgAjaxWatch.watchLinks.length; i++) {
27 changeText(wgAjaxWatch.watchLinks[i], newText);
28 }
29 };
30
31 wgAjaxWatch.setLinkID = function(newId) {
32 // We can only set the first one
33 wgAjaxWatch.watchLinks[0].setAttribute( 'id', newId );
34 akeytt(newId); // update tooltips for Monobook
35 };
36
37 wgAjaxWatch.setHref = function( string ) {
38 for( i = 0; i < wgAjaxWatch.watchLinks.length; i++ ) {
39 if( string == 'watch' ) {
40 wgAjaxWatch.watchLinks[i].href = wgAjaxWatch.watchLinks[i].href
41 .replace( /&action=unwatch/, '&action=watch' );
42 } else if( string == 'unwatch' ) {
43 wgAjaxWatch.watchLinks[i].href = wgAjaxWatch.watchLinks[i].href
44 .replace( /&action=watch/, '&action=unwatch' );
45 }
46 }
47 }
48
49 wgAjaxWatch.ajaxCall = function() {
50 if(!wgAjaxWatch.supported) {
51 return true;
52 } else if (wgAjaxWatch.inprogress) {
53 return false;
54 }
55 wgAjaxWatch.inprogress = true;
56 wgAjaxWatch.setLinkText( wgAjaxWatch.watching
57 ? wgAjaxWatch.unwatchingMsg : wgAjaxWatch.watchingMsg);
58 sajax_do_call(
59 "wfAjaxWatch",
60 [wgPageName, (wgAjaxWatch.watching ? "u" : "w")],
61 wgAjaxWatch.processResult
62 );
63 // if the request isn't done in 10 seconds, allow user to try again
64 wgAjaxWatch.timeoutID = window.setTimeout(
65 function() { wgAjaxWatch.inprogress = false; },
66 10000
67 );
68 return false;
69 };
70
71 wgAjaxWatch.processResult = function(request) {
72 if(!wgAjaxWatch.supported) {
73 return;
74 }
75 var response = request.responseText;
76 if( response.match(/^<w#>/) ) {
77 wgAjaxWatch.watching = true;
78 wgAjaxWatch.setLinkText(wgAjaxWatch.unwatchMsg);
79 wgAjaxWatch.setLinkID("ca-unwatch");
80 wgAjaxWatch.setHref( 'unwatch' );
81 } else if( response.match(/^<u#>/) ) {
82 wgAjaxWatch.watching = false;
83 wgAjaxWatch.setLinkText(wgAjaxWatch.watchMsg);
84 wgAjaxWatch.setLinkID("ca-watch");
85 wgAjaxWatch.setHref( 'watch' );
86 } else {
87 // Either we got a <err#> error code or it just plain broke.
88 window.location.href = wgAjaxWatch.watchLinks[0].href;
89 return;
90 }
91 jsMsg( response.substr(4), 'watch' );
92 wgAjaxWatch.inprogress = false;
93 if(wgAjaxWatch.timeoutID) {
94 window.clearTimeout(wgAjaxWatch.timeoutID);
95 }
96 return;
97 };
98
99 wgAjaxWatch.onLoad = function() {
100 // This document structure hardcoding sucks. We should make a class and
101 // toss all this out the window.
102 var el1 = document.getElementById("ca-unwatch");
103 var el2 = null;
104 if (!el1) {
105 el1 = document.getElementById("mw-unwatch-link1");
106 el2 = document.getElementById("mw-unwatch-link2");
107 }
108 if(el1) {
109 wgAjaxWatch.watching = true;
110 } else {
111 wgAjaxWatch.watching = false;
112 el1 = document.getElementById("ca-watch");
113 if (!el1) {
114 el1 = document.getElementById("mw-watch-link1");
115 el2 = document.getElementById("mw-watch-link2");
116 }
117 if(!el1) {
118 wgAjaxWatch.supported = false;
119 return;
120 }
121 }
122
123 if(!wfSupportsAjax()) {
124 wgAjaxWatch.supported = false;
125 return;
126 }
127
128 // The id can be either for the parent (Monobook-based) or the element
129 // itself (non-Monobook)
130 wgAjaxWatch.watchLinks.push( el1.tagName.toLowerCase() == "a"
131 ? el1 : el1.firstChild );
132
133 if( el2 ) {
134 wgAjaxWatch.watchLinks.push( el2 );
135 }
136
137 // I couldn't get for (watchLink in wgAjaxWatch.watchLinks) to work, if
138 // you can be my guest.
139 for( i = 0; i < wgAjaxWatch.watchLinks.length; i++ ) {
140 wgAjaxWatch.watchLinks[i].onclick = wgAjaxWatch.ajaxCall;
141 }
142 return;
143 };
144
145 hookEvent("load", wgAjaxWatch.onLoad);
146
147 /**
148 * @return boolean whether the browser supports XMLHttpRequest
149 */
150 function wfSupportsAjax() {
151 var request = sajax_init_object();
152 var supportsAjax = request ? true : false;
153 delete request;
154 return supportsAjax;
155 }