fix: track value of inputs and textareas in shadow DOM - #1332
TanbirRamim wants to merge 2 commits into
Conversation
The document-level focus and blur listeners used `event.target`, which is retargeted to the shadow host for elements inside a shadow root. So the value interceptor was never installed on those elements, and resetting their value was not picked up by the next `user.type()`. Use the original target from `composedPath()` instead. Fixes testing-library#1314
| e => { | ||
| const el = e.target as Element | ||
| // Focus on elements in a shadow tree is retargeted to the shadow host. | ||
| const el = e.composedPath()[0] as Element |
There was a problem hiding this comment.
The first three steps of the composedPath algorithm suggest this could be an empty array
https://dom.spec.whatwg.org/#dom-event-composedpath
one place this can happen is if a synthetic focus or blur is called. Some libraries do this to trigger known side effects, so I think we need to check the length and fall back to target if it's empty
There was a problem hiding this comment.
I think these lines need to use getActiveElement instead?
|
Thanks, both changed. The focus and blur listeners now fall back to |
What
Fixes #1314. For an
<input>or<textarea>inside a shadow root, setting.valueafteruser.type()was not picked up, so the nextuser.type()appended to the old text (helloworldinstead ofworld). Thechangeevent on blur was also never dispatched for these elements.Why
The document-level
focusandblurlisteners inprepareDocumentusedevent.target, which is retargeted to the shadow host, so the value interceptor was never installed on the actual element.How
Both listeners now use
event.composedPath()[0]to get the original target. I added tests for value tracking and the blurchangeevent intests/document/index.ts, plus the reporteduser.type()case intests/utility/type.ts; all three fail before the change and pass after, and lint and typecheck are clean. Closed shadow roots still resolve to the host, same as before.Checklist