|
1 /* |
|
2 YUI 3.10.3 (build 2fb5187) |
|
3 Copyright 2013 Yahoo! Inc. All rights reserved. |
|
4 Licensed under the BSD License. |
|
5 http://yuilibrary.com/license/ |
|
6 */ |
|
7 |
|
8 YUI.add('dom-style', function (Y, NAME) { |
|
9 |
|
10 (function(Y) { |
|
11 /** |
|
12 * Add style management functionality to DOM. |
|
13 * @module dom |
|
14 * @submodule dom-style |
|
15 * @for DOM |
|
16 */ |
|
17 |
|
18 var DOCUMENT_ELEMENT = 'documentElement', |
|
19 DEFAULT_VIEW = 'defaultView', |
|
20 OWNER_DOCUMENT = 'ownerDocument', |
|
21 STYLE = 'style', |
|
22 FLOAT = 'float', |
|
23 CSS_FLOAT = 'cssFloat', |
|
24 STYLE_FLOAT = 'styleFloat', |
|
25 TRANSPARENT = 'transparent', |
|
26 GET_COMPUTED_STYLE = 'getComputedStyle', |
|
27 GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect', |
|
28 |
|
29 WINDOW = Y.config.win, |
|
30 DOCUMENT = Y.config.doc, |
|
31 UNDEFINED = undefined, |
|
32 |
|
33 Y_DOM = Y.DOM, |
|
34 |
|
35 TRANSFORM = 'transform', |
|
36 TRANSFORMORIGIN = 'transformOrigin', |
|
37 VENDOR_TRANSFORM = [ |
|
38 'WebkitTransform', |
|
39 'MozTransform', |
|
40 'OTransform', |
|
41 'msTransform' |
|
42 ], |
|
43 |
|
44 re_color = /color$/i, |
|
45 re_unit = /width|height|top|left|right|bottom|margin|padding/i; |
|
46 |
|
47 Y.Array.each(VENDOR_TRANSFORM, function(val) { |
|
48 if (val in DOCUMENT[DOCUMENT_ELEMENT].style) { |
|
49 TRANSFORM = val; |
|
50 TRANSFORMORIGIN = val + "Origin"; |
|
51 } |
|
52 }); |
|
53 |
|
54 Y.mix(Y_DOM, { |
|
55 DEFAULT_UNIT: 'px', |
|
56 |
|
57 CUSTOM_STYLES: { |
|
58 }, |
|
59 |
|
60 |
|
61 /** |
|
62 * Sets a style property for a given element. |
|
63 * @method setStyle |
|
64 * @param {HTMLElement} An HTMLElement to apply the style to. |
|
65 * @param {String} att The style property to set. |
|
66 * @param {String|Number} val The value. |
|
67 */ |
|
68 setStyle: function(node, att, val, style) { |
|
69 style = style || node.style; |
|
70 var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES; |
|
71 |
|
72 if (style) { |
|
73 if (val === null || val === '') { // normalize unsetting |
|
74 val = ''; |
|
75 } else if (!isNaN(new Number(val)) && re_unit.test(att)) { // number values may need a unit |
|
76 val += Y_DOM.DEFAULT_UNIT; |
|
77 } |
|
78 |
|
79 if (att in CUSTOM_STYLES) { |
|
80 if (CUSTOM_STYLES[att].set) { |
|
81 CUSTOM_STYLES[att].set(node, val, style); |
|
82 return; // NOTE: return |
|
83 } else if (typeof CUSTOM_STYLES[att] === 'string') { |
|
84 att = CUSTOM_STYLES[att]; |
|
85 } |
|
86 } else if (att === '') { // unset inline styles |
|
87 att = 'cssText'; |
|
88 val = ''; |
|
89 } |
|
90 style[att] = val; |
|
91 } |
|
92 }, |
|
93 |
|
94 /** |
|
95 * Returns the current style value for the given property. |
|
96 * @method getStyle |
|
97 * @param {HTMLElement} An HTMLElement to get the style from. |
|
98 * @param {String} att The style property to get. |
|
99 */ |
|
100 getStyle: function(node, att, style) { |
|
101 style = style || node.style; |
|
102 var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES, |
|
103 val = ''; |
|
104 |
|
105 if (style) { |
|
106 if (att in CUSTOM_STYLES) { |
|
107 if (CUSTOM_STYLES[att].get) { |
|
108 return CUSTOM_STYLES[att].get(node, att, style); // NOTE: return |
|
109 } else if (typeof CUSTOM_STYLES[att] === 'string') { |
|
110 att = CUSTOM_STYLES[att]; |
|
111 } |
|
112 } |
|
113 val = style[att]; |
|
114 if (val === '') { // TODO: is empty string sufficient? |
|
115 val = Y_DOM[GET_COMPUTED_STYLE](node, att); |
|
116 } |
|
117 } |
|
118 |
|
119 return val; |
|
120 }, |
|
121 |
|
122 /** |
|
123 * Sets multiple style properties. |
|
124 * @method setStyles |
|
125 * @param {HTMLElement} node An HTMLElement to apply the styles to. |
|
126 * @param {Object} hash An object literal of property:value pairs. |
|
127 */ |
|
128 setStyles: function(node, hash) { |
|
129 var style = node.style; |
|
130 Y.each(hash, function(v, n) { |
|
131 Y_DOM.setStyle(node, n, v, style); |
|
132 }, Y_DOM); |
|
133 }, |
|
134 |
|
135 /** |
|
136 * Returns the computed style for the given node. |
|
137 * @method getComputedStyle |
|
138 * @param {HTMLElement} An HTMLElement to get the style from. |
|
139 * @param {String} att The style property to get. |
|
140 * @return {String} The computed value of the style property. |
|
141 */ |
|
142 getComputedStyle: function(node, att) { |
|
143 var val = '', |
|
144 doc = node[OWNER_DOCUMENT], |
|
145 computed; |
|
146 |
|
147 if (node[STYLE] && doc[DEFAULT_VIEW] && doc[DEFAULT_VIEW][GET_COMPUTED_STYLE]) { |
|
148 computed = doc[DEFAULT_VIEW][GET_COMPUTED_STYLE](node, null); |
|
149 if (computed) { // FF may be null in some cases (ticket #2530548) |
|
150 val = computed[att]; |
|
151 } |
|
152 } |
|
153 return val; |
|
154 } |
|
155 }); |
|
156 |
|
157 // normalize reserved word float alternatives ("cssFloat" or "styleFloat") |
|
158 if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][CSS_FLOAT] !== UNDEFINED) { |
|
159 Y_DOM.CUSTOM_STYLES[FLOAT] = CSS_FLOAT; |
|
160 } else if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][STYLE_FLOAT] !== UNDEFINED) { |
|
161 Y_DOM.CUSTOM_STYLES[FLOAT] = STYLE_FLOAT; |
|
162 } |
|
163 |
|
164 // fix opera computedStyle default color unit (convert to rgb) |
|
165 if (Y.UA.opera) { |
|
166 Y_DOM[GET_COMPUTED_STYLE] = function(node, att) { |
|
167 var view = node[OWNER_DOCUMENT][DEFAULT_VIEW], |
|
168 val = view[GET_COMPUTED_STYLE](node, '')[att]; |
|
169 |
|
170 if (re_color.test(att)) { |
|
171 val = Y.Color.toRGB(val); |
|
172 } |
|
173 |
|
174 return val; |
|
175 }; |
|
176 |
|
177 } |
|
178 |
|
179 // safari converts transparent to rgba(), others use "transparent" |
|
180 if (Y.UA.webkit) { |
|
181 Y_DOM[GET_COMPUTED_STYLE] = function(node, att) { |
|
182 var view = node[OWNER_DOCUMENT][DEFAULT_VIEW], |
|
183 val = view[GET_COMPUTED_STYLE](node, '')[att]; |
|
184 |
|
185 if (val === 'rgba(0, 0, 0, 0)') { |
|
186 val = TRANSPARENT; |
|
187 } |
|
188 |
|
189 return val; |
|
190 }; |
|
191 |
|
192 } |
|
193 |
|
194 Y.DOM._getAttrOffset = function(node, attr) { |
|
195 var val = Y.DOM[GET_COMPUTED_STYLE](node, attr), |
|
196 offsetParent = node.offsetParent, |
|
197 position, |
|
198 parentOffset, |
|
199 offset; |
|
200 |
|
201 if (val === 'auto') { |
|
202 position = Y.DOM.getStyle(node, 'position'); |
|
203 if (position === 'static' || position === 'relative') { |
|
204 val = 0; |
|
205 } else if (offsetParent && offsetParent[GET_BOUNDING_CLIENT_RECT]) { |
|
206 parentOffset = offsetParent[GET_BOUNDING_CLIENT_RECT]()[attr]; |
|
207 offset = node[GET_BOUNDING_CLIENT_RECT]()[attr]; |
|
208 if (attr === 'left' || attr === 'top') { |
|
209 val = offset - parentOffset; |
|
210 } else { |
|
211 val = parentOffset - node[GET_BOUNDING_CLIENT_RECT]()[attr]; |
|
212 } |
|
213 } |
|
214 } |
|
215 |
|
216 return val; |
|
217 }; |
|
218 |
|
219 Y.DOM._getOffset = function(node) { |
|
220 var pos, |
|
221 xy = null; |
|
222 |
|
223 if (node) { |
|
224 pos = Y_DOM.getStyle(node, 'position'); |
|
225 xy = [ |
|
226 parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'left'), 10), |
|
227 parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'top'), 10) |
|
228 ]; |
|
229 |
|
230 if ( isNaN(xy[0]) ) { // in case of 'auto' |
|
231 xy[0] = parseInt(Y_DOM.getStyle(node, 'left'), 10); // try inline |
|
232 if ( isNaN(xy[0]) ) { // default to offset value |
|
233 xy[0] = (pos === 'relative') ? 0 : node.offsetLeft || 0; |
|
234 } |
|
235 } |
|
236 |
|
237 if ( isNaN(xy[1]) ) { // in case of 'auto' |
|
238 xy[1] = parseInt(Y_DOM.getStyle(node, 'top'), 10); // try inline |
|
239 if ( isNaN(xy[1]) ) { // default to offset value |
|
240 xy[1] = (pos === 'relative') ? 0 : node.offsetTop || 0; |
|
241 } |
|
242 } |
|
243 } |
|
244 |
|
245 return xy; |
|
246 |
|
247 }; |
|
248 |
|
249 Y_DOM.CUSTOM_STYLES.transform = { |
|
250 set: function(node, val, style) { |
|
251 style[TRANSFORM] = val; |
|
252 }, |
|
253 |
|
254 get: function(node, style) { |
|
255 return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORM); |
|
256 } |
|
257 }; |
|
258 |
|
259 Y_DOM.CUSTOM_STYLES.transformOrigin = { |
|
260 set: function(node, val, style) { |
|
261 style[TRANSFORMORIGIN] = val; |
|
262 }, |
|
263 |
|
264 get: function(node, style) { |
|
265 return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORMORIGIN); |
|
266 } |
|
267 }; |
|
268 |
|
269 |
|
270 })(Y); |
|
271 |
|
272 |
|
273 }, '3.10.3', {"requires": ["dom-base", "color-base"]}); |