From 039222f8bf4591807e5d25e2a2308a79f87e656d Mon Sep 17 00:00:00 2001 From: Elijah Manor Date: Mon, 23 Jul 2012 12:23:20 -0500 Subject: Fix IE10 bug when cloning an object element without a parentNode --- src/manipulation.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/manipulation.js b/src/manipulation.js index d118529d4..b755b2f1c 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -440,7 +440,13 @@ function cloneFixAttributes( src, dest ) { // the proprietary classid attribute value (rather than the type // attribute) to identify the type of content to display if ( nodeName === "object" ) { - dest.outerHTML = src.outerHTML; + // The official HTML5 specs read that a NO_MODIFICATION_ALLOWED_ERR + // needs to be thrown if the parent is a Document + // http://html5.org/specs/dom-parsing.html#dom-element-outerhtml + // IE10 throws NoModificationAllowedError if parent node is null + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } // This path appears unavoidable for IE9. When cloning an object // element in IE9, the outerHTML strategy above is not sufficient. -- cgit v1.2.3 From d5d8622329e379e449b54ab8805f043d1e6ec02a Mon Sep 17 00:00:00 2001 From: Elijah Manor Date: Wed, 8 Aug 2012 15:31:59 -0500 Subject: Fix weird clone bug and add a unit test to verify --- src/manipulation.js | 10 ++++++++-- test/unit/manipulation.js | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/manipulation.js b/src/manipulation.js index 3cfc97c3b..457975a59 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -585,11 +585,17 @@ jQuery.extend({ var srcElements, destElements, i, - clone; + clone, + fix8908; if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { - clone = elem.cloneNode( true ); + // Fixes #8909 - By accessing one of the cloned element's computed styles it breaks the + // connection with the source element's styles in IE9/10 + if ( elem.nodeType === 1 && window.getComputedStyle ) { + fix8908 = ( window.getComputedStyle( elem, null ) || {} ).backgroundImage; + } + clone = elem.cloneNode( true ); // IE<=8 does not properly clone detached, unknown element nodes } else { fragmentDiv.innerHTML = elem.outerHTML; diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 4038f1a74..60a0830c7 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -1907,3 +1907,39 @@ test("checked state is cloned with clone()", function(){ elem.checked = true; 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( 8 ); + + var baseUrl = document.location.href.replace( /([^\/]*)$/, "" ); + var styles = [ + { name: "background-attachment", value: [ "fixed" ], expected: [ "scroll" ] }, + { name: "background-color", value: [ "rgb(255, 0, 0)", "rgb(255,0,0)" ], expected: [ "transparent" ] }, + { name: "background-image", value: [ 'url("test.png")', 'url(' + baseUrl + 'test.png)', 'url("' + baseUrl + 'test.png")' ], expected: [ "none" ] }, + { name: "background-position", value: [ "5% 5%" ], expected: [ "0% 0%" ] }, + { name: "background-repeat", value: [ "repeat-y" ], expected: [ "repeat" ] }, + { name: "background-clip", value: [ "content-box" ], expected: [ "border-box" ] }, + { name: "background-origin", value: [ "content-box" ], expected: [ "padding-box" ] }, + { name: "background-size", value: [ "80px 60px" ], expected: [] } + ]; + + 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" ); + 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 ), + "Clearning clone.css() doesn't affect source.css(): " + style.name + + "; result: " + $source.css( style.name ) + + "; expected: " + style.value.join( "," ) ); + }); +}); \ No newline at end of file -- cgit v1.2.3 From f952b97997e529f872859e5cfd43070fc533f3b0 Mon Sep 17 00:00:00 2001 From: Elijah Manor Date: Wed, 8 Aug 2012 15:36:20 -0500 Subject: Updated the comment above the fix --- src/manipulation.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/manipulation.js b/src/manipulation.js index 457975a59..22dfc9171 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -589,8 +589,8 @@ jQuery.extend({ fix8908; if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { - // Fixes #8909 - By accessing one of the cloned element's computed styles it breaks the - // connection with the source element's styles in IE9/10 + // 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 ( elem.nodeType === 1 && window.getComputedStyle ) { fix8908 = ( window.getComputedStyle( elem, null ) || {} ).backgroundImage; } -- cgit v1.2.3 From f29633536076e831e25705b560c983674ed839ee Mon Sep 17 00:00:00 2001 From: Elijah Manor Date: Mon, 13 Aug 2012 07:46:55 -0500 Subject: Add support check, added assertion to check if cleared, add edge case for backgroundPosition --- grep | 0 src/css.js | 3 + src/manipulation.js | 7 +- src/support.js | 13 ++ test/unit/clone.html | 295 ++++++++++++++++++++++++++ test/unit/clone.js | 523 ++++++++++++++++++++++++++++++++++++++++++++++ test/unit/manipulation.js | 23 +- 7 files changed, 851 insertions(+), 13 deletions(-) create mode 100644 grep create mode 100644 test/unit/clone.html create mode 100644 test/unit/clone.js (limited to 'src') diff --git a/grep b/grep new file mode 100644 index 000000000..e69de29bb diff --git a/src/css.js b/src/css.js index dcba720e5..72ee8eef9 100644 --- a/src/css.js +++ b/src/css.js @@ -204,6 +204,9 @@ 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 { diff --git a/src/manipulation.js b/src/manipulation.js index 22dfc9171..5057e39f7 100644 --- a/src/manipulation.js +++ b/src/manipulation.js @@ -585,14 +585,13 @@ jQuery.extend({ var srcElements, destElements, i, - clone, - fix8908; + clone; if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { // 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 ( elem.nodeType === 1 && window.getComputedStyle ) { - fix8908 = ( window.getComputedStyle( elem, null ) || {} ).backgroundImage; + if ( !jQuery.support.clearCloneStyle && elem.nodeType === 1 && window.getComputedStyle ) { + i = ( window.getComputedStyle( elem, null ) || {} ).backgroundPosition; } clone = elem.cloneNode( true ); diff --git a/src/support.js b/src/support.js index e4a8b7c83..9cc46c63e 100644 --- a/src/support.js +++ b/src/support.js @@ -170,6 +170,19 @@ 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; + })(); + // Run tests that need a body at doc ready jQuery(function() { var container, div, tds, marginDiv, diff --git a/test/unit/clone.html b/test/unit/clone.html new file mode 100644 index 000000000..2f3c453b3 --- /dev/null +++ b/test/unit/clone.html @@ -0,0 +1,295 @@ + + + + + + jQuery Test Suite + + + + + + + + + + + + + + + + + + +

jQuery Test Suite

+

+
+

+
    + + +
    +
    +
    + + + +
    +
    +

    See this blog entry for more information.

    +

    + Here are some links in a normal paragraph: Google, + Google Groups (Link). + This link has class="blog": + diveintomark + +

    +
    +

    Everything inside the red border is inside a div with id="foo".

    +

    This is a normal link: Yahoo

    +

    This link has class="blog": Simon Willison's Weblog

    + +
    + +

    Try them out:

    +
      +
        +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + test element +
        + Float test. + +
        + + +
        +
        + +
        + + + + +
        + +
        + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
        +
        +
        + +
        +
        hi there
        +
        +
        +
        +
        +
        +
        +
        +
        + +
        +
          +
        1. Rice
        2. +
        3. Beans
        4. +
        5. Blinis
        6. +
        7. Tofu
        8. +
        + +
        I'm hungry. I should...
        + ...Eat lots of food... | + ...Eat a little food... | + ...Eat no food... + ...Eat a burger... + ...Eat some funyuns... + ...Eat some funyuns... +
        + +
        + + +
        + +
        + 1 + 2 + + + + + + + + +
        +
        +
        +
        +
        +
        fadeIn
        fadeIn
        +
        fadeOut
        fadeOut
        + +
        show
        show
        +
        hide
        hide
        + +
        togglein
        togglein
        +
        toggleout
        toggleout
        + + +
        slideUp
        slideUp
        +
        slideDown
        slideDown
        + +
        slideToggleIn
        slideToggleIn
        +
        slideToggleOut
        slideToggleOut
        + +
        fadeToggleIn
        fadeToggleIn
        +
        fadeToggleOut
        fadeToggleOut
        + +
        fadeTo
        fadeTo
        +
        + +
        +
        + + + + + + diff --git a/test/unit/clone.js b/test/unit/clone.js new file mode 100644 index 000000000..3ff183dfc --- /dev/null +++ b/test/unit/clone.js @@ -0,0 +1,523 @@ +/*global module:false, window:false, moduleTeardown:false, console:false, test:false, equal:false, $:false, ok:false, alert:false, jQuery:false, document:false*/ +/*jshint laxcomma:true */ + +(function( $ ) { +"use strict"; + +var _console, $console; + +module( "clone", { + setup: function() { + $console = $( "#console" ); + $console.val( "" ); + _console = window.console || {}; + window.console = { + log: function( message ) { + if ( _console.log ) { + // _console.log.apply( _console, arguments ); + } + $console.val(function(index, value) { + return value + ( value ? "\n" : "" ) + message; + }); + } + }; + }, + teardown: function() { + window.console = _console; + moduleTeardown(); + } +}); + +test( "Clearing Clone's Property Doesn't Clear Original Element's Property", function() { + // Define styles from http://www.w3.org/TR/CSS/#indices + // Array.prototype.forEach.call( document.querySelectorAll( "tr" ), function( row ) { var imgs = row.querySelectorAll( "img" ); if ( imgs[2] && imgs[2].attributes.alt.value === "no" && imgs[3] && imgs[3].attributes.alt.value === "yes" ) { console.log( "skipping" ); } else { row.style.display = "none"; } } ); + var baseUrl = document.location.href.replace( /([^\/]*)$/, "" ), count = 0; + var styles = [ + { name: "background-attachment", value: ["fixed"], expected: ["scroll"] }, + { name: "background-color", value: ["rgb(255, 0, 0)", "rgb(255,0,0)"], expected: ["transparent"] }, + { + name: "background-image", + value: [ + 'url("test.png")', + 'url(' + baseUrl + 'test.png)', + 'url("' + baseUrl + 'test.png")' + ], + expected: ["none"] + }, + { name: "background-position", value: ["5% 5%"], expected: ["0% 0%"] }, + { name: "background-repeat", value: ["repeat-y"], expected: ["repeat"] }, + { + name: "background", + value: [ + "rgb(255, 0, 0) 50% 50%", + "50% 50% rgb(255, 0, 0)", + "rgb(255,0,0) 50% 50%", + "none repeat scroll 50% 50% rgb(255, 0, 0)" + ], + expected: ["none", "none transparent scroll repeat 0% 0%"] + }, + { name: "border-collapse", value: ["collapse"], expected: ["separate"] }, + { name: "border-color", value: ["rgb(255, 0, 0)", "rgb(255,0,0)"], expected: ["none", "#000000"] }, + // BEGIN + { name: "border-spacing", value: ["5px 5px", "5px"], expected: ["0px 0px"] }, + // END + { name: "border-style", value: ["dashed"], expected: ["none"] }, + { + name: "border-top", + value: ["thick double rgb(255, 0, 0)", "rgb(255,0,0) thick double"], + expected: ["none", "medium none"] + }, + { + name: "border-right", + value: ["thick double rgb(255, 0, 0)", "rgb(255,0,0) thick double"], + expected: ["none", "medium none"] + }, + { + name: "border-bottom", + value: ["thick double rgb(255, 0, 0)", "rgb(255,0,0) thick double"], + expected: ["none", "medium none"] + }, + { + name: "border-left", + value: ["thick double rgb(255, 0, 0)", "rgb(255,0,0) thick double"], + expected: ["none", "medium none"] + }, + { name: "border-top-color", value: ["rgb(255, 0, 0)", "rgb(255,0,0)"], expected: ["rgb(0, 0, 0)", "#000000"] }, + { name: "border-right-color", value: ["rgb(255, 0, 0)", "rgb(255,0,0)"], expected: ["rgb(0, 0, 0)", "#000000"] }, + { name: "border-bottom-color", value: ["rgb(255, 0, 0)", "rgb(255,0,0)"], expected: ["rgb(0, 0, 0)", "#000000"] }, + { name: "border-left-color", value: ["rgb(255, 0, 0)", "rgb(255,0,0)"], expected: ["rgb(0, 0, 0)", "#000000"] }, + { name: "border-top-style", value: ["dotted"], expected: ["none"] }, + { name: "border-right-style", value: ["dotted"], expected: ["none"] }, + { name: "border-bottom-style", value: ["dotted"], expected: ["none"] }, + { name: "border-left-style", value: ["dotted"], expected: ["none"] }, + // BEGIN - IE10 doesn't seem to apply these correctly getComputedStyle shows as 0px for thick + // { name: "border-top-width", value: ["thick"], expected: ["medium"] }, + // { name: "border-right-width", value: ["thick"], expected: ["medium"] }, + // { name: "border-bottom-width", value: ["thick"], expected: ["medium"] }, + // { name: "border-left-width", value: ["thick"], expected: ["medium"] }, + // END + { name: "border-width", value: ["5px"], expected: ["0px", "medium"] }, + { name: "border", value: ["5px solid rgb(255, 0, 0)", "rgb(255,0,0) 5px solid"], expected: ["none", undefined, "undefined"] }, + { name: "bottom", value: ["5px"], expected: [] }, + { name: "caption-side", value: ["bottom"], expected: ["top"] }, + { name: "clear", value: ["right"], expected: ["none"] }, + { + name: "clip", + value: [ + "rect(110px 160px 170px 60px)", + "rect(110px, 160px, 170px, 60px)", + "rect(110px,160px,170px,60px)" + ], + expected: [ + "rect(auto,auto,auto,auto)", + "rect(auto auto auto auto)", + "rect(0px, 0px, 0px, 0px)" + ] + }, + { name: "color", value: ["rgb(255, 0, 0)", "rgb(255,0,0)"], expected: ["rgb(0, 0, 0)", "#000000"] }, + // { name: "content", value: ["test"], expected: ["normal", "none"] }, // Content isn't found in DOM + { name: "counter-increment", value: ["section", "section 1"], expected: ["none"] }, + { name: "counter-reset", value: ["section", "section 0"], expected: ["none"] }, + { name: "cursor", value: ["crosshair"], expected: [] }, + { name: "direction", value: ["rtl"], expected: ["ltr"] }, + { name: "display", value: ["list-item"], expected: ["block"] }, + { name: "empty-cells", value: ["hide"], expected: ["show"] }, + { name: "float", value: ["right"], expected: ["none"] }, + { name: "font-family", value: ["Georgia, serif"], expected: ["Times New Roman", "serif"] }, + { name: "font-size", value: ["12px"], expected: ["16px"] }, + { name: "font-style", value: ["italic"], expected: ["normal"] }, + { name: "font-variant", value: ["small-caps"], expected: ["normal"] }, + { name: "font-weight", value: ["700", 700], expected: ["400", 400, "700"] }, + { + name: "font", + value: [ + "italic 12px Georgia", + "italic 12px/normal Georgia", + "italic normal normal 12px/normal Georgia" + ], + expected: ["italic 12px Georgia"] + }, + { name: "height", value: ["5px"], expected: ["0px"] }, + { name: "left", value: ["5px"], expected: [] }, + { name: "letter-spacing", value: ["5px"], expected: [0] }, + { name: "line-height", value: ["12px"], expected: [1, "19.2px"] }, + { + name: "list-style-image", + value: [ + 'url("test.png")', + 'url(' + baseUrl + 'test.png)', + 'url("' + baseUrl + 'test.png")' + ], + expected: ["none"] + }, + { name: "list-style-position", value: ["inside"], expected: ["outside"] }, + { name: "list-style-type", value: ["disc"], expected: ["disc"] }, + { + name: "list-style", + value: [ + 'square url("test.png")', + 'square url(' + baseUrl + 'test.png)', + 'square url("' + baseUrl + 'test.png")', + 'square url(test.png)' + ], + expected: ["none", undefined] + }, + { name: "margin-right", value: ["5px"], expected: ["0px"] }, + { name: "margin-left", value: ["5px"], expected: ["0px"] }, + { name: "margin-top", value: ["5px"], expected: ["0px"] }, + { name: "margin-bottom", value: ["5px"], expected: ["0px"] }, + { name: "margin", value: ["5px"], expected: ["", "0px"] }, + { name: "max-height", value: ["5px"], expected: ["none"] }, + { name: "max-width", value: ["5px"], expected: ["none"] }, + { name: "min-height", value: ["5px"], expected: ["0px"] }, + { name: "min-width", value: ["5px"], expected: ["0px"] }, + { name: "opacity", value: ["0.5"], expected: [1, "1"] }, + { name: "orphans", value: ["3", 3], expected: [0, "0"] }, + { + name: "outline-color", + value: ["rgb(255, 0, 0)", "rgb(255,0,0)"], + expected: ["transparent", "rgb(0, 0, 0)", "#000000"] + }, + { name: "outline-style", value: ["dashed"], expected: ["none"] }, + // BEGIN - IE8 throws exception when trying to check for curCSS + // { name: "outline", value: ["red dotted thick", "thick dotted red"], expected: ["none"] }, + // END + { name: "overflow", value: ["scroll"], expected: ["visible"] }, + { name: "padding-top", value: ["5px"], expected: ["0px"] }, + { name: "padding-right", value: ["5px"], expected: ["0px"] }, + { name: "padding-bottom", value: ["5px"], expected: ["0px"] }, + { name: "padding-left", value: ["5px"], expected: ["0px"] }, + { name: "padding", value: ["5px"], expected: ["0px"] }, + { name: "page-break-after", value: ["right"], expected: [] }, + { name: "page-break-before", value: ["right"], expected: [] }, + { name: "page-break-inside", value: ["avoid"], expected: [] }, + { name: "position", value: ["absolute"], expected: ["static"] }, + { + name: "quotes", + value: [ + '"«" "»" "\'" "\'"', + "«, », '\\'', '\\''", + '"«" "»" "\\\'" "\\\'"' + ], + expected: [ + '"“" "”" "‘" "’"', + '"“" "”" "‘" "’"', + '“, ”, ‘, ’' + ] + }, + { name: "right", value: ["5px"], expected: [] }, + { name: "table-layout", value: ["fixed"], expected: [] }, + { name: "text-align", value: ["right"], expected: ["left", "start"] }, + { name: "text-decoration", value: ["underline"], expected: ["none"] }, + { name: "text-indent", value: ["5px"], expected: ["0px"] }, + { name: "text-transform", value: ["uppercase"], expected: ["none"] }, + { name: "top", value: ["5px"], expected: [] }, + { name: "unicode-bidi", value: ["bidi-override"], expected: ["normal"] }, + { name: "vertical-align", value: ["text-top"], expected: ["baseline"] }, + { name: "visibility", value: ["hidden"], expected: ["visible", "inherit"] }, + { name: "white-space", value: ["nowrap"], expected: ["normal"] }, + { name: "widows", value: ["2", 2], expected: [0, "0"] }, + { name: "width", value: ["5px"], expected: ["0px"] }, + { name: "word-spacing", value: ["5px"], expected: ["0px", "normal"] }, + { name: "z-index", value: [100, "100"], expected: [0] }, + { name: "alignment-adjust", value: ["middle"], expected: [] }, + { name: "alignment-baseline", value: ["middle"], expected: ["baseline"] }, + { name: "anchor-point", value: ["5px"], expected: ["none"] }, + { name: "animation", value: ["test 5s infinite"], expected: ["none 0 ease 0 1 normal"] }, + { name: "animation-delay", value: ["2s"], expected: ["0s"] }, + { name: "animation-direction", value: ["alternate"], expected: ["normal"] }, + { name: "animation-duration", value: ["2s"], expected: ["0s"] }, + { name: "animation-iteration-count", value: ["3"], expected: ["1"] }, + { name: "animation-name", value: ["test"], expected: ["none"] }, + { name: "animation-play-state", value: ["paused"], expected: ["running"] }, + { + name: "animation-timing-function", + value: ["linear", "cubic-bezier(0, 0, 1, 1)"], + expected: ["ease", "cubic-bezier(0.25, 0.1, 0.25, 1)"] + }, + { name: "appearance", value: ["button"], expected: ["normal"] }, + { name: "backface-visibility", value: ["hidden"], expected: ["visible"] }, + { name: "background-clip", value: ["content-box"], expected: ["border-box"] }, + { name: "background-origin", value: ["content-box"], expected: ["padding-box"] }, + { name: "background-size", value: ["80px 60px"], expected: [] }, + { name: "baseline-shift", value: ["super"], expected: ["baseline"] }, + { + name: "binding", + value: ['url("test.png")'], + expected: [] + }, + { name: "bleed", value: ["3pt"], expected: ["6pt"] }, + { name: "bookmark-label", value: ["test"], expected: ["content()"] }, + { name: "bookmark-level", value: ["3"], expected: ["none"] }, + { name: "bookmark-state", value: ["closed"], expected: ["open"] }, + { name: "bookmark-target", value: ["attr(href, url)"], expected: ["none"] }, + { name: "border-bottom-left-radius", value: ["32px", "32px 32px"], expected: ["0px"] }, + { name: "border-bottom-right-radius", value: ["32px", "32px 32px"], expected: ["0px"] }, + // Setting border-image in Chrome splits out to border-image-source, border-image-slice, and border-image-repeate + // { name: "border-image", value: ["url(border.png) 30 30 round"], expected: ["none 100% 1 0 stretch"] }, + { name: "border-image-outset", value: ["30 30", "30"], expected: [0] }, + { name: "border-image-repeat", value: ["round"], expected: ["stretch"] }, + { name: "border-image-slice", value: ["50% 50%", "50%"], expected: ["100%"] }, + { + name: "border-image-source", + value: [ + 'url("border.png")', + 'url(' + baseUrl + 'border.png)', + 'url("' + baseUrl + 'border.png")', + 'url(border.png)' + ], + expected: ["none"] + }, + { name: "border-image-width", value: ["30 30", "30"], expected: [1] }, + // Setting border-radius in Chrome splits out to border-top-left-radius, etc... + // { name: "border-radius", value: ["25px"], expected: [0] }, + { name: "border-top-left-radius", value: ["32px", "32px 32px"], expected: ["0px"] }, + { name: "border-top-right-radius", value: ["32px", "32px 32px"], expected: ["0px"] }, + { name: "box-decoration-break", value: ["clone"], expected: ["slice"] }, + { + name: "box-shadow", + value: ["10px 10px 5px #cccccc", "rgb(204, 204, 204) 10px 10px 5px"], + expected: ["none"] + }, + { name: "box-sizing", value: ["border-box"], expected: ["content-box"] }, + { name: "break-after", value: ["right"], expected: [] }, + { name: "break-before", value: ["right"], expected: [] }, + { name: "break-inside", value: ["avoid"], expected: [] }, + // I can't seem to get this to take in Chrome + // { name: "color-profile", value: ['url("http://eg.icm")'], expected: [] }, + { name: "column-count", value: ["3"], expected: [] }, + { name: "column-fill", value: ["auto"], expected: ["balance"] }, + { name: "column-gap", value: ["40px"], expected: ["normal"] }, + { name: "column-rule", value: ["3px outset rgb(255, 0, 255)"], expected: ["medium none black"] }, + { name: "column-rule-color", value: ["#ff0000", "rgb(255, 0, 0)"], expected: ["rgb(0, 0, 0)"] }, + { name: "column-rule-style", value: ["dotted"], expected: ["none"] }, + { name: "column-rule-width", value: ["5px"], expected: ["medium"] }, + { name: "column-span", value: ["all"], expected: ["1"] }, + { name: "column-width", value: ["100px"], expected: [] }, + { name: "columns", value: ["12em", "auto 12em"], expected: [] }, + { name: "crop", value: ["rect(0px, 115px, 85px, 30px)"], expected: [] }, + { name: "dominant-baseline", value: ["alphabetic"], expected: [] }, + { name: "drop-initial-after-adjust", value: [""], expected: ["text-after-edge"] }, + { name: "drop-initial-after-align", value: [""], expected: ["baseline"] }, + { name: "drop-initial-before-adjust", value: [""], expected: ["text-before-edge"] }, + { name: "drop-initial-before-align", value: [""], expected: ["caps-height"] }, + { name: "drop-initial-size", value: [""], expected: [] }, + { name: "drop-initial-value", value: [""], expected: ["initial"] }, + { name: "fit", value: ["meet"], expected: ["fill"] }, + { name: "fit-position", value: ["50% 50%"], expected: ["0% 0%"] }, + { name: "align-items", value: ["baseline"], expected: ["streth"] }, + { name: "align-self", value: ["baseline"], expected: [] }, + { name: "align-content", value: ["center"], expected: ["stretch"] }, + { name: "order", value: ["3"], expected: [0] }, + { name: "justify-content", value: ["center"], expected: ["flex-start"] }, + { name: "flex-grow", value: ["5"], expected: ["0"] }, + { name: "flex-shrink", value: ["3"], expected: ["1"] }, + { name: "flex-basis", value: ["22px"], expected: [] }, + { name: "float-offset", value: ["-50% 3em"], expected: ["0 0"] }, + { name: "font-feature-settings", value: ['"smcp" 1, "swsh" 2'], expected: ["normal"] }, + { name: "font-kerning", value: ["normal"], expected: [] }, + { name: "font-language-override", value: ["SRB"], expected: ["normal"] }, + // I can't seem to get this to take in Chrome + // { name: "font-size-adjust", value: ["0.5"], expected: ["none"] }, + // I can't seem to get this to take in Chrome + // { name: "font-stretch", value: ["condensed"], expected: ["normal"] }, + { name: "font-synthesis", value: ["none"], expected: ["weight style"] }, + { name: "font-variant-alternates", value: ["swash(flowing)"], expected: ["normal"] }, + { name: "font-variant-caps", value: ["all-petite-caps"], expected: ["normal"] }, + { name: "font-variant-east-asian", value: ["traditional"], expected: ["normal"] }, + { name: "font-variant-ligatures", value: ["historical-ligatures"], expected: ["normal"] }, + { name: "font-variant-numeric", value: ["diagonal-fractions"], expected: ["normal"] }, + { name: "font-variant-position", value: ["super"], expected: ["normal"] }, + { name: "hanging-punctuation", value: ["first"], expected: ["none"] }, + { name: "hyphens", value: ["auto"], expected: ["manual"] }, + { name: "icon", value: ['url("icon.png")'], expected: [] }, + { name: "image-orientation", value: ["90deg"], expected: ["0deg"] }, + // I can't seem to get this to take in Chrome + // { name: "image-rendering", value: ["optimizeQuality"], expected: [] }, + { name: "image-resolution", value: ["300dpi"], expected: ["normal"] }, + { name: "inline-box-align", value: ["initial"], expected: ["last"] }, + { name: "line-break", value: ["strict"], expected: ["normal"] }, + { name: "line-stacking", value: ["grid-height include-ruby disregard-shifts"], expected: [] }, + { name: "line-stacking-ruby", value: ["include-ruby"], expected: ["exclude-ruby"] }, + { name: "line-stacking-shift", value: ["disregard-shifts"], expected: ["consider-shifts"] }, + { name: "line-stacking-strategy", value: ["grid-height"], expected: ["inline-line-height"] }, + { name: "marks", value: ["cross"], expected: ["none"] }, + { name: "marquee-direction", value: ["reverse"], expected: ["forward"] }, + { name: "marquee-loop", value: ["5"], expected: [1] }, + { name: "marquee-play-count", value: ["5"], expected: [1] }, + { name: "marquee-speed", value: ["fast"], expected: ["normal"] }, + { name: "marquee-style", value: ["alternate"], expected: ["scroll"] }, + { name: "move-to", value: ["here"], expected: ["normal"] }, + { name: "nav-down", value: ["#test"], expected: [] }, + { name: "nav-index", value: ["5"], expected: [] }, + { name: "nav-left", value: ["#test"], expected: [] }, + { name: "nav-right", value: ["#test"], expected: [] }, + { name: "nav-up", value: ["#test"], expected: [] }, + { name: "opacity", value: ["0.5"], expected: ["1"] }, + { name: "outline-offset", value: ["5px"], expected: [0] }, + { name: "overflow-style", value: ["marquee-line"], expected: [] }, + { name: "overflow-wrap", value: ["break-word"], expected: ["normal"] }, + { name: "overflow-x", value: ["scroll"], expected: ["visible"] }, + { name: "overflow-y", value: ["scroll"], expected: ["visible"] }, + { name: "page", value: ["rotated"], expected: [] }, + { name: "page-policy", value: ["last"], expected: ["start"] }, + { name: "perspective", value: ["500px"], expected: ["none"] }, + { name: "perspective-origin", value: ["10px 10px"], expected: ["50% 50%", "0px 0px"] }, + { name: "presentation-level", value: ["same"], expected: [0] }, + { name: "punctuation-trim", value: ["start"], expected: ["none"] }, + { name: "rendering-intent", value: ["saturation"], expected: [] }, + { name: "resize", value: ["horizontal"], expected: ["none"] }, + { name: "rest", value: ["weak strong"], expected: [] }, + { name: "rest-after", value: ["x-weak"], expected: [] }, + { name: "rest-before", value: ["strong"], expected: [] }, + { name: "rotation", value: ["180deg"], expected: [0] }, + { name: "rotation-point", value: ["25% 75%"], expected: ["50% 50%"] }, + { name: "ruby-align", value: ["center"], expected: [] }, + { name: "ruby-overhang", value: ["whitespace"], expected: ["none"] }, + { name: "ruby-position", value: ["inline"], expected: ["above"] }, + { name: "ruby-span", value: ["attr(rbspan)"], expected: ["none"] }, + { name: "size", value: ["landscape"], expected: ["auto"] }, + { name: "speak-as", value: ["literal-punctuation"], expected: ["normal"] }, + { name: "string-set", value: ["index content(first-letter)"], expected: ["none"] }, + { name: "tab-size", value: ["4"], expected: [8] }, + { name: "target", value: ["parent tab front"], expected: [] }, + { name: "target-name", value: ["parent"], expected: ["current"] }, + { name: "target-new", value: ["tab"], expected: ["window"] }, + { name: "target-position", value: ["front"], expected: ["above"] }, + { name: "text-align-last", value: ["right"], expected: [] }, + { name: "text-decoration-color", value: ["rgb(255, 0, 0)"], expected: ["currentColor"] }, + { name: "text-decoration-line", value: ["line-through"], expected: ["none"] }, + { name: "text-decoration-skip", value: ["spaces"], expected: ["objects"] }, + { name: "text-decoration-style", value: ["dotted"], expected: ["solid"] }, + { name: "text-emphasis", value: ["double-circle"], expected: ["none"] }, + { name: "text-emphasis-color", value: ["rgb(255, 0, 0)"], expected: ["currentColor"] }, + { name: "text-emphasis-position", value: ["below left"], expected: ["above right"] }, + { name: "text-emphasis-style", value: ["double-circle"], expected: ["none"] }, + { name: "text-height", value: ["text-size"], expected: [] }, + // Unable to Set Style on Source Element + // { name: "text-justify", value: ["distribute"], expected: [] }, + { name: "text-outline", value: ["inter-word"], expected: ["none"] }, + { + name: "text-shadow", + value: ["2px 2px #ff0000", "rgb(255, 0, 0) 2px 2px"], + expected: ["none"] + }, + { name: "text-space-collapse", value: ["preserve"], expected: ["collapse"] }, + { name: "text-underline-position", value: ["below"], expected: [] }, + { name: "text-wrap", value: ["avoid"], expected: ["normal"] }, + { name: "transform", value: ["rotate(7deg)", "matrix(0.992546, 0.121869, -0.121869, 0.992546, 0, 0)"], expected: ["none"] }, + { name: "transform-origin", value: ["20px 40px"], expected: ["50% 50% 0%", "0px 0px"] }, + { name: "transform-style", value: ["flat"], expected: ["flat"] }, + { name: "transition", value: ["background-color linear 1s", "background-color 1s linear"], expected: [] }, + { name: "transition-delay", value: ["2s"], expected: [0, "0s"] }, + { name: "transition-duration", value: ["5s"], expected: [0, "0s"] }, + { name: "transition-property", value: ["width"], expected: ["all"] }, + { + name: "transition-timing-function", + value: ["linear", "cubic-bezier(0, 0, 1, 1)"], + expected: ["ease", "cubic-bezier(0.25, 0.1, 0.25, 1)"] + }, + { name: "voice-balance", value: ["right"], expected: ["center"] }, + { name: "voice-duration", value: ["+3s"], expected: [] }, + { name: "voice-pitch", value: ["250Hz"], expected: ["medium"] }, + { name: "voice-range", value: ["+20Hz"], expected: ["medium"] }, + { name: "voice-rate", value: ["fast"], expected: ["normal"] }, + { name: "voice-stress", value: ["strong"], expected: ["moderate"] }, + { name: "voice-volume", value: ["soft"], expected: ["medium"] }, + { name: "word-break", value: ["break-all"], expected: ["normal"] }, + { name: "overflow-wrap", value: ["break-word"], expected: ["normal"] } + ]; + + $.each( styles, function(index, style) { + var defaultValue = { + "background-attachment": "scroll" + , "background-color": "transparent" + , "background-image": "none" + , "background-position": "0% 0%" + , "background-repeat": "repeat" + , "background-clip": "border-box" + , "background-origin": "padding-box" + , "background-size": "auto auto" // Fails in PhantomJS, but not IE10 or Chrome + , "orphans": 0 + , "widows": 0 + , "quotes": '"“" "”" "‘" "’"' + , "clip": "rect(auto,auto,auto,auto)" + }, + domStyleName = cssPropertyToDomStyleProperty(style.name), + newValue, $source, source, $clone, clone; + + // defaultValue = {}; // TODO: Remove this... + + count++; + style.expected = style.expected.concat(["", "auto"]); + $source = $("
        "); + source = $source[0]; + if ( source.style[style.name] === undefined ) { + console.log( "NOT SUPPORTED: " + style.name ); + return true; + } else if ( window.getComputedStyle && + window.getComputedStyle(source)[domStyleName] === undefined ) { + console.log( "SUPPORTED, BUT NOT REALLY: " + style.name ); + return true; + } + $source.css( style.name, style.value[0] ); + + /* + // By accessing the .css() getter it masks the bug we are trying to detect + ok( ~$.inArray($source.css(style.name), style.value), "Style applied to source before cloning: " + style.name + + "; result: " + $source.css(style.name) + + "; expected: " + style.value.join(",") ); + if ( ~$.inArray($source.css(style.name), style.value) ) { + */ + $clone = $source.clone(); + clone = $clone[0]; + newValue = defaultValue[style.name] !== undefined ? defaultValue[style.name] : ""; + $clone.css( style.name, newValue ); + + ok( source !== clone, "Verify objects different: " + style.name ); + ok( source.style !== clone.style, "Verify style properties different: " + style.name ); + + ok( ~$.inArray($clone.css(style.name) !== undefined ? $clone.css(style.name) : "undefined", style.expected), + "Clearing clone.css() works: " + style.name + + "; result: " + $clone.css(style.name) + + "; expected: " + style.expected.join(",") ); + ok( ~$.inArray($source.css(style.name), style.value), + "Clearning clone.css() doesn't affect source.css(): " + style.name + + "; result: " + $source.css(style.name) + + "; expected: " + style.value.join(",") ); + if ( !~$.inArray($source.css(style.name), style.value) ) { + console.log( "FAILED: " + style.name + + "; result: " + $source.css(style.name) + + "; expected: " + style.value.join(",") ); + } + + // IE actually clears out the source style in many cases, but + // .css() still gets answer because it uses getComputedStyle + ok( ~$.inArray(source.style[domStyleName], style.value), + "Underlying source style unchanged: " + style.name + + "; result: " + source.style[style.name] + + "; expected: " + style.value.join(",") ); + if ( !~$.inArray(source.style[domStyleName], style.value) ) { + console.log( "FAILED: Underlying Cleared: " + style.name + + "; result: " + source.style[domStyleName] + + "; expected: " + style.value.join(",") ); + } + equal( clone.style[domStyleName], "", + "Underlying clone style cleared: " + style.name ); + /* + } else { + console.log( "NOT WORKING: " + style.name ); + } + */ + }); + + console.log( "Number of styles tested: " + count ); +}); + +function cssPropertyToDomStyleProperty( name ) { + return name .replace( /-(\w)/g, function(match, group) { + return group.toUpperCase(); + }); +} + +})( jQuery ); \ No newline at end of file diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js index 60a0830c7..764da0349 100644 --- a/test/unit/manipulation.js +++ b/test/unit/manipulation.js @@ -1909,18 +1909,18 @@ test("checked state is cloned with clone()", function(){ }); test( "Clearing a Cloned Element's Style Shouldn't Clear the Original Element's Style (#8908)", function() { - expect( 8 ); + expect( 16 ); var baseUrl = document.location.href.replace( /([^\/]*)$/, "" ); var styles = [ - { name: "background-attachment", value: [ "fixed" ], expected: [ "scroll" ] }, - { name: "background-color", value: [ "rgb(255, 0, 0)", "rgb(255,0,0)" ], expected: [ "transparent" ] }, - { name: "background-image", value: [ 'url("test.png")', 'url(' + baseUrl + 'test.png)', 'url("' + baseUrl + 'test.png")' ], expected: [ "none" ] }, - { name: "background-position", value: [ "5% 5%" ], expected: [ "0% 0%" ] }, - { name: "background-repeat", value: [ "repeat-y" ], expected: [ "repeat" ] }, - { name: "background-clip", value: [ "content-box" ], expected: [ "border-box" ] }, - { name: "background-origin", value: [ "content-box" ], expected: [ "padding-box" ] }, - { name: "background-size", value: [ "80px 60px" ], expected: [] } + { name: "backgroundAttachment", value: [ "fixed" ], expected: [ "scroll" ] }, + { name: "backgroundColor", value: [ "rgb(255, 0, 0)", "rgb(255,0,0)", "#ff0000" ], expected: [ "transparent" ] }, + { 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) { @@ -1931,6 +1931,7 @@ test( "Clearing a Cloned Element's Style Shouldn't Clear the Original Element's 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] ); @@ -1941,5 +1942,9 @@ test( "Clearing a Cloned Element's Style Shouldn't Clear the Original Element's "Clearning 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 ), + "The cloned element was reset to it's default value: " + style.name + + "; result: " + $clone.css( style.name ) + + "; expected: " + style.expected.join( "," ) ); }); }); \ No newline at end of file -- cgit v1.2.3