]>
Commit | Line | Data |
---|---|---|
f0cfe83e AD |
1 | define("dojo/dom", ["./sniff", "./_base/window"], |
2 | function(has, win){ | |
3 | // module: | |
4 | // dojo/dom | |
5 | ||
6 | // FIXME: need to add unit tests for all the semi-public methods | |
7 | ||
8 | if(has("ie") <= 7){ | |
9 | try{ | |
10 | document.execCommand("BackgroundImageCache", false, true); | |
11 | }catch(e){ | |
12 | // sane browsers don't have cache "issues" | |
13 | } | |
14 | } | |
15 | ||
16 | // ============================= | |
17 | // DOM Functions | |
18 | // ============================= | |
19 | ||
20 | // the result object | |
21 | var dom = { | |
22 | // summary: | |
23 | // This module defines the core dojo DOM API. | |
24 | }; | |
25 | ||
26 | if(has("ie")){ | |
27 | dom.byId = function(id, doc){ | |
28 | if(typeof id != "string"){ | |
29 | return id; | |
30 | } | |
31 | var _d = doc || win.doc, te = id && _d.getElementById(id); | |
32 | // attributes.id.value is better than just id in case the | |
33 | // user has a name=id inside a form | |
34 | if(te && (te.attributes.id.value == id || te.id == id)){ | |
35 | return te; | |
36 | }else{ | |
37 | var eles = _d.all[id]; | |
38 | if(!eles || eles.nodeName){ | |
39 | eles = [eles]; | |
40 | } | |
41 | // if more than 1, choose first with the correct id | |
42 | var i = 0; | |
43 | while((te = eles[i++])){ | |
44 | if((te.attributes && te.attributes.id && te.attributes.id.value == id) || te.id == id){ | |
45 | return te; | |
46 | } | |
47 | } | |
48 | } | |
49 | }; | |
50 | }else{ | |
51 | dom.byId = function(id, doc){ | |
52 | // inline'd type check. | |
53 | // be sure to return null per documentation, to match IE branch. | |
54 | return ((typeof id == "string") ? (doc || win.doc).getElementById(id) : id) || null; // DOMNode | |
55 | }; | |
56 | } | |
57 | /*===== | |
58 | dom.byId = function(id, doc){ | |
59 | // summary: | |
60 | // Returns DOM node with matching `id` attribute or falsy value (ex: null or undefined) | |
61 | // if not found. If `id` is a DomNode, this function is a no-op. | |
62 | // | |
63 | // id: String|DOMNode | |
64 | // A string to match an HTML id attribute or a reference to a DOM Node | |
65 | // | |
66 | // doc: Document? | |
67 | // Document to work in. Defaults to the current value of | |
68 | // dojo.doc. Can be used to retrieve | |
69 | // node references from other documents. | |
70 | // | |
71 | // example: | |
72 | // Look up a node by ID: | |
73 | // | var n = dojo.byId("foo"); | |
74 | // | |
75 | // example: | |
76 | // Check if a node exists, and use it. | |
77 | // | var n = dojo.byId("bar"); | |
78 | // | if(n){ doStuff() ... } | |
79 | // | |
80 | // example: | |
81 | // Allow string or DomNode references to be passed to a custom function: | |
82 | // | var foo = function(nodeOrId){ | |
83 | // | nodeOrId = dojo.byId(nodeOrId); | |
84 | // | // ... more stuff | |
85 | // | } | |
86 | }; | |
87 | =====*/ | |
88 | ||
89 | dom.isDescendant = function(/*DOMNode|String*/ node, /*DOMNode|String*/ ancestor){ | |
90 | // summary: | |
91 | // Returns true if node is a descendant of ancestor | |
92 | // node: DOMNode|String | |
93 | // string id or node reference to test | |
94 | // ancestor: DOMNode|String | |
95 | // string id or node reference of potential parent to test against | |
96 | // | |
97 | // example: | |
98 | // Test is node id="bar" is a descendant of node id="foo" | |
99 | // | if(dojo.isDescendant("bar", "foo")){ ... } | |
100 | ||
101 | try{ | |
102 | node = dom.byId(node); | |
103 | ancestor = dom.byId(ancestor); | |
104 | while(node){ | |
105 | if(node == ancestor){ | |
106 | return true; // Boolean | |
107 | } | |
108 | node = node.parentNode; | |
109 | } | |
110 | }catch(e){ /* squelch, return false */ } | |
111 | return false; // Boolean | |
112 | }; | |
113 | ||
114 | ||
115 | // TODO: do we need setSelectable in the base? | |
116 | ||
117 | // Add feature test for user-select CSS property | |
118 | // (currently known to work in all but IE < 10 and Opera) | |
119 | has.add("css-user-select", function(global, doc, element){ | |
120 | // Avoid exception when dom.js is loaded in non-browser environments | |
121 | if(!element){ return false; } | |
122 | ||
123 | var style = element.style; | |
124 | var prefixes = ["Khtml", "O", "ms", "Moz", "Webkit"], | |
125 | i = prefixes.length, | |
126 | name = "userSelect", | |
127 | prefix; | |
128 | ||
129 | // Iterate prefixes from most to least likely | |
130 | do{ | |
131 | if(typeof style[name] !== "undefined"){ | |
132 | // Supported; return property name | |
133 | return name; | |
134 | } | |
135 | }while(i-- && (name = prefixes[i] + "UserSelect")); | |
136 | ||
137 | // Not supported if we didn't return before now | |
138 | return false; | |
139 | }); | |
140 | ||
141 | /*===== | |
142 | dom.setSelectable = function(node, selectable){ | |
143 | // summary: | |
144 | // Enable or disable selection on a node | |
145 | // node: DOMNode|String | |
146 | // id or reference to node | |
147 | // selectable: Boolean | |
148 | // state to put the node in. false indicates unselectable, true | |
149 | // allows selection. | |
150 | // example: | |
151 | // Make the node id="bar" unselectable | |
152 | // | dojo.setSelectable("bar"); | |
153 | // example: | |
154 | // Make the node id="bar" selectable | |
155 | // | dojo.setSelectable("bar", true); | |
156 | }; | |
157 | =====*/ | |
158 | ||
159 | var cssUserSelect = has("css-user-select"); | |
160 | dom.setSelectable = cssUserSelect ? function(node, selectable){ | |
161 | // css-user-select returns a (possibly vendor-prefixed) CSS property name | |
162 | dom.byId(node).style[cssUserSelect] = selectable ? "" : "none"; | |
163 | } : function(node, selectable){ | |
164 | node = dom.byId(node); | |
165 | ||
166 | // (IE < 10 / Opera) Fall back to setting/removing the | |
167 | // unselectable attribute on the element and all its children | |
168 | var nodes = node.getElementsByTagName("*"), | |
169 | i = nodes.length; | |
170 | ||
171 | if(selectable){ | |
172 | node.removeAttribute("unselectable"); | |
173 | while(i--){ | |
174 | nodes[i].removeAttribute("unselectable"); | |
175 | } | |
176 | }else{ | |
177 | node.setAttribute("unselectable", "on"); | |
178 | while(i--){ | |
179 | nodes[i].setAttribute("unselectable", "on"); | |
180 | } | |
181 | } | |
182 | }; | |
183 | ||
184 | return dom; | |
185 | }); |