src/js/libs/lab.js
author veltr
Mon, 23 Apr 2012 19:11:08 +0200
branchnew-model
changeset 875 43629caa77bc
parent 495 41a9f7b27952
permissions -rw-r--r--
Big refactoring of widget files + started migration of segmentwidget
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
495
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
     1
/*! LAB.js (LABjs :: Loading And Blocking JavaScript)
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
     2
    v2.0.3 (c) Kyle Simpson
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
     3
    MIT License
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
     4
*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
     5
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
     6
(function(global){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
     7
	var _$LAB = global.$LAB,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
     8
	
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
     9
		// constants for the valid keys of the options object
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    10
		_UseLocalXHR = "UseLocalXHR",
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    11
		_AlwaysPreserveOrder = "AlwaysPreserveOrder",
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    12
		_AllowDuplicates = "AllowDuplicates",
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    13
		_CacheBust = "CacheBust",
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    14
		/*!START_DEBUG*/_Debug = "Debug",/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    15
		_BasePath = "BasePath",
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    16
		
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    17
		// stateless variables used across all $LAB instances
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    18
		root_page = /^[^?#]*\//.exec(location.href)[0],
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    19
		root_domain = /^\w+\:\/\/\/?[^\/]+/.exec(root_page)[0],
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    20
		append_to = document.head || document.getElementsByTagName("head"),
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    21
		
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    22
		// inferences... ick, but still necessary
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    23
		opera_or_gecko = (global.opera && Object.prototype.toString.call(global.opera) == "[object Opera]") || ("MozAppearance" in document.documentElement.style),
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    24
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    25
/*!START_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    26
		// console.log() and console.error() wrappers
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    27
		log_msg = function(){}, 
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    28
		log_error = log_msg,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    29
/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    30
		
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    31
		// feature sniffs (yay!)
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    32
		test_script_elem = document.createElement("script"),
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    33
		explicit_preloading = typeof test_script_elem.preload == "boolean", // http://wiki.whatwg.org/wiki/Script_Execution_Control#Proposal_1_.28Nicholas_Zakas.29
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    34
		real_preloading = explicit_preloading || (test_script_elem.readyState && test_script_elem.readyState == "uninitialized"), // will a script preload with `src` set before DOM append?
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    35
		script_ordered_async = !real_preloading && test_script_elem.async === true, // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    36
		
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    37
		// XHR preloading (same-domain) and cache-preloading (remote-domain) are the fallbacks (for some browsers)
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    38
		xhr_or_cache_preloading = !real_preloading && !script_ordered_async && !opera_or_gecko
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    39
	;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    40
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    41
/*!START_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    42
	// define console wrapper functions if applicable
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    43
	if (global.console && global.console.log) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    44
		if (!global.console.error) global.console.error = global.console.log;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    45
		log_msg = function(msg) { global.console.log(msg); };
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    46
		log_error = function(msg,err) { global.console.error(msg,err); };
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    47
	}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    48
/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    49
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    50
	// test for function
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    51
	function is_func(func) { return Object.prototype.toString.call(func) == "[object Function]"; }
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    52
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    53
	// test for array
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    54
	function is_array(arr) { return Object.prototype.toString.call(arr) == "[object Array]"; }
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    55
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    56
	// make script URL absolute/canonical
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    57
	function canonical_uri(src,base_path) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    58
		var absolute_regex = /^\w+\:\/\//;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    59
		
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    60
		// is `src` is protocol-relative (begins with // or ///), prepend protocol
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    61
		if (/^\/\/\/?/.test(src)) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    62
			src = location.protocol + src;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    63
		}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    64
		// is `src` page-relative? (not an absolute URL, and not a domain-relative path, beginning with /)
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    65
		else if (!absolute_regex.test(src) && src.charAt(0) != "/") {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    66
			// prepend `base_path`, if any
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    67
			src = (base_path || "") + src;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    68
		}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    69
		// make sure to return `src` as absolute
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    70
		return absolute_regex.test(src) ? src : ((src.charAt(0) == "/" ? root_domain : root_page) + src);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    71
	}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    72
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    73
	// merge `source` into `target`
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    74
	function merge_objs(source,target) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    75
		for (var k in source) { if (source.hasOwnProperty(k)) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    76
			target[k] = source[k]; // TODO: does this need to be recursive for our purposes?
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    77
		}}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    78
		return target;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    79
	}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    80
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    81
	// does the chain group have any ready-to-execute scripts?
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    82
	function check_chain_group_scripts_ready(chain_group) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    83
		var any_scripts_ready = false;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    84
		for (var i=0; i<chain_group.scripts.length; i++) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    85
			if (chain_group.scripts[i].ready && chain_group.scripts[i].exec_trigger) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    86
				any_scripts_ready = true;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    87
				chain_group.scripts[i].exec_trigger();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    88
				chain_group.scripts[i].exec_trigger = null;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    89
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    90
		}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    91
		return any_scripts_ready;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    92
	}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    93
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    94
	// creates a script load listener
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    95
	function create_script_load_listener(elem,registry_item,flag,onload) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    96
		elem.onload = elem.onreadystatechange = function() {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    97
			if ((elem.readyState && elem.readyState != "complete" && elem.readyState != "loaded") || registry_item[flag]) return;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    98
			elem.onload = elem.onreadystatechange = null;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
    99
			onload();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   100
		};
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   101
	}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   102
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   103
	// script executed handler
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   104
	function script_executed(registry_item) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   105
		registry_item.ready = registry_item.finished = true;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   106
		for (var i=0; i<registry_item.finished_listeners.length; i++) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   107
			registry_item.finished_listeners[i]();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   108
		}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   109
		registry_item.ready_listeners = [];
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   110
		registry_item.finished_listeners = [];
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   111
	}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   112
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   113
	// make the request for a scriptha
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   114
	function request_script(chain_opts,script_obj,registry_item,onload,preload_this_script) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   115
		// setTimeout() "yielding" prevents some weird race/crash conditions in older browsers
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   116
		setTimeout(function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   117
			var script, src = script_obj.real_src, xhr;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   118
			
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   119
			// don't proceed until `append_to` is ready to append to
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   120
			if ("item" in append_to) { // check if `append_to` ref is still a live node list
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   121
				if (!append_to[0]) { // `append_to` node not yet ready
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   122
					// try again in a little bit -- note: will re-call the anonymous function in the outer setTimeout, not the parent `request_script()`
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   123
					setTimeout(arguments.callee,25);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   124
					return;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   125
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   126
				// reassign from live node list ref to pure node ref -- avoids nasty IE bug where changes to DOM invalidate live node lists
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   127
				append_to = append_to[0];
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   128
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   129
			script = document.createElement("script");
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   130
			if (script_obj.type) script.type = script_obj.type;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   131
			if (script_obj.charset) script.charset = script_obj.charset;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   132
			
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   133
			// should preloading be used for this script?
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   134
			if (preload_this_script) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   135
				// real script preloading?
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   136
				if (real_preloading) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   137
					/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload: "+src);/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   138
					registry_item.elem = script;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   139
					if (explicit_preloading) { // explicit preloading (aka, Zakas' proposal)
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   140
						script.preload = true;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   141
						script.onpreload = onload;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   142
					}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   143
					else {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   144
						script.onreadystatechange = function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   145
							if (script.readyState == "loaded") onload();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   146
						};
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   147
					}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   148
					script.src = src;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   149
					// NOTE: no append to DOM yet, appending will happen when ready to execute
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   150
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   151
				// same-domain and XHR allowed? use XHR preloading
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   152
				else if (preload_this_script && src.indexOf(root_domain) == 0 && chain_opts[_UseLocalXHR]) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   153
					xhr = new XMLHttpRequest(); // note: IE never uses XHR (it supports true preloading), so no more need for ActiveXObject fallback for IE <= 7
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   154
					/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (xhr): "+src);/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   155
					xhr.onreadystatechange = function() {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   156
						if (xhr.readyState == 4) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   157
							xhr.onreadystatechange = function(){}; // fix a memory leak in IE
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   158
							registry_item.text = xhr.responseText + "\n//@ sourceURL=" + src; // http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   159
							onload();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   160
						}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   161
					};
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   162
					xhr.open("GET",src);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   163
					xhr.send();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   164
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   165
				// as a last resort, use cache-preloading
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   166
				else {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   167
					/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (cache): "+src);/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   168
					script.type = "text/cache-script";
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   169
					create_script_load_listener(script,registry_item,"ready",function() {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   170
						append_to.removeChild(script);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   171
						onload();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   172
					});
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   173
					script.src = src;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   174
					append_to.insertBefore(script,append_to.firstChild);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   175
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   176
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   177
			// use async=false for ordered async? parallel-load-serial-execute http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   178
			else if (script_ordered_async) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   179
				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load (ordered async): "+src);/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   180
				script.async = false;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   181
				create_script_load_listener(script,registry_item,"finished",onload);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   182
				script.src = src;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   183
				append_to.insertBefore(script,append_to.firstChild);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   184
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   185
			// otherwise, just a normal script element
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   186
			else {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   187
				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load: "+src);/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   188
				create_script_load_listener(script,registry_item,"finished",onload);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   189
				script.src = src;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   190
				append_to.insertBefore(script,append_to.firstChild);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   191
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   192
		},0);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   193
	}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   194
		
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   195
	// create a clean instance of $LAB
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   196
	function create_sandbox() {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   197
		var global_defaults = {},
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   198
			can_use_preloading = real_preloading || xhr_or_cache_preloading,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   199
			queue = [],
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   200
			registry = {},
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   201
			instanceAPI
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   202
		;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   203
		
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   204
		// global defaults
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   205
		global_defaults[_UseLocalXHR] = true;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   206
		global_defaults[_AlwaysPreserveOrder] = false;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   207
		global_defaults[_AllowDuplicates] = false;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   208
		global_defaults[_CacheBust] = false;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   209
		/*!START_DEBUG*/global_defaults[_Debug] = false;/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   210
		global_defaults[_BasePath] = "";
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   211
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   212
		// execute a script that has been preloaded already
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   213
		function execute_preloaded_script(chain_opts,script_obj,registry_item) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   214
			var script;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   215
			
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   216
			function preload_execute_finished() {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   217
				if (script != null) { // make sure this only ever fires once
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   218
					script = null;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   219
					script_executed(registry_item);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   220
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   221
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   222
			
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   223
			if (registry[script_obj.src].finished) return;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   224
			if (!chain_opts[_AllowDuplicates]) registry[script_obj.src].finished = true;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   225
			
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   226
			script = registry_item.elem || document.createElement("script");
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   227
			if (script_obj.type) script.type = script_obj.type;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   228
			if (script_obj.charset) script.charset = script_obj.charset;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   229
			create_script_load_listener(script,registry_item,"finished",preload_execute_finished);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   230
			
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   231
			// script elem was real-preloaded
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   232
			if (registry_item.elem) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   233
				registry_item.elem = null;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   234
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   235
			// script was XHR preloaded
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   236
			else if (registry_item.text) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   237
				script.onload = script.onreadystatechange = null;	// script injection doesn't fire these events
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   238
				script.text = registry_item.text;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   239
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   240
			// script was cache-preloaded
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   241
			else {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   242
				script.src = script_obj.real_src;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   243
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   244
			append_to.insertBefore(script,append_to.firstChild);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   245
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   246
			// manually fire execution callback for injected scripts, since events don't fire
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   247
			if (registry_item.text) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   248
				preload_execute_finished();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   249
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   250
		}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   251
	
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   252
		// process the script request setup
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   253
		function do_script(chain_opts,script_obj,chain_group,preload_this_script) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   254
			var registry_item,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   255
				registry_items,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   256
				ready_cb = function(){ script_obj.ready_cb(script_obj,function(){ execute_preloaded_script(chain_opts,script_obj,registry_item); }); },
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   257
				finished_cb = function(){ script_obj.finished_cb(script_obj,chain_group); }
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   258
			;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   259
			
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   260
			script_obj.src = canonical_uri(script_obj.src,chain_opts[_BasePath]);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   261
			script_obj.real_src = script_obj.src + 
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   262
				// append cache-bust param to URL?
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   263
				(chain_opts[_CacheBust] ? ((/\?.*$/.test(script_obj.src) ? "&_" : "?_") + ~~(Math.random()*1E9) + "=") : "")
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   264
			;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   265
			
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   266
			if (!registry[script_obj.src]) registry[script_obj.src] = {items:[],finished:false};
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   267
			registry_items = registry[script_obj.src].items;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   268
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   269
			// allowing duplicates, or is this the first recorded load of this script?
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   270
			if (chain_opts[_AllowDuplicates] || registry_items.length == 0) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   271
				registry_item = registry_items[registry_items.length] = {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   272
					ready:false,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   273
					finished:false,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   274
					ready_listeners:[ready_cb],
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   275
					finished_listeners:[finished_cb]
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   276
				};
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   277
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   278
				request_script(chain_opts,script_obj,registry_item,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   279
					// which callback type to pass?
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   280
					(
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   281
					 	(preload_this_script) ? // depends on script-preloading
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   282
						function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   283
							registry_item.ready = true;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   284
							for (var i=0; i<registry_item.ready_listeners.length; i++) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   285
								registry_item.ready_listeners[i]();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   286
							}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   287
							registry_item.ready_listeners = [];
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   288
						} :
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   289
						function(){ script_executed(registry_item); }
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   290
					),
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   291
					// signal if script-preloading should be used or not
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   292
					preload_this_script
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   293
				);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   294
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   295
			else {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   296
				registry_item = registry_items[0];
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   297
				if (registry_item.finished) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   298
					finished_cb();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   299
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   300
				else {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   301
					registry_item.finished_listeners.push(finished_cb);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   302
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   303
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   304
		}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   305
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   306
		// creates a closure for each separate chain spawned from this $LAB instance, to keep state cleanly separated between chains
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   307
		function create_chain() {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   308
			var chainedAPI,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   309
				chain_opts = merge_objs(global_defaults,{}),
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   310
				chain = [],
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   311
				exec_cursor = 0,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   312
				scripts_currently_loading = false,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   313
				group
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   314
			;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   315
			
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   316
			// called when a script has finished preloading
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   317
			function chain_script_ready(script_obj,exec_trigger) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   318
				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script preload finished: "+script_obj.real_src);/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   319
				script_obj.ready = true;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   320
				script_obj.exec_trigger = exec_trigger;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   321
				advance_exec_cursor(); // will only check for 'ready' scripts to be executed
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   322
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   323
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   324
			// called when a script has finished executing
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   325
			function chain_script_executed(script_obj,chain_group) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   326
				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script execution finished: "+script_obj.real_src);/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   327
				script_obj.ready = script_obj.finished = true;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   328
				script_obj.exec_trigger = null;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   329
				// check if chain group is all finished
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   330
				for (var i=0; i<chain_group.scripts.length; i++) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   331
					if (!chain_group.scripts[i].finished) return;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   332
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   333
				// chain_group is all finished if we get this far
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   334
				chain_group.finished = true;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   335
				advance_exec_cursor();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   336
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   337
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   338
			// main driver for executing each part of the chain
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   339
			function advance_exec_cursor() {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   340
				while (exec_cursor < chain.length) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   341
					if (is_func(chain[exec_cursor])) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   342
						/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("$LAB.wait() executing: "+chain[exec_cursor]);/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   343
						try { chain[exec_cursor++](); } catch (err) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   344
							/*!START_DEBUG*/if (chain_opts[_Debug]) log_error("$LAB.wait() error caught: ",err);/*!END_DEBUG*/
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   345
						}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   346
						continue;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   347
					}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   348
					else if (!chain[exec_cursor].finished) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   349
						if (check_chain_group_scripts_ready(chain[exec_cursor])) continue;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   350
						break;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   351
					}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   352
					exec_cursor++;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   353
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   354
				// we've reached the end of the chain (so far)
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   355
				if (exec_cursor == chain.length) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   356
					scripts_currently_loading = false;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   357
					group = false;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   358
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   359
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   360
			
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   361
			// setup next chain script group
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   362
			function init_script_chain_group() {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   363
				if (!group || !group.scripts) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   364
					chain.push(group = {scripts:[],finished:true});
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   365
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   366
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   367
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   368
			// API for $LAB chains
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   369
			chainedAPI = {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   370
				// start loading one or more scripts
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   371
				script:function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   372
					for (var i=0; i<arguments.length; i++) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   373
						(function(script_obj,script_list){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   374
							var splice_args;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   375
							
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   376
							if (!is_array(script_obj)) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   377
								script_list = [script_obj];
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   378
							}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   379
							for (var j=0; j<script_list.length; j++) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   380
								init_script_chain_group();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   381
								script_obj = script_list[j];
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   382
								
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   383
								if (is_func(script_obj)) script_obj = script_obj();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   384
								if (!script_obj) continue;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   385
								if (is_array(script_obj)) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   386
									// set up an array of arguments to pass to splice()
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   387
									splice_args = [].slice.call(script_obj); // first include the actual array elements we want to splice in
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   388
									splice_args.unshift(j,1); // next, put the `index` and `howMany` parameters onto the beginning of the splice-arguments array
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   389
									[].splice.apply(script_list,splice_args); // use the splice-arguments array as arguments for splice()
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   390
									j--; // adjust `j` to account for the loop's subsequent `j++`, so that the next loop iteration uses the same `j` index value
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   391
									continue;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   392
								}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   393
								if (typeof script_obj == "string") script_obj = {src:script_obj};
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   394
								script_obj = merge_objs(script_obj,{
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   395
									ready:false,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   396
									ready_cb:chain_script_ready,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   397
									finished:false,
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   398
									finished_cb:chain_script_executed
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   399
								});
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   400
								group.finished = false;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   401
								group.scripts.push(script_obj);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   402
								
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   403
								do_script(chain_opts,script_obj,group,(can_use_preloading && scripts_currently_loading));
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   404
								scripts_currently_loading = true;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   405
								
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   406
								if (chain_opts[_AlwaysPreserveOrder]) chainedAPI.wait();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   407
							}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   408
						})(arguments[i],arguments[i]);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   409
					}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   410
					return chainedAPI;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   411
				},
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   412
				// force LABjs to pause in execution at this point in the chain, until the execution thus far finishes, before proceeding
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   413
				wait:function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   414
					if (arguments.length > 0) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   415
						for (var i=0; i<arguments.length; i++) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   416
							chain.push(arguments[i]);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   417
						}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   418
						group = chain[chain.length-1];
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   419
					}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   420
					else group = false;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   421
					
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   422
					advance_exec_cursor();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   423
					
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   424
					return chainedAPI;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   425
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   426
			};
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   427
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   428
			// the first chain link API (includes `setOptions` only this first time)
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   429
			return {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   430
				script:chainedAPI.script, 
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   431
				wait:chainedAPI.wait, 
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   432
				setOptions:function(opts){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   433
					merge_objs(opts,chain_opts);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   434
					return chainedAPI;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   435
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   436
			};
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   437
		}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   438
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   439
		// API for each initial $LAB instance (before chaining starts)
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   440
		instanceAPI = {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   441
			// main API functions
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   442
			setGlobalDefaults:function(opts){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   443
				merge_objs(opts,global_defaults);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   444
				return instanceAPI;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   445
			},
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   446
			setOptions:function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   447
				return create_chain().setOptions.apply(null,arguments);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   448
			},
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   449
			script:function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   450
				return create_chain().script.apply(null,arguments);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   451
			},
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   452
			wait:function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   453
				return create_chain().wait.apply(null,arguments);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   454
			},
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   455
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   456
			// built-in queuing for $LAB `script()` and `wait()` calls
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   457
			// useful for building up a chain programmatically across various script locations, and simulating
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   458
			// execution of the chain
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   459
			queueScript:function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   460
				queue[queue.length] = {type:"script", args:[].slice.call(arguments)};
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   461
				return instanceAPI;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   462
			},
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   463
			queueWait:function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   464
				queue[queue.length] = {type:"wait", args:[].slice.call(arguments)};
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   465
				return instanceAPI;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   466
			},
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   467
			runQueue:function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   468
				var $L = instanceAPI, len=queue.length, i=len, val;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   469
				for (;--i>=0;) {
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   470
					val = queue.shift();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   471
					$L = $L[val.type].apply(null,val.args);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   472
				}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   473
				return $L;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   474
			},
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   475
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   476
			// rollback `[global].$LAB` to what it was before this file was loaded, the return this current instance of $LAB
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   477
			noConflict:function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   478
				global.$LAB = _$LAB;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   479
				return instanceAPI;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   480
			},
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   481
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   482
			// create another clean instance of $LAB
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   483
			sandbox:function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   484
				return create_sandbox();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   485
			}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   486
		};
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   487
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   488
		return instanceAPI;
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   489
	}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   490
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   491
	// create the main instance of $LAB
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   492
	global.$LAB = create_sandbox();
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   493
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   494
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   495
	/* The following "hack" was suggested by Andrea Giammarchi and adapted from: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   496
	   NOTE: this hack only operates in FF and then only in versions where document.readyState is not present (FF < 3.6?).
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   497
	   
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   498
	   The hack essentially "patches" the **page** that LABjs is loaded onto so that it has a proper conforming document.readyState, so that if a script which does 
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   499
	   proper and safe dom-ready detection is loaded onto a page, after dom-ready has passed, it will still be able to detect this state, by inspecting the now hacked 
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   500
	   document.readyState property. The loaded script in question can then immediately trigger any queued code executions that were waiting for the DOM to be ready. 
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   501
	   For instance, jQuery 1.4+ has been patched to take advantage of document.readyState, which is enabled by this hack. But 1.3.2 and before are **not** safe or 
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   502
	   fixed by this hack, and should therefore **not** be lazy-loaded by script loader tools such as LABjs.
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   503
	*/ 
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   504
	(function(addEvent,domLoaded,handler){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   505
		if (document.readyState == null && document[addEvent]){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   506
			document.readyState = "loading";
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   507
			document[addEvent](domLoaded,handler = function(){
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   508
				document.removeEventListener(domLoaded,handler,false);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   509
				document.readyState = "complete";
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   510
			},false);
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   511
		}
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   512
	})("addEventListener","DOMContentLoaded");
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   513
41a9f7b27952 added lab js source file.
hamidouk
parents:
diff changeset
   514
})(this);