Index: trunk/phase3/resources/Resources.php |
— | — | @@ -328,6 +328,7 @@ |
329 | 329 | ) ), |
330 | 330 | 'mediawiki.util' => new ResourceLoaderFileModule( array( |
331 | 331 | 'scripts' => 'resources/mediawiki/mediawiki.util.js', |
| 332 | + 'debugScripts' => 'resources/mediawiki/mediawiki.utiltest.js', |
332 | 333 | ) ), |
333 | 334 | |
334 | 335 | /* MediaWiki Legacy */ |
Index: trunk/phase3/resources/mediawiki/mediawiki.util.js |
— | — | @@ -26,7 +26,7 @@ |
27 | 27 | } else if (is_ff2) { |
28 | 28 | this.tooltipAccessKeyPrefix = 'alt-shift-'; |
29 | 29 | } |
30 | | - |
| 30 | + |
31 | 31 | // Setup CheckboxShiftClick |
32 | 32 | $.fn.enableCheckboxShiftClick = function () { |
33 | 33 | var prevCheckbox = null; |
— | — | @@ -42,17 +42,17 @@ |
43 | 43 | }); |
44 | 44 | return $box; |
45 | 45 | }; |
46 | | - |
| 46 | + |
47 | 47 | // Prototype enhancements |
48 | 48 | if (typeof String.prototype.ucFirst === 'undefined') { |
49 | 49 | String.prototype.ucFirst = function () { |
50 | 50 | return this.substr(0, 1).toUpperCase() + this.substr(1, this.length); |
51 | 51 | }; |
52 | 52 | } |
53 | | - |
| 53 | + |
54 | 54 | // Any initialisation after the DOM is ready |
55 | 55 | $(function () { |
56 | | - $('input[type=checkbox]:not(.noshiftselect)').enableCheckboxShiftClick(); |
| 56 | + $('input[type=checkbox]:not(.noshiftselect)').enableCheckboxShiftClick(); |
57 | 57 | }); |
58 | 58 | |
59 | 59 | |
— | — | @@ -96,7 +96,7 @@ |
97 | 97 | |
98 | 98 | /** |
99 | 99 | * Check is a variable is empty. Support for strings, booleans, arrays and objects. |
100 | | - * String "0" is considered empty. String containing only whitespace (ie. " ") is considered not empty. |
| 100 | + * String "0" is considered empty. String containing only whitespace (ie. " ") is considered not empty. |
101 | 101 | * |
102 | 102 | * @param Mixed v the variable to check for empty ness |
103 | 103 | */ |
— | — | @@ -281,6 +281,6 @@ |
282 | 282 | |
283 | 283 | }; |
284 | 284 | |
285 | | -})(jQuery, mediaWiki); |
| 285 | + mediaWiki.util.init(); |
286 | 286 | |
287 | | -mediaWiki.util.init(); |
\ No newline at end of file |
| 287 | +})(jQuery, mediaWiki); |
\ No newline at end of file |
Index: trunk/phase3/resources/mediawiki/mediawiki.utiltest.js |
— | — | @@ -0,0 +1,137 @@ |
| 2 | +/* |
| 3 | + * mediaWiki Debug Test Suit on [[Special:MWUtilJSTest]] (only when ?debug=true) |
| 4 | + */ |
| 5 | + |
| 6 | +(function ($, mw) { |
| 7 | + |
| 8 | + mediaWiki.test = { |
| 9 | + |
| 10 | + /* Variables */ |
| 11 | + '$bodyContent' : null, |
| 12 | + '$table' : null, |
| 13 | + 'addedTests' : [], |
| 14 | + |
| 15 | + /* Functions */ |
| 16 | + |
| 17 | + /** |
| 18 | + * Adds a row to the test-table |
| 19 | + * |
| 20 | + * @param String code Code of the test to be executed |
| 21 | + * @param String result Expected result in 'var (vartype)' form. |
| 22 | + */ |
| 23 | + 'addTest' : function (code, result) { |
| 24 | + this.addedTests.push([code, result]); |
| 25 | + this.$table.append('<tr><td>' + mw.util.htmlEscape(code) + '</td><td>' + mw.util.htmlEscape(result) + '<td></td></td><td>?</td></tr>'); |
| 26 | + }, |
| 27 | + |
| 28 | + /* Initialisation */ |
| 29 | + 'initialised' : false, |
| 30 | + 'init' : function () { |
| 31 | + if (this.initialised === false) { |
| 32 | + this.initialised = true; |
| 33 | + $(function () { |
| 34 | + if (wgTitle == 'MWUtilJSTest' && wgCanonicalNamespace == 'Special') { |
| 35 | + |
| 36 | + // Build page |
| 37 | + document.title = 'mediaWiki.util JavaScript Test - ' + wgSiteName; |
| 38 | + $('#firstHeading').text('mediaWiki.util JavaScript Test'); |
| 39 | + mw.test.bodyContent = $('#bodyContent'); |
| 40 | + mw.test.bodyContent.html( |
| 41 | + '<p>Below is a list of tests to confirm proper functionality of the mediaWiki.util functions</p>' + |
| 42 | + '<hr />' + |
| 43 | + '<table id="mw-mwutiltest-table" class="wikitable sortable"><tr><th>Exec</th><th>Should return</th><th>Does return</th><th>Equal ?</th></tr></table>' |
| 44 | + ); |
| 45 | + mw.test.$table = $('table#mw-mwutiltest-table'); |
| 46 | + |
| 47 | + // Populate tests |
| 48 | + mw.test.addTest('typeof String.prototype.trim', |
| 49 | + 'function (string)'); |
| 50 | + mw.test.addTest('typeof String.prototype.trimLeft', |
| 51 | + 'function (string)'); |
| 52 | + mw.test.addTest('typeof String.prototype.trimRight', |
| 53 | + 'function (string)'); |
| 54 | + mw.test.addTest('typeof Array.prototype.compare', |
| 55 | + 'function (string)'); |
| 56 | + mw.test.addTest('typeof Array.prototype.indexOf', |
| 57 | + 'function (string)'); |
| 58 | + mw.test.addTest('4', |
| 59 | + '4 (number)'); |
| 60 | + mw.test.addTest('typeof mediaWiki', |
| 61 | + 'object (string)'); |
| 62 | + mw.test.addTest('typeof mw', |
| 63 | + 'object (string)'); |
| 64 | + mw.test.addTest('typeof mw.util', |
| 65 | + 'object (string)'); |
| 66 | + mw.test.addTest('typeof String.prototype.ucFirst', |
| 67 | + 'function (string)'); |
| 68 | + mw.test.addTest('\'mediawiki\'.ucFirst()', |
| 69 | + 'Mediawiki (string)'); |
| 70 | + mw.test.addTest('typeof $.fn.enableCheckboxShiftClick', |
| 71 | + 'function (string)'); |
| 72 | + mw.test.addTest('typeof mw.util.rawurlencode', |
| 73 | + 'function (string)'); |
| 74 | + mw.test.addTest('mw.util.rawurlencode(\'Test: A&B/Here\')', |
| 75 | + 'Test%3A%20A%26B%2FHere (string)'); |
| 76 | + mw.test.addTest('typeof mw.util.getWikilink', |
| 77 | + 'function (string)'); |
| 78 | + mw.test.addTest('typeof mw.util.getParamValue', |
| 79 | + 'function (string)'); |
| 80 | + mw.test.addTest('mw.util.getParamValue(\'debug\')', |
| 81 | + 'true (string)'); |
| 82 | + mw.test.addTest('typeof mw.util.htmlEscape', |
| 83 | + 'function (string)'); |
| 84 | + mw.test.addTest('mw.util.htmlEscape(\'<a href="http://mw.org/?a=b&c=d">link</a>\')', |
| 85 | + '<a href="http://mw.org/?a=b&c=d">link</a> (string)'); |
| 86 | + mw.test.addTest('typeof mw.util.htmlUnescape', |
| 87 | + 'function (string)'); |
| 88 | + mw.test.addTest('mw.util.htmlUnescape(\'<a href="http://mw.org/?a=b&c=d">link</a>\')', |
| 89 | + '<a href="http://mw.org/?a=b&c=d">link</a> (string)'); |
| 90 | + mw.test.addTest('typeof mw.util.tooltipAccessKeyRegexp', |
| 91 | + 'function (string)'); |
| 92 | + mw.test.addTest('typeof mw.util.updateTooltipAccessKeys', |
| 93 | + 'function (string)'); |
| 94 | + mw.test.addTest('typeof mw.util.addPortletLink', |
| 95 | + 'function (string)'); |
| 96 | + mw.test.addTest('typeof mw.util.addPortletLink("p-tb", "http://mediawiki.org/", "MediaWiki.org", "t-mworg", "Go to MediaWiki.org ", "m", "#t-print")', |
| 97 | + 'object (string)'); |
| 98 | + mw.test.addTest('mw.util.addPortletLink("p-tb", "http://mediawiki.org/", "MediaWiki.org", "t-mworg", "Go to MediaWiki.org ", "m", "#t-print").outerHTML', |
| 99 | + '<li id="t-mworg"><span><a href="http://mediawiki.org/" accesskey="m" title="Go to MediaWiki.org [ctrl-alt-m]">MediaWiki.org</a></span></li> (string)'); |
| 100 | + |
| 101 | + // Run tests and compare results |
| 102 | + var exec, |
| 103 | + result, |
| 104 | + resulttype, |
| 105 | + numberoftests = 0, |
| 106 | + numberoferrors = 0, |
| 107 | + $testrows; |
| 108 | + $testrows = mw.test.$table.find('tr'); |
| 109 | + $.each(mw.test.addedTests, (function (i) { |
| 110 | + numberoftests++; |
| 111 | + |
| 112 | + exec = mw.test.addedTests[i][0]; |
| 113 | + shouldreturn = mw.test.addedTests[i][1]; |
| 114 | + doesreturn = eval(exec); |
| 115 | + doesreturn = doesreturn + ' (' + typeof doesreturn + ')'; |
| 116 | + $thisrow = $testrows.eq(i + 1); |
| 117 | + $thisrow.find('> td').eq(2).text(doesreturn); |
| 118 | + |
| 119 | + if (shouldreturn === doesreturn) { |
| 120 | + $thisrow.find('> td').eq(3).css('background', '#EFE').text('OK'); |
| 121 | + } else { |
| 122 | + $thisrow.find('> td').eq(3).css('background', '#FEE').text('ERROR'); |
| 123 | + numberoferrors++; |
| 124 | + } |
| 125 | + |
| 126 | + }) |
| 127 | + ); |
| 128 | + mw.test.$table.before('<p><strong>Ran ' + numberoftests + ' tests. ' + numberoferrors + ' error(s). </p>'); |
| 129 | + |
| 130 | + } |
| 131 | + }); |
| 132 | + } |
| 133 | + } |
| 134 | + }; |
| 135 | + |
| 136 | + mediaWiki.test.init(); |
| 137 | + |
| 138 | +})(jQuery, mediaWiki); |
\ No newline at end of file |
Property changes on: trunk/phase3/resources/mediawiki/mediawiki.utiltest.js |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 139 | + native |
Index: trunk/phase3/resources/mediawiki/mediawiki.js |
— | — | @@ -3,11 +3,11 @@ |
4 | 4 | */ |
5 | 5 | |
6 | 6 | // New fallback String trimming functionality, was introduced natively in JavaScript 1.8.1 |
7 | | -if (typeof String.prototype.trimx === 'undefined') { |
| 7 | +if (typeof String.prototype.trim === 'undefined') { |
8 | 8 | // Add removing trailing and leading whitespace functionality cross-browser |
9 | 9 | // See also: http://blog.stevenlevithan.com/archives/faster-trim-javascript |
10 | 10 | String.prototype.trim = function () { |
11 | | - return this.replace(/^\s+|\s+$/g, ''); |
| 11 | + return this.replace(/^\s+|\s+$/g, ''); |
12 | 12 | }; |
13 | 13 | } |
14 | 14 | if (typeof String.prototype.trimLeft === 'undefined') { |
— | — | @@ -15,7 +15,7 @@ |
16 | 16 | return this.replace(/^\s\s*/, ""); |
17 | 17 | }; |
18 | 18 | } |
19 | | - |
| 19 | + |
20 | 20 | if (typeof String.prototype.trimRight === 'undefined') { |
21 | 21 | String.prototype.trimRight = function () { |
22 | 22 | return this.replace(/\s\s*$/, ""); |
— | — | @@ -59,18 +59,18 @@ |
60 | 60 | */ |
61 | 61 | // Attach to window |
62 | 62 | window.mediaWiki = new ( function( $ ) { |
63 | | - |
| 63 | + |
64 | 64 | /* Constants */ |
65 | | - |
| 65 | + |
66 | 66 | // This will not change until we are 100% ready to turn off legacy globals |
67 | 67 | var LEGACY_GLOBALS = true; |
68 | | - |
| 68 | + |
69 | 69 | /* Private Members */ |
70 | | - |
| 70 | + |
71 | 71 | var that = this; |
72 | | - |
| 72 | + |
73 | 73 | /* Prototypes */ |
74 | | - |
| 74 | + |
75 | 75 | this.prototypes = { |
76 | 76 | /* |
77 | 77 | * An object which allows single and multiple get/set/exists functionality on a list of key / value pairs |
— | — | @@ -81,14 +81,14 @@ |
82 | 82 | * where value is the data to be parsed and options is additional data passed through to the parser |
83 | 83 | */ |
84 | 84 | 'map': function( global, parser, fallback ) { |
85 | | - |
| 85 | + |
86 | 86 | /* Private Members */ |
87 | | - |
| 87 | + |
88 | 88 | var that = this; |
89 | 89 | var values = global === true ? window : {}; |
90 | | - |
| 90 | + |
91 | 91 | /* Public Methods */ |
92 | | - |
| 92 | + |
93 | 93 | /** |
94 | 94 | * Gets one or more values |
95 | 95 | * |
— | — | @@ -138,7 +138,7 @@ |
139 | 139 | return values; |
140 | 140 | } |
141 | 141 | }; |
142 | | - |
| 142 | + |
143 | 143 | /** |
144 | 144 | * Sets one or multiple configuration values using a key and a value or an object of keys and values |
145 | 145 | * |
— | — | @@ -154,7 +154,7 @@ |
155 | 155 | values[selection] = value; |
156 | 156 | } |
157 | 157 | }; |
158 | | - |
| 158 | + |
159 | 159 | /** |
160 | 160 | * Checks if one or multiple configuration fields exist |
161 | 161 | */ |
— | — | @@ -172,31 +172,31 @@ |
173 | 173 | }; |
174 | 174 | } |
175 | 175 | }; |
176 | | - |
| 176 | + |
177 | 177 | /* Methods */ |
178 | | - |
| 178 | + |
179 | 179 | /* |
180 | 180 | * Dummy function which in debug mode can be replaced with a function that does something clever |
181 | 181 | */ |
182 | 182 | this.log = function() { }; |
183 | | - |
| 183 | + |
184 | 184 | /* |
185 | 185 | * List of configuration values |
186 | 186 | * |
187 | 187 | * In legacy mode the values this object wraps will be in the global space |
188 | 188 | */ |
189 | 189 | this.config = new this.prototypes.map( LEGACY_GLOBALS ); |
190 | | - |
| 190 | + |
191 | 191 | /* |
192 | 192 | * Information about the current user |
193 | 193 | */ |
194 | 194 | this.user = new ( function() { |
195 | | - |
| 195 | + |
196 | 196 | /* Public Members */ |
197 | | - |
| 197 | + |
198 | 198 | this.options = new that.prototypes.map(); |
199 | 199 | } )(); |
200 | | - |
| 200 | + |
201 | 201 | /* |
202 | 202 | * Basic parser, can be replaced with something more robust |
203 | 203 | */ |
— | — | @@ -209,19 +209,19 @@ |
210 | 210 | } |
211 | 211 | return text; |
212 | 212 | }; |
213 | | - |
| 213 | + |
214 | 214 | /* |
215 | 215 | * Localization system |
216 | 216 | */ |
217 | 217 | this.msg = new that.prototypes.map( false, this.parser, function( key ) { return '<' + key + '>'; } ); |
218 | | - |
| 218 | + |
219 | 219 | /* |
220 | 220 | * Client-side module loader which integrates with the MediaWiki ResourceLoader |
221 | 221 | */ |
222 | 222 | this.loader = new ( function() { |
223 | | - |
| 223 | + |
224 | 224 | /* Private Members */ |
225 | | - |
| 225 | + |
226 | 226 | var that = this; |
227 | 227 | /* |
228 | 228 | * Mapping of registered modules |
— | — | @@ -253,9 +253,9 @@ |
254 | 254 | var suspended = true; |
255 | 255 | // Flag inidicating that document ready has occured |
256 | 256 | var ready = false; |
257 | | - |
| 257 | + |
258 | 258 | /* Private Methods */ |
259 | | - |
| 259 | + |
260 | 260 | /** |
261 | 261 | * Generates an ISO8601 "basic" string from a UNIX timestamp |
262 | 262 | */ |
— | — | @@ -270,7 +270,7 @@ |
271 | 271 | pad( d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds() ), 'Z' |
272 | 272 | ].join( '' ); |
273 | 273 | } |
274 | | - |
| 274 | + |
275 | 275 | /** |
276 | 276 | * Recursively resolves dependencies and detects circular references |
277 | 277 | */ |
— | — | @@ -298,7 +298,7 @@ |
299 | 299 | resolved[resolved.length] = module; |
300 | 300 | unresolved.splice( unresolved.indexOf( module ), 1 ); |
301 | 301 | } |
302 | | - |
| 302 | + |
303 | 303 | /** |
304 | 304 | * Gets a list of modules names that a module dependencies in their proper dependency order |
305 | 305 | * |
— | — | @@ -328,7 +328,7 @@ |
329 | 329 | } |
330 | 330 | throw new Error( 'Invalid module argument: ' + module ); |
331 | 331 | }; |
332 | | - |
| 332 | + |
333 | 333 | /** |
334 | 334 | * Narrows a list of module names down to those matching a specific state. Possible states are 'undefined', |
335 | 335 | * 'registered', 'loading', 'loaded', or 'ready' |
— | — | @@ -363,7 +363,7 @@ |
364 | 364 | } |
365 | 365 | return list; |
366 | 366 | } |
367 | | - |
| 367 | + |
368 | 368 | /** |
369 | 369 | * Executes a loaded module, making it ready to use |
370 | 370 | * |
— | — | @@ -418,7 +418,7 @@ |
419 | 419 | } catch ( e ) { |
420 | 420 | mediaWiki.log( 'Exception thrown by ' + module + ': ' + e.message ); |
421 | 421 | mediaWiki.log( e ); |
422 | | - registry[module].state = 'error'; |
| 422 | + registry[module].state = 'error'; |
423 | 423 | // Run error callbacks of jobs affected by this condition |
424 | 424 | for ( var j = 0; j < jobs.length; j++ ) { |
425 | 425 | if ( jobs[j].dependencies.indexOf( module ) !== -1 ) { |
— | — | @@ -431,7 +431,7 @@ |
432 | 432 | } |
433 | 433 | } |
434 | 434 | } |
435 | | - |
| 435 | + |
436 | 436 | /** |
437 | 437 | * Adds a dependencies to the queue with optional callbacks to be run when the dependencies are ready or fail |
438 | 438 | * |
— | — | @@ -467,7 +467,7 @@ |
468 | 468 | // Work the queue |
469 | 469 | that.work(); |
470 | 470 | } |
471 | | - |
| 471 | + |
472 | 472 | function sortQuery(o) { |
473 | 473 | var sorted = {}, key, a = []; |
474 | 474 | for ( key in o ) { |
— | — | @@ -481,9 +481,9 @@ |
482 | 482 | } |
483 | 483 | return sorted; |
484 | 484 | } |
485 | | - |
| 485 | + |
486 | 486 | /* Public Methods */ |
487 | | - |
| 487 | + |
488 | 488 | /** |
489 | 489 | * Requests dependencies from server, loading and executing when things when ready. |
490 | 490 | */ |
— | — | @@ -560,7 +560,7 @@ |
561 | 561 | } |
562 | 562 | } |
563 | 563 | }; |
564 | | - |
| 564 | + |
565 | 565 | /** |
566 | 566 | * Registers a module, letting the system know about it and it's dependencies. loader.js files contain calls |
567 | 567 | * to this function. |
— | — | @@ -599,7 +599,7 @@ |
600 | 600 | registry[module].dependencies = dependencies; |
601 | 601 | } |
602 | 602 | }; |
603 | | - |
| 603 | + |
604 | 604 | /** |
605 | 605 | * Implements a module, giving the system a course of action to take upon loading. Results of a request for |
606 | 606 | * one or more modules contain calls to this function. |
— | — | @@ -639,7 +639,7 @@ |
640 | 640 | request( module ); |
641 | 641 | } |
642 | 642 | }; |
643 | | - |
| 643 | + |
644 | 644 | /** |
645 | 645 | * Executes a function as soon as one or more required modules are ready |
646 | 646 | * |
— | — | @@ -676,7 +676,7 @@ |
677 | 677 | request( dependencies, ready, error ); |
678 | 678 | } |
679 | 679 | }; |
680 | | - |
| 680 | + |
681 | 681 | /** |
682 | 682 | * Loads an external script or one or more modules for future use |
683 | 683 | * |
— | — | @@ -727,7 +727,7 @@ |
728 | 728 | return true; |
729 | 729 | } |
730 | 730 | }; |
731 | | - |
| 731 | + |
732 | 732 | /** |
733 | 733 | * Flushes the request queue and begin executing load requests on demand |
734 | 734 | */ |
— | — | @@ -735,7 +735,7 @@ |
736 | 736 | suspended = false; |
737 | 737 | that.work(); |
738 | 738 | }; |
739 | | - |
| 739 | + |
740 | 740 | /** |
741 | 741 | * Changes the state of a module |
742 | 742 | * |
— | — | @@ -754,7 +754,7 @@ |
755 | 755 | } |
756 | 756 | registry[module].state = state; |
757 | 757 | }; |
758 | | - |
| 758 | + |
759 | 759 | /** |
760 | 760 | * Gets the version of a module |
761 | 761 | * |
— | — | @@ -766,16 +766,16 @@ |
767 | 767 | } |
768 | 768 | return null; |
769 | 769 | } |
770 | | - |
| 770 | + |
771 | 771 | /* Cache document ready status */ |
772 | | - |
| 772 | + |
773 | 773 | $(document).ready( function() { ready = true; } ); |
774 | 774 | } )(); |
775 | | - |
| 775 | + |
776 | 776 | /* Extension points */ |
777 | | - |
| 777 | + |
778 | 778 | this.legacy = {}; |
779 | | - |
| 779 | + |
780 | 780 | } )( jQuery ); |
781 | 781 | |
782 | 782 | /* Auto-register from pre-loaded startup scripts */ |