]>
Commit | Line | Data |
---|---|---|
f0cfe83e AD |
1 | define("dijit/registry", [ |
2 | "dojo/_base/array", // array.forEach array.map | |
3 | "dojo/sniff", // has("ie") | |
4 | "dojo/_base/unload", // unload.addOnWindowUnload | |
5 | "dojo/_base/window", // win.body | |
6 | "./main" // dijit._scopeName | |
7 | ], function(array, has, unload, win, dijit){ | |
8 | ||
9 | // module: | |
10 | // dijit/registry | |
11 | ||
12 | var _widgetTypeCtr = {}, hash = {}; | |
13 | ||
14 | var registry = { | |
15 | // summary: | |
16 | // Registry of existing widget on page, plus some utility methods. | |
17 | ||
18 | // length: Number | |
19 | // Number of registered widgets | |
20 | length: 0, | |
21 | ||
22 | add: function(widget){ | |
23 | // summary: | |
24 | // Add a widget to the registry. If a duplicate ID is detected, a error is thrown. | |
25 | // widget: dijit/_WidgetBase | |
26 | // Any dijit/_WidgetBase subclass. | |
27 | if(hash[widget.id]){ | |
28 | throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered"); | |
29 | } | |
30 | hash[widget.id] = widget; | |
31 | this.length++; | |
32 | }, | |
33 | ||
34 | remove: function(/*String*/ id){ | |
35 | // summary: | |
36 | // Remove a widget from the registry. Does not destroy the widget; simply | |
37 | // removes the reference. | |
38 | if(hash[id]){ | |
39 | delete hash[id]; | |
40 | this.length--; | |
41 | } | |
42 | }, | |
43 | ||
44 | byId: function(/*String|Widget*/ id){ | |
45 | // summary: | |
46 | // Find a widget by it's id. | |
47 | // If passed a widget then just returns the widget. | |
48 | return typeof id == "string" ? hash[id] : id; // dijit/_WidgetBase | |
49 | }, | |
50 | ||
51 | byNode: function(/*DOMNode*/ node){ | |
52 | // summary: | |
53 | // Returns the widget corresponding to the given DOMNode | |
54 | return hash[node.getAttribute("widgetId")]; // dijit/_WidgetBase | |
55 | }, | |
56 | ||
57 | toArray: function(){ | |
58 | // summary: | |
59 | // Convert registry into a true Array | |
60 | // | |
61 | // example: | |
62 | // Work with the widget .domNodes in a real Array | |
63 | // | array.map(registry.toArray(), function(w){ return w.domNode; }); | |
64 | ||
65 | var ar = []; | |
66 | for(var id in hash){ | |
67 | ar.push(hash[id]); | |
68 | } | |
69 | return ar; // dijit/_WidgetBase[] | |
70 | }, | |
71 | ||
72 | getUniqueId: function(/*String*/widgetType){ | |
73 | // summary: | |
74 | // Generates a unique id for a given widgetType | |
75 | ||
76 | var id; | |
77 | do{ | |
78 | id = widgetType + "_" + | |
79 | (widgetType in _widgetTypeCtr ? | |
80 | ++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0); | |
81 | }while(hash[id]); | |
82 | return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String | |
83 | }, | |
84 | ||
85 | findWidgets: function(root, skipNode){ | |
86 | // summary: | |
87 | // Search subtree under root returning widgets found. | |
88 | // Doesn't search for nested widgets (ie, widgets inside other widgets). | |
89 | // root: DOMNode | |
90 | // Node to search under. | |
91 | // skipNode: DOMNode | |
92 | // If specified, don't search beneath this node (usually containerNode). | |
93 | ||
94 | var outAry = []; | |
95 | ||
96 | function getChildrenHelper(root){ | |
97 | for(var node = root.firstChild; node; node = node.nextSibling){ | |
98 | if(node.nodeType == 1){ | |
99 | var widgetId = node.getAttribute("widgetId"); | |
100 | if(widgetId){ | |
101 | var widget = hash[widgetId]; | |
102 | if(widget){ // may be null on page w/multiple dojo's loaded | |
103 | outAry.push(widget); | |
104 | } | |
105 | }else if(node !== skipNode){ | |
106 | getChildrenHelper(node); | |
107 | } | |
108 | } | |
109 | } | |
110 | } | |
111 | ||
112 | getChildrenHelper(root); | |
113 | return outAry; | |
114 | }, | |
115 | ||
116 | _destroyAll: function(){ | |
117 | // summary: | |
118 | // Code to destroy all widgets and do other cleanup on page unload | |
119 | ||
120 | // Clean up focus manager lingering references to widgets and nodes | |
121 | dijit._curFocus = null; | |
122 | dijit._prevFocus = null; | |
123 | dijit._activeStack = []; | |
124 | ||
125 | // Destroy all the widgets, top down | |
126 | array.forEach(registry.findWidgets(win.body()), function(widget){ | |
127 | // Avoid double destroy of widgets like Menu that are attached to <body> | |
128 | // even though they are logically children of other widgets. | |
129 | if(!widget._destroyed){ | |
130 | if(widget.destroyRecursive){ | |
131 | widget.destroyRecursive(); | |
132 | }else if(widget.destroy){ | |
133 | widget.destroy(); | |
134 | } | |
135 | } | |
136 | }); | |
137 | }, | |
138 | ||
139 | getEnclosingWidget: function(/*DOMNode*/ node){ | |
140 | // summary: | |
141 | // Returns the widget whose DOM tree contains the specified DOMNode, or null if | |
142 | // the node is not contained within the DOM tree of any widget | |
143 | while(node){ | |
144 | var id = node.nodeType == 1 && node.getAttribute("widgetId"); | |
145 | if(id){ | |
146 | return hash[id]; | |
147 | } | |
148 | node = node.parentNode; | |
149 | } | |
150 | return null; | |
151 | }, | |
152 | ||
153 | // In case someone needs to access hash. | |
154 | // Actually, this is accessed from WidgetSet back-compatibility code | |
155 | _hash: hash | |
156 | }; | |
157 | ||
158 | dijit.registry = registry; | |
159 | ||
160 | return registry; | |
161 | }); |