Hide metadata when serializing JS objects using JSON.stringify via a toJSON hack. Fixes #8108.
This commit is contained in:
parent
217a9919c3
commit
2ed81708bd
26
src/data.js
26
src/data.js
|
@ -24,7 +24,7 @@ jQuery.extend({
|
||||||
hasData: function( elem ) {
|
hasData: function( elem ) {
|
||||||
elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];
|
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 */ ) {
|
data: function( elem, name, data, pvt /* Internal Use Only */ ) {
|
||||||
|
@ -64,6 +64,13 @@ jQuery.extend({
|
||||||
|
|
||||||
if ( !cache[ id ] ) {
|
if ( !cache[ id ] ) {
|
||||||
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
|
||||||
|
cache[ id ].toJSON = function () {
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// An object can be passed to jQuery.data instead of a key/value pair; this gets
|
// An object can be passed to jQuery.data instead of a key/value pair; this gets
|
||||||
|
@ -130,7 +137,7 @@ jQuery.extend({
|
||||||
|
|
||||||
// If there is no data left in the cache, we want to continue
|
// If there is no data left in the cache, we want to continue
|
||||||
// and let the cache object itself get destroyed
|
// and let the cache object itself get destroyed
|
||||||
if ( !jQuery.isEmptyObject(thisCache) ) {
|
if ( !isEmptyDataObject(thisCache) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +149,7 @@ jQuery.extend({
|
||||||
|
|
||||||
// Don't destroy the parent cache unless the internal data object
|
// Don't destroy the parent cache unless the internal data object
|
||||||
// had been the only thing left in it
|
// had been the only thing left in it
|
||||||
if ( !jQuery.isEmptyObject(cache[ id ]) ) {
|
if ( !isEmptyDataObject(cache[ id ]) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -291,4 +298,17 @@ function dataAttr( elem, key, data ) {
|
||||||
return 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 );
|
})( jQuery );
|
||||||
|
|
|
@ -180,7 +180,13 @@ test(".data()", function() {
|
||||||
var div = jQuery("#foo");
|
var div = jQuery("#foo");
|
||||||
strictEqual( div.data("foo"), undefined, "Make sure that missing result is undefined" );
|
strictEqual( div.data("foo"), undefined, "Make sure that missing result is undefined" );
|
||||||
div.data("test", "success");
|
div.data("test", "success");
|
||||||
same( div.data(), {test: "success"}, "data() get the entire data object" );
|
|
||||||
|
var dataObj = div.data();
|
||||||
|
|
||||||
|
// TODO: Remove this hack which was introduced in 1.5.1
|
||||||
|
delete dataObj.toJSON;
|
||||||
|
|
||||||
|
same( dataObj, {test: "success"}, "data() get the entire data object" );
|
||||||
strictEqual( div.data("foo"), undefined, "Make sure that missing result is still undefined" );
|
strictEqual( div.data("foo"), undefined, "Make sure that missing result is still undefined" );
|
||||||
|
|
||||||
var nodiv = jQuery("#unfound");
|
var nodiv = jQuery("#unfound");
|
||||||
|
@ -189,7 +195,10 @@ test(".data()", function() {
|
||||||
var obj = { foo: "bar" };
|
var obj = { foo: "bar" };
|
||||||
jQuery(obj).data("foo", "baz");
|
jQuery(obj).data("foo", "baz");
|
||||||
|
|
||||||
var dataObj = jQuery.extend(true, {}, jQuery(obj).data());
|
dataObj = jQuery.extend(true, {}, jQuery(obj).data());
|
||||||
|
|
||||||
|
// TODO: Remove this hack which was introduced for 1.5.1
|
||||||
|
delete dataObj.toJSON;
|
||||||
|
|
||||||
deepEqual( dataObj, { foo: "baz" }, "Retrieve data object from a wrapped JS object (#7524)" );
|
deepEqual( dataObj, { foo: "baz" }, "Retrieve data object from a wrapped JS object (#7524)" );
|
||||||
});
|
});
|
||||||
|
@ -329,12 +338,18 @@ test("data-* attributes", function() {
|
||||||
num++;
|
num++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Remove this hack which was introduced for 1.5.1
|
||||||
|
num--;
|
||||||
|
|
||||||
equals( num, check.length, "Make sure that the right number of properties came through." );
|
equals( num, check.length, "Make sure that the right number of properties came through." );
|
||||||
|
|
||||||
for ( var prop in obj2 ) {
|
for ( var prop in obj2 ) {
|
||||||
num2++;
|
num2++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Remove this hack which was introduced for 1.5.1
|
||||||
|
num2--;
|
||||||
|
|
||||||
equals( num2, check.length, "Make sure that the right number of properties came through." );
|
equals( num2, check.length, "Make sure that the right number of properties came through." );
|
||||||
|
|
||||||
child.attr("data-other", "newvalue");
|
child.attr("data-other", "newvalue");
|
||||||
|
@ -466,3 +481,14 @@ test(".removeData()", function() {
|
||||||
div.removeData("test.foo");
|
div.removeData("test.foo");
|
||||||
equals( div.data("test.foo"), undefined, "Make sure data is intact" );
|
equals( div.data("test.foo"), undefined, "Make sure data is intact" );
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (window.JSON && window.JSON.stringify) {
|
||||||
|
test("JSON serialization (#8108)", function () {
|
||||||
|
expect(1);
|
||||||
|
|
||||||
|
var obj = { foo: "bar" };
|
||||||
|
jQuery.data(obj, "hidden", true);
|
||||||
|
|
||||||
|
equals( JSON.stringify(obj), '{"foo":"bar"}', "Expando is hidden from JSON.stringify" );
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in a new issue