From: Jason Bedard Date: Wed, 10 Dec 2014 16:42:00 +0000 (-0500) Subject: Data: use removeAttribute in cleanData to bypass Chrome bug X-Git-Tag: 3.0.0-alpha1+compat~177 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=9d1d90e7a274cae7f5f587bd28613044ea24264f;p=jquery.git Data: use removeAttribute in cleanData to bypass Chrome bug Related: https://code.google.com/p/chromium/issues/detail?id=378607 Fixes gh-1664 --- diff --git a/src/data.js b/src/data.js index e8f269b01..da2b01b5d 100644 --- a/src/data.js +++ b/src/data.js @@ -230,9 +230,9 @@ function internalRemoveData( elem, name, pvt ) { /* jshint eqeqeq: true */ delete cache[ id ]; - // When all else fails, null + // When all else fails, undefined } else { - cache[ id ] = null; + cache[ id ] = undefined; } } diff --git a/src/data/support.js b/src/data/support.js index 014e973c8..9e0ba14bc 100644 --- a/src/data/support.js +++ b/src/data/support.js @@ -5,15 +5,12 @@ define([ (function() { var div = document.createElement( "div" ); - // Execute the test only if not already executed in another module. - if (support.deleteExpando == null) { - // Support: IE<9 - support.deleteExpando = true; - try { - delete div.test; - } catch ( e ) { - support.deleteExpando = false; - } + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch ( e ) { + support.deleteExpando = false; } // Null elements to avoid leaks in IE. diff --git a/src/manipulation.js b/src/manipulation.js index 003d05fe0..9276355ce 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -367,7 +367,7 @@ jQuery.extend({ i = 0, internalKey = jQuery.expando, cache = jQuery.cache, - deleteExpando = support.deleteExpando, + attributes = support.attributes, special = jQuery.event.special; for ( ; (elem = elems[i]) != null; i++ ) { @@ -394,17 +394,18 @@ jQuery.extend({ delete cache[ id ]; - // IE does not allow us to delete expando properties from nodes, - // nor does it have a removeAttribute function on Document nodes; - // we must handle all of these cases - if ( deleteExpando ) { - delete elem[ internalKey ]; - - } else if ( typeof elem.removeAttribute !== "undefined" ) { + // Support: IE<9 + // IE does not allow us to delete expando properties from nodes + // IE creates expando attributes along with the property + // IE does not have a removeAttribute function on Document nodes + if ( !attributes && typeof elem.removeAttribute !== "undefined" ) { elem.removeAttribute( internalKey ); + // Webkit & Blink performance suffers when deleting properties + // from DOM nodes, so set to undefined instead + // https://code.google.com/p/chromium/issues/detail?id=378607 } else { - elem[ internalKey ] = null; + elem[ internalKey ] = undefined; } deletedIds.push( id ); diff --git a/src/manipulation/support.js b/src/manipulation/support.js index 27e0fb1de..9bfceabe2 100644 --- a/src/manipulation/support.js +++ b/src/manipulation/support.js @@ -1,6 +1,7 @@ define([ + "../core", "../var/support" -], function( support ) { +], function( jQuery, support ) { (function() { var div = document.createElement( "div" ), @@ -38,16 +39,11 @@ define([ // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+ support.noCloneEvent = !!div.addEventListener; - // Execute the test only if not already executed in another module. - if (support.deleteExpando == null) { - // Support: IE<9 - support.deleteExpando = true; - try { - delete div.test; - } catch ( e ) { - support.deleteExpando = false; - } - } + // Support: IE<9 + // Since attributes and properties are the same in IE, + // cleanData must set properties to undefined rather than use removeAttribute + div[ jQuery.expando ] = 1; + support.attributes = !div.getAttribute( jQuery.expando ); })(); return support; diff --git a/test/unit/data.js b/test/unit/data.js index cd3de7af0..a3b5384fd 100644 --- a/test/unit/data.js +++ b/test/unit/data.js @@ -100,18 +100,10 @@ test("jQuery.data(document)", 25, function() { }); test("Expando cleanup", 4, function() { - var expected, actual, - div = document.createElement("div"); + var div = document.createElement("div"); function assertExpandoAbsent(message) { - if (jQuery.support.deleteExpando) { - expected = false; - actual = jQuery.expando in div; - } else { - expected = null; - actual = div[ jQuery.expando ]; - } - equal( actual, expected, message ); + strictEqual( div[ jQuery.expando ], undefined, message ); } assertExpandoAbsent("There is no expando on new elements"); diff --git a/test/unit/support.js b/test/unit/support.js index a214ccd9a..e09566006 100644 --- a/test/unit/support.js +++ b/test/unit/support.js @@ -73,6 +73,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec // Android browser on Android >= 4.4). expected = { "ajax": true, + "attributes": true, "boxSizingReliable": true, "changeBubbles": true, "checkClone": true, @@ -103,6 +104,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec } else if ( /(msie 10\.0|trident\/7\.0)/i.test( userAgent ) ) { expected = { "ajax": true, + "attributes": true, "boxSizingReliable": false, "changeBubbles": true, "checkClone": true, @@ -133,6 +135,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec } else if ( /msie 9\.0/i.test( userAgent ) ) { expected = { "ajax": true, + "attributes": true, "boxSizingReliable": false, "changeBubbles": true, "checkClone": true, @@ -163,6 +166,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec } else if ( /msie 8\.0/i.test( userAgent ) ) { expected = { "ajax": true, + "attributes": false, "boxSizingReliable": false, "changeBubbles": false, "checkClone": true, @@ -193,6 +197,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec } else if ( /(6|7)\.0(\.\d+|) safari/i.test( userAgent ) ) { expected = { "ajax": true, + "attributes": true, "boxSizingReliable": true, "changeBubbles": true, "checkClone": true, @@ -223,6 +228,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec } else if ( /8.0(\.\d+|) safari/i.test( userAgent ) ) { expected = { "ajax": true, + "attributes": true, "boxSizingReliable": true, "changeBubbles": true, "checkClone": true, @@ -253,6 +259,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec } else if ( /firefox/i.test( userAgent ) ) { expected = { "ajax": true, + "attributes": true, "boxSizingReliable": true, "changeBubbles": true, "checkClone": true, @@ -283,6 +290,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec } else if ( /iphone os/i.test( userAgent ) ) { expected = { "ajax": true, + "attributes": true, "boxSizingReliable": true, "changeBubbles": true, "checkClone": true, @@ -313,6 +321,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec } else if ( /android 4\.[0-3]/i.test( userAgent ) ) { expected = { "ajax": true, + "attributes": true, "boxSizingReliable": true, "changeBubbles": true, "checkClone": false, @@ -343,6 +352,7 @@ testIframeWithCallback( "Check CSP (https://developer.mozilla.org/en-US/docs/Sec } else if ( /android 2\.3/i.test( userAgent ) ) { expected = { "ajax": true, + "attributes": true, "boxSizingReliable": true, "changeBubbles": true, "checkClone": true,