Skip to content
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

Tab into iframe #23

Closed
ulfbrehmer opened this issue Mar 9, 2018 · 5 comments
Closed

Tab into iframe #23

ulfbrehmer opened this issue Mar 9, 2018 · 5 comments

Comments

@ulfbrehmer
Copy link

Tabbable does not select iframes it as candidate, and thus it is impossible to tab into them. This is needed in some scenarios, for instance when you have a reCaptcha (which is constructed as an iframe) in a form. One solution could be to just add 'iframe' to the candidateSelectors, but perhaps there is some issues with that?

@davidtheclark
Copy link
Collaborator

One solution could be to just add 'iframe' to the candidateSelectors, but perhaps there is some issues with that?

I think the issue with that is that you do not in fact tab to the iframe elements: you can tab to elements inside the iframe.

We might have to document this as a caveat and leave it at that — unless there's some clever way to reliably make this work. My understanding is that the JS in the parent document is typically not allowed to access the DOM of the iframe, unless they share the same domain. If they do share the same domain, iframe.contentWindow could be used.

I don't plan to work on this myself but am open to PRs, if there's a simple approach to this.

@ulfbrehmer
Copy link
Author

Yes, the issue is to tab into elements inside the iframe. I am actually using another one of your projects, namely react-aria-modal, and when I use an iframe component inside a dialog, I never get to tab into the iframe (e.g. to check a checkbox). But if I add 'iframe' to the candidateSelectors in tabbable, I'm allowed to tab into the elements in the iframe.

@davidtheclark
Copy link
Collaborator

But if I add 'iframe' to the candidateSelectors in tabbable, I'm allowed to tab into the elements in the iframe.

That's interesting ... I wonder what's going on there?

react-aria-modal uses focus-trap to trap focus inside the modal, and focus trap uses this library, tabbable, behind the scenes. I think this issue is similar to focus-trap/focus-trap#39, because elements with shadow DOM seem to have the same problem as iframes: tabbable doesn't recognize that they can contain tabbable elements, so focus-trap skips over them.

One possibility would be to change the way focus-trap controls tabbing. Right now, it hijacks the Tab key and manually chooses the next element to receive focus:
https://github.com/davidtheclark/focus-trap/blob/ef4da4f7b43f42d33487bcffb7deefd434a9ff50/index.js#L206-L226

We could change that so it only hijacks Tab if the focus change would end up leaving the focus trap. This should allow users within focus-traps to tab into an iframe or shadow DOM as long as there's a regular tabbable element on either side of it. That caveat is a weird one, though. I'm not sure it's reasonable to build in such a weird caveat.

So ... I don't know what to do! Open to solutions.

@valdrinkoshi
Copy link

Regarding Shadow DOM, collecting the list of tabbables is doable (e.g. see https://github.com/PolymerElements/iron-overlay-behavior/blob/master/iron-focusables-helper.html), but the hard part is keeping the correct order, as in Shadow DOM v1 tab order is affected by the order of distribution.
E.g. the correct ordering of tabbable nodes in this example is [#inputA, #inputB]. Even if #inputB has tabindex = 1, it is distributed in #slotB which comes after #slotA.

<my-element>

  #shadowRoot
    <slot id="slotA" name="a">
    <slot id="slotB" name="b">
  /#shadowRoot

  <input id="inputA" slot="a">
  <input id="inputB" slot="b" tabindex="1">

</my-element>

@davidtheclark
Copy link
Collaborator

I added some notes in the readme about this situation. If anyone knows how to improve it reliably and would like to submit a PR, please do!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants