зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1621517: Make nsIAccessible child retrieval work for OuterDocAccessibles with remote documents. r=yzen
This code (and an upcoming dependent patch) is currently behind a pref which is disabled by default, as there is uncertainty as to how it might impact the Dev Tools A11y Panel. The A11y Panel is currently a moving target due to ongoing refactor for Fission. This pref should be removed once that groundwork is complete and the impact has been verified. This patch also includes fixes to some ProxyAccessible methods which previously crashed when there was no parent, as is the case for top level documents. Without these fixes, the Dev Tools A11y Panel would crash the parent process. Differential Revision: https://phabricator.services.mozilla.com/D66354 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
75f2319471
Коммит
73a8260a74
|
@ -5,6 +5,9 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "AccessibleOrProxy.h"
|
||||
#include "mozilla/a11y/DocAccessibleParent.h"
|
||||
#include "mozilla/a11y/OuterDocAccessible.h"
|
||||
#include "mozilla/StaticPrefs_accessibility.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
@ -27,5 +30,19 @@ AccessibleOrProxy AccessibleOrProxy::Parent() const {
|
|||
return proxy->OuterDocOfRemoteBrowser();
|
||||
}
|
||||
|
||||
ProxyAccessible* AccessibleOrProxy::RemoteChildDoc() const {
|
||||
// This pref should be removed once the Dev Tools A11y Panel Fission
|
||||
// groundwork has landed and it has been verified that this doesn't cause
|
||||
// problems.
|
||||
if (!StaticPrefs::accessibility_xpcom_traverse_outerdoc() || IsProxy()) {
|
||||
return nullptr;
|
||||
}
|
||||
OuterDocAccessible* outerDoc = AsAccessible()->AsOuterDoc();
|
||||
if (!outerDoc) {
|
||||
return nullptr;
|
||||
}
|
||||
return outerDoc->RemoteChildDoc();
|
||||
}
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -53,6 +53,10 @@ class AccessibleOrProxy {
|
|||
return AsProxy()->ChildrenCount();
|
||||
}
|
||||
|
||||
if (RemoteChildDoc()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return AsAccessible()->ChildCount();
|
||||
}
|
||||
|
||||
|
@ -65,6 +69,11 @@ class AccessibleOrProxy {
|
|||
return AsProxy()->ChildAt(aIdx);
|
||||
}
|
||||
|
||||
ProxyAccessible* childDoc = RemoteChildDoc();
|
||||
if (childDoc && aIdx == 0) {
|
||||
return childDoc;
|
||||
}
|
||||
|
||||
return AsAccessible()->GetChildAt(aIdx);
|
||||
}
|
||||
|
||||
|
@ -76,17 +85,27 @@ class AccessibleOrProxy {
|
|||
return AsProxy()->FirstChild();
|
||||
}
|
||||
|
||||
ProxyAccessible* childDoc = RemoteChildDoc();
|
||||
if (childDoc) {
|
||||
return childDoc;
|
||||
}
|
||||
|
||||
return AsAccessible()->FirstChild();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the first child object.
|
||||
* Return the last child object.
|
||||
*/
|
||||
AccessibleOrProxy LastChild() {
|
||||
if (IsProxy()) {
|
||||
return AsProxy()->LastChild();
|
||||
}
|
||||
|
||||
ProxyAccessible* childDoc = RemoteChildDoc();
|
||||
if (childDoc) {
|
||||
return childDoc;
|
||||
}
|
||||
|
||||
return AsAccessible()->LastChild();
|
||||
}
|
||||
|
||||
|
@ -105,6 +124,11 @@ class AccessibleOrProxy {
|
|||
void SetBits(uintptr_t aBits) { mBits = aBits; }
|
||||
|
||||
private:
|
||||
/**
|
||||
* If this is an OuterDocAccessible, return the remote child document.
|
||||
*/
|
||||
ProxyAccessible* RemoteChildDoc() const;
|
||||
|
||||
uintptr_t mBits;
|
||||
static const uintptr_t IS_PROXY = 0x1;
|
||||
};
|
||||
|
|
|
@ -55,18 +55,30 @@ class ProxyAccessibleBase {
|
|||
return mChildren.Length() ? mChildren[mChildren.Length() - 1] : nullptr;
|
||||
}
|
||||
Derived* PrevSibling() const {
|
||||
size_t idx = IndexInParent();
|
||||
int32_t idx = IndexInParent();
|
||||
if (idx == -1) {
|
||||
return nullptr; // No parent.
|
||||
}
|
||||
return idx > 0 ? Parent()->mChildren[idx - 1] : nullptr;
|
||||
}
|
||||
Derived* NextSibling() const {
|
||||
size_t idx = IndexInParent();
|
||||
return idx + 1 < Parent()->mChildren.Length() ? Parent()->mChildren[idx + 1]
|
||||
: nullptr;
|
||||
int32_t idx = IndexInParent();
|
||||
if (idx == -1) {
|
||||
return nullptr; // No parent.
|
||||
}
|
||||
MOZ_ASSERT(idx >= 0);
|
||||
size_t newIdx = idx + 1;
|
||||
return newIdx < Parent()->mChildren.Length() ? Parent()->mChildren[newIdx]
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
// XXX evaluate if this is fast enough.
|
||||
size_t IndexInParent() const {
|
||||
return Parent()->mChildren.IndexOf(static_cast<const Derived*>(this));
|
||||
int32_t IndexInParent() const {
|
||||
Derived* parent = Parent();
|
||||
if (!parent) {
|
||||
return -1;
|
||||
}
|
||||
return parent->mChildren.IndexOf(static_cast<const Derived*>(this));
|
||||
}
|
||||
uint32_t EmbeddedChildCount() const;
|
||||
int32_t IndexOfEmbeddedChild(const Derived* aChild);
|
||||
|
|
|
@ -184,6 +184,11 @@
|
|||
value: false
|
||||
mirror: always
|
||||
|
||||
- name: accessibility.xpcom.traverse_outerdoc
|
||||
type: bool
|
||||
value: false
|
||||
mirror: always
|
||||
|
||||
#ifdef ANDROID
|
||||
#---------------------------------------------------------------------------
|
||||
# Prefs starting with "android."
|
||||
|
|
Загрузка…
Ссылка в новой задаче