author | James Teh <jteh@mozilla.com> |
Mon, 25 Jan 2021 17:31:19 +0000 | |
changeset 564811 | 2c9004c95a7a7d39c2c1417b66fda37892398263 |
parent 564810 | 2a3f24bdb8e2adc88494f03e331abe0f81460f12 |
child 564812 | 0d0bce9329de0f3eea56921594233ba72089dbf2 |
push id | 135063 |
push user | jteh@mozilla.com |
push date | Wed, 27 Jan 2021 05:35:39 +0000 |
treeherder | autoland@2c9004c95a7a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | eeejay |
bugs | 493683 |
milestone | 87.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/accessible/generic/DocAccessible.cpp +++ b/accessible/generic/DocAccessible.cpp @@ -11,16 +11,17 @@ #include "HTMLImageMapAccessible.h" #include "nsAccCache.h" #include "nsAccessiblePivot.h" #include "nsAccUtils.h" #include "nsDeckFrame.h" #include "nsEventShell.h" #include "nsLayoutUtils.h" #include "nsTextEquivUtils.h" +#include "Pivot.h" #include "Role.h" #include "RootAccessible.h" #include "TreeWalker.h" #include "xpcAccessibleDocument.h" #include "nsCommandManager.h" #include "nsContentUtils.h" #include "nsIDocShell.h" @@ -846,25 +847,60 @@ void DocAccessible::AttributeChangedImpl // Fire name change and description change events. XXX: it's not complete and // dupes the code logic of accessible name and description calculation, we do // that for performance reasons. if (aAttribute == nsGkAtoms::aria_label) { FireDelayedEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, aAccessible); return; } + dom::Element* elm = aAccessible->GetContent()->AsElement(); if (aAttribute == nsGkAtoms::aria_describedby) { FireDelayedEvent(nsIAccessibleEvent::EVENT_DESCRIPTION_CHANGE, aAccessible); + if (aModType == dom::MutationEvent_Binding::MODIFICATION || + aModType == dom::MutationEvent_Binding::ADDITION) { + // The subtrees of the new aria-describedby targets might be used to + // compute the description for aAccessible. Therefore, we need to set + // the eHasDescriptionDependent flag on all Accessibles in these subtrees. + IDRefsIterator iter(this, aAccessible->Elm(), + nsGkAtoms::aria_describedby); + while (Accessible* target = iter.Next()) { + Pivot pivot(target); + LocalAccInSameDocRule rule; + for (AccessibleOrProxy anchor(target); !anchor.IsNull(); + anchor = pivot.Next(anchor, rule)) { + Accessible* acc = anchor.AsAccessible(); + MOZ_ASSERT(acc); + acc->mContextFlags |= eHasDescriptionDependent; + } + } + } return; } - dom::Element* elm = aAccessible->GetContent()->AsElement(); if (aAttribute == nsGkAtoms::aria_labelledby && !elm->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_label)) { FireDelayedEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, aAccessible); + if (aModType == dom::MutationEvent_Binding::MODIFICATION || + aModType == dom::MutationEvent_Binding::ADDITION) { + // The subtrees of the new aria-labelledby targets might be used to + // compute the name for aAccessible. Therefore, we need to set + // the eHasNameDependent flag on all Accessibles in these subtrees. + IDRefsIterator iter(this, aAccessible->Elm(), nsGkAtoms::aria_labelledby); + while (Accessible* target = iter.Next()) { + Pivot pivot(target); + LocalAccInSameDocRule rule; + for (AccessibleOrProxy anchor(target); !anchor.IsNull(); + anchor = pivot.Next(anchor, rule)) { + Accessible* acc = anchor.AsAccessible(); + MOZ_ASSERT(acc); + acc->mContextFlags |= eHasNameDependent; + } + } + } return; } if (aAttribute == nsGkAtoms::alt && !elm->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_label) && !elm->HasAttr(kNameSpaceID_None, nsGkAtoms::aria_labelledby)) { FireDelayedEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, aAccessible); return;
--- a/accessible/tests/mochitest/events/test_descrchange.html +++ b/accessible/tests/mochitest/events/test_descrchange.html @@ -85,16 +85,32 @@ descChanged = PromEvents.waitForEvent( EVENT_DESCRIPTION_CHANGE, describedBy ); info("Changing text of aria-describedby target's child"); getNode("descriptionChild").textContent = "d4"; await descChanged; + const lateDescribedBy = getNode("lateDescribedBy"); + descChanged = PromEvents.waitForEvent( + EVENT_DESCRIPTION_CHANGE, + lateDescribedBy + ); + info("Setting aria-describedby"); + lateDescribedBy.setAttribute("aria-describedby", "lateDescription"); + await descChanged; + descChanged = PromEvents.waitForEvent( + EVENT_DESCRIPTION_CHANGE, + lateDescribedBy + ); + info("Changing text of late aria-describedby target's child"); + getNode("lateDescriptionChild").textContent = "d2"; + await descChanged; + SimpleTest.finish(); } SimpleTest.waitForExplicitFinish(); addA11yLoadEvent(doTests); </script> </head> @@ -112,11 +128,14 @@ </pre> <button id="tst1">btn1</button> <button id="tst2">btn2</button> <div id="describedBy" aria-describedby="description"></div> <div id="description">d1</div> + <div id="lateDescribedBy"></div> + <div id="lateDescription"><p id="lateDescriptionChild">d1</p></div> + <div id="eventdump"></div> </body> </html>
--- a/accessible/tests/mochitest/events/test_namechange.html +++ b/accessible/tests/mochitest/events/test_namechange.html @@ -114,16 +114,26 @@ info("Adding node to aria-labelledby target"); label.innerHTML = '<p id="labelChild">l3</p>'; await nameChanged; nameChanged = PromEvents.waitForEvent(EVENT_NAME_CHANGE, labelledBy); info("Changing text of aria-labelledby target's child"); getNode("labelChild").textContent = "l4"; await nameChanged; + const lateLabelledBy = getNode("lateLabelledBy"); + nameChanged = PromEvents.waitForEvent(EVENT_NAME_CHANGE, lateLabelledBy); + info("Setting aria-labelledby"); + lateLabelledBy.setAttribute("aria-labelledby", "lateLabel"); + await nameChanged; + nameChanged = PromEvents.waitForEvent(EVENT_NAME_CHANGE, lateLabelledBy); + info("Changing text of late aria-labelledby target's child"); + getNode("lateLabelChild").textContent = "l2"; + await nameChanged; + SimpleTest.finish(); } SimpleTest.waitForExplicitFinish(); addA11yLoadEvent(doTests); </script> </head> @@ -143,11 +153,14 @@ <img id="tst1" alt="initial" src="../moz.png"> <img id="tst2" src="../moz.png"> <img id="tst3"> <img id="tst4" src="../moz.png"> <div id="labelledBy" aria-labelledby="label"></div> <div id="label">l1</div> + <div id="lateLabelledBy"></div> + <div id="lateLabel"><p id="lateLabelChild">l1</p></div> + <div id="eventdump"></div> </body> </html>