Index: branches/resourceloader/phase3/resources/test/test.js |
— | — | @@ -1,6 +1,2 @@ |
2 | | - |
3 | | -// Attaches an implementation to the loading system |
4 | | -mw.loader.implement( 'test', function() { |
5 | | - // Test output |
6 | | - console.log( 'Test succeeded!' ); |
7 | | -} ); |
| 2 | +// Test output |
| 3 | +console.log( 'Test succeeded!' ); |
Index: branches/resourceloader/phase3/resources/mw/mw.js |
— | — | @@ -99,7 +99,7 @@ |
100 | 100 | if ( typeof keys === 'object' ) { |
101 | 101 | var result = {}; |
102 | 102 | for ( key in keys ) { |
103 | | - result[key] = typeof values[keys] === 'undefined' ? null, values[keys]; |
| 103 | + result[key] = typeof values[keys] === 'undefined' ? null : values[keys]; |
104 | 104 | } |
105 | 105 | return result; |
106 | 106 | } else if ( typeof values[keys] === 'undefined' ) { |
— | — | @@ -166,15 +166,65 @@ |
167 | 167 | }; |
168 | 168 | // List of callbacks and their dependencies - this gets reduced each time work() is called, if possible |
169 | 169 | var queue = []; |
| 170 | + // List of modules to wait to load until ready, or right away after ready |
| 171 | + var batch = []; |
| 172 | + // True after document ready occurs |
| 173 | + var ready = false; |
170 | 174 | |
| 175 | + /* Event Bindings */ |
| 176 | + |
| 177 | + $( document ).ready( function() { |
| 178 | + ready = true; |
| 179 | + that.work(); |
| 180 | + } ); |
| 181 | + |
171 | 182 | /* Private Functions */ |
172 | 183 | |
173 | 184 | /** |
| 185 | + * Narrows a list of requirements down to only those which are still pending (not registered or not ready) |
| 186 | + */ |
| 187 | + function pending( requirements ) { |
| 188 | + // Collect the names of pending modules |
| 189 | + var list = []; |
| 190 | + for ( r in requirements ) { |
| 191 | + if ( |
| 192 | + typeof registry[requirements[r]] === 'undefined' || |
| 193 | + typeof registry[requirements[r]].state === 'undefined' || |
| 194 | + registry[requirements[r]].state !== 'ready' |
| 195 | + ) { |
| 196 | + list[list.length] = requirements[r]; |
| 197 | + } |
| 198 | + } |
| 199 | + return list; |
| 200 | + } |
| 201 | + /** |
| 202 | + * Executes a loaded but not ready module, making it ready to use |
| 203 | + */ |
| 204 | + function execute( requirement ) { |
| 205 | + if ( registry[requirement].state === 'loaded' ) { |
| 206 | + // Add style, if any |
| 207 | + if ( typeof registry[requirement].style === 'string' ) { |
| 208 | + var style = document.createElement( 'style' ); |
| 209 | + style.type = 'text/css'; |
| 210 | + style.innerHTML = registry[requirement].style; |
| 211 | + } |
| 212 | + // Add localizations |
| 213 | + if ( typeof registry[requirement].localization === 'object' ) { |
| 214 | + mw.msg.set( registry[requirement].localization ); |
| 215 | + } |
| 216 | + // Execute script, if any |
| 217 | + registry[requirement].script(); |
| 218 | + // Change state |
| 219 | + registry[requirement].state = 'ready'; |
| 220 | + } |
| 221 | + } |
| 222 | + |
| 223 | + /* Public Functions */ |
| 224 | + |
| 225 | + /** |
174 | 226 | * Processes the queue, loading and executing when things when ready. |
175 | 227 | */ |
176 | | - function work() { |
177 | | - var batch = []; |
178 | | - var head = document.getElementById( 'head' )[0]; |
| 228 | + this.work = function() { |
179 | 229 | for ( q in queue ) { |
180 | 230 | for ( p in queue[q].pending ) { |
181 | 231 | var requirement = queue[q].pending[p]; |
— | — | @@ -211,74 +261,36 @@ |
212 | 262 | } |
213 | 263 | } |
214 | 264 | } |
215 | | - // Handle the batch |
216 | | - if ( batch.length ) { |
217 | | - // Always order module alphabetically to help reduce cache misses for otherwise identical content |
218 | | - batch.sort(); |
| 265 | + // Handle the batch only when ready |
| 266 | + if ( batch.length && ready ) { |
219 | 267 | // It may be more performant to do this with an Ajax call, but that's limited to same-domain, so we can |
220 | | - // either auto-detect (if there really is any benefit) or just use this method, which is safe either way |
221 | | - var script = document.createElement( 'script' ); |
222 | | - script.type = 'text/javascript'; |
223 | | - // Build and set the request URL |
224 | | - var query = mw.config.get( [ 'user', 'skin', 'space', 'view', 'language' ] ); |
225 | | - query.modules = batch.join( '|' ); |
226 | | - script.src = mw.util.buildUrlString( { |
227 | | - 'path': 'load.php', |
228 | | - 'query': query |
| 268 | + // either auto-detect (if there really is any benefit) or just use this method, which is safe either |
| 269 | + // way. Also note, we're using "each" here so we only clear the batch if there was a head to add to |
| 270 | + $( 'head' ).each( function() { |
| 271 | + // Always order module alphabetically to help reduce cache misses for otherwise identical content |
| 272 | + batch.sort(); |
| 273 | + // Append script to head |
| 274 | + $(this).append( |
| 275 | + $( '<script type="text/javascript"></script>' ) |
| 276 | + .attr( 'src', mw.util.buildUrlString( { |
| 277 | + 'path': 'load.php', |
| 278 | + 'query': $.extend( |
| 279 | + // Pass configuration values through the URL |
| 280 | + mw.config.get( [ 'user', 'skin', 'space', 'view', 'language' ] ), |
| 281 | + // Modules are in the format foo|bar|baz|buz |
| 282 | + { 'modules': batch.join( '|' ) } |
| 283 | + ) |
| 284 | + } ) ) |
| 285 | + .load( function() { |
| 286 | + that.work(); |
| 287 | + } ) |
| 288 | + ); |
| 289 | + // Clear the batch |
| 290 | + batch = []; |
229 | 291 | } ); |
230 | | - // Good browsers |
231 | | - script.onload = work; |
232 | | - // Bad browsers (IE 6 & 7) |
233 | | - script.onreadystatechange = function() { |
234 | | - if ( this.readyState == 'complete' ) { |
235 | | - work(); |
236 | | - } |
237 | | - } |
238 | | - head.appendChild( script ); |
239 | 292 | } |
240 | | - } |
| 293 | + }; |
241 | 294 | /** |
242 | | - * Narrows a list of requirements down to only those which are still pending (not registered or not ready) |
243 | | - */ |
244 | | - function pending( requirements ) { |
245 | | - // Collect the names of pending modules |
246 | | - var list = []; |
247 | | - for ( r in requirements ) { |
248 | | - if ( |
249 | | - typeof registry[requirements[r]] === 'undefined' || |
250 | | - typeof registry[requirements[r]].state === 'undefined' || |
251 | | - registry[requirements[r]].state !== 'ready' |
252 | | - ) { |
253 | | - list[list.length] = requirements[r]; |
254 | | - } |
255 | | - } |
256 | | - return list; |
257 | | - } |
258 | | - /** |
259 | | - * Executes a loaded but not ready module, making it ready to use |
260 | | - */ |
261 | | - function execute( requirement ) { |
262 | | - if ( registry[requirement].state === 'loaded' ) { |
263 | | - // Add style, if any |
264 | | - if ( typeof registry[requirement].style === 'string' ) { |
265 | | - var style = document.createElement( 'style' ); |
266 | | - style.type = 'text/css'; |
267 | | - style.innerHTML = registry[requirement].style; |
268 | | - } |
269 | | - // Add localizations |
270 | | - if ( typeof registry[requirement].localization === 'object' ) { |
271 | | - mw.msg.set( registry[requirement].localization ); |
272 | | - } |
273 | | - // Execute script, if any |
274 | | - registry[requirement].script(); |
275 | | - // Change state |
276 | | - registry[requirement].state = 'ready'; |
277 | | - } |
278 | | - } |
279 | | - |
280 | | - /* Public Functions */ |
281 | | - |
282 | | - /** |
283 | 295 | * Registers a module, letting the system know about it and it's dependencies. loader.js files contain calls |
284 | 296 | * to this function. |
285 | 297 | */ |
— | — | @@ -334,7 +346,7 @@ |
335 | 347 | } else { |
336 | 348 | // Queue it up and work the queue |
337 | 349 | queue[queue.length] = { 'pending': requirements, 'callback': function() { execute( name ); } }; |
338 | | - work(); |
| 350 | + that.work(); |
339 | 351 | } |
340 | 352 | return true; |
341 | 353 | } |
— | — | @@ -356,7 +368,7 @@ |
357 | 369 | } else { |
358 | 370 | // Queue it up and work the queue |
359 | 371 | queue[queue.length] = { 'pending': requirements, 'callback': callback }; |
360 | | - work(); |
| 372 | + that.work(); |
361 | 373 | } |
362 | 374 | }; |
363 | 375 | } )() |