Merge branch 'master' of git://github.com/jquery/jquery into fixedbuild
[jquery.git] / src / data.js
index a1abc9e..2d53a71 100644 (file)
@@ -24,7 +24,7 @@ jQuery.extend({
        hasData: function( elem ) {
                elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
 
-               return !!elem && !jQuery.isEmptyObject(elem);
+               return !!elem && !isEmptyDataObject( elem );
        },
 
        data: function( elem, name, data, pvt /* Internal Use Only */ ) {
@@ -64,11 +64,18 @@ jQuery.extend({
 
                if ( !cache[ id ] ) {
                        cache[ id ] = {};
+
+                       // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+                       // metadata on plain JS objects when the object is serialized using
+                       // JSON.stringify
+                       if ( !isNode ) {
+                               cache[ id ].toJSON = jQuery.noop;
+                       }
                }
 
                // An object can be passed to jQuery.data instead of a key/value pair; this gets
                // shallow copied over onto the existing cache
-               if ( typeof name === "object" ) {
+               if ( typeof name === "object" || typeof name === "function" ) {
                        if ( pvt ) {
                                cache[ id ][ internalKey ] = jQuery.extend(cache[ id ][ internalKey ], name);
                        } else {
@@ -93,6 +100,13 @@ jQuery.extend({
                        thisCache[ name ] = data;
                }
 
+               // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should
+               // not attempt to inspect the internal events object using jQuery.data, as this
+               // internal data object is undocumented and subject to change.
+               if ( name === "events" && !thisCache[name] ) {
+                       return thisCache[ internalKey ] && thisCache[ internalKey ].events;
+               }
+
                return getByName ? thisCache[ name ] : thisCache;
        },
 
@@ -123,7 +137,7 @@ jQuery.extend({
 
                                // If there is no data left in the cache, we want to continue
                                // and let the cache object itself get destroyed
-                               if ( !jQuery.isEmptyObject(thisCache) ) {
+                               if ( !isEmptyDataObject(thisCache) ) {
                                        return;
                                }
                        }
@@ -135,7 +149,7 @@ jQuery.extend({
 
                        // Don't destroy the parent cache unless the internal data object
                        // had been the only thing left in it
-                       if ( !jQuery.isEmptyObject(cache[ id ]) ) {
+                       if ( !isEmptyDataObject(cache[ id ]) ) {
                                return;
                        }
                }
@@ -156,6 +170,13 @@ jQuery.extend({
                // data if it existed
                if ( internalCache ) {
                        cache[ id ] = {};
+                       // TODO: This is a hack for 1.5 ONLY. Avoids exposing jQuery
+                       // metadata on plain JS objects when the object is serialized using
+                       // JSON.stringify
+                       if ( !isNode ) {
+                               cache[ id ].toJSON = jQuery.noop;
+                       }
+
                        cache[ id ][ internalKey ] = internalCache;
 
                // Otherwise, we need to eliminate the expando on the node to avoid
@@ -284,4 +305,17 @@ function dataAttr( elem, key, data ) {
        return data;
 }
 
+// TODO: This is a hack for 1.5 ONLY to allow objects with a single toJSON
+// property to be considered empty objects; this property always exists in
+// order to make sure JSON.stringify does not expose internal metadata
+function isEmptyDataObject( obj ) {
+       for ( var name in obj ) {
+               if ( name !== "toJSON" ) {
+                       return false;
+               }
+       }
+
+       return true;
+}
+
 })( jQuery );