diff options
Diffstat (limited to 'lib/dijit/_Templated.js')
-rw-r--r-- | lib/dijit/_Templated.js | 353 |
1 files changed, 2 insertions, 351 deletions
diff --git a/lib/dijit/_Templated.js b/lib/dijit/_Templated.js index 2e8d6b72f..f21df3a16 100644 --- a/lib/dijit/_Templated.js +++ b/lib/dijit/_Templated.js @@ -1,351 +1,2 @@ -/* - Copyright (c) 2004-2011, 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["dijit._Templated"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. -dojo._hasResource["dijit._Templated"] = true; -dojo.provide("dijit._Templated"); -dojo.require("dijit._Widget"); -dojo.require("dojo.string"); -dojo.require("dojo.parser"); -dojo.require("dojo.cache"); - - -dojo.declare("dijit._Templated", - null, - { - // summary: - // Mixin for widgets that are instantiated from a template - - // templateString: [protected] String - // A string that represents the widget template. Pre-empts the - // templatePath. In builds that have their strings "interned", the - // templatePath is converted to an inline templateString, thereby - // preventing a synchronous network call. - // - // Use in conjunction with dojo.cache() to load from a file. - templateString: null, - - // templatePath: [protected deprecated] String - // Path to template (HTML file) for this widget relative to dojo.baseUrl. - // Deprecated: use templateString with dojo.cache() instead. - templatePath: null, - - // widgetsInTemplate: [protected] Boolean - // Should we parse the template to find widgets that might be - // declared in markup inside it? False by default. - widgetsInTemplate: false, - - // skipNodeCache: [protected] Boolean - // If using a cached widget template node poses issues for a - // particular widget class, it can set this property to ensure - // that its template is always re-built from a string - _skipNodeCache: false, - - // _earlyTemplatedStartup: Boolean - // A fallback to preserve the 1.0 - 1.3 behavior of children in - // templates having their startup called before the parent widget - // fires postCreate. Defaults to 'false', causing child widgets to - // have their .startup() called immediately before a parent widget - // .startup(), but always after the parent .postCreate(). Set to - // 'true' to re-enable to previous, arguably broken, behavior. - _earlyTemplatedStartup: false, - -/*===== - // _attachPoints: [private] String[] - // List of widget attribute names associated with dojoAttachPoint=... in the - // template, ex: ["containerNode", "labelNode"] - _attachPoints: [], - =====*/ - -/*===== - // _attachEvents: [private] Handle[] - // List of connections associated with dojoAttachEvent=... in the - // template - _attachEvents: [], - =====*/ - - constructor: function(){ - this._attachPoints = []; - this._attachEvents = []; - }, - - _stringRepl: function(tmpl){ - // summary: - // Does substitution of ${foo} type properties in template string - // tags: - // private - var className = this.declaredClass, _this = this; - // Cache contains a string because we need to do property replacement - // do the property replacement - return dojo.string.substitute(tmpl, this, function(value, key){ - if(key.charAt(0) == '!'){ value = dojo.getObject(key.substr(1), false, _this); } - if(typeof value == "undefined"){ throw new Error(className+" template:"+key); } // a debugging aide - if(value == null){ return ""; } - - // Substitution keys beginning with ! will skip the transform step, - // in case a user wishes to insert unescaped markup, e.g. ${!foo} - return key.charAt(0) == "!" ? value : - // Safer substitution, see heading "Attribute values" in - // http://www.w3.org/TR/REC-html40/appendix/notes.html#h-B.3.2 - value.toString().replace(/"/g,"""); //TODO: add &? use encodeXML method? - }, this); - }, - - buildRendering: function(){ - // summary: - // Construct the UI for this widget from a template, setting this.domNode. - // tags: - // protected - - // Lookup cached version of template, and download to cache if it - // isn't there already. Returns either a DomNode or a string, depending on - // whether or not the template contains ${foo} replacement parameters. - var cached = dijit._Templated.getCachedTemplate(this.templatePath, this.templateString, this._skipNodeCache); - - var node; - if(dojo.isString(cached)){ - node = dojo._toDom(this._stringRepl(cached)); - if(node.nodeType != 1){ - // Flag common problems such as templates with multiple top level nodes (nodeType == 11) - throw new Error("Invalid template: " + cached); - } - }else{ - // if it's a node, all we have to do is clone it - node = cached.cloneNode(true); - } - - this.domNode = node; - - // Call down to _Widget.buildRendering() to get base classes assigned - // TODO: change the baseClass assignment to attributeMap - this.inherited(arguments); - - // recurse through the node, looking for, and attaching to, our - // attachment points and events, which should be defined on the template node. - this._attachTemplateNodes(node); - - if(this.widgetsInTemplate){ - // Store widgets that we need to start at a later point in time - var cw = (this._startupWidgets = dojo.parser.parse(node, { - noStart: !this._earlyTemplatedStartup, - template: true, - inherited: {dir: this.dir, lang: this.lang}, - propsThis: this, // so data-dojo-props of widgets in the template can reference "this" to refer to me - scope: "dojo" // even in multi-version mode templates use dojoType/data-dojo-type - })); - - this._supportingWidgets = dijit.findWidgets(node); - - this._attachTemplateNodes(cw, function(n,p){ - return n[p]; - }); - } - - this._fillContent(this.srcNodeRef); - }, - - _fillContent: function(/*DomNode*/ source){ - // summary: - // Relocate source contents to templated container node. - // this.containerNode must be able to receive children, or exceptions will be thrown. - // tags: - // protected - var dest = this.containerNode; - if(source && dest){ - while(source.hasChildNodes()){ - dest.appendChild(source.firstChild); - } - } - }, - - _attachTemplateNodes: function(rootNode, getAttrFunc){ - // summary: - // Iterate through the template and attach functions and nodes accordingly. - // Alternately, if rootNode is an array of widgets, then will process dojoAttachPoint - // etc. for those widgets. - // description: - // Map widget properties and functions to the handlers specified in - // the dom node and it's descendants. This function iterates over all - // nodes and looks for these properties: - // * dojoAttachPoint - // * dojoAttachEvent - // * waiRole - // * waiState - // rootNode: DomNode|Array[Widgets] - // the node to search for properties. All children will be searched. - // getAttrFunc: Function? - // a function which will be used to obtain property for a given - // DomNode/Widget - // tags: - // private - - getAttrFunc = getAttrFunc || function(n,p){ return n.getAttribute(p); }; - - var nodes = dojo.isArray(rootNode) ? rootNode : (rootNode.all || rootNode.getElementsByTagName("*")); - var x = dojo.isArray(rootNode) ? 0 : -1; - for(; x<nodes.length; x++){ - var baseNode = (x == -1) ? rootNode : nodes[x]; - if(this.widgetsInTemplate && (getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type"))){ - continue; - } - // Process dojoAttachPoint - var attachPoint = getAttrFunc(baseNode, "dojoAttachPoint") || getAttrFunc(baseNode, "data-dojo-attach-point"); - if(attachPoint){ - var point, points = attachPoint.split(/\s*,\s*/); - while((point = points.shift())){ - if(dojo.isArray(this[point])){ - this[point].push(baseNode); - }else{ - this[point]=baseNode; - } - this._attachPoints.push(point); - } - } - - // Process dojoAttachEvent - var attachEvent = getAttrFunc(baseNode, "dojoAttachEvent") || getAttrFunc(baseNode, "data-dojo-attach-event");; - if(attachEvent){ - // NOTE: we want to support attributes that have the form - // "domEvent: nativeEvent; ..." - var event, events = attachEvent.split(/\s*,\s*/); - var trim = dojo.trim; - while((event = events.shift())){ - if(event){ - var thisFunc = null; - if(event.indexOf(":") != -1){ - // oh, if only JS had tuple assignment - var funcNameArr = event.split(":"); - event = trim(funcNameArr[0]); - thisFunc = trim(funcNameArr[1]); - }else{ - event = trim(event); - } - if(!thisFunc){ - thisFunc = event; - } - this._attachEvents.push(this.connect(baseNode, event, thisFunc)); - } - } - } - - // waiRole, waiState - // TODO: remove this in 2.0, templates are now using role=... and aria-XXX=... attributes directicly - var role = getAttrFunc(baseNode, "waiRole"); - if(role){ - dijit.setWaiRole(baseNode, role); - } - var values = getAttrFunc(baseNode, "waiState"); - if(values){ - dojo.forEach(values.split(/\s*,\s*/), function(stateValue){ - if(stateValue.indexOf('-') != -1){ - var pair = stateValue.split('-'); - dijit.setWaiState(baseNode, pair[0], pair[1]); - } - }); - } - } - }, - - startup: function(){ - dojo.forEach(this._startupWidgets, function(w){ - if(w && !w._started && w.startup){ - w.startup(); - } - }); - this.inherited(arguments); - }, - - destroyRendering: function(){ - // Delete all attach points to prevent IE6 memory leaks. - dojo.forEach(this._attachPoints, function(point){ - delete this[point]; - }, this); - this._attachPoints = []; - - // And same for event handlers - dojo.forEach(this._attachEvents, this.disconnect, this); - this._attachEvents = []; - - this.inherited(arguments); - } - } -); - -// key is either templatePath or templateString; object is either string or DOM tree -dijit._Templated._templateCache = {}; - -dijit._Templated.getCachedTemplate = function(templatePath, templateString, alwaysUseString){ - // summary: - // Static method to get a template based on the templatePath or - // templateString key - // templatePath: String||dojo.uri.Uri - // The URL to get the template from. - // templateString: String? - // a string to use in lieu of fetching the template from a URL. Takes precedence - // over templatePath - // returns: Mixed - // Either string (if there are ${} variables that need to be replaced) or just - // a DOM tree (if the node can be cloned directly) - - // is it already cached? - var tmplts = dijit._Templated._templateCache; - var key = templateString || templatePath; - var cached = tmplts[key]; - if(cached){ - try{ - // if the cached value is an innerHTML string (no ownerDocument) or a DOM tree created within the current document, then use the current cached value - if(!cached.ownerDocument || cached.ownerDocument == dojo.doc){ - // string or node of the same document - return cached; - } - }catch(e){ /* squelch */ } // IE can throw an exception if cached.ownerDocument was reloaded - dojo.destroy(cached); - } - - // If necessary, load template string from template path - if(!templateString){ - templateString = dojo.cache(templatePath, {sanitize: true}); - } - templateString = dojo.string.trim(templateString); - - if(alwaysUseString || templateString.match(/\$\{([^\}]+)\}/g)){ - // there are variables in the template so all we can do is cache the string - return (tmplts[key] = templateString); //String - }else{ - // there are no variables in the template so we can cache the DOM tree - var node = dojo._toDom(templateString); - if(node.nodeType != 1){ - throw new Error("Invalid template: " + templateString); - } - return (tmplts[key] = node); //Node - } -}; - -if(dojo.isIE){ - dojo.addOnWindowUnload(function(){ - var cache = dijit._Templated._templateCache; - for(var key in cache){ - var value = cache[key]; - if(typeof value == "object"){ // value is either a string or a DOM node template - dojo.destroy(value); - } - delete cache[key]; - } - }); -} - -// These arguments can be specified for widgets which are used in templates. -// Since any widget can be specified as sub widgets in template, mix it -// into the base widget class. (This is a hack, but it's effective.) -dojo.extend(dijit._Widget,{ - dojoAttachEvent: "", - dojoAttachPoint: "", - waiRole: "", - waiState:"" -}); - -} +//>>built +define("dijit/_Templated",["./_WidgetBase","./_TemplatedMixin","./_WidgetsInTemplateMixin","dojo/_base/array","dojo/_base/declare","dojo/_base/lang","dojo/_base/kernel"],function(_1,_2,_3,_4,_5,_6,_7){_6.extend(_1,{waiRole:"",waiState:""});return _5("dijit._Templated",[_2,_3],{widgetsInTemplate:false,constructor:function(){_7.deprecated(this.declaredClass+": dijit._Templated deprecated, use dijit._TemplatedMixin and if necessary dijit._WidgetsInTemplateMixin","","2.0");},_attachTemplateNodes:function(_8,_9){this.inherited(arguments);var _a=_6.isArray(_8)?_8:(_8.all||_8.getElementsByTagName("*"));var x=_6.isArray(_8)?0:-1;for(;x<_a.length;x++){var _b=(x==-1)?_8:_a[x];var _c=_9(_b,"waiRole");if(_c){_b.setAttribute("role",_c);}var _d=_9(_b,"waiState");if(_d){_4.forEach(_d.split(/\s*,\s*/),function(_e){if(_e.indexOf("-")!=-1){var _f=_e.split("-");_b.setAttribute("aria-"+_f[0],_f[1]);}});}}}});});
\ No newline at end of file |