dijit/_Templated.js

  • Provides:

    • dijit._Templated
  • dijit._Templated

    • type
      Function
    • summary
      Mixin for widgets that are instantiated from a template
    • source: [view]
         this._attachPoints = [];
         this._attachEvents = [];
  • dijit._Templated.templateString

    • tags: protected
    • type
      String
    • summary
      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.
  • dijit._Templated.templatePath

    • tags: protected deprecated
    • type
      String
    • summary
      Path to template (HTML file) for this widget relative to dojo.baseUrl.
      Deprecated: use templateString with dojo.cache() instead.
  • dijit._Templated.widgetsInTemplate

    • tags: protected
    • type
      Boolean
    • summary
      Should we parse the template to find widgets that might be
      declared in markup inside it?  False by default.
  • dijit._Templated._skipNodeCache

    • summary
  • dijit._Templated._earlyTemplatedStartup

    • type
      Boolean
    • summary
      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.
  • dijit._Templated._attachPoints

    • tags: private
    • type
      String[
    • summary
      List of widget attribute names associated with dojoAttachPoint=... in the
      template, ex: ["containerNode", "labelNode"]
  • dijit._Templated._attachEvents

    • tags: private
    • type
      Handle[
    • summary
      List of connections associated with dojoAttachEvent=... in the
      template
  • dijit._Templated._stringRepl

    • type
      Function
    • parameters:
      • tmpl: (typeof )
    • source: [view]
         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);
    • summary
      Does substitution of ${foo} type properties in template string
    • tags:
  • dijit._Templated.buildRendering

    • type
      Function
    • source: [view]
      define("dijit/_Templated", ["dojo", "dijit", "dijit/_Widget", "dojo/string", "dojo/parser", "dojo/cache"], function(dojo, dijit) {


      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);
    • summary
      Construct the UI for this widget from a template, setting this.domNode.
  • dijit._Templated._fillContent

    • type
      Function
    • parameters:
      • source: (typeof DomNode)
    • source: [view]
         var dest = this.containerNode;
         if(source && dest){
          while(source.hasChildNodes()){
           dest.appendChild(source.firstChild);
          }
         }
    • summary
      Relocate source contents to templated container node.
      this.containerNode must be able to receive children, or exceptions will be thrown.
    • tags:
  • dijit._Templated._attachTemplateNodes

    • type
      Function
    • parameters:
      • rootNode: (typeof DomNode|Array[Widgets)
        the node to search for properties. All children will be searched.
      • getAttrFunc: (typeof Function)
        a function which will be used to obtain property for a given
        DomNode/Widget
    • source: [view]
         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    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]);
            }
           });
          }
         }
    • 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
    • tags:
  • dijit._Templated.startup

    • type
      Function
    • source: [view]
         dojo.forEach(this._startupWidgets, function(w){
          if(w && !w._started && w.startup){
           w.startup();
          }
         });
         this.inherited(arguments);
    • summary
  • dijit._Templated.destroyRendering

    • type
      Function
    • source: [view]
      define("dijit/_Templated", ["dojo", "dijit", "dijit/_Widget", "dojo/string", "dojo/parser", "dojo/cache"], function(dojo, dijit) {


      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    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);
    • summary
  • dijit._Templated.domNode

    • summary
  • dijit._Templated._startupWidgets

    • summary
  • dijit._Templated._supportingWidgets

    • summary
  • dijit._Templated._templateCache

    • type
      Object
    • summary
  • dijit._Templated.getCachedTemplate

    • type
      Function
    • parameters:
      • templatePath: (typeof String||dojo.uri.Uri)
        The URL to get the template from.
      • templateString: (typeof String)
        a string to use in lieu of fetching the template from a URL. Takes precedence
        over templatePath
      • alwaysUseString: (typeof )
    • source: [view]
      define("dijit/_Templated", ["dojo", "dijit", "dijit/_Widget", "dojo/string", "dojo/parser", "dojo/cache"], function(dojo, dijit) {


      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    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
       }
    • summary
      Static method to get a template based on the templatePath or
      templateString key
    • returns
      String|Node
  • dijit._Widget.dojoAttachEvent

    • summary
  • dijit._Widget.dojoAttachPoint

    • summary
  • dijit._Widget.waiRole

    • summary
  • dijit._Widget.waiState

    • summary
  • cache

    • summary
  • value

    • summary
  • dijit

    • type
      Object
    • summary