Core: add workaround for iOS JIT error in isArrayLike
[jquery.git] / src / data / Data.js
blob4584734305455de99ace17ac7b3b6ad1e1c86b67
1 define([
2         "../core",
3         "../var/rnotwhite",
4         "./accepts"
5 ], function( jQuery, rnotwhite ) {
7 function Data() {
8         this.expando = jQuery.expando + Data.uid++;
11 Data.uid = 1;
12 Data.accepts = jQuery.acceptData;
14 Data.prototype = {
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
27                 } else {
28                         Object.defineProperty( owner, this.expando, {
29                                 value: value,
30                                 writable: true,
31                                 configurable: true
32                         });
33                 }
34                 return owner[ this.expando ];
35         },
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 ) ) {
41                         return {};
42                 }
44                 // Check if the owner object already has a cache
45                 var cache = owner[ this.expando ];
47                 // If so, return it
48                 if ( cache ) {
49                         return cache;
50                 }
52                 // If not, register one
53                 return this.register( owner, initial );
54         },
55         set: function( owner, data, value ) {
56                 var prop,
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
64                 } else {
65                         // Copy the properties one-by-one to the cache object
66                         for ( prop in data ) {
67                                 cache[ prop ] = data[ prop ];
68                         }
69                 }
70                 return cache;
71         },
72         get: function( owner, key ) {
73                 var cache = this.cache( owner );
75                 return key === undefined ?
76                         cache : cache[ key ];
77         },
78         access: function( owner, key, value ) {
79                 var stored;
80                 // In cases where either:
81                 //
82                 //   1. No key was specified
83                 //   2. A string key was specified, but no value provided
84                 //
85                 // Take the "read" path and allow the get method to determine
86                 // which value to return, respectively either:
87                 //
88                 //   1. The entire cache object
89                 //   2. The data stored at the key
90                 //
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) );
98                 }
100                 // [*]When the key is not a string, or both a key and value
101                 // are specified, set or extend (existing objects) with either:
102                 //
103                 //   1. An object of properties
104                 //   2. A key and value
105                 //
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;
111         },
112         remove: function( owner, key ) {
113                 var i, name, camel,
114                         cache = owner[ this.expando ];
116                 if ( cache === undefined ) {
117                         return;
118                 }
120                 if ( key === undefined ) {
121                         this.register( owner );
123                 } else {
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 ) );
133                         } else {
134                                 camel = jQuery.camelCase( key );
135                                 // Try the string as a key before any manipulation
136                                 if ( key in cache ) {
137                                         name = [ key, camel ];
138                                 } else {
139                                         // If a key with the spaces exists, use it.
140                                         // Otherwise, create an array by matching non-whitespace
141                                         name = camel;
142                                         name = name in cache ?
143                                                 [ name ] : ( name.match( rnotwhite ) || [] );
144                                 }
145                         }
147                         i = name.length;
149                         while ( i-- ) {
150                                 delete cache[ name[ i ] ];
151                         }
152                 }
153         },
154         hasData: function( owner ) {
155                 var cache = owner[ this.expando ];
156                 return cache !== undefined && !jQuery.isEmptyObject( cache );
157         },
158         discard: function( owner ) {
159                 if ( owner[ this.expando ] ) {
160                         delete owner[ this.expando ];
161                 }
162         }
165 return Data;