Refactor queueing system to allow auto-dequeuing to use dequeue directly and
[jquery.git] / src / data.js
1 var expando = "jQuery" + now(), uuid = 0, windowData = {};\r
2 \r
3 jQuery.extend({\r
4         cache: {},\r
5 \r
6         data: function( elem, name, data ) {\r
7                 elem = elem == window ?\r
8                         windowData :\r
9                         elem;\r
10 \r
11                 var id = elem[ expando ], cache = jQuery.cache;\r
12 \r
13                 // Compute a unique ID for the element\r
14                 if(!id) id = elem[ expando ] = ++uuid;\r
15 \r
16                 // Only generate the data cache if we're\r
17                 // trying to access or manipulate it\r
18                 if ( name && !cache[ id ] )\r
19                         cache[ id ] = {};\r
20 \r
21                 var thisCache = cache[ id ];\r
22 \r
23                 // Prevent overriding the named cache with undefined values\r
24                 if ( data !== undefined ) thisCache[ name ] = data;\r
25 \r
26                 if(name === true) return thisCache\r
27                 else if(name) return thisCache[name]\r
28                 else return id\r
29         },\r
30 \r
31         removeData: function( elem, name ) {\r
32                 elem = elem == window ?\r
33                         windowData :\r
34                         elem;\r
35 \r
36                 var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];\r
37 \r
38                 // If we want to remove a specific section of the element's data\r
39                 if ( name ) {\r
40                         if ( thisCache ) {\r
41                                 // Remove the section of cache data\r
42                                 delete thisCache[ name ];\r
43 \r
44                                 // If we've removed all the data, remove the element's cache\r
45                                 if( jQuery.isEmptyObject(thisCache) )\r
46                                         jQuery.removeData( elem );\r
47                         }\r
48 \r
49                 // Otherwise, we want to remove all of the element's data\r
50                 } else {\r
51                         // Clean up the element expando\r
52                         try {\r
53                                 delete elem[ expando ];\r
54                         } catch(e){\r
55                                 // IE has trouble directly removing the expando\r
56                                 // but it's ok with using removeAttribute\r
57                                 if ( elem.removeAttribute )\r
58                                         elem.removeAttribute( expando );\r
59                         }\r
60 \r
61                         // Completely remove the data cache\r
62                         delete cache[ id ];\r
63                 }\r
64         },\r
65         queue: function( elem, type, data ) {\r
66                 if( !elem ) return;\r
67 \r
68                 type = (type || "fx") + "queue";\r
69                 var q = jQuery.data( elem, type );\r
70 \r
71                 // Speed up dequeue by getting out quickly if this is just a lookup\r
72                 if( !data ) return q || [];\r
73 \r
74                 if ( !q || jQuery.isArray(data) )\r
75                         q = jQuery.data( elem, type, jQuery.makeArray(data) );\r
76                 else\r
77                         q.push( data );\r
78 \r
79                 return q;\r
80         },\r
81 \r
82         dequeue: function( elem, type ){\r
83                 type = type || "fx";\r
84 \r
85                 var queue = jQuery.queue( elem, type ), fn = queue.shift();\r
86 \r
87                 // If the fx queue is dequeued, always remove the progress sentinel\r
88                 if( fn === "inprogress" ) fn = queue.shift();\r
89 \r
90                 if( fn ) {\r
91                         // Add a progress sentinel to prevent the fx queue from being\r
92                         // automatically dequeued\r
93                         if( type == "fx" ) queue.unshift("inprogress");\r
94 \r
95                         fn.call(elem, function() { jQuery.dequeue(elem, type); });\r
96                 }\r
97         }\r
98 });\r
99 \r
100 jQuery.fn.extend({\r
101         data: function( key, value ){\r
102                 if(typeof key === "undefined" && this.length) return jQuery.data(this[0], true);\r
103 \r
104                 var parts = key.split(".");\r
105                 parts[1] = parts[1] ? "." + parts[1] : "";\r
106 \r
107                 if ( value === undefined ) {\r
108                         var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);\r
109 \r
110                         if ( data === undefined && this.length )\r
111                                 data = jQuery.data( this[0], key );\r
112 \r
113                         return data === undefined && parts[1] ?\r
114                                 this.data( parts[0] ) :\r
115                                 data;\r
116                 } else\r
117                         return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){\r
118                                 jQuery.data( this, key, value );\r
119                         });\r
120         },\r
121 \r
122         removeData: function( key ){\r
123                 return this.each(function(){\r
124                         jQuery.removeData( this, key );\r
125                 });\r
126         },\r
127         queue: function(type, data){\r
128                 if ( typeof type !== "string" ) {\r
129                         data = type;\r
130                         type = "fx";\r
131                 }\r
132 \r
133                 if ( data === undefined )\r
134                         return jQuery.queue( this[0], type );\r
135 \r
136                 return this.each(function(i, elem){\r
137                         var queue = jQuery.queue( this, type, data );\r
138 \r
139                         if( type == "fx" && queue[0] !== "inprogress" )\r
140                                 jQuery.dequeue( this, type )\r
141                 });\r
142         },\r
143         dequeue: function(type){\r
144                 return this.each(function(){\r
145                         jQuery.dequeue( this, type );\r
146                 });\r
147         },\r
148         clearQueue: function(type){\r
149                 return this.queue( type || "fx", [] );\r
150         }\r
151 });