Skip to content
This repository was archived by the owner on Dec 31, 2022. It is now read-only.

Commit b09c6fd

Browse files
committed
LABjs.next: adding DEBUG mode functionality, and more/better code comments
1 parent 6134e2c commit b09c6fd

File tree

1 file changed

+54
-11
lines changed

1 file changed

+54
-11
lines changed

next/LAB.src.js

Lines changed: 54 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
_AlwaysPreserveOrder = "AlwaysPreserveOrder",
1212
_AllowDuplicates = "AllowDuplicates",
1313
_CacheBust = "CacheBust",
14+
/*!START_DEBUG*/_Debug = "Debug",/*!END_DEBUG*/
1415
_BasePath = "BasePath",
1516

1617
// stateless variables used across all $LAB instances
@@ -21,13 +22,28 @@
2122
// inferences... ick, but still necessary
2223
opera_or_gecko = (global.opera && Object.prototype.toString.call(global.opera) == "[object Opera]") || ("MozAppearance" in document.documentElement.style),
2324

25+
/*!START_DEBUG*/
26+
// console.log() and console.error() wrappers
27+
log_msg = function(){},
28+
log_error = log_msg,
29+
/*!END_DEBUG*/
30+
2431
// feature sniffs (yay!)
2532
test_script_elem = document.createElement("script"),
2633
script_ordered_async = test_script_elem.async === true, // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
2734
explicit_script_preload = typeof test_script_elem.preload == "boolean", // http://wiki.whatwg.org/wiki/Script_Execution_Control#Proposal_1_.28Nicholas_Zakas.29
2835
script_preload = explicit_script_preload || (test_script_elem.readyState && test_script_elem.readyState == "uninitialized") // will a script preload with `src` set before DOM append?
2936
;
30-
37+
38+
/*!START_DEBUG*/
39+
// define console wrapper functions if applicable
40+
if (global.console && global.console.log) {
41+
if (!global.console.error) global.console.error = global.console.log;
42+
log_msg = function(msg) { global.console.log(msg); };
43+
log_error = function(msg,err) { global.console.error(msg,err); };
44+
}
45+
/*!END_DEBUG*/
46+
3147
// test for function
3248
function is_func(func) { return Object.prototype.toString.call(func) == "[object Function]"; }
3349

@@ -113,29 +129,35 @@
113129

