Data.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. define( [
  2. "../core",
  3. "../var/rnotwhite",
  4. "./var/acceptData"
  5. ], function( jQuery, rnotwhite, acceptData ) {
  6. "use strict";
  7. function Data() {
  8. this.expando = jQuery.expando + Data.uid++;
  9. }
  10. Data.uid = 1;
  11. Data.prototype = {
  12. cache: function( owner ) {
  13. // Check if the owner object already has a cache
  14. var value = owner[ this.expando ];
  15. // If not, create one
  16. if ( !value ) {
  17. value = {};
  18. // We can accept data for non-element nodes in modern browsers,
  19. // but we should not, see #8335.
  20. // Always return an empty object.
  21. if ( acceptData( owner ) ) {
  22. // If it is a node unlikely to be stringify-ed or looped over
  23. // use plain assignment
  24. if ( owner.nodeType ) {
  25. owner[ this.expando ] = value;
  26. // Otherwise secure it in a non-enumerable property
  27. // configurable must be true to allow the property to be
  28. // deleted when data is removed
  29. } else {
  30. Object.defineProperty( owner, this.expando, {
  31. value: value,
  32. configurable: true
  33. } );
  34. }
  35. }
  36. }
  37. return value;
  38. },
  39. set: function( owner, data, value ) {
  40. var prop,
  41. cache = this.cache( owner );
  42. // Handle: [ owner, key, value ] args
  43. // Always use camelCase key (gh-2257)
  44. if ( typeof data === "string" ) {
  45. cache[ jQuery.camelCase( data ) ] = value;
  46. // Handle: [ owner, { properties } ] args
  47. } else {
  48. // Copy the properties one-by-one to the cache object
  49. for ( prop in data ) {
  50. cache[ jQuery.camelCase( prop ) ] = data[ prop ];
  51. }
  52. }
  53. return cache;
  54. },
  55. get: function( owner, key ) {
  56. return key === undefined ?
  57. this.cache( owner ) :
  58. // Always use camelCase key (gh-2257)
  59. owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
  60. },
  61. access: function( owner, key, value ) {
  62. // In cases where either:
  63. //
  64. // 1. No key was specified
  65. // 2. A string key was specified, but no value provided
  66. //
  67. // Take the "read" path and allow the get method to determine
  68. // which value to return, respectively either:
  69. //
  70. // 1. The entire cache object
  71. // 2. The data stored at the key
  72. //
  73. if ( key === undefined ||
  74. ( ( key && typeof key === "string" ) && value === undefined ) ) {
  75. return this.get( owner, key );
  76. }
  77. // When the key is not a string, or both a key and value
  78. // are specified, set or extend (existing objects) with either:
  79. //
  80. // 1. An object of properties
  81. // 2. A key and value
  82. //
  83. this.set( owner, key, value );
  84. // Since the "set" path can have two possible entry points
  85. // return the expected data based on which path was taken[*]
  86. return value !== undefined ? value : key;
  87. },
  88. remove: function( owner, key ) {
  89. var i,
  90. cache = owner[ this.expando ];
  91. if ( cache === undefined ) {
  92. return;
  93. }
  94. if ( key !== undefined ) {
  95. // Support array or space separated string of keys
  96. if ( jQuery.isArray( key ) ) {
  97. // If key is an array of keys...
  98. // We always set camelCase keys, so remove that.
  99. key = key.map( jQuery.camelCase );
  100. } else {
  101. key = jQuery.camelCase( key );
  102. // If a key with the spaces exists, use it.
  103. // Otherwise, create an array by matching non-whitespace
  104. key = key in cache ?
  105. [ key ] :
  106. ( key.match( rnotwhite ) || [] );
  107. }
  108. i = key.length;
  109. while ( i-- ) {
  110. delete cache[ key[ i ] ];
  111. }
  112. }
  113. // Remove the expando if there's no more data
  114. if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
  115. // Support: Chrome <=35 - 45
  116. // Webkit & Blink performance suffers when deleting properties
  117. // from DOM nodes, so set to undefined instead
  118. // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
  119. if ( owner.nodeType ) {
  120. owner[ this.expando ] = undefined;
  121. } else {
  122. delete owner[ this.expando ];
  123. }
  124. }
  125. },
  126. hasData: function( owner ) {
  127. var cache = owner[ this.expando ];
  128. return cache !== undefined && !jQuery.isEmptyObject( cache );
  129. }
  130. };
  131. return Data;
  132. } );