Make sure that jQuery works even when the individual modules are loaded separately...
[jquery.git] / src / data.js
1 (function( jQuery ) {
2
3 var windowData = {};
4
5 jQuery.extend({
6         cache: {},
7
8         // Please use with caution
9         uuid: 0,
10
11         // Unique for each copy of jQuery on the page   
12         expando: "jQuery" + jQuery.now(),
13
14         // The following elements throw uncatchable exceptions if you
15         // attempt to add expando properties to them.
16         noData: {
17                 "embed": true,
18                 "object": true,
19                 "applet": true
20         },
21
22         data: function( elem, name, data ) {
23                 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
24                         return;
25                 }
26
27                 elem = elem == window ?
28                         windowData :
29                         elem;
30
31                 var id = elem[ jQuery.expando ], cache = jQuery.cache, thisCache,
32                         isNode = elem.nodeType,
33                         store;
34
35                 if ( !id && typeof name === "string" && data === undefined ) {
36                         return;
37                 }
38
39                 // Get the data from the object directly
40                 if ( !isNode ) {
41                         cache = elem;
42                         id = jQuery.expando;
43
44                 // Compute a unique ID for the element
45                 } else if ( !id ) {
46                         elem[ jQuery.expando ] = id = ++jQuery.uuid;
47                 }
48
49                 // Avoid generating a new cache unless none exists and we
50                 // want to manipulate it.
51                 if ( typeof name === "object" ) {
52                         if ( isNode ) {
53                                 cache[ id ] = jQuery.extend(true, {}, name);
54                         } else {
55                                 store = jQuery.extend(true, {}, name);
56                                 cache[ id ] = function() {
57                                         return store;
58                                 };
59                         }
60
61                 } else if ( !cache[ id ] ) {
62                         if ( isNode ) {
63                                 cache[ id ] = {};
64                         } else {
65                                 store = {};
66                                 cache[ id ] = function() {
67                                         return store;
68                                 };
69                         }
70                         
71                 }
72
73                 thisCache = isNode ? cache[ id ] : cache[ id ]();
74
75                 // Prevent overriding the named cache with undefined values
76                 if ( data !== undefined ) {
77                         thisCache[ name ] = data;
78                 }
79
80                 return typeof name === "string" ? thisCache[ name ] : thisCache;
81         },
82
83         removeData: function( elem, name ) {
84                 if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {
85                         return;
86                 }
87
88                 elem = elem == window ?
89                         windowData :
90                         elem;
91
92                 var isNode = elem.nodeType,
93                         id = elem[ jQuery.expando ], cache = jQuery.cache;
94                 if ( id && !isNode ) {
95                         id = id();
96                 }
97                 var thisCache = cache[ id ];
98
99                 // If we want to remove a specific section of the element's data
100                 if ( name ) {
101                         if ( thisCache ) {
102                                 // Remove the section of cache data
103                                 delete thisCache[ name ];
104
105                                 // If we've removed all the data, remove the element's cache
106                                 if ( jQuery.isEmptyObject(thisCache) ) {
107                                         jQuery.removeData( elem );
108                                 }
109                         }
110
111                 // Otherwise, we want to remove all of the element's data
112                 } else {
113                         if ( jQuery.support.deleteExpando || !isNode ) {
114                                 delete elem[ jQuery.expando ];
115
116                         } else if ( elem.removeAttribute ) {
117                                 elem.removeAttribute( jQuery.expando );
118                         }
119
120                         // Completely remove the data cache
121                         if ( isNode ) {
122                                 delete cache[ id ];
123                         }
124                 }
125         }
126 });
127
128 jQuery.fn.extend({
129         data: function( key, value ) {
130                 if ( typeof key === "undefined" && this.length ) {
131                         return jQuery.data( this[0] );
132
133                 } else if ( typeof key === "object" ) {
134                         return this.each(function() {
135                                 jQuery.data( this, key );
136                         });
137                 }
138
139                 var parts = key.split(".");
140                 parts[1] = parts[1] ? "." + parts[1] : "";
141
142                 if ( value === undefined ) {
143                         var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
144
145                         if ( data === undefined && this.length ) {
146                                 data = jQuery.data( this[0], key );
147                         }
148
149                         return data === undefined && parts[1] ?
150                                 this.data( parts[0] ) :
151                                 data;
152
153                 } else {
154                         return this.each(function() {
155                                 var $this = jQuery( this ), args = [ parts[0], value ];
156
157                                 $this.triggerHandler( "setData" + parts[1] + "!", args );
158                                 jQuery.data( this, key, value );
159                                 $this.triggerHandler( "changeData" + parts[1] + "!", args );
160                         });
161                 }
162         },
163
164         removeData: function( key ) {
165                 return this.each(function() {
166                         jQuery.removeData( this, key );
167                 });
168         }
169 });
170
171 })( jQuery );