Skip to content

Commit 8faede9

Browse files
author
Sandor Molnar
committed
Revert "Bug 1981349 - Add referenceTarget support for label/for, label wrapped and output/for. r=credential-management-reviewers,webidl,dimi,Jamie,smaug" for causing accessibility crashes (bug 2008970)
This reverts commit d46abe6. Revert "Bug 1981346 - Add referenceTarget support for the form attribute. r=credential-management-reviewers,webidl,dimi,Jamie,smaug" This reverts commit df11a46. Revert "Bug 1981345 - Implement referenceTarget support for multiple element attributes. r=dom-core,Jamie,smaug" This reverts commit 89cc779. Revert "Bug 1984685 - Refactor: consistently return Maybe<nsTArray<RefPtr<Element>>> when getting attr-associated elements, and key AttrRelProviders on nsAtom rather than nsString. r=dom-core,morgan,Jamie,smaug" This reverts commit 33130e7. Revert "Bug 1981344 - Implement referenceTarget support for single-element attributes. r=dom-core,credential-management-reviewers,webidl,layout-reviewers,emilio,keithamus,smaug,mtigley" This reverts commit d6440c4. Revert "Bug 1983766 - Split single element attribute getters into bindings/internals versions. r=dom-core,credential-management-reviewers,webidl,layout-reviewers,smaug,keithamus,jwatt,mtigley" This reverts commit 83b70e0. Revert "Bug 1989323 - Make `referenceTarget` IDL attributes on ShadowRoot, HTMLTemplateElement and ShadowRootInit nullable. r=dom-core,webidl,saschanaz,smaug" This reverts commit 3a0b291.
1 parent b77ea87 commit 8faede9

File tree

92 files changed

+5661
-2382
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+5661
-2382
lines changed

accessible/base/AccIterator.cpp

Lines changed: 111 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@
1414
#include "mozilla/a11y/DocAccessibleParent.h"
1515
#include "mozilla/dom/DocumentOrShadowRoot.h"
1616
#include "mozilla/dom/Element.h"
17-
#include "mozilla/dom/ElementInternals.h"
1817
#include "mozilla/dom/HTMLLabelElement.h"
19-
#include "mozilla/dom/TreeOrderedArrayInlines.h"
2018

