You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
4.2 KiB
108 lines
4.2 KiB
define([ |
|
"dojo/_base/array", // forEach() |
|
"dojo/aspect", // after() |
|
"dojo/_base/declare", // declare() |
|
"dojo/_base/lang", // hitch() |
|
"dojo/parser" // parse() |
|
], function(array, aspect, declare, lang, parser){ |
|
|
|
// module: |
|
// dijit/_WidgetsInTemplateMixin |
|
|
|
return declare("dijit._WidgetsInTemplateMixin", null, { |
|
// summary: |
|
// Mixin to supplement _TemplatedMixin when template contains widgets |
|
|
|
// _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, |
|
|
|
// contextRequire: Function |
|
// Used to provide a context require to the dojo/parser in order to be |
|
// able to use relative MIDs (e.g. `./Widget`) in the widget's template. |
|
contextRequire: null, |
|
|
|
_beforeFillContent: function(){ |
|
// Short circuit the parser when the template doesn't contain any widgets. Note that checking against |
|
// this.templateString is insufficient because the data-dojo-type=... may appear through a substitution |
|
// variable, like in ConfirmDialog, where the widget is hidden inside of the ${!actionBarTemplate}. |
|
if(/dojoType|data-dojo-type/i.test(this.domNode.innerHTML)){ |
|
// Before copying over content, instantiate widgets in template |
|
var node = this.domNode; |
|
|
|
if(this.containerNode && !this.searchContainerNode){ |
|
// Tell parse call below not to look for widgets inside of this.containerNode |
|
this.containerNode.stopParser = true; |
|
} |
|
|
|
parser.parse(node, { |
|
noStart: !this._earlyTemplatedStartup, |
|
template: true, |
|
inherited: {dir: this.dir, lang: this.lang, textDir: this.textDir}, |
|
propsThis: this, // so data-dojo-props of widgets in the template can reference "this" to refer to me |
|
contextRequire: this.contextRequire, |
|
scope: "dojo" // even in multi-version mode templates use dojoType/data-dojo-type |
|
}).then(lang.hitch(this, function(widgets){ |
|
this._startupWidgets = widgets; |
|
|
|
// _WidgetBase::destroy() will destroy any supporting widgets under this.domNode. |
|
// If we wanted to, we could call this.own() on anything in this._startupWidgets that was moved outside |
|
// of this.domNode (like Dialog, which is moved to <body>). |
|
|
|
// Hook up attach points and events for nodes that were converted to widgets |
|
for(var i = 0; i < widgets.length; i++){ |
|
this._processTemplateNode(widgets[i], function(n,p){ |
|
// callback to get a property of a widget |
|
return n[p]; |
|
}, function(widget, type, callback){ |
|
// callback to do data-dojo-attach-event to a widget |
|
if(type in widget){ |
|
// back-compat, remove for 2.0 |
|
return widget.connect(widget, type, callback); |
|
}else{ |
|
// 1.x may never hit this branch, but it's the default for 2.0 |
|
return widget.on(type, callback, true); |
|
} |
|
}); |
|
} |
|
|
|
// Cleanup flag set above, just in case |
|
if(this.containerNode && this.containerNode.stopParser){ |
|
delete this.containerNode.stopParser; |
|
} |
|
})); |
|
|
|
if(!this._startupWidgets){ |
|
throw new Error(this.declaredClass + ": parser returned unfilled promise (probably waiting for module auto-load), " + |
|
"unsupported by _WidgetsInTemplateMixin. Must pre-load all supporting widgets before instantiation."); |
|
} |
|
} |
|
}, |
|
|
|
_processTemplateNode: function(/*DOMNode|Widget*/ baseNode, getAttrFunc, attachFunc){ |
|
// Override _AttachMixin._processNode to skip DOMNodes with data-dojo-type set. They are handled separately |
|
// in the _beforeFillContent() code above. |
|
|
|
if(getAttrFunc(baseNode, "dojoType") || getAttrFunc(baseNode, "data-dojo-type")){ |
|
return true; |
|
} |
|
|
|
return this.inherited(arguments); |
|
}, |
|
|
|
startup: function(){ |
|
array.forEach(this._startupWidgets, function(w){ |
|
if(w && !w._started && w.startup){ |
|
w.startup(); |
|
} |
|
}); |
|
this._startupWidgets = null; |
|
this.inherited(arguments); |
|
} |
|
}); |
|
});
|
|
|