var expando = "jQuery" + now(), uuid = 0, windowData = {};\r
+var emptyObject = {};\r
\r
jQuery.extend({\r
cache: {},\r
+ \r
+ expando:expando,\r
\r
data: function( elem, name, data ) {\r
elem = elem == window ?\r
windowData :\r
elem;\r
\r
- var id = elem[ expando ];\r
+ var id = elem[ expando ], cache = jQuery.cache, thisCache;\r
\r
- // Compute a unique ID for the element\r
- if ( !id )\r
- id = elem[ expando ] = ++uuid;\r
+ // Handle the case where there's no name immediately\r
+ if ( !name ) {\r
+ return id;\r
+ }\r
\r
- // Only generate the data cache if we're\r
- // trying to access or manipulate it\r
- if ( name && !jQuery.cache[ id ] )\r
- jQuery.cache[ id ] = {};\r
+ // Compute a unique ID for the element\r
+ if ( !id ) { \r
+ id = ++uuid;\r
+ }\r
\r
+ // Avoid generating a new cache unless none exists and we\r
+ // want to manipulate it.\r
+ if ( cache[ id ] ) {\r
+ thisCache = cache[ id ];\r
+ } else if ( typeof data === "undefined" ) {\r
+ thisCache = emptyObject;\r
+ } else {\r
+ thisCache = cache[ id ] = {};\r
+ }\r
+ \r
// Prevent overriding the named cache with undefined values\r
- if ( data !== undefined )\r
- jQuery.cache[ id ][ name ] = data;\r
-\r
- // Return the named cache data, or the ID for the element\r
- return name ?\r
- jQuery.cache[ id ][ name ] :\r
- id;\r
+ if ( data !== undefined ) {\r
+ elem[ expando ] = id;\r
+ thisCache[ name ] = data;\r
+ }\r
+ \r
+ return name === true ? thisCache : thisCache[ name ];\r
},\r
\r
removeData: function( elem, name ) {\r
windowData :\r
elem;\r
\r
- var id = elem[ expando ];\r
+ var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];\r
\r
// If we want to remove a specific section of the element's data\r
if ( name ) {\r
- if ( jQuery.cache[ id ] ) {\r
+ if ( thisCache ) {\r
// Remove the section of cache data\r
- delete jQuery.cache[ id ][ name ];\r
+ delete thisCache[ name ];\r
\r
// If we've removed all the data, remove the element's cache\r
- name = "";\r
-\r
- for ( name in jQuery.cache[ id ] )\r
- break;\r
-\r
- if ( !name )\r
+ if ( jQuery.isEmptyObject(thisCache) ) {\r
jQuery.removeData( elem );\r
+ }\r
}\r
\r
// Otherwise, we want to remove all of the element's data\r
// Clean up the element expando\r
try {\r
delete elem[ expando ];\r
- } catch(e){\r
+ } catch( e ) {\r
// IE has trouble directly removing the expando\r
// but it's ok with using removeAttribute\r
- if ( elem.removeAttribute )\r
+ if ( elem.removeAttribute ) {\r
elem.removeAttribute( expando );\r
+ }\r
}\r
\r
// Completely remove the data cache\r
- delete jQuery.cache[ id ];\r
+ delete cache[ id ];\r
}\r
},\r
+ \r
queue: function( elem, type, data ) {\r
- if ( elem ){\r
+ if( !elem ) return;\r
\r
- type = (type || "fx") + "queue";\r
+ type = (type || "fx") + "queue";\r
+ var q = jQuery.data( elem, type );\r
\r
- var q = jQuery.data( elem, type );\r
+ // Speed up dequeue by getting out quickly if this is just a lookup\r
+ if( !data ) return q || [];\r
\r
- if ( !q || jQuery.isArray(data) )\r
- q = jQuery.data( elem, type, jQuery.makeArray(data) );\r
- else if( data )\r
- q.push( data );\r
+ if ( !q || jQuery.isArray(data) )\r
+ q = jQuery.data( elem, type, jQuery.makeArray(data) );\r
+ else\r
+ q.push( data );\r
\r
- }\r
return q;\r
},\r
\r
dequeue: function( elem, type ){\r
- var queue = jQuery.queue( elem, type ),\r
- fn = queue.shift();\r
+ type = type || "fx";\r
+\r
+ var queue = jQuery.queue( elem, type ), fn = queue.shift();\r
\r
- if( !type || type === "fx" )\r
- fn = queue[0];\r
+ // If the fx queue is dequeued, always remove the progress sentinel\r
+ if( fn === "inprogress" ) fn = queue.shift();\r
\r
- if( fn !== undefined )\r
- fn.call(elem, function() { jQuery(elem).dequeue(type); });\r
+ if( fn ) {\r
+ // Add a progress sentinel to prevent the fx queue from being\r
+ // automatically dequeued\r
+ if( type == "fx" ) queue.unshift("inprogress");\r
+\r
+ fn.call(elem, function() { jQuery.dequeue(elem, type); });\r
+ }\r
}\r
});\r
\r
jQuery.fn.extend({\r
data: function( key, value ){\r
+ if(typeof key === "undefined" && this.length) return jQuery.data(this[0], true);\r
+\r
var parts = key.split(".");\r
parts[1] = parts[1] ? "." + parts[1] : "";\r
\r
return this.each(function(i, elem){\r
var queue = jQuery.queue( this, type, data );\r
\r
- if( type == "fx" && queue.length == 1 )\r
- queue[0].call(this, function() { jQuery(elem).dequeue(type); });\r
+ if( type == "fx" && queue[0] !== "inprogress" )\r
+ jQuery.dequeue( this, type )\r
});\r
},\r
dequeue: function(type){\r