-
Notifications
You must be signed in to change notification settings - Fork 20.5k
[1.9] Prevent Clearing Cloned Style to Affect Source Element's Style. Fixes #8908 #886
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Nice detective work! 👍 I think we'll have to land something in 1.9/2.0 since IE9 is not gonna get fixed and I think it's even too late for an IE10 fix at this point since they have gone RTM with Windows 8. The call to There's a very similar-sounding bug regarding The commits are kind of messed up, probably because you submitted the earlier pull from your master, but we can cherry-pick d5d8622 off there. If you haven't already you should probably clean up your master if you haven't already. http://stackoverflow.com/questions/1628088/how-to-reset-my-local-repository-to-be-just-like-the-remote-repository-head |
|
Yeah, I wondered if the PR came in clean or not. Arg. Yeah, I'll try what is listed on that SO link. The fix comes down to adding the following before the call to // 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;
}As one of the cons I mentioned performance because it would run that code for any browser. I wasn't sure a good way to isolate just to IE9/10. Good point about causing a reflow. I'm not sure about that one, but I can try to dig into that further. I'll take a look at #9777 as you mentioned. It maybe be related, but as for the above bug it didn't show itself in IE7. I figured this PR would probably wait since 1.8 is about finalized. Thanks for your feedback. If you have any ideas on how to isolate this to IE9/10 I am all ears ;) |
src/manipulation.js
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to avoid having numbered identifiers. This seems like something that belongs in the support module.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rwldrn Yeah, I wasn't too thrilled about that either, but the fix depends on getting a style off of the object returned from getComputedStyle(). The reason I went ahead and saved it off to a variable was to get around the Expected an assignment or function call and instead saw an expression. JSHint error. I could save it off to an existing variable such as i, but that felt weird too.
I am thinking of pulling out a feature detection into the jQuery.support module to test for this strange bug so that it can be scoped to only IE9/10 and not affect the performance of other browsers.
With this support feature, I will still need to save the style to a variable for JSHint to like it. Would you recommend renaming the variable, reusing another variable, or something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a strange thing... It's really bothersome that IE10 actually released a browser that allows a clone's style property to retain reference to the source element.
Anyway, yeah this belongs in jQuery.support, maybe called jQuery.support.whenWillTheyLearn ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of having the ticket number in the variable name, usually we mention the ticket in a short comment. So you can just pick a short name or even reuse i if it isn't used in the code path.
Changes Since the Initial Pull RequestSource Code ChangesI make a new test in the support module called 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;
})();I am using the ...
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 ( !jQuery.support.clearCloneStyle && elem.nodeType === 1 &&
+ window.getComputedStyle ) {
+ i = ( window.getComputedStyle( elem, null ) || {} ).backgroundPosition;
+ }
clone = elem.cloneNode( true );
...
}
...As I was retesting the code in IE6/7/8/9/10 I noticed that one of the styles ( ...
// 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 {
style[ name ] = value;
} catch(e) {}
}
...Browsers TestedI have run the above changes through the following browsers Windows
Mac
Unit Test ChangesAs I was testing the code in all the above browsers I added another assertion to the Unit Test to check if the style that was being cleared on the clone element was indeed being reset. Because of that addition assertion I made the following changes...
Summary of Changes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a regex because of backgroundPositionX and backgroundPositionY? Is that value still work for those? Also, can you move the regex out to it's own variable at the top of the file with the other regex's so it can get cached?
We only care about the result of parseJSON so there's no reason to feature detect the entire test.
… bug that caused a performance hit. Closes jquerygh-958
Test expects input elements having name='id', name='name', and name='target'. Additionally, these should have id='id', id='name', and id='target' respectively. No element was provided with id='id' or name='id', but rather one element had two name attributes (illegal) with the values 'id' and 'name' respectively.
I don't want to add a unit test that creates a dependency on an applet.
jquerygh-967" This reverts commit 063ea02. I've beaten on this for a while and can't find a suitable feature detect that catches Chrome's support for focusin.
|
@dmethvin I just pulled in the changes and fixed the differences. Unfortunately I saw you said "rebase" after I pushed ;( So there are tons of commits shown. |
|
Didn't actually close. |
|
I haven't landed this yet, I just created a branch for @elijahmanor to review. |
|
Woops, read the close, thought it needed to be closes/closed. :/ |
|
I realized there was no need to fix for backgroundPositionX/Y since they're not standard or supported across browsers (Firefox is the holdout, possibly Opera as well). |
Clearing a Cloned Element's Style Causes the Original Element's Style to be Cleared
Introduction
In IE9 and IE10 you can run into the situation when clearing (
"") a cloned element's style will also clear out the original element's corresponding style.The actual jQuery Core Ticket #8908 isolates the bug when using the background-image style.
While I was trying to recreate and research this issue I had a feeling that there may be other styles that have the same issue, so I've created a test suite checking 252 CSS1-3 styles and testing various assertions.
Along the way, I also found some additional inconsistencies. These findings are technically unrelated to the #8908 issue so I will list those inconsistencies somewhere else and we can discuss those later.
Source Element's Style Cleared When Cloned Element's Style Cleared
IE9 & IE10
After testing 252 various styles only the following 8 ended up being problematic.
IE 6/7/8, Chrome, Firefox, Opera
Thankfully these browsers did not have the problem described in this issue when tested.
Proposed Solutions
1. Use Default Values when Trying to Empty Style
The following fix resolves the weird issue by substituting and empty string with it's default value. An object is used to store the style name and associated default value. If the value happens to be an empty string then it will look in the object for a matching key and if there is a match it will use that instead.
Pros
Cons
.css()method is very common2. Strange Side Effect That Breaks the Clone Connection
This solution is a little more strange and not so obvious. I ran into this fix as I was building up my unit tests and asserting a bunch of things I thought should be true. One of those assertions was verifying that when setting a style using the
$elem.css( "someStyle", "someValue" )method that it actually worked. So, I used the getter ($elem.css( "someValue" )method, but by doing so I found the problem going away just by calling the getter! And with that the following solution came about.You may notice a slightly strange piece of code
( window.getComputedStyle( elem, null ) || {} ), but that was needed to get around an Opera bug I had when working with XML nodes. Technically I could have made the whole fix into one statement, but the minification process does a decent job of squishing down the fix to look like(b.nodeType===1&&a.getComputedStyle&&(i=(a.getComputedStyle(b,null)||{}).backgroundImage).// clone.js jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { var srcElements, destElements, i, - clone; + clone, + fix8908; 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; + } + clone = elem.cloneNode( true ); // IE<=8 does not properly clone detached, unknown element nodes } else { ... } ... }, ... });Pros
.css()method approach in option Accumulated, not yet pulled commits #1.Cons
3. Have IE9 & IE10 Fix this Bug
It would be ideal if no patch had to be made to jQuery at all and IE9 and IE10 could apply a fix instead. Seeing that the issue is found in IE9 though may rule out this option entirely.
Pros
Cons
Unit Test
The following Unit Test exposes the problem in IE9 and IE10. In browsers that don't support these styles I am skipping over them and asserting that they are not an issue.
Conclusion
Based on the research I have done testing 252 CSS styles I have isolated this issue to only 8 styles in IE9 and IE10.
I've recommended solving this issue 3 different ways, but in the end the 2nd option seems best to me since it only is executed in the clone execution path and is significantly smaller than the 1st option. The 3rd option of having IE fix this issue seems too late since the issue also affects IE9.