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