]> source.dussan.org Git - jquery.git/commitdiff
Data: use removeAttribute in cleanData to bypass Chrome bug
authorJason Bedard <jason+github@jbedard.ca>
Wed, 10 Dec 2014 16:42:00 +0000 (11:42 -0500)
committerTimmy Willison <timmywillisn@gmail.com>
Wed, 10 Dec 2014 16:47:54 +0000 (11:47 -0500)
Related:
https://code.google.com/p/chromium/issues/detail?id=378607

Fixes gh-1664

src/data.js
src/data/support.js
src/manipulation.js
src/manipulation/support.js
test/unit/data.js
test/unit/support.js

index e8f269b01451ae0399769c53c964a4e172d06416..da2b01b5db7d676ae05ebd03476c604506501aee 100644 (file)
@@ -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;
        }
 }
 
index 014e973c8b0e940930375bb33a455ea4fac81909..9e0ba14bc095f8606bad29e392afe0912b8ca9cc 100644 (file)
@@ -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.
index 003d05fe07ee3faade9bc12a1055080d5571f95f..9276355cec94a0467c9e55ce9f9a2345fc4d83c5 100644 (file)
@@ -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 );
index 27e0fb1de712237010d46034f7687cf7ae1bb0fa..9bfceabe22f53bc12cca01a408a471041ac3c2b4 100644 (file)
@@ -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;
index cd3de7af0d5f4a4bad0d544209f5d0a780aa8a7d..a3b5384fde1bee0de4e69f18cdbc7fa2e0d307c5 100644 (file)
@@ -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");
index a214ccd9a21bee7605df8a297bccd40f554473f2..e095660062f49efa6e7b0b4ce769abcba93b2982 100644 (file)
@@ -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,