158 lines
5.1 KiB
JavaScript
158 lines
5.1 KiB
JavaScript
define("dojox/mobile/parser", [
|
|
"dojo/_base/kernel",
|
|
"dojo/_base/array",
|
|
"dojo/_base/config",
|
|
"dojo/_base/lang",
|
|
"dojo/_base/window",
|
|
"dojo/ready"
|
|
], function(dojo, array, config, lang, win, ready){
|
|
|
|
// module:
|
|
// dojox/mobile/parser
|
|
|
|
var dm = lang.getObject("dojox.mobile", true);
|
|
|
|
var Parser = function(){
|
|
// summary:
|
|
// A lightweight parser.
|
|
// description:
|
|
// dojox/mobile/parser is an extremely small subset of dojo/parser.
|
|
// It has no additional features over dojo/parser, so there is no
|
|
// benefit in terms of features by using dojox/mobile/parser instead
|
|
// of dojo/parser. However, if dojox/mobile/parser's capabilities are
|
|
// enough for your application, using it could reduce the total code size.
|
|
|
|
var _ctorMap = {};
|
|
var getCtor = function(type, mixins){
|
|
if(typeof(mixins) === "string"){
|
|
var t = type + ":" + mixins.replace(/ /g, "");
|
|
return _ctorMap[t] ||
|
|
(_ctorMap[t] = getCtor(type).createSubclass(array.map(mixins.split(/, */), getCtor)));
|
|
}
|
|
return _ctorMap[type] || (_ctorMap[type] = lang.getObject(type) || require(type));
|
|
};
|
|
var _eval = function(js){ return eval(js); };
|
|
|
|
this.instantiate = function(/* DomNode[] */nodes, /* Object? */mixin, /* Object? */options){
|
|
// summary:
|
|
// Function for instantiating a list of widget nodes.
|
|
// nodes:
|
|
// The list of DomNodes to walk and instantiate widgets on.
|
|
mixin = mixin || {};
|
|
options = options || {};
|
|
var i, ws = [];
|
|
if(nodes){
|
|
for(i = 0; i < nodes.length; i++){
|
|
var n = nodes[i],
|
|
type = n._type,
|
|
ctor = getCtor(type, n.getAttribute("data-dojo-mixins")),
|
|
proto = ctor.prototype,
|
|
params = {}, prop, v, t;
|
|
lang.mixin(params, _eval.call(options.propsThis, '({'+(n.getAttribute("data-dojo-props")||"")+'})'));
|
|
lang.mixin(params, options.defaults);
|
|
lang.mixin(params, mixin);
|
|
for(prop in proto){
|
|
v = n.getAttributeNode(prop);
|
|
v = v && v.nodeValue;
|
|
t = typeof proto[prop];
|
|
if(!v && (t !== "boolean" || v !== "")){ continue; }
|
|
if(lang.isArray(proto[prop])){
|
|
params[prop] = v.split(/\s*,\s*/);
|
|
}else if(t === "string"){
|
|
params[prop] = v;
|
|
}else if(t === "number"){
|
|
params[prop] = v - 0;
|
|
}else if(t === "boolean"){
|
|
params[prop] = (v !== "false");
|
|
}else if(t === "object"){
|
|
params[prop] = eval("(" + v + ")");
|
|
}else if(t === "function"){
|
|
params[prop] = lang.getObject(v, false) || new Function(v);
|
|
n.removeAttribute(prop);
|
|
}
|
|
}
|
|
params["class"] = n.className;
|
|
if(!params.style){ params.style = n.style.cssText; }
|
|
v = n.getAttribute("data-dojo-attach-point");
|
|
if(v){ params.dojoAttachPoint = v; }
|
|
v = n.getAttribute("data-dojo-attach-event");
|
|
if(v){ params.dojoAttachEvent = v; }
|
|
var instance = new ctor(params, n);
|
|
ws.push(instance);
|
|
var jsId = n.getAttribute("jsId") || n.getAttribute("data-dojo-id");
|
|
if(jsId){
|
|
lang.setObject(jsId, instance);
|
|
}
|
|
}
|
|
for(i = 0; i < ws.length; i++){
|
|
var w = ws[i];
|
|
!options.noStart && w.startup && !w._started && w.startup();
|
|
}
|
|
}
|
|
return ws;
|
|
};
|
|
|
|
this.parse = function(/* DomNode */ rootNode, /* Object? */ options){
|
|
// summary:
|
|
// Function to handle parsing for widgets in the current document.
|
|
// It is not as powerful as the full parser, but it will handle basic
|
|
// use cases fine.
|
|
// rootNode:
|
|
// The root node in the document to parse from
|
|
if(!rootNode){
|
|
rootNode = win.body();
|
|
}else if(!options && rootNode.rootNode){
|
|
// Case where 'rootNode' is really a params object.
|
|
options = rootNode;
|
|
rootNode = rootNode.rootNode;
|
|
}
|
|
|
|
var nodes = rootNode.getElementsByTagName("*");
|
|
var i, j, list = [];
|
|
for(i = 0; i < nodes.length; i++){
|
|
var n = nodes[i],
|
|
type = (n._type = n.getAttribute("dojoType") || n.getAttribute("data-dojo-type"));
|
|
if(type){
|
|
if(n._skip){
|
|
n._skip = "";
|
|
continue;
|
|
}
|
|
if(getCtor(type).prototype.stopParser && !(options && options.template)){
|
|
var arr = n.getElementsByTagName("*");
|
|
for(j = 0; j < arr.length; j++){
|
|
arr[j]._skip = "1";
|
|
}
|
|
}
|
|
list.push(n);
|
|
}
|
|
}
|
|
var mixin = options && options.template ? {template: true} : null;
|
|
return this.instantiate(list, mixin, options);
|
|
};
|
|
};
|
|
|
|
// Singleton. (TODO: replace parser class and singleton w/a simple hash of functions)
|
|
var parser = new Parser();
|
|
|
|
if(config.parseOnLoad){
|
|
ready(100, function(){
|
|
// Now that all the modules are loaded, check if the app loaded dojo/parser too.
|
|
// If it did, let dojo/parser handle the parseOnLoad flag instead of me.
|
|
try{
|
|
if(!require("dojo/parser")){
|
|
// IE6 takes this path when dojo/parser unavailable, rather than catch() block below,
|
|
// due to http://support.microsoft.com/kb/944397
|
|
parser.parse();
|
|
}
|
|
}catch(e){
|
|
// Other browsers (and later versions of IE) take this path when dojo/parser unavailable
|
|
parser.parse();
|
|
}
|
|
});
|
|
}
|
|
dm.parser = parser; // for backward compatibility
|
|
dojo.parser = dojo.parser || parser; // in case user application calls dojo.parser
|
|
|
|
return parser;
|
|
});
|