diff --git a/accessible/ipc/RemoteAccessibleBase.cpp b/accessible/ipc/RemoteAccessibleBase.cpp index eedd0cffa197..acf73a1481c8 100644 --- a/accessible/ipc/RemoteAccessibleBase.cpp +++ b/accessible/ipc/RemoteAccessibleBase.cpp @@ -630,6 +630,22 @@ LayoutDeviceIntRect RemoteAccessibleBase::Bounds() const { template Relation RemoteAccessibleBase::RelationByType( RelationType aType) const { + // We are able to handle some relations completely in the + // parent process, without the help of the cache. Those + // relations are enumerated here. Other relations, whose + // types are stored in kRelationTypeAtoms, are processed + // below using the cache. + if (aType == RelationType::CONTAINING_TAB_PANE) { + if (dom::CanonicalBrowsingContext* cbc = mDoc->GetBrowsingContext()) { + if (dom::CanonicalBrowsingContext* topCbc = cbc->Top()) { + if (dom::BrowserParent* bp = topCbc->GetBrowserParent()) { + return Relation(bp->GetTopLevelDocAccessible()); + } + } + } + return Relation(); + } + Relation rel; if (!mCachedFields) { return rel; diff --git a/accessible/tests/browser/e10s/browser_caching_relations.js b/accessible/tests/browser/e10s/browser_caching_relations.js index b3a50737712b..598e48a18d95 100644 --- a/accessible/tests/browser/e10s/browser_caching_relations.js +++ b/accessible/tests/browser/e10s/browser_caching_relations.js @@ -322,3 +322,33 @@ addAccessibleTask( }, { chrome: true, iframe: true, remoteIframe: true } ); + +/** + * Test CONTAINING_TAB_PANE + */ +addAccessibleTask( + `

hello world

`, + async function(browser, primaryDocAcc, secondaryDocAcc) { + // The CONTAINING_TAB_PANE of any acc should be the top level + // content document. If this test runs in an iframe, + // the test harness will pass in doc accs for both the + // iframe (primaryDocAcc) and the top level remote + // browser (secondaryDocAcc). We should use the second + // one. + // If this is not in an iframe, we'll only get + // a single docAcc (primaryDocAcc) which refers to + // the top level content doc. + const topLevelDoc = secondaryDocAcc ? secondaryDocAcc : primaryDocAcc; + await testCachedRelation( + findAccessibleChildByID(primaryDocAcc, "p"), + RELATION_CONTAINING_TAB_PANE, + topLevelDoc + ); + }, + { + chrome: true, + topLevel: isCacheEnabled, + iframe: isCacheEnabled, + remoteIframe: isCacheEnabled, + } +); diff --git a/accessible/windows/msaa/MsaaAccessible.cpp b/accessible/windows/msaa/MsaaAccessible.cpp index 02565e40e820..914c39513d93 100644 --- a/accessible/windows/msaa/MsaaAccessible.cpp +++ b/accessible/windows/msaa/MsaaAccessible.cpp @@ -795,6 +795,10 @@ ITypeInfo* MsaaAccessible::GetTI(LCID lcid) { /* static */ MsaaAccessible* MsaaAccessible::GetFrom(Accessible* aAcc) { + if (!aAcc) { + return nullptr; + } + if (RemoteAccessible* remoteAcc = aAcc->AsRemote()) { return reinterpret_cast(remoteAcc->GetWrapper()); } diff --git a/accessible/windows/msaa/ServiceProvider.cpp b/accessible/windows/msaa/ServiceProvider.cpp index decc5c5d3e9c..98542a230cf5 100644 --- a/accessible/windows/msaa/ServiceProvider.cpp +++ b/accessible/windows/msaa/ServiceProvider.cpp @@ -17,6 +17,7 @@ #include "mozilla/a11y/DocAccessibleChild.h" #include "mozilla/Preferences.h" +#include "mozilla/StaticPrefs_accessibility.h" #include "ISimpleDOM.h" @@ -62,7 +63,7 @@ ServiceProvider::QueryService(REFGUID aGuidService, REFIID aIID, 0x3571, 0x4d8f, {0x95, 0x21, 0x07, 0xed, 0x28, 0xfb, 0x07, 0x2e}}; - if (aGuidService == SID_IAccessibleContentDocument && localAcc) { + if (aGuidService == SID_IAccessibleContentDocument) { if (aIID != IID_IAccessible) return E_NOINTERFACE; // If acc is within an OOP iframe document, the top level document @@ -83,13 +84,16 @@ ServiceProvider::QueryService(REFGUID aGuidService, REFIID aIID, } } - Relation rel = localAcc->RelationByType(RelationType::CONTAINING_TAB_PANE); - AccessibleWrap* tabDoc = static_cast(rel.LocalNext()); - if (!tabDoc) return E_NOINTERFACE; + MOZ_ASSERT( + acc->IsLocal() || StaticPrefs::accessibility_cache_enabled_AtStartup(), + "We should only handle remote accs here if the cache is on!"); + Relation rel = acc->RelationByType(RelationType::CONTAINING_TAB_PANE); + RefPtr next = MsaaAccessible::GetFrom(rel.Next()); + if (!next) { + return E_NOINTERFACE; + } - RefPtr result; - tabDoc->GetNativeInterface(getter_AddRefs(result)); - result.forget(aInstancePtr); + next.forget(aInstancePtr); return S_OK; }