Bug 1755604: Add Accessible::IsBefore/IsAncestorOf. r=eeejay

Differential Revision: https://phabricator.services.mozilla.com/D138743
This commit is contained in:
James Teh 2022-02-18 09:49:02 +00:00
Родитель ede3f249a7
Коммит 4181fc7eb2
3 изменённых файлов: 51 добавлений и 33 удалений

Просмотреть файл

@ -375,39 +375,7 @@ bool TextLeafPoint::operator<(const TextLeafPoint& aPoint) const {
if (mAcc == aPoint.mAcc) {
return mOffset < aPoint.mOffset;
}
// Build the chain of parents.
Accessible* thisP = mAcc;
Accessible* otherP = aPoint.mAcc;
AutoTArray<Accessible*, 30> thisParents, otherParents;
do {
thisParents.AppendElement(thisP);
thisP = thisP->Parent();
} while (thisP);
do {
otherParents.AppendElement(otherP);
otherP = otherP->Parent();
} while (otherP);
// Find where the parent chain differs.
uint32_t thisPos = thisParents.Length(), otherPos = otherParents.Length();
for (uint32_t len = std::min(thisPos, otherPos); len > 0; --len) {
Accessible* thisChild = thisParents.ElementAt(--thisPos);
Accessible* otherChild = otherParents.ElementAt(--otherPos);
if (thisChild != otherChild) {
return thisChild->IndexInParent() < otherChild->IndexInParent();
}
}
// If the ancestries are the same length (both thisPos and otherPos are 0),
// we should have returned by now.
MOZ_ASSERT(thisPos != 0 || otherPos != 0);
// At this point, one of the ancestries is a superset of the other, so one of
// thisPos or otherPos should be 0.
MOZ_ASSERT(thisPos != otherPos);
// If the other Accessible is deeper than this one (otherPos > 0), this
// Accessible comes before the other.
return otherPos > 0;
return mAcc->IsBefore(aPoint.mAcc);
}
bool TextLeafPoint::IsEmptyLastLine() const {

Просмотреть файл

@ -33,6 +33,41 @@ void Accessible::StaticAsserts() const {
"Accessible::mGenericType was oversized by eLastAccGenericType!");
}
bool Accessible::IsBefore(const Accessible* aAcc) const {
// Build the chain of parents.
const Accessible* thisP = this;
const Accessible* otherP = aAcc;
AutoTArray<const Accessible*, 30> thisParents, otherParents;
do {
thisParents.AppendElement(thisP);
thisP = thisP->Parent();
} while (thisP);
do {
otherParents.AppendElement(otherP);
otherP = otherP->Parent();
} while (otherP);
// Find where the parent chain differs.
uint32_t thisPos = thisParents.Length(), otherPos = otherParents.Length();
for (uint32_t len = std::min(thisPos, otherPos); len > 0; --len) {
const Accessible* thisChild = thisParents.ElementAt(--thisPos);
const Accessible* otherChild = otherParents.ElementAt(--otherPos);
if (thisChild != otherChild) {
return thisChild->IndexInParent() < otherChild->IndexInParent();
}
}
// If the ancestries are the same length (both thisPos and otherPos are 0),
// we should have returned by now.
MOZ_ASSERT(thisPos != 0 || otherPos != 0);
// At this point, one of the ancestries is a superset of the other, so one of
// thisPos or otherPos should be 0.
MOZ_ASSERT(thisPos != otherPos);
// If the other Accessible is deeper than this one (otherPos > 0), this
// Accessible comes before the other.
return otherPos > 0;
}
const nsRoleMapEntry* Accessible::ARIARoleMap() const {
return aria::GetRoleMapFromIndex(mRoleMapEntryIndex);
}

Просмотреть файл

@ -101,6 +101,21 @@ class Accessible {
return childCount ? ChildAt(childCount - 1) : nullptr;
}
/**
* Return true if this Accessible is before another Accessible in the tree.
*/
bool IsBefore(const Accessible* aAcc) const;
bool IsAncestorOf(const Accessible* aAcc) const {
for (const Accessible* parent = aAcc->Parent(); parent;
parent = parent->Parent()) {
if (parent == this) {
return true;
}
}
return false;
}
/**
* Used by ChildAtPoint() method to get direct or deepest child at point.
*/