source: Dev/branches/rest-dojo-ui/client/dijit/registry.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

File size: 4.5 KB
Line 
1define([
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});
Note: See TracBrowser for help on using the repository browser.