scratch – Blame information for rev 125
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
125 | office | 1 | define([ |
58 | office | 2 | "./core", |
125 | office | 3 | "./var/rnotwhite", |
58 | office | 4 | "./core/access", |
125 | office | 5 | "./data/var/data_priv", |
6 | "./data/var/data_user" |
||
7 | ], function( jQuery, rnotwhite, access, data_priv, data_user ) { |
||
58 | office | 8 | |
9 | // Implementation Summary |
||
10 | // |
||
11 | // 1. Enforce API surface and semantic compatibility with 1.9.x branch |
||
12 | // 2. Improve the module's maintainability by reducing the storage |
||
13 | // paths to a single mechanism. |
||
14 | // 3. Use the same single mechanism to support "private" and "user" data. |
||
15 | // 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) |
||
16 | // 5. Avoid exposing implementation details on user objects (eg. expando properties) |
||
17 | // 6. Provide a clear path for implementation upgrade to WeakMap in 2014 |
||
18 | |||
19 | var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, |
||
125 | office | 20 | rmultiDash = /([A-Z])/g; |
58 | office | 21 | |
22 | function dataAttr( elem, key, data ) { |
||
23 | var name; |
||
24 | |||
25 | // If nothing was found internally, try to fetch any |
||
26 | // data from the HTML5 data-* attribute |
||
27 | if ( data === undefined && elem.nodeType === 1 ) { |
||
125 | office | 28 | name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); |
58 | office | 29 | data = elem.getAttribute( name ); |
30 | |||
31 | if ( typeof data === "string" ) { |
||
32 | try { |
||
125 | office | 33 | data = data === "true" ? true : |
34 | data === "false" ? false : |
||
35 | data === "null" ? null : |
||
36 | // Only convert to a number if it doesn't change the string |
||
37 | +data + "" === data ? +data : |
||
38 | rbrace.test( data ) ? jQuery.parseJSON( data ) : |
||
39 | data; |
||
40 | } catch( e ) {} |
||
58 | office | 41 | |
42 | // Make sure we set the data so it isn't changed later |
||
125 | office | 43 | data_user.set( elem, key, data ); |
58 | office | 44 | } else { |
45 | data = undefined; |
||
46 | } |
||
47 | } |
||
48 | return data; |
||
49 | } |
||
50 | |||
125 | office | 51 | jQuery.extend({ |
58 | office | 52 | hasData: function( elem ) { |
125 | office | 53 | return data_user.hasData( elem ) || data_priv.hasData( elem ); |
58 | office | 54 | }, |
55 | |||
56 | data: function( elem, name, data ) { |
||
125 | office | 57 | return data_user.access( elem, name, data ); |
58 | office | 58 | }, |
59 | |||
60 | removeData: function( elem, name ) { |
||
125 | office | 61 | data_user.remove( elem, name ); |
58 | office | 62 | }, |
63 | |||
64 | // TODO: Now that all calls to _data and _removeData have been replaced |
||
125 | office | 65 | // with direct calls to data_priv methods, these can be deprecated. |
58 | office | 66 | _data: function( elem, name, data ) { |
125 | office | 67 | return data_priv.access( elem, name, data ); |
58 | office | 68 | }, |
69 | |||
70 | _removeData: function( elem, name ) { |
||
125 | office | 71 | data_priv.remove( elem, name ); |
58 | office | 72 | } |
125 | office | 73 | }); |
58 | office | 74 | |
125 | office | 75 | jQuery.fn.extend({ |
58 | office | 76 | data: function( key, value ) { |
77 | var i, name, data, |
||
78 | elem = this[ 0 ], |
||
79 | attrs = elem && elem.attributes; |
||
80 | |||
81 | // Gets all values |
||
82 | if ( key === undefined ) { |
||
83 | if ( this.length ) { |
||
125 | office | 84 | data = data_user.get( elem ); |
58 | office | 85 | |
125 | office | 86 | if ( elem.nodeType === 1 && !data_priv.get( elem, "hasDataAttrs" ) ) { |
58 | office | 87 | i = attrs.length; |
88 | while ( i-- ) { |
||
89 | |||
125 | office | 90 | // Support: IE11+ |
58 | office | 91 | // The attrs elements can be null (#14894) |
92 | if ( attrs[ i ] ) { |
||
93 | name = attrs[ i ].name; |
||
94 | if ( name.indexOf( "data-" ) === 0 ) { |
||
125 | office | 95 | name = jQuery.camelCase( name.slice(5) ); |
58 | office | 96 | dataAttr( elem, name, data[ name ] ); |
97 | } |
||
98 | } |
||
99 | } |
||
125 | office | 100 | data_priv.set( elem, "hasDataAttrs", true ); |
58 | office | 101 | } |
102 | } |
||
103 | |||
104 | return data; |
||
105 | } |
||
106 | |||
107 | // Sets multiple values |
||
108 | if ( typeof key === "object" ) { |
||
125 | office | 109 | return this.each(function() { |
110 | data_user.set( this, key ); |
||
111 | }); |
||
58 | office | 112 | } |
113 | |||
114 | return access( this, function( value ) { |
||
125 | office | 115 | var data, |
116 | camelKey = jQuery.camelCase( key ); |
||
58 | office | 117 | |
118 | // The calling jQuery object (element matches) is not empty |
||
119 | // (and therefore has an element appears at this[ 0 ]) and the |
||
120 | // `value` parameter was not undefined. An empty jQuery object |
||
121 | // will result in `undefined` for elem = this[ 0 ] which will |
||
122 | // throw an exception if an attempt to read a data cache is made. |
||
123 | if ( elem && value === undefined ) { |
||
125 | office | 124 | // Attempt to get data from the cache |
125 | // with the key as-is |
||
126 | data = data_user.get( elem, key ); |
||
127 | if ( data !== undefined ) { |
||
128 | return data; |
||
129 | } |
||
58 | office | 130 | |
131 | // Attempt to get data from the cache |
||
125 | office | 132 | // with the key camelized |
133 | data = data_user.get( elem, camelKey ); |
||
58 | office | 134 | if ( data !== undefined ) { |
135 | return data; |
||
136 | } |
||
137 | |||
138 | // Attempt to "discover" the data in |
||
139 | // HTML5 custom data-* attrs |
||
125 | office | 140 | data = dataAttr( elem, camelKey, undefined ); |
58 | office | 141 | if ( data !== undefined ) { |
142 | return data; |
||
143 | } |
||
144 | |||
145 | // We tried really hard, but the data doesn't exist. |
||
146 | return; |
||
147 | } |
||
148 | |||
149 | // Set the data... |
||
125 | office | 150 | this.each(function() { |
151 | // First, attempt to store a copy or reference of any |
||
152 | // data that might've been store with a camelCased key. |
||
153 | var data = data_user.get( this, camelKey ); |
||
58 | office | 154 | |
125 | office | 155 | // For HTML5 data-* attribute interop, we have to |
156 | // store property names with dashes in a camelCase form. |
||
157 | // This might not apply to all properties...* |
||
158 | data_user.set( this, camelKey, value ); |
||
159 | |||
160 | // *... In the case of properties that might _actually_ |
||
161 | // have dashes, we need to also store a copy of that |
||
162 | // unchanged property. |
||
163 | if ( key.indexOf("-") !== -1 && data !== undefined ) { |
||
164 | data_user.set( this, key, value ); |
||
165 | } |
||
166 | }); |
||
58 | office | 167 | }, null, value, arguments.length > 1, null, true ); |
168 | }, |
||
169 | |||
170 | removeData: function( key ) { |
||
125 | office | 171 | return this.each(function() { |
172 | data_user.remove( this, key ); |
||
173 | }); |
||
58 | office | 174 | } |
125 | office | 175 | }); |
58 | office | 176 | |
177 | return jQuery; |
||
125 | office | 178 | }); |