Merge with lab-port popcorn-port
authorhamidouk
Wed, 21 Dec 2011 16:06:41 +0100
branchpopcorn-port
changeset 505 b1e442d9a1bc
parent 494 cb88c0c8ddfa (current diff)
parent 504 02daece5dfda (diff)
child 508 00054959ee92
child 517 97599ff43072
Merge with lab-port
src/js/libs/popcorn.mediafragment.js
--- a/sbin/build/client.xml	Wed Dec 21 10:56:09 2011 +0100
+++ b/sbin/build/client.xml	Wed Dec 21 16:06:41 2011 +0100
@@ -50,7 +50,7 @@
 			<filelist dir="../../src/js/" files="header.js" />
 			
       <filelist dir="../../src/js/libs" 
-                files="popcorn.js popcorn.youtube.js popcorn.code.js popcorn.jwplayer.js popcorn.mediafragment.js jwplayer.js mustache.js raphael.js"/> 
+                files="lab.js mustache.js"/> 
      
       <!-- required file before everything else -->
 	    <filelist dir="../../src/js" files="main.js" />
--- a/src/js/init.js	Wed Dec 21 10:56:09 2011 +0100
+++ b/src/js/init.js	Wed Dec 21 16:06:41 2011 +0100
@@ -30,7 +30,7 @@
            if (options.hasOwnProperty("height"))
              IriSP.jQuery("#" + containerDiv).css("height", options.height);
 
-           pop = Popcorn("#" + tmpId).mediafragment({start : 0});
+           pop = Popcorn("#" + tmpId);
         break;
         
       case "jwplayer":
@@ -69,7 +69,7 @@
           // Popcorn.youtube wants us to specify the size of the player in the style attribute of its container div.
           IriSP.jQuery("#" + containerDiv).attr("style", str);
           
-          pop = Popcorn.youtube("#" + containerDiv, opts.video, opts).mediafragment({start : 0});
+          pop = Popcorn.youtube("#" + containerDiv, opts.video, opts);
         break;
         
       default:
--- a/src/js/layout.js	Wed Dec 21 10:56:09 2011 +0100
+++ b/src/js/layout.js	Wed Dec 21 16:06:41 2011 +0100
@@ -51,8 +51,8 @@
     if (typeof(stem) === "undefined")
        stem = "";
 
-    var newDiv = Popcorn.guid(this._div + "_widget_" + stem + "_");
-    var spacerDiv = Popcorn.guid("LdtPlayer_spacer_");
+    var newDiv = IriSP.guid(this._div + "_widget_" + stem + "_");
+    var spacerDiv = IriSP.guid("LdtPlayer_spacer_");
     this._widgets.push(newDiv);
 
     var divTempl = "<div id='{{id}}' style='width: {{width}}px; position: relative;'></div";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/js/libs/lab.js	Wed Dec 21 16:06:41 2011 +0100
