[jQuery] Evaluating <script> elements

[jQuery] Evaluating <script> elements

Hi,
I believe there is a flaw in the way scripts are evaluated in the
'load' function.
This piece of code is my concern:
// Execute all the scripts inside of the newly-injected HTML
$("script", self).each(function(){
if ( this.src )
$.getScript( this.src );
else
eval.call( window, this.text || this.textContent ||
this.innerHTML || "" );
});
It doesn't load scripts (with src attribute) in expected way that
a browser would. Take the following snippet of html:
<script src="fancy-plugin.js"></script>
<script>
$('#foo').FancyPlugin();
</script>
Loaded in a normal html page in the normal way in a browser,
fancy-plugin.js would be loaded and ready, before the second
script is executed.
If loaded via 'load', then 'fancy-plugin.js' is loaded asyncronously,
and may not be evaluated before the second literal script is.
You see the problem?
The solution is to wait for each script to load before executing the
next. Here's my solution as a plugin:
(I was thinking it should probably be added to the core as a reusable
function, and called from within 'load', replacing the snippet above)
$.fn.eval = function(callback) {
    var self = this;
    var exec = function(scripts) {
        console.log(scripts);
        for (var i=0; i < scripts.length; i++) {
            if (scripts[i].src) {
                $.getScript(scripts[i].src, function() {
                    if (i+1 < scripts.length) {
                        // Continue executing remaining of scripts
                        exec(scripts.gt(i));
                    } else if (typeof callback == 'function') {
                        // This was last script, so call the callback fn
                        callback.call(self);
                    }
                });
                // Remaining scripts will be eval'd after this script is loaded
                return;
            } else {
                // Evaluate the content as the script
                eval.call(window, scripts[i].text || scripts[i].textContent ||
scripts[i].innerHTML || "");
            }
        }
        if (typeof callback == 'function') callback.call(self);
    }
    exec($(this).filter('script'));
    return this;
};
BTW: this was tested with jQuery rev 384.
Cheers
- Mark Gibson
_______________________________________________
jQuery mailing list
discuss@jquery.com
http://jquery.com/discuss/