5 ], function( jQuery, rnotwhite ) {
8 this.expando = jQuery.expando + Data.uid++;
12 Data.accepts = jQuery.acceptData;
16 register: function( owner, initial ) {
17 var value = initial || {};
19 // If it is a node unlikely to be stringify-ed or looped over
20 // use plain assignment
21 if ( owner.nodeType ) {
22 owner[ this.expando ] = value;
24 // Otherwise secure it in a non-enumerable, non-writable property
25 // configurability must be true to allow the property to be
26 // deleted with the delete operator
28 Object.defineProperty( owner, this.expando, {
34 return owner[ this.expando ];
36 cache: function( owner, initial ) {
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 ( !Data.accepts( owner ) ) {
44 // Check if the owner object already has a cache
45 var cache = owner[ this.expando ];
52 // If not, register one
53 return this.register( owner, initial );
55 set: function( owner, data, value ) {
57 cache = this.cache( owner );
59 // Handle: [ owner, key, value ] args
60 if ( typeof data === "string" ) {
61 cache[ data ] = value;
63 // Handle: [ owner, { properties } ] args
65 // Copy the properties one-by-one to the cache object
66 for ( prop in data ) {
67 cache[ prop ] = data[ prop ];
72 get: function( owner, key ) {
73 var cache = this.cache( owner );
75 return key === undefined ?
78 access: function( owner, key, value ) {
80 // In cases where either:
82 // 1. No key was specified
83 // 2. A string key was specified, but no value provided
85 // Take the "read" path and allow the get method to determine
86 // which value to return, respectively either:
88 // 1. The entire cache object
89 // 2. The data stored at the key
91 if ( key === undefined ||
92 ((key && typeof key === "string") && value === undefined) ) {
94 stored = this.get( owner, key );
96 return stored !== undefined ?
97 stored : this.get( owner, jQuery.camelCase(key) );
100 // [*]When the key is not a string, or both a key and value
101 // are specified, set or extend (existing objects) with either:
103 // 1. An object of properties
104 // 2. A key and value
106 this.set( owner, key, value );
108 // Since the "set" path can have two possible entry points
109 // return the expected data based on which path was taken[*]
110 return value !== undefined ? value : key;
112 remove: function( owner, key ) {
114 cache = owner[ this.expando ];
116 if ( cache === undefined ) {
120 if ( key === undefined ) {
121 this.register( owner );
124 // Support array or space separated string of keys
125 if ( jQuery.isArray( key ) ) {
126 // If "name" is an array of keys...
127 // When data is initially created, via ("key", "val") signature,
128 // keys will be converted to camelCase.
129 // Since there is no way to tell _how_ a key was added, remove
130 // both plain key and camelCase key. #12786
131 // This will only penalize the array argument path.
132 name = key.concat( key.map( jQuery.camelCase ) );
134 camel = jQuery.camelCase( key );
135 // Try the string as a key before any manipulation
136 if ( key in cache ) {
137 name = [ key, camel ];
139 // If a key with the spaces exists, use it.
140 // Otherwise, create an array by matching non-whitespace
142 name = name in cache ?
143 [ name ] : ( name.match( rnotwhite ) || [] );
150 delete cache[ name[ i ] ];
154 hasData: function( owner ) {
155 var cache = owner[ this.expando ];
156 return cache !== undefined && !jQuery.isEmptyObject( cache );
158 discard: function( owner ) {
159 if ( owner[ this.expando ] ) {
160 delete owner[ this.expando ];