1
|
define( [
|
2
|
"../core",
|
3
|
"../var/rnothtmlwhite",
|
4
|
"./var/acceptData"
|
5
|
], function( jQuery, rnothtmlwhite, acceptData ) {
|
6
|
|
7
|
"use strict";
|
8
|
|
9
|
function Data() {
|
10
|
this.expando = jQuery.expando + Data.uid++;
|
11
|
}
|
12
|
|
13
|
Data.uid = 1;
|
14
|
|
15
|
Data.prototype = {
|
16
|
|
17
|
cache: function( owner ) {
|
18
|
|
19
|
// Check if the owner object already has a cache
|
20
|
var value = owner[ this.expando ];
|
21
|
|
22
|
// If not, create one
|
23
|
if ( !value ) {
|
24
|
value = {};
|
25
|
|
26
|
// We can accept data for non-element nodes in modern browsers,
|
27
|
// but we should not, see #8335.
|
28
|
// Always return an empty object.
|
29
|
if ( acceptData( owner ) ) {
|
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
|
|
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 {
|
40
|
Object.defineProperty( owner, this.expando, {
|
41
|
value: value,
|
42
|
configurable: true
|
43
|
} );
|
44
|
}
|
45
|
}
|
46
|
}
|
47
|
|
48
|
return value;
|
49
|
},
|
50
|
set: function( owner, data, value ) {
|
51
|
var prop,
|
52
|
cache = this.cache( owner );
|
53
|
|
54
|
// Handle: [ owner, key, value ] args
|
55
|
// Always use camelCase key (gh-2257)
|
56
|
if ( typeof data === "string" ) {
|
57
|
cache[ jQuery.camelCase( data ) ] = value;
|
58
|
|
59
|
// Handle: [ owner, { properties } ] args
|
60
|
} else {
|
61
|
|
62
|
// Copy the properties one-by-one to the cache object
|
63
|
for ( prop in data ) {
|
64
|
cache[ jQuery.camelCase( prop ) ] = data[ prop ];
|
65
|
}
|
66
|
}
|
67
|
return cache;
|
68
|
},
|
69
|
get: function( owner, key ) {
|
70
|
return key === undefined ?
|
71
|
this.cache( owner ) :
|
72
|
|
73
|
// Always use camelCase key (gh-2257)
|
74
|
owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
|
75
|
},
|
76
|
access: function( owner, key, value ) {
|
77
|
|
78
|
// In cases where either:
|
79
|
//
|
80
|
// 1. No key was specified
|
81
|
// 2. A string key was specified, but no value provided
|
82
|
//
|
83
|
// Take the "read" path and allow the get method to determine
|
84
|
// which value to return, respectively either:
|
85
|
//
|
86
|
// 1. The entire cache object
|
87
|
// 2. The data stored at the key
|
88
|
//
|
89
|
if ( key === undefined ||
|
90
|
( ( key && typeof key === "string" ) && value === undefined ) ) {
|
91
|
|
92
|
return this.get( owner, key );
|
93
|
}
|
94
|
|
95
|
// When the key is not a string, or both a key and value
|
96
|
// are specified, set or extend (existing objects) with either:
|
97
|
//
|
98
|
// 1. An object of properties
|
99
|
// 2. A key and value
|
100
|
//
|
101
|
this.set( owner, key, value );
|
102
|
|
103
|
// Since the "set" path can have two possible entry points
|
104
|
// return the expected data based on which path was taken[*]
|
105
|
return value !== undefined ? value : key;
|
106
|
},
|
107
|
remove: function( owner, key ) {
|
108
|
var i,
|
109
|
cache = owner[ this.expando ];
|
110
|
|
111
|
if ( cache === undefined ) {
|
112
|
return;
|
113
|
}
|
114
|
|
115
|
if ( key !== undefined ) {
|
116
|
|
117
|
// Support array or space separated string of keys
|
118
|
if ( Array.isArray( key ) ) {
|
119
|
|
120
|
// If key is an array of keys...
|
121
|
// We always set camelCase keys, so remove that.
|
122
|
key = key.map( jQuery.camelCase );
|
123
|
} else {
|
124
|
key = jQuery.camelCase( key );
|
125
|
|
126
|
// If a key with the spaces exists, use it.
|
127
|
// Otherwise, create an array by matching non-whitespace
|
128
|
key = key in cache ?
|
129
|
[ key ] :
|
130
|
( key.match( rnothtmlwhite ) || [] );
|
131
|
}
|
132
|
|
133
|
i = key.length;
|
134
|
|
135
|
while ( i-- ) {
|
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
|
145
|
// from DOM nodes, so set to undefined instead
|
146
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
|
147
|
if ( owner.nodeType ) {
|
148
|
owner[ this.expando ] = undefined;
|
149
|
} else {
|
150
|
delete owner[ this.expando ];
|
151
|
}
|
152
|
}
|
153
|
},
|
154
|
hasData: function( owner ) {
|
155
|
var cache = owner[ this.expando ];
|
156
|
return cache !== undefined && !jQuery.isEmptyObject( cache );
|
157
|
}
|
158
|
};
|
159
|
|
160
|
return Data;
|
161
|
} );
|