@@ -0,0 +1,514 @@
+/*! LAB.js (LABjs :: Loading And Blocking JavaScript)
+    v2.0.3 (c) Kyle Simpson
+    MIT License
+*/
+
+(function(global){
+	var _$LAB = global.$LAB,
+	
+		// constants for the valid keys of the options object
+		_UseLocalXHR = "UseLocalXHR",
+		_AlwaysPreserveOrder = "AlwaysPreserveOrder",
+		_AllowDuplicates = "AllowDuplicates",
+		_CacheBust = "CacheBust",
+		/*!START_DEBUG*/_Debug = "Debug",/*!END_DEBUG*/
+		_BasePath = "BasePath",
+		
+		// stateless variables used across all $LAB instances
+		root_page = /^[^?#]*\//.exec(location.href)[0],
+		root_domain = /^\w+\:\/\/\/?[^\/]+/.exec(root_page)[0],
+		append_to = document.head || document.getElementsByTagName("head"),
+		
+		// inferences... ick, but still necessary
+		opera_or_gecko = (global.opera && Object.prototype.toString.call(global.opera) == "[object Opera]") || ("MozAppearance" in document.documentElement.style),
+
+/*!START_DEBUG*/
+		// console.log() and console.error() wrappers
+		log_msg = function(){}, 
+		log_error = log_msg,
+/*!END_DEBUG*/
+		
+		// feature sniffs (yay!)
+		test_script_elem = document.createElement("script"),
+		explicit_preloading = typeof test_script_elem.preload == "boolean", // http://wiki.whatwg.org/wiki/Script_Execution_Control#Proposal_1_.28Nicholas_Zakas.29
+		real_preloading = explicit_preloading || (test_script_elem.readyState && test_script_elem.readyState == "uninitialized"), // will a script preload with `src` set before DOM append?
+		script_ordered_async = !real_preloading && test_script_elem.async === true, // http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
+		
+		// XHR preloading (same-domain) and cache-preloading (remote-domain) are the fallbacks (for some browsers)
+		xhr_or_cache_preloading = !real_preloading && !script_ordered_async && !opera_or_gecko
+	;
+
+/*!START_DEBUG*/
+	// define console wrapper functions if applicable
+	if (global.console && global.console.log) {
+		if (!global.console.error) global.console.error = global.console.log;
+		log_msg = function(msg) { global.console.log(msg); };
+		log_error = function(msg,err) { global.console.error(msg,err); };
+	}
+/*!END_DEBUG*/
+
+	// test for function
+	function is_func(func) { return Object.prototype.toString.call(func) == "[object Function]"; }
+
+	// test for array
+	function is_array(arr) { return Object.prototype.toString.call(arr) == "[object Array]"; }
+
+	// make script URL absolute/canonical
+	function canonical_uri(src,base_path) {
+		var absolute_regex = /^\w+\:\/\//;
+		
+		// is `src` is protocol-relative (begins with // or ///), prepend protocol
+		if (/^\/\/\/?/.test(src)) {
+			src = location.protocol + src;
+		}
+		// is `src` page-relative? (not an absolute URL, and not a domain-relative path, beginning with /)
+		else if (!absolute_regex.test(src) && src.charAt(0) != "/") {
+			// prepend `base_path`, if any
+			src = (base_path || "") + src;
+		}
+		// make sure to return `src` as absolute
+		return absolute_regex.test(src) ? src : ((src.charAt(0) == "/" ? root_domain : root_page) + src);
+	}
+
+	// merge `source` into `target`
+	function merge_objs(source,target) {
+		for (var k in source) { if (source.hasOwnProperty(k)) {
+			target[k] = source[k]; // TODO: does this need to be recursive for our purposes?
+		}}
+		return target;
+	}
+
+	// does the chain group have any ready-to-execute scripts?
+	function check_chain_group_scripts_ready(chain_group) {
+		var any_scripts_ready = false;
+		for (var i=0; i<chain_group.scripts.length; i++) {
+			if (chain_group.scripts[i].ready && chain_group.scripts[i].exec_trigger) {
+				any_scripts_ready = true;
+				chain_group.scripts[i].exec_trigger();
+				chain_group.scripts[i].exec_trigger = null;
+			}
+		}
+		return any_scripts_ready;
+	}
+
+	// creates a script load listener
+	function create_script_load_listener(elem,registry_item,flag,onload) {
+		elem.onload = elem.onreadystatechange = function() {
+			if ((elem.readyState && elem.readyState != "complete" && elem.readyState != "loaded") || registry_item[flag]) return;
+			elem.onload = elem.onreadystatechange = null;
+			onload();
+		};
+	}
+
+	// script executed handler
+	function script_executed(registry_item) {
+		registry_item.ready = registry_item.finished = true;
+		for (var i=0; i<registry_item.finished_listeners.length; i++) {
+			registry_item.finished_listeners[i]();
+		}
+		registry_item.ready_listeners = [];
+		registry_item.finished_listeners = [];
+	}
+
+	// make the request for a scriptha
+	function request_script(chain_opts,script_obj,registry_item,onload,preload_this_script) {
+		// setTimeout() "yielding" prevents some weird race/crash conditions in older browsers
+		setTimeout(function(){
+			var script, src = script_obj.real_src, xhr;
+			
+			// don't proceed until `append_to` is ready to append to
+			if ("item" in append_to) { // check if `append_to` ref is still a live node list
+				if (!append_to[0]) { // `append_to` node not yet ready
+					// try again in a little bit -- note: will re-call the anonymous function in the outer setTimeout, not the parent `request_script()`
+					setTimeout(arguments.callee,25);
+					return;
+				}
+				// reassign from live node list ref to pure node ref -- avoids nasty IE bug where changes to DOM invalidate live node lists
+				append_to = append_to[0];
+			}
+			script = document.createElement("script");
+			if (script_obj.type) script.type = script_obj.type;
+			if (script_obj.charset) script.charset = script_obj.charset;
+			
+			// should preloading be used for this script?
+			if (preload_this_script) {
+				// real script preloading?
+				if (real_preloading) {
+					/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload: "+src);/*!END_DEBUG*/
+					registry_item.elem = script;
+					if (explicit_preloading) { // explicit preloading (aka, Zakas' proposal)
+						script.preload = true;
+						script.onpreload = onload;
+					}
+					else {
+						script.onreadystatechange = function(){
+							if (script.readyState == "loaded") onload();
+						};
+					}
+					script.src = src;
+					// NOTE: no append to DOM yet, appending will happen when ready to execute
+				}
+				// same-domain and XHR allowed? use XHR preloading
+				else if (preload_this_script && src.indexOf(root_domain) == 0 && chain_opts[_UseLocalXHR]) {
+					xhr = new XMLHttpRequest(); // note: IE never uses XHR (it supports true preloading), so no more need for ActiveXObject fallback for IE <= 7
+					/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (xhr): "+src);/*!END_DEBUG*/
+					xhr.onreadystatechange = function() {
+						if (xhr.readyState == 4) {
+							xhr.onreadystatechange = function(){}; // fix a memory leak in IE
+							registry_item.text = xhr.responseText + "\n//@ sourceURL=" + src; // http://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
+							onload();
+						}
+					};
+					xhr.open("GET",src);
+					xhr.send();
+				}
+				// as a last resort, use cache-preloading
+				else {
+					/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script preload (cache): "+src);/*!END_DEBUG*/
+					script.type = "text/cache-script";
+					create_script_load_listener(script,registry_item,"ready",function() {
+						append_to.removeChild(script);
+						onload();
+					});
+					script.src = src;
+					append_to.insertBefore(script,append_to.firstChild);
+				}
+			}
+			// use async=false for ordered async? parallel-load-serial-execute http://wiki.whatwg.org/wiki/Dynamic_Script_Execution_Order
+			else if (script_ordered_async) {
+				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load (ordered async): "+src);/*!END_DEBUG*/
+				script.async = false;
+				create_script_load_listener(script,registry_item,"finished",onload);
+				script.src = src;
+				append_to.insertBefore(script,append_to.firstChild);
+			}
+			// otherwise, just a normal script element
+			else {
+				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("start script load: "+src);/*!END_DEBUG*/
+				create_script_load_listener(script,registry_item,"finished",onload);
+				script.src = src;
+				append_to.insertBefore(script,append_to.firstChild);
+			}
+		},0);
+	}
+		
+	// create a clean instance of $LAB
+	function create_sandbox() {
+		var global_defaults = {},
+			can_use_preloading = real_preloading || xhr_or_cache_preloading,
+			queue = [],
+			registry = {},
+			instanceAPI
+		;
+		
+		// global defaults
+		global_defaults[_UseLocalXHR] = true;
+		global_defaults[_AlwaysPreserveOrder] = false;
+		global_defaults[_AllowDuplicates] = false;
+		global_defaults[_CacheBust] = false;
+		/*!START_DEBUG*/global_defaults[_Debug] = false;/*!END_DEBUG*/
+		global_defaults[_BasePath] = "";
+
+		// execute a script that has been preloaded already
+		function execute_preloaded_script(chain_opts,script_obj,registry_item) {
+			var script;
+			
+			function preload_execute_finished() {
+				if (script != null) { // make sure this only ever fires once
+					script = null;
+					script_executed(registry_item);
+				}
+			}
+			
+			if (registry[script_obj.src].finished) return;
+			if (!chain_opts[_AllowDuplicates]) registry[script_obj.src].finished = true;
+			
+			script = registry_item.elem || document.createElement("script");
+			if (script_obj.type) script.type = script_obj.type;
+			if (script_obj.charset) script.charset = script_obj.charset;
+			create_script_load_listener(script,registry_item,"finished",preload_execute_finished);
+			
+			// script elem was real-preloaded
+			if (registry_item.elem) {
+				registry_item.elem = null;
+			}
+			// script was XHR preloaded
+			else if (registry_item.text) {
+				script.onload = script.onreadystatechange = null;	// script injection doesn't fire these events
+				script.text = registry_item.text;
+			}
+			// script was cache-preloaded
+			else {
+				script.src = script_obj.real_src;
+			}
+			append_to.insertBefore(script,append_to.firstChild);
+
+			// manually fire execution callback for injected scripts, since events don't fire
+			if (registry_item.text) {
+				preload_execute_finished();
+			}
+		}
+	
+		// process the script request setup
+		function do_script(chain_opts,script_obj,chain_group,preload_this_script) {
+			var registry_item,
+				registry_items,
+				ready_cb = function(){ script_obj.ready_cb(script_obj,function(){ execute_preloaded_script(chain_opts,script_obj,registry_item); }); },
+				finished_cb = function(){ script_obj.finished_cb(script_obj,chain_group); }
+			;
+			
+			script_obj.src = canonical_uri(script_obj.src,chain_opts[_BasePath]);
+			script_obj.real_src = script_obj.src + 
+				// append cache-bust param to URL?
+				(chain_opts[_CacheBust] ? ((/\?.*$/.test(script_obj.src) ? "&_" : "?_") + ~~(Math.random()*1E9) + "=") : "")
+			;
+			
+			if (!registry[script_obj.src]) registry[script_obj.src] = {items:[],finished:false};
+			registry_items = registry[script_obj.src].items;
+
+			// allowing duplicates, or is this the first recorded load of this script?
+			if (chain_opts[_AllowDuplicates] || registry_items.length == 0) {
+				registry_item = registry_items[registry_items.length] = {
+					ready:false,
+					finished:false,
+					ready_listeners:[ready_cb],
+					finished_listeners:[finished_cb]
+				};
+
+				request_script(chain_opts,script_obj,registry_item,
+					// which callback type to pass?
+					(
+					 	(preload_this_script) ? // depends on script-preloading
+						function(){
+							registry_item.ready = true;
+							for (var i=0; i<registry_item.ready_listeners.length; i++) {
+								registry_item.ready_listeners[i]();
+							}
+							registry_item.ready_listeners = [];
+						} :
+						function(){ script_executed(registry_item); }
+					),
+					// signal if script-preloading should be used or not
+					preload_this_script
+				);
+			}
+			else {
+				registry_item = registry_items[0];
+				if (registry_item.finished) {
+					finished_cb();
+				}
+				else {
+					registry_item.finished_listeners.push(finished_cb);
+				}
+			}
+		}
+
+		// creates a closure for each separate chain spawned from this $LAB instance, to keep state cleanly separated between chains
+		function create_chain() {
+			var chainedAPI,
+				chain_opts = merge_objs(global_defaults,{}),
+				chain = [],
+				exec_cursor = 0,
+				scripts_currently_loading = false,
+				group
+			;
+			
+			// called when a script has finished preloading
+			function chain_script_ready(script_obj,exec_trigger) {
+				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script preload finished: "+script_obj.real_src);/*!END_DEBUG*/
+				script_obj.ready = true;
+				script_obj.exec_trigger = exec_trigger;
+				advance_exec_cursor(); // will only check for 'ready' scripts to be executed
+			}
+
+			// called when a script has finished executing
+			function chain_script_executed(script_obj,chain_group) {
+				/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("script execution finished: "+script_obj.real_src);/*!END_DEBUG*/
+				script_obj.ready = script_obj.finished = true;
+				script_obj.exec_trigger = null;
+				// check if chain group is all finished
+				for (var i=0; i<chain_group.scripts.length; i++) {
+					if (!chain_group.scripts[i].finished) return;
+				}
+				// chain_group is all finished if we get this far
+				chain_group.finished = true;
+				advance_exec_cursor();
+			}
+
+			// main driver for executing each part of the chain
+			function advance_exec_cursor() {
+				while (exec_cursor < chain.length) {
+					if (is_func(chain[exec_cursor])) {
+						/*!START_DEBUG*/if (chain_opts[_Debug]) log_msg("$LAB.wait() executing: "+chain[exec_cursor]);/*!END_DEBUG*/
+						try { chain[exec_cursor++](); } catch (err) {
+							/*!START_DEBUG*/if (chain_opts[_Debug]) log_error("$LAB.wait() error caught: ",err);/*!END_DEBUG*/
+						}
+						continue;
+					}
+					else if (!chain[exec_cursor].finished) {
+						if (check_chain_group_scripts_ready(chain[exec_cursor])) continue;
+						break;
+					}
+					exec_cursor++;
+				}
+				// we've reached the end of the chain (so far)
+				if (exec_cursor == chain.length) {
+					scripts_currently_loading = false;
+					group = false;
+				}
+			}
+			
+			// setup next chain script group
+			function init_script_chain_group() {
+				if (!group || !group.scripts) {
+					chain.push(group = {scripts:[],finished:true});
+				}
+			}
+
+			// API for $LAB chains
+			chainedAPI = {
+				// start loading one or more scripts
+				script:function(){
+					for (var i=0; i<arguments.length; i++) {
+						(function(script_obj,script_list){
+							var splice_args;
+							
+							if (!is_array(script_obj)) {
+								script_list = [script_obj];
+							}
+							for (var j=0; j<script_list.length; j++) {
+								init_script_chain_group();
+								script_obj = script_list[j];
+								
+								if (is_func(script_obj)) script_obj = script_obj();
+								if (!script_obj) continue;
+								if (is_array(script_obj)) {
+									// set up an array of arguments to pass to splice()
+									splice_args = [].slice.call(script_obj); // first include the actual array elements we want to splice in
+									splice_args.unshift(j,1); // next, put the `index` and `howMany` parameters onto the beginning of the splice-arguments array
+									[].splice.apply(script_list,splice_args); // use the splice-arguments array as arguments for splice()
+									j--; // adjust `j` to account for the loop's subsequent `j++`, so that the next loop iteration uses the same `j` index value
+									continue;
+								}
+								if (typeof script_obj == "string") script_obj = {src:script_obj};
+								script_obj = merge_objs(script_obj,{
+									ready:false,
+									ready_cb:chain_script_ready,
+									finished:false,
+									finished_cb:chain_script_executed
+								});
+								group.finished = false;
+								group.scripts.push(script_obj);
+								
+								do_script(chain_opts,script_obj,group,(can_use_preloading && scripts_currently_loading));
+								scripts_currently_loading = true;
+								
+								if (chain_opts[_AlwaysPreserveOrder]) chainedAPI.wait();
+							}
+						})(arguments[i],arguments[i]);
+					}
+					return chainedAPI;
+				},
+				// force LABjs to pause in execution at this point in the chain, until the execution thus far finishes, before proceeding
+				wait:function(){
+					if (arguments.length > 0) {
+						for (var i=0; i<arguments.length; i++) {
+							chain.push(arguments[i]);
+						}
+						group = chain[chain.length-1];
+					}
+					else group = false;
+					
+					advance_exec_cursor();
+					
+					return chainedAPI;
+				}
+			};
+
+			// the first chain link API (includes `setOptions` only this first time)
+			return {
+				script:chainedAPI.script, 
+				wait:chainedAPI.wait, 
+				setOptions:function(opts){
+					merge_objs(opts,chain_opts);
+					return chainedAPI;
+				}
+			};
+		}
+
+		// API for each initial $LAB instance (before chaining starts)
+		instanceAPI = {
+			// main API functions
+			setGlobalDefaults:function(opts){
+				merge_objs(opts,global_defaults);
+				return instanceAPI;
+			},
+			setOptions:function(){
+				return create_chain().setOptions.apply(null,arguments);
+			},
+			script:function(){
+				return create_chain().script.apply(null,arguments);
+			},
+			wait:function(){
+				return create_chain().wait.apply(null,arguments);
+			},
+
+			// built-in queuing for $LAB `script()` and `wait()` calls
+			// useful for building up a chain programmatically across various script locations, and simulating
+			// execution of the chain
+			queueScript:function(){
+				queue[queue.length] = {type:"script", args:[].slice.call(arguments)};
+				return instanceAPI;
+			},
+			queueWait:function(){
+				queue[queue.length] = {type:"wait", args:[].slice.call(arguments)};
+				return instanceAPI;
+			},
+			runQueue:function(){
+				var $L = instanceAPI, len=queue.length, i=len, val;
+				for (;--i>=0;) {
+					val = queue.shift();
+					$L = $L[val.type].apply(null,val.args);
+				}
+				return $L;
+			},
+
+			// rollback `[global].$LAB` to what it was before this file was loaded, the return this current instance of $LAB
+			noConflict:function(){
+				global.$LAB = _$LAB;
+				return instanceAPI;
+			},
+
+			// create another clean instance of $LAB
+			sandbox:function(){
+				return create_sandbox();
+			}
+		};
+
+		return instanceAPI;
+	}
+
+	// create the main instance of $LAB
+	global.$LAB = create_sandbox();
+
+
+	/* The following "hack" was suggested by Andrea Giammarchi and adapted from: http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html
+	   NOTE: this hack only operates in FF and then only in versions where document.readyState is not present (FF < 3.6?).
+	   
+	   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 
+	   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 
+	   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. 
+	   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 
+	   fixed by this hack, and should therefore **not** be lazy-loaded by script loader tools such as LABjs.
+	*/ 
+	(function(addEvent,domLoaded,handler){
+		if (document.readyState == null && document[addEvent]){
+			document.readyState = "loading";
+			document[addEvent](domLoaded,handler = function(){
+				document.removeEventListener(domLoaded,handler,false);
+				document.readyState = "complete";
+			},false);
+		}
+	})("addEventListener","DOMContentLoaded");
+
+})(this);
\ No newline at end of file
--- a/src/js/libs/popcorn.mediafragment.js	Wed Dec 21 10:56:09 2011 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-// PLUGIN: Mediafragment
-
-(function ( Popcorn ) {
-
-  /**
-   * Mediafragment popcorn plug-in
-   * Adds (limited) support for mediafragment requests
-   * to a popcorn video.
-   * @param {Object} options
-   *
-  **/
-    Popcorn.plugin( "mediafragment" , {
-
-      manifest: {
-        about: {
-          name: "Popcorn mediafragment plugin",
-          version: "0.1",
-          author: "Karim Hamidou",
-          website: "http://neyret.fr/~karim"
-        },
-        options: {
-        }
-      },
-
-    _setup: function( options ) {
-        var advanceTime = function() {
-              var url = window.location.href;
-
-              if ( url.split( "#" )[ 1 ] != null ) {
-                  pageoffset = url.split( "#" )[1];
-
-                  if ( pageoffset.substring( 2 ) != null ) {
-                    var offsettime = pageoffset.substring( 2 );
-                    this.currentTime( parseFloat( offsettime ) );
-                  }
-              }
-        }
-
-        var updateTime = function() {
-            var history = window.history;
-            if ( !history.pushState ) {
-              return false;
-            }
-            
-            splitArr = window.location.href.split( "#" )
-            history.replaceState( {}, "", splitArr[0] + "#t=" + this.currentTime().toFixed( 2 ) );
-        };
-
-        this.listen( "loadedmetadata", advanceTime );
-        this.listen( "pause", updateTime );
-        this.listen( "seeked", updateTime );
-    },
-
-    _teardown: function( options ) {
-      // FIXME: anything to implement here ?
-    }
-  });
-})( Popcorn );
--- a/src/js/main.js	Wed Dec 21 10:56:09 2011 +0100
+++ b/src/js/main.js	Wed Dec 21 16:06:41 2011 +0100
@@ -5,127 +5,68 @@
 	var __IriSP = IriSP; /* for backward compatibility */
 }
 
