176 lines
4.6 KiB
JavaScript
176 lines
4.6 KiB
JavaScript
|
//>>built
|
||
|
define("dijit/registry", [
|
||
|
"dojo/_base/array", // array.forEach array.map
|
||
|
"dojo/_base/sniff", // has("ie")
|
||
|
"dojo/_base/unload", // unload.addOnWindowUnload
|
||
|
"dojo/_base/window", // win.body
|
||
|
"." // dijit._scopeName
|
||
|
], function(array, has, unload, win, dijit){
|
||
|
|
||
|
// module:
|
||
|
// dijit/registry
|
||
|
// summary:
|
||
|
// Registry of existing widget on page, plus some utility methods.
|
||
|
// Must be accessed through AMD api, ex:
|
||
|
// require(["dijit/registry"], function(registry){ registry.byId("foo"); })
|
||
|
|
||
|
var _widgetTypeCtr = {}, hash = {};
|
||
|
|
||
|
var registry = {
|
||
|
// summary:
|
||
|
// A set of widgets indexed by id
|
||
|
|
||
|
length: 0,
|
||
|
|
||
|
add: function(/*dijit._Widget*/ widget){
|
||
|
// summary:
|
||
|
// Add a widget to the registry. If a duplicate ID is detected, a error is thrown.
|
||
|
//
|
||
|
// widget: dijit._Widget
|
||
|
// Any dijit._Widget subclass.
|
||
|
if(hash[widget.id]){
|
||
|
throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered");
|
||
|
}
|
||
|
hash[widget.id] = widget;
|
||
|
this.length++;
|
||
|
},
|
||
|
|
||
|
remove: function(/*String*/ id){
|
||
|
// summary:
|
||
|
// Remove a widget from the registry. Does not destroy the widget; simply
|
||
|
// removes the reference.
|
||
|
if(hash[id]){
|
||
|
delete hash[id];
|
||
|
this.length--;
|
||
|
}
|
||
|
},
|
||
|
|
||
|
byId: function(/*String|Widget*/ id){
|
||
|
// summary:
|
||
|
// Find a widget by it's id.
|
||
|
// If passed a widget then just returns the widget.
|
||
|
return typeof id == "string" ? hash[id] : id; // dijit._Widget
|
||
|
},
|
||
|
|
||
|
byNode: function(/*DOMNode*/ node){
|
||
|
// summary:
|
||
|
// Returns the widget corresponding to the given DOMNode
|
||
|
return hash[node.getAttribute("widgetId")]; // dijit._Widget
|
||
|
},
|
||
|
|
||
|
toArray: function(){
|
||
|
// summary:
|
||
|
// Convert registry into a true Array
|
||
|
//
|
||
|
// example:
|
||
|
// Work with the widget .domNodes in a real Array
|
||
|
// | array.map(dijit.registry.toArray(), function(w){ return w.domNode; });
|
||
|
|
||
|
var ar = [];
|
||
|
for(var id in hash){
|
||
|
ar.push(hash[id]);
|
||
|
}
|
||
|
return ar; // dijit._Widget[]
|
||
|
},
|
||
|
|
||
|
getUniqueId: function(/*String*/widgetType){
|
||
|
// summary:
|
||
|
// Generates a unique id for a given widgetType
|
||
|
|
||
|
var id;
|
||
|
do{
|
||
|
id = widgetType + "_" +
|
||
|
(widgetType in _widgetTypeCtr ?
|
||
|
++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0);
|
||
|
}while(hash[id]);
|
||
|
return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String
|
||
|
},
|
||
|
|
||
|
findWidgets: function(/*DomNode*/ root){
|
||
|
// summary:
|
||
|
// Search subtree under root returning widgets found.
|
||
|
// Doesn't search for nested widgets (ie, widgets inside other widgets).
|
||
|
|
||
|
var outAry = [];
|
||
|
|
||
|
function getChildrenHelper(root){
|
||
|
for(var node = root.firstChild; node; node = node.nextSibling){
|
||
|
if(node.nodeType == 1){
|
||
|
var widgetId = node.getAttribute("widgetId");
|
||
|
if(widgetId){
|
||
|
var widget = hash[widgetId];
|
||
|
if(widget){ // may be null on page w/multiple dojo's loaded
|
||
|
outAry.push(widget);
|
||
|
}
|
||
|
}else{
|
||
|
getChildrenHelper(node);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
getChildrenHelper(root);
|
||
|
return outAry;
|
||
|
},
|
||
|
|
||
|
_destroyAll: function(){
|
||
|
// summary:
|
||
|
// Code to destroy all widgets and do other cleanup on page unload
|
||
|
|
||
|
// Clean up focus manager lingering references to widgets and nodes
|
||
|
dijit._curFocus = null;
|
||
|
dijit._prevFocus = null;
|
||
|
dijit._activeStack = [];
|
||
|
|
||
|
// Destroy all the widgets, top down
|
||
|
array.forEach(registry.findWidgets(win.body()), function(widget){
|
||
|
// Avoid double destroy of widgets like Menu that are attached to <body>
|
||
|
// even though they are logically children of other widgets.
|
||
|
if(!widget._destroyed){
|
||
|
if(widget.destroyRecursive){
|
||
|
widget.destroyRecursive();
|
||
|
}else if(widget.destroy){
|
||
|
widget.destroy();
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
},
|
||
|
|
||
|
getEnclosingWidget: function(/*DOMNode*/ node){
|
||
|
// summary:
|
||
|
// Returns the widget whose DOM tree contains the specified DOMNode, or null if
|
||
|
// the node is not contained within the DOM tree of any widget
|
||
|
while(node){
|
||
|
var id = node.getAttribute && node.getAttribute("widgetId");
|
||
|
if(id){
|
||
|
return hash[id];
|
||
|
}
|
||
|
node = node.parentNode;
|
||
|
}
|
||
|
return null;
|
||
|
},
|
||
|
|
||
|
// In case someone needs to access hash.
|
||
|
// Actually, this is accessed from WidgetSet back-compatibility code
|
||
|
_hash: hash
|
||
|
};
|
||
|
|
||
|
if(has("ie")){
|
||
|
// Only run _destroyAll() for IE because we think it's only necessary in that case,
|
||
|
// and because it causes problems on FF. See bug #3531 for details.
|
||
|
unload.addOnWindowUnload(function(){
|
||
|
registry._destroyAll();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/*=====
|
||
|
dijit.registry = {
|
||
|
// summary:
|
||
|
// A list of widgets on a page.
|
||
|
};
|
||
|
=====*/
|
||
|
dijit.registry = registry;
|
||
|
|
||
|
return registry;
|
||
|
});
|