Skip to content

Commit 0e98243

Browse files
jbedardmgol
authored andcommitted
Data: avoid using delete on DOM nodes
Closes gh-2479
1 parent d4def22 commit 0e98243

File tree

5 files changed

+46
-12
lines changed

5 files changed

+46
-12
lines changed

src/data/Data.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,12 @@ Data.prototype = {
2020
if ( owner.nodeType ) {
2121
owner[ this.expando ] = value;
2222

23-
// Otherwise secure it in a non-enumerable, non-writable property
24-
// configurability must be true to allow the property to be
25-
// deleted with the delete operator
23+
// Otherwise secure it in a non-enumerable property
24+
// configurable must be true to allow the property to be
25+
// deleted when data is removed
2626
} else {
2727
Object.defineProperty( owner, this.expando, {
2828
value: value,
29-
writable: true,
3029
configurable: true
3130
} );
3231
}
@@ -144,7 +143,16 @@ Data.prototype = {
144143

145144
// Remove the expando if there's no more data
146145
if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
147-
delete owner[ this.expando ];
146+
147+
// Support: Chrome <= 35-45+
148+
// Webkit & Blink performance suffers when deleting properties
149+
// from DOM nodes, so set to undefined instead
150+
// https://code.google.com/p/chromium/issues/detail?id=378607
151+
if ( owner.nodeType ) {
152+
owner[ this.expando ] = undefined;
153+
} else {
154+
delete owner[ this.expando ];
155+
}
148156
}
149157
},
150158
hasData: function( owner ) {

src/manipulation.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,16 @@ jQuery.extend( {
290290
}
291291
}
292292
}
293-
delete elem[ dataPriv.expando ];
293+
294+
// Support: Chrome <= 35-45+
295+
// Assign undefined instead of using delete, see Data#remove
296+
elem[ dataPriv.expando ] = undefined;
294297
}
295298
if ( elem[ dataUser.expando ] ) {
296-
delete elem[ dataUser.expando ];
299+
300+
// Support: Chrome <= 35-45+
301+
// Assign undefined instead of using delete, see Data#remove
302+
elem[ dataUser.expando ] = undefined;
297303
}
298304
}
299305
}

test/unit/data.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ testIframeWithCallback(
867867
);
868868

869869
QUnit.test( "Check that the expando is removed when there's no more data", function( assert ) {
870-
assert.expect( 1 );
870+
assert.expect( 2 );
871871

872872
var key,
873873
div = jQuery( "<div/>" );
@@ -877,6 +877,23 @@ QUnit.test( "Check that the expando is removed when there's no more data", funct
877877

878878
// Make sure the expando is gone
879879
for ( key in div[ 0 ] ) {
880+
if ( /^jQuery/.test( key ) ) {
881+
assert.strictEqual( div[ 0 ][ key ], undefined, "Expando was not removed when there was no more data" );
882+
}
883+
}
884+
});
885+
886+
QUnit.test( "Check that the expando is removed when there's no more data on non-nodes", function( assert ) {
887+
assert.expect( 1 );
888+
889+
var key,
890+
obj = jQuery( {key: 42} );
891+
obj.data( "some", "data" );
892+
assert.equal( obj.data( "some" ), "data", "Data is added" );
893+
obj.removeData( "some" );
894+
895+
// Make sure the expando is gone
896+
for ( key in obj[ 0 ] ) {
880897
if ( /^jQuery/.test( key ) ) {
881898
assert.ok( false, "Expando was not removed when there was no more data" );
882899
}

test/unit/event.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2702,7 +2702,7 @@ QUnit.test( "Inline event result is returned (#13993)", function( assert ) {
27022702
} );
27032703

27042704
QUnit.test( ".off() removes the expando when there's no more data", function( assert ) {
2705-
assert.expect( 1 );
2705+
assert.expect( 2 );
27062706

27072707
var key,
27082708
div = jQuery( "<div/>" ).appendTo( "#qunit-fixture" );
@@ -2717,7 +2717,10 @@ QUnit.test( ".off() removes the expando when there's no more data", function( as
27172717
// Make sure the expando is gone
27182718
for ( key in div[ 0 ] ) {
27192719
if ( /^jQuery/.test( key ) ) {
2720-
assert.ok( false, "Expando was not removed when there was no more data" );
2720+
assert.strictEqual(
2721+
div[ 0 ][ key ], undefined,
2722+
"Expando was not removed when there was no more data"
2723+
);
27212724
}
27222725
}
27232726
} );

test/unit/manipulation.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2086,7 +2086,7 @@ QUnit.test( "jQuery.cleanData eliminates all private data (gh-2127)", function(
20862086
} );
20872087

20882088
QUnit.test( "jQuery.cleanData eliminates all public data", function( assert ) {
2089-
assert.expect( 2 );
2089+
assert.expect( 3 );
20902090

20912091
var key,
20922092
div = jQuery( "<div/>" );
@@ -2100,7 +2100,7 @@ QUnit.test( "jQuery.cleanData eliminates all public data", function( assert ) {
21002100
// Make sure the expando is gone
21012101
for ( key in div[ 0 ] ) {
21022102
if ( /^jQuery/.test( key ) ) {
2103-
assert.ok( false, "Expando was not removed when there was no more data" );
2103+
assert.strictEqual( div[ 0 ][ key ], undefined, "Expando was not removed when there was no more data" );
21042104
}
21052105
}
21062106
} );

0 commit comments

Comments
 (0)