|  | define( [ | 
|  | "./core", | 
|  | "./core/access", | 
|  | "./core/camelCase", | 
|  | "./data/var/dataPriv", | 
|  | "./data/var/dataUser" | 
|  | ], function( jQuery, access, camelCase, dataPriv, dataUser ) { | 
|  |  | 
|  | "use strict"; | 
|  |  | 
|  | //	Implementation Summary | 
|  | // | 
|  | //	1. Enforce API surface and semantic compatibility with 1.9.x branch | 
|  | //	2. Improve the module's maintainability by reducing the storage | 
|  | //		paths to a single mechanism. | 
|  | //	3. Use the same single mechanism to support "private" and "user" data. | 
|  | //	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) | 
|  | //	5. Avoid exposing implementation details on user objects (eg. expando properties) | 
|  | //	6. Provide a clear path for implementation upgrade to WeakMap in 2014 | 
|  |  | 
|  | var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, | 
|  | rmultiDash = /[A-Z]/g; | 
|  |  | 
|  | function getData( data ) { | 
|  | if ( data === "true" ) { | 
|  | return true; | 
|  | } | 
|  |  | 
|  | if ( data === "false" ) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | if ( data === "null" ) { | 
|  | return null; | 
|  | } | 
|  |  | 
|  | // Only convert to a number if it doesn't change the string | 
|  | if ( data === +data + "" ) { | 
|  | return +data; | 
|  | } | 
|  |  | 
|  | if ( rbrace.test( data ) ) { | 
|  | return JSON.parse( data ); | 
|  | } | 
|  |  | 
|  | return data; | 
|  | } | 
|  |  | 
|  | function dataAttr( elem, key, data ) { | 
|  | var name; | 
|  |  | 
|  | // If nothing was found internally, try to fetch any | 
|  | // data from the HTML5 data-* attribute | 
|  | if ( data === undefined && elem.nodeType === 1 ) { | 
|  | name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); | 
|  | data = elem.getAttribute( name ); | 
|  |  | 
|  | if ( typeof data === "string" ) { | 
|  | try { | 
|  | data = getData( data ); | 
|  | } catch ( e ) {} | 
|  |  | 
|  | // Make sure we set the data so it isn't changed later | 
|  | dataUser.set( elem, key, data ); | 
|  | } else { | 
|  | data = undefined; | 
|  | } | 
|  | } | 
|  | return data; | 
|  | } | 
|  |  | 
|  | jQuery.extend( { | 
|  | hasData: function( elem ) { | 
|  | return dataUser.hasData( elem ) || dataPriv.hasData( elem ); | 
|  | }, | 
|  |  | 
|  | data: function( elem, name, data ) { | 
|  | return dataUser.access( elem, name, data ); | 
|  | }, | 
|  |  | 
|  | removeData: function( elem, name ) { | 
|  | dataUser.remove( elem, name ); | 
|  | }, | 
|  |  | 
|  | // TODO: Now that all calls to _data and _removeData have been replaced | 
|  | // with direct calls to dataPriv methods, these can be deprecated. | 
|  | _data: function( elem, name, data ) { | 
|  | return dataPriv.access( elem, name, data ); | 
|  | }, | 
|  |  | 
|  | _removeData: function( elem, name ) { | 
|  | dataPriv.remove( elem, name ); | 
|  | } | 
|  | } ); | 
|  |  | 
|  | jQuery.fn.extend( { | 
|  | data: function( key, value ) { | 
|  | var i, name, data, | 
|  | elem = this[ 0 ], | 
|  | attrs = elem && elem.attributes; | 
|  |  | 
|  | // Gets all values | 
|  | if ( key === undefined ) { | 
|  | if ( this.length ) { | 
|  | data = dataUser.get( elem ); | 
|  |  | 
|  | if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { | 
|  | i = attrs.length; | 
|  | while ( i-- ) { | 
|  |  | 
|  | // Support: IE 11 only | 
|  | // The attrs elements can be null (trac-14894) | 
|  | if ( attrs[ i ] ) { | 
|  | name = attrs[ i ].name; | 
|  | if ( name.indexOf( "data-" ) === 0 ) { | 
|  | name = camelCase( name.slice( 5 ) ); | 
|  | dataAttr( elem, name, data[ name ] ); | 
|  | } | 
|  | } | 
|  | } | 
|  | dataPriv.set( elem, "hasDataAttrs", true ); | 
|  | } | 
|  | } | 
|  |  | 
|  | return data; | 
|  | } | 
|  |  | 
|  | // Sets multiple values | 
|  | if ( typeof key === "object" ) { | 
|  | return this.each( function() { | 
|  | dataUser.set( this, key ); | 
|  | } ); | 
|  | } | 
|  |  | 
|  | return access( this, function( value ) { | 
|  | var data; | 
|  |  | 
|  | // The calling jQuery object (element matches) is not empty | 
|  | // (and therefore has an element appears at this[ 0 ]) and the | 
|  | // `value` parameter was not undefined. An empty jQuery object | 
|  | // will result in `undefined` for elem = this[ 0 ] which will | 
|  | // throw an exception if an attempt to read a data cache is made. | 
|  | if ( elem && value === undefined ) { | 
|  |  | 
|  | // Attempt to get data from the cache | 
|  | // The key will always be camelCased in Data | 
|  | data = dataUser.get( elem, key ); | 
|  | if ( data !== undefined ) { | 
|  | return data; | 
|  | } | 
|  |  | 
|  | // Attempt to "discover" the data in | 
|  | // HTML5 custom data-* attrs | 
|  | data = dataAttr( elem, key ); | 
|  | if ( data !== undefined ) { | 
|  | return data; | 
|  | } | 
|  |  | 
|  | // We tried really hard, but the data doesn't exist. | 
|  | return; | 
|  | } | 
|  |  | 
|  | // Set the data... | 
|  | this.each( function() { | 
|  |  | 
|  | // We always store the camelCased key | 
|  | dataUser.set( this, key, value ); | 
|  | } ); | 
|  | }, null, value, arguments.length > 1, null, true ); | 
|  | }, | 
|  |  | 
|  | removeData: function( key ) { | 
|  | return this.each( function() { | 
|  | dataUser.remove( this, key ); | 
|  | } ); | 
|  | } | 
|  | } ); | 
|  |  | 
|  | return jQuery; | 
|  | } ); |