Bug 1744573: Maintain a reference to old ComputedStyle struct on LocalAccessibles r=Jamie,emilio

Differential Revision: https://phabricator.services.mozilla.com/D136435
This commit is contained in:
Morgan Reschenberg 2022-02-10 17:15:35 +00:00
parent 61287b0f62
commit 03a7882ef0
5 changed files with 66 additions and 0 deletions

View File

@ -372,6 +372,21 @@ void nsAccessibilityService::NotifyOfPossibleBoundsChange(
}
}
void nsAccessibilityService::NotifyOfComputedStyleChange(
mozilla::PresShell* aPresShell, nsIContent* aContent) {
if (!StaticPrefs::accessibility_cache_enabled_AtStartup()) {
return;
}
DocAccessible* document = GetDocAccessible(aPresShell);
if (document) {
LocalAccessible* accessible = document->GetAccessible(aContent);
if (accessible) {
accessible->MaybeQueueCacheUpdateForStyleChanges();
}
}
}
void nsAccessibilityService::NotifyOfResolutionChange(
mozilla::PresShell* aPresShell, float aResolution) {
if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {

View File

@ -236,6 +236,9 @@ class nsAccessibilityService final : public mozilla::a11y::DocManager,
void NotifyOfPossibleBoundsChange(mozilla::PresShell* aPresShell,
nsIContent* aContent);
void NotifyOfComputedStyleChange(mozilla::PresShell* aPresShell,
nsIContent* aContent);
void NotifyOfResolutionChange(mozilla::PresShell* aPresShell,
float aResolution);

View File

@ -3306,11 +3306,34 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
}
}
}
if (nsIFrame* frame = GetFrame()) {
// Note our frame's current computed style so we can track style changes
// later on.
mOldComputedStyle = frame->Style();
}
}
return fields.forget();
}
void LocalAccessible::MaybeQueueCacheUpdateForStyleChanges() {
if (!StaticPrefs::accessibility_cache_enabled_AtStartup()) {
return;
}
if (nsIFrame* frame = GetFrame()) {
const ComputedStyle* newStyle = frame->Style();
MOZ_ASSERT(newStyle != mOldComputedStyle, "New style matches old style!");
// TODO: comparison on a11y-relevant style attributes
// TODO: Queue cache update, schedule processing on document
mOldComputedStyle = newStyle;
}
}
nsAtom* LocalAccessible::TagName() const {
return mContent && mContent->IsElement() ? mContent->NodeInfo()->NameAtom()
: nullptr;

View File

@ -6,6 +6,7 @@
#ifndef _LocalAccessible_H_
#define _LocalAccessible_H_
#include "mozilla/ComputedStyle.h"
#include "mozilla/a11y/Accessible.h"
#include "mozilla/a11y/AccTypes.h"
#include "mozilla/a11y/RelationType.h"
@ -790,6 +791,8 @@ class LocalAccessible : public nsISupports, public Accessible {
*/
void SendCache(uint64_t aCacheDomain, CacheUpdateType aUpdate);
void MaybeQueueCacheUpdateForStyleChanges();
virtual nsAtom* TagName() const override;
protected:
@ -988,6 +991,21 @@ class LocalAccessible : public nsISupports, public Accessible {
int32_t mIndexInParent;
Maybe<nsRect> mBounds;
/**
* Maintain a reference to the ComputedStyle of our frame so we can
* send cache updates when style changes are observed.
*
* This RefPtr is initialised in BundleFieldsForCache to the ComputedStyle
* for our initial frame.
* When a style change is observed in DidSetComputedStyle we call into
* MaybeQueueCacheUpdateForStyleChanges. There, we compare a11y-relevant
* properties in mOldComputedStyle with the current ComputedStyle fetched
* from GetFrame()->Style(). Finally, we send cache updates for attributes
* affected by the style change and update mOldComputedStyle to the style of
* our current frame.
*/
RefPtr<const ComputedStyle> mOldComputedStyle;
static const uint8_t kStateFlagsBits = 11;
static const uint8_t kContextFlagsBits = 3;

View File

@ -1179,6 +1179,13 @@ void nsIFrame::MarkNeedsDisplayItemRebuild() {
// Subclass hook for style post processing
/* virtual */
void nsIFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle) {
#ifdef ACCESSIBILITY
if (nsAccessibilityService* accService = GetAccService()) {
// Notify for all frames, including those that will be reconstructed
accService->NotifyOfComputedStyleChange(PresShell(), mContent);
}
#endif
MaybeScheduleReflowSVGNonDisplayText(this);
Document* doc = PresContext()->Document();