]>
Commit | Line | Data |
---|---|---|
1354d172 AD |
1 | define("dojo/dom-prop", ["exports", "./_base/kernel", "./_base/sniff", "./_base/lang", "./dom", "./dom-style", "./dom-construct", "./_base/connect"], |
2 | function(exports, dojo, has, lang, dom, style, ctr, conn){ | |
3 | // module: | |
4 | // dojo/dom-prop | |
5 | // summary: | |
6 | // This module defines the core dojo DOM properties API. | |
7 | // Indirectly depends on dojo.empty() and dojo.toDom(). | |
8 | ||
9 | // ============================= | |
10 | // Element properties Functions | |
11 | // ============================= | |
12 | ||
13 | /*===== | |
14 | prop.get = function(node, name){ | |
15 | // summary: | |
16 | // Gets a property on an HTML element. | |
17 | // description: | |
18 | // Handles normalized getting of properties on DOM nodes. | |
19 | // | |
20 | // node: DOMNode|String | |
21 | // id or reference to the element to get the property on | |
22 | // name: String | |
23 | // the name of the property to get. | |
24 | // returns: | |
25 | // the value of the requested property or its default value | |
26 | // | |
27 | // example: | |
28 | // | // get the current value of the "foo" property on a node | |
29 | // | dojo.getProp(dojo.byId("nodeId"), "foo"); | |
30 | // | // or we can just pass the id: | |
31 | // | dojo.getProp("nodeId", "foo"); | |
32 | }; | |
33 | =====*/ | |
34 | ||
35 | /*===== | |
36 | prop.set = function(node, name, value){ | |
37 | // summary: | |
38 | // Sets a property on an HTML element. | |
39 | // description: | |
40 | // Handles normalized setting of properties on DOM nodes. | |
41 | // | |
42 | // When passing functions as values, note that they will not be | |
43 | // directly assigned to slots on the node, but rather the default | |
44 | // behavior will be removed and the new behavior will be added | |
45 | // using `dojo.connect()`, meaning that event handler properties | |
46 | // will be normalized and that some caveats with regards to | |
47 | // non-standard behaviors for onsubmit apply. Namely that you | |
48 | // should cancel form submission using `dojo.stopEvent()` on the | |
49 | // passed event object instead of returning a boolean value from | |
50 | // the handler itself. | |
51 | // node: DOMNode|String | |
52 | // id or reference to the element to set the property on | |
53 | // name: String|Object | |
54 | // the name of the property to set, or a hash object to set | |
55 | // multiple properties at once. | |
56 | // value: String? | |
57 | // The value to set for the property | |
58 | // returns: | |
59 | // the DOM node | |
60 | // | |
61 | // example: | |
62 | // | // use prop() to set the tab index | |
63 | // | dojo.setProp("nodeId", "tabIndex", 3); | |
64 | // | | |
65 | // | |
66 | // example: | |
67 | // Set multiple values at once, including event handlers: | |
68 | // | dojo.setProp("formId", { | |
69 | // | "foo": "bar", | |
70 | // | "tabIndex": -1, | |
71 | // | "method": "POST", | |
72 | // | "onsubmit": function(e){ | |
73 | // | // stop submitting the form. Note that the IE behavior | |
74 | // | // of returning true or false will have no effect here | |
75 | // | // since our handler is connect()ed to the built-in | |
76 | // | // onsubmit behavior and so we need to use | |
77 | // | // dojo.stopEvent() to ensure that the submission | |
78 | // | // doesn't proceed. | |
79 | // | dojo.stopEvent(e); | |
80 | // | | |
81 | // | // submit the form with Ajax | |
82 | // | dojo.xhrPost({ form: "formId" }); | |
83 | // | } | |
84 | // | }); | |
85 | // | |
86 | // example: | |
87 | // Style is s special case: Only set with an object hash of styles | |
88 | // | dojo.setProp("someNode",{ | |
89 | // | id:"bar", | |
90 | // | style:{ | |
91 | // | width:"200px", height:"100px", color:"#000" | |
92 | // | } | |
93 | // | }); | |
94 | // | |
95 | // example: | |
96 | // Again, only set style as an object hash of styles: | |
97 | // | var obj = { color:"#fff", backgroundColor:"#000" }; | |
98 | // | dojo.setProp("someNode", "style", obj); | |
99 | // | | |
100 | // | // though shorter to use `dojo.style()` in this case: | |
101 | // | dojo.style("someNode", obj); | |
102 | }; | |
103 | =====*/ | |
104 | ||
105 | // helper to connect events | |
106 | var _evtHdlrMap = {}, _ctr = 0, _attrId = dojo._scopeName + "attrid"; | |
107 | ||
108 | // the next dictionary lists elements with read-only innerHTML on IE | |
109 | var _roInnerHtml = {col: 1, colgroup: 1, | |
110 | // frameset: 1, head: 1, html: 1, style: 1, | |
111 | table: 1, tbody: 1, tfoot: 1, thead: 1, tr: 1, title: 1}; | |
112 | ||
113 | exports.names = { | |
114 | // properties renamed to avoid clashes with reserved words | |
115 | "class": "className", | |
116 | "for": "htmlFor", | |
117 | // properties written as camelCase | |
118 | tabindex: "tabIndex", | |
119 | readonly: "readOnly", | |
120 | colspan: "colSpan", | |
121 | frameborder: "frameBorder", | |
122 | rowspan: "rowSpan", | |
123 | valuetype: "valueType" | |
124 | }; | |
125 | ||
126 | exports.get = function getProp(/*DOMNode|String*/node, /*String*/name){ | |
127 | node = dom.byId(node); | |
128 | var lc = name.toLowerCase(), propName = exports.names[lc] || name; | |
129 | return node[propName]; // Anything | |
130 | }; | |
131 | ||
132 | exports.set = function setProp(/*DOMNode|String*/node, /*String|Object*/name, /*String?*/value){ | |
133 | node = dom.byId(node); | |
134 | var l = arguments.length; | |
135 | if(l == 2 && typeof name != "string"){ // inline'd type check | |
136 | // the object form of setter: the 2nd argument is a dictionary | |
137 | for(var x in name){ | |
138 | exports.set(node, x, name[x]); | |
139 | } | |
140 | return node; // DomNode | |
141 | } | |
142 | var lc = name.toLowerCase(), propName = exports.names[lc] || name; | |
143 | if(propName == "style" && typeof value != "string"){ // inline'd type check | |
144 | // special case: setting a style | |
145 | style.style(node, value); | |
146 | return node; // DomNode | |
147 | } | |
148 | if(propName == "innerHTML"){ | |
149 | // special case: assigning HTML | |
150 | if(has("ie") && node.tagName.toLowerCase() in _roInnerHtml){ | |
151 | ctr.empty(node); | |
152 | node.appendChild(ctr.toDom(value, node.ownerDocument)); | |
153 | }else{ | |
154 | node[propName] = value; | |
155 | } | |
156 | return node; // DomNode | |
157 | } | |
158 | if(lang.isFunction(value)){ | |
159 | // special case: assigning an event handler | |
160 | // clobber if we can | |
161 | var attrId = node[_attrId]; | |
162 | if(!attrId){ | |
163 | attrId = _ctr++; | |
164 | node[_attrId] = attrId; | |
165 | } | |
166 | if(!_evtHdlrMap[attrId]){ | |
167 | _evtHdlrMap[attrId] = {}; | |
168 | } | |
169 | var h = _evtHdlrMap[attrId][propName]; | |
170 | if(h){ | |
171 | //h.remove(); | |
172 | conn.disconnect(h); | |
173 | }else{ | |
174 | try{ | |
175 | delete node[propName]; | |
176 | }catch(e){} | |
177 | } | |
178 | // ensure that event objects are normalized, etc. | |
179 | if(value){ | |
180 | //_evtHdlrMap[attrId][propName] = on(node, propName, value); | |
181 | _evtHdlrMap[attrId][propName] = conn.connect(node, propName, value); | |
182 | }else{ | |
183 | node[propName] = null; | |
184 | } | |
185 | return node; // DomNode | |
186 | } | |
187 | node[propName] = value; | |
188 | return node; // DomNode | |
189 | }; | |
190 | }); |