Support for out-of-process iframes in Firefox#9672
Conversation
…t instead of accChild on the document. This was changed to use accChild on the document in the theoretical hope that it might be slightly faster, since it doesn't need to go via the parent process. However, this was never proved to be a performance benefit in real terms. In Firefox, when an iframe document is rendered in a separate process to its embedder, the embedder has no knowledge of children in the embedded document and cannot communicate with the embedded document at all. This means that accChild for accessibles in the embedded document fails. The root accessible is in the parent process and can fetch children in all content documents, so using AccessibleObjectFromEvent works as expected.
…me(s). In Firefox, when an iframe document is rendered in a separate process to its embedder, accChild for accessibles in the embedded document fails. If this is the case, we can get the embedder iframe and try accChild with the iframe's id. There can be nested out-of-process iframes, so we keep trying this until there are no more embedders in the hierarchy (or until we hit the buffer's root id).
|
I take it that out-of-process support is already available in Firefox nightlies? is there anything special one must do to enable these, or will any iFrames do this by default? |
|
It's in nightly, but currently super early testing stages. It requires both
a pref to be set and an attribute on the iframe. Happy to provide specific
details privately; this definitely isn't ready for general public testing.
If you'd prefer, we could hold off on getting this into master until the
Firefox work is further along.
|
michaelDCurran
left a comment
There was a problem hiding this comment.
All good. But I'll leave this unmerged until this feature is a little more public.
|
Currently in Firefox nightly 71, if I enable fission.autostart, restart nightly and go to https://www.nvaccess.org/ |
|
Tabbing to the Youtube frame however does, in NVDA master at least, cause a new browseMode document to be created for just the youtube frame. I have not specifically tested with this pr yet. |
|
Hmm. If you press NVDA+f5, do you see the Youtube iframe show up? If so,
that suggests we're not firing an event we should be firing. I thought I'd
fixed that, but it's possible I missed something.
As for the new browse mode document being rendered when you focus the
iframe document, that's essentially what this PR fixes.
|
|
No, refreshing does not improve things. It really looks like it is not
accessible from the root document's tree at all. Not in browseMode, not
in object navigation.
In fact, turning off simple review mode, I can find the frame, but it
has no children. nav.children is empty and
nav.IAccessibleObject.accChild(1) fails. Yet,
nav.IAccessibleObject.accChildCount is 1.
Testing with this pr did not improve the situation.
|
|
Oh. I think I know what's going on here. I bet the document inside the
iframe (the one you can tab to) also has a null accParent. I'll look into
it.
|
|
Yep, accParent on the Youtube document is NULL.
|
|
This turned out to be a lot more difficult to track down than I thought. It was actually not the problem I originally thought it was. Anyway, it's now fixed; see https://bugzilla.mozilla.org/show_bug.cgi?id=1581441. I also fixed another bug that could cause similar behaviour, but was very different behind the scenes; see https://bugzilla.mozilla.org/show_bug.cgi?id=1581040. @michaelDCurran, would you mind taking another look at this? Thanks. |
Link to issue number:
None.
Summary of the issue:
Firefox is adding support for out-of-process iframes; i.e. iframes rendered in a separate process to their embedder document. For an out-of-process iframe, the embedder has no knowledge of children in the embedded document and cannot communicate with the embedded document at all. This means that accChild for accessibles in the embedded document fails. This requires some changes to the gecko_ia2 virtual buffer.
Description of how this pull request fixes the issue:
In the gecko_ia2 vbuf:
__contains__: If accChild fails, get the embedder iframe and try accChild with the iframe's id. There can be nested out-of-process iframes, so we keep trying this until there are no more embedders in the hierarchy (or until we hit the buffer's root id).Testing performed:
ti1 = nav.treeInterceptor.nav in ti1is True andnav in ti2is False.nav in ti1is False andnav in ti2is True.Also used a build with this change for a while doing some daily browsing with Gmail, GitHub, etc.
Known issues with pull request:
There will be some additional COM calls for objects in out-of-process iframes. However, there don't tend to be many levels of nested iframes, so I don't anticipate this will be a significant issue in reality.
Other avenues explored:
Originally, I tried having
__contains__check the buffer itself to see if it contains the node in question. This also had to check ancestors (limited at an arbitrary number for performance) just in case the buffer hasn't caught up yet or in case we chose not to render descendants in the buffer.Change log entry:
Changes:
- Support for out-of-process iframes in Mozilla Firefox.