mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-03 18:47:53 +00:00
Bug 1774043: [Part 1] Add cache domains, caching logic for LABEL_FOR and LABELLED_BY relations r=Jamie
Differential Revision: https://phabricator.services.mozilla.com/D152100
This commit is contained in:
parent
89d63c91e6
commit
4d3f82861a
@ -7,6 +7,8 @@
|
||||
#ifndef _CacheConstants_h_
|
||||
#define _CacheConstants_h_
|
||||
|
||||
#include "RelationType.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
@ -28,6 +30,7 @@ class CacheDomain {
|
||||
static constexpr uint64_t Spelling = ((uint64_t)0x1) << 13;
|
||||
static constexpr uint64_t Viewport = ((uint64_t)0x1) << 14;
|
||||
static constexpr uint64_t ARIA = ((uint64_t)0x1) << 15;
|
||||
static constexpr uint64_t Relations = ((uint64_t)0x1) << 16;
|
||||
static constexpr uint64_t All = ~((uint64_t)0x0);
|
||||
};
|
||||
|
||||
@ -43,6 +46,28 @@ enum class CacheUpdateType {
|
||||
Update,
|
||||
};
|
||||
|
||||
struct RelationData {
|
||||
nsStaticAtom* const mAtom;
|
||||
nsStaticAtom* const mValidTag;
|
||||
RelationType mType;
|
||||
};
|
||||
|
||||
/**
|
||||
* This array of RelationData lists our relation types and the cache
|
||||
* attribute atoms that store their targets. Attributes may describe
|
||||
* different kinds of relations, depending on the element they originate on.
|
||||
* For example, an <output> element's `for` attribute describes a CONTROLLER_FOR
|
||||
* relation, while the `for` attribute of a <label> describes a LABEL_FOR
|
||||
* relation.
|
||||
* To ensure we process these attributes appropriately, RelationData.mValidTag
|
||||
* contains the atom for the tag this attribute/relation type paring is valid
|
||||
* on. If the pairing is valid for all tag types, this field is null.
|
||||
*/
|
||||
static constexpr RelationData kRelationTypeAtoms[] = {
|
||||
{nsGkAtoms::aria_labelledby, nullptr, RelationType::LABELLED_BY},
|
||||
{nsGkAtoms::_for, nsGkAtoms::label, RelationType::LABEL_FOR},
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -87,6 +87,7 @@
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/HTMLCanvasElement.h"
|
||||
#include "mozilla/dom/HTMLBodyElement.h"
|
||||
#include "mozilla/dom/HTMLLabelElement.h"
|
||||
#include "mozilla/dom/KeyboardEventBinding.h"
|
||||
#include "mozilla/dom/TreeWalker.h"
|
||||
#include "mozilla/dom/UserActivation.h"
|
||||
@ -1348,6 +1349,10 @@ void LocalAccessible::DOMAttributeChanged(int32_t aNameSpaceID,
|
||||
}
|
||||
|
||||
if (aAttribute == nsGkAtoms::aria_labelledby) {
|
||||
// We only queue cache updates for explicit relations. Implicit, reverse
|
||||
// relations are handled in ApplyCache and stored in a map on the remote
|
||||
// document itself.
|
||||
mDoc->QueueCacheUpdate(this, CacheDomain::Relations);
|
||||
mDoc->FireDelayedEvent(nsIAccessibleEvent::EVENT_NAME_CHANGE, this);
|
||||
if (aModType == dom::MutationEvent_Binding::MODIFICATION ||
|
||||
aModType == dom::MutationEvent_Binding::ADDITION) {
|
||||
@ -3558,6 +3563,39 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
|
||||
}
|
||||
}
|
||||
|
||||
if (CacheDomain::Relations) {
|
||||
for (auto const& data : kRelationTypeAtoms) {
|
||||
nsTArray<uint64_t> ids;
|
||||
nsStaticAtom* const relAtom = data.mAtom;
|
||||
|
||||
Relation rel;
|
||||
if (data.mType == RelationType::LABEL_FOR) {
|
||||
// Labels are a special case -- we need to validate that the target of
|
||||
// their `for` attribute is in fact labelable. DOM checks this when we
|
||||
// call GetControl().
|
||||
if (dom::HTMLLabelElement* labelEl =
|
||||
dom::HTMLLabelElement::FromNode(mContent)) {
|
||||
rel.AppendTarget(mDoc, labelEl->GetControl());
|
||||
}
|
||||
} else {
|
||||
// We use an IDRefsIterator here instead of calling RelationByType
|
||||
// directly because we only want to cache explicit relations. Implicit
|
||||
// relations will be computed and stored separately in the parent
|
||||
// process.
|
||||
rel.AppendIter(new IDRefsIterator(mDoc, mContent, relAtom));
|
||||
}
|
||||
|
||||
while (LocalAccessible* acc = rel.Next()) {
|
||||
ids.AppendElement(acc->IsDoc() ? 0 : acc->ID());
|
||||
}
|
||||
if (ids.Length()) {
|
||||
fields->SetAttribute(relAtom, std::move(ids));
|
||||
} else if (aUpdateType == CacheUpdateType::Update) {
|
||||
fields->SetAttribute(relAtom, DeleteEntry());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aUpdateType == CacheUpdateType::Initial) {
|
||||
// Add fields which never change and thus only need to be included in the
|
||||
// initial cache push.
|
||||
|
@ -66,6 +66,7 @@ void HTMLLabelAccessible::DOMAttributeChanged(int32_t aNameSpaceID,
|
||||
aModType, aOldValue, aOldState);
|
||||
|
||||
if (aAttribute == nsGkAtoms::_for) {
|
||||
mDoc->QueueCacheUpdate(this, CacheDomain::Relations);
|
||||
SendCache(CacheDomain::Actions, CacheUpdateType::Update);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user