114130
// make the request for a script
115131
function request_script(chain_opts,script_obj,chain_group,registry_item,onload) {
132+
// setTimeout() "yielding" prevents some weird race/crash conditions in older browsers
116133
setTimeout(function(){
117-
if ("item" in append_to) { // check if ref is still a live node list
118-
if (!append_to[0]) { // append_to node not yet ready
119-
setTimeout(arguments.callee,25); // try again in a little bit -- note, will recall the anonymous function in the outer setTimeout, not the parent `request_script()`
134+
// don't proceed until `append_to` is ready to append to
135+
if ("item" in append_to) { // check if `append_to` ref is still a live node list
136+
if (!append_to[0]) { // `append_to` node not yet ready
137+
// try again in a little bit -- note: will re-call the anonymous function in the outer setTimeout, not the parent `request_script()`
138+
setTimeout(arguments.callee,25);
120139
return;
121140
}
122-
append_to = append_to[0]; // reassign from live node list ref to pure node ref -- avoids nasty IE bug where changes to DOM invalidate live node lists
141+
// reassign from live node list ref to pure node ref -- avoids nasty IE bug where changes to DOM invalidate live node lists
142+
append_to = append_to[0];
123143
}
124144
var script = document.createElement("script"),
125-
src = script_obj.real_src = script_obj.src + (chain_opts[_CacheBust] ? (/\?.*$/.test(script_obj.src) ? "&_" : "?_") + ~~(Math.random()*1E9) + "=" : "")
145+
src = script_obj.real_src
126146
;
127147
if (script_obj.type) script.type = script_obj.type;
128148
if (script_obj.charset) script.charset = script_obj.charset;
129149

130150
// no preloading, just normal script element
131151
if (!chain_group.preload && !script_ordered_async) {
152+
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load: "+src);/*!END_DEBUG*/
132153
if (script_ordered_async) script.async = false;
133154
create_script_load_listener(script,registry_item,"finished",onload);
134155
script.src = src;
135156
append_to.insertBefore(script,append_to.firstChild);
136157
}
137158
// real script preloading
138159
else if (script_preload) {
160+
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload: "+src);/*!END_DEBUG*/
139161
registry_item.elem = script;
140162
if (explicit_script_preload) { // Zakas style preloading (aka, explicit preloading)
141163
script.preload = true;
@@ -150,8 +172,9 @@
150172
script.src = src;
151173
// NOTE: no append to DOM yet, appending will happen when ready to execute
152174
}
153-
// use async=false parallel-load-serial-execute
175+
// use async=false parallel-load-serial-execute http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
154176
else if (script_ordered_async) {
177+
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load (ordered async): "+src);/*!END_DEBUG*/
155178
script.async = false;
156179
create_script_load_listener(script,registry_item,"finished",onload);
157180
script.src = src;
@@ -164,18 +187,20 @@
164187
global_defaults[_UseLocalXHR] = chain_opts[_UseLocalXHR] = false; // can't use XHR for some reason, so don't try anymore
165188
return request_script(chain_opts,registry_item,onload);
166189
}
190+
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (xhr): "+src);/*!END_DEBUG*/
167191
xhr.onreadystatechange = function() {
168-
if (xhr.readyState === 4) {
192+
if (xhr.readyState == 4) {
169193
xhr.onreadystatechange = function(){}; // fix a memory leak in IE
170194
registry_item.text = xhr.responseText + "\n//@ sourceURL=" + src; // http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
171195
onload();
172196
}
173197
};
174198
xhr.open("GET",src);
175-
xhr.send("");
199+
xhr.send();
176200
}
177201
// as a last resort, use cache-preloading
178202
else {
203+
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (cache): "+src);/*!END_DEBUG*/
179204
script.type = "text/cache-script";
180205
create_script_load_listener(script,registry_item,"ready",function() {
181206
append_to.removeChild(script);
@@ -195,12 +220,13 @@
195220
registry = {},
196221
instanceAPI
197222
;
198-
223+
199224
// global defaults
200225
global_defaults[_UseLocalXHR] = true;
201226
global_defaults[_AlwaysPreserveOrder] = false;
202227
global_defaults[_AllowDuplicates] = false;
203228
global_defaults[_CacheBust] = false;
229+
/*!START_DEBUG*/global_defaults[_Debug] = false;/*!END_DEBUG*/
204230
global_defaults[_BasePath] = "";
205231

206232
// execute a script that has been preloaded already
@@ -248,6 +274,9 @@
248274
;
249275

250276
script_obj.src = canonical_uri(script_obj.src,chain_opts[_BasePath]);
277+
script_obj.real_src = script_obj.src +
278+
// append cache-bust param to URL?
279+
(chain_opts[_CacheBust] ? (/\?.*$/.test(script_obj.src) ? "&_" : "?_") + ~~(Math.random()*1E9) + "=" : "");
251280

252281
if (!registry[script_obj.src]) registry[script_obj.src] = {items:[],finished:false};
253282
registry_items = registry[script_obj.src].items;
@@ -295,13 +324,15 @@
295324

296325
// called when a script has finished preloading
297326
function chain_script_ready(script_obj,chain_group,exec_trigger) {
327+
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script preload finished: "+script_obj.real_src);/*!END_DEBUG*/
298328
script_obj.ready = true;
299329
script_obj.exec_trigger = exec_trigger;
300330
advance_exec_cursor(); // will only check for 'ready' scripts to be executed
301331
}
302332

303333
// called when a script has finished executing
304334
function chain_script_executed(script_obj,chain_group) {
335+
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script execution finished: "+script_obj.real_src);/*!END_DEBUG*/
305336
script_obj.ready = script_obj.finished = true;
306337
script_obj.exec_trigger = null;
307338
if (check_chain_group_complete(chain_group)) {
@@ -313,7 +344,10 @@
313344
function advance_exec_cursor() {
314345
while (exec_cursor < chain.length) {
315346
if (is_func(chain[exec_cursor])) {
316-
try { chain[exec_cursor](); } catch (err) { } // TODO: wire up error logging
347+
/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("$LAB.wait() executing: "+chain[exec_cursor]);/*!END_DEBUG*/
348+
try { chain[exec_cursor](); } catch (err) {
349+
/*!START_DEBUG*/if (chain_opts[_Debug]) log_error("$LAB.wait() error caught: ",err);/*!END_DEBUG*/
350+
}
317351
}
318352
else if (!chain[exec_cursor].finished) {
319353
if (check_chain_group_scripts_ready(chain[exec_cursor])) continue;
@@ -335,7 +369,9 @@
335369
}
336370
}
337371

372+
// API for $LAB chains
338373
chainedAPI = {
374+
// start loading one or more scripts
339375
script:function(){
340376
init_script_chain_group();
341377
scripts_currently_loading = true;
@@ -374,6 +410,7 @@
374410
}
375411
return chainedAPI;
376412
},
413+
// force LABjs to pause in execution at this point in the chain, until the execution thus far finishes, before proceeding
377414
wait:function(){
378415
if (arguments.length > 0) {
379416
for (var i=0; i<arguments.length; i++) {
@@ -389,6 +426,7 @@
389426
}
390427
};
391428

429+
// the first chain link API (includes `setOptions` only this first time)
392430
return {
393431
script:chainedAPI.script,
394432
wait:chainedAPI.wait,
@@ -399,7 +437,9 @@
399437
};
400438
}
401439

440+
// API for each initial $LAB instance (before chaining starts)
402441
instanceAPI = {
442+
// main API functions
403443
setGlobalDefaults:function(opts){
404444
merge_objs(opts,global_defaults);
405445
return instanceAPI;
@@ -413,6 +453,7 @@
413453
wait:function(){
414454
return create_chain().wait.apply(null,arguments);
415455
},
456+
416457
// built-in queuing for $LAB `script()` and `wait()` calls
417458
// useful for building up a chain programmatically across various script locations, and simulating
418459
// execution of the chain
@@ -432,11 +473,13 @@
432473
}
433474
return $L;
434475
},
476+
435477
// rollback `[global].$LAB` to what it was before this file was loaded, the return this current instance of $LAB
436478
noConflict:function(){
437479
global.$LAB = _$LAB;
438480
return instanceAPI;
439481
},
482+
440483
// create another clean instance of $LAB
441484
sandbox:function(){
442485
return create_sandbox();

0 commit comments

Comments
 (0)