From 56bb677725b21415905e5c3eeb1e05be4480e780 Mon Sep 17 00:00:00 2001 From: Timmy Willison Date: Wed, 6 May 2015 15:29:06 -0700 Subject: [PATCH] Data: remove the expando when there's no more data Fixes gh-1760 Close gh-2271 --- src/data/Data.js | 10 ++++++---- src/event.js | 9 ++------- test/unit/data.js | 21 +++++++++++++++++++-- test/unit/event.js | 21 +++++++++++++++++++++ 4 files changed, 48 insertions(+), 13 deletions(-) diff --git a/src/data/Data.js b/src/data/Data.js index d56e37839..5268f3f2c 100644 --- a/src/data/Data.js +++ b/src/data/Data.js @@ -120,10 +120,7 @@ Data.prototype = { return; } - if ( key === undefined ) { - this.register( owner ); - - } else { + if ( key !== undefined ) { // Support array or space separated string of keys if ( jQuery.isArray( key ) ) { @@ -147,6 +144,11 @@ Data.prototype = { delete cache[ key[ i ] ]; } } + + // Remove the expando if there's no more data + if ( key === undefined || jQuery.isEmptyObject( cache ) ) { + delete owner[ this.expando ]; + } }, hasData: function( owner ) { var cache = owner[ this.expando ]; diff --git a/src/event.js b/src/event.js index b371b9a27..584ba9073 100644 --- a/src/event.js +++ b/src/event.js @@ -216,14 +216,9 @@ jQuery.event = { } } - // Remove the expando if it's no longer used + // Remove data and the expando if it's no longer used if ( jQuery.isEmptyObject( events ) ) { - // Normally this should go through the data api - // but since event.js owns these properties, - // this exception is made for the sake of optimizing - // the operation. - delete elemData.handle; - delete elemData.events; + dataPriv.remove( elem, "handle events" ); } }, diff --git a/test/unit/data.js b/test/unit/data.js index c08550b1b..20e5af828 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -837,7 +837,24 @@ test("Check proper data removal of non-element descendants nodes (#8335)", 1, fu }); testIframeWithCallback( "enumerate data attrs on body (#14894)", "data/dataAttrs.html", function( result ) { - expect(1); + expect( 1 ); + + equal( result, "ok", "enumeration of data- attrs on body" ); +}); + +test( "Check that the expando is removed when there's no more data", function() { + expect( 1 ); - equal(result, "ok", "enumeration of data- attrs on body" ); + var key, + div = jQuery( "
" ); + div.data( "some", "data" ); + equal( div.data( "some" ), "data", "Data is added" ); + div.removeData( "some" ); + + // Make sure the expando is gone + for ( key in div[ 0 ] ) { + if ( /^jQuery/.test( key ) ) { + ok( false, "Expando was not removed when there was no more data" ); + } + } }); diff --git a/test/unit/event.js b/test/unit/event.js index 95f6f4b33..d9bdafc34 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -2657,6 +2657,27 @@ test( "Inline event result is returned (#13993)", function() { equal( result, 42, "inline handler returned value" ); }); +test( ".off() removes the expando when there's no more data", function() { + expect( 1 ); + + var key, + div = jQuery( "
" ).appendTo( "#qunit-fixture" ); + + div.on( "click", false ); + div.on( "custom", function() { + ok( true, "Custom event triggered" ); + } ); + div.trigger( "custom" ); + div.off( "click custom" ); + + // Make sure the expando is gone + for ( key in div[ 0 ] ) { + if ( /^jQuery/.test( key ) ) { + ok( false, "Expando was not removed when there was no more data" ); + } + } +}); + // This tests are unreliable in Firefox if ( !(/firefox/i.test( window.navigator.userAgent )) ) { test( "Check order of focusin/focusout events", 2, function() { -- 2.39.5