5 ], function( jQuery, rnotwhite, acceptData ) {
8 this.expando = jQuery.expando + Data.uid++;
15 register: function( owner, initial ) {
16 var value = initial || {};
18 // If it is a node unlikely to be stringify-ed or looped over
19 // use plain assignment
20 if ( owner.nodeType ) {
21 owner[ this.expando ] = value;
23 // Otherwise secure it in a non-enumerable, non-writable property
24 // configurability must be true to allow the property to be
25 // deleted with the delete operator
27 Object.defineProperty( owner, this.expando, {
33 return owner[ this.expando ];
35 cache: function( owner ) {
37 // We can accept data for non-element nodes in modern browsers,
38 // but we should not, see #8335.
39 // Always return an empty object.
40 if ( !acceptData( owner ) ) {
44 // Check if the owner object already has a cache
45 var value = owner[ this.expando ];
51 // We can accept data for non-element nodes in modern browsers,
52 // but we should not, see #8335.
53 // Always return an empty object.
54 if ( acceptData( owner ) ) {
56 // If it is a node unlikely to be stringify-ed or looped over
57 // use plain assignment
58 if ( owner.nodeType ) {
59 owner[ this.expando ] = value;
61 // Otherwise secure it in a non-enumerable property
62 // configurable must be true to allow the property to be
63 // deleted when data is removed
65 Object.defineProperty( owner, this.expando, {
75 set: function( owner, data, value ) {
77 cache = this.cache( owner );
79 // Handle: [ owner, key, value ] args
80 if ( typeof data === "string" ) {
81 cache[ data ] = value;
83 // Handle: [ owner, { properties } ] args
86 // Copy the properties one-by-one to the cache object
87 for ( prop in data ) {
88 cache[ prop ] = data[ prop ];
93 get: function( owner, key ) {
94 return key === undefined ?
96 owner[ this.expando ] && owner[ this.expando ][ key ];
98 access: function( owner, key, value ) {
101 // In cases where either:
103 // 1. No key was specified
104 // 2. A string key was specified, but no value provided
106 // Take the "read" path and allow the get method to determine
107 // which value to return, respectively either:
109 // 1. The entire cache object
110 // 2. The data stored at the key
112 if ( key === undefined ||
113 ( ( key && typeof key === "string" ) && value === undefined ) ) {
115 stored = this.get( owner, key );
117 return stored !== undefined ?
118 stored : this.get( owner, jQuery.camelCase( key ) );
121 // When the key is not a string, or both a key and value
122 // are specified, set or extend (existing objects) with either:
124 // 1. An object of properties
125 // 2. A key and value
127 this.set( owner, key, value );
129 // Since the "set" path can have two possible entry points
130 // return the expected data based on which path was taken[*]
131 return value !== undefined ? value : key;
133 remove: function( owner, key ) {
135 cache = owner[ this.expando ];
137 if ( cache === undefined ) {
141 if ( key === undefined ) {
142 this.register( owner );
146 // Support array or space separated string of keys
147 if ( jQuery.isArray( key ) ) {
149 // If "name" is an array of keys...
150 // When data is initially created, via ("key", "val") signature,
151 // keys will be converted to camelCase.
152 // Since there is no way to tell _how_ a key was added, remove
153 // both plain key and camelCase key. #12786
154 // This will only penalize the array argument path.
155 name = key.concat( key.map( jQuery.camelCase ) );
157 camel = jQuery.camelCase( key );
159 // Try the string as a key before any manipulation
160 if ( key in cache ) {
161 name = [ key, camel ];
164 // If a key with the spaces exists, use it.
165 // Otherwise, create an array by matching non-whitespace
167 name = name in cache ?
168 [ name ] : ( name.match( rnotwhite ) || [] );
175 delete cache[ name[ i ] ];
179 // Remove the expando if there's no more data
180 if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
182 // Support: Chrome <= 35-45+
183 // Webkit & Blink performance suffers when deleting properties
184 // from DOM nodes, so set to undefined instead
185 // https://code.google.com/p/chromium/issues/detail?id=378607
186 if ( owner.nodeType ) {
187 owner[ this.expando ] = undefined;
189 delete owner[ this.expando ];
193 hasData: function( owner ) {
194 var cache = owner[ this.expando ];
195 return cache !== undefined && !jQuery.isEmptyObject( cache );