Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
179 lines (146 sloc)
4.2 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| define( [ | |
| "./core", | |
| "./core/access", | |
| "./data/var/dataPriv", | |
| "./data/var/dataUser" | |
| ], function( jQuery, access, 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 (#14894) | |
| if ( attrs[ i ] ) { | |
| name = attrs[ i ].name; | |
| if ( name.indexOf( "data-" ) === 0 ) { | |
| name = jQuery.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; | |
| } ); |