]> git.pond.sub.org Git - eow/blobdiff - static/dojo-release-1.1.1/dojo/parser.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dojo / parser.js
diff --git a/static/dojo-release-1.1.1/dojo/parser.js b/static/dojo-release-1.1.1/dojo/parser.js
new file mode 100644 (file)
index 0000000..5394338
--- /dev/null
@@ -0,0 +1,277 @@
+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");
+
+dojo.parser = new function(){
+       // summary: The Dom/Widget parsing package
+
+       var d = dojo;
+       var dtName = d._scopeName + "Type";
+       var qry = "[" + dtName + "]";
+
+       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.search(/[^\w\.]+/i) != -1){
+                                               // TODO: "this" here won't work
+                                               value = d.parser._nameAnonFunc(new Function(value), this);
+                                       }
+                                       return d.getObject(value, false);
+                               }catch(e){ return new Function(); }
+                       case "array":
+                               return 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 instanceClasses = {
+               // map from fully qualified name (like "dijit.Button") to structure like
+               // { cls: dijit.Button, params: {label: "string", disabled: "boolean"} }
+       };
+       
+       function getClassInfo(/*String*/ className){
+               // className:
+               //              fully qualified name (like "dijit.Button")
+               // returns:
+               //              structure like
+               //                      { 
+               //                              cls: dijit.Button, 
+               //                              params: { label: "string", disabled: "boolean"}
+               //                      }
+
+               if(!instanceClasses[className]){
+                       // get pointer to widget class
+                       var cls = d.getObject(className);
+                       if(!d.isFunction(cls)){
+                               throw new Error("Could not load class '" + className +
+                                       "'. Did you spell the name correctly and use a full path, like 'dijit.form.Button'?");
+                       }
+                       var proto = cls.prototype;
+       
+                       // get table of parameter names & types
+                       var params={};
+                       for(var name in proto){
+                               if(name.charAt(0)=="_"){ continue; }    // skip internal properties
+                               var defVal = proto[name];
+                               params[name]=val2type(defVal);
+                       }
+
+                       instanceClasses[className] = { cls: cls, params: params };
+               }
+               return instanceClasses[className];
+       }
+
+       this._functionFromScript = function(script){
+               var preamble = "";
+               var suffix = "";
+               var argsStr = 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){
+               // summary:
+               //              Takes array of nodes, and turns them into class instances and
+               //              potentially calls a layout method to allow them to connect with
+               //              any children            
+               var thelist = [];
+               d.forEach(nodes, function(node){
+                       if(!node){ return; }
+                       var type = node.getAttribute(dtName);
+                       if((!type)||(!type.length)){ return; }
+                       var clsInfo = getClassInfo(type);
+                       var clazz = clsInfo.cls;
+                       var ps = clazz._noScript||clazz.prototype._noScript;
+
+                       // read parameters (ie, attributes).
+                       // clsInfo.params lists expected params like {"checked": "boolean", "n": "number"}
+                       var params = {};
+                       var attributes = node.attributes;
+                       for(var name in clsInfo.params){
+                               var item = 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 = node.className;
+                                       break;
+                               case "style":
+                                       value = node.style && node.style.cssText; // FIXME: Opera?
+                               }
+                               var _type = clsInfo.params[name];
+                               params[name] = str2obj(value, _type);
+                       }
+
+                       // 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 />
+                       if(!ps){
+                               var connects = [],      // functions to connect after instantiation
+                                       calls = [];             // functions to call after instantiation
+
+                               d.query("> script[type^='dojo/']", node).orphan().forEach(function(script){
+                                       var event = script.getAttribute("event"),
+                                               type = script.getAttribute("type"),
+                                               nf = d.parser._functionFromScript(script);
+                                       if(event){
+                                               if(type == "dojo/connect"){
+                                                       connects.push({event: event, func: nf});
+                                               }else{
+                                                       params[event] = nf;
+                                               }
+                                       }else{
+                                               calls.push(nf);
+                                       }
+                               });
+                       }
+
+                       var markupFactory = clazz["markupFactory"];
+                       if(!markupFactory && clazz["prototype"]){
+                               markupFactory = 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
+                       var jsname = node.getAttribute("jsId");
+                       if(jsname){
+                               d.setObject(jsname, instance);
+                       }
+
+                       // process connections and startup functions
+                       if(!ps){
+                               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
+               d.forEach(thelist, function(instance){
+                       if(     instance  && 
+                               instance.startup &&
+                               !instance._started && 
+                               (!instance.getParent || !instance.getParent())
+                       ){
+                               instance.startup();
+                       }
+               });
+               return thelist;
+       };
+
+       this.parse = function(/*DomNode?*/ rootNode){
+               // summary:
+               //              Search specified node (or root node) recursively for class instances,
+               //              and instantiate them Searches for
+               //              dojoType="qualified.class.name"
+               var list = d.query(qry, rootNode);
+               // go build the object instances
+               var instances = this.instantiate(list);
+               return instances;
+       };
+}();
+
+//Register the parser callback. It should be the first callback
+//after the a11y test.
+
+(function(){
+       var parseRunner = function(){ 
+               if(dojo.config["parseOnLoad"] == true){
+                       dojo.parser.parse(); 
+               }
+       };
+
+       // FIXME: need to clobber cross-dependency!!
+       if(dojo.exists("dijit.wai.onload") && (dijit.wai.onload === dojo._loaders[0])){
+               dojo._loaders.splice(1, 0, parseRunner);
+       }else{
+               dojo._loaders.unshift(parseRunner);
+       }
+})();
+
+//TODO: ported from 0.4.x Dojo.  Can we reduce this?
+dojo.parser._anonCtr = 0;
+dojo.parser._anon = {}; // why is this property required?
+dojo.parser._nameAnonFunc = function(/*Function*/anonFuncPtr, /*Object*/thisObj){
+       // summary:
+       //              Creates a reference to anonFuncPtr in thisObj with a completely
+       //              unique name. The new name is returned as a String. 
+       var jpn = "$joinpoint";
+       var nso = (thisObj|| dojo.parser._anon);
+       if(dojo.isIE){
+               var cn = anonFuncPtr["__dojoNameCache"];
+               if(cn && nso[cn] === anonFuncPtr){
+                       return anonFuncPtr["__dojoNameCache"];
+               }
+       }
+       var ret = "__"+dojo.parser._anonCtr++;
+       while(typeof nso[ret] != "undefined"){
+               ret = "__"+dojo.parser._anonCtr++;
+       }
+       nso[ret] = anonFuncPtr;
+       return ret; // String
+}
+
+}