API Docs for: 3.10.3
Show:

File: dom/js/dom-style.js

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