API Docs for: 3.13.0
Show:

File: dom/js/dom-attrs.js

  1. /**
  2. * @for DOM
  3. * @module dom
  4. */
  5. var documentElement = Y.config.doc.documentElement,
  6. Y_DOM = Y.DOM,
  7. TAG_NAME = 'tagName',
  8. OWNER_DOCUMENT = 'ownerDocument',
  9. EMPTY_STRING = '',
  10. addFeature = Y.Features.add,
  11. testFeature = Y.Features.test;
  12.  
  13. Y.mix(Y_DOM, {
  14. /**
  15. * Returns the text content of the HTMLElement.
  16. * @method getText
  17. * @param {HTMLElement} element The html element.
  18. * @return {String} The text content of the element (includes text of any descending elements).
  19. */
  20. getText: (documentElement.textContent !== undefined) ?
  21. function(element) {
  22. var ret = '';
  23. if (element) {
  24. ret = element.textContent;
  25. }
  26. return ret || '';
  27. } : function(element) {
  28. var ret = '';
  29. if (element) {
  30. ret = element.innerText || element.nodeValue; // might be a textNode
  31. }
  32. return ret || '';
  33. },
  34.  
  35. /**
  36. * Sets the text content of the HTMLElement.
  37. * @method setText
  38. * @param {HTMLElement} element The html element.
  39. * @param {String} content The content to add.
  40. */
  41. setText: (documentElement.textContent !== undefined) ?
  42. function(element, content) {
  43. if (element) {
  44. element.textContent = content;
  45. }
  46. } : function(element, content) {
  47. if ('innerText' in element) {
  48. element.innerText = content;
  49. } else if ('nodeValue' in element) {
  50. element.nodeValue = content;
  51. }
  52. },
  53.  
  54. CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8
  55. 'for': 'htmlFor',
  56. 'class': 'className'
  57. } : { // w3c
  58. 'htmlFor': 'for',
  59. 'className': 'class'
  60. },
  61.  
  62. /**
  63. * Provides a normalized attribute interface.
  64. * @method setAttribute
  65. * @param {HTMLElement} el The target element for the attribute.
  66. * @param {String} attr The attribute to set.
  67. * @param {String} val The value of the attribute.
  68. */
  69. setAttribute: function(el, attr, val, ieAttr) {
  70. if (el && attr && el.setAttribute) {
  71. attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
  72. el.setAttribute(attr, val, ieAttr);
  73. }
  74. else { Y.log('bad input to setAttribute', 'warn', 'dom'); }
  75. },
  76.  
  77.  
  78. /**
  79. * Provides a normalized attribute interface.
  80. * @method getAttribute
  81. * @param {HTMLElement} el The target element for the attribute.
  82. * @param {String} attr The attribute to get.
  83. * @return {String} The current value of the attribute.
  84. */
  85. getAttribute: function(el, attr, ieAttr) {
  86. ieAttr = (ieAttr !== undefined) ? ieAttr : 2;
  87. var ret = '';
  88. if (el && attr && el.getAttribute) {
  89. attr = Y_DOM.CUSTOM_ATTRIBUTES[attr] || attr;
  90. ret = el.getAttribute(attr, ieAttr);
  91.  
  92. if (ret === null) {
  93. ret = ''; // per DOM spec
  94. }
  95. }
  96. else { Y.log('bad input to getAttribute', 'warn', 'dom'); }
  97. return ret;
  98. },
  99.  
  100. VALUE_SETTERS: {},
  101.  
  102. VALUE_GETTERS: {},
  103.  
  104. getValue: function(node) {
  105. var ret = '', // TODO: return null?
  106. getter;
  107.  
  108. if (node && node[TAG_NAME]) {
  109. getter = Y_DOM.VALUE_GETTERS[node[TAG_NAME].toLowerCase()];
  110.  
  111. if (getter) {
  112. ret = getter(node);
  113. } else {
  114. ret = node.value;
  115. }
  116. }
  117.  
  118. // workaround for IE8 JSON stringify bug
  119. // which converts empty string values to null
  120. if (ret === EMPTY_STRING) {
  121. ret = EMPTY_STRING; // for real
  122. }
  123.  
  124. return (typeof ret === 'string') ? ret : '';
  125. },
  126.  
  127. setValue: function(node, val) {
  128. var setter;
  129.  
  130. if (node && node[TAG_NAME]) {
  131. setter = Y_DOM.VALUE_SETTERS[node[TAG_NAME].toLowerCase()];
  132.  
  133. if (setter) {
  134. setter(node, val);
  135. } else {
  136. node.value = val;
  137. }
  138. }
  139. },
  140.  
  141. creators: {}
  142. });
  143.  
  144. addFeature('value-set', 'select', {
  145. test: function() {
  146. var node = Y.config.doc.createElement('select');
  147. node.innerHTML = '<option>1</option><option>2</option>';
  148. node.value = '2';
  149. return (node.value && node.value === '2');
  150. }
  151. });
  152.  
  153. if (!testFeature('value-set', 'select')) {
  154. Y_DOM.VALUE_SETTERS.select = function(node, val) {
  155. for (var i = 0, options = node.getElementsByTagName('option'), option;
  156. option = options[i++];) {
  157. if (Y_DOM.getValue(option) === val) {
  158. option.selected = true;
  159. //Y_DOM.setAttribute(option, 'selected', 'selected');
  160. break;
  161. }
  162. }
  163. };
  164. }
  165.  
  166. Y.mix(Y_DOM.VALUE_GETTERS, {
  167. button: function(node) {
  168. return (node.attributes && node.attributes.value) ? node.attributes.value.value : '';
  169. }
  170. });
  171.  
  172. Y.mix(Y_DOM.VALUE_SETTERS, {
  173. // IE: node.value changes the button text, which should be handled via innerHTML
  174. button: function(node, val) {
  175. var attr = node.attributes.value;
  176. if (!attr) {
  177. attr = node[OWNER_DOCUMENT].createAttribute('value');
  178. node.setAttributeNode(attr);
  179. }
  180.  
  181. attr.value = val;
  182. }
  183. });
  184.  
  185.  
  186. Y.mix(Y_DOM.VALUE_GETTERS, {
  187. option: function(node) {
  188. var attrs = node.attributes;
  189. return (attrs.value && attrs.value.specified) ? node.value : node.text;
  190. },
  191.  
  192. select: function(node) {
  193. var val = node.value,
  194. options = node.options;
  195.  
  196. if (options && options.length) {
  197. // TODO: implement multipe select
  198. if (node.multiple) {
  199. Y.log('multiple select normalization not implemented', 'warn', 'DOM');
  200. } else if (node.selectedIndex > -1) {
  201. val = Y_DOM.getValue(options[node.selectedIndex]);
  202. }
  203. }
  204.  
  205. return val;
  206. }
  207. });
  208.