mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 05:48:26 +00:00
Bug 1581040: handle late creation/re-creation of OuterDocAccessible for OOP iframe. r=yzen,nika
1. When creating a DocAccessibleParent for an embedded document in an OOP iframe, it's possible that the embedder accessible hasn't been set yet. This can occur if the iframe is initially hidden. Previously, we incorrectly set the document up as a top level document (e.g. tab document) in this case. Now, we set up the document as top level in its content process, set up the proxy, etc. The document will be added to its child document later when the embedder is set. 2. When setting the embedder accessible for an OOP iframe, check if the embedded DocAccessibleParent already exists. This can happen if an iframe is hidden and then shown or an iframe is reflowed by layout. If it already exists, add the embedded (child) document to its embedder. Differential Revision: https://phabricator.services.mozilla.com/D51357 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
73b429ab38
commit
28a8c82da1
@ -139,6 +139,7 @@ uint32_t DocAccessibleParent::AddSubtree(
|
||||
break;
|
||||
}
|
||||
}
|
||||
DebugOnly<bool> isOuterDoc = newProxy->ChildrenCount() == 1;
|
||||
|
||||
uint32_t accessibles = 1;
|
||||
uint32_t kids = newChild.ChildrenCount();
|
||||
@ -149,7 +150,7 @@ uint32_t DocAccessibleParent::AddSubtree(
|
||||
accessibles += consumed;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(newProxy->ChildrenCount() == kids);
|
||||
MOZ_ASSERT((isOuterDoc && kids == 0) || newProxy->ChildrenCount() == kids);
|
||||
|
||||
return accessibles;
|
||||
}
|
||||
|
@ -232,6 +232,17 @@ IPCResult BrowserBridgeParent::RecvSetEmbedderAccessible(
|
||||
#ifdef ACCESSIBILITY
|
||||
mEmbedderAccessibleDoc = static_cast<a11y::DocAccessibleParent*>(aDoc);
|
||||
mEmbedderAccessibleID = aID;
|
||||
if (auto embeddedBrowser = GetBrowserParent()) {
|
||||
a11y::DocAccessibleParent* childDocAcc =
|
||||
embeddedBrowser->GetTopLevelDocAccessible();
|
||||
if (childDocAcc && !childDocAcc->IsShutdown()) {
|
||||
// The embedded DocAccessibleParent has already been created. This can
|
||||
// happen if, for example, an iframe is hidden and then shown or
|
||||
// an iframe is reflowed by layout.
|
||||
mEmbedderAccessibleDoc->AddChildDoc(childDocAcc, aID,
|
||||
/* aCreating */ false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
# include "mozilla/a11y/DocAccessibleParent.h"
|
||||
# include "mozilla/a11y/Platform.h"
|
||||
# include "mozilla/a11y/ProxyAccessibleBase.h"
|
||||
# include "nsAccessibilityService.h"
|
||||
#endif
|
||||
#include "mozilla/BrowserElementParent.h"
|
||||
@ -1173,35 +1175,44 @@ mozilla::ipc::IPCResult BrowserParent::RecvPDocAccessibleConstructor(
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
a11y::DocAccessibleParent* embedderDoc;
|
||||
uint64_t embedderID;
|
||||
Tie(embedderDoc, embedderID) = doc->GetRemoteEmbedder();
|
||||
if (embedderDoc) {
|
||||
if (GetBrowserBridgeParent()) {
|
||||
// Iframe document rendered in a different process to its embedder.
|
||||
// In this case, we don't get aParentDoc and aParentID.
|
||||
MOZ_ASSERT(!aParentDoc && !aParentID);
|
||||
MOZ_ASSERT(embedderID);
|
||||
doc->SetTopLevelInContentProcess();
|
||||
# ifdef XP_WIN
|
||||
MOZ_ASSERT(!aDocCOMProxy.IsNull());
|
||||
RefPtr<IAccessible> proxy(aDocCOMProxy.Get());
|
||||
doc->SetCOMInterface(proxy);
|
||||
# endif
|
||||
mozilla::ipc::IPCResult added = embedderDoc->AddChildDoc(doc, embedderID);
|
||||
if (!added) {
|
||||
# ifdef DEBUG
|
||||
return added;
|
||||
# else
|
||||
return IPC_OK();
|
||||
# endif
|
||||
}
|
||||
a11y::ProxyCreated(
|
||||
doc, a11y::Interfaces::DOCUMENT | a11y::Interfaces::HYPERTEXT);
|
||||
# ifdef XP_WIN
|
||||
// This *must* be called after AddChildDoc because AddChildDoc
|
||||
// calls ProxyCreated and WrapperFor will fail before that.
|
||||
// This *must* be called after ProxyCreated because WrapperFor will fail
|
||||
// before that.
|
||||
a11y::AccessibleWrap* wrapper = a11y::WrapperFor(doc);
|
||||
MOZ_ASSERT(wrapper);
|
||||
wrapper->SetID(aMsaaID);
|
||||
# endif
|
||||
a11y::DocAccessibleParent* embedderDoc;
|
||||
uint64_t embedderID;
|
||||
Tie(embedderDoc, embedderID) = doc->GetRemoteEmbedder();
|
||||
// It's possible the embedder accessible hasn't been set yet; e.g.
|
||||
// a hidden iframe. In that case, embedderDoc will be null and this will
|
||||
// be handled when the embedder is set.
|
||||
if (embedderDoc) {
|
||||
MOZ_ASSERT(embedderID);
|
||||
mozilla::ipc::IPCResult added =
|
||||
embedderDoc->AddChildDoc(doc, embedderID,
|
||||
/* aCreating */ false);
|
||||
if (!added) {
|
||||
# ifdef DEBUG
|
||||
return added;
|
||||
# else
|
||||
return IPC_OK();
|
||||
# endif
|
||||
}
|
||||
}
|
||||
return IPC_OK();
|
||||
} else {
|
||||
// null aParentDoc means this document is at the top level in the child
|
||||
|
Loading…
x
Reference in New Issue
Block a user