scratch – Diff between revs 58 and 125
?pathlinks?
Rev 58 | Rev 125 | |||
---|---|---|---|---|
1 | define( [ |
1 | define([ |
|
2 | "../core", |
2 | "../core", |
|
3 | "../var/rnothtmlwhite", |
3 | "../var/rnotwhite", |
|
4 | "./var/acceptData" |
4 | "./accepts" |
|
5 | ], function( jQuery, rnothtmlwhite, acceptData ) { |
5 | ], function( jQuery, rnotwhite ) { |
|
6 | |
- | ||
7 | "use strict"; |
- | ||
8 | |
6 | |
|
- | 7 | function Data() { |
||
- | 8 | // Support: Android<4, |
||
- | 9 | // Old WebKit does not have Object.preventExtensions/freeze method, |
||
- | 10 | // return new empty object instead with no [[set]] accessor |
||
- | 11 | Object.defineProperty( this.cache = {}, 0, { |
||
- | 12 | get: function() { |
||
- | 13 | return {}; |
||
- | 14 | } |
||
- | 15 | }); |
||
9 | function Data() { |
16 | |
|
10 | this.expando = jQuery.expando + Data.uid++; |
17 | this.expando = jQuery.expando + Data.uid++; |
|
11 | } |
18 | } |
|
12 | |
19 | |
|
13 | Data.uid = 1; |
20 | Data.uid = 1; |
|
- | 21 | Data.accepts = jQuery.acceptData; |
||
14 | |
22 | |
|
- | 23 | Data.prototype = { |
||
- | 24 | key: function( owner ) { |
||
- | 25 | // We can accept data for non-element nodes in modern browsers, |
||
- | 26 | // but we should not, see #8335. |
||
- | 27 | // Always return the key for a frozen object. |
||
- | 28 | if ( !Data.accepts( owner ) ) { |
||
- | 29 | return 0; |
||
15 | Data.prototype = { |
30 | } |
|
16 | |
- | ||
17 | cache: function( owner ) { |
31 | |
|
18 | |
32 | var descriptor = {}, |
|
19 | // Check if the owner object already has a cache |
33 | // Check if the owner object already has a cache key |
|
20 | var value = owner[ this.expando ]; |
34 | unlock = owner[ this.expando ]; |
|
21 | |
35 | |
|
22 | // If not, create one |
36 | // If not, create one |
|
23 | if ( !value ) { |
37 | if ( !unlock ) { |
|
24 | value = {}; |
38 | unlock = Data.uid++; |
|
25 | |
39 | |
|
26 | // We can accept data for non-element nodes in modern browsers, |
40 | // Secure it in a non-enumerable, non-writable property |
|
27 | // but we should not, see #8335. |
41 | try { |
|
28 | // Always return an empty object. |
42 | descriptor[ this.expando ] = { value: unlock }; |
|
29 | if ( acceptData( owner ) ) { |
43 | Object.defineProperties( owner, descriptor ); |
|
30 | |
- | ||
31 | // If it is a node unlikely to be stringify-ed or looped over |
- | ||
32 | // use plain assignment |
- | ||
33 | if ( owner.nodeType ) { |
- | ||
34 | owner[ this.expando ] = value; |
- | ||
35 | |
44 | |
|
36 | // Otherwise secure it in a non-enumerable property |
- | ||
37 | // configurable must be true to allow the property to be |
- | ||
38 | // deleted when data is removed |
- | ||
39 | } else { |
45 | // Support: Android<4 |
|
40 | Object.defineProperty( owner, this.expando, { |
46 | // Fallback to a less secure definition |
|
- | 47 | } catch ( e ) { |
||
- | 48 | descriptor[ this.expando ] = unlock; |
||
- | 49 | jQuery.extend( owner, descriptor ); |
||
- | 50 | } |
||
41 | value: value, |
51 | } |
|
42 | configurable: true |
52 | |
|
43 | } ); |
53 | // Ensure the cache object |
|
44 | } |
54 | if ( !this.cache[ unlock ] ) { |
|
45 | } |
55 | this.cache[ unlock ] = {}; |
|
46 | } |
56 | } |
|
47 | |
57 | |
|
48 | return value; |
58 | return unlock; |
|
49 | }, |
59 | }, |
|
50 | set: function( owner, data, value ) { |
60 | set: function( owner, data, value ) { |
|
51 | var prop, |
61 | var prop, |
|
- | 62 | // There may be an unlock assigned to this node, |
||
- | 63 | // if there is no entry for this "owner", create one inline |
||
- | 64 | // and set the unlock as though an owner entry had always existed |
||
- | 65 | unlock = this.key( owner ), |
||
52 | cache = this.cache( owner ); |
66 | cache = this.cache[ unlock ]; |
|
53 | |
67 | |
|
54 | // Handle: [ owner, key, value ] args |
- | ||
55 | // Always use camelCase key (gh-2257) |
68 | // Handle: [ owner, key, value ] args |
|
56 | if ( typeof data === "string" ) { |
69 | if ( typeof data === "string" ) { |
|
57 | cache[ jQuery.camelCase( data ) ] = value; |
70 | cache[ data ] = value; |
|
58 | |
71 | |
|
59 | // Handle: [ owner, { properties } ] args |
72 | // Handle: [ owner, { properties } ] args |
|
60 | } else { |
73 | } else { |
|
61 | |
- | ||
- | 74 | // Fresh assignments by object are shallow copied |
||
- | 75 | if ( jQuery.isEmptyObject( cache ) ) { |
||
- | 76 | jQuery.extend( this.cache[ unlock ], data ); |
||
62 | // Copy the properties one-by-one to the cache object |
77 | // Otherwise, copy the properties one-by-one to the cache object |
|
- | 78 | } else { |
||
63 | for ( prop in data ) { |
79 | for ( prop in data ) { |
|
64 | cache[ jQuery.camelCase( prop ) ] = data[ prop ]; |
80 | cache[ prop ] = data[ prop ]; |
|
- | 81 | } |
||
65 | } |
82 | } |
|
66 | } |
83 | } |
|
67 | return cache; |
84 | return cache; |
|
68 | }, |
85 | }, |
|
69 | get: function( owner, key ) { |
86 | get: function( owner, key ) { |
|
- | 87 | // Either a valid cache is found, or will be created. |
||
- | 88 | // New caches will be created and the unlock returned, |
||
70 | return key === undefined ? |
89 | // allowing direct access to the newly created |
|
- | 90 | // empty data object. A valid owner object must be provided. |
||
71 | this.cache( owner ) : |
91 | var cache = this.cache[ this.key( owner ) ]; |
|
72 | |
92 | |
|
73 | // Always use camelCase key (gh-2257) |
93 | return key === undefined ? |
|
74 | owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ]; |
94 | cache : cache[ key ]; |
|
75 | }, |
95 | }, |
|
76 | access: function( owner, key, value ) { |
96 | access: function( owner, key, value ) { |
|
77 | |
97 | var stored; |
|
78 | // In cases where either: |
98 | // In cases where either: |
|
79 | // |
99 | // |
|
80 | // 1. No key was specified |
100 | // 1. No key was specified |
|
81 | // 2. A string key was specified, but no value provided |
101 | // 2. A string key was specified, but no value provided |
|
82 | // |
102 | // |
|
83 | // Take the "read" path and allow the get method to determine |
103 | // Take the "read" path and allow the get method to determine |
|
84 | // which value to return, respectively either: |
104 | // which value to return, respectively either: |
|
85 | // |
105 | // |
|
86 | // 1. The entire cache object |
106 | // 1. The entire cache object |
|
87 | // 2. The data stored at the key |
107 | // 2. The data stored at the key |
|
88 | // |
108 | // |
|
89 | if ( key === undefined || |
109 | if ( key === undefined || |
|
90 | ( ( key && typeof key === "string" ) && value === undefined ) ) { |
110 | ((key && typeof key === "string") && value === undefined) ) { |
|
91 | |
111 | |
|
- | 112 | stored = this.get( owner, key ); |
||
- | 113 | |
||
- | 114 | return stored !== undefined ? |
||
92 | return this.get( owner, key ); |
115 | stored : this.get( owner, jQuery.camelCase(key) ); |
|
93 | } |
116 | } |
|
94 | |
117 | |
|
95 | // When the key is not a string, or both a key and value |
118 | // [*]When the key is not a string, or both a key and value |
|
96 | // are specified, set or extend (existing objects) with either: |
119 | // are specified, set or extend (existing objects) with either: |
|
97 | // |
120 | // |
|
98 | // 1. An object of properties |
121 | // 1. An object of properties |
|
99 | // 2. A key and value |
122 | // 2. A key and value |
|
100 | // |
123 | // |
|
101 | this.set( owner, key, value ); |
124 | this.set( owner, key, value ); |
|
102 | |
125 | |
|
103 | // Since the "set" path can have two possible entry points |
126 | // Since the "set" path can have two possible entry points |
|
104 | // return the expected data based on which path was taken[*] |
127 | // return the expected data based on which path was taken[*] |
|
105 | return value !== undefined ? value : key; |
128 | return value !== undefined ? value : key; |
|
106 | }, |
129 | }, |
|
107 | remove: function( owner, key ) { |
130 | remove: function( owner, key ) { |
|
108 | var i, |
131 | var i, name, camel, |
|
- | 132 | unlock = this.key( owner ), |
||
109 | cache = owner[ this.expando ]; |
133 | cache = this.cache[ unlock ]; |
|
110 | |
134 | |
|
111 | if ( cache === undefined ) { |
- | ||
112 | return; |
- | ||
113 | } |
- | ||
114 | |
135 | if ( key === undefined ) { |
|
- | 136 | this.cache[ unlock ] = {}; |
||
115 | if ( key !== undefined ) { |
137 | |
|
116 | |
138 | } else { |
|
117 | // Support array or space separated string of keys |
- | ||
118 | if ( jQuery.isArray( key ) ) { |
139 | // Support array or space separated string of keys |
|
- | 140 | if ( jQuery.isArray( key ) ) { |
||
- | 141 | // If "name" is an array of keys... |
||
- | 142 | // When data is initially created, via ("key", "val") signature, |
||
119 | |
143 | // keys will be converted to camelCase. |
|
- | 144 | // Since there is no way to tell _how_ a key was added, remove |
||
120 | // If key is an array of keys... |
145 | // both plain key and camelCase key. #12786 |
|
- | 146 | // This will only penalize the array argument path. |
||
- | 147 | name = key.concat( key.map( jQuery.camelCase ) ); |
||
- | 148 | } else { |
||
- | 149 | camel = jQuery.camelCase( key ); |
||
- | 150 | // Try the string as a key before any manipulation |
||
121 | // We always set camelCase keys, so remove that. |
151 | if ( key in cache ) { |
|
122 | key = key.map( jQuery.camelCase ); |
- | ||
123 | } else { |
- | ||
124 | key = jQuery.camelCase( key ); |
152 | name = [ key, camel ]; |
|
125 | |
153 | } else { |
|
126 | // If a key with the spaces exists, use it. |
154 | // If a key with the spaces exists, use it. |
|
127 | // Otherwise, create an array by matching non-whitespace |
155 | // Otherwise, create an array by matching non-whitespace |
|
128 | key = key in cache ? |
156 | name = camel; |
|
129 | [ key ] : |
157 | name = name in cache ? |
|
130 | ( key.match( rnothtmlwhite ) || [] ); |
- | ||
131 | } |
- | ||
132 | |
- | ||
133 | i = key.length; |
- | ||
134 | |
- | ||
135 | while ( i-- ) { |
158 | [ name ] : ( name.match( rnotwhite ) || [] ); |
|
136 | delete cache[ key[ i ] ]; |
- | ||
137 | } |
- | ||
138 | } |
- | ||
139 | |
- | ||
140 | // Remove the expando if there's no more data |
- | ||
141 | if ( key === undefined || jQuery.isEmptyObject( cache ) ) { |
- | ||
142 | |
- | ||
143 | // Support: Chrome <=35 - 45 |
- | ||
144 | // Webkit & Blink performance suffers when deleting properties |
159 | } |
|
145 | // from DOM nodes, so set to undefined instead |
- | ||
146 | // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) |
160 | } |
|
147 | if ( owner.nodeType ) { |
161 | |
|
148 | owner[ this.expando ] = undefined; |
162 | i = name.length; |
|
149 | } else { |
163 | while ( i-- ) { |
|
150 | delete owner[ this.expando ]; |
164 | delete cache[ name[ i ] ]; |
|
151 | } |
165 | } |
|
152 | } |
166 | } |
|
153 | }, |
167 | }, |
|
154 | hasData: function( owner ) { |
168 | hasData: function( owner ) { |
|
- | 169 | return !jQuery.isEmptyObject( |
||
155 | var cache = owner[ this.expando ]; |
170 | this.cache[ owner[ this.expando ] ] || {} |
|
- | 171 | ); |
||
- | 172 | }, |
||
- | 173 | discard: function( owner ) { |
||
- | 174 | if ( owner[ this.expando ] ) { |
||
156 | return cache !== undefined && !jQuery.isEmptyObject( cache ); |
175 | delete this.cache[ owner[ this.expando ] ]; |
|
- | 176 | } |
||
157 | } |
177 | } |
|
158 | }; |
178 | }; |
|
159 | |
179 | |
|
160 | return Data; |
180 | return Data; |
|
161 | } ); |
181 | }); |
|
162 | |
182 | |