From: Colin Snover Date: Mon, 7 Feb 2011 16:52:33 +0000 (-0600) Subject: Merge branch 'master' of github.com:jquery/jquery into jquery-master X-Git-Url: http://git.asbjorn.it/?p=jquery.git;a=commitdiff_plain;h=8805f1373d321d7e80e1984bd7e9a3e5d8e50943;hp=5b421fed003e6704bd0fbba2dea5c1b6add2cf52 Merge branch 'master' of github.com:jquery/jquery into jquery-master --- diff --git a/src/data.js b/src/data.js index 21f0e3a..faa44f3 100644 --- a/src/data.js +++ b/src/data.js @@ -63,12 +63,14 @@ jQuery.extend({ } if ( !cache[ id ] ) { - cache[ id ] = {}; + // Use a Function as the cache object instead of an Object on JS objects + // as a hack to prevent JSON.stringify from serializing it (#8108) + cache[ id ] = isNode ? {} : function () {}; } // 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 { diff --git a/src/event.js b/src/event.js index 2d53562..f3a5d9f 100644 --- a/src/event.js +++ b/src/event.js @@ -7,8 +7,7 @@ var rnamespaces = /\.(.*)$/, rescape = /[^\w\s.|`]/g, fcleanup = function( nm ) { return nm.replace(rescape, "\\$&"); - }, - eventKey = "events"; + }; /* * A number of helper functions used for managing events. @@ -58,23 +57,10 @@ jQuery.event = { return; } - var events = elemData[ eventKey ], + var events = elemData.events, eventHandle = elemData.handle; - if ( typeof events === "function" ) { - // On plain objects events is a fn that holds the the data - // which prevents this data from being JSON serialized - // the function does not need to be called, it just contains the data - eventHandle = events.handle; - events = events.events; - - } else if ( !events ) { - if ( !elem.nodeType ) { - // On plain objects, create a fn that acts as the holder - // of the values to avoid JSON serialization of event data - elemData[ eventKey ] = elemData = function(){}; - } - + if ( !events ) { elemData.events = events = {}; } @@ -175,17 +161,12 @@ jQuery.event = { var ret, type, fn, j, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType, elemData = jQuery.hasData( elem ) && jQuery._data( elem ), - events = elemData && elemData[ eventKey ]; + events = elemData && elemData.events; if ( !elemData || !events ) { return; } - if ( typeof events === "function" ) { - elemData = events; - events = events.events; - } - // types is actually an event object here if ( types && types.type ) { handler = types.handler; @@ -285,10 +266,7 @@ jQuery.event = { delete elemData.events; delete elemData.handle; - if ( typeof elemData === "function" ) { - jQuery.removeData( elem, eventKey, true ); - - } else if ( jQuery.isEmptyObject( elemData ) ) { + if ( jQuery.isEmptyObject( elemData ) ) { jQuery.removeData( elem, undefined, true ); } } @@ -329,7 +307,7 @@ jQuery.event = { // points to jQuery.expando var internalKey = jQuery.expando, internalCache = this[ internalKey ]; - if ( internalCache && internalCache.events && internalCache.events[type] ) { + if ( internalCache && internalCache.events && internalCache.events[ type ] ) { jQuery.event.trigger( event, data, internalCache.handle.elem ); } }); @@ -355,9 +333,7 @@ jQuery.event = { event.currentTarget = elem; // Trigger the event, it is assumed that "handle" is a function - var handle = elem.nodeType ? - jQuery._data( elem, "handle" ) : - (jQuery._data( elem, eventKey ) || {}).handle; + var handle = jQuery._data( elem, "handle" ); if ( handle ) { handle.apply( elem, data ); @@ -435,11 +411,7 @@ jQuery.event = { event.namespace = event.namespace || namespace_sort.join("."); - events = jQuery._data(this, eventKey); - - if ( typeof events === "function" ) { - events = events.events; - } + events = jQuery._data(this, "events"); handlers = (events || {})[ event.type ]; @@ -606,7 +578,7 @@ jQuery.Event = function( src ) { // Events bubbling up the document may have been marked as prevented // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || + this.isDefaultPrevented = (src.defaultPrevented || src.returnValue === false || src.getPreventDefault && src.getPreventDefault()) ? returnTrue : returnFalse; // Event type @@ -880,8 +852,8 @@ if ( document.addEventListener ) { jQuery.event.special[ fix ] = { setup: function() { this.addEventListener( orig, handler, true ); - }, - teardown: function() { + }, + teardown: function() { this.removeEventListener( orig, handler, true ); } }; @@ -1074,11 +1046,7 @@ function liveHandler( event ) { var stop, maxLevel, related, match, handleObj, elem, j, i, l, data, close, namespace, ret, elems = [], selectors = [], - events = jQuery._data( this, eventKey ); - - if ( typeof events === "function" ) { - events = events.events; - } + events = jQuery._data( this, "events" ); // Make sure we avoid non-left-click bubbling in Firefox (#3861) and disabled elements in IE (#6911) if ( event.liveFired === this || !events || !events.live || event.target.disabled || event.button && event.type === "click" ) { diff --git a/test/unit/data.js b/test/unit/data.js index 889fc2d..1ce512c 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -22,7 +22,7 @@ function dataTests (elem) { strictEqual( jQuery.hasData(elem), false, "jQuery.hasData agrees no data exists initially" ); var dataObj = jQuery.data(elem); - equals( typeof dataObj, "object", "Calling data with no args gives us a data object reference" ); + equals( typeof dataObj, elem.nodeType ? "object" : "function", "Calling data with no args gives us a data object reference" ); strictEqual( jQuery.data(elem), dataObj, "Calling jQuery.data returns the same data object when called multiple times" ); strictEqual( jQuery.hasData(elem), false, "jQuery.hasData agrees no data exists even when an empty data obj exists" ); @@ -187,8 +187,12 @@ test(".data()", function() { equals( nodiv.data(), null, "data() on empty set returns null" ); var obj = { foo: "bar" }; - deepEqual( jQuery(obj).data(), {}, "Retrieve data object from a wrapped JS object (#7524)" ); -}) + jQuery(obj).data("foo", "baz"); + + var dataObj = jQuery.extend(true, {}, jQuery(obj).data()); + + deepEqual( dataObj, { foo: "baz" }, "Retrieve data object from a wrapped JS object (#7524)" ); +}); test(".data(String) and .data(String, Object)", function() { expect(29); @@ -461,4 +465,15 @@ test(".removeData()", function() { div.removeData("test.foo"); equals( div.data("test.foo"), undefined, "Make sure data is intact" ); -}); \ No newline at end of file +}); + +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" ); + }); +} \ No newline at end of file diff --git a/test/unit/event.js b/test/unit/event.js index e4caee8..045ea73 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -312,7 +312,7 @@ test("bind/delegate bubbling, isDefaultPrevented", function() { // Use a native click so we don't get jQuery simulated bubbling if ( document.createEvent ) { var e = document.createEvent( 'MouseEvents' ); - e.initEvent( "click", true, true ); + e.initEvent( "click", true, true ); $jq[0].dispatchEvent(e); } else if ( $jq[0].click ) { @@ -548,7 +548,7 @@ test("bind(name, false), unbind(name, false)", function() { }); test("bind()/trigger()/unbind() on plain object", function() { - expect( 8 ); + expect( 7 ); var obj = {}; @@ -570,7 +570,6 @@ test("bind()/trigger()/unbind() on plain object", function() { var events = jQuery._data(obj, "events"); ok( events, "Object has events bound." ); equals( obj.events, undefined, "Events object on plain objects is not events" ); - equals( typeof events, "function", "'events' expando is a function on plain objects." ); equals( obj.test, undefined, "Make sure that test event is not on the plain object." ); equals( obj.handle, undefined, "Make sure that the event handler is not on the plain object." );