Closed jessevanassen closed 4 years ago
Thanks for the detailed writeup. I'll look at this soon.
29 days ago
I don't think setting forwardTab_ = undefined
makes sense, because a user might be shift-tabbing through the page, although I suppose the dialog blocks anything else from being tabbed.
FYI we can reproduce this in Safari by adding tabindex="0"
to the <html>
element. IE must just have that behavior by default (and I don't have a Windows machine that handy). I'll have a fix soon.
Can you test the solution I've pushed in this commit? I'll do a release if it works for you.
When shift-tab is being pressed from within a modal dialog, the polyfill gets into an infinite loop, which completely freezes the Internet Explorer and requiring a browser restart.
Reproduction recipe:
<dialog>
natively, the polyfill will be used.The culprit is the handleFocus_ function. If
this.forwardTab_
isfalse
(which it is in case of shift-tab), it will calldocument.documentElement.focus()
. This is in turn being picked up bydocument.documentElement.addEventListener('focus', this.handleFocus_, true);
, which callsthis.handleFocus_
, resulting in an infinite loop.Edge seems to be unaffected though, because
document.documentElement.addEventListener('focus', this.handleFocus_, true);
won't actually fire when shift tabbing, I suspect that's because shift-tabbing might put the focus outside of thedocument.documentElement
.To show this in action, you can replace
document.documentElement.focus()
byThis will fill up the console log without crashing the browser.
A possible solution could be to insert
this.forwardTab_ = undefined;
right before callingdocument.documentElement.focus()
. This is already done in the keydown listener or when clicking on the overlay. This will result in the focus listener only firing twice: once originating from the focus shift from actually pressing the tab key, and once from the call todocument.documentElement.focus()
. In the second call,if (this.forwardTab_ === undefined) { return; } // move focus only from a tab key
will kill the loop.