Address issues where ID of nodeName causes internal errors in React#10076
Address issues where ID of nodeName causes internal errors in React#10076nhunzaker wants to merge 2 commits intofacebook:masterfrom
Conversation
7a4ec79 to
ecca02b
Compare
| var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); | ||
|
|
||
| if (nodeName === 'input') { | ||
| if (elem instanceof HTMLInputElement) { |
There was a problem hiding this comment.
This doesn't work when these nodes are rendered into another iframe. It's not a super common use case but a bigger discussion if we should stop supporting that.
There was a problem hiding this comment.
Woah:
iframe.contentWindow.window.HTMLInputElement instanceof HTMLInputElement // falseToday I learned....
There was a problem hiding this comment.
Seems like we could at least get some test coverage for this. I'll dig into that too. Though, if we don't have any coverage for it presently, I wonder if it's just a can of worms in JSDOM.
There was a problem hiding this comment.
How much slower would it be to do something like:
getInstanceForNode(elem)._tag === 'input'
That gets us around working with the DOM.
sebmarkbage
left a comment
There was a problem hiding this comment.
Let's chat about the possibility of dropping multiple iframes support. I think the instanceof check can probably often be faster when available.
I'm not as concerned about that use case as I am about supporting React itself being in a different realm than the one being rendered into. That's still trivially supported even with instanceof checks.
|
Cool, I'd be interested in knowing more about that use case. Time to dig into realms. For discussion's sake, another option might be to perform a check like: function elementIsType (element: HTMLElement, type: string): boolean {
return element instanceof element.ownerDocument.defaultView[type]
}Which is interesting, but it doesn't really get around the underling problem: the id attribute can arbitrarily screw up any specific DOM API access. This just recreates the same issue with I wonder if this is only isolated to forms and window. |
|
This only fixes the problem for I think in theory we could extract these methods from the prototype chain. Like this: var nodeNameGetter = Object.getOwnPropertyDescriptor(
Node.prototype,
'nodeName'
).get;
console.log(nodeNameGetter.call(element));I'm not sure it's worth the performance overhead and file size to deal with this kind of defensive coding. |
- Add test coverage for nodeName fix - Add defaultValue to test to avoid log
|
Another proposal: Throw if any of the known names are used as a form name? Warning would be nice but I'm also concerned about the potential attack surface of dynamic values. |
|
I think the nodeName getter will work. Seems fast too: I've almost got this setup, I just hit a snag because the original test case doesn't hit the code path with the new ChangeEvent updates. Be back shortly :). |
53b5992 to
1810b5a
Compare
| var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase(); | ||
| if (elem === window) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
@sebmarkbage this is the only downside I see to calling the nodeName getter. Occasionally this value is the window. That's because the target instance falls back to the window when it can't find a target instance:
I can't help but wonder if this could be document.body instead of window.
There was a problem hiding this comment.
A good example of this is if you throw a breakpoint in this function and click anywhere on the page other than the target input.
There was a problem hiding this comment.
Sorry. To clarify: calling nodeNameGetter on window raises an exception.
|
The reason this is even an issue in the first place is because elements with IDs are registered as properties on Why don't we just type check the |
|
@aweary That might work. The only other element that exhibits this behavior, that I can find, is inputs within forms: https://codepen.io/nhunzaker/pen/qXjOGy?editors=1111 The Beyond that, if we access nodeName directly, are there any other edge cases that producing a |
|
Specifically, we need to know if there's any situation where this can occur on a |
|
Stale. |
This is a continuation of #6311. More or less, using
nodeNameas an ID on an input causes references to thenodeNameprototype property to be overriden.I've rebased @jimfb's original PR and added some test coverage. I've also browser tested this against IE11, Firefox, Safari, and Chrome.
I would like to test down to IE9, however it looks like I need the Set polyfill on our DOM fixtures. Is there a preferred method of adding the Set polyfill?