| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562 | 
							- /*
 
- 	Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
 
- 	Available via Academic Free License >= 2.1 OR the modified BSD license.
 
- 	see: http://dojotoolkit.org/license for details
 
- */
 
- if(!dojo._hasResource["dojo.parser"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
 
- dojo._hasResource["dojo.parser"] = true;
 
- dojo.provide("dojo.parser");
 
- dojo.require("dojo.date.stamp");
 
- new Date("X"); // workaround for #11279, new Date("") == NaN
 
- dojo.parser = new function(){
 
- 	// summary:
 
- 	//		The Dom/Widget parsing package
 
- 	var d = dojo;
 
- 	function val2type(/*Object*/ value){
 
- 		// summary:
 
- 		//		Returns name of type of given value.
 
- 		if(d.isString(value)){ return "string"; }
 
- 		if(typeof value == "number"){ return "number"; }
 
- 		if(typeof value == "boolean"){ return "boolean"; }
 
- 		if(d.isFunction(value)){ return "function"; }
 
- 		if(d.isArray(value)){ return "array"; } // typeof [] == "object"
 
- 		if(value instanceof Date) { return "date"; } // assume timestamp
 
- 		if(value instanceof d._Url){ return "url"; }
 
- 		return "object";
 
- 	}
 
- 	function str2obj(/*String*/ value, /*String*/ type){
 
- 		// summary:
 
- 		//		Convert given string value to given type
 
- 		switch(type){
 
- 			case "string":
 
- 				return value;
 
- 			case "number":
 
- 				return value.length ? Number(value) : NaN;
 
- 			case "boolean":
 
- 				// for checked/disabled value might be "" or "checked".	 interpret as true.
 
- 				return typeof value == "boolean" ? value : !(value.toLowerCase()=="false");
 
- 			case "function":
 
- 				if(d.isFunction(value)){
 
- 					// IE gives us a function, even when we say something like onClick="foo"
 
- 					// (in which case it gives us an invalid function "function(){ foo }").
 
- 					//	Therefore, convert to string
 
- 					value=value.toString();
 
- 					value=d.trim(value.substring(value.indexOf('{')+1, value.length-1));
 
- 				}
 
- 				try{
 
- 					if(value === "" || value.search(/[^\w\.]+/i) != -1){
 
- 						// The user has specified some text for a function like "return x+5"
 
- 						return new Function(value);
 
- 					}else{
 
- 						// The user has specified the name of a function like "myOnClick"
 
- 						// or a single word function "return"
 
- 						return d.getObject(value, false) || new Function(value);
 
- 					}
 
- 				}catch(e){ return new Function(); }
 
- 			case "array":
 
- 				return value ? value.split(/\s*,\s*/) : [];
 
- 			case "date":
 
- 				switch(value){
 
- 					case "": return new Date("");	// the NaN of dates
 
- 					case "now": return new Date();	// current date
 
- 					default: return d.date.stamp.fromISOString(value);
 
- 				}
 
- 			case "url":
 
- 				return d.baseUrl + value;
 
- 			default:
 
- 				return d.fromJson(value);
 
- 		}
 
- 	}
 
- 	var dummyClass = {}, instanceClasses = {
 
- 		// map from fully qualified name (like "dijit.Button") to structure like
 
- 		// { cls: dijit.Button, params: {label: "string", disabled: "boolean"} }
 
- 	};
 
- 	// Widgets like BorderContainer add properties to _Widget via dojo.extend().
 
- 	// If BorderContainer is loaded after _Widget's parameter list has been cached,
 
- 	// we need to refresh that parameter list (for _Widget and all widgets that extend _Widget).
 
- 	// TODO: remove this in 2.0, when we stop caching parameters.
 
- 	d.connect(d, "extend", function(){
 
- 		instanceClasses = {};
 
- 	});
 
- 	function getProtoInfo(cls, params){
 
- 		// cls: A prototype
 
- 		//		The prototype of the class to check props on
 
- 		// params: Object
 
- 		//		The parameters object to mix found parameters onto.
 
- 		for(var name in cls){
 
- 			if(name.charAt(0)=="_"){ continue; }	// skip internal properties
 
- 			if(name in dummyClass){ continue; }		// skip "constructor" and "toString"
 
- 			params[name] = val2type(cls[name]);
 
- 		}
 
- 		return params;
 
- 	}
 
- 	function getClassInfo(/*String*/ className, /*Boolean*/ skipParamsLookup){
 
- 		// summary:
 
- 		//		Maps a widget name string like "dijit.form.Button" to the widget constructor itself,
 
- 		//		and a list of that widget's parameters and their types
 
- 		// className:
 
- 		//		fully qualified name (like "dijit.form.Button")
 
- 		// returns:
 
- 		//		structure like
 
- 		//			{
 
- 		//				cls: dijit.Button,
 
- 		//				params: { label: "string", disabled: "boolean"}
 
- 		//			}
 
- 		var c = instanceClasses[className];
 
- 		if(!c){
 
- 			// get pointer to widget class
 
- 			var cls = d.getObject(className), params = null;
 
- 			if(!cls){ return null; }		// class not defined [yet]
 
- 			if(!skipParamsLookup){ // from fastpath, we don't need to lookup the attrs on the proto because they are explicit
 
- 				params = getProtoInfo(cls.prototype, {})
 
- 			}
 
- 			c = { cls: cls, params: params };
 
- 			
 
- 		}else if(!skipParamsLookup && !c.params){
 
- 			// if we're calling getClassInfo and have a cls proto, but no params info, scan that cls for params now
 
- 			// and update the pointer in instanceClasses[className]. This happens when a widget appears in another
 
- 			// widget's template which still uses dojoType, but an instance of the widget appears prior with a data-dojo-type,
 
- 			// skipping this lookup the first time.
 
- 			c.params = getProtoInfo(c.cls.prototype, {});
 
- 		}
 
- 		
 
- 		return c;
 
- 	}
 
- 	this._functionFromScript = function(script, attrData){
 
- 		// summary:
 
- 		//		Convert a <script type="dojo/method" args="a, b, c"> ... </script>
 
- 		//		into a function
 
- 		// script: DOMNode
 
- 		//		The <script> DOMNode
 
- 		// attrData: String
 
- 		//		For HTML5 compliance, searches for attrData + "args" (typically
 
- 		//		"data-dojo-args") instead of "args"
 
- 		var preamble = "";
 
- 		var suffix = "";
 
- 		var argsStr = (script.getAttribute(attrData + "args") || script.getAttribute("args"));
 
- 		if(argsStr){
 
- 			d.forEach(argsStr.split(/\s*,\s*/), function(part, idx){
 
- 				preamble += "var "+part+" = arguments["+idx+"]; ";
 
- 			});
 
- 		}
 
- 		var withStr = script.getAttribute("with");
 
- 		if(withStr && withStr.length){
 
- 			d.forEach(withStr.split(/\s*,\s*/), function(part){
 
- 				preamble += "with("+part+"){";
 
- 				suffix += "}";
 
- 			});
 
- 		}
 
- 		return new Function(preamble+script.innerHTML+suffix);
 
- 	};
 
- 	this.instantiate = function(/* Array */nodes, /* Object? */mixin, /* Object? */args){
 
- 		// summary:
 
- 		//		Takes array of nodes, and turns them into class instances and
 
- 		//		potentially calls a startup method to allow them to connect with
 
- 		//		any children.
 
- 		// nodes: Array
 
- 		//		Array of nodes or objects like
 
- 		//	|		{
 
- 		//	|			type: "dijit.form.Button",
 
- 		//	|			node: DOMNode,
 
- 		//	|			scripts: [ ... ],	// array of <script type="dojo/..."> children of node
 
- 		//	|			inherited: { ... }	// settings inherited from ancestors like dir, theme, etc.
 
- 		//	|		}
 
- 		// mixin: Object?
 
- 		//		An object that will be mixed in with each node in the array.
 
- 		//		Values in the mixin will override values in the node, if they
 
- 		//		exist.
 
- 		// args: Object?
 
- 		//		An object used to hold kwArgs for instantiation.
 
- 		//		See parse.args argument for details.
 
- 		var thelist = [],
 
- 		mixin = mixin||{};
 
- 		args = args||{};
 
- 		// TODO: for 2.0 default to data-dojo- regardless of scopeName (or maybe scopeName won't exist in 2.0)
 
- 		var attrName = (args.scope || d._scopeName) + "Type",	// typically "dojoType"
 
- 			attrData = "data-" + (args.scope || d._scopeName) + "-";	// typically "data-dojo-"
 
- 		d.forEach(nodes, function(obj){
 
- 			if(!obj){ return; }
 
- 			// Get pointers to DOMNode, dojoType string, and clsInfo (metadata about the dojoType), etc.
 
- 			var node, type, clsInfo, clazz, scripts, fastpath;
 
- 			if(obj.node){
 
- 				// new format of nodes[] array, object w/lots of properties pre-computed for me
 
- 				node = obj.node;
 
- 				type = obj.type;
 
- 				fastpath = obj.fastpath;
 
- 				clsInfo = obj.clsInfo || (type && getClassInfo(type, fastpath));
 
- 				clazz = clsInfo && clsInfo.cls;
 
- 				scripts = obj.scripts;
 
- 			}else{
 
- 				// old (backwards compatible) format of nodes[] array, simple array of DOMNodes. no fastpath/data-dojo-type support here.
 
- 				node = obj;
 
- 				type = attrName in mixin ? mixin[attrName] : node.getAttribute(attrName);
 
- 				clsInfo = type && getClassInfo(type);
 
- 				clazz = clsInfo && clsInfo.cls;
 
- 				scripts = (clazz && (clazz._noScript || clazz.prototype._noScript) ? [] :
 
- 							d.query("> script[type^='dojo/']", node));
 
- 			}
 
- 			if(!clsInfo){
 
- 				throw new Error("Could not load class '" + type);
 
- 			}
 
- 			// Setup hash to hold parameter settings for this widget.	Start with the parameter
 
- 			// settings inherited from ancestors ("dir" and "lang").
 
- 			// Inherited setting may later be overridden by explicit settings on node itself.
 
- 			var params = {};
 
- 				
 
- 			if(args.defaults){
 
- 				// settings for the document itself (or whatever subtree is being parsed)
 
- 				d._mixin(params, args.defaults);
 
- 			}
 
- 			if(obj.inherited){
 
- 				// settings from dir=rtl or lang=... on a node above this node
 
- 				d._mixin(params, obj.inherited);
 
- 			}
 
- 			
 
- 			// mix things found in data-dojo-props into the params
 
- 			if(fastpath){
 
- 				var extra = node.getAttribute(attrData + "props");
 
- 				if(extra && extra.length){
 
- 					try{
 
- 						extra = d.fromJson.call(args.propsThis, "{" + extra + "}");
 
- 						d._mixin(params, extra);
 
- 					}catch(e){
 
- 						// give the user a pointer to their invalid parameters. FIXME: can we kill this in production?
 
- 						throw new Error(e.toString() + " in data-dojo-props='" + extra + "'");
 
- 					}
 
- 				}
 
- 				// For the benefit of _Templated, check if node has data-dojo-attach-point/data-dojo-attach-event
 
- 				// and mix those in as though they were parameters
 
- 				var attachPoint = node.getAttribute(attrData + "attach-point");
 
- 				if(attachPoint){
 
- 					params.dojoAttachPoint = attachPoint;
 
- 				}
 
- 				var attachEvent = node.getAttribute(attrData + "attach-event");
 
- 				if(attachEvent){
 
- 					params.dojoAttachEvent = attachEvent;
 
- 				}
 
- 				dojo.mixin(params, mixin);
 
- 			}else{
 
- 				// FIXME: we need something like "deprecateOnce()" to throw dojo.deprecation for something.
 
- 				// remove this logic in 2.0
 
- 				// read parameters (ie, attributes) specified on DOMNode
 
- 				var attributes = node.attributes;
 
- 				// clsInfo.params lists expected params like {"checked": "boolean", "n": "number"}
 
- 				for(var name in clsInfo.params){
 
- 					var item = name in mixin ? { value:mixin[name], specified:true } : attributes.getNamedItem(name);
 
- 					if(!item || (!item.specified && (!dojo.isIE || name.toLowerCase()!="value"))){ continue; }
 
- 					var value = item.value;
 
- 					// Deal with IE quirks for 'class' and 'style'
 
- 					switch(name){
 
- 					case "class":
 
- 						value = "className" in mixin ? mixin.className : node.className;
 
- 						break;
 
- 					case "style":
 
- 						value = "style" in mixin ? mixin.style : (node.style && node.style.cssText); // FIXME: Opera?
 
- 					}
 
- 					var _type = clsInfo.params[name];
 
- 					if(typeof value == "string"){
 
- 						params[name] = str2obj(value, _type);
 
- 					}else{
 
- 						params[name] = value;
 
- 					}
 
- 				}
 
- 			}
 
- 			// Process <script type="dojo/*"> script tags
 
- 			// <script type="dojo/method" event="foo"> tags are added to params, and passed to
 
- 			// the widget on instantiation.
 
- 			// <script type="dojo/method"> tags (with no event) are executed after instantiation
 
- 			// <script type="dojo/connect" event="foo"> tags are dojo.connected after instantiation
 
- 			// note: dojo/* script tags cannot exist in self closing widgets, like <input />
 
- 			var connects = [],	// functions to connect after instantiation
 
- 				calls = [];		// functions to call after instantiation
 
- 			d.forEach(scripts, function(script){
 
- 				node.removeChild(script);
 
- 				// FIXME: drop event="" support in 2.0. use data-dojo-event="" instead
 
- 				var event = (script.getAttribute(attrData + "event") || script.getAttribute("event")),
 
- 					type = script.getAttribute("type"),
 
- 					nf = d.parser._functionFromScript(script, attrData);
 
- 				if(event){
 
- 					if(type == "dojo/connect"){
 
- 						connects.push({event: event, func: nf});
 
- 					}else{
 
- 						params[event] = nf;
 
- 					}
 
- 				}else{
 
- 					calls.push(nf);
 
- 				}
 
- 			});
 
- 			var markupFactory = clazz.markupFactory || clazz.prototype && clazz.prototype.markupFactory;
 
- 			// create the instance
 
- 			var instance = markupFactory ? markupFactory(params, node, clazz) : new clazz(params, node);
 
- 			thelist.push(instance);
 
- 			// map it to the JS namespace if that makes sense
 
- 			// FIXME: in 2.0, drop jsId support. use data-dojo-id instead
 
- 			var jsname = (node.getAttribute(attrData + "id") || node.getAttribute("jsId"));
 
- 			if(jsname){
 
- 				d.setObject(jsname, instance);
 
- 			}
 
- 			// process connections and startup functions
 
- 			d.forEach(connects, function(connect){
 
- 				d.connect(instance, connect.event, null, connect.func);
 
- 			});
 
- 			d.forEach(calls, function(func){
 
- 				func.call(instance);
 
- 			});
 
- 		});
 
- 		// Call startup on each top level instance if it makes sense (as for
 
- 		// widgets).  Parent widgets will recursively call startup on their
 
- 		// (non-top level) children
 
- 		if(!mixin._started){
 
- 			// TODO: for 2.0, when old instantiate() API is desupported, store parent-child
 
- 			// relationships in the nodes[] array so that no getParent() call is needed.
 
- 			// Note that will  require a parse() call from ContentPane setting a param that the
 
- 			// ContentPane is the parent widget (so that the parse doesn't call startup() on the
 
- 			// ContentPane's children)
 
- 			d.forEach(thelist, function(instance){
 
- 				if( !args.noStart && instance  &&
 
- 					dojo.isFunction(instance.startup) &&
 
- 					!instance._started &&
 
- 					(!instance.getParent || !instance.getParent())
 
- 				){
 
- 					instance.startup();
 
- 				}
 
- 			});
 
- 		}
 
- 		return thelist;
 
- 	};
 
- 	this.parse = function(rootNode, args){
 
- 		// summary:
 
- 		//		Scan the DOM for class instances, and instantiate them.
 
- 		//
 
- 		// description:
 
- 		//		Search specified node (or root node) recursively for class instances,
 
- 		//		and instantiate them. Searches for either data-dojo-type="Class" or
 
- 		//		dojoType="Class" where "Class" is a a fully qualified class name,
 
- 		//		like `dijit.form.Button`
 
- 		//
 
- 		//		Using `data-dojo-type`:
 
- 		//		Attributes using can be mixed into the parameters used to instantitate the
 
- 		//		Class by using a `data-dojo-props` attribute on the node being converted.
 
- 		//		`data-dojo-props` should be a string attribute to be converted from JSON.
 
- 		//
 
- 		//		Using `dojoType`:
 
- 		//		Attributes are read from the original domNode and converted to appropriate
 
- 		//		types by looking up the Class prototype values. This is the default behavior
 
- 		//		from Dojo 1.0 to Dojo 1.5. `dojoType` support is deprecated, and will
 
- 		//		go away in Dojo 2.0.
 
- 		//
 
- 		// rootNode: DomNode?
 
- 		//		A default starting root node from which to start the parsing. Can be
 
- 		//		omitted, defaulting to the entire document. If omitted, the `args`
 
- 		//		object can be passed in this place. If the `args` object has a
 
- 		//		`rootNode` member, that is used.
 
- 		//
 
- 		// args: Object
 
- 		//		a kwArgs object passed along to instantiate()
 
- 		//
 
- 		//			* noStart: Boolean?
 
- 		//				when set will prevent the parser from calling .startup()
 
- 		//				when locating the nodes.
 
- 		//			* rootNode: DomNode?
 
- 		//				identical to the function's `rootNode` argument, though
 
- 		//				allowed to be passed in via this `args object.
 
- 		//			* template: Boolean
 
- 		//				If true, ignores ContentPane's stopParser flag and parses contents inside of
 
- 		//				a ContentPane inside of a template.   This allows dojoAttachPoint on widgets/nodes
 
- 		//				nested inside the ContentPane to work.
 
- 		//			* inherited: Object
 
- 		//				Hash possibly containing dir and lang settings to be applied to
 
- 		//				parsed widgets, unless there's another setting on a sub-node that overrides
 
- 		//			* scope: String
 
- 		//				Root for attribute names to search for.   If scopeName is dojo,
 
- 		//				will search for data-dojo-type (or dojoType).   For backwards compatibility
 
- 		//				reasons defaults to dojo._scopeName (which is "dojo" except when
 
- 		//				multi-version support is used, when it will be something like dojo16, dojo20, etc.)
 
- 		//			* propsThis: Object
 
- 		//				If specified, "this" referenced from data-dojo-props will refer to propsThis.
 
- 		//				Intended for use from the widgets-in-template feature of `dijit._Templated`
 
- 		//
 
- 		// example:
 
- 		//		Parse all widgets on a page:
 
- 		//	|		dojo.parser.parse();
 
- 		//
 
- 		// example:
 
- 		//		Parse all classes within the node with id="foo"
 
- 		//	|		dojo.parser.parse(dojo.byId('foo'));
 
- 		//
 
- 		// example:
 
- 		//		Parse all classes in a page, but do not call .startup() on any
 
- 		//		child
 
- 		//	|		dojo.parser.parse({ noStart: true })
 
- 		//
 
- 		// example:
 
- 		//		Parse all classes in a node, but do not call .startup()
 
- 		//	|		dojo.parser.parse(someNode, { noStart:true });
 
- 		//	|		// or
 
- 		//	|		dojo.parser.parse({ noStart:true, rootNode: someNode });
 
- 		// determine the root node based on the passed arguments.
 
- 		var root;
 
- 		if(!args && rootNode && rootNode.rootNode){
 
- 			args = rootNode;
 
- 			root = args.rootNode;
 
- 		}else{
 
- 			root = rootNode;
 
- 		}
 
- 		root = root ? dojo.byId(root) : dojo.body();
 
- 		args = args || {};
 
- 		var attrName = (args.scope || d._scopeName) + "Type",		// typically "dojoType"
 
- 			attrData = "data-" + (args.scope || d._scopeName) + "-";	// typically "data-dojo-"
 
- 		function scan(parent, list){
 
- 			// summary:
 
- 			//		Parent is an Object representing a DOMNode, with or without a dojoType specified.
 
- 			//		Scan parent's children looking for nodes with dojoType specified, storing in list[].
 
- 			//		If parent has a dojoType, also collects <script type=dojo/*> children and stores in parent.scripts[].
 
- 			// parent: Object
 
- 			//		Object representing the parent node, like
 
- 			//	|	{
 
- 			//	|		node: DomNode,			// scan children of this node
 
- 			//	|		inherited: {dir: "rtl"},	// dir/lang setting inherited from above node
 
- 			//	|
 
- 			//	|		// attributes only set if node has dojoType specified
 
- 			//	|		scripts: [],			// empty array, put <script type=dojo/*> in here
 
- 			//	|		clsInfo: { cls: dijit.form.Button, ...}
 
- 			//	|	}
 
- 			// list: DomNode[]
 
- 			//		Output array of objects (same format as parent) representing nodes to be turned into widgets
 
- 			// Effective dir and lang settings on parent node, either set directly or inherited from grandparent
 
- 			var inherited = dojo.clone(parent.inherited);
 
- 			dojo.forEach(["dir", "lang"], function(name){
 
- 				// TODO: what if this is a widget and dir/lang are declared in data-dojo-props?
 
- 				var val = parent.node.getAttribute(name);
 
- 				if(val){
 
- 					inherited[name] = val;
 
- 				}
 
- 			});
 
- 			// if parent is a widget, then search for <script type=dojo/*> tags and put them in scripts[].
 
- 			var scripts = parent.clsInfo && !parent.clsInfo.cls.prototype._noScript ? parent.scripts : null;
 
- 			// unless parent is a widget with the stopParser flag set, continue search for dojoType, recursively
 
- 			var recurse = (!parent.clsInfo || !parent.clsInfo.cls.prototype.stopParser) || (args && args.template);
 
- 			// scan parent's children looking for dojoType and <script type=dojo/*>
 
- 			for(var child = parent.node.firstChild; child; child = child.nextSibling){
 
- 				if(child.nodeType == 1){
 
- 					// FIXME: desupport dojoType in 2.0. use data-dojo-type instead
 
- 					var type, html5 = recurse && child.getAttribute(attrData + "type");
 
- 					if(html5){
 
- 						type = html5;
 
- 					}else{
 
- 						// fallback to backward compatible mode, using dojoType. remove in 2.0
 
- 						type = recurse && child.getAttribute(attrName);
 
- 					}
 
- 					
 
- 					var fastpath = html5 == type;
 
- 					if(type){
 
- 						// if dojoType/data-dojo-type specified, add to output array of nodes to instantiate
 
- 						var params = {
 
- 							"type": type,
 
- 							fastpath: fastpath,
 
- 							clsInfo: getClassInfo(type, fastpath), // note: won't find classes declared via dojo.Declaration
 
- 							node: child,
 
- 							scripts: [], // <script> nodes that are parent's children
 
- 							inherited: inherited // dir & lang attributes inherited from parent
 
- 						};
 
- 						list.push(params);
 
- 						// Recurse, collecting <script type="dojo/..."> children, and also looking for
 
- 						// descendant nodes with dojoType specified (unless the widget has the stopParser flag),
 
- 						scan(params, list);
 
- 					}else if(scripts && child.nodeName.toLowerCase() == "script"){
 
- 						// if <script type="dojo/...">, save in scripts[]
 
- 						type = child.getAttribute("type");
 
- 						if (type && /^dojo\/\w/i.test(type)) {
 
- 							scripts.push(child);
 
- 						}
 
- 					}else if(recurse){
 
- 						// Recurse, looking for grandchild nodes with dojoType specified
 
- 						scan({
 
- 							node: child,
 
- 							inherited: inherited
 
- 						}, list);
 
- 					}
 
- 				}
 
- 			}
 
- 		}
 
- 		// Ignore bogus entries in inherited hash like {dir: ""}
 
- 		var inherited = {};
 
- 		if(args && args.inherited){
 
- 			for(var key in args.inherited){
 
- 				if(args.inherited[key]){ inherited[key] = args.inherited[key]; }
 
- 			}
 
- 		}
 
- 		// Make list of all nodes on page w/dojoType specified
 
- 		var list = [];
 
- 		scan({
 
- 			node: root,
 
- 			inherited: inherited
 
- 		}, list);
 
- 		// go build the object instances
 
- 		var mixin = args && args.template ? {template: true} : null;
 
- 		return this.instantiate(list, mixin, args); // Array
 
- 	};
 
- }();
 
- //Register the parser callback. It should be the first callback
 
- //after the a11y test.
 
- (function(){
 
- 	var parseRunner = function(){
 
- 		if(dojo.config.parseOnLoad){
 
- 			dojo.parser.parse();
 
- 		}
 
- 	};
 
- 	// FIXME: need to clobber cross-dependency!!
 
- 	if(dojo.getObject("dijit.wai.onload") === dojo._loaders[0]){
 
- 		dojo._loaders.splice(1, 0, parseRunner);
 
- 	}else{
 
- 		dojo._loaders.unshift(parseRunner);
 
- 	}
 
- })();
 
- }
 
 
  |