1 import { jQuery } from "../core.js";
2 import { camelCase } from "../core/camelCase.js";
3 import { rnothtmlwhite } from "../var/rnothtmlwhite.js";
4 import { acceptData } from "./var/acceptData.js";
6 export function Data() {
7 this.expando = jQuery.expando + Data.uid++;
14 cache: function( owner ) {
16 // Check if the owner object already has a cache
17 var value = owner[ this.expando ];
21 value = Object.create( null );
23 // We can accept data for non-element nodes in modern browsers,
24 // but we should not, see trac-8335.
25 // Always return an empty object.
26 if ( acceptData( owner ) ) {
28 // If it is a node unlikely to be stringify-ed or looped over
29 // use plain assignment
30 if ( owner.nodeType ) {
31 owner[ this.expando ] = value;
33 // Otherwise secure it in a non-enumerable property
34 // configurable must be true to allow the property to be
35 // deleted when data is removed
37 Object.defineProperty( owner, this.expando, {
47 set: function( owner, data, value ) {
49 cache = this.cache( owner );
51 // Handle: [ owner, key, value ] args
52 // Always use camelCase key (gh-2257)
53 if ( typeof data === "string" ) {
54 cache[ camelCase( data ) ] = value;
56 // Handle: [ owner, { properties } ] args
59 // Copy the properties one-by-one to the cache object
60 for ( prop in data ) {
61 cache[ camelCase( prop ) ] = data[ prop ];
66 get: function( owner, key ) {
67 return key === undefined ?
70 // Always use camelCase key (gh-2257)
71 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ];
73 access: function( owner, key, value ) {
75 // In cases where either:
77 // 1. No key was specified
78 // 2. A string key was specified, but no value provided
80 // Take the "read" path and allow the get method to determine
81 // which value to return, respectively either:
83 // 1. The entire cache object
84 // 2. The data stored at the key
86 if ( key === undefined ||
87 ( ( key && typeof key === "string" ) && value === undefined ) ) {
89 return this.get( owner, key );
92 // When the key is not a string, or both a key and value
93 // are specified, set or extend (existing objects) with either:
95 // 1. An object of properties
98 this.set( owner, key, value );
100 // Since the "set" path can have two possible entry points
101 // return the expected data based on which path was taken[*]
102 return value !== undefined ? value : key;
104 remove: function( owner, key ) {
106 cache = owner[ this.expando ];
108 if ( cache === undefined ) {
112 if ( key !== undefined ) {
114 // Support array or space separated string of keys
115 if ( Array.isArray( key ) ) {
117 // If key is an array of keys...
118 // We always set camelCase keys, so remove that.
119 key = key.map( camelCase );
121 key = camelCase( key );
123 // If a key with the spaces exists, use it.
124 // Otherwise, create an array by matching non-whitespace
127 ( key.match( rnothtmlwhite ) || [] );
133 delete cache[ key[ i ] ];
137 // Remove the expando if there's no more data
138 if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
140 // Support: Chrome <=35 - 45+
141 // Webkit & Blink performance suffers when deleting properties
142 // from DOM nodes, so set to undefined instead
143 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
144 if ( owner.nodeType ) {
145 owner[ this.expando ] = undefined;
147 delete owner[ this.expando ];
151 hasData: function( owner ) {
152 var cache = owner[ this.expando ];
153 return cache !== undefined && !jQuery.isEmptyObject( cache );