Skip to content

Commit bcb5d13

Browse files
committed
Bug 1990094 - Notify a11y cache of details relation changes caused by scroll. r=Jamie,jwatt
Differential Revision: https://phabricator.services.mozilla.com/D270902
1 parent ad2c530 commit bcb5d13

File tree

4 files changed

+110
-0
lines changed

4 files changed

+110
-0
lines changed

accessible/base/nsAccessibilityService.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,26 @@ void nsAccessibilityService::NotifyAnchorRemoved(mozilla::PresShell* aPresShell,
715715
}
716716
}
717717

718+
void nsAccessibilityService::NotifyAnchorPositionedScrollUpdate(
719+
mozilla::PresShell* aPresShell, nsIFrame* aFrame) {
720+
DocAccessible* document = aPresShell->GetDocAccessible();
721+
if (!document) {
722+
return;
723+
}
724+
725+
if (LocalAccessible* positionedAcc =
726+
document->GetAccessible(aFrame->GetContent())) {
727+
// Refresh relations before reflow to notify current anchor.
728+
document->RefreshAnchorRelationCacheForTarget(positionedAcc);
729+
730+
// Refresh relations after next tick when reflow updated to the
731+
// new anchor state.
732+
document->Controller()->ScheduleNotification<DocAccessible>(
733+
document, &DocAccessible::RefreshAnchorRelationCacheForTarget,
734+
positionedAcc);
735+
}
736+
}
737+
718738
void nsAccessibilityService::NotifyAttrElementWillChange(
719739
mozilla::dom::Element* aElement, nsAtom* aAttr) {
720740
mozilla::dom::Document* doc = aElement->OwnerDoc();

accessible/base/nsAccessibilityService.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,14 @@ class nsAccessibilityService final : public mozilla::a11y::DocManager,
283283
*/
284284
void NotifyAnchorRemoved(mozilla::PresShell* aPresShell, nsIFrame* aFrame);
285285

286+
/**
287+
* Notify accessibility that an anchor positioned frame has
288+
* been marked for reflow because of a scroll change for one of its
289+
* anchors. A fallback anchor may be activated or deactivated.
290+
*/
291+
void NotifyAnchorPositionedScrollUpdate(mozilla::PresShell* aPresShell,
292+
nsIFrame* aFrame);
293+
286294
/**
287295
* Notify accessibility that an element explicitly set for an attribute is
288296
* about to change. See dom::Element::ExplicitlySetAttrElement.

accessible/tests/browser/relations/browser_anchor_positioning.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,3 +663,80 @@ addAccessibleTask(
663663
},
664664
{ chrome: true, topLevel: true }
665665
);
666+
667+
addAccessibleTask(
668+
`
669+
<style>
670+
.anchor {
671+
width: 50px;
672+
height: 50px;
673+
background: pink;
674+
}
675+
676+
.positioned {
677+
width: 50px;
678+
height: 50px;
679+
background: purple;
680+
position: absolute;
681+
position-anchor: --a;
682+
left: anchor(right);
683+
bottom: anchor(bottom);
684+
position-try-fallbacks: --fb;
685+
}
686+
687+
@position-try --fb {
688+
position-anchor: --b;
689+
}
690+
691+
.abs-cb {
692+
width: 200px;
693+
height: 200px;
694+
border: 1px solid;
695+
position: relative;
696+
}
697+
698+
.scroller {
699+
overflow: scroll;
700+
width: 100%;
701+
height: 100%;
702+
border: 1px solid;
703+
box-sizing: border-box;
704+
}
705+
706+
.filler {
707+
height: 125px;
708+
width: 1px;
709+
}
710+
711+
.dn {
712+
display: none;
713+
}
714+
</style>
715+
<div class="abs-cb">
716+
<div class="scroller">
717+
<div class="filler"></div>
718+
<div class="anchor" id="anchor1" style="anchor-name: --a;" role="group"></div>
719+
<div class="filler"></div>
720+
<div class="anchor" id="anchor2" style="anchor-name: --b; background: aqua;" role="group"></div>
721+
<div class="filler"></div>
722+
</div>
723+
<div id="target" class="positioned" role="group"></div>
724+
</div>`,
725+
async function testScrollWithFallback(browser, docAcc) {
726+
const anchor1 = findAccessibleChildByID(docAcc, "anchor1");
727+
const anchor2 = findAccessibleChildByID(docAcc, "anchor2");
728+
const target = findAccessibleChildByID(docAcc, "target");
729+
730+
info("Correct details relation before scroll");
731+
await testDetailsRelations(anchor1, target);
732+
733+
await invokeContentTaskAndTick(browser, [], () => {
734+
let scroller = content.document.querySelector(".scroller");
735+
scroller.scrollTo(0, scroller.scrollTopMax);
736+
});
737+
738+
info("Correct details relation after scroll");
739+
await testDetailsRelations(anchor2, target);
740+
},
741+
{ chrome: true, topLevel: true }
742+
);

layout/base/PresShell.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11967,6 +11967,11 @@ void PresShell::UpdateAnchorPosForScroll(
1196711967
positioned->GetParent()->UpdateOverflow();
1196811968
referenceData.mDefaultScrollShift = offset;
1196911969
if (CheckOverflow(positioned, offset, referenceData)) {
11970+
#ifdef ACCESSIBILITY
11971+
if (nsAccessibilityService* accService = GetAccService()) {
11972+
accService->NotifyAnchorPositionedScrollUpdate(this, positioned);
11973+
}
11974+
#endif
1197011975
FrameNeedsReflow(positioned, IntrinsicDirty::None,
1197111976
NS_FRAME_HAS_DIRTY_CHILDREN);
1197211977
}

0 commit comments

Comments
 (0)