-/* crap code will be the first against the wall when the
-   revolution comes */
-IriSP.loadLibs = function( libs, customCssPath, metadata_url, callback ) {
-		// Localize jQuery variable
+IriSP.loadLibs = function( libs, config, metadata_url, callback ) {
+    // Localize jQuery variable
 		IriSP.jQuery = null;
-
-		/* FIXME : to refactor using popcorn.getscript ? */
-		/******** Load jQuery if not present *********/
-		if ( window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.2' ) {
-			
-			var script_tag = document.createElement( 'script' );
-			script_tag.setAttribute( "type", "text/javascript" );
-			script_tag.setAttribute( "src", libs.jQuery );
-			
-			script_tag.onload = scriptLibHandler;
-			script_tag.onreadystatechange = function () { // Same thing but for IE
-				if ( this.readyState == 'complete' || this.readyState == 'loaded' ) {
-					scriptLibHandler();					
-				}
-			};
-			
-			// Try to find the head, otherwise default to the documentElement
-			( document.getElementsByTagName("head")[0] || document.documentElement ).appendChild( script_tag );
-		} else {
-			// The jQuery version on the window is the one we want to use
-			 IriSP.jQuery = window.jQuery;
-			 scriptLibHandler();
-		}
+    var $L = $LAB.script(libs.jQuery).script(libs.swfObject)
+                .script(libs.jQueryUI)
+                                   
+    if (config.player.type === "jwplayer") {
+      // load our popcorn.js lookalike
+      $L = $L.script(libs.jwplayer);
+    } else {
+      // load the real popcorn
+      $L = $L.script(libs.popcorn).script(libs["popcorn.code"]);
+      if (config.player.type === "youtube") {
+        $L = $L.script(libs["popcorn.youtube"]);
+      } 
+      if (config.player.type === "vimeo")
+        $L = $L.script(libs["popcorn.vimeo"]);
+      
+      /* do nothing for html5 */
+    }       
+    
+    /* widget specific requirements */
+    for (var idx in config.gui.widgets) {
+      if (config.gui.widgets[idx].type === "PolemicWidget") {        
+        $L.script(libs.raphael);
+      }
+    }
+    
+    // same for modules
+    /*
+    for (var idx in config.modules) {
+      if (config.modules[idx].type === "PolemicWidget")
+        $L.script(libs.raphaelJs);
+    }
+    */
 
-		/******** Called once jQuery has loaded ******/
-		function scriptLibHandler() {
-			
-			var script_jqUi_tooltip = document.createElement( 'script' );
-			script_jqUi_tooltip.setAttribute( "type", "text/javascript" );
-			script_jqUi_tooltip.setAttribute( "src", libs.jQueryToolTip );
-			script_jqUi_tooltip.onload = scriptLoadHandler;
-			script_jqUi_tooltip.onreadystatechange = function () { // Same thing but for IE
-				if ( this.readyState == 'complete' || this.readyState == 'loaded' ) {
-					scriptLoadHandler( "jquery.tools.min.js loded" );
-				}
-			};
-			
-			var script_swfObj = document.createElement('script');
-			script_swfObj.setAttribute( "type","text/javascript" );
-			script_swfObj.setAttribute( "src",libs.swfObject );
-			script_swfObj.onload = scriptLoadHandler;
-			script_swfObj.onreadystatechange = function () { // Same thing but for IE
-				if ( this.readyState == 'complete' || this.readyState == 'loaded' ) {
-					scriptLoadHandler( "swfobject.js loded" );
-				}
-			};
-		
-			var script_jqUi = document.createElement( 'script' );
-			script_jqUi.setAttribute( "type","text/javascript" );
-			script_jqUi.setAttribute( "src",libs.jQueryUI );
-			script_jqUi.onload = scriptLoadHandler;
-			script_jqUi.onreadystatechange = function () { // Same thing but for IE
-				if ( this.readyState == 'complete' || this.readyState == 'loaded' ) {
-					scriptLoadHandler( "jquery-ui.min.js loded" );
-				}
-			};
-		
-
-			( document.getElementsByTagName("head")[0] || document.documentElement ).appendChild( script_jqUi_tooltip);
-			( document.getElementsByTagName("head")[0] || document.documentElement ).appendChild( script_jqUi );
-			( document.getElementsByTagName("head")[0] || document.documentElement ).appendChild( script_swfObj );
-			
-
-		};
-
-		/******** Called once all lib are loaded ******/
-		var loadLib = 0;
-		/* FIXME : ugly */
-		function scriptLoadHandler( Mylib ) {
-			//alert(Mylib);
-			loadLib +=1;
-			if( loadLib===3 ) { 
-				main(); 			  
-			}
-		};
-
-		/******** Our main function ********/
-		function main() { 
-			
-
-			//  Make our own IriSP.jQuery and restore window.jQuery if there was one. 
-			IriSP.jQuery = window.jQuery.noConflict( true );
-			// Call our Jquery
-			IriSP.jQuery( document ).ready( function($) { 
-				
-				/******* Load CSS *******/
-				var css_link_jquery = IriSP.jQuery( "<link>", { 
-					rel: "stylesheet", 
-					type: "text/css", 
-					href: libs.cssjQueryUI,
-					'class': "dynamic_css"
-				} );
-				var css_link_custom = IriSP.jQuery( "<link>", { 
-					rel: "stylesheet", 
-					type: "text/css", 
-					href: customCssPath,
-					'class': "dynamic_css"
-				} );
-				
-				css_link_jquery.appendTo( 'head' );
-				css_link_custom.appendTo( 'head' );   
-
-				// to see dynamicly loaded css on IE
-				if ( $.browser.msie ) {
-					$( '.dynamic_css' ).clone().appendTo( 'head' );
-				}
-        
-        IriSP.setupDataLoader();
-        IriSP.__dataloader.get(metadata_url, 
-            function(data) {
-              /* save the data so that we could re-use it to
-                 configure the video
-              */
-              IriSP.__jsonMetadata = data;
-              callback.call(window) });
-      });
-    }
-};
-
+    $L.wait(function() {
+      IriSP.jQuery = window.jQuery.noConflict( true );
+      
+      var css_link_jquery = IriSP.jQuery( "<link>", { 
+        rel: "stylesheet", 
+        type: "text/css", 
+        href: libs.cssjQueryUI,
+        'class': "dynamic_css"
+      } );
+      var css_link_custom = IriSP.jQuery( "<link>", { 
+        rel: "stylesheet", 
+        type: "text/css", 
+        href: config.gui.css,
+        'class': "dynamic_css"
+      } );
+      
+      css_link_jquery.appendTo('head');
+      css_link_custom.appendTo('head');
+          
+      IriSP.setupDataLoader();
+      IriSP.__dataloader.get(metadata_url, 
+          function(data) {
+            /* save the data so that we could re-use it to
+               configure the video
+            */
+            IriSP.__jsonMetadata = data;
+            callback.call(window) });
+    });
+};
\ No newline at end of file
--- a/src/js/utils.js	Wed Dec 21 10:56:09 2011 +0100
+++ b/src/js/utils.js	Wed Dec 21 16:06:41 2011 +0100
@@ -122,7 +122,11 @@
                                  replace(/\)/g, '%29').replace(/\*/g, '%2A');  
 }  
 
