-
Notifications
You must be signed in to change notification settings - Fork 46.9k
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
Use removeAttribute to forcefully remove properties from the DOM #1510
Conversation
// Boolean properties set to false removes the attribute from the DOM. | ||
// Additionally, using removeAttribute to clear boolean properties can | ||
// apparently prevent related side-effects from occuring, example: | ||
// selectNode.removeAttribute('multiple') might not update value |
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.
might not?
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.
selectNode.removeAttribute('multiple') is apparently not guaranteed to correctly update "option.selected"
Makes more sense?
I found this while running the tests, removing the attribute for some reason does not update selected
for the affected options, causing multiple to still be selected (even though it should not be allowed at that point).
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.
That wording makes sense but it seems quite strange to me.
Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Facebook open source project. Thanks! |
@syranide, can you rebase? Based on @sebmarkbage adding that tag, I guess he's ready for this. |
@zpao Will do, tomorrow. |
@zpao Rebased. However!
|
Sorry, what's wrong with DOMAttributeNames as it is now? |
@spicyj Nothing, I had missed that it's automatically filled with lower-cased names. :) |
"Kind of waiting" for #2202 |
@zpao Apart from breaking (the already broken)
Correctly restores the property value in all browsers I have my hands on, as you would expect. |
Accepted but only once the dependency is resolved. |
Dependency landed, I'll rebase and retest this PR. |
We're the worst at merging… This is still passing all tests in a real browser and Phantom, but it's failing with jest, which is a bit of a bummer. It's actually an issue with the outdated jsdom we have in jest (which I'm going to fix... jestjs/jest#221). In the mean time we might have to |
@zpao This is on me actually, I got the go-ahead for merging my accepted ones some time (too long) ago after rebasing and testing... it's just been one thing after another on my end. But I'm trying to get some time over to go through my accepted PRs and get them rebased/tested soon. |
@sebmarkbage @zpao I've verified that there aren't any other properties that should have I've changed it to always set boolean properties to There's an unsolvable edge-case for now; So unless there's any red flags for you guys, this should be OK to merge from my POV. EDIT: (jest) JSDOM was failing my new prop/attr tests, I commented out the affected rows in hopes that JSDOM will correct it in the future (or if we drop JSDOM). Ok? Or should I just remove the affected tests, they have some value they way they are now at least... |
ping (no rush) PS. I'm not quite sure why travis is failing this PR because of existing lint errors but not others? |
} else if (DOMProperty.mustDeleteProperty[name]) { | ||
// Some properties are separate from their attribute, `removeAttribute` | ||
// does not have the intended effect for these. | ||
var propName = DOMProperty.getPropertyName[name]; |
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.
@syranide This is the lint error making Travis fail:
src/browser/ui/dom/DOMPropertyOperations.js
174:12 error propName is already defined no-redeclare
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.
Ah thanks.
Ping. I fixed the lint issue and I feel confident that everything is in order and that only the above mentioned caveats apply (which are far better than the current caveats), also note the issue with JSDOM tests. |
Ok, I wrote a jsfiddle to help identify attributes that might warrant manual investigation. I ran it on chrome, next step is to run it on other browsers. Fiddle is located here: http://jsfiddle.net/gLd3hfrn/ On chrome, it flagged: radiogroup mediaGroup cc @syranide |
Looks like http-equiv works fine if you spell it as http-equiv not html-equiv. |
Ah, ok, that's good :). |
Again really sorry for dragging my feet on this. Personally I'm mostly concerned about input controls and the various mutations of them (e.g. toggling |
…p MUST_USE_ATTRIBUTE and manage all regular properties as attributes instead
Simple test: http://jsfiddle.net/670u7ure/8/ However as you can see @jimfb Do you feel like the transition from properties to attributes is safe from your tests? Unrelated; Also, I noticed that React has acquired some weird behavior (in master) where it doesn't set Unrelated 2; https://github.com/facebook/react/blob/master/src/renderers/dom/shared/DOMPropertyOperations.js#L176 that seems broken, NS-attributes don't obey by the property flags correctly. |
@syranide updated the pull request. |
PS. Another thing to consider, we could get rid of |
Yes, we can move the .value logic to the wrappers. I wanted to make it use attributes at the low level anyway as part of a fix for #4618. |
@spicyj Make that change first, then remove |
Ping |
I don't think they need to be intertwined. Will leave merging this to @jimfb since he's already done most of the testing. |
Ok, I ran a whole suite of tests on a wide variety of browsers (firefox, chrome, ie, edge, safari, etc). I also cherrypicked this over to my devserver and ran through the whole react test flow. I think we've done our due diligence here. Worst case, we revert/fix, but I think the risk is low. Let's do this. |
Use removeAttribute to forcefully remove properties from the DOM
Totally missed that this landed, that's awesome @jimfb 👍 |
This PR introduces this bug: #6219 I discussed my solution in that thread a little bit and offered a small fix: #6228 The fix is aimed to preserve current behavior as much as possible without breaking anything. We could leave it at that, but it might be better to reconsider current implementation in general. Current |
@everdimension Just by looking at it I'm not entirely sure why that code is to blame or why yours fixes it, or why it worked before but not now (if that is the actual source of the problem)... But the actual problem I assume should be related to the one described in #6119. Namely that |
Oh now it makes sense to me, yeah, #6221 is the correct way to fix this. But I'm not sure why it worked before but not now still, that logic is the same, unless there are unrelated changes elsewhere that are the cause of this (I know selects/options have been updated). |
Oh my bad, #6119 is the one I meant I think. It removes the concept of these special properties so it no longer affects DOMPropertyOperations. |
Proper implementation of #1448, because now there's something factual to discuss.
The DOM now statelessly reflects the props provided to DOM components. No more
getDefaultValueForProperty
.""
,null
andundefined
no longer behave differently depending on the value being an attribute or property, with""
being an actual value and distinct fromnull
andundefined
. I would dare say that this is the correct fix for #1431.As is mentioned and benchmarked in the #1448, there should be a theoretically measurable impact of this (in some browsers). But I dare anyone to suggest a reasonable real-life use-case where it is actually at all measurable (unless my benchmark is flawed).
If we want to push the performance of edge-browsers to the limit, we could conditionally make the default type be attribute (instead of property) as FF and Chrome perform significantly better, but they're basically an order of magnitude faster already making it quite pointless (and fragile) IMHO.
Basic tests added, removed an existing test (that has been half-broken) as it no longer makes sense.