var windowData = {}; jQuery.extend({ cache: {}, // Please use with caution uuid: 0, // Unique for each copy of jQuery on the page expando: "jQuery" + jQuery.now(), // The following elements throw uncatchable exceptions if you // attempt to add expando properties to them. noData: { "embed": true, "object": true, "applet": true }, data: function( elem, name, data ) { if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { return; } elem = elem == window ? windowData : elem; var id = elem[ jQuery.expando ], cache = jQuery.cache, thisCache, isNode = elem.nodeType; if ( !id && typeof name === "string" && data === undefined ) { return; } // Get the data from the object directly if ( !isNode ) { cache = elem; id = jQuery.expando; // Compute a unique ID for the element } else if ( !id ) { elem[ jQuery.expando ] = id = ++jQuery.uuid; } // Avoid generating a new cache unless none exists and we // want to manipulate it. if ( typeof name === "object" ) { if ( isNode ) { cache[ id ] = jQuery.extend(true, {}, name); } else { cache[ id ] = function() { return jQuery.extend(true, {}, name); } } } else if ( !cache[ id ] ) { if ( isNode ) { cache[ id ] = {}; } else { var store = {}; cache[ id ] = function() { return store; } } } thisCache = cache[ id ]; if ( !isNode ) { thisCache = thisCache(); } // Prevent overriding the named cache with undefined values if ( data !== undefined ) { thisCache[ name ] = data; } return typeof name === "string" ? thisCache[ name ] : thisCache; }, removeData: function( elem, name ) { if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) { return; } elem = elem == window ? windowData : elem; var isNode = elem.nodeType, id = elem[ jQuery.expando ], cache = jQuery.cache; if ( id && !isNode ) { id = id(); } var thisCache = cache[ id ]; // If we want to remove a specific section of the element's data if ( name ) { if ( thisCache ) { // Remove the section of cache data delete thisCache[ name ]; // If we've removed all the data, remove the element's cache if ( jQuery.isEmptyObject(thisCache) ) { jQuery.removeData( elem ); } } // Otherwise, we want to remove all of the element's data } else { if ( jQuery.support.deleteExpando || !isNode ) { delete elem[ jQuery.expando ]; } else if ( elem.removeAttribute ) { elem.removeAttribute( jQuery.expando ); } // Completely remove the data cache if ( isNode ) { delete cache[ id ]; } } } }); jQuery.fn.extend({ data: function( key, value ) { if ( typeof key === "undefined" && this.length ) { return jQuery.data( this[0] ); } else if ( typeof key === "object" ) { return this.each(function() { jQuery.data( this, key ); }); } var parts = key.split("."); parts[1] = parts[1] ? "." + parts[1] : ""; if ( value === undefined ) { var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]); if ( data === undefined && this.length ) { data = jQuery.data( this[0], key ); } return data === undefined && parts[1] ? this.data( parts[0] ) : data; } else { return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() { jQuery.data( this, key, value ); jQuery.event.trigger( "changeData" + parts[1] + "!", [parts[0], value], this ); }); } }, removeData: function( key ) { return this.each(function() { jQuery.removeData( this, key ); }); } });