summaryrefslogtreecommitdiff
path: root/lib/dojo/parser.js.uncompressed.js
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dojo/parser.js.uncompressed.js')
-rw-r--r--lib/dojo/parser.js.uncompressed.js865
1 files changed, 0 insertions, 865 deletions
diff --git a/lib/dojo/parser.js.uncompressed.js b/lib/dojo/parser.js.uncompressed.js
deleted file mode 100644
index 7ce8c2eb2..000000000
--- a/lib/dojo/parser.js.uncompressed.js
+++ /dev/null
@@ -1,865 +0,0 @@
-define(
- "dojo/parser", ["require", "./_base/kernel", "./_base/lang", "./_base/array", "./_base/config", "./_base/html", "./_base/window",
- "./_base/url", "./_base/json", "./aspect", "./date/stamp", "./Deferred", "./has", "./query", "./on", "./ready"],
- function(require, dojo, dlang, darray, config, dhtml, dwindow, _Url, djson, aspect, dates, Deferred, has, query, don, ready){
-
- // module:
- // dojo/parser
-
- new Date("X"); // workaround for #11279, new Date("") == NaN
-
-
- // 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).
- var extendCnt = 0;
- aspect.after(dlang, "extend", function(){
- extendCnt++;
- }, true);
-
- function getNameMap(ctor){
- // summary:
- // Returns map from lowercase name to attribute name in class, ex: {onclick: "onClick"}
- var map = ctor._nameCaseMap, proto = ctor.prototype;
-
- // Create the map if it's undefined.
- // Refresh the map if a superclass was possibly extended with new methods since the map was created.
- if(!map || map._extendCnt < extendCnt){
- map = ctor._nameCaseMap = {};
- for(var name in proto){
- if(name.charAt(0) === "_"){ continue; } // skip internal properties
- map[name.toLowerCase()] = name;
- }
- map._extendCnt = extendCnt;
- }
- return map;
- }
-
- // Map from widget name or list of widget names(ex: "dijit/form/Button,acme/MyMixin") to a constructor.
- var _ctorMap = {};
-
- function getCtor(/*String[]*/ types){
- // summary:
- // Retrieves a constructor. If the types array contains more than one class/MID then the
- // subsequent classes will be mixed into the first class and a unique constructor will be
- // returned for that array.
-
- var ts = types.join();
- if(!_ctorMap[ts]){
- var mixins = [];
- for(var i = 0, l = types.length; i < l; i++){
- var t = types[i];
- // TODO: Consider swapping getObject and require in the future
- mixins[mixins.length] = (_ctorMap[t] = _ctorMap[t] || (dlang.getObject(t) || (~t.indexOf('/') && require(t))));
- }
- var ctor = mixins.shift();
- _ctorMap[ts] = mixins.length ? (ctor.createSubclass ? ctor.createSubclass(mixins) : ctor.extend.apply(ctor, mixins)) : ctor;
- }
-
- return _ctorMap[ts];
- }
-
- var parser = {
- // summary:
- // The Dom/Widget parsing package
-
- _clearCache: function(){
- // summary:
- // Clear cached data. Used mainly for benchmarking.
- extendCnt++;
- _ctorMap = {};
- },
-
- _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 = "",
- suffix = "",
- argsStr = (script.getAttribute(attrData + "args") || script.getAttribute("args")),
- withStr = script.getAttribute("with");
-
- // Convert any arguments supplied in script tag into an array to be passed to the
- var fnArgs = (argsStr || "").split(/\s*,\s*/);
-
- if(withStr && withStr.length){
- darray.forEach(withStr.split(/\s*,\s*/), function(part){
- preamble += "with("+part+"){";
- suffix += "}";
- });
- }
-
- return new Function(fnArgs, preamble + script.innerHTML + suffix);
- },
-
- instantiate: function(nodes, mixin, options){
- // 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 DOM nodes
- // 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.
- // options: Object?
- // An object used to hold kwArgs for instantiation.
- // See parse.options argument for details.
-
- mixin = mixin || {};
- options = options || {};
-
- var dojoType = (options.scope || dojo._scopeName) + "Type", // typically "dojoType"
- attrData = "data-" + (options.scope || dojo._scopeName) + "-",// typically "data-dojo-"
- dataDojoType = attrData + "type", // typically "data-dojo-type"
- dataDojoMixins = attrData + "mixins"; // typically "data-dojo-mixins"
-
- var list = [];
- darray.forEach(nodes, function(node){
- var type = dojoType in mixin ? mixin[dojoType] : node.getAttribute(dataDojoType) || node.getAttribute(dojoType);
- if(type){
- var mixinsValue = node.getAttribute(dataDojoMixins),
- types = mixinsValue ? [type].concat(mixinsValue.split(/\s*,\s*/)) : [type];
-
- list.push({
- node: node,
- types: types
- });
- }
- });
-
- // Instantiate the nodes and return the objects
- return this._instantiate(list, mixin, options);
- },
-
- _instantiate: function(nodes, mixin, options){
- // summary:
- // Takes array of objects representing 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 objects like
- // | {
- // | ctor: Function (may be null)
- // | types: ["dijit/form/Button", "acme/MyMixin"] (used if ctor not specified)
- // | 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.
- // options: Object
- // An options object used to hold kwArgs for instantiation.
- // See parse.options argument for details.
-
- // Call widget constructors
- var thelist = darray.map(nodes, function(obj){
- var ctor = obj.ctor || getCtor(obj.types);
- // If we still haven't resolved a ctor, it is fatal now
- if(!ctor){
- throw new Error("Unable to resolve constructor for: '" + obj.types.join() + "'");
- }
- return this.construct(ctor, obj.node, mixin, options, obj.scripts, obj.inherited);
- }, this);
-
- // 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 && !options.noStart){
- darray.forEach(thelist, function(instance){
- if(typeof instance.startup === "function" && !instance._started){
- instance.startup();
- }
- });
- }
-
- return thelist;
- },
-
- construct: function(ctor, node, mixin, options, scripts, inherited){
- // summary:
- // Calls new ctor(params, node), where params is the hash of parameters specified on the node,
- // excluding data-dojo-type and data-dojo-mixins. Does not call startup(). Returns the widget.
- // ctor: Function
- // Widget constructor.
- // node: DOMNode
- // This node will be replaced/attached to by the widget. It also specifies the arguments to pass to ctor.
- // mixin: Object?
- // Attributes in this object will be passed as parameters to ctor,
- // overriding attributes specified on the node.
- // options: Object?
- // An options object used to hold kwArgs for instantiation. See parse.options argument for details.
- // scripts: DomNode[]?
- // Array of `<script type="dojo/*">` DOMNodes. If not specified, will search for `<script>` tags inside node.
- // inherited: Object?
- // Settings from dir=rtl or lang=... on a node above this node. Overrides options.inherited.
-
- var proto = ctor && ctor.prototype;
- options = options || {};
-
- // 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(options.defaults){
- // settings for the document itself (or whatever subtree is being parsed)
- dlang.mixin(params, options.defaults);
- }
- if(inherited){
- // settings from dir=rtl or lang=... on a node above this node
- dlang.mixin(params, inherited);
- }
-
- // Get list of attributes explicitly listed in the markup
- var attributes;
- if(has("dom-attributes-explicit")){
- // Standard path to get list of user specified attributes
- attributes = node.attributes;
- }else if(has("dom-attributes-specified-flag")){
- // Special processing needed for IE8, to skip a few faux values in attributes[]
- attributes = darray.filter(node.attributes, function(a){ return a.specified;});
- }else{
- // Special path for IE6-7, avoid (sometimes >100) bogus entries in node.attributes
- var clone = /^input$|^img$/i.test(node.nodeName) ? node : node.cloneNode(false),
- attrs = clone.outerHTML.replace(/=[^\s"']+|="[^"]*"|='[^']*'/g, "").replace(/^\s*<[a-zA-Z0-9]*\s*/, "").replace(/\s*>.*$/, "");
-
- attributes = darray.map(attrs.split(/\s+/), function(name){
- var lcName = name.toLowerCase();
- return {
- name: name,
- // getAttribute() doesn't work for button.value, returns innerHTML of button.
- // but getAttributeNode().value doesn't work for the form.encType or li.value
- value: (node.nodeName == "LI" && name == "value") || lcName == "enctype" ?
- node.getAttribute(lcName) : node.getAttributeNode(lcName).value
- };
- });
- }
-
- // Hash to convert scoped attribute name (ex: data-dojo17-params) to something friendly (ex: data-dojo-params)
- // TODO: remove scope for 2.0
- var scope = options.scope || dojo._scopeName,
- attrData = "data-" + scope + "-", // typically "data-dojo-"
- hash = {};
- if(scope !== "dojo"){
- hash[attrData + "props"] = "data-dojo-props";
- hash[attrData + "type"] = "data-dojo-type";
- hash[attrData + "mixins"] = "data-dojo-mixins";
- hash[scope + "type"] = "dojoType";
- hash[attrData + "id"] = "data-dojo-id";
- }
-
- // Read in attributes and process them, including data-dojo-props, data-dojo-type,
- // dojoAttachPoint, etc., as well as normal foo=bar attributes.
- var i=0, item, funcAttrs=[], jsname, extra;
- while(item = attributes[i++]){
- var name = item.name,
- lcName = name.toLowerCase(),
- value = item.value;
-
- switch(hash[lcName] || lcName){
- // Already processed, just ignore
- case "data-dojo-type":
- case "dojotype":
- case "data-dojo-mixins":
- break;
-
- // Data-dojo-props. Save for later to make sure it overrides direct foo=bar settings
- case "data-dojo-props":
- extra = value;
- break;
-
- // data-dojo-id or jsId. TODO: drop jsId in 2.0
- case "data-dojo-id":
- case "jsid":
- jsname = value;
- break;
-
- // For the benefit of _Templated
- case "data-dojo-attach-point":
- case "dojoattachpoint":
- params.dojoAttachPoint = value;
- break;
- case "data-dojo-attach-event":
- case "dojoattachevent":
- params.dojoAttachEvent = value;
- break;
-
- // Special parameter handling needed for IE
- case "class":
- params["class"] = node.className;
- break;
- case "style":
- params["style"] = node.style && node.style.cssText;
- break;
- default:
- // Normal attribute, ex: value="123"
-
- // Find attribute in widget corresponding to specified name.
- // May involve case conversion, ex: onclick --> onClick
- if(!(name in proto)){
- var map = getNameMap(ctor);
- name = map[lcName] || name;
- }
-
- // Set params[name] to value, doing type conversion
- if(name in proto){
- switch(typeof proto[name]){
- case "string":
- params[name] = value;
- break;
- case "number":
- params[name] = value.length ? Number(value) : NaN;
- break;
- case "boolean":
- // for checked/disabled value might be "" or "checked". interpret as true.
- params[name] = value.toLowerCase() != "false";
- break;
- case "function":
- if(value === "" || value.search(/[^\w\.]+/i) != -1){
- // The user has specified some text for a function like "return x+5"
- params[name] = new Function(value);
- }else{
- // The user has specified the name of a global function like "myOnClick"
- // or a single word function "return"
- params[name] = dlang.getObject(value, false) || new Function(value);
- }
- funcAttrs.push(name); // prevent "double connect", see #15026
- break;
- default:
- var pVal = proto[name];
- params[name] =
- (pVal && "length" in pVal) ? (value ? value.split(/\s*,\s*/) : []) : // array
- (pVal instanceof Date) ?
- (value == "" ? new Date("") : // the NaN of dates
- value == "now" ? new Date() : // current date
- dates.fromISOString(value)) :
- (pVal instanceof _Url) ? (dojo.baseUrl + value) :
- djson.fromJson(value);
- }
- }else{
- params[name] = value;
- }
- }
- }
-
- // Remove function attributes from DOMNode to prevent "double connect" problem, see #15026.
- // Do this as a separate loop since attributes[] is often a live collection (depends on the browser though).
- for(var j=0; j<funcAttrs.length; j++){
- var lcfname = funcAttrs[j].toLowerCase();
- node.removeAttribute(lcfname);
- node[lcfname] = null;
- }
-
- // Mix things found in data-dojo-props into the params, overriding any direct settings
- if(extra){
- try{
- extra = djson.fromJson.call(options.propsThis, "{" + extra + "}");
- dlang.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 + "'");
- }
- }
-
- // Any parameters specified in "mixin" override everything else.
- dlang.mixin(params, mixin);
-
- // Get <script> nodes associated with this widget, if they weren't specified explicitly
- if(!scripts){
- scripts = (ctor && (ctor._noScript || proto._noScript) ? [] : query("> script[type^='dojo/']", node));
- }
-
- // 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" data-dojo-event="foo"> tags are dojo.connected after instantiation
- // <script type="dojo/watch" data-dojo-prop="foo"> tags are dojo.watch after instantiation
- // <script type="dojo/on" data-dojo-event="foo"> tags are dojo.on after instantiation
- // note: dojo/* script tags cannot exist in self closing widgets, like <input />
- var aspects = [], // aspects to connect after instantiation
- calls = [], // functions to call after instantiation
- watches = [], // functions to watch after instantiation
- ons = []; // functions to on after instantiation
-
- if(scripts){
- for(i=0; i<scripts.length; i++){
- var script = scripts[i];
- node.removeChild(script);
- // FIXME: drop event="" support in 2.0. use data-dojo-event="" instead
- var event = (script.getAttribute(attrData + "event") || script.getAttribute("event")),
- prop = script.getAttribute(attrData + "prop"),
- method = script.getAttribute(attrData + "method"),
- advice = script.getAttribute(attrData + "advice"),
- scriptType = script.getAttribute("type"),
- nf = this._functionFromScript(script, attrData);
- if(event){
- if(scriptType == "dojo/connect"){
- aspects.push({ method: event, func: nf });
- }else if(scriptType == "dojo/on"){
- ons.push({ event: event, func: nf });
- }else{
- params[event] = nf;
- }
- }else if(scriptType == "dojo/aspect"){
- aspects.push({ method: method, advice: advice, func: nf });
- }else if(scriptType == "dojo/watch"){
- watches.push({ prop: prop, func: nf });
- }else{
- calls.push(nf);
- }
- }
- }
-
- // create the instance
- var markupFactory = ctor.markupFactory || proto.markupFactory;
- var instance = markupFactory ? markupFactory(params, node, ctor) : new ctor(params, node);
-
- // map it to the JS namespace if that makes sense
- if(jsname){
- dlang.setObject(jsname, instance);
- }
-
- // process connections and startup functions
- for(i=0; i<aspects.length; i++){
- aspect[aspects[i].advice || "after"](instance, aspects[i].method, dlang.hitch(instance, aspects[i].func), true);
- }
- for(i=0; i<calls.length; i++){
- calls[i].call(instance);
- }
- for(i=0; i<watches.length; i++){
- instance.watch(watches[i].prop, watches[i].func);
- }
- for(i=0; i<ons.length; i++){
- don(instance, ons[i].event, ons[i].func);
- }
-
- return instance;
- },
-
- scan: function(root, options){
- // summary:
- // Scan a DOM tree and return an array of objects representing the DOMNodes
- // that need to be turned into widgets.
- // description:
- // Search specified node (or document root node) recursively for class instances
- // and return an array of objects that represent potential widgets to be
- // instantiated. Searches for either data-dojo-type="MID" or dojoType="MID" where
- // "MID" is a module ID like "dijit/form/Button" or a fully qualified Class name
- // like "dijit/form/Button". If the MID is not currently available, scan will
- // attempt to require() in the module.
- //
- // See parser.parse() for details of markup.
- // root: DomNode?
- // A default starting root node from which to start the parsing. Can be
- // omitted, defaulting to the entire document. If omitted, the `options`
- // object can be passed in this place. If the `options` object has a
- // `rootNode` member, that is used.
- // options: Object
- // a kwArgs options object, see parse() for details
- //
- // returns: Promise
- // A promise that is resolved with the nodes that have been parsed.
-
- var list = [], // Output List
- mids = [], // An array of modules that are not yet loaded
- midsHash = {}; // Used to keep the mids array unique
-
- var dojoType = (options.scope || dojo._scopeName) + "Type", // typically "dojoType"
- attrData = "data-" + (options.scope || dojo._scopeName) + "-", // typically "data-dojo-"
- dataDojoType = attrData + "type", // typically "data-dojo-type"
- dataDojoTextDir = attrData + "textdir", // typically "data-dojo-textdir"
- dataDojoMixins = attrData + "mixins"; // typically "data-dojo-mixins"
-
- // Info on DOMNode currently being processed
- var node = root.firstChild;
-
- // Info on parent of DOMNode currently being processed
- // - inherited: dir, lang, and textDir setting of parent, or inherited by parent
- // - parent: pointer to identical structure for my parent (or null if no parent)
- // - scripts: if specified, collects <script type="dojo/..."> type nodes from children
- var inherited = options.inherited;
- if(!inherited){
- function findAncestorAttr(node, attr){
- return (node.getAttribute && node.getAttribute(attr)) ||
- (node.parentNode && findAncestorAttr(node.parentNode, attr));
- }
- inherited = {
- dir: findAncestorAttr(root, "dir"),
- lang: findAncestorAttr(root, "lang"),
- textDir: findAncestorAttr(root, dataDojoTextDir)
- };
- for(var key in inherited){
- if(!inherited[key]){ delete inherited[key]; }
- }
- }
-
- // Metadata about parent node
- var parent = {
- inherited: inherited
- };
-
- // For collecting <script type="dojo/..."> type nodes (when null, we don't need to collect)
- var scripts;
-
- // when true, only look for <script type="dojo/..."> tags, and don't recurse to children
- var scriptsOnly;
-
- function getEffective(parent){
- // summary:
- // Get effective dir, lang, textDir settings for specified obj
- // (matching "parent" object structure above), and do caching.
- // Take care not to return null entries.
- if(!parent.inherited){
- parent.inherited = {};
- var node = parent.node,
- grandparent = getEffective(parent.parent);
- var inherited = {
- dir: node.getAttribute("dir") || grandparent.dir,
- lang: node.getAttribute("lang") || grandparent.lang,
- textDir: node.getAttribute(dataDojoTextDir) || grandparent.textDir
- };
- for(var key in inherited){
- if(inherited[key]){
- parent.inherited[key] = inherited[key];
- }
- }
- }
- return parent.inherited;
- }
-
- // DFS on DOM tree, collecting nodes with data-dojo-type specified.
- while(true){
- if(!node){
- // Finished this level, continue to parent's next sibling
- if(!parent || !parent.node){
- break;
- }
- node = parent.node.nextSibling;
- scriptsOnly = false;
- parent = parent.parent;
- scripts = parent.scripts;
- continue;
- }
-
- if(node.nodeType != 1){
- // Text or comment node, skip to next sibling
- node = node.nextSibling;
- continue;
- }
-
- if(scripts && node.nodeName.toLowerCase() == "script"){
- // Save <script type="dojo/..."> for parent, then continue to next sibling
- type = node.getAttribute("type");
- if(type && /^dojo\/\w/i.test(type)){
- scripts.push(node);
- }
- node = node.nextSibling;
- continue;
- }
- if(scriptsOnly){
- // scriptsOnly flag is set, we have already collected scripts if the parent wants them, so now we shouldn't
- // continue further analysis of the node and will continue to the next sibling
- node = node.nextSibling;
- continue;
- }
-
- // Check for data-dojo-type attribute, fallback to backward compatible dojoType
- // TODO: Remove dojoType in 2.0
- var type = node.getAttribute(dataDojoType) || node.getAttribute(dojoType);
-
- // Short circuit for leaf nodes containing nothing [but text]
- var firstChild = node.firstChild;
- if(!type && (!firstChild || (firstChild.nodeType == 3 && !firstChild.nextSibling))){
- node = node.nextSibling;
- continue;
- }
-
- // Meta data about current node
- var current;
-
- var ctor = null;
- if(type){
- // If dojoType/data-dojo-type specified, add to output array of nodes to instantiate.
- var mixinsValue = node.getAttribute(dataDojoMixins),
- types = mixinsValue ? [type].concat(mixinsValue.split(/\s*,\s*/)) : [type];
-
- // Note: won't find classes declared via dojo/Declaration or any modules that haven't been
- // loaded yet so use try/catch to avoid throw from require()
- try{
- ctor = getCtor(types);
- }catch(e){}
-
- // If the constructor was not found, check to see if it has modules that can be loaded
- if(!ctor){
- darray.forEach(types, function(t){
- if(~t.indexOf('/') && !midsHash[t]){
- // If the type looks like a MID and it currently isn't in the array of MIDs to load, add it.
- midsHash[t] = true;
- mids[mids.length] = t;
- }
- });
- }
-
- var childScripts = ctor && !ctor.prototype._noScript ? [] : null; // <script> nodes that are parent's children
-
- // Setup meta data about this widget node, and save it to list of nodes to instantiate
- current = {
- types: types,
- ctor: ctor,
- parent: parent,
- node: node,
- scripts: childScripts
- };
- current.inherited = getEffective(current); // dir & lang settings for current node, explicit or inherited
- list.push(current);
- }else{
- // Meta data about this non-widget node
- current = {
- node: node,
- scripts: scripts,
- parent: parent
- };
- }
-
- // Recurse, collecting <script type="dojo/..."> children, and also looking for
- // descendant nodes with dojoType specified (unless the widget has the stopParser flag).
- // When finished with children, go to my next sibling.
- node = firstChild;
- scripts = childScripts;
- scriptsOnly = ctor && ctor.prototype.stopParser && !(options.template);
- parent = current;
- }
-
- var d = new Deferred();
-
- // If there are modules to load then require them in
- if(mids.length){
- // Warn that there are modules being auto-required
- if(has("dojo-debug-messages")){
- console.warn("WARNING: Modules being Auto-Required: " + mids.join(", "));
- }
- require(mids, function(){
- // Go through list of widget nodes, filling in missing constructors, and filtering out nodes that shouldn't
- // be instantiated due to a stopParser flag on an ancestor that we belatedly learned about due to
- // auto-require of a module like ContentPane. Assumes list is in DFS order.
- d.resolve(darray.filter(list, function(widget){
- if(!widget.ctor){
- // Attempt to find the constructor again. Still won't find classes defined via
- // dijit/Declaration so need to try/catch.
- try{
- widget.ctor = getCtor(widget.types);
- }catch(e){}
- }
-
- // Get the parent widget
- var parent = widget.parent;
- while(parent && !parent.types){
- parent = parent.parent;
- }
-
- // Return false if this node should be skipped due to stopParser on an ancestor.
- // Since list[] is in DFS order, this loop will always set parent.instantiateChildren before
- // trying to compute widget.instantiate.
- var proto = widget.ctor && widget.ctor.prototype;
- widget.instantiateChildren = !(proto && proto.stopParser && !(options.template));
- widget.instantiate = !parent || (parent.instantiate && parent.instantiateChildren);
- return widget.instantiate;
- }));
- });
- }else{
- // There were no modules to load, so just resolve with the parsed nodes. This separate code path is for
- // efficiency, to avoid running the require() and the callback code above.
- d.resolve(list);
- }
-
- // Return the promise
- return d.promise;
- },
-
- _require: function(/*DOMNode*/ script){
- // summary:
- // Helper for _scanAMD(). Takes a `<script type=dojo/require>bar: "acme/bar", ...</script>` node,
- // calls require() to load the specified modules and (asynchronously) assign them to the specified global
- // variables, and returns a Promise for when that operation completes.
- //
- // In the example above, it is effectively doing a require(["acme/bar", ...], function(a){ bar = a; }).
-
- var hash = djson.fromJson("{" + script.innerHTML + "}"),
- vars = [],
- mids = [],
- d = new Deferred();
-
- for(var name in hash){
- vars.push(name);
- mids.push(hash[name]);
- }
-
- require(mids, function(){
- for(var i=0; i<vars.length; i++){
- dlang.setObject(vars[i], arguments[i]);
- }
- d.resolve(arguments);
- });
-
- return d.promise;
- },
-
- _scanAmd: function(root){
- // summary:
- // Scans the DOM for any declarative requires and returns their values.
- // description:
- // Looks for `<script type=dojo/require>bar: "acme/bar", ...</script>` node, calls require() to load the
- // specified modules and (asynchronously) assign them to the specified global variables,
- // and returns a Promise for when those operations complete.
- // root: DomNode
- // The node to base the scan from.
-
- // Promise that resolves when all the <script type=dojo/require> nodes have finished loading.
- var deferred = new Deferred(),
- promise = deferred.promise;
- deferred.resolve(true);
-
- var self = this;
- query("script[type='dojo/require']", root).forEach(function(node){
- // Fire off require() call for specified modules. Chain this require to fire after
- // any previous requires complete, so that layers can be loaded before individual module require()'s fire.
- promise = promise.then(function(){ return self._require(node); });
-
- // Remove from DOM so it isn't seen again
- node.parentNode.removeChild(node);
- });
-
- return promise;
- },
-
- parse: function(rootNode, options){
- // 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 instantiate 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 `options`
- // object can be passed in this place. If the `options` object has a
- // `rootNode` member, that is used.
- // options: Object?
- // A hash of options.
- //
- // - 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 `options 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._WidgetsInTemplateMixin`
- // returns: Mixed
- // Returns a blended object that is an array of the instantiated objects, but also can include
- // a promise that is resolved with the instantiated objects. This is done for backwards
- // compatibility. If the parser auto-requires modules, it will always behave in a promise
- // fashion and `parser.parse().then(function(instances){...})` should be used.
- // example:
- // Parse all widgets on a page:
- // | parser.parse();
- // example:
- // Parse all classes within the node with id="foo"
- // | parser.parse(dojo.byId('foo'));
- // example:
- // Parse all classes in a page, but do not call .startup() on any
- // child
- // | parser.parse({ noStart: true })
- // example:
- // Parse all classes in a node, but do not call .startup()
- // | parser.parse(someNode, { noStart:true });
- // | // or
- // | parser.parse({ noStart:true, rootNode: someNode });
-
- // determine the root node and options based on the passed arguments.
- var root;
- if(!options && rootNode && rootNode.rootNode){
- options = rootNode;
- root = options.rootNode;
- }else if(rootNode && dlang.isObject(rootNode) && !("nodeType" in rootNode)){
- options = rootNode;
- }else{
- root = rootNode;
- }
- root = root ? dhtml.byId(root) : dwindow.body();
-
- options = options || {};
-
- var mixin = options.template ? { template: true } : {},
- instances = [],
- self = this;
-
- // First scan for any <script type=dojo/require> nodes, and execute.
- // Then scan for all nodes with data-dojo-type, and load any unloaded modules.
- // Then build the object instances. Add instances to already existing (but empty) instances[] array,
- // which may already have been returned to caller. Also, use otherwise to collect and throw any errors
- // that occur during the parse().
- var p =
- this._scanAmd(root, options).then(function(){
- return self.scan(root, options);
- }).then(function(parsedNodes){
- return instances = instances.concat(self._instantiate(parsedNodes, mixin, options));
- }).otherwise(function(e){
- // TODO Modify to follow better pattern for promise error managment when available
- console.error("dojo/parser::parse() error", e);
- throw e;
- });
-
- // Blend the array with the promise
- dlang.mixin(instances, p);
- return instances;
- }
- };
-
- if( 1 ){
- dojo.parser = parser;
- }
-
- // Register the parser callback. It should be the first callback
- // after the a11y test.
- if(config.parseOnLoad){
- ready(100, parser, "parse");
- }
-
- return parser;
-});