]> source.dussan.org Git - jquery.git/commitdiff
Fix #8908. Don't let change to originals affect clones in IE9/10. Close gh-886.
authorElijah Manor <elijah.manor@gmail.com>
Fri, 16 Nov 2012 03:20:07 +0000 (22:20 -0500)
committerDave Methvin <dave.methvin@gmail.com>
Sun, 18 Nov 2012 19:49:36 +0000 (14:49 -0500)
1  2 
src/css.js
src/manipulation.js
src/support.js
test/unit/manipulation.js

diff --cc src/css.js
index 1723223e53415edda79b7e6245eda551789fea02,72ee8eef9f3e31b0385b5641a43ee373fee8d10c..eb0aed63961ede8b8f58f77e7ec4f91f0e93bab2
@@@ -198,6 -204,9 +198,7 @@@ jQuery.extend(
  
                        // 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 ) {
 -                              // IE9/10 Clearing Cloned Style Clear's Original Style. Fixes bug #8908
 -                              value = !jQuery.support.clearCloneStyle && value === "" && name.match( /backgroundPosition/ ) ? "0% 0%" : value;
                                // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
                                // Fixes bug #5509
                                try {
@@@ -515,6 -517,6 +516,15 @@@ jQuery.each([ "height", "width" ], func
        };
  });
  
++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 ) {
index b6dd6f086285ef5e3fe66d8e3f39ebcf7f63d439,5057e39f7650eb3c6c484ac00f2021a1dc0a4c43..473fa5c82b6410f35c1fa2362e6d24aeae3e821a
@@@ -596,8 -588,13 +596,12 @@@ jQuery.extend(
                        clone;
  
                if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) {
-                       clone = elem.cloneNode( true );
 -                      // Fixes #8909 - By accessing one of the element's computed styles it breaks the
 -                      // connection with the cloned element's styles in IE9/10
 -                      if ( !jQuery.support.clearCloneStyle && elem.nodeType === 1 && window.getComputedStyle ) {
++                      // 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;
diff --cc src/support.js
index 7629c38e7fd4654e2d6d4a44ff5b7ad439628a89,9cc46c63ee0f3a315030e362bb51039b3488f26b..1001f407a73558460ab6f4aa01fd30b7ffdd5e14
@@@ -169,6 -170,19 +169,10 @@@ jQuery.support = (function() 
                }
        }
  
 -      support.clearCloneStyle = (function() {
 -              var source = document.createElement( "div" ),
 -                      styleName = "backgroundClip",
 -                      value = "content-box",
 -                      clone;
 -
 -              source.style[ styleName ] = value;
 -              clone = source.cloneNode( true );
 -              clone.style[ styleName ] = "";
 -
 -              return source.style[ styleName ] === value;
 -      })();
++      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,
index 6c37e51962a45b0808137e0c04d67de87745a1e8,764da0349a032f0170358408aee8e52cdf4e7d2d..19897af749097c1695bb537e18702c5a1fd088cd
@@@ -2023,22 -1908,43 +2023,63 @@@ test("checked state is cloned with clon
        equal( jQuery(elem).clone().attr("id","clone")[0].checked, true, "Checked true state correctly cloned" );
  });
  
 -              { 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")' ] }, // Firefox returns auto's value
+ 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( /([^\/]*)$/, "" );
+       var styles = [
+               { name: "backgroundAttachment", value: [ "fixed" ], expected: [ "scroll" ] },
+               { name: "backgroundColor", value: [ "rgb(255, 0, 0)", "rgb(255,0,0)", "#ff0000" ], expected: [ "transparent" ] },
 -                      "Clearning clone.css() doesn't affect source.css(): " + style.name +
++              { 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\")" ] }, // Firefox returns auto's value
+               { name: "backgroundPosition", value: [ "5% 5%" ], expected: [ "0% 0%", "-1000px 0px", "-1000px 0%" ] },
+               { name: "backgroundRepeat", value: [ "repeat-y" ], expected: [ "repeat", "no-repeat" ] }, // Firefox returns 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( "<div />" );
+               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 ),
 -                      "The cloned element was reset to it's default value: " + style.name +
++                      "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);
 +
 +      var div = jQuery("<div>a</div>").append( "&nbsp;", jQuery("<span>b</span>"), "&nbsp;", jQuery("<span>c</span>") ),
 +              nbsp = String.fromCharCode(160);
 +      equal( div.text(), "a" + nbsp + "b" + nbsp+ "c", "Appending mixed jQuery with text nodes" );
 +
 +      div = jQuery("<div><div></div></div>")
 +              .find("div")
 +              .after("<p>a</p>", "<p>b</p>" )
 +              .parent();
 +      equal( div.find("*").length, 3, "added 2 paragraphs after inner div" );
 +});
 +
 +testIframeWithCallback( "buildFragment works even if document[0] is iframe's window object in IE9/10 (#12266)", "manipulation/iframe-denied.html", function( test ) {
 +      expect( 1 );
 +
 +      ok( test.status, test.description );
 +});