Show:
  1. /**
  2. * Provides methods for managing custom Node data.
  3. *
  4. * @module node
  5. * @main node
  6. * @submodule node-data
  7. */
  8. Y.mix(Y.Node.prototype, {
  9. _initData: function() {
  10. if (! ('_data' in this)) {
  11. this._data = {};
  12. }
  13. },
  14. /**
  15. * @method getData
  16. * @for Node
  17. * @description Retrieves arbitrary data stored on a Node instance.
  18. * If no data is associated with the Node, it will attempt to retrieve
  19. * a value from the corresponding HTML data attribute. (e.g. node.getData('foo')
  20. * will check node.getAttribute('data-foo')).
  21. * @param {string} name Optional name of the data field to retrieve.
  22. * If no name is given, all data is returned.
  23. * @return {any | Object} Whatever is stored at the given field,
  24. * or an object hash of all fields.
  25. */
  26. getData: function(name) {
  27. this._initData();
  28. var data = this._data,
  29. ret = data;
  30. if (arguments.length) { // single field
  31. if (name in data) {
  32. ret = data[name];
  33. } else { // initialize from HTML attribute
  34. ret = this._getDataAttribute(name);
  35. }
  36. } else if (typeof data == 'object' && data !== null) { // all fields
  37. ret = {};
  38. Y.Object.each(data, function(v, n) {
  39. ret[n] = v;
  40. });
  41. ret = this._getDataAttributes(ret);
  42. }
  43. return ret;
  44. },
  45. _getDataAttributes: function(ret) {
  46. ret = ret || {};
  47. var i = 0,
  48. attrs = this._node.attributes,
  49. len = attrs.length,
  50. prefix = this.DATA_PREFIX,
  51. prefixLength = prefix.length,
  52. name;
  53. while (i < len) {
  54. name = attrs[i].name;
  55. if (name.indexOf(prefix) === 0) {
  56. name = name.substr(prefixLength);
  57. if (!(name in ret)) { // only merge if not already stored
  58. ret[name] = this._getDataAttribute(name);
  59. }
  60. }
  61. i += 1;
  62. }
  63. return ret;
  64. },
  65. _getDataAttribute: function(name) {
  66. name = this.DATA_PREFIX + name;
  67. var node = this._node,
  68. attrs = node.attributes,
  69. data = attrs && attrs[name] && attrs[name].value;
  70. return data;
  71. },
  72. /**
  73. * @method setData
  74. * @for Node
  75. * @description Stores arbitrary data on a Node instance.
  76. * This is not stored with the DOM node.
  77. * @param {string} name The name of the field to set. If no val
  78. * is given, name is treated as the data and overrides any existing data.
  79. * @param {any} val The value to be assigned to the field.
  80. * @chainable
  81. */
  82. setData: function(name, val) {
  83. this._initData();
  84. if (arguments.length > 1) {
  85. this._data[name] = val;
  86. } else {
  87. this._data = name;
  88. }
  89. return this;
  90. },
  91. /**
  92. * @method clearData
  93. * @for Node
  94. * @description Clears internally stored data.
  95. * @param {string} name The name of the field to clear. If no name
  96. * is given, all data is cleared.
  97. * @chainable
  98. */
  99. clearData: function(name) {
  100. if ('_data' in this) {
  101. if (typeof name != 'undefined') {
  102. delete this._data[name];
  103. } else {
  104. delete this._data;
  105. }
  106. }
  107. return this;
  108. }
  109. });
  110. Y.mix(Y.NodeList.prototype, {
  111. /**
  112. * @method getData
  113. * @for NodeList
  114. * @description Retrieves arbitrary data stored on each Node instance
  115. * bound to the NodeList.
  116. * @see Node
  117. * @param {string} name Optional name of the data field to retrieve.
  118. * If no name is given, all data is returned.
  119. * @return {Array} An array containing all of the data for each Node instance.
  120. * or an object hash of all fields.
  121. */
  122. getData: function(name) {
  123. var args = (arguments.length) ? [name] : [];
  124. return this._invoke('getData', args, true);
  125. },
  126. /**
  127. * @method setData
  128. * @for NodeList
  129. * @description Stores arbitrary data on each Node instance bound to the
  130. * NodeList. This is not stored with the DOM node.
  131. * @param {string} name The name of the field to set. If no name
  132. * is given, name is treated as the data and overrides any existing data.
  133. * @param {any} val The value to be assigned to the field.
  134. * @chainable
  135. */
  136. setData: function(name, val) {
  137. var args = (arguments.length > 1) ? [name, val] : [name];
  138. return this._invoke('setData', args);
  139. },
  140. /**
  141. * @method clearData
  142. * @for NodeList
  143. * @description Clears data on all Node instances bound to the NodeList.
  144. * @param {string} name The name of the field to clear. If no name
  145. * is given, all data is cleared.
  146. * @chainable
  147. */
  148. clearData: function(name) {
  149. var args = (arguments.length) ? [name] : [];
  150. return this._invoke('clearData', [name]);
  151. }
  152. });