Bug 1769586 - P3: Rename IDRefsIterator AssociatedElementsIterator. r=Jamie

The iterator uses both explicitly set element attributes and content attributes
with IDs to iterate over all associated elements

Differential Revision: https://phabricator.services.mozilla.com/D215688
This commit is contained in:
Eitan Isaacson 2024-09-15 22:39:53 +00:00
Родитель 5a1e8aa269
Коммит cd4a3691f1
8 изменённых файлов: 55 добавлений и 47 удалений

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

@ -243,11 +243,12 @@ LocalAccessible* XULDescriptionIterator::Next() {
}
////////////////////////////////////////////////////////////////////////////////
// IDRefsIterator
// AssociatedElementsIterator
////////////////////////////////////////////////////////////////////////////////
IDRefsIterator::IDRefsIterator(DocAccessible* aDoc, nsIContent* aContent,
nsAtom* aIDRefsAttr)
AssociatedElementsIterator::AssociatedElementsIterator(DocAccessible* aDoc,
nsIContent* aContent,
nsAtom* aIDRefsAttr)
: mContent(aContent), mDoc(aDoc), mCurrIdx(0), mElemIdx(0) {
if (mContent->IsElement()) {
mContent->AsElement()->GetAttr(aIDRefsAttr, mIDs);
@ -259,7 +260,7 @@ IDRefsIterator::IDRefsIterator(DocAccessible* aDoc, nsIContent* aContent,
}
}
const nsDependentSubstring IDRefsIterator::NextID() {
const nsDependentSubstring AssociatedElementsIterator::NextID() {
for (; mCurrIdx < mIDs.Length(); mCurrIdx++) {
if (!NS_IsAsciiWhitespace(mIDs[mCurrIdx])) break;
}
@ -274,7 +275,7 @@ const nsDependentSubstring IDRefsIterator::NextID() {
return Substring(mIDs, idStartIdx, mCurrIdx++ - idStartIdx);
}
nsIContent* IDRefsIterator::NextElem() {
nsIContent* AssociatedElementsIterator::NextElem() {
while (true) {
const nsDependentSubstring id = NextID();
if (id.IsEmpty()) break;
@ -293,8 +294,8 @@ nsIContent* IDRefsIterator::NextElem() {
return nullptr;
}
dom::Element* IDRefsIterator::GetElem(nsIContent* aContent,
const nsAString& aID) {
dom::Element* AssociatedElementsIterator::GetElem(nsIContent* aContent,
const nsAString& aID) {
// Get elements in DOM tree by ID attribute if this is an explicit content.
// In case of bound element check its anonymous subtree.
if (!aContent->IsInNativeAnonymousSubtree()) {
@ -310,11 +311,12 @@ dom::Element* IDRefsIterator::GetElem(nsIContent* aContent,
return nullptr;
}
dom::Element* IDRefsIterator::GetElem(const nsDependentSubstring& aID) {
dom::Element* AssociatedElementsIterator::GetElem(
const nsDependentSubstring& aID) {
return GetElem(mContent, aID);
}
LocalAccessible* IDRefsIterator::Next() {
LocalAccessible* AssociatedElementsIterator::Next() {
nsIContent* nextEl = nullptr;
while ((nextEl = NextElem())) {
LocalAccessible* acc = mDoc->GetAccessible(nextEl);

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

@ -211,11 +211,11 @@ class XULDescriptionIterator : public AccIterable {
* iterate through IDs, elements, or accessibles moves iterator to next
* position.
*/
class IDRefsIterator : public AccIterable {
class AssociatedElementsIterator : public AccIterable {
public:
IDRefsIterator(DocAccessible* aDoc, nsIContent* aContent,
nsAtom* aIDRefsAttr);
virtual ~IDRefsIterator() {}
AssociatedElementsIterator(DocAccessible* aDoc, nsIContent* aContent,
nsAtom* aIDRefsAttr);
virtual ~AssociatedElementsIterator() {}
/**
* Return next ID.
@ -237,9 +237,9 @@ class IDRefsIterator : public AccIterable {
virtual LocalAccessible* Next() override;
private:
IDRefsIterator();
IDRefsIterator(const IDRefsIterator&);
IDRefsIterator operator=(const IDRefsIterator&);
AssociatedElementsIterator();
AssociatedElementsIterator(const AssociatedElementsIterator&);
AssociatedElementsIterator operator=(const AssociatedElementsIterator&);
nsString mIDs;
nsIContent* mContent;

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

@ -340,7 +340,7 @@ UniquePtr<AccIterable> CachedTableCellAccessible::GetExplicitHeadersIterator() {
}
}
} else if (LocalAccessible* localAcc = mAcc->AsLocal()) {
return MakeUnique<IDRefsIterator>(
return MakeUnique<AssociatedElementsIterator>(
localAcc->Document(), localAcc->GetContent(), nsGkAtoms::headers);
}
return nullptr;

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

@ -99,7 +99,8 @@ nsresult nsTextEquivUtils::GetTextEquivFromIDRefs(
if (!content) return NS_OK;
nsIContent* refContent = nullptr;
IDRefsIterator iter(aAccessible->Document(), content, aIDRefsAttr);
AssociatedElementsIterator iter(aAccessible->Document(), content,
aIDRefsAttr);
while ((refContent = iter.NextElem())) {
if (!aTextEquiv.IsEmpty()) aTextEquiv += ' ';

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

@ -1802,7 +1802,7 @@ void DocAccessible::AddDependentIDsFor(LocalAccessible* aRelProvider,
}
}
IDRefsIterator iter(this, relProviderEl, relAttr);
AssociatedElementsIterator iter(this, relProviderEl, relAttr);
while (true) {
const nsDependentSubstring id = iter.NextID();
if (id.IsEmpty()) break;
@ -1845,7 +1845,7 @@ void DocAccessible::RemoveDependentIDsFor(LocalAccessible* aRelProvider,
nsStaticAtom* relAttr = kRelationAttrs[idx];
if (aRelAttr && aRelAttr != kRelationAttrs[idx]) continue;
IDRefsIterator iter(this, relProviderElm, relAttr);
AssociatedElementsIterator iter(this, relProviderElm, relAttr);
while (true) {
const nsDependentSubstring id = iter.NextID();
if (id.IsEmpty()) break;
@ -2459,7 +2459,7 @@ void DocAccessible::DoARIAOwnsRelocation(LocalAccessible* aOwner) {
nsTArray<RefPtr<LocalAccessible>>* owned =
mARIAOwnsHash.GetOrInsertNew(aOwner);
IDRefsIterator iter(this, aOwner->Elm(), nsGkAtoms::aria_owns);
AssociatedElementsIterator iter(this, aOwner->Elm(), nsGkAtoms::aria_owns);
uint32_t idx = 0;
while (nsIContent* childEl = iter.NextElem()) {
LocalAccessible* child = GetAccessible(childEl);

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

@ -196,7 +196,8 @@ already_AddRefed<nsIURI> ImageAccessible::GetLongDescURI() const {
DocAccessible* document = Document();
if (document) {
IDRefsIterator iter(document, mContent, nsGkAtoms::aria_describedby);
AssociatedElementsIterator iter(document, mContent,
nsGkAtoms::aria_describedby);
while (nsIContent* target = iter.NextElem()) {
if ((target->IsHTMLElement(nsGkAtoms::a) ||
target->IsHTMLElement(nsGkAtoms::area)) &&

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

@ -1416,7 +1416,7 @@ void LocalAccessible::DOMAttributeChanged(int32_t aNameSpaceID,
if (aAttribute == nsGkAtoms::aria_label) {
// A valid aria-labelledby would take precedence so an aria-label change
// won't change the name.
IDRefsIterator iter(mDoc, elm, nsGkAtoms::aria_labelledby);
AssociatedElementsIterator iter(mDoc, elm, nsGkAtoms::aria_labelledby);
if (!iter.NextElem()) {
mDoc->FireDelayedEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this);
}
@ -1426,7 +1426,7 @@ void LocalAccessible::DOMAttributeChanged(int32_t aNameSpaceID,
if (aAttribute == nsGkAtoms::aria_description) {
// A valid aria-describedby would take precedence so an aria-description
// change won't change the description.
IDRefsIterator iter(mDoc, elm, nsGkAtoms::aria_describedby);
AssociatedElementsIterator iter(mDoc, elm, nsGkAtoms::aria_describedby);
if (!iter.NextElem()) {
mDoc->FireDelayedEvent(nsIAccessibleEvent::EVENT_DESCRIPTION_CHANGE,
this);
@ -1442,7 +1442,7 @@ void LocalAccessible::DOMAttributeChanged(int32_t aNameSpaceID,
// The subtrees of the new aria-describedby targets might be used to
// compute the description for this. Therefore, we need to set
// the eHasDescriptionDependent flag on all Accessibles in these subtrees.
IDRefsIterator iter(mDoc, elm, nsGkAtoms::aria_describedby);
AssociatedElementsIterator iter(mDoc, elm, nsGkAtoms::aria_describedby);
while (LocalAccessible* target = iter.Next()) {
target->ModifySubtreeContextFlags(eHasDescriptionDependent, true);
}
@ -1461,7 +1461,7 @@ void LocalAccessible::DOMAttributeChanged(int32_t aNameSpaceID,
// The subtrees of the new aria-labelledby targets might be used to
// compute the name for this. Therefore, we need to set
// the eHasNameDependent flag on all Accessibles in these subtrees.
IDRefsIterator iter(mDoc, elm, nsGkAtoms::aria_labelledby);
AssociatedElementsIterator iter(mDoc, elm, nsGkAtoms::aria_labelledby);
while (LocalAccessible* target = iter.Next()) {
target->ModifySubtreeContextFlags(eHasNameDependent, true);
}
@ -2173,8 +2173,8 @@ Relation LocalAccessible::RelationByType(RelationType aType) const {
// defined on.
switch (aType) {
case RelationType::LABELLED_BY: {
Relation rel(
new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_labelledby));
Relation rel(new AssociatedElementsIterator(mDoc, mContent,
nsGkAtoms::aria_labelledby));
if (mContent->IsHTMLElement()) {
rel.AppendIter(new HTMLLabelIterator(Document(), this));
}
@ -2187,15 +2187,16 @@ Relation LocalAccessible::RelationByType(RelationType aType) const {
Relation rel(new RelatedAccIterator(Document(), mContent,
nsGkAtoms::aria_labelledby));
if (mContent->IsXULElement(nsGkAtoms::label)) {
rel.AppendIter(new IDRefsIterator(mDoc, mContent, nsGkAtoms::control));
rel.AppendIter(
new AssociatedElementsIterator(mDoc, mContent, nsGkAtoms::control));
}
return rel;
}
case RelationType::DESCRIBED_BY: {
Relation rel(
new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_describedby));
Relation rel(new AssociatedElementsIterator(mDoc, mContent,
nsGkAtoms::aria_describedby));
if (mContent->IsXULElement()) {
rel.AppendIter(new XULDescriptionIterator(Document(), mContent));
}
@ -2211,7 +2212,8 @@ Relation LocalAccessible::RelationByType(RelationType aType) const {
// which only affects accessibility, by allowing the description to be
// tied to a control.
if (mContent->IsXULElement(nsGkAtoms::description)) {
rel.AppendIter(new IDRefsIterator(mDoc, mContent, nsGkAtoms::control));
rel.AppendIter(
new AssociatedElementsIterator(mDoc, mContent, nsGkAtoms::control));
}
return rel;
@ -2290,15 +2292,15 @@ Relation LocalAccessible::RelationByType(RelationType aType) const {
nsGkAtoms::aria_controls));
case RelationType::CONTROLLER_FOR: {
Relation rel(
new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_controls));
Relation rel(new AssociatedElementsIterator(mDoc, mContent,
nsGkAtoms::aria_controls));
rel.AppendIter(new HTMLOutputIterator(Document(), mContent));
return rel;
}
case RelationType::FLOWS_TO:
return Relation(
new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_flowto));
return Relation(new AssociatedElementsIterator(mDoc, mContent,
nsGkAtoms::aria_flowto));
case RelationType::FLOWS_FROM:
return Relation(
@ -2450,8 +2452,8 @@ Relation LocalAccessible::RelationByType(RelationType aType) const {
if (mContent->IsElement() &&
nsAccUtils::HasARIAAttr(mContent->AsElement(),
nsGkAtoms::aria_details)) {
return Relation(
new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_details));
return Relation(new AssociatedElementsIterator(
mDoc, mContent, nsGkAtoms::aria_details));
}
if (LocalAccessible* target = GetPopoverTargetDetailsRelation()) {
return Relation(target);
@ -2478,8 +2480,8 @@ Relation LocalAccessible::RelationByType(RelationType aType) const {
}
case RelationType::ERRORMSG:
return Relation(
new IDRefsIterator(mDoc, mContent, nsGkAtoms::aria_errormessage));
return Relation(new AssociatedElementsIterator(
mDoc, mContent, nsGkAtoms::aria_errormessage));
case RelationType::ERRORMSG_FOR:
return Relation(
@ -3990,7 +3992,7 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
}
if (mContent->AsElement()->HasAttr(nsGkAtoms::headers)) {
nsTArray<uint64_t> headers;
IDRefsIterator iter(mDoc, mContent, nsGkAtoms::headers);
AssociatedElementsIterator iter(mDoc, mContent, nsGkAtoms::headers);
while (LocalAccessible* cell = iter.Next()) {
if (cell->IsTableCell()) {
headers.AppendElement(cell->ID());
@ -4061,11 +4063,12 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
// relation, so using RelationByType here is fine.
rel = RelationByType(RelationType::DETAILS);
} else {
// We use an IDRefsIterator here instead of calling RelationByType
// directly because we only want to cache explicit relations. Implicit
// relations (e.g. LABEL_FOR exposed on the target of aria-labelledby)
// will be computed and stored separately in the parent process.
rel.AppendIter(new IDRefsIterator(mDoc, mContent, relAtom));
// We use an AssociatedElementsIterator here instead of calling
// RelationByType directly because we only want to cache explicit
// relations. Implicit relations (e.g. LABEL_FOR exposed on the target
// of aria-labelledby) will be computed and stored separately in the
// parent process.
rel.AppendIter(new AssociatedElementsIterator(mDoc, mContent, relAtom));
}
while (LocalAccessible* acc = rel.LocalNext()) {

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

@ -88,7 +88,8 @@ void HTMLLabelAccessible::ActionNameAt(uint8_t aIndex, nsAString& aName) {
Relation HTMLOutputAccessible::RelationByType(RelationType aType) const {
Relation rel = AccessibleWrap::RelationByType(aType);
if (aType == RelationType::CONTROLLED_BY) {
rel.AppendIter(new IDRefsIterator(mDoc, mContent, nsGkAtoms::_for));
rel.AppendIter(
new AssociatedElementsIterator(mDoc, mContent, nsGkAtoms::_for));
}
return rel;