-
+IriSP.__guidCounter = 0;
+IriSP.guid = function(prefix) {
+  IriSP.__guidCounter += 1;
+  return prefix + IriSP.__guidCounter;
+};
 /* for ie compatibility
 if (Object.prototype.__defineGetter__&&!Object.defineProperty) {
    Object.defineProperty=function(obj,prop,desc) {
--- a/test/integration/jwplayer-video.htm	Wed Dec 21 10:56:09 2011 +0100
+++ b/test/integration/jwplayer-video.htm	Wed Dec 21 16:06:41 2011 +0100
@@ -16,15 +16,11 @@
  <!-- START Integration  ###################################### -->
  <!-- SIMPLE PLAYER EXPERIMENTATION -->
 	<script type="text/javascript" src="../../build/LdtPlayer-release.js" type="text/javascript"></script> 
-	<script src="../../res/js/jquery.min.js" type="text/javascript"></script>
-	<script src="../../res/js/jquery.tools.min.js" type="text/javascript"></script>
-	<script src="../../res/js/jquery-ui.min.js" type="text/javascript"></script>
 	
 	<div id="video"></div>
 	<div id="LdtPlayer"></div>
 	
 	<script  type="text/javascript">
-		$(document).ready(function() {
 		var config = {
 						gui:{
 							width:650,
@@ -56,13 +52,11 @@
               duration: 50}
 					};
 		
-          IriSP.loadLibs(IriSP.lib, config.gui.css, "../test.json", function() { 	
+          IriSP.loadLibs(IriSP.lib, config, "../test.json", function() { 	
               var layoutManager = new IriSP.LayoutManager(config.gui.container);
               var pop = IriSP.configurePopcorn(layoutManager, config.player);
               
               var widgets = IriSP.configureWidgets(pop, layoutManager, config.gui); });
-    
-    });
 	</script>
 	
 	
--- a/test/integration/polemic-youtube.htm	Wed Dec 21 10:56:09 2011 +0100
+++ b/test/integration/polemic-youtube.htm	Wed Dec 21 16:06:41 2011 +0100
@@ -16,16 +16,11 @@
  <!-- START Integration  ###################################### -->
  <!-- SIMPLE PLAYER EXPERIMENTATION -->
 	<script type="text/javascript" src="../../build/LdtPlayer-release.js" type="text/javascript"></script> 
-	<script type="text/javascript" src="../../unittests/mockSerializer.js" type="text/javascript"></script> 
-	<script src="../../res/js/jquery.min.js" type="text/javascript"></script>
-	<script src="../../res/js/jquery.tools.min.js" type="text/javascript"></script>
-	<script src="../../res/js/jquery-ui.min.js" type="text/javascript"></script>
 	
 	<div id="video"></div>
 	<div id="LdtPlayer"></div>
 	
 	<script  type="text/javascript">
-		$(document).ready(function() {
 		var config = {						
 				gui:{
 						width:650,
@@ -109,14 +104,12 @@
             }
 		};
 		
-		IriSP.loadLibs(IriSP.lib, config.gui.css, "polemic_fr.json",
+		IriSP.loadLibs(IriSP.lib, config, "polemic_fr.json",
 			function() { 	
 							var layoutManager = new IriSP.LayoutManager(config.gui.container);
 							var pop = IriSP.configurePopcorn(layoutManager, config.player);
 							
 							var widgets = IriSP.configureWidgets(pop, layoutManager, config.gui); });
-		
-		});
 	</script>
 	
 	
--- a/test/integration/polemic.htm	Wed Dec 21 10:56:09 2011 +0100
+++ b/test/integration/polemic.htm	Wed Dec 21 16:06:41 2011 +0100
@@ -15,17 +15,12 @@
   
  <!-- START Integration  ###################################### -->
  <!-- SIMPLE PLAYER EXPERIMENTATION -->
-  <script type="text/javascript" src="../../build/LdtPlayer-release.js" type="text/javascript"></script> 
-  <script type="text/javascript" src="../../unittests/mockSerializer.js" type="text/javascript"></script> 
-  <script src="../../res/js/jquery.min.js" type="text/javascript"></script>
-  <script src="../../res/js/jquery.tools.min.js" type="text/javascript"></script>
-  <script src="../../res/js/jquery-ui.min.js" type="text/javascript"></script>
+  <script type="text/javascript" src="../../build/LdtPlayer-release.js" type="text/javascript"></script>   
   
   <div id="video"></div>
   <div id="LdtPlayer"></div>
   
   <script  type="text/javascript">
-    $(document).ready(function() {
     var config = {            
         gui:{
             width:650,
@@ -120,7 +115,7 @@
 
     };
     
-    IriSP.loadLibs(IriSP.lib, config.gui.css, "polemic_fr.json",
+    IriSP.loadLibs(IriSP.lib, config, "polemic_fr.json",
       function() {   
               var layoutManager = new IriSP.LayoutManager(config.gui.container);
               var pop = IriSP.configurePopcorn(layoutManager, config.player);
@@ -128,8 +123,6 @@
               var widgets = IriSP.configureWidgets(pop, layoutManager, config.gui); 
               var modules = IriSP.configureModules(pop, config.modules); 
       });
-    
-    });
   </script>
   
   
--- a/test/integration/radio.htm	Wed Dec 21 10:56:09 2011 +0100
+++ b/test/integration/radio.htm	Wed Dec 21 16:06:41 2011 +0100
@@ -16,16 +16,11 @@
  <!-- START Integration  ###################################### -->
  <!-- SIMPLE PLAYER EXPERIMENTATION -->
 	<script type="text/javascript" src="../../build/LdtPlayer-release.js" type="text/javascript"></script> 
-	<script type="text/javascript" src="../../unittests/mockSerializer.js" type="text/javascript"></script> 
-	<script src="../../res/js/jquery.min.js" type="text/javascript"></script>
-	<script src="../../res/js/jquery.tools.min.js" type="text/javascript"></script>
-	<script src="../../res/js/jquery-ui.min.js" type="text/javascript"></script>
 	
 	<div id="video"></div>
 	<div id="LdtPlayer"></div>
 	
 	<script  type="text/javascript">
-		$(document).ready(function() {
 		var config = {						
 				gui:{
 						width:650,
@@ -72,14 +67,12 @@
             }
 		};
 		
-		IriSP.loadLibs(IriSP.lib, config.gui.css, "../test.json",
+		IriSP.loadLibs(IriSP.lib, config, "../test.json",
 			function() { 	
 							var layoutManager = new IriSP.LayoutManager(config.gui.container);
 							var pop = IriSP.configurePopcorn(layoutManager, config.player);
 							
 							var widgets = IriSP.configureWidgets(pop, layoutManager, config.gui); });
-		
-		});
 	</script>
 	
 	
--- a/test/integration/youtube.htm	Wed Dec 21 10:56:09 2011 +0100
+++ b/test/integration/youtube.htm	Wed Dec 21 16:06:41 2011 +0100
@@ -16,13 +16,10 @@
  <!-- START Integration  ###################################### -->
  <!-- SIMPLE PLAYER EXPERIMENTATION -->
 	<script type="text/javascript" src="../../build/LdtPlayer-release.js"></script> 
-	<script src="../../res/js/jquery.min.js"></script>
-	<script src="../../res/js/jquery.tools.min.js"></script>
-	<script src="../../res/js/jquery-ui.min.js"></script>
+
 	<div id="LdtPlayer"></div>
 	
 	<script  type="text/javascript">
-		$(document).ready(function() {
 		var config = {						
 				gui:{
 						width:650,
@@ -43,15 +40,31 @@
 						  src:'../test.json',
 						  type:'json'}
 						},
-						
+
 						{type: "SegmentsWidget", // please note that type refers directly to the constructor of the widget.
 						 mode: "radio",
 						 metadata:{
 						  format:'cinelab',
 						  src:'../test.json',
+						  type:'json'},
+              requires: [{
+              type: "TooltipWidget",
+              width: 180,
+              heigh: 160,
+              metadata : {
+                type:'empty'
+              }
+             }]
+						},
+												
+						{type: "ArrowWidget", // please note that type refers directly to the constructor of the widget.
+						 mode: "radio",
+						 metadata:{
+						  format:'cinelab',
+						  src:'../test.json',
 						  type:'json'}
 						},
-						
+            
 						{type: "AnnotationsWidget", // please note that type refers directly to the constructor of the widget.
 						 mode: "radio",
 						 metadata:{
@@ -72,14 +85,12 @@
 				}
 		};
 		
-		IriSP.loadLibs(IriSP.lib, config.gui.css, '../test.json',
+		IriSP.loadLibs(IriSP.lib, config, '../test.json',
 			function() { 	
 							var layoutManager = new IriSP.LayoutManager(config.gui.container);
 							var pop = IriSP.configurePopcorn(layoutManager, config.player);
 							
 							var widgets = IriSP.configureWidgets(pop, layoutManager, config.gui); });
-		
-		});	
 	</script>
 <div id='Ldt-Root'>
 	<div id='Ldt-PlaceHolder'>
--- a/unittests/index.html	Wed Dec 21 10:56:09 2011 +0100
+++ b/unittests/index.html	Wed Dec 21 16:06:41 2011 +0100
@@ -13,6 +13,10 @@
 	<!-- -->	
 	
 	<script src="../build/LdtPlayer-release.js" type="text/javascript"></script>
+	<script src="../src/js/libs/popcorn.js" type="text/javascript"></script>
+	<script src="../src/js/libs/popcorn.code.js" type="text/javascript"></script>
+	<script src="../src/js/libs/popcorn.youtube.js" type="text/javascript"></script>
+	<script src="../src/js/libs/raphael.js" type="text/javascript"></script>
 	<link rel="stylesheet" href="../src/css/LdtPlayer.css"  type="text/css" media="screen" />
   
 	<script src="mockSerializer.js" type="text/javascript"></script>