[483] | 1 | define([ |
---|
| 2 | "dojo/_base/array", // array.forEach array.map |
---|
| 3 | "dojo/sniff", // has("ie") |
---|
| 4 | "dojo/_base/window", // win.body |
---|
| 5 | "./main" // dijit._scopeName |
---|
| 6 | ], function(array, has, win, dijit){ |
---|
| 7 | |
---|
| 8 | // module: |
---|
| 9 | // dijit/registry |
---|
| 10 | |
---|
| 11 | var _widgetTypeCtr = {}, hash = {}; |
---|
| 12 | |
---|
| 13 | var registry = { |
---|
| 14 | // summary: |
---|
| 15 | // Registry of existing widget on page, plus some utility methods. |
---|
| 16 | |
---|
| 17 | // length: Number |
---|
| 18 | // Number of registered widgets |
---|
| 19 | length: 0, |
---|
| 20 | |
---|
| 21 | add: function(widget){ |
---|
| 22 | // summary: |
---|
| 23 | // Add a widget to the registry. If a duplicate ID is detected, a error is thrown. |
---|
| 24 | // widget: dijit/_WidgetBase |
---|
| 25 | // Any dijit/_WidgetBase subclass. |
---|
| 26 | if(hash[widget.id]){ |
---|
| 27 | throw new Error("Tried to register widget with id==" + widget.id + " but that id is already registered"); |
---|
| 28 | } |
---|
| 29 | hash[widget.id] = widget; |
---|
| 30 | this.length++; |
---|
| 31 | }, |
---|
| 32 | |
---|
| 33 | remove: function(/*String*/ id){ |
---|
| 34 | // summary: |
---|
| 35 | // Remove a widget from the registry. Does not destroy the widget; simply |
---|
| 36 | // removes the reference. |
---|
| 37 | if(hash[id]){ |
---|
| 38 | delete hash[id]; |
---|
| 39 | this.length--; |
---|
| 40 | } |
---|
| 41 | }, |
---|
| 42 | |
---|
| 43 | byId: function(/*String|Widget*/ id){ |
---|
| 44 | // summary: |
---|
| 45 | // Find a widget by it's id. |
---|
| 46 | // If passed a widget then just returns the widget. |
---|
| 47 | return typeof id == "string" ? hash[id] : id; // dijit/_WidgetBase |
---|
| 48 | }, |
---|
| 49 | |
---|
| 50 | byNode: function(/*DOMNode*/ node){ |
---|
| 51 | // summary: |
---|
| 52 | // Returns the widget corresponding to the given DOMNode |
---|
| 53 | return hash[node.getAttribute("widgetId")]; // dijit/_WidgetBase |
---|
| 54 | }, |
---|
| 55 | |
---|
| 56 | toArray: function(){ |
---|
| 57 | // summary: |
---|
| 58 | // Convert registry into a true Array |
---|
| 59 | // |
---|
| 60 | // example: |
---|
| 61 | // Work with the widget .domNodes in a real Array |
---|
| 62 | // | array.map(registry.toArray(), function(w){ return w.domNode; }); |
---|
| 63 | |
---|
| 64 | var ar = []; |
---|
| 65 | for(var id in hash){ |
---|
| 66 | ar.push(hash[id]); |
---|
| 67 | } |
---|
| 68 | return ar; // dijit/_WidgetBase[] |
---|
| 69 | }, |
---|
| 70 | |
---|
| 71 | getUniqueId: function(/*String*/widgetType){ |
---|
| 72 | // summary: |
---|
| 73 | // Generates a unique id for a given widgetType |
---|
| 74 | |
---|
| 75 | var id; |
---|
| 76 | do{ |
---|
| 77 | id = widgetType + "_" + |
---|
| 78 | (widgetType in _widgetTypeCtr ? |
---|
| 79 | ++_widgetTypeCtr[widgetType] : _widgetTypeCtr[widgetType] = 0); |
---|
| 80 | }while(hash[id]); |
---|
| 81 | return dijit._scopeName == "dijit" ? id : dijit._scopeName + "_" + id; // String |
---|
| 82 | }, |
---|
| 83 | |
---|
| 84 | findWidgets: function(root, skipNode){ |
---|
| 85 | // summary: |
---|
| 86 | // Search subtree under root returning widgets found. |
---|
| 87 | // Doesn't search for nested widgets (ie, widgets inside other widgets). |
---|
| 88 | // root: DOMNode |
---|
| 89 | // Node to search under. |
---|
| 90 | // skipNode: DOMNode |
---|
| 91 | // If specified, don't search beneath this node (usually containerNode). |
---|
| 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 if(node !== skipNode){ |
---|
| 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.nodeType == 1 && 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 | dijit.registry = registry; |
---|
| 158 | |
---|
| 159 | return registry; |
---|
| 160 | }); |
---|