2119
using namespace mozilla;
2220
using namespace mozilla::a11y;
@@ -78,76 +76,69 @@ RelatedAccIterator::RelatedAccIterator(DocAccessible* aDocument,
7876
nsAtom* aRelAttr)
7977
: mDocument(aDocument),
8078
mDependentContent(aDependentContent),
81-
mRelAttr(aRelAttr) {}
82-
83-
void RelatedAccIterator::Initialize() {
84-
nsIContent* content = mDependentContent;
85-
dom::DocumentOrShadowRoot* root =
86-
content->GetUncomposedDocOrConnectedShadowRoot();
87-
88-
while (root) {
89-
if (nsAtom* id = content->GetID()) {
90-
DocAccessible::AttrRelProviders* idProviders =
91-
mDocument->GetRelProviders(content->AsElement(), id);
92-
93-
if (idProviders) {
94-
for (auto& provider : *idProviders) {
95-
if (mRelAttr && provider->mRelAttr != mRelAttr) {
96-
continue;
97-
}
98-
99-
mRelatedNodes.Insert(*provider->mContent);
100-
}
101-
}
102-
}
103-
if (auto result = mDocument->mDependentElementsMap.Lookup(content)) {
104-
DocAccessible::AttrRelProviders* elementProviders = &result.Data();
105-
if (elementProviders) {
106-
for (auto& provider : *elementProviders) {
107-
if (mRelAttr && provider->mRelAttr != mRelAttr) {
108-
continue;
109-
}
110-
111-
if (nsCoreUtils::IsDescendantOfAnyShadowIncludingAncestor(
112-
content, provider->mContent)) {
113-
mRelatedNodes.Insert(*provider->mContent);
114-
}
115-
}
116-
}
117-
}
118-
dom::ShadowRoot* shadow = content->GetContainingShadow();
119-
dom::Element* element =
120-
content->IsElement() ? content->AsElement() : nullptr;
121-
if (shadow && element && element == shadow->GetReferenceTargetElement()) {
122-
content = shadow->Host();
123-
root = content->GetUncomposedDocOrConnectedShadowRoot();
124-
} else {
125-
root = nullptr;
126-
}
79+
mRelAttr(aRelAttr),
80+
mProviders(nullptr),
81+
mIndex(0),
82+
mIsWalkingDependentElements(false) {
83+
nsAutoString id;
84+
if (aDependentContent->IsElement() &&
85+
aDependentContent->AsElement()->GetAttr(nsGkAtoms::id, id)) {
86+
mProviders = mDocument->GetRelProviders(aDependentContent->AsElement(), id);
12787
}
128-
129-
mInitialized = true;
13088
}
13189

13290
LocalAccessible* RelatedAccIterator::Next() {
133-
if (!mInitialized) {
134-
Initialize();
91+
if (!mProviders || mIndex == mProviders->Length()) {
92+
if (mIsWalkingDependentElements) {
93+
// We've walked both dependent ids and dependent elements, so there are
94+
// no more targets.
95+
return nullptr;
96+
}
97+
// We've returned all dependent ids, but there might be dependent elements
98+
// too. Walk those next.
99+
mIsWalkingDependentElements = true;
100+
mIndex = 0;
101+
if (auto providers =
102+
mDocument->mDependentElementsMap.Lookup(mDependentContent)) {
103+
mProviders = &providers.Data();
104+
} else {
105+
mProviders = nullptr;
106+
return nullptr;
107+
}
135108
}
136109

137-
while (mNextIndex < mRelatedNodes.Length()) {
138-
nsIContent* nextContent = mRelatedNodes[mNextIndex];
139-
mNextIndex++;
110+
while (mIndex < mProviders->Length()) {
111+
const auto& provider = (*mProviders)[mIndex++];
140112

141-
LocalAccessible* next = mDocument->GetAccessible(nextContent);
142-
if (next) {
143-
return next;
113+
// Return related accessible for the given attribute.
114+
if (mRelAttr && provider->mRelAttr != mRelAttr) {
115+
continue;
116+
}
117+
// If we're walking elements (not ids), the explicitly set attr-element
118+
// `mDependentContent` must be a descendant of any of the refering element
119+
// `mProvider->mContent`'s shadow-including ancestors.
120+
if (mIsWalkingDependentElements &&
121+
!nsCoreUtils::IsDescendantOfAnyShadowIncludingAncestor(
122+
mDependentContent, provider->mContent)) {
123+
continue;
124+
}
125+
LocalAccessible* related = mDocument->GetAccessible(provider->mContent);
126+
if (related) {
127+
return related;
144128
}
145129

146-
if (nextContent == mDocument->GetContent()) {
130+
// If the document content is pointed by relation then return the
131+
// document itself.
132+
if (provider->mContent == mDocument->GetContent()) {
147133
return mDocument;
148134
}
149135
}
150136

137+
// We exhausted mProviders without returning anything.
138+
if (!mIsWalkingDependentElements) {
139+
// Call this function again to start walking the dependent elements.
140+
return Next();
141+
}
151142
return nullptr;
152143
}
153144

@@ -165,7 +156,7 @@ HTMLLabelIterator::HTMLLabelIterator(DocAccessible* aDocument,
165156
bool HTMLLabelIterator::IsLabel(LocalAccessible* aLabel) {
166157
dom::HTMLLabelElement* labelEl =
167158
dom::HTMLLabelElement::FromNode(aLabel->GetContent());
168-
return labelEl && labelEl->GetLabeledElementInternal() == mAcc->GetContent();
159+
return labelEl && labelEl->GetControl() == mAcc->GetContent();
169160
}
170161

171162
LocalAccessible* HTMLLabelIterator::Next() {
@@ -179,21 +170,7 @@ LocalAccessible* HTMLLabelIterator::Next() {
179170
}
180171

181172
// Ignore ancestor label on not widget accessible.
182-
if (mLabelFilter == eSkipAncestorLabel) {
183-
return nullptr;
184-
}
185-
186-
if (!mAcc->IsWidget()) {
187-
nsIContent* content = mAcc->GetContent();
188-
if (!content->IsElement()) {
189-
return nullptr;
190-
}
191-
dom::Element* element = content->AsElement();
192-
// <output> is not a widget but is labelable.
193-
if (!element->IsLabelable()) {
194-
return nullptr;
195-
}
196-
}
173+
if (mLabelFilter == eSkipAncestorLabel || !mAcc->IsWidget()) return nullptr;
197174

198175
// Go up tree to get a name of ancestor label if there is one (an ancestor
199176
// <label> implicitly points to us). Don't go up farther than form or
@@ -272,26 +249,71 @@ LocalAccessible* XULDescriptionIterator::Next() {
272249
AssociatedElementsIterator::AssociatedElementsIterator(DocAccessible* aDoc,
273250
nsIContent* aContent,
274251
nsAtom* aIDRefsAttr)
275-
: mContent(aContent), mDoc(aDoc), mElemIdx(0) {
276-
if (!mContent->IsElement()) {
277-
return;
252+
: mContent(aContent), mDoc(aDoc), mCurrIdx(0), mElemIdx(0) {
253+
if (mContent->IsElement()) {
254+
mContent->AsElement()->GetAttr(aIDRefsAttr, mIDs);
255+
if (mIDs.IsEmpty() &&
256+
(aria::AttrCharacteristicsFor(aIDRefsAttr) & ATTR_REFLECT_ELEMENTS)) {
257+
nsAccUtils::GetARIAElementsAttr(mContent->AsElement(), aIDRefsAttr,
258+
mElements);
259+
}
260+
}
261+
}
262+
263+
const nsDependentSubstring AssociatedElementsIterator::NextID() {
264+
for (; mCurrIdx < mIDs.Length(); mCurrIdx++) {
265+
if (!NS_IsAsciiWhitespace(mIDs[mCurrIdx])) break;
266+
}
267+
268+
if (mCurrIdx >= mIDs.Length()) return nsDependentSubstring();
269+
270+
nsAString::index_type idStartIdx = mCurrIdx;
271+
while (++mCurrIdx < mIDs.Length()) {
272+
if (NS_IsAsciiWhitespace(mIDs[mCurrIdx])) break;
278273
}
279-
auto elements =
280-
mContent->AsElement()->GetAttrAssociatedElementsInternal(aIDRefsAttr);
281-
if (elements) {
282-
mElements.SwapElements(*elements);
283-
} else if (auto* element = nsGenericHTMLElement::FromNode(aContent)) {
284-
if (auto* internals = element->GetInternals()) {
285-
elements = internals->GetAttrElements(aIDRefsAttr);
286-
if (elements) {
287-
mElements.SwapElements(*elements);
274+
275+
return Substring(mIDs, idStartIdx, mCurrIdx++ - idStartIdx);
276+
}
277+
278+
dom::Element* AssociatedElementsIterator::NextElem() {
279+
while (true) {
280+
const nsDependentSubstring id = NextID();
281+
if (id.IsEmpty()) break;
282+
283+
dom::Element* refContent = GetElem(id);
284+
if (refContent) return refContent;
285+
}
286+
287+
while (dom::Element* element = mElements.SafeElementAt(mElemIdx++)) {
288+
if (nsCoreUtils::IsDescendantOfAnyShadowIncludingAncestor(element,
289+
mContent)) {
290+
return element;
291+
}
292+
}
293+
294+
return nullptr;
295+
}
296+
297+
dom::Element* AssociatedElementsIterator::GetElem(nsIContent* aContent,
298+
const nsAString& aID) {
299+
// Get elements in DOM tree by ID attribute if this is an explicit content.
300+
// In case of bound element check its anonymous subtree.
301+
if (!aContent->IsInNativeAnonymousSubtree()) {
302+
dom::DocumentOrShadowRoot* docOrShadowRoot =
303+
aContent->GetUncomposedDocOrConnectedShadowRoot();
304+
if (docOrShadowRoot) {
305+
dom::Element* refElm = docOrShadowRoot->GetElementById(aID);
306+
if (refElm) {
307+
return refElm;
288308
}
289309
}
290310
}
311+
return nullptr;
291312
}
292313

293-
dom::Element* AssociatedElementsIterator::NextElem() {
294-
return mElements.SafeElementAt(mElemIdx++);
314+
dom::Element* AssociatedElementsIterator::GetElem(
315+
const nsDependentSubstring& aID) {
316+
return GetElem(mContent, aID);
295317
}
296318

297319
LocalAccessible* AssociatedElementsIterator::Next() {

accessible/base/AccIterator.h

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@
99

1010
#include "Filters.h"
1111
#include "mozilla/a11y/DocAccessible.h"
12-
#include "mozilla/dom/Element.h"
1312
#include "nsTArray.h"
14-
#include "nsContentUtils.h"
15-
#include "mozilla/dom/TreeOrderedArray.h"
1613

1714
#include <memory>
1815

@@ -21,8 +18,7 @@ class nsITreeView;
2118
namespace mozilla {
2219
namespace dom {
2320
class Element;
24-
class HTMLLabelElement;
25-
} // namespace dom
21+
}
2622

2723
namespace a11y {
2824
class DocAccessibleParent;
@@ -106,16 +102,12 @@ class RelatedAccIterator : public AccIterable {
106102
RelatedAccIterator(const RelatedAccIterator&);
107103
RelatedAccIterator& operator=(const RelatedAccIterator&);
108104

109-
void Initialize();
110-
111105
DocAccessible* mDocument;
112106
nsIContent* mDependentContent;
113107
nsAtom* mRelAttr;
114-
115-
dom::TreeOrderedArray<nsIContent*, TreeKind::ShadowIncludingDOM>
116-
mRelatedNodes;
117-
size_t mNextIndex = 0;
118-
bool mInitialized = false;
108+
DocAccessible::AttrRelProviders* mProviders;
109+
uint32_t mIndex;
110+
bool mIsWalkingDependentElements;
119111
};
120112

121113
/**
@@ -225,11 +217,22 @@ class AssociatedElementsIterator : public AccIterable {
225217
nsAtom* aIDRefsAttr);
226218
virtual ~AssociatedElementsIterator() {}
227219

220+
/**
221+
* Return next ID.
222+
*/
223+
const nsDependentSubstring NextID();
224+
228225
/**
229226
* Return next element.
230227
*/
231228
dom::Element* NextElem();
232229

230+
/**
231+
* Return the element with the given ID.
232+
*/
233+
static dom::Element* GetElem(nsIContent* aContent, const nsAString& aID);
234+
dom::Element* GetElem(const nsDependentSubstring& aID);
235+
233236
// AccIterable
234237
virtual LocalAccessible* Next() override;
235238

@@ -238,9 +241,11 @@ class AssociatedElementsIterator : public AccIterable {
238241
AssociatedElementsIterator(const AssociatedElementsIterator&);
239242
AssociatedElementsIterator operator=(const AssociatedElementsIterator&);
240243

244+
nsString mIDs;
241245
nsIContent* mContent;
242246
DocAccessible* mDoc;
243-
nsTArray<RefPtr<dom::Element>> mElements;
247+
nsAString::index_type mCurrIdx;
248+
nsTArray<dom::Element*> mElements;
244249
uint32_t mElemIdx;
245250
};
246251

accessible/base/nsAccUtils.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -579,19 +579,20 @@ const nsAttrValue* nsAccUtils::GetARIAAttr(dom::Element* aElement,
579579
return defaults->GetAttr(aName, kNameSpaceID_None);
580580
}
581581

582-
Maybe<nsTArray<RefPtr<dom::Element>>> nsAccUtils::GetARIAElementsAttr(
583-
dom::Element* aElement, nsAtom* aName) {
582+
bool nsAccUtils::GetARIAElementsAttr(dom::Element* aElement, nsAtom* aName,
583+
nsTArray<dom::Element*>& aElements) {
584584
if (aElement->HasAttr(aName)) {
585-
return aElement->GetExplicitlySetAttrElements(aName);
585+
aElement->GetExplicitlySetAttrElements(aName, aElements);
586+
return true;
586587
}
587588

588589
if (auto* element = nsGenericHTMLElement::FromNode(aElement)) {
589590
if (auto* internals = element->GetInternals()) {
590-
return internals->GetAttrElements(aName);
591+
return internals->GetAttrElements(aName, aElements);
591592
}
592593
}
593594

594-
return Nothing();
595+
return false;
595596
}
596597

597598
bool nsAccUtils::ARIAAttrValueIs(dom::Element* aElement, const nsAtom* aName,

accessible/base/nsAccUtils.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,8 @@ class nsAccUtils {
289289
nsAString& aResult);
290290
static const nsAttrValue* GetARIAAttr(dom::Element* aElement,
291291
const nsAtom* aName);
292-
static Maybe<nsTArray<RefPtr<dom::Element>>> GetARIAElementsAttr(
293-
dom::Element* aElement, nsAtom* aName);
292+
static bool GetARIAElementsAttr(dom::Element* aElement, nsAtom* aName,
293+
nsTArray<dom::Element*>& aElements);
294294
static bool ARIAAttrValueIs(dom::Element* aElement, const nsAtom* aName,
295295
const nsAString& aValue,
296296
nsCaseTreatment aCaseSensitive);

accessible/base/nsAccessibilityService.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,8 @@ static bool MustBeAccessible(nsIContent* aContent, DocAccessible* aDocument) {
242242

243243
// If the given ID is referred by relation attribute then create an
244244
// Accessible for it.
245-
if (nsAtom* id = aContent->GetID()) {
245+
nsAutoString id;
246+
if (nsCoreUtils::GetID(aContent, id) && !id.IsEmpty()) {
246247
return aDocument->IsDependentID(aContent->AsElement(), id);
247248
}
248249
}

accessible/base/nsCoreUtils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ using mozilla::a11y::nsAccUtils;
5656

5757
bool nsCoreUtils::IsLabelWithControl(nsIContent* aContent) {
5858
dom::HTMLLabelElement* label = dom::HTMLLabelElement::FromNode(aContent);
59-
if (label && label->GetLabeledElementInternal()) return true;
59+
if (label && label->GetControl()) return true;
6060

6161
return false;
6262
}

0 commit comments

Comments
 (0)