(function(Y) {
/**
* Add style management functionality to DOM.
* @module dom
* @submodule dom-style
* @for DOM
*/
var DOCUMENT_ELEMENT = 'documentElement',
DEFAULT_VIEW = 'defaultView',
OWNER_DOCUMENT = 'ownerDocument',
STYLE = 'style',
FLOAT = 'float',
CSS_FLOAT = 'cssFloat',
STYLE_FLOAT = 'styleFloat',
TRANSPARENT = 'transparent',
GET_COMPUTED_STYLE = 'getComputedStyle',
DOCUMENT = Y.config.doc,
UNDEFINED = undefined,
re_color = /color$/i;
Y.mix(Y.DOM, {
CUSTOM_STYLES: {
},
/**
* Sets a style property for a given element.
* @method setStyle
* @param {HTMLElement} An HTMLElement to apply the style to.
* @param {String} att The style property to set.
* @param {String|Number} val The value.
*/
setStyle: function(node, att, val, style) {
style = style || node.style;
var CUSTOM_STYLES = Y.DOM.CUSTOM_STYLES;
if (style) {
if (val === null) {
val = ''; // normalize for unsetting
}
if (att in CUSTOM_STYLES) {
if (CUSTOM_STYLES[att].set) {
CUSTOM_STYLES[att].set(node, val, style);
return; // NOTE: return
} else if (typeof CUSTOM_STYLES[att] === 'string') {
att = CUSTOM_STYLES[att];
}
}
style[att] = val;
}
},
/**
* Returns the current style value for the given property.
* @method getStyle
* @param {HTMLElement} An HTMLElement to get the style from.
* @param {String} att The style property to get.
*/
getStyle: function(node, att) {
var style = node[STYLE],
CUSTOM_STYLES = Y.DOM.CUSTOM_STYLES,
val = '';
if (style) {
if (att in CUSTOM_STYLES) {
if (CUSTOM_STYLES[att].get) {
return CUSTOM_STYLES[att].get(node, att, style); // NOTE: return
} else if (typeof CUSTOM_STYLES[att] === 'string') {
att = CUSTOM_STYLES[att];
}
}
val = style[att];
if (val === '') { // TODO: is empty string sufficient?
val = Y.DOM[GET_COMPUTED_STYLE](node, att);
}
}
return val;
},
/**
* Sets multiple style properties.
* @method setStyles
* @param {HTMLElement} node An HTMLElement to apply the styles to.
* @param {Object} hash An object literal of property:value pairs.
*/
setStyles: function(node, hash) {
var style = node.style;
Y.each(hash, function(v, n) {
Y.DOM.setStyle(node, n, v, style);
}, Y.DOM);
},
/**
* Returns the computed style for the given node.
* @method getComputedStyle
* @param {HTMLElement} An HTMLElement to get the style from.
* @param {String} att The style property to get.
* @return {String} The computed value of the style property.
*/
getComputedStyle: function(node, att) {
var val = '',
doc = node[OWNER_DOCUMENT];
if (node[STYLE]) {
val = doc[DEFAULT_VIEW][GET_COMPUTED_STYLE](node, null)[att];
}
return val;
}
});
// normalize reserved word float alternatives ("cssFloat" or "styleFloat")
if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][CSS_FLOAT] !== UNDEFINED) {
Y.DOM.CUSTOM_STYLES[FLOAT] = CSS_FLOAT;
} else if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][STYLE_FLOAT] !== UNDEFINED) {
Y.DOM.CUSTOM_STYLES[FLOAT] = STYLE_FLOAT;
}
// fix opera computedStyle default color unit (convert to rgb)
if (Y.UA.opera) {
Y.DOM[GET_COMPUTED_STYLE] = function(node, att) {
var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
val = view[GET_COMPUTED_STYLE](node, '')[att];
if (re_color.test(att)) {
val = Y.Color.toRGB(val);
}
return val;
};
}
// safari converts transparent to rgba(), others use "transparent"
if (Y.UA.webkit) {
Y.DOM[GET_COMPUTED_STYLE] = function(node, att) {
var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
val = view[GET_COMPUTED_STYLE](node, '')[att];
if (val === 'rgba(0, 0, 0, 0)') {
val = TRANSPARENT;
}
return val;
};
}
})(Y);