Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.prefs.js |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | |
12 | 12 | /* Extension */ |
13 | 13 | |
14 | | -$.extend( mw.legacy, { |
| 14 | +$.extend( true, mw.legacy, { |
15 | 15 | |
16 | 16 | /* Functions */ |
17 | 17 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.metadata.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | |
8 | 8 | /* Extension */ |
9 | 9 | |
10 | | -$.extend( mw.legacy, { |
| 10 | +$.extend( true, mw.legacy, { |
11 | 11 | /** |
12 | 12 | * Exif metadata display for MediaWiki file uploads |
13 | 13 | * |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.protect.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | |
8 | 8 | /* Extension */ |
9 | 9 | |
10 | | -$.extend( mw.legacy, { |
| 10 | +$.extend( true, mw.legacy, { |
11 | 11 | |
12 | 12 | /* Global Variables */ |
13 | 13 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.preview.js |
— | — | @@ -8,7 +8,7 @@ |
9 | 9 | |
10 | 10 | /* Extension */ |
11 | 11 | |
12 | | -$.extend( mw.legacy, { |
| 12 | +$.extend( true, mw.legacy, { |
13 | 13 | |
14 | 14 | /* Functions */ |
15 | 15 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.ajax.js |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | |
12 | 12 | /* Extension */ |
13 | 13 | |
14 | | -$.extend( mw.legacy, { |
| 14 | +$.extend( true, mw.legacy, { |
15 | 15 | |
16 | 16 | /* Global Variables */ |
17 | 17 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.upload.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | |
8 | 8 | /* Extension */ |
9 | 9 | |
10 | | -$.extend( mw.legacy, { |
| 10 | +$.extend( true, mw.legacy, { |
11 | 11 | |
12 | 12 | /* Global Variables */ |
13 | 13 | |
— | — | @@ -26,7 +26,7 @@ |
27 | 27 | if ( !wgAjaxUploadDestCheck || !sajax_init_object() ) return; |
28 | 28 | |
29 | 29 | // Find file to upload |
30 | | - var destFile = document.getElementById('wpDestFile'); |
| 30 | + var destFile = document.getElementById( 'wpDestFile' ); |
31 | 31 | var warningElt = document.getElementById( 'wpDestFile-warning' ); |
32 | 32 | if ( !destFile || !warningElt ) return ; |
33 | 33 | this.nameToCheck = destFile.value ; |
— | — | @@ -35,15 +35,15 @@ |
36 | 36 | window.clearTimeout( this.timeoutID ); |
37 | 37 | } |
38 | 38 | // Check response cache |
39 | | - for (cached in this.responseCache) { |
40 | | - if (this.nameToCheck == cached) { |
41 | | - this.setWarning(this.responseCache[this.nameToCheck]); |
| 39 | + for ( cached in this.responseCache ) { |
| 40 | + if ( this.nameToCheck == cached ) { |
| 41 | + this.setWarning( this.responseCache[this.nameToCheck] ); |
42 | 42 | return; |
43 | 43 | } |
44 | 44 | } |
45 | 45 | this.timeoutID = window.setTimeout( 'wgUploadWarningObj.timeout()', this.delay ); |
46 | 46 | }, |
47 | | - 'checkNow': function (fname) { |
| 47 | + 'checkNow': function ( fname ) { |
48 | 48 | if ( !wgAjaxUploadDestCheck || !sajax_init_object() ) return; |
49 | 49 | if ( this.timeoutID ) { |
50 | 50 | window.clearTimeout( this.timeoutID ); |
— | — | @@ -61,21 +61,21 @@ |
62 | 62 | var obj = this; |
63 | 63 | var fileName = this.nameToCheck; |
64 | 64 | sajax_do_call( 'SpecialUpload::ajaxGetExistsWarning', [this.nameToCheck], |
65 | | - function (result) { |
66 | | - obj.processResult(result, fileName) |
| 65 | + function ( result ) { |
| 66 | + obj.processResult( result, fileName ) |
67 | 67 | } |
68 | | - ); |
| 68 | + ); |
69 | 69 | }, |
70 | | - 'processResult' : function (result, fileName) { |
| 70 | + 'processResult' : function ( result, fileName ) { |
71 | 71 | removeSpinner( 'destcheck' ); |
72 | | - this.setWarning(result.responseText); |
| 72 | + this.setWarning( result.responseText ); |
73 | 73 | this.responseCache[fileName] = result.responseText; |
74 | 74 | }, |
75 | | - 'setWarning' : function (warning) { |
| 75 | + 'setWarning' : function ( warning ) { |
76 | 76 | var warningElt = document.getElementById( 'wpDestFile-warning' ); |
77 | 77 | var ackElt = document.getElementsByName( 'wpDestFileWarningAck' ); |
78 | 78 | |
79 | | - this.setInnerHTML(warningElt, warning); |
| 79 | + this.setInnerHTML( warningElt, warning ); |
80 | 80 | |
81 | 81 | // Set a value in the form indicating that the warning is acknowledged and |
82 | 82 | // doesn't need to be redisplayed post-upload |
— | — | @@ -85,9 +85,9 @@ |
86 | 86 | ackElt[0].value = '1'; |
87 | 87 | } |
88 | 88 | }, |
89 | | - 'setInnerHTML' : function (element, text) { |
| 89 | + 'setInnerHTML' : function ( element, text ) { |
90 | 90 | // Check for no change to avoid flicker in IE 7 |
91 | | - if (element.innerHTML != text) { |
| 91 | + if ( element.innerHTML != text ) { |
92 | 92 | element.innerHTML = text; |
93 | 93 | } |
94 | 94 | } |
— | — | @@ -101,15 +101,15 @@ |
102 | 102 | /* Functions */ |
103 | 103 | |
104 | 104 | 'fetchPreview': function( license ) { |
105 | | - if( !wgAjaxLicensePreview ) return; |
106 | | - for (cached in this.responseCache) { |
107 | | - if (cached == license) { |
| 105 | + if ( !wgAjaxLicensePreview ) return; |
| 106 | + for ( cached in this.responseCache ) { |
| 107 | + if ( cached == license ) { |
108 | 108 | this.showPreview( this.responseCache[license] ); |
109 | 109 | return; |
110 | 110 | } |
111 | 111 | } |
112 | 112 | injectSpinner( document.getElementById( 'wpLicense' ), 'license' ); |
113 | | - var title = document.getElementById('wpDestFile').value; |
| 113 | + var title = document.getElementById( 'wpDestFile' ).value; |
114 | 114 | if ( !title ) title = 'File:Sample.jpg'; |
115 | 115 | var url = wgScriptPath + '/api' + wgScriptExtension |
116 | 116 | + '?action=parse&text={{' + encodeURIComponent( license ) + '}}' |
— | — | @@ -118,7 +118,7 @@ |
119 | 119 | var req = sajax_init_object(); |
120 | 120 | req.onreadystatechange = function() { |
121 | 121 | if ( req.readyState == 4 && req.status == 200 ) |
122 | | - wgUploadLicenseObj.processResult( eval( '(' + req.responseText + ')' ), license ); |
| 122 | + wgUploadLicenseObj.processResult( eval( '( ' + req.responseText + ' )' ), license ); |
123 | 123 | }; |
124 | 124 | req.open( 'GET', url, true ); |
125 | 125 | req.send( '' ); |
— | — | @@ -138,10 +138,10 @@ |
139 | 139 | /* Functions */ |
140 | 140 | |
141 | 141 | 'licenseSelectorCheck': function() { |
142 | | - var selector = document.getElementById( "wpLicense" ); |
| 142 | + var selector = document.getElementById( 'wpLicense' ); |
143 | 143 | var selection = selector.options[selector.selectedIndex].value; |
144 | 144 | if( selector.selectedIndex > 0 ) { |
145 | | - if( selection == "" ) { |
| 145 | + if( selection == '' ) { |
146 | 146 | // Option disabled, but browser is broken and doesn't respect this |
147 | 147 | selector.selectedIndex = 0; |
148 | 148 | } |
— | — | @@ -155,18 +155,18 @@ |
156 | 156 | if( e ) { |
157 | 157 | if( !e.checked ) { |
158 | 158 | var ein = document.getElementById( 'wpUploadFileURL' ); |
159 | | - if(ein) |
| 159 | + if( ein ) |
160 | 160 | ein.setAttribute( 'disabled', 'disabled' ); |
161 | 161 | } |
162 | 162 | } |
163 | 163 | // For MSIE/Mac: non-breaking spaces cause the <option> not to render. |
164 | 164 | // But for some reason, setting the text to itself works |
165 | | - var selector = document.getElementById("wpLicense"); |
166 | | - if (selector) { |
| 165 | + var selector = document.getElementById( 'wpLicense' ); |
| 166 | + if ( selector ) { |
167 | 167 | var ua = navigator.userAgent; |
168 | | - var isMacIe = (ua.indexOf("MSIE") != -1) && (ua.indexOf("Mac") != -1); |
169 | | - if (isMacIe) { |
170 | | - for (var i = 0; i < selector.options.length; i++) { |
| 168 | + var isMacIe = ( ua.indexOf( 'MSIE' ) != -1 ) && ( ua.indexOf( 'Mac' ) != -1 ); |
| 169 | + if ( isMacIe ) { |
| 170 | + for ( var i = 0; i < selector.options.length; i++ ) { |
171 | 171 | selector.options[i].text = selector.options[i].text; |
172 | 172 | } |
173 | 173 | } |
— | — | @@ -181,9 +181,9 @@ |
182 | 182 | // Insert an event handler that fetches upload warnings when wpDestFile |
183 | 183 | // has been changed |
184 | 184 | document.getElementById( 'wpDestFile' ).onchange = function ( e ) { |
185 | | - wgUploadWarningObj.checkNow(this.value); |
| 185 | + wgUploadWarningObj.checkNow( this.value ); |
186 | 186 | }; |
187 | | - // Insert a row where the warnings will be displayed just below the |
| 187 | + // Insert a row where the warnings will be displayed just below the |
188 | 188 | // wpDestFile row |
189 | 189 | var optionsTable = document.getElementById( 'mw-htmlform-description' ).tBodies[0]; |
190 | 190 | var row = optionsTable.insertRow( 1 ); |
— | — | @@ -209,14 +209,15 @@ |
210 | 210 | } |
211 | 211 | // fillDestFile setup |
212 | 212 | for ( var i = 0; i < wgUploadSourceIds.length; i++ ) |
213 | | - document.getElementById( wgUploadSourceIds[i] ).onchange = function (e) { |
| 213 | + document.getElementById( wgUploadSourceIds[i] ).onchange = function ( e ) { |
214 | 214 | fillDestFilename( this.id ); |
215 | 215 | }; |
216 | 216 | }, |
217 | 217 | /** |
218 | 218 | * Iterate over all upload source fields and disable all except the selected one. |
219 | 219 | * |
220 | | - * @param enabledId The id of the selected radio button |
| 220 | + * @param enabledId |
| 221 | + * The id of the selected radio button |
221 | 222 | * @return emptiness |
222 | 223 | */ |
223 | 224 | 'toggleUploadInputs': function() { |
— | — | @@ -243,16 +244,16 @@ |
244 | 245 | } |
245 | 246 | // Disable all unselected rows |
246 | 247 | for ( var j = 0; j < inputs.length; j++ ) { |
247 | | - if ( inputs[j].type != 'radio') |
| 248 | + if ( inputs[j].type != 'radio' ) |
248 | 249 | inputs[j].disabled = !isChecked; |
249 | 250 | } |
250 | 251 | } |
251 | 252 | }, |
252 | | - 'fillDestFilename': function(id) { |
253 | | - if (!wgUploadAutoFill) { |
| 253 | + 'fillDestFilename': function( id ) { |
| 254 | + if ( !wgUploadAutoFill ) { |
254 | 255 | return; |
255 | 256 | } |
256 | | - if (!document.getElementById) { |
| 257 | + if ( !document.getElementById ) { |
257 | 258 | return; |
258 | 259 | } |
259 | 260 | // Remove any previously flagged errors |
— | — | @@ -260,62 +261,62 @@ |
261 | 262 | if( e ) e.className = ''; |
262 | 263 | var e = document.getElementById( 'mw-upload-prohibited' ); |
263 | 264 | if( e ) e.className = ''; |
264 | | - var path = document.getElementById(id).value; |
| 265 | + var path = document.getElementById( id ).value; |
265 | 266 | // Find trailing part |
266 | | - var slash = path.lastIndexOf('/'); |
267 | | - var backslash = path.lastIndexOf('\\'); |
| 267 | + var slash = path.lastIndexOf( '/' ); |
| 268 | + var backslash = path.lastIndexOf( '\\' ); |
268 | 269 | var fname; |
269 | | - if (slash == -1 && backslash == -1) { |
| 270 | + if ( slash == -1 && backslash == -1 ) { |
270 | 271 | fname = path; |
271 | | - } else if (slash > backslash) { |
272 | | - fname = path.substring(slash+1, 10000); |
| 272 | + } else if ( slash > backslash ) { |
| 273 | + fname = path.substring( slash+1, 10000 ); |
273 | 274 | } else { |
274 | | - fname = path.substring(backslash+1, 10000); |
| 275 | + fname = path.substring( backslash+1, 10000 ); |
275 | 276 | } |
276 | 277 | // Clear the filename if it does not have a valid extension. |
277 | | - // URLs are less likely to have a useful extension, so don't include them in the |
| 278 | + // URLs are less likely to have a useful extension, so don't include them in the |
278 | 279 | // extension check. |
279 | 280 | if( wgStrictFileExtensions && wgFileExtensions && id != 'wpUploadFileURL' ) { |
280 | 281 | var found = false; |
281 | | - if( fname.lastIndexOf( '.' ) != -1 ) { |
| 282 | + if ( fname.lastIndexOf( '.' ) != -1 ) { |
282 | 283 | var ext = fname.substr( fname.lastIndexOf( '.' ) + 1 ); |
283 | | - for( var i = 0; i < wgFileExtensions.length; i++ ) { |
284 | | - if( wgFileExtensions[i].toLowerCase() == ext.toLowerCase() ) { |
| 284 | + for ( var i = 0; i < wgFileExtensions.length; i++ ) { |
| 285 | + if ( wgFileExtensions[i].toLowerCase() == ext.toLowerCase() ) { |
285 | 286 | found = true; |
286 | 287 | break; |
287 | 288 | } |
288 | 289 | } |
289 | 290 | } |
290 | | - if( !found ) { |
| 291 | + if ( !found ) { |
291 | 292 | // Not a valid extension |
292 | 293 | // Clear the upload and set mw-upload-permitted to error |
293 | | - document.getElementById(id).value = ''; |
| 294 | + document.getElementById( id ).value = ''; |
294 | 295 | var e = document.getElementById( 'mw-upload-permitted' ); |
295 | | - if( e ) e.className = 'error'; |
| 296 | + if ( e ) e.className = 'error'; |
296 | 297 | var e = document.getElementById( 'mw-upload-prohibited' ); |
297 | | - if( e ) e.className = 'error'; |
| 298 | + if ( e ) e.className = 'error'; |
298 | 299 | // Clear wpDestFile as well |
299 | 300 | var e = document.getElementById( 'wpDestFile' ) |
300 | | - if( e ) e.value = ''; |
| 301 | + if ( e ) e.value = ''; |
301 | 302 | |
302 | 303 | return false; |
303 | 304 | } |
304 | 305 | } |
305 | 306 | // Capitalise first letter and replace spaces by underscores |
306 | 307 | // FIXME: $wgCapitalizedNamespaces |
307 | | - fname = fname.charAt(0).toUpperCase().concat(fname.substring(1,10000)).replace(/ /g, '_'); |
| 308 | + fname = fname.charAt( 0 ).toUpperCase().concat( fname.substring( 1,10000 ) ).replace( / /g, '_' ); |
308 | 309 | // Output result |
309 | | - var destFile = document.getElementById('wpDestFile'); |
310 | | - if (destFile) { |
| 310 | + var destFile = document.getElementById( 'wpDestFile' ); |
| 311 | + if ( destFile ) { |
311 | 312 | destFile.value = fname; |
312 | | - wgUploadWarningObj.checkNow(fname) ; |
| 313 | + wgUploadWarningObj.checkNow( fname ) ; |
313 | 314 | } |
314 | 315 | }, |
315 | 316 | 'toggleFilenameFiller': function() { |
316 | | - if(!document.getElementById) return; |
317 | | - var upfield = document.getElementById('wpUploadFile'); |
318 | | - var destName = document.getElementById('wpDestFile').value; |
319 | | - if (destName=='' || destName==' ') { |
| 317 | + if ( !document.getElementById ) return; |
| 318 | + var upfield = document.getElementById( 'wpUploadFile' ); |
| 319 | + var destName = document.getElementById( 'wpDestFile' ).value; |
| 320 | + if ( destName=='' || destName==' ' ) { |
320 | 321 | wgUploadAutoFill = true; |
321 | 322 | } else { |
322 | 323 | wgUploadAutoFill = false; |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.wikibits.js |
— | — | @@ -2,20 +2,1089 @@ |
3 | 3 | * Legacy emulation for the now depricated skins/common/wikibits.js |
4 | 4 | * |
5 | 5 | * MediaWiki JavaScript support functions |
| 6 | + * |
| 7 | + * Global external objects used by this script: ta, stylepath, skin |
6 | 8 | */ |
7 | 9 | |
8 | 10 | ( function( $, mw ) { |
9 | 11 | |
10 | 12 | /* Extension */ |
11 | 13 | |
12 | | -$.extend( mw.legacy, { |
13 | | - // |
| 14 | +/* |
| 15 | + * Scary user-agent detection stuff |
| 16 | + */ |
| 17 | +mw.legacy.clientPC = navigator.userAgent.toLowerCase(); // Get client info |
| 18 | +mw.legacy.is_gecko = /gecko/.test( mw.legacy.clientPC ) && !/khtml|spoofer|netscape\/7\.0/.test(mw.legacy.clientPC); |
| 19 | +mw.legacy.webkit_match = mw.legacy.clientPC.match(/applewebkit\/(\d+)/); |
| 20 | +if (mw.legacy.webkit_match) { |
| 21 | + mw.legacy.is_safari = mw.legacy.clientPC.indexOf('applewebkit') != -1 && |
| 22 | + mw.legacy.clientPC.indexOf('spoofer') == -1; |
| 23 | + mw.legacy.is_safari_win = mw.legacy.is_safari && mw.legacy.clientPC.indexOf('windows') != -1; |
| 24 | + mw.legacy.webkit_version = parseInt(mw.legacy.webkit_match[1]); |
| 25 | + // Tests for chrome here, to avoid breaking old scripts safari left alone |
| 26 | + // This is here for accesskeys |
| 27 | + mw.legacy.is_chrome = mw.legacy.clientPC.indexOf('chrome') !== -1 && |
| 28 | + mw.legacy.clientPC.indexOf('spoofer') === -1; |
| 29 | + mw.legacy.is_chrome_mac = mw.legacy.is_chrome && mw.legacy.clientPC.indexOf('mac') !== -1 |
| 30 | +} |
| 31 | +// For accesskeys; note that FF3+ is included here! |
| 32 | +mw.legacy.is_ff2 = /firefox\/[2-9]|minefield\/3/.test( mw.legacy.clientPC ); |
| 33 | +mw.legacy.ff2_bugs = /firefox\/2/.test( mw.legacy.clientPC ); |
| 34 | +// These aren't used here, but some custom scripts rely on them |
| 35 | +mw.legacy.is_ff2_win = mw.legacy.is_ff2 && mw.legacy.clientPC.indexOf('windows') != -1; |
| 36 | +mw.legacy.is_ff2_x11 = mw.legacy.is_ff2 && mw.legacy.clientPC.indexOf('x11') != -1; |
| 37 | +if (mw.legacy.clientPC.indexOf('opera') != -1) { |
| 38 | + mw.legacy.is_opera = true; |
| 39 | + mw.legacy.is_opera_preseven = window.opera && !document.childNodes; |
| 40 | + mw.legacy.is_opera_seven = window.opera && document.childNodes; |
| 41 | + mw.legacy.is_opera_95 = /opera\/(9\.[5-9]|[1-9][0-9])/.test( mw.legacy.clientPC ); |
| 42 | + mw.legacy.opera6_bugs = mw.legacy.is_opera_preseven; |
| 43 | + mw.legacy.opera7_bugs = mw.legacy.is_opera_seven && !mw.legacy.is_opera_95; |
| 44 | + mw.legacy.opera95_bugs = /opera\/(9\.5)/.test( mw.legacy.clientPC ); |
| 45 | +} |
| 46 | +// As recommended by <http://msdn.microsoft.com/en-us/library/ms537509.aspx>, |
| 47 | +// avoiding false positives from moronic extensions that append to the IE UA |
| 48 | +// string (bug 23171) |
| 49 | +mw.legacy.ie6_bugs = false; |
| 50 | +if ( /MSIE ([0-9]{1,}[\.0-9]{0,})/.exec( mw.legacy.clientPC ) != null && parseFloat( RegExp.$1 ) <= 6.0 ) { |
| 51 | + mw.legacy.ie6_bugs = true; |
| 52 | +} |
| 53 | + |
| 54 | +$.extend( true, mw.legacy, { |
| 55 | + |
| 56 | + /* |
| 57 | + * Events |
| 58 | + * |
| 59 | + * Add any onload functions in this hook (please don't hard-code any events in the xhtml source) |
| 60 | + */ |
| 61 | + |
| 62 | + /* Global Variables */ |
| 63 | + |
| 64 | + 'doneOnloadHook': null, |
| 65 | + 'onloadFuncts': [], |
| 66 | + |
| 67 | + /* Functions */ |
| 68 | + |
| 69 | + 'addOnloadHook': function( hookFunct ) { |
| 70 | + // Allows add-on scripts to add onload functions |
| 71 | + if( !mw.legacy.doneOnloadHook ) { |
| 72 | + mw.legacy.onloadFuncts[mw.legacy.onloadFuncts.length] = hookFunct; |
| 73 | + } else { |
| 74 | + hookFunct(); // bug in MSIE script loading |
| 75 | + } |
| 76 | + }, |
| 77 | + 'hookEvent': function( hookName, hookFunct ) { |
| 78 | + addHandler( window, hookName, hookFunct ); |
| 79 | + }, |
| 80 | + 'killEvt': function( evt ) { |
| 81 | + evt = evt || window.event || window.Event; // W3C, IE, Netscape |
| 82 | + if ( typeof ( evt.preventDefault ) != 'undefined' ) { |
| 83 | + evt.preventDefault(); // Don't follow the link |
| 84 | + evt.stopPropagation(); |
| 85 | + } else { |
| 86 | + evt.cancelBubble = true; // IE |
| 87 | + } |
| 88 | + return false; // Don't follow the link (IE) |
| 89 | + }, |
| 90 | + |
| 91 | + /* |
| 92 | + * Dynamic loading |
| 93 | + */ |
| 94 | + |
| 95 | + /* Global Variables */ |
| 96 | + |
| 97 | + 'loadedScripts': {}, |
| 98 | + |
| 99 | + /* Functions */ |
| 100 | + |
| 101 | + 'importScript': function( page ) { |
| 102 | + // TODO: might want to introduce a utility function to match wfUrlencode() in PHP |
| 103 | + var uri = wgScript + '?title=' + |
| 104 | + encodeURIComponent(page.replace(/ /g,'_')).replace(/%2F/ig,'/').replace(/%3A/ig,':') + |
| 105 | + '&action=raw&ctype=text/javascript'; |
| 106 | + return importScriptURI( uri ); |
| 107 | + }, |
| 108 | + 'importScriptURI': function( url ) { |
| 109 | + if ( mw.legacy.loadedScripts[url] ) { |
| 110 | + return null; |
| 111 | + } |
| 112 | + mw.legacy.loadedScripts[url] = true; |
| 113 | + var s = document.createElement( 'script' ); |
| 114 | + s.setAttribute( 'src', url ); |
| 115 | + s.setAttribute( 'type', 'text/javascript' ); |
| 116 | + document.getElementsByTagName('head')[0].appendChild( s ); |
| 117 | + return s; |
| 118 | + }, |
| 119 | + 'importStylesheet': function( page ) { |
| 120 | + return importStylesheetURI( wgScript + '?action=raw&ctype=text/css&title=' + encodeURIComponent( page.replace(/ /g,'_') ) ); |
| 121 | + }, |
| 122 | + 'importStylesheetURI': function( url, media ) { |
| 123 | + var l = document.createElement( 'link' ); |
| 124 | + l.type = 'text/css'; |
| 125 | + l.rel = 'stylesheet'; |
| 126 | + l.href = url; |
| 127 | + if( media ) { |
| 128 | + l.media = media; |
| 129 | + } |
| 130 | + document.getElementsByTagName('head')[0].appendChild( l ); |
| 131 | + return l; |
| 132 | + }, |
| 133 | + 'appendCSS': function( text ) { |
| 134 | + var s = document.createElement( 'style' ); |
| 135 | + s.type = 'text/css'; |
| 136 | + s.rel = 'stylesheet'; |
| 137 | + if ( s.styleSheet ) { |
| 138 | + s.styleSheet.cssText = text; // IE |
| 139 | + } else { |
| 140 | + s.appendChild( document.createTextNode( text + '' ) ); // Safari sometimes borks on null |
| 141 | + } |
| 142 | + document.getElementsByTagName('head')[0].appendChild( s ); |
| 143 | + return s; |
| 144 | + }, |
| 145 | + 'runOnloadHook': function() { |
| 146 | + // don't run anything below this for non-dom browsers |
| 147 | + if ( mw.legacy.doneOnloadHook || !( document.getElementById && document.getElementsByTagName ) ) { |
| 148 | + return; |
| 149 | + } |
| 150 | + // set this before running any hooks, since any errors below |
| 151 | + // might cause the function to terminate prematurely |
| 152 | + mw.legacy.doneOnloadHook = true; |
| 153 | + updateTooltipAccessKeys( null ); |
| 154 | + setupCheckboxShiftClick(); |
| 155 | + sortables_init(); |
| 156 | + // Run any added-on functions |
| 157 | + for ( var i = 0; i < mw.legacy.onloadFuncts.length; i++ ) { |
| 158 | + mw.legacy.onloadFuncts[i](); |
| 159 | + } |
| 160 | + }, |
| 161 | + /** |
| 162 | + * Add an event handler to an element |
| 163 | + * |
| 164 | + * @param Element element Element to add handler to |
| 165 | + * @param String attach Event to attach to |
| 166 | + * @param callable handler Event handler callback |
| 167 | + */ |
| 168 | + 'addHandler': function( element, attach, handler ) { |
| 169 | + if( window.addEventListener ) { |
| 170 | + element.addEventListener( attach, handler, false ); |
| 171 | + } else if( window.attachEvent ) { |
| 172 | + element.attachEvent( 'on' + attach, handler ); |
| 173 | + } |
| 174 | + }, |
| 175 | + /** |
| 176 | + * Add a click event handler to an element |
| 177 | + * |
| 178 | + * @param Element element Element to add handler to |
| 179 | + * @param callable handler Event handler callback |
| 180 | + */ |
| 181 | + 'addClickHandler': function( element, handler ) { |
| 182 | + addHandler( element, 'click', handler ); |
| 183 | + }, |
| 184 | + /** |
| 185 | + * Removes an event handler from an element |
| 186 | + * |
| 187 | + * @param Element element Element to remove handler from |
| 188 | + * @param String remove Event to remove |
| 189 | + * @param callable handler Event handler callback to remove |
| 190 | + */ |
| 191 | + 'removeHandler': function( element, remove, handler ) { |
| 192 | + if( window.removeEventListener ) { |
| 193 | + element.removeEventListener( remove, handler, false ); |
| 194 | + } else if( window.detachEvent ) { |
| 195 | + element.detachEvent( 'on' + remove, handler ); |
| 196 | + } |
| 197 | + }, |
| 198 | + |
| 199 | + /* |
| 200 | + * Toolbar |
| 201 | + */ |
| 202 | + |
| 203 | + /* Global Variables */ |
| 204 | + |
| 205 | + 'mwEditButtons': [], |
| 206 | + 'mwCustomEditButtons': [], |
| 207 | + |
| 208 | + /** |
| 209 | + * Tooltips and access-keys |
| 210 | + */ |
| 211 | + |
| 212 | + /* Global Variables */ |
| 213 | + |
| 214 | + /** |
| 215 | + * Set the accesskey prefix based on browser detection. |
| 216 | + */ |
| 217 | + 'tooltipAccessKeyPrefix': ( function() { |
| 218 | + if ( mw.legacy.is_opera ) { |
| 219 | + return 'shift-esc-'; |
| 220 | + } else if ( mw.legacy.is_chrome ) { |
| 221 | + return mw.legacy.is_chrome_mac ? 'ctrl-option-' : 'alt-'; |
| 222 | + } else if ( !mw.legacy.is_safari_win && mw.legacy.is_safari && mw.legacy.webkit_version > 526 ) { |
| 223 | + return 'ctrl-alt-'; |
| 224 | + } else if ( |
| 225 | + !mw.legacy.is_safari_win && |
| 226 | + ( |
| 227 | + mw.legacy.is_safari || |
| 228 | + mw.legacy.clientPC.indexOf( 'mac' ) != -1 || |
| 229 | + mw.legacy.clientPC.indexOf( 'konqueror' ) != -1 |
| 230 | + ) |
| 231 | + ) { |
| 232 | + return = 'ctrl-'; |
| 233 | + } else if ( mw.legacy.is_ff2 ) { |
| 234 | + return = 'alt-shift-'; |
| 235 | + } |
| 236 | + return 'alt-'; |
| 237 | + } )(), |
| 238 | + 'tooltipAccessKeyRegexp': /\[(ctrl-)?(alt-)?(shift-)?(esc-)?(.)\]$/, |
| 239 | + // Dummy for deprecated function |
| 240 | + 'ta': [], |
| 241 | + |
| 242 | + /* Functions */ |
| 243 | + |
| 244 | + /** |
| 245 | + * Add the appropriate prefix to the accesskey shown in the tooltip. |
| 246 | + * If the nodeList parameter is given, only those nodes are updated; |
| 247 | + * otherwise, all the nodes that will probably have accesskeys by |
| 248 | + * default are updated. |
| 249 | + * |
| 250 | + * @param Array nodeList -- list of elements to update |
| 251 | + */ |
| 252 | + 'updateTooltipAccessKeys': function( nodeList ) { |
| 253 | + if ( !nodeList ) { |
| 254 | + // Rather than scan all links on the whole page, we can just scan these |
| 255 | + // containers which contain the relevant links. This is really just an |
| 256 | + // optimization technique. |
| 257 | + var linkContainers = [ |
| 258 | + 'column-one', // Monobook and Modern |
| 259 | + 'mw-head', 'mw-panel', 'p-logo' // Vector |
| 260 | + ]; |
| 261 | + for ( var i in linkContainers ) { |
| 262 | + var linkContainer = document.getElementById( linkContainers[i] ); |
| 263 | + if ( linkContainer ) { |
| 264 | + updateTooltipAccessKeys( linkContainer.getElementsByTagName( 'a' ) ); |
| 265 | + } |
| 266 | + } |
| 267 | + // these are rare enough that no such optimization is needed |
| 268 | + updateTooltipAccessKeys( document.getElementsByTagName( 'input' ) ); |
| 269 | + updateTooltipAccessKeys( document.getElementsByTagName( 'label' ) ); |
| 270 | + return; |
| 271 | + } |
| 272 | + for ( var i = 0; i < nodeList.length; i++ ) { |
| 273 | + var element = nodeList[i]; |
| 274 | + var tip = element.getAttribute( 'title' ); |
| 275 | + if ( tip && mw.legacy.tooltipAccessKeyRegexp.exec( tip ) ) { |
| 276 | + tip = tip.replace(mw.legacy.tooltipAccessKeyRegexp, |
| 277 | + '[' + mw.legacy.tooltipAccessKeyPrefix + "$5]"); |
| 278 | + element.setAttribute( 'title', tip ); |
| 279 | + } |
| 280 | + } |
| 281 | + }, |
| 282 | + // Dummy function for depricated feature |
| 283 | + 'akeytt': function( doId ) { }, |
| 284 | + |
| 285 | + /* |
| 286 | + * Checkboxes |
| 287 | + */ |
| 288 | + |
| 289 | + /* Global Varibles */ |
| 290 | + |
| 291 | + 'checkboxes': null, |
| 292 | + 'lastCheckbox': null, |
| 293 | + |
| 294 | + /* Functions */ |
| 295 | + |
| 296 | + 'setupCheckboxShiftClick': function() { |
| 297 | + mw.legacy.checkboxes = []; |
| 298 | + mw.legacy.lastCheckbox = null; |
| 299 | + var inputs = document.getElementsByTagName( 'input' ); |
| 300 | + addCheckboxClickHandlers( inputs ); |
| 301 | + }, |
| 302 | + 'addCheckboxClickHandlers': function( inputs, start ) { |
| 303 | + if ( !start ) { |
| 304 | + start = 0; |
| 305 | + } |
| 306 | + var finish = start + 250; |
| 307 | + if ( finish > inputs.length ) { |
| 308 | + finish = inputs.length; |
| 309 | + } |
| 310 | + for ( var i = start; i < finish; i++ ) { |
| 311 | + var cb = inputs[i]; |
| 312 | + if ( !cb.type || cb.type.toLowerCase() != 'checkbox' ) { |
| 313 | + continue; |
| 314 | + } |
| 315 | + var end = mw.legacy.checkboxes.length; |
| 316 | + mw.legacy.checkboxes[end] = cb; |
| 317 | + cb.index = end; |
| 318 | + addClickHandler( cb, checkboxClickHandler ); |
| 319 | + } |
| 320 | + if ( finish < inputs.length ) { |
| 321 | + setTimeout( function() { |
| 322 | + addCheckboxClickHandlers( inputs, finish ); |
| 323 | + }, 200 ); |
| 324 | + } |
| 325 | + }, |
| 326 | + 'checkboxClickHandler': function( e ) { |
| 327 | + if ( typeof e == 'undefined' ) { |
| 328 | + e = window.event; |
| 329 | + } |
| 330 | + if ( !e.shiftKey || mw.legacy.lastCheckbox === null ) { |
| 331 | + mw.legacy.lastCheckbox = this.index; |
| 332 | + return true; |
| 333 | + } |
| 334 | + var endState = this.checked; |
| 335 | + var start, finish; |
| 336 | + if ( this.index < mw.legacy.lastCheckbox ) { |
| 337 | + start = this.index + 1; |
| 338 | + finish = mw.legacy.lastCheckbox; |
| 339 | + } else { |
| 340 | + start = mw.legacy.lastCheckbox; |
| 341 | + finish = this.index - 1; |
| 342 | + } |
| 343 | + for ( var i = start; i <= finish; ++i ) { |
| 344 | + mw.legacy.checkboxes[i].checked = endState; |
| 345 | + if( i > start && typeof mw.legacy.checkboxes[i].onchange == 'function' ) { |
| 346 | + mw.legacy.checkboxes[i].onchange(); // fire triggers |
| 347 | + } |
| 348 | + } |
| 349 | + mw.legacy.lastCheckbox = this.index; |
| 350 | + return true; |
| 351 | + }, |
| 352 | + |
| 353 | + /* |
| 354 | + * Table of contents |
| 355 | + */ |
| 356 | + |
| 357 | + /* Functions */ |
| 358 | + |
| 359 | + 'showTocToggle': function() { |
| 360 | + if ( document.createTextNode ) { |
| 361 | + // Uses DOM calls to avoid document.write + XHTML issues |
| 362 | + var linkHolder = document.getElementById( 'toctitle' ); |
| 363 | + var existingLink = document.getElementById( 'togglelink' ); |
| 364 | + if ( !linkHolder || existingLink ) { |
| 365 | + // Don't add the toggle link twice |
| 366 | + return; |
| 367 | + } |
| 368 | + var outerSpan = document.createElement( 'span' ); |
| 369 | + outerSpan.className = 'toctoggle'; |
| 370 | + var toggleLink = document.createElement( 'a' ); |
| 371 | + toggleLink.id = 'togglelink'; |
| 372 | + toggleLink.className = 'internal'; |
| 373 | + toggleLink.href = '#'; |
| 374 | + addClickHandler( toggleLink, function( evt ) { toggleToc(); return killEvt( evt ); } ); |
| 375 | + toggleLink.appendChild( document.createTextNode( tocHideText ) ); |
| 376 | + outerSpan.appendChild( document.createTextNode( '[' ) ); |
| 377 | + outerSpan.appendChild( toggleLink ); |
| 378 | + outerSpan.appendChild( document.createTextNode( ']' ) ); |
| 379 | + linkHolder.appendChild( document.createTextNode( ' ' ) ); |
| 380 | + linkHolder.appendChild( outerSpan ); |
| 381 | + var cookiePos = document.cookie.indexOf( "hidetoc=" ); |
| 382 | + if ( cookiePos > -1 && document.cookie.charAt( cookiePos + 8 ) == 1 ) { |
| 383 | + toggleToc(); |
| 384 | + } |
| 385 | + } |
| 386 | + }, |
| 387 | + 'toggleToc': function() { |
| 388 | + var tocmain = document.getElementById( 'toc' ); |
| 389 | + var toc = document.getElementById('toc').getElementsByTagName('ul')[0]; |
| 390 | + var toggleLink = document.getElementById( 'togglelink' ); |
| 391 | + |
| 392 | + if ( toc && toggleLink && toc.style.display == 'none' ) { |
| 393 | + changeText( toggleLink, tocHideText ); |
| 394 | + toc.style.display = 'block'; |
| 395 | + document.cookie = "hidetoc=0"; |
| 396 | + tocmain.className = 'toc'; |
| 397 | + } else { |
| 398 | + changeText( toggleLink, tocShowText ); |
| 399 | + toc.style.display = 'none'; |
| 400 | + document.cookie = "hidetoc=1"; |
| 401 | + tocmain.className = 'toc tochidden'; |
| 402 | + } |
| 403 | + return false; |
| 404 | + }, |
| 405 | + |
| 406 | + /* |
| 407 | + * Table sorting |
| 408 | + * |
| 409 | + * Script based on one (c) 1997-2006 Stuart Langridge and Joost de Valk: |
| 410 | + * http://www.joostdevalk.nl/code/sortable-table/ |
| 411 | + * http://www.kryogenix.org/code/browser/sorttable/ |
| 412 | + * |
| 413 | + * @todo don't break on colspans/rowspans (bug 8028) |
| 414 | + * @todo language-specific digit grouping/decimals (bug 8063) |
| 415 | + * @todo support all accepted date formats (bug 8226) |
| 416 | + */ |
| 417 | + |
| 418 | + /* Global Variables */ |
| 419 | + |
| 420 | + 'ts_image_path': mw.legacy.stylepath + '/common/images/', |
| 421 | + 'ts_image_up': 'sort_up.gif', |
| 422 | + 'ts_image_down': 'sort_down.gif', |
| 423 | + 'ts_image_none': 'sort_none.gif', |
| 424 | + // The non-American-inclined can change to "true" |
| 425 | + 'ts_europeandate': mw.legacy.wgContentLanguage != 'en', |
| 426 | + 'ts_alternate_row_colors': false, |
| 427 | + 'ts_number_transform_table': null, |
| 428 | + 'ts_number_regex': null, |
| 429 | + |
| 430 | + /* Functions */ |
| 431 | + |
| 432 | + 'sortables_init': function() { |
| 433 | + var idnum = 0; |
| 434 | + // Find all tables with class sortable and make them sortable |
| 435 | + var tables = getElementsByClassName( document, 'table', 'sortable' ); |
| 436 | + for ( var ti = 0; ti < tables.length ; ti++ ) { |
| 437 | + if ( !tables[ti].id ) { |
| 438 | + tables[ti].setAttribute( 'id', 'sortable_table_id_' + idnum ); |
| 439 | + ++idnum; |
| 440 | + } |
| 441 | + mw.legacy.ts_makeSortable( tables[ti] ); |
| 442 | + } |
| 443 | + }, |
| 444 | + 'ts_makeSortable': function( table ) { |
| 445 | + var firstRow; |
| 446 | + if ( table.rows && table.rows.length > 0 ) { |
| 447 | + if ( table.tHead && table.tHead.rows.length > 0 ) { |
| 448 | + firstRow = table.tHead.rows[table.tHead.rows.length-1]; |
| 449 | + } else { |
| 450 | + firstRow = table.rows[0]; |
| 451 | + } |
| 452 | + } |
| 453 | + if ( !firstRow ) { |
| 454 | + return; |
| 455 | + } |
| 456 | + // We have a first row: assume it's the header, and make its contents clickable links |
| 457 | + for ( var i = 0; i < firstRow.cells.length; i++ ) { |
| 458 | + var cell = firstRow.cells[i]; |
| 459 | + if ( (' ' + cell.className + ' ').indexOf(' unsortable ') == -1 ) { |
| 460 | + cell.innerHTML += '<a href="#" class="sortheader" ' |
| 461 | + + 'onclick="mw.legacy.ts_resortTable(this);return false;">' |
| 462 | + + '<span class="sortarrow">' |
| 463 | + + '<img src="' |
| 464 | + + mw.legacy.ts_image_path |
| 465 | + + mw.legacy.ts_image_none |
| 466 | + + '" alt="↓"/></span></a>'; |
| 467 | + } |
| 468 | + } |
| 469 | + if ( mw.legacy.ts_alternate_row_colors ) { |
| 470 | + mw.legacy.ts_alternate( table ); |
| 471 | + } |
| 472 | + }, |
| 473 | + 'ts_getInnerText': function( el ) { |
| 474 | + return getInnerText( el ); |
| 475 | + }, |
| 476 | + 'ts_resortTable': function( lnk ) { |
| 477 | + // get the span |
| 478 | + var span = lnk.getElementsByTagName('span')[0]; |
| 479 | + var td = lnk.parentNode; |
| 480 | + var tr = td.parentNode; |
| 481 | + var column = td.cellIndex; |
| 482 | + var table = tr.parentNode; |
| 483 | + while ( table && !( table.tagName && table.tagName.toLowerCase() == 'table' ) ) { |
| 484 | + table = table.parentNode; |
| 485 | + } |
| 486 | + if ( !table ) { |
| 487 | + return; |
| 488 | + } |
| 489 | + if ( table.rows.length <= 1 ) { |
| 490 | + return; |
| 491 | + } |
| 492 | + // Generate the number transform table if it's not done already |
| 493 | + if ( mw.legacy.ts_number_transform_table === null ) { |
| 494 | + mw.legacy.ts_initTransformTable(); |
| 495 | + } |
| 496 | + // Work out a type for the column |
| 497 | + // Skip the first row if that's where the headings are |
| 498 | + var rowStart = ( table.tHead && table.tHead.rows.length > 0 ? 0 : 1 ); |
| 499 | + var bodyRows = 0; |
| 500 | + if (rowStart == 0 && table.tBodies) { |
| 501 | + for (var i=0; i < table.tBodies.length; i++ ) { |
| 502 | + bodyRows += table.tBodies[i].rows.length; |
| 503 | + } |
| 504 | + if (bodyRows < table.rows.length) |
| 505 | + rowStart = 1; |
| 506 | + } |
| 507 | + var itm = ''; |
| 508 | + for ( var i = rowStart; i < table.rows.length; i++ ) { |
| 509 | + if ( table.rows[i].cells.length > column ) { |
| 510 | + itm = mw.legacy.ts_getInnerText(table.rows[i].cells[column]); |
| 511 | + itm = itm.replace(/^[\s\xa0]+/, '').replace(/[\s\xa0]+$/, ''); |
| 512 | + if ( itm != '' ) { |
| 513 | + break; |
| 514 | + } |
| 515 | + } |
| 516 | + } |
| 517 | + // TODO: bug 8226, localised date formats |
| 518 | + var sortfn = mw.legacy.ts_sort_generic; |
| 519 | + var preprocessor = mw.legacy.ts_toLowerCase; |
| 520 | + if ( /^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/.test( itm ) ) { |
| 521 | + preprocessor = mw.legacy.ts_dateToSortKey; |
| 522 | + } else if ( /^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/.test( itm ) ) { |
| 523 | + preprocessor = mw.legacy.ts_dateToSortKey; |
| 524 | + } else if ( /^\d\d[\/.-]\d\d[\/.-]\d\d$/.test( itm ) ) { |
| 525 | + preprocessor = mw.legacy.ts_dateToSortKey; |
| 526 | + // (minus sign)([pound dollar euro yen currency]|cents) |
| 527 | + } else if ( /(^([-\u2212] *)?[\u00a3$\u20ac\u00a4\u00a5]|\u00a2$)/.test( itm ) ) { |
| 528 | + preprocessor = mw.legacy.ts_currencyToSortKey; |
| 529 | + } else if ( mw.legacy.ts_number_regex.test( itm ) ) { |
| 530 | + preprocessor = mw.legacy.ts_parseFloat; |
| 531 | + } |
| 532 | + var reverse = ( span.getAttribute( 'sortdir' ) == 'down' ); |
| 533 | + var newRows = new Array(); |
| 534 | + var staticRows = new Array(); |
| 535 | + for ( var j = rowStart; j < table.rows.length; j++ ) { |
| 536 | + var row = table.rows[j]; |
| 537 | + if( (' ' + row.className + ' ').indexOf(' unsortable ') < 0 ) { |
| 538 | + var keyText = mw.legacy.ts_getInnerText( row.cells[column] ); |
| 539 | + if( keyText === undefined ) { |
| 540 | + keyText = ''; |
| 541 | + } |
| 542 | + var oldIndex = ( reverse ? -j : j ); |
| 543 | + var preprocessed = preprocessor( keyText.replace(/^[\s\xa0]+/, '').replace(/[\s\xa0]+$/, '') ); |
| 544 | + newRows[newRows.length] = new Array( row, preprocessed, oldIndex ); |
| 545 | + } else { |
| 546 | + staticRows[staticRows.length] = new Array( row, false, j-rowStart ); |
| 547 | + } |
| 548 | + } |
| 549 | + newRows.sort( sortfn ); |
| 550 | + var arrowHTML; |
| 551 | + if ( reverse ) { |
| 552 | + arrowHTML = '<img src="' + mw.legacy.ts_image_path + mw.legacy.ts_image_down + '" alt="↓"/>'; |
| 553 | + newRows.reverse(); |
| 554 | + span.setAttribute( 'sortdir', 'up' ); |
| 555 | + } else { |
| 556 | + arrowHTML = '<img src="' + mw.legacy.ts_image_path + mw.legacy.ts_image_up + '" alt="↑"/>'; |
| 557 | + span.setAttribute( 'sortdir', 'down' ); |
| 558 | + } |
| 559 | + for ( var i = 0; i < staticRows.length; i++ ) { |
| 560 | + var row = staticRows[i]; |
| 561 | + newRows.splice( row[2], 0, row ); |
| 562 | + } |
| 563 | + // We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones |
| 564 | + // don't do sortbottom rows |
| 565 | + for ( var i = 0; i < newRows.length; i++ ) { |
| 566 | + if ( ( ' ' + newRows[i][0].className + ' ').indexOf(' sortbottom ') == -1 ) { |
| 567 | + table.tBodies[0].appendChild( newRows[i][0] ); |
| 568 | + } |
| 569 | + } |
| 570 | + // do sortbottom rows only |
| 571 | + for ( var i = 0; i < newRows.length; i++ ) { |
| 572 | + if ( ( ' ' + newRows[i][0].className + ' ').indexOf(' sortbottom ') != -1 ) { |
| 573 | + table.tBodies[0].appendChild( newRows[i][0] ); |
| 574 | + } |
| 575 | + } |
| 576 | + // Delete any other arrows there may be showing |
| 577 | + var spans = getElementsByClassName( tr, 'span', 'sortarrow' ); |
| 578 | + for ( var i = 0; i < spans.length; i++ ) { |
| 579 | + spans[i].innerHTML = '<img src="' + mw.legacy.ts_image_path + mw.legacy.ts_image_none + '" alt="↓"/>'; |
| 580 | + } |
| 581 | + span.innerHTML = arrowHTML; |
| 582 | + |
| 583 | + if ( mw.legacy.ts_alternate_row_colors ) { |
| 584 | + mw.legacy.ts_alternate( table ); |
| 585 | + } |
| 586 | + }, |
| 587 | + 'ts_initTransformTable': function() { |
| 588 | + if ( typeof wgSeparatorTransformTable == 'undefined' |
| 589 | + || ( wgSeparatorTransformTable[0] == '' && wgDigitTransformTable[2] == '' ) ) |
| 590 | + { |
| 591 | + var digitClass = "[0-9,.]"; |
| 592 | + mw.legacy.ts_number_transform_table = false; |
| 593 | + } else { |
| 594 | + mw.legacy.ts_number_transform_table = {}; |
| 595 | + // Unpack the transform table |
| 596 | + // Separators |
| 597 | + var ascii = wgSeparatorTransformTable[0].split("\t"); |
| 598 | + var localised = wgSeparatorTransformTable[1].split("\t"); |
| 599 | + for ( var i = 0; i < ascii.length; i++ ) { |
| 600 | + mw.legacy.ts_number_transform_table[localised[i]] = ascii[i]; |
| 601 | + } |
| 602 | + // Digits |
| 603 | + ascii = wgDigitTransformTable[0].split("\t"); |
| 604 | + localised = wgDigitTransformTable[1].split("\t"); |
| 605 | + for ( var i = 0; i < ascii.length; i++ ) { |
| 606 | + mw.legacy.ts_number_transform_table[localised[i]] = ascii[i]; |
| 607 | + } |
| 608 | + // Construct regex for number identification |
| 609 | + var digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ',', '\\.']; |
| 610 | + var maxDigitLength = 1; |
| 611 | + for ( var digit in mw.legacy.ts_number_transform_table ) { |
| 612 | + // Escape regex metacharacters |
| 613 | + digits.push( |
| 614 | + digit.replace( /[\\\\$\*\+\?\.\(\)\|\{\}\[\]\-]/, |
| 615 | + function( s ) { return '\\' + s; } ) |
| 616 | + ); |
| 617 | + if ( digit.length > maxDigitLength ) { |
| 618 | + maxDigitLength = digit.length; |
| 619 | + } |
| 620 | + } |
| 621 | + if ( maxDigitLength > 1 ) { |
| 622 | + var digitClass = '[' + digits.join( '', digits ) + ']'; |
| 623 | + } else { |
| 624 | + var digitClass = '(' + digits.join( '|', digits ) + ')'; |
| 625 | + } |
| 626 | + } |
| 627 | + // We allow a trailing percent sign, which we just strip. This works fine |
| 628 | + // if percents and regular numbers aren't being mixed. |
| 629 | + mw.legacy.ts_number_regex = new RegExp( |
| 630 | + "^(" + |
| 631 | + "[-+\u2212]?[0-9][0-9,]*(\\.[0-9,]*)?(E[-+\u2212]?[0-9][0-9,]*)?" + // Fortran-style scientific |
| 632 | + "|" + |
| 633 | + "[-+\u2212]?" + digitClass + "+%?" + // Generic localised |
| 634 | + ")$", "i" |
| 635 | + ); |
| 636 | + }, |
| 637 | + 'ts_toLowerCase': function( s ) { |
| 638 | + return s.toLowerCase(); |
| 639 | + }, |
| 640 | + 'ts_dateToSortKey': function( date ) { |
| 641 | + // y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX |
| 642 | + if ( date.length == 11 ) { |
| 643 | + switch ( date.substr( 3, 3 ).toLowerCase() ) { |
| 644 | + case 'jan': |
| 645 | + var month = '01'; |
| 646 | + break; |
| 647 | + case 'feb': |
| 648 | + var month = '02'; |
| 649 | + break; |
| 650 | + case 'mar': |
| 651 | + var month = '03'; |
| 652 | + break; |
| 653 | + case 'apr': |
| 654 | + var month = '04'; |
| 655 | + break; |
| 656 | + case 'may': |
| 657 | + var month = '05'; |
| 658 | + break; |
| 659 | + case 'jun': |
| 660 | + var month = '06'; |
| 661 | + break; |
| 662 | + case 'jul': |
| 663 | + var month = '07'; |
| 664 | + break; |
| 665 | + case 'aug': |
| 666 | + var month = '08'; |
| 667 | + break; |
| 668 | + case 'sep': |
| 669 | + var month = '09'; |
| 670 | + break; |
| 671 | + case 'oct': |
| 672 | + var month = '10'; |
| 673 | + break; |
| 674 | + case 'nov': |
| 675 | + var month = '11'; |
| 676 | + break; |
| 677 | + case 'dec': |
| 678 | + var month = '12'; |
| 679 | + break; |
| 680 | + // default: var month = '00'; |
| 681 | + } |
| 682 | + return date.substr( 7, 4 ) + month + date.substr( 0, 2 ); |
| 683 | + } else if ( date.length == 10 ) { |
| 684 | + if ( mw.legacy.ts_europeandate == false ) { |
| 685 | + return date.substr( 6, 4 ) + date.substr( 0, 2 ) + date.substr( 3, 2 ); |
| 686 | + } else { |
| 687 | + return date.substr( 6, 4 ) + date.substr( 3, 2 ) + date.substr( 0, 2 ); |
| 688 | + } |
| 689 | + } else if ( date.length == 8 ) { |
| 690 | + var yr = date.substr( 6, 2 ); |
| 691 | + if ( parseInt( yr ) < 50 ) { |
| 692 | + yr = '20' + yr; |
| 693 | + } else { |
| 694 | + yr = '19' + yr; |
| 695 | + } |
| 696 | + if ( mw.legacy.ts_europeandate == true ) { |
| 697 | + return yr + date.substr( 3, 2 ) + date.substr( 0, 2 ); |
| 698 | + } else { |
| 699 | + return yr + date.substr( 0, 2 ) + date.substr( 3, 2 ); |
| 700 | + } |
| 701 | + } |
| 702 | + return '00000000'; |
| 703 | + }, |
| 704 | + 'ts_parseFloat': function( s ) { |
| 705 | + if ( !s ) { |
| 706 | + return 0; |
| 707 | + } |
| 708 | + if ( mw.legacy.ts_number_transform_table != false ) { |
| 709 | + var newNum = '', c; |
| 710 | + |
| 711 | + for ( var p = 0; p < s.length; p++ ) { |
| 712 | + c = s.charAt( p ); |
| 713 | + if ( c in mw.legacy.ts_number_transform_table ) { |
| 714 | + newNum += mw.legacy.ts_number_transform_table[c]; |
| 715 | + } else { |
| 716 | + newNum += c; |
| 717 | + } |
| 718 | + } |
| 719 | + s = newNum; |
| 720 | + } |
| 721 | + var num = parseFloat( s.replace(/[, ]/g, '').replace("\u2212", '-') ); |
| 722 | + return ( isNaN( num ) ? -Infinity : num ); |
| 723 | + }, |
| 724 | + 'ts_currencyToSortKey': function( s ) { |
| 725 | + return mw.legacy.ts_parseFloat(s.replace(/[^-\u22120-9.,]/g,'')); |
| 726 | + }, |
| 727 | + 'ts_sort_generic': function( a, b ) { |
| 728 | + return a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : a[2] - b[2]; |
| 729 | + }, |
| 730 | + 'ts_alternate': function( table ) { |
| 731 | + // Take object table and get all it's tbodies. |
| 732 | + var tableBodies = table.getElementsByTagName( 'tbody' ); |
| 733 | + // Loop through these tbodies |
| 734 | + for ( var i = 0; i < tableBodies.length; i++ ) { |
| 735 | + // Take the tbody, and get all it's rows |
| 736 | + var tableRows = tableBodies[i].getElementsByTagName( 'tr' ); |
| 737 | + // Loop through these rows |
| 738 | + // Start at 1 because we want to leave the heading row untouched |
| 739 | + for ( var j = 0; j < tableRows.length; j++ ) { |
| 740 | + // Check if j is even, and apply classes for both possible results |
| 741 | + var oldClasses = tableRows[j].className.split(' '); |
| 742 | + var newClassName = ''; |
| 743 | + for ( var k = 0; k < oldClasses.length; k++ ) { |
| 744 | + if ( oldClasses[k] != '' && oldClasses[k] != 'even' && oldClasses[k] != 'odd' ) { |
| 745 | + newClassName += oldClasses[k] + ' '; |
| 746 | + } |
| 747 | + } |
| 748 | + tableRows[j].className = newClassName + ( j % 2 == 0 ? 'even' : 'odd' ); |
| 749 | + } |
| 750 | + } |
| 751 | + }, |
| 752 | + |
| 753 | + /* |
| 754 | + * Skins |
| 755 | + */ |
| 756 | + |
| 757 | + /* Functions */ |
| 758 | + |
| 759 | + 'changeText': function( el, newText ) { |
| 760 | + // Safari work around |
| 761 | + if ( el.innerText ) { |
| 762 | + el.innerText = newText; |
| 763 | + } else if ( el.firstChild && el.firstChild.nodeValue ) { |
| 764 | + el.firstChild.nodeValue = newText; |
| 765 | + } |
| 766 | + }, |
| 767 | + 'escapeQuotes': function( text ) { |
| 768 | + var re = new RegExp( "'", "g" ); |
| 769 | + text = text.replace( re, "\\'" ); |
| 770 | + re = new RegExp( "\\n", "g" ); |
| 771 | + text = text.replace( re, "\\n" ); |
| 772 | + return escapeQuotesHTML( text ); |
| 773 | + }, |
| 774 | + 'escapeQuotesHTML': function( text ) { |
| 775 | + var re = new RegExp( '&', "g" ); |
| 776 | + text = text.replace( re, "&" ); |
| 777 | + re = new RegExp( '"', "g" ); |
| 778 | + text = text.replace( re, """ ); |
| 779 | + re = new RegExp( '<', "g" ); |
| 780 | + text = text.replace( re, "<" ); |
| 781 | + re = new RegExp( '>', "g" ); |
| 782 | + text = text.replace( re, ">" ); |
| 783 | + return text; |
| 784 | + }, |
| 785 | + /** |
| 786 | + * Add a link to one of the portlet menus on the page, including: |
| 787 | + * |
| 788 | + * p-cactions: Content actions (shown as tabs above the main content in Monobook) |
| 789 | + * p-personal: Personal tools (shown at the top right of the page in Monobook) |
| 790 | + * p-navigation: Navigation |
| 791 | + * p-tb: Toolbox |
| 792 | + * |
| 793 | + * This function exists for the convenience of custom JS authors. All |
| 794 | + * but the first three parameters are optional, though providing at |
| 795 | + * least an id and a tooltip is recommended. |
| 796 | + * |
| 797 | + * By default the new link will be added to the end of the list. To |
| 798 | + * add the link before a given existing item, pass the DOM node of |
| 799 | + * that item (easily obtained with document.getElementById()) as the |
| 800 | + * nextnode parameter; to add the link _after_ an existing item, pass |
| 801 | + * the node's nextSibling instead. |
| 802 | + * |
| 803 | + * @param String portlet -- id of the target portlet ("p-cactions", "p-personal", "p-navigation" or "p-tb") |
| 804 | + * @param String href -- link URL |
| 805 | + * @param String text -- link text (will be automatically lowercased by CSS for p-cactions in Monobook) |
| 806 | + * @param String id -- id of the new item, should be unique and preferably have the appropriate prefix ("ca-", "pt-", "n-" or "t-") |
| 807 | + * @param String tooltip -- text to show when hovering over the link, without accesskey suffix |
| 808 | + * @param String accesskey -- accesskey to activate this link (one character, try to avoid conflicts) |
| 809 | + * @param Node nextnode -- the DOM node before which the new item should be added, should be another item in the same list |
| 810 | + * |
| 811 | + * @return Node -- the DOM node of the new item (an LI element) or null |
| 812 | + */ |
| 813 | + 'addPortletLink': function( portlet, href, text, id, tooltip, accesskey, nextnode ) { |
| 814 | + var root = document.getElementById( portlet ); |
| 815 | + if ( !root ) { |
| 816 | + return null; |
| 817 | + } |
| 818 | + var uls = root.getElementsByTagName( 'ul' ); |
| 819 | + var node; |
| 820 | + if ( uls.length > 0 ) { |
| 821 | + node = uls[0]; |
| 822 | + } else { |
| 823 | + node = document.createElement( 'ul' ); |
| 824 | + var lastElementChild = null; |
| 825 | + for ( var i = 0; i < root.childNodes.length; ++i ) { /* get root.lastElementChild */ |
| 826 | + if ( root.childNodes[i].nodeType == 1 ) { |
| 827 | + lastElementChild = root.childNodes[i]; |
| 828 | + } |
| 829 | + } |
| 830 | + if ( lastElementChild && lastElementChild.nodeName.match( /div/i ) ) { |
| 831 | + /* Insert into the menu divs */ |
| 832 | + lastElementChild.appendChild( node ); |
| 833 | + } else { |
| 834 | + root.appendChild( node ); |
| 835 | + } |
| 836 | + } |
| 837 | + if ( !node ) { |
| 838 | + return null; |
| 839 | + } |
| 840 | + // unhide portlet if it was hidden before |
| 841 | + root.className = root.className.replace( /(^| )emptyPortlet( |$)/, "$2" ); |
| 842 | + var span = document.createElement( 'span' ); |
| 843 | + span.appendChild( document.createTextNode( text ) ); |
| 844 | + var link = document.createElement( 'a' ); |
| 845 | + link.appendChild( span ); |
| 846 | + link.href = href; |
| 847 | + var item = document.createElement( 'li' ); |
| 848 | + item.appendChild( link ); |
| 849 | + if ( id ) { |
| 850 | + item.id = id; |
| 851 | + } |
| 852 | + if ( accesskey ) { |
| 853 | + link.setAttribute( 'accesskey', accesskey ); |
| 854 | + tooltip += ' [' + accesskey + ']'; |
| 855 | + } |
| 856 | + if ( tooltip ) { |
| 857 | + link.setAttribute( 'title', tooltip ); |
| 858 | + } |
| 859 | + if ( accesskey && tooltip ) { |
| 860 | + updateTooltipAccessKeys( new Array( link ) ); |
| 861 | + } |
| 862 | + if ( nextnode && nextnode.parentNode == node ) { |
| 863 | + node.insertBefore( item, nextnode ); |
| 864 | + } else { |
| 865 | + node.appendChild( item ); // IE compatibility (?) |
| 866 | + } |
| 867 | + return item; |
| 868 | + }, |
| 869 | + /** |
| 870 | + * Add a cute little box at the top of the screen to inform the user of |
| 871 | + * something, replacing any preexisting message. |
| 872 | + * |
| 873 | + * @param String -or- Dom Object message HTML to be put inside the right div |
| 874 | + * @param String className Used in adding a class; should be different for each |
| 875 | + * call to allow CSS/JS to hide different boxes. null = no class used. |
| 876 | + * @return Boolean True on success, false on failure |
| 877 | + */ |
| 878 | + 'jsMsg': function( message, className ) { |
| 879 | + if ( !document.getElementById ) { |
| 880 | + return false; |
| 881 | + } |
| 882 | + // We special-case skin structures provided by the software. Skins that |
| 883 | + // choose to abandon or significantly modify our formatting can just define |
| 884 | + // an mw-js-message div to start with. |
| 885 | + var messageDiv = document.getElementById( 'mw-js-message' ); |
| 886 | + if ( !messageDiv ) { |
| 887 | + messageDiv = document.createElement( 'div' ); |
| 888 | + if ( document.getElementById( 'column-content' ) |
| 889 | + && document.getElementById( 'content' ) ) { |
| 890 | + // MonoBook, presumably |
| 891 | + document.getElementById( 'content' ).insertBefore( |
| 892 | + messageDiv, |
| 893 | + document.getElementById( 'content' ).firstChild |
| 894 | + ); |
| 895 | + } else if ( document.getElementById( 'content' ) |
| 896 | + && document.getElementById( 'article' ) ) { |
| 897 | + // Non-Monobook but still recognizable (old-style) |
| 898 | + document.getElementById( 'article').insertBefore( |
| 899 | + messageDiv, |
| 900 | + document.getElementById( 'article' ).firstChild |
| 901 | + ); |
| 902 | + } else { |
| 903 | + return false; |
| 904 | + } |
| 905 | + } |
| 906 | + messageDiv.setAttribute( 'id', 'mw-js-message' ); |
| 907 | + messageDiv.style.display = 'block'; |
| 908 | + if( className ) { |
| 909 | + messageDiv.setAttribute( 'class', 'mw-js-message-' + className ); |
| 910 | + } |
| 911 | + if ( typeof message === 'object' ) { |
| 912 | + while ( messageDiv.hasChildNodes() ) { // Remove old content |
| 913 | + messageDiv.removeChild( messageDiv.firstChild ); |
| 914 | + } |
| 915 | + messageDiv.appendChild( message ); // Append new content |
| 916 | + } else { |
| 917 | + messageDiv.innerHTML = message; |
| 918 | + } |
| 919 | + return true; |
| 920 | + }, |
| 921 | + /** |
| 922 | + * Inject a cute little progress spinner after the specified element |
| 923 | + * |
| 924 | + * @param element Element to inject after |
| 925 | + * @param id Identifier string (for use with removeSpinner(), below) |
| 926 | + */ |
| 927 | + 'injectSpinner': function( element, id ) { |
| 928 | + var spinner = document.createElement( 'img' ); |
| 929 | + spinner.id = 'mw-spinner-' + id; |
| 930 | + spinner.src = mw.legacy.stylepath + '/common/images/spinner.gif'; |
| 931 | + spinner.alt = spinner.title = '...'; |
| 932 | + if( element.nextSibling ) { |
| 933 | + element.parentNode.insertBefore( spinner, element.nextSibling ); |
| 934 | + } else { |
| 935 | + element.parentNode.appendChild( spinner ); |
| 936 | + } |
| 937 | + }, |
| 938 | + /** |
| 939 | + * Remove a progress spinner added with injectSpinner() |
| 940 | + * |
| 941 | + * @param id Identifier string |
| 942 | + */ |
| 943 | + 'removeSpinner': function( id ) { |
| 944 | + var spinner = document.getElementById( 'mw-spinner-' + id ); |
| 945 | + if( spinner ) { |
| 946 | + spinner.parentNode.removeChild( spinner ); |
| 947 | + } |
| 948 | + }, |
| 949 | + |
| 950 | + /* |
| 951 | + * DOM manipulation and traversal |
| 952 | + */ |
| 953 | + |
| 954 | + /* Functions */ |
| 955 | + |
| 956 | + 'getInnerText': function( el ) { |
| 957 | + if ( typeof el == 'string' ) { |
| 958 | + return el; |
| 959 | + } |
| 960 | + if ( typeof el == 'undefined' ) { |
| 961 | + return el; |
| 962 | + } |
| 963 | + if ( el.textContent ) { |
| 964 | + return el.textContent; // not needed but it is faster |
| 965 | + } |
| 966 | + if ( el.innerText ) { |
| 967 | + return el.innerText; // IE doesn't have textContent |
| 968 | + } |
| 969 | + var str = ''; |
| 970 | + var cs = el.childNodes; |
| 971 | + var l = cs.length; |
| 972 | + for ( var i = 0; i < l; i++ ) { |
| 973 | + switch ( cs[i].nodeType ) { |
| 974 | + case 1: // ELEMENT_NODE |
| 975 | + str += mw.legacy.ts_getInnerText( cs[i] ); |
| 976 | + break; |
| 977 | + case 3: // TEXT_NODE |
| 978 | + str += cs[i].nodeValue; |
| 979 | + break; |
| 980 | + } |
| 981 | + } |
| 982 | + return str; |
| 983 | + }, |
| 984 | + /** |
| 985 | + * Written by Jonathan Snook, http://www.snook.ca/jonathan |
| 986 | + * Add-ons by Robert Nyman, http://www.robertnyman.com |
| 987 | + * Author says "The credit comment is all it takes, no license. Go crazy with it!:-)" |
| 988 | + * From http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/ |
| 989 | + */ |
| 990 | + 'getElementsByClassName': function( oElm, strTagName, oClassNames ) { |
| 991 | + var arrReturnElements = new Array(); |
| 992 | + if ( typeof( oElm.getElementsByClassName ) == 'function' ) { |
| 993 | + /* Use a native implementation where possible FF3, Saf3.2, Opera 9.5 */ |
| 994 | + var arrNativeReturn = oElm.getElementsByClassName( oClassNames ); |
| 995 | + if ( strTagName == '*' ) { |
| 996 | + return arrNativeReturn; |
| 997 | + } |
| 998 | + for ( var h = 0; h < arrNativeReturn.length; h++ ) { |
| 999 | + if( arrNativeReturn[h].tagName.toLowerCase() == strTagName.toLowerCase() ) { |
| 1000 | + arrReturnElements[arrReturnElements.length] = arrNativeReturn[h]; |
| 1001 | + } |
| 1002 | + } |
| 1003 | + return arrReturnElements; |
| 1004 | + } |
| 1005 | + var arrElements = ( strTagName == '*' && oElm.all ) ? oElm.all : oElm.getElementsByTagName( strTagName ); |
| 1006 | + var arrRegExpClassNames = new Array(); |
| 1007 | + if( typeof oClassNames == 'object' ) { |
| 1008 | + for( var i = 0; i < oClassNames.length; i++ ) { |
| 1009 | + arrRegExpClassNames[arrRegExpClassNames.length] = |
| 1010 | + new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)"); |
| 1011 | + } |
| 1012 | + } else { |
| 1013 | + arrRegExpClassNames[arrRegExpClassNames.length] = |
| 1014 | + new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)"); |
| 1015 | + } |
| 1016 | + var oElement; |
| 1017 | + var bMatchesAll; |
| 1018 | + for( var j = 0; j < arrElements.length; j++ ) { |
| 1019 | + oElement = arrElements[j]; |
| 1020 | + bMatchesAll = true; |
| 1021 | + for( var k = 0; k < arrRegExpClassNames.length; k++ ) { |
| 1022 | + if( !arrRegExpClassNames[k].test( oElement.className ) ) { |
| 1023 | + bMatchesAll = false; |
| 1024 | + break; |
| 1025 | + } |
| 1026 | + } |
| 1027 | + if( bMatchesAll ) { |
| 1028 | + arrReturnElements[arrReturnElements.length] = oElement; |
| 1029 | + } |
| 1030 | + } |
| 1031 | + return ( arrReturnElements ); |
| 1032 | + }, |
| 1033 | + 'redirectToFragment': function( fragment ) { |
| 1034 | + var match = navigator.userAgent.match(/AppleWebKit\/(\d+)/); |
| 1035 | + if ( match ) { |
| 1036 | + var webKitVersion = parseInt( match[1] ); |
| 1037 | + if ( webKitVersion < 420 ) { |
| 1038 | + // Released Safari w/ WebKit 418.9.1 messes up horribly |
| 1039 | + // Nightlies of 420+ are ok |
| 1040 | + return; |
| 1041 | + } |
| 1042 | + } |
| 1043 | + if ( window.location.hash == '' ) { |
| 1044 | + window.location.hash = fragment; |
| 1045 | + // Mozilla needs to wait until after load, otherwise the window doesn't |
| 1046 | + // scroll. See <https://bugzilla.mozilla.org/show_bug.cgi?id=516293>. |
| 1047 | + // There's no obvious way to detect this programmatically, so we use |
| 1048 | + // version-testing. If Firefox fixes the bug, they'll jump twice, but |
| 1049 | + // better twice than not at all, so make the fix hit future versions as |
| 1050 | + // well. |
| 1051 | + if ( mw.legacy.is_gecko ) { |
| 1052 | + addOnloadHook(function() { |
| 1053 | + if ( window.location.hash == fragment ) { |
| 1054 | + window.location.hash = fragment; |
| 1055 | + } |
| 1056 | + }); |
| 1057 | + } |
| 1058 | + } |
| 1059 | + } |
14 | 1060 | } ); |
15 | 1061 | |
16 | 1062 | /* Initialization */ |
17 | 1063 | |
18 | 1064 | $( document ).ready( function() { |
19 | | - // |
| 1065 | + if ( wgBreakFrames ) { |
| 1066 | + // Un-trap us from framesets |
| 1067 | + if ( window.top != window ) { |
| 1068 | + window.top.location = window.location; |
| 1069 | + } |
| 1070 | + } |
| 1071 | + // Special stylesheet links for Monobook only (see bug 14717) |
| 1072 | + if ( typeof stylepath != 'undefined' && skin == 'monobook' ) { |
| 1073 | + if ( mw.legacy.opera6_bugs ) { |
| 1074 | + importStylesheetURI( stylepath + '/' + skin + '/Opera6Fixes.css' ); |
| 1075 | + } else if ( mw.legacy.opera7_bugs ) { |
| 1076 | + importStylesheetURI( stylepath + '/' + skin + '/Opera7Fixes.css' ); |
| 1077 | + } else if ( mw.legacy.opera95_bugs ) { |
| 1078 | + importStylesheetURI( stylepath + '/' + skin + '/Opera9Fixes.css' ); |
| 1079 | + } else if ( mw.legacy.ff2_bugs ) { |
| 1080 | + importStylesheetURI( stylepath + '/' + skin + '/FF2Fixes.css' ); |
| 1081 | + } |
| 1082 | + } |
| 1083 | + if ( mw.legacy.ie6_bugs ) { |
| 1084 | + importScriptURI( mw.legacy.stylepath + '/common/IEFixes.js' ); |
| 1085 | + } |
| 1086 | + // NOTE: All skins should call runOnloadHook() at the end of html output, so this should be redundant - it's here |
| 1087 | + // just in case |
| 1088 | + runOnloadHook(); |
20 | 1089 | } ); |
21 | 1090 | |
22 | 1091 | } )( jQuery, MediaWiki ); |
\ No newline at end of file |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.edit.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | |
8 | 8 | /* Extension */ |
9 | 9 | |
10 | | -$.extend( mw.legacy, { |
| 10 | +$.extend( true, mw.legacy, { |
11 | 11 | |
12 | 12 | /* Global Variables */ |
13 | 13 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.mwsuggest.js |
— | — | @@ -12,7 +12,7 @@ |
13 | 13 | |
14 | 14 | /* Extension */ |
15 | 15 | |
16 | | -$.extend( mw.legacy, { |
| 16 | +$.extend( true, mw.legacy, { |
17 | 17 | |
18 | 18 | /* Global Variables */ |
19 | 19 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.htmlform.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | |
8 | 8 | /* Extension */ |
9 | 9 | |
10 | | -$.extend( mw.legacy, { |
| 10 | +$.extend( true, mw.legacy, { |
11 | 11 | |
12 | 12 | /* Global Variables */ |
13 | 13 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.rightclickedit.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | |
8 | 8 | /* Extension */ |
9 | 9 | |
10 | | -$.extend( mw.legacy, { |
| 10 | +$.extend( true, mw.legacy, { |
11 | 11 | |
12 | 12 | /* Functions */ |
13 | 13 | |
— | — | @@ -40,7 +40,6 @@ |
41 | 41 | targ = targ.parentNode; |
42 | 42 | } |
43 | 43 | // targ is now the target element |
44 | | - |
45 | 44 | // We don't want to deprive the noble reader of a context menu |
46 | 45 | // for the section edit link, do we? (Might want to extend this |
47 | 46 | // to all <a>'s?) |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.block.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | |
8 | 8 | /* Extension */ |
9 | 9 | |
10 | | -$.extend( mw.legacy, { |
| 10 | +$.extend( true, mw.legacy, { |
11 | 11 | |
12 | 12 | /* Functions */ |
13 | 13 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.IEFixes.js |
— | — | @@ -23,7 +23,7 @@ |
24 | 24 | |
25 | 25 | /* Extension */ |
26 | 26 | |
27 | | -$.extend( mw.legacy, { |
| 27 | +$.extend( true, mw.legacy, { |
28 | 28 | |
29 | 29 | /* Global Variables */ |
30 | 30 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.enhancedchanges.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | |
8 | 8 | /* Extension */ |
9 | 9 | |
10 | | -$.extend( mw.legacy, { |
| 10 | +$.extend( true, mw.legacy, { |
11 | 11 | |
12 | 12 | /* Functions */ |
13 | 13 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.history.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | |
8 | 8 | /* Extension */ |
9 | 9 | |
10 | | -$.extend( mw.legacy, { |
| 10 | +$.extend( true, mw.legacy, { |
11 | 11 | |
12 | 12 | /* Functions */ |
13 | 13 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.search.js |
— | — | @@ -8,34 +8,34 @@ |
9 | 9 | |
10 | 10 | /* Extension */ |
11 | 11 | |
12 | | -$.extend( mw.legacy, { |
| 12 | +$.extend( true, mw.legacy, { |
13 | 13 | |
14 | 14 | /* Functions */ |
15 | 15 | |
16 | 16 | /** |
17 | 17 | * Change the search link to what user entered |
18 | 18 | */ |
19 | | - function mwSearchHeaderClick( obj ) { |
| 19 | + 'mwSearchHeaderClick': function( obj ) { |
20 | 20 | var searchbox = document.getElementById( 'searchText' ); |
21 | | - if( searchbox === null ) { |
| 21 | + if ( searchbox === null ) { |
22 | 22 | searchbox = document.getElementById( 'powerSearchText' ); |
23 | 23 | } |
24 | | - if( searchbox === null ) { |
| 24 | + if ( searchbox === null ) { |
25 | 25 | return; // should always have either normal or advanced search |
26 | 26 | } |
27 | 27 | var searchterm = searchbox.value; |
28 | 28 | var parts = obj.href.split( 'search=' ); |
29 | 29 | var lastpart = ''; |
30 | 30 | var prefix = 'search='; |
31 | | - if( parts.length > 1 && parts[1].indexOf('&') >= 0 ) { |
| 31 | + if ( parts.length > 1 && parts[1].indexOf('&') >= 0 ) { |
32 | 32 | lastpart = parts[1].substring( parts[1].indexOf('&') ); |
33 | 33 | } else { |
34 | 34 | prefix = '&search='; |
35 | 35 | } |
36 | 36 | obj.href = parts[0] + prefix + encodeURIComponent( searchterm ) + lastpart; |
37 | | - } |
38 | | - function mwToggleSearchCheckboxes( btn ) { |
39 | | - if( !document.getElementById ) { |
| 37 | + }, |
| 38 | + 'mwToggleSearchCheckboxes': function( btn ) { |
| 39 | + if ( !document.getElementById ) { |
40 | 40 | return; |
41 | 41 | } |
42 | 42 | var nsInputs = document.getElementById( 'powersearch' ).getElementsByTagName( 'input' ); |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.changepassword.js |
— | — | @@ -6,7 +6,7 @@ |
7 | 7 | |
8 | 8 | /* Extension */ |
9 | 9 | |
10 | | -$.extend( mw.legacy, { |
| 10 | +$.extend( true, mw.legacy, { |
11 | 11 | |
12 | 12 | /* Functions */ |
13 | 13 | |
Index: branches/resourceloader/phase3/resources/mw/legacy/mw.legacy.ajaxwatch.js |
— | — | @@ -10,7 +10,7 @@ |
11 | 11 | |
12 | 12 | /* Extension */ |
13 | 13 | |
14 | | -$.extend( mw.legacy, { |
| 14 | +$.extend( true, mw.legacy, { |
15 | 15 | |
16 | 16 | /* Global Variables */ |
17 | 17 | |