diff --git a/accessible/base/CacheConstants.h b/accessible/base/CacheConstants.h index 58ce94aa5407..d4440a03a204 100644 --- a/accessible/base/CacheConstants.h +++ b/accessible/base/CacheConstants.h @@ -69,6 +69,10 @@ static constexpr RelationData kRelationTypeAtoms[] = { RelationType::LABEL_FOR}, {nsGkAtoms::_for, nsGkAtoms::label, RelationType::LABEL_FOR, RelationType::LABELLED_BY}, + {nsGkAtoms::aria_controls, nullptr, RelationType::CONTROLLER_FOR, + RelationType::CONTROLLED_BY}, + {nsGkAtoms::_for, nsGkAtoms::output, RelationType::CONTROLLED_BY, + RelationType::CONTROLLER_FOR}, }; } // namespace a11y diff --git a/accessible/generic/LocalAccessible.cpp b/accessible/generic/LocalAccessible.cpp index 09c3656014a4..8bcfa5f7aee5 100644 --- a/accessible/generic/LocalAccessible.cpp +++ b/accessible/generic/LocalAccessible.cpp @@ -1374,6 +1374,10 @@ void LocalAccessible::DOMAttributeChanged(int32_t aNameSpaceID, SendCache(CacheDomain::Actions, CacheUpdateType::Update); } + if (aAttribute == nsGkAtoms::aria_controls) { + mDoc->QueueCacheUpdate(this, CacheDomain::Relations); + } + if (aAttribute == nsGkAtoms::alt && !elm->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_label) && !elm->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_labelledby)) { diff --git a/accessible/html/HTMLElementAccessibles.cpp b/accessible/html/HTMLElementAccessibles.cpp index 3398e59b22e3..518506fe753c 100644 --- a/accessible/html/HTMLElementAccessibles.cpp +++ b/accessible/html/HTMLElementAccessibles.cpp @@ -96,6 +96,19 @@ Relation HTMLOutputAccessible::RelationByType(RelationType aType) const { return rel; } +void HTMLOutputAccessible::DOMAttributeChanged(int32_t aNameSpaceID, + nsAtom* aAttribute, + int32_t aModType, + const nsAttrValue* aOldValue, + uint64_t aOldState) { + HyperTextAccessibleWrap::DOMAttributeChanged(aNameSpaceID, aAttribute, + aModType, aOldValue, aOldState); + + if (aAttribute == nsGkAtoms::_for) { + mDoc->QueueCacheUpdate(this, CacheDomain::Relations); + } +} + //////////////////////////////////////////////////////////////////////////////// // HTMLSummaryAccessible //////////////////////////////////////////////////////////////////////////////// diff --git a/accessible/html/HTMLElementAccessibles.h b/accessible/html/HTMLElementAccessibles.h index fdae42db2d07..b45e94591203 100644 --- a/accessible/html/HTMLElementAccessibles.h +++ b/accessible/html/HTMLElementAccessibles.h @@ -84,6 +84,11 @@ class HTMLOutputAccessible : public HyperTextAccessibleWrap { // LocalAccessible virtual Relation RelationByType(RelationType aType) const override; + virtual void DOMAttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute, + int32_t aModType, + const nsAttrValue* aOldValue, + uint64_t aOldState) override; + protected: virtual ~HTMLOutputAccessible() {} }; diff --git a/accessible/tests/browser/e10s/browser_caching_relations.js b/accessible/tests/browser/e10s/browser_caching_relations.js index b56b19462ba9..ddaf26c708f6 100644 --- a/accessible/tests/browser/e10s/browser_caching_relations.js +++ b/accessible/tests/browser/e10s/browser_caching_relations.js @@ -226,3 +226,25 @@ addAccessibleTask( }, { iframe: true, remoteIframe: true } ); + +/** + * Test caching of relations with respect to output objects and their "for" attr. + */ +addAccessibleTask( + ` +
+ + + = + +
`, + async function(browser, accDoc) { + await testRelated( + browser, + accDoc, + "for", + RELATION_CONTROLLED_BY, + RELATION_CONTROLLER_FOR + ); + }, + { iframe: true, remoteIframe: true } +);