MDL-32843 import YUI 3.5.1
[moodle.git] / lib / yui / 3.5.1 / build / dom-style / dom-style-debug.js
blob59af1d66fa57c7458562668e38193ca30e931c1d
1 /*
2 YUI 3.5.1 (build 22)
3 Copyright 2012 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
7 YUI.add('dom-style', function(Y) {
9 (function(Y) {
10 /** 
11  * Add style management functionality to DOM.
12  * @module dom
13  * @submodule dom-style
14  * @for DOM
15  */
17 var DOCUMENT_ELEMENT = 'documentElement',
18     DEFAULT_VIEW = 'defaultView',
19     OWNER_DOCUMENT = 'ownerDocument',
20     STYLE = 'style',
21     FLOAT = 'float',
22     CSS_FLOAT = 'cssFloat',
23     STYLE_FLOAT = 'styleFloat',
24     TRANSPARENT = 'transparent',
25     GET_COMPUTED_STYLE = 'getComputedStyle',
26     GET_BOUNDING_CLIENT_RECT = 'getBoundingClientRect',
28     WINDOW = Y.config.win,
29     DOCUMENT = Y.config.doc,
30     UNDEFINED = undefined,
32     Y_DOM = Y.DOM,
34     TRANSFORM = 'transform',
35     VENDOR_TRANSFORM = [
36         'WebkitTransform',
37         'MozTransform',
38         'OTransform'
39     ],
41     re_color = /color$/i,
42     re_unit = /width|height|top|left|right|bottom|margin|padding/i;
44 Y.Array.each(VENDOR_TRANSFORM, function(val) {
45     if (val in DOCUMENT[DOCUMENT_ELEMENT].style) {
46         TRANSFORM = val;
47     }
48 });
50 Y.mix(Y_DOM, {
51     DEFAULT_UNIT: 'px',
53     CUSTOM_STYLES: {
54     },
57     /**
58      * Sets a style property for a given element.
59      * @method setStyle
60      * @param {HTMLElement} An HTMLElement to apply the style to.
61      * @param {String} att The style property to set. 
62      * @param {String|Number} val The value. 
63      */
64     setStyle: function(node, att, val, style) {
65         style = style || node.style;
66         var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES;
68         if (style) {
69             if (val === null || val === '') { // normalize unsetting
70                 val = '';
71             } else if (!isNaN(new Number(val)) && re_unit.test(att)) { // number values may need a unit
72                 val += Y_DOM.DEFAULT_UNIT;
73             }
75             if (att in CUSTOM_STYLES) {
76                 if (CUSTOM_STYLES[att].set) {
77                     CUSTOM_STYLES[att].set(node, val, style);
78                     return; // NOTE: return
79                 } else if (typeof CUSTOM_STYLES[att] === 'string') {
80                     att = CUSTOM_STYLES[att];
81                 }
82             } else if (att === '') { // unset inline styles
83                 att = 'cssText';
84                 val = '';
85             }
86             style[att] = val; 
87         }
88     },
90     /**
91      * Returns the current style value for the given property.
92      * @method getStyle
93      * @param {HTMLElement} An HTMLElement to get the style from.
94      * @param {String} att The style property to get. 
95      */
96     getStyle: function(node, att, style) {
97         style = style || node.style;
98         var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES,
99             val = '';
101         if (style) {
102             if (att in CUSTOM_STYLES) {
103                 if (CUSTOM_STYLES[att].get) {
104                     return CUSTOM_STYLES[att].get(node, att, style); // NOTE: return
105                 } else if (typeof CUSTOM_STYLES[att] === 'string') {
106                     att = CUSTOM_STYLES[att];
107                 }
108             }
109             val = style[att];
110             if (val === '') { // TODO: is empty string sufficient?
111                 val = Y_DOM[GET_COMPUTED_STYLE](node, att);
112             }
113         }
115         return val;
116     },
118     /**
119      * Sets multiple style properties.
120      * @method setStyles
121      * @param {HTMLElement} node An HTMLElement to apply the styles to. 
122      * @param {Object} hash An object literal of property:value pairs. 
123      */
124     setStyles: function(node, hash) {
125         var style = node.style;
126         Y.each(hash, function(v, n) {
127             Y_DOM.setStyle(node, n, v, style);
128         }, Y_DOM);
129     },
131     /**
132      * Returns the computed style for the given node.
133      * @method getComputedStyle
134      * @param {HTMLElement} An HTMLElement to get the style from.
135      * @param {String} att The style property to get. 
136      * @return {String} The computed value of the style property. 
137      */
138     getComputedStyle: function(node, att) {
139         var val = '',
140             doc = node[OWNER_DOCUMENT],
141             computed;
143         if (node[STYLE] && doc[DEFAULT_VIEW] && doc[DEFAULT_VIEW][GET_COMPUTED_STYLE]) {
144             computed = doc[DEFAULT_VIEW][GET_COMPUTED_STYLE](node, null);
145             if (computed) { // FF may be null in some cases (ticket #2530548)
146                 val = computed[att];
147             }
148         }
149         return val;
150     }
153 // normalize reserved word float alternatives ("cssFloat" or "styleFloat")
154 if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][CSS_FLOAT] !== UNDEFINED) {
155     Y_DOM.CUSTOM_STYLES[FLOAT] = CSS_FLOAT;
156 } else if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][STYLE_FLOAT] !== UNDEFINED) {
157     Y_DOM.CUSTOM_STYLES[FLOAT] = STYLE_FLOAT;
160 // fix opera computedStyle default color unit (convert to rgb)
161 if (Y.UA.opera) {
162     Y_DOM[GET_COMPUTED_STYLE] = function(node, att) {
163         var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
164             val = view[GET_COMPUTED_STYLE](node, '')[att];
166         if (re_color.test(att)) {
167             val = Y.Color.toRGB(val);
168         }
170         return val;
171     };
175 // safari converts transparent to rgba(), others use "transparent"
176 if (Y.UA.webkit) {
177     Y_DOM[GET_COMPUTED_STYLE] = function(node, att) {
178         var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
179             val = view[GET_COMPUTED_STYLE](node, '')[att];
181         if (val === 'rgba(0, 0, 0, 0)') {
182             val = TRANSPARENT; 
183         }
185         return val;
186     };
190 Y.DOM._getAttrOffset = function(node, attr) {
191     var val = Y.DOM[GET_COMPUTED_STYLE](node, attr),
192         offsetParent = node.offsetParent,
193         position,
194         parentOffset,
195         offset;
197     if (val === 'auto') {
198         position = Y.DOM.getStyle(node, 'position');
199         if (position === 'static' || position === 'relative') {
200             val = 0;    
201         } else if (offsetParent && offsetParent[GET_BOUNDING_CLIENT_RECT]) {
202             parentOffset = offsetParent[GET_BOUNDING_CLIENT_RECT]()[attr];
203             offset = node[GET_BOUNDING_CLIENT_RECT]()[attr];
204             if (attr === 'left' || attr === 'top') {
205                 val = offset - parentOffset;
206             } else {
207                 val = parentOffset - node[GET_BOUNDING_CLIENT_RECT]()[attr];
208             }
209         }
210     }
212     return val;
215 Y.DOM._getOffset = function(node) {
216     var pos,
217         xy = null;
219     if (node) {
220         pos = Y_DOM.getStyle(node, 'position');
221         xy = [
222             parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'left'), 10),
223             parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'top'), 10)
224         ];
226         if ( isNaN(xy[0]) ) { // in case of 'auto'
227             xy[0] = parseInt(Y_DOM.getStyle(node, 'left'), 10); // try inline
228             if ( isNaN(xy[0]) ) { // default to offset value
229                 xy[0] = (pos === 'relative') ? 0 : node.offsetLeft || 0;
230             }
231         } 
233         if ( isNaN(xy[1]) ) { // in case of 'auto'
234             xy[1] = parseInt(Y_DOM.getStyle(node, 'top'), 10); // try inline
235             if ( isNaN(xy[1]) ) { // default to offset value
236                 xy[1] = (pos === 'relative') ? 0 : node.offsetTop || 0;
237             }
238         } 
239     }
241     return xy;
245 Y_DOM.CUSTOM_STYLES.transform = {
246     set: function(node, val, style) {
247         style[TRANSFORM] = val;
248     },
250     get: function(node, style) {
251         return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORM);
252     }
256 })(Y);
257 (function(Y) {
258 var PARSE_INT = parseInt,
259     RE = RegExp;
261 Y.Color = {
262     KEYWORDS: {
263         black: '000',
264         silver: 'c0c0c0',
265         gray: '808080',
266         white: 'fff',
267         maroon: '800000',
268         red: 'f00',
269         purple: '800080',
270         fuchsia: 'f0f',
271         green: '008000',
272         lime: '0f0',
273         olive: '808000',
274         yellow: 'ff0',
275         navy: '000080',
276         blue: '00f',
277         teal: '008080',
278         aqua: '0ff'
279     },
281     re_RGB: /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,
282     re_hex: /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,
283     re_hex3: /([0-9A-F])/gi,
285     toRGB: function(val) {
286         if (!Y.Color.re_RGB.test(val)) {
287             val = Y.Color.toHex(val);
288         }
290         if(Y.Color.re_hex.exec(val)) {
291             val = 'rgb(' + [
292                 PARSE_INT(RE.$1, 16),
293                 PARSE_INT(RE.$2, 16),
294                 PARSE_INT(RE.$3, 16)
295             ].join(', ') + ')';
296         }
297         return val;
298     },
300     toHex: function(val) {
301         val = Y.Color.KEYWORDS[val] || val;
302         if (Y.Color.re_RGB.exec(val)) {
303             val = [
304                 Number(RE.$1).toString(16),
305                 Number(RE.$2).toString(16),
306                 Number(RE.$3).toString(16)
307             ];
309             for (var i = 0; i < val.length; i++) {
310                 if (val[i].length < 2) {
311                     val[i] = '0' + val[i];
312                 }
313             }
315             val = val.join('');
316         }
318         if (val.length < 6) {
319             val = val.replace(Y.Color.re_hex3, '$1$1');
320         }
322         if (val !== 'transparent' && val.indexOf('#') < 0) {
323             val = '#' + val;
324         }
326         return val.toUpperCase();
327     }
329 })(Y);
333 }, '3.5.1' ,{requires:['dom-base']});