weekly release 2.4dev
[moodle.git] / lib / yuilib / 3.7.1 / build / dom-style / dom-style-debug.js
blob66958ada266faa563e5319c149a85b773788aa42
1 /*
2 YUI 3.7.1 (build 5627)
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, NAME) {
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     TRANSFORMORIGIN = 'transformOrigin',
36     VENDOR_TRANSFORM = [
37         'WebkitTransform',
38         'MozTransform',
39         'OTransform',
40         'msTransform'
41     ],
43     re_color = /color$/i,
44     re_unit = /width|height|top|left|right|bottom|margin|padding/i;
46 Y.Array.each(VENDOR_TRANSFORM, function(val) {
47     if (val in DOCUMENT[DOCUMENT_ELEMENT].style) {
48         TRANSFORM = val;
49         TRANSFORMORIGIN = val + "Origin";
50     }
51 });
53 Y.mix(Y_DOM, {
54     DEFAULT_UNIT: 'px',
56     CUSTOM_STYLES: {
57     },
60     /**
61      * Sets a style property for a given element.
62      * @method setStyle
63      * @param {HTMLElement} An HTMLElement to apply the style to.
64      * @param {String} att The style property to set. 
65      * @param {String|Number} val The value. 
66      */
67     setStyle: function(node, att, val, style) {
68         style = style || node.style;
69         var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES;
71         if (style) {
72             if (val === null || val === '') { // normalize unsetting
73                 val = '';
74             } else if (!isNaN(new Number(val)) && re_unit.test(att)) { // number values may need a unit
75                 val += Y_DOM.DEFAULT_UNIT;
76             }
78             if (att in CUSTOM_STYLES) {
79                 if (CUSTOM_STYLES[att].set) {
80                     CUSTOM_STYLES[att].set(node, val, style);
81                     return; // NOTE: return
82                 } else if (typeof CUSTOM_STYLES[att] === 'string') {
83                     att = CUSTOM_STYLES[att];
84                 }
85             } else if (att === '') { // unset inline styles
86                 att = 'cssText';
87                 val = '';
88             }
89             style[att] = val; 
90         }
91     },
93     /**
94      * Returns the current style value for the given property.
95      * @method getStyle
96      * @param {HTMLElement} An HTMLElement to get the style from.
97      * @param {String} att The style property to get. 
98      */
99     getStyle: function(node, att, style) {
100         style = style || node.style;
101         var CUSTOM_STYLES = Y_DOM.CUSTOM_STYLES,
102             val = '';
104         if (style) {
105             if (att in CUSTOM_STYLES) {
106                 if (CUSTOM_STYLES[att].get) {
107                     return CUSTOM_STYLES[att].get(node, att, style); // NOTE: return
108                 } else if (typeof CUSTOM_STYLES[att] === 'string') {
109                     att = CUSTOM_STYLES[att];
110                 }
111             }
112             val = style[att];
113             if (val === '') { // TODO: is empty string sufficient?
114                 val = Y_DOM[GET_COMPUTED_STYLE](node, att);
115             }
116         }
118         return val;
119     },
121     /**
122      * Sets multiple style properties.
123      * @method setStyles
124      * @param {HTMLElement} node An HTMLElement to apply the styles to. 
125      * @param {Object} hash An object literal of property:value pairs. 
126      */
127     setStyles: function(node, hash) {
128         var style = node.style;
129         Y.each(hash, function(v, n) {
130             Y_DOM.setStyle(node, n, v, style);
131         }, Y_DOM);
132     },
134     /**
135      * Returns the computed style for the given node.
136      * @method getComputedStyle
137      * @param {HTMLElement} An HTMLElement to get the style from.
138      * @param {String} att The style property to get. 
139      * @return {String} The computed value of the style property. 
140      */
141     getComputedStyle: function(node, att) {
142         var val = '',
143             doc = node[OWNER_DOCUMENT],
144             computed;
146         if (node[STYLE] && doc[DEFAULT_VIEW] && doc[DEFAULT_VIEW][GET_COMPUTED_STYLE]) {
147             computed = doc[DEFAULT_VIEW][GET_COMPUTED_STYLE](node, null);
148             if (computed) { // FF may be null in some cases (ticket #2530548)
149                 val = computed[att];
150             }
151         }
152         return val;
153     }
156 // normalize reserved word float alternatives ("cssFloat" or "styleFloat")
157 if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][CSS_FLOAT] !== UNDEFINED) {
158     Y_DOM.CUSTOM_STYLES[FLOAT] = CSS_FLOAT;
159 } else if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][STYLE_FLOAT] !== UNDEFINED) {
160     Y_DOM.CUSTOM_STYLES[FLOAT] = STYLE_FLOAT;
163 // fix opera computedStyle default color unit (convert to rgb)
164 if (Y.UA.opera) {
165     Y_DOM[GET_COMPUTED_STYLE] = function(node, att) {
166         var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
167             val = view[GET_COMPUTED_STYLE](node, '')[att];
169         if (re_color.test(att)) {
170             val = Y.Color.toRGB(val);
171         }
173         return val;
174     };
178 // safari converts transparent to rgba(), others use "transparent"
179 if (Y.UA.webkit) {
180     Y_DOM[GET_COMPUTED_STYLE] = function(node, att) {
181         var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
182             val = view[GET_COMPUTED_STYLE](node, '')[att];
184         if (val === 'rgba(0, 0, 0, 0)') {
185             val = TRANSPARENT; 
186         }
188         return val;
189     };
193 Y.DOM._getAttrOffset = function(node, attr) {
194     var val = Y.DOM[GET_COMPUTED_STYLE](node, attr),
195         offsetParent = node.offsetParent,
196         position,
197         parentOffset,
198         offset;
200     if (val === 'auto') {
201         position = Y.DOM.getStyle(node, 'position');
202         if (position === 'static' || position === 'relative') {
203             val = 0;    
204         } else if (offsetParent && offsetParent[GET_BOUNDING_CLIENT_RECT]) {
205             parentOffset = offsetParent[GET_BOUNDING_CLIENT_RECT]()[attr];
206             offset = node[GET_BOUNDING_CLIENT_RECT]()[attr];
207             if (attr === 'left' || attr === 'top') {
208                 val = offset - parentOffset;
209             } else {
210                 val = parentOffset - node[GET_BOUNDING_CLIENT_RECT]()[attr];
211             }
212         }
213     }
215     return val;
218 Y.DOM._getOffset = function(node) {
219     var pos,
220         xy = null;
222     if (node) {
223         pos = Y_DOM.getStyle(node, 'position');
224         xy = [
225             parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'left'), 10),
226             parseInt(Y_DOM[GET_COMPUTED_STYLE](node, 'top'), 10)
227         ];
229         if ( isNaN(xy[0]) ) { // in case of 'auto'
230             xy[0] = parseInt(Y_DOM.getStyle(node, 'left'), 10); // try inline
231             if ( isNaN(xy[0]) ) { // default to offset value
232                 xy[0] = (pos === 'relative') ? 0 : node.offsetLeft || 0;
233             }
234         } 
236         if ( isNaN(xy[1]) ) { // in case of 'auto'
237             xy[1] = parseInt(Y_DOM.getStyle(node, 'top'), 10); // try inline
238             if ( isNaN(xy[1]) ) { // default to offset value
239                 xy[1] = (pos === 'relative') ? 0 : node.offsetTop || 0;
240             }
241         } 
242     }
244     return xy;
248 Y_DOM.CUSTOM_STYLES.transform = {
249     set: function(node, val, style) {
250         style[TRANSFORM] = val;
251     },
253     get: function(node, style) {
254         return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORM);
255     }
258 Y_DOM.CUSTOM_STYLES.transformOrigin = {
259     set: function(node, val, style) {
260         style[TRANSFORMORIGIN] = val;
261     },
263     get: function(node, style) {
264         return Y_DOM[GET_COMPUTED_STYLE](node, TRANSFORMORIGIN);
265     }
269 })(Y);
270 (function(Y) {
271 var PARSE_INT = parseInt,
272     RE = RegExp;
274 Y.Color = {
275     KEYWORDS: {
276         black: '000',
277         silver: 'c0c0c0',
278         gray: '808080',
279         white: 'fff',
280         maroon: '800000',
281         red: 'f00',
282         purple: '800080',
283         fuchsia: 'f0f',
284         green: '008000',
285         lime: '0f0',
286         olive: '808000',
287         yellow: 'ff0',
288         navy: '000080',
289         blue: '00f',
290         teal: '008080',
291         aqua: '0ff'
292     },
294     re_RGB: /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,
295     re_hex: /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,
296     re_hex3: /([0-9A-F])/gi,
298     toRGB: function(val) {
299         if (!Y.Color.re_RGB.test(val)) {
300             val = Y.Color.toHex(val);
301         }
303         if(Y.Color.re_hex.exec(val)) {
304             val = 'rgb(' + [
305                 PARSE_INT(RE.$1, 16),
306                 PARSE_INT(RE.$2, 16),
307                 PARSE_INT(RE.$3, 16)
308             ].join(', ') + ')';
309         }
310         return val;
311     },
313     toHex: function(val) {
314         val = Y.Color.KEYWORDS[val] || val;
315         if (Y.Color.re_RGB.exec(val)) {
316             val = [
317                 Number(RE.$1).toString(16),
318                 Number(RE.$2).toString(16),
319                 Number(RE.$3).toString(16)
320             ];
322             for (var i = 0; i < val.length; i++) {
323                 if (val[i].length < 2) {
324                     val[i] = '0' + val[i];
325                 }
326             }
328             val = val.join('');
329         }
331         if (val.length < 6) {
332             val = val.replace(Y.Color.re_hex3, '$1$1');
333         }
335         if (val !== 'transparent' && val.indexOf('#') < 0) {
336             val = '#' + val;
337         }
339         return val.toUpperCase();
340     }
342 })(Y);
346 }, '3.7.1', {"requires": ["dom-base"]});