From: Oleg Date: Sun, 18 Nov 2012 22:03:38 +0000 (+0400) Subject: Ref #8908, gh-886. Avoid clone identity crisis in IE9/10. Close gh-1036. X-Git-Tag: 1.9.0b1~21 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=643ecf9d63018a7ef907c1e058b778b68ddaf48f;p=jquery.git Ref #8908, gh-886. Avoid clone identity crisis in IE9/10. Close gh-1036. --- diff --git a/src/css.js b/src/css.js index 8f5f0d4cf..b39b58ee6 100644 --- a/src/css.js +++ b/src/css.js @@ -211,6 +211,12 @@ jQuery.extend({ value += "px"; } + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( value === "" && name.indexOf("background") === 0 ) { + value = " "; + } + // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { @@ -543,15 +549,6 @@ jQuery.each([ "height", "width" ], function( i, name ) { }; }); -if ( !jQuery.support.clearCloneStyle ) { - // #8908, this part for IE9 only; see gh-886 - jQuery.cssHooks.backgroundPosition = { - set: function( elem, value ) { - return value === "" ? "0% 0%" : value; - } - }; -} - if ( !jQuery.support.opacity ) { jQuery.cssHooks.opacity = { get: function( elem, computed ) { diff --git a/src/manipulation.js b/src/manipulation.js index 40885e95c..ec7a0c16b 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -433,7 +433,7 @@ function cloneCopyEvent( src, dest ) { } } -function cloneFixAttributes( src, dest ) { +function fixCloneNodeIssues( src, dest ) { var nodeName, data, e; // We do not need to do anything for non-Elements @@ -559,12 +559,8 @@ jQuery.extend({ inPage = jQuery.contains( elem.ownerDocument, elem ); if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { - // Break the original-clone style connection in IE9/10 (#8909) - if ( !jQuery.support.clearCloneStyle && elem.nodeType === 1 ) { - i = ( window.getComputedStyle( elem, null ) || {} ).backgroundPosition; - } - clone = elem.cloneNode( true ); + // IE<=8 does not properly clone detached, unknown element nodes } else { fragmentDiv.innerHTML = elem.outerHTML; @@ -582,7 +578,7 @@ jQuery.extend({ for ( i = 0; (node = srcElements[i]) != null; ++i ) { // Ensure that the destination node is not null; Fixes #9587 if ( destElements[i] ) { - cloneFixAttributes( node, destElements[i] ); + fixCloneNodeIssues( node, destElements[i] ); } } } diff --git a/src/support.js b/src/support.js index 2657a182f..85b6899dc 100644 --- a/src/support.js +++ b/src/support.js @@ -169,10 +169,6 @@ jQuery.support = (function() { } } - div.style.backgroundClip = "content-box"; - div.cloneNode( true ).style.backgroundClip = ""; - support.clearCloneStyle = div.style.backgroundClip === "content-box"; - // Run tests that need a body at doc ready jQuery(function() { var container, div, tds, marginDiv, diff --git a/test/unit/css.js b/test/unit/css.js index 092be7e09..e7ada8bf9 100644 --- a/test/unit/css.js +++ b/test/unit/css.js @@ -923,4 +923,81 @@ test( "css opacity consistency across browsers (#12685)", function() { equal( Math.round( el.css("opacity") * 100 ), 20, "remove opacity override" ); }); +asyncTest( "Clearing a Cloned Element's Style Shouldn't Clear the Original Element's Style (#8908)", 16, function() { + var baseUrl = document.location.href.replace( /([^\/]*)$/, "" ), + styles = [{ + name: "backgroundAttachment", + value: ["fixed"], + expected: [ "scroll" ] + },{ + name: "backgroundColor", + value: [ "rgb(255, 0, 0)", "rgb(255,0,0)", "#ff0000" ], + expected: ["transparent"] + }, { + // Firefox returns auto's value + name: "backgroundImage", + value: [ "url('test.png')", "url(" + baseUrl + "test.png)", "url(\"" + baseUrl + "test.png\")" ], + expected: [ "none", "url(\"http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif\")" ] + }, { + name: "backgroundPosition", + value: ["5% 5%"], + expected: [ "0% 0%", "-1000px 0px", "-1000px 0%" ] + }, { + // Firefox returns no-repeat + name: "backgroundRepeat", + value: ["repeat-y"], + expected: [ "repeat", "no-repeat" ] + }, { + name: "backgroundClip", + value: ["padding-box"], + expected: ["border-box"] + }, { + name: "backgroundOrigin", + value: ["content-box"], + expected: ["padding-box"] + }, { + name: "backgroundSize", + value: ["80px 60px"], + expected: [ "auto auto" ] + }]; + + jQuery.each( styles, function(index, style) { + var $clone, $clonedChildren, + $source = jQuery( "#firstp" ), + source = $source[ 0 ], + $children = $source.children(); + + style.expected = style.expected.concat( [ "", "auto" ] ); + + if ( source.style[ style.name ] === undefined ) { + ok( true, style.name + ": style isn't supported and therefore not an issue" ); + ok( true ); + return true; + } + + $source.css( style.name, style.value[ 0 ] ); + $children.css( style.name, style.value[ 0 ] ); + + $clone = $source.clone(); + $clonedChildren = $clone.children(); + + $clone.css( style.name, "" ); + $clonedChildren.css( style.name, "" ); + + window.setTimeout(function() { + ok( jQuery.inArray( $source.css( style.name ) !== -1, style.value ), + "Clearing clone.css() doesn't affect source.css(): " + style.name + + "; result: " + $source.css( style.name ) + + "; expected: " + style.value.join( "," ) ); + + ok( jQuery.inArray( $children.css( style.name ) !== -1, style.value ), + "Clearing clonedChildren.css() doesn't affect children.css(): " + style.name + + "; result: " + $children.css( style.name ) + + "; expected: " + style.value.join( "," ) ); + }, 100 ); + }); + + window.setTimeout( start, 1000 ); +}); + } diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index af063b059..fe9f6c203 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -2127,73 +2127,6 @@ test( "checked state is cloned with clone()", function() { equal( jQuery(elem).clone().attr("id","clone")[ 0 ].checked, true, "Checked true state correctly cloned" ); }); -test( "Clearing a Cloned Element's Style Shouldn't Clear the Original Element's Style (#8908)", function() { - - expect( 16 ); - - var baseUrl = document.location.href.replace( /([^\/]*)$/, "" ), - styles = [{ - name: "backgroundAttachment", - value: ["fixed"], - expected: [ "scroll" ] - },{ - name: "backgroundColor", - value: [ "rgb(255, 0, 0)", "rgb(255,0,0)", "#ff0000" ], - expected: ["transparent"] - }, { - // Firefox returns auto's value - name: "backgroundImage", - value: [ "url('test.png')", "url(" + baseUrl + "test.png)", "url(\"" + baseUrl + "test.png\")" ], - expected: [ "none", "url(\"http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif\")" ] - }, { - name: "backgroundPosition", - value: ["5% 5%"], - expected: [ "0% 0%", "-1000px 0px", "-1000px 0%" ] - }, { - // Firefox returns no-repeat - name: "backgroundRepeat", - value: ["repeat-y"], - expected: [ "repeat", "no-repeat" ] - }, { - name: "backgroundClip", - value: ["padding-box"], - expected: ["border-box"] - }, { - name: "backgroundOrigin", - value: ["content-box"], - expected: ["padding-box"] - }, { - name: "backgroundSize", - value: ["80px 60px"], - expected: [ "auto auto" ] - }]; - - jQuery.each( styles, function( index, style ) { - var $source, source, $clone; - - style.expected = style.expected.concat([ "", "auto" ]); - $source = jQuery( "
" ); - source = $source[ 0 ]; - if ( source.style[ style.name ] === undefined ) { - ok( true, style.name + ": style isn't supported and therefore not an issue" ); - ok( true ); - return true; - } - $source.css( style.name, style.value[ 0 ] ); - $clone = $source.clone(); - $clone.css( style.name, "" ); - - ok( ~jQuery.inArray( $source.css( style.name ), style.value ), - "Clearing clone.css() doesn't affect source.css(): " + style.name + - "; result: " + $source.css( style.name ) + - "; expected: " + style.value.join(",") ); - ok( ~jQuery.inArray( $clone.css( style.name ), style.expected ), - "Cloned element was reset to its default value: " + style.name + - "; result: " + $clone.css( style.name ) + - "; expected: " + style.expected.join(",") ); - }); -}); - test( "manipulate mixed jQuery and text (#12384, #12346)", function() { expect( 2 );