On Mon, 19 Mar 2012 00:40:54 -0700, Dmitriy Sintsov questpc@rambler.ru wrote:
Hi! I've tweaked my code few times, trying to make it simpler: got rid of some closure calls and left only one dynamic module load at client-side.
http://pastebin.com/UxyifLmx http://pastebin.com/q3Tm6Ajd http://pastebin.com/4emMDBS6
Still, it gives me headaches, because mw.loader.using( 'ext.jqgmap.edit' ,function(...)) does not actually execute the loaded module's code even when the callback function is "fired". This means that additional mw.jqgmap prototypes defined in 'ext.jqgmap.edit' are not available when actual object instances are created in function createMapControllers(), thus throws an error. When I add explicit call to dummy function loadEditPrototypes() defined in 'ext.jqgmap.edit', the module is executed, but the further scipts execution abruptly ends without any error in Chrome console.
To me it seems that ResourceLoader tries to be too smart not actually executing the code just before .using() callback. How does it figure out that I defined function loadEditPrototypes() in 'ext.jqgmap.edit' module? That kind of 'automagic' is tricky. Why not to have something like $wgAutoloadClasses but for ResourceLoader? Or, even to be able to really execute module on load. And why does it stop execution path is a puzzle to me..
Autoloading classes is not possible. Even if every browser supported getters and we could use them to dynamically load classes, this would require synchronous http calls. Which are absolutely HORRIBLE because they block the entire JS thread and in addition typically even block the browser's UI.
Dmitriy
You shouldn't be dropping the closure, you don't want local things in the global scope. You also shouldn't be using the global $ and mw directly. Everything should be using a pattern like: ( function( $, mw ) {
} )( jQuery, mediaWiki );
var jqgmap = []; for ( var mapIndex in jqgmap ) {
This is VERY bad JavaScript coding practice. Please use $.each().
$('<div class="jqgmap_code" id="jqgmap_code' + this.Idx + '">'+ '<input type="checkbox"></input>' + mw.msg( 'jqgmap-show-code' )
'<input type="checkbox"></input>' + mw.msg( 'jqgmap-show-code' )
'<div class="jqgmap_preview"></div>' + '<div class="jqgmap_preview"></div>' + '</div>')
I should really start poking people about this one. `"<div>" . wfMsg( 'foo' ) . "</div>"` is bad in PHP code, and it's just as bad inside JS. You should be creating your html with NO + concatenation, and then using a .find() and .text() to insert things where they belong. That, or use multiple $() calls with .append() to create the full structure. Likewise you shouldn;t be inserting this.Idx that way into the attribute. It should be added with something like .attr( "jqgmap_code" + this.Idx );