[Pkg-javascript-commits] [dojo] 11/19: Make sure that domReady(), when used as a function rather than a plugin, executes registered callbacks sequentially. This is how ready() is supposed to work, so it makes sense for domReady() to follow suit.

David Prévot taffit at moszumanska.debian.org
Sun Sep 14 16:23:09 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to annotated tag 1.8.7
in repository dojo.

commit 33e4435e30d59f339af3bcce6d84fbc0aa3bd6c6
Author: Bill Keese <bill at dojotoolkit.org>
Date:   Tue Nov 27 07:44:03 2012 +0000

    Make sure that domReady(), when used as a function rather than a plugin, executes registered callbacks sequentially.    This is how ready() is supposed to work, so it makes sense for domReady() to follow suit.
    
    Fixes #16389, refs #16386 on 1.8 branch.
    
    This is a combination of 3 commits:
    
    -----
    Make sure that domReady(), when used as a function rather than a plugin, executes registered callbacks sequentially.    This is how ready() is supposed to work, so it makes sense for domReady() to follow suit.
    
    Plus, it's needed to make ready() work as advertised, since ready() calls domReady() internally.  Note that it's still dodgy that there are two queues, one in dojo/ready and one in dojo/domReady.   However, since dojo/ready is essentially deprecated, that's probably not worth fixing.
    
    This fix is mainly a recursive guard, i.e. if f1() calls domReady(f2), f2() will be delayed until f1() completes.   However, it also addresses a concurrency issue:
    
    In Editor_mouse.html on chrome I noticed that DOH started running the tests while test_Editor.s dojo.ready() callback was still executing.   It was mainly because the ready(999, ...) call from DOH occurred while the test_Editor.html dojo.ready() callback was running.   Normally browsers don't run multiple threads but I guess this is an exception since DOH and test_Editor.html are in different frames.
    
    Also added a try/catch around each domReady() callback so that a failure in one callback won't affect other code, and won't get the guard variable stuck.
    
    Fixes #16389, refs #16386 !strict.
    
    git-svn-id: http://svn.dojotoolkit.org/src/dojo/trunk@30057 560b804f-0ae3-0310-86f3-f6aa0a117693
    (cherry picked from commit e41487e670984085567db9a30a0ef6150b8f6a12)
    
    -----
    
    Second try to get dojo/ready and dojo/domReady! to play nice together.   dojo/ready still needs to yield to any tasks registered via domReady(), but callbacks in the dojo/ready queue cannot be removed until they are ready to be run.   Fixes #16389 !strict.   Needed to add some hooks into the dojo/domReady code so that dojo/ready can yield to tasks in that queue, but they can be removed for 2.0.
    
    git-svn-id: http://svn.dojotoolkit.org/src/dojo/trunk@30282 560b804f-0ae3-0310-86f3-f6aa0a117693
    
    -----
    
    Get dojo/ready working on a non-browser environment again, so the builder works.   I'm unclear why dojo/ready is getting called at all in that case though.  Refs #16389, fixes #16557 !strict
    
    git-svn-id: http://svn.dojotoolkit.org/src/dojo/trunk@30322 560b804f-0ae3-0310-86f3-f6aa0a117693
    (cherry picked from commit 328a0a21c74a73e9cb1ade61ba025ccd6aa9f758)
---
 domReady.js | 65 ++++++++++++++++++++++++++++++++++++++++-----------------
 ready.js    | 69 +++++++++++++++++++++++++++++++++++--------------------------
 2 files changed, 86 insertions(+), 48 deletions(-)

diff --git a/domReady.js b/domReady.js
index 92505f4..207359a 100644
--- a/domReady.js
+++ b/domReady.js
@@ -3,24 +3,64 @@ define(['./has'], function(has){
 		doc = document,
 		readyStates = { 'loaded': 1, 'complete': 1 },
 		fixReadyState = typeof doc.readyState != "string",
-		ready = !!readyStates[doc.readyState];
+		ready = !!readyStates[doc.readyState],
+		readyQ = [],
+		recursiveGuard;
+
+	function domReady(callback){
+		// summary:
+		//		Plugin to delay require()/define() callback from firing until the DOM has finished loading.
+		readyQ.push(callback);
+		if(ready){ processQ(); }
+	}
+	domReady.load = function(id, req, load){
+		domReady(load);
+	};
+
+	// Export queue so that ready() can check if it's empty or not.
+	domReady._Q = readyQ;
+	domReady._onQEmpty = function(){
+		// summary:
+		//		Private method overridden by dojo/ready, to notify when everything in the
+		//		domReady queue has been processed.  Do not use directly.
+		//		Will be removed in 2.0, along with domReady._Q.
+	};
 
 	// For FF <= 3.5
 	if(fixReadyState){ doc.readyState = "loading"; }
 
+	function processQ(){
+		// Calls all functions in the queue in order, unless processQ() is already running, in which case just return
+
+		if(recursiveGuard){ return; }
+		recursiveGuard = true;
+
+		while(readyQ.length){
+			try{
+				(readyQ.shift())(doc);
+			}catch(err){
+				console.log("Error on domReady callback: " + err);
+			}
+		}
+
+		recursiveGuard = false;
+
+		// Notification for dojo/ready.  Remove for 2.0.
+		// Note that this could add more tasks to the ready queue.
+		domReady._onQEmpty();
+	}
+
 	if(!ready){
-		var readyQ = [], tests = [],
+		var tests = [],
 			detectReady = function(evt){
 				evt = evt || global.event;
 				if(ready || (evt.type == "readystatechange" && !readyStates[doc.readyState])){ return; }
-				ready = 1;
 
 				// For FF <= 3.5
 				if(fixReadyState){ doc.readyState = "complete"; }
 
-				while(readyQ.length){
-					(readyQ.shift())(doc);
-				}
+				ready = 1;
+				processQ();
 			},
 			on = function(node, event){
 				node.addEventListener(event, detectReady, false);
@@ -80,18 +120,5 @@ define(['./has'], function(has){
 		}
 	}
 
-	function domReady(callback){
-		// summary:
-		//		Plugin to delay require()/define() callback from firing until the DOM has finished loading.
-		if(ready){
-			callback(doc);
-		}else{
-			readyQ.push(callback);
-		}
-	}
-	domReady.load = function(id, req, load){
-		domReady(load);
-	};
-
 	return domReady;
 });
diff --git a/ready.js b/ready.js
index 811e73d..29bace9 100644
--- a/ready.js
+++ b/ready.js
@@ -8,9 +8,6 @@ define(["./_base/kernel", "./has", "require", "./has!host-browser?./domReady", "
 		// truthy if DOMContentLoaded or better (e.g., window.onload fired) has been achieved
 		isDomReady = 0,
 
-		// a function to call to cause onLoad to be called when all requested modules have been loaded
-		requestCompleteSignal,
-
 		// The queue of functions waiting to execute as soon as dojo.ready conditions satisfied
 		loadQ = [],
 
@@ -20,42 +17,56 @@ define(["./_base/kernel", "./has", "require", "./has!host-browser?./domReady", "
 		handleDomReady = function(){
 			isDomReady = 1;
 			dojo._postLoad = dojo.config.afterOnLoad = true;
-			if(loadQ.length){
-				requestCompleteSignal(onLoad);
-			}
+			onEvent();
 		},
 
-		// run the next function queued with dojo.ready
-		onLoad = function(){
-			if(isDomReady && !onLoadRecursiveGuard && loadQ.length){
-				//guard against recursions into this function
-				onLoadRecursiveGuard = 1;
+		onEvent = function(){
+			// Called when some state changes:
+			//		- dom ready
+			//		- dojo/domReady has finished processing everything in its queue
+			//		- task added to loadQ
+			//		- require() has finished loading all currently requested modules
+			//
+			// Run the functions queued with dojo.ready if appropriate.
+
+
+			//guard against recursions into this function
+			if(onLoadRecursiveGuard){
+				return;
+			}
+			onLoadRecursiveGuard = 1;
+
+			// Run tasks in queue if require() is finished loading modules, the dom is ready, and there are no
+			// pending tasks registered via domReady().
+			// The last step is necessary so that a user defined dojo.ready() callback is delayed until after the
+			// domReady() calls inside of dojo.   Failure can be seen on dijit/tests/robot/Dialog_ally.html on IE8
+			// because the dijit/focus.js domReady() callback doesn't execute until after the test starts running.
+			while(isDomReady && (!domReady || domReady._Q.length == 0) && require.idle() && loadQ.length){
 				var f = loadQ.shift();
-					try{
-						f();
-					}
-						// FIXME: signal the error via require.on
-					finally{
-						onLoadRecursiveGuard = 0;
-					}
-				onLoadRecursiveGuard = 0;
-				if(loadQ.length){
-					requestCompleteSignal(onLoad);
+				try{
+					f();
+				}catch(e){
+					// FIXME: signal the error via require.on
 				}
 			}
+
+			onLoadRecursiveGuard = 0;
 		};
 
-	require.on && require.on("idle", onLoad);
-	requestCompleteSignal = function(){
-		if(require.idle ? require.idle() : true){
-			onLoad();
-		} // else do nothing, onLoad will be called with the next idle signal
-	};
+	// Check if we should run the next queue operation whenever require() finishes loading modules or domReady
+	// finishes processing it's queue.
+	require.on("idle", onEvent);
+	if(domReady){
+		domReady._onQEmpty = onEvent;
+	}
 
 	var ready = dojo.ready = dojo.addOnLoad = function(priority, context, callback){
 		// summary:
 		//		Add a function to execute on DOM content loaded and all requested modules have arrived and been evaluated.
 		//		In most cases, the `domReady` plug-in should suffice and this method should not be needed.
+		//
+		//		When called in a non-browser environment, just checks that all requested modules have arrived and been
+		//		evaluated.
 		// priority: Integer?
 		//		The order in which to exec this callback relative to other callbacks, defaults to 1000
 		// context: Object?|Function
@@ -106,7 +117,7 @@ define(["./_base/kernel", "./has", "require", "./has!host-browser?./domReady", "
 		callback.priority = priority;
 		for(var i = 0; i < loadQ.length && priority >= loadQ[i].priority; i++){}
 		loadQ.splice(i, 0, callback);
-		requestCompleteSignal();
+		onEvent();
 	};
 
 	has.add("dojo-config-addOnLoad", 1);
@@ -126,7 +137,7 @@ define(["./_base/kernel", "./has", "require", "./has!host-browser?./domReady", "
 		});
 	}
 
-	if(has("host-browser")){
+	if(domReady){
 		domReady(handleDomReady);
 	}else{
 		handleDomReady();

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/dojo.git



More information about the Pkg-javascript-commits mailing list