зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1787284: [Part 2] Cache name and create radio name pivot rule r=eeejay
Depends on D158892 Differential Revision: https://phabricator.services.mozilla.com/D159118
This commit is contained in:
Родитель
6e6dc5a06e
Коммит
dbeec6c2f2
|
@ -634,3 +634,29 @@ uint16_t LocalAccInSameDocRule::Match(Accessible* aAcc) {
|
|||
}
|
||||
return nsIAccessibleTraversalRule::FILTER_MATCH;
|
||||
}
|
||||
|
||||
// Radio Button Name Rule
|
||||
|
||||
PivotRadioNameRule::PivotRadioNameRule(const nsString& aName) : mName(aName) {}
|
||||
|
||||
uint16_t PivotRadioNameRule::Match(Accessible* aAcc) {
|
||||
uint16_t result = nsIAccessibleTraversalRule::FILTER_IGNORE;
|
||||
RemoteAccessible* remote = aAcc->AsRemote();
|
||||
if (!remote || !StaticPrefs::accessibility_cache_enabled_AtStartup()) {
|
||||
// We need the cache to be able to fetch the name attribute below.
|
||||
return result;
|
||||
}
|
||||
|
||||
if (nsAccUtils::MustPrune(aAcc) || aAcc->IsOuterDoc()) {
|
||||
result |= nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
|
||||
}
|
||||
|
||||
if (remote->IsHTMLRadioButton()) {
|
||||
nsString currName = remote->GetCachedHTMLRadioNameAttribute();
|
||||
if (!currName.IsEmpty() && mName.Equals(currName)) {
|
||||
result |= nsIAccessibleTraversalRule::FILTER_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -122,6 +122,20 @@ class LocalAccInSameDocRule : public PivotRule {
|
|||
virtual uint16_t Match(Accessible* aAcc) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* This rule matches remote radio button accessibles with the given name
|
||||
* attribute. It assumes the cache is enabled.
|
||||
*/
|
||||
class PivotRadioNameRule : public PivotRule {
|
||||
public:
|
||||
explicit PivotRadioNameRule(const nsString& aName);
|
||||
|
||||
virtual uint16_t Match(Accessible* aAcc) override;
|
||||
|
||||
protected:
|
||||
const nsString& mName;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
|
|
|
@ -501,6 +501,8 @@ class Accessible {
|
|||
|
||||
bool IsHTMLOptGroup() const { return mType == eHTMLOptGroupType; }
|
||||
|
||||
bool IsHTMLRadioButton() const { return mType == eHTMLRadioButtonType; }
|
||||
|
||||
bool IsHTMLTable() const { return mType == eHTMLTableType; }
|
||||
bool IsHTMLTableRow() const { return mType == eHTMLTableRowType; }
|
||||
|
||||
|
|
|
@ -3618,6 +3618,21 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
|
|||
}
|
||||
|
||||
if (aCacheDomain & CacheDomain::Relations && mContent) {
|
||||
if (IsHTMLRadioButton()) {
|
||||
// HTML radio buttons with the same name should be grouped
|
||||
// and returned together when their MEMBER_OF relation is
|
||||
// requested. We cache the name attribute, if it exists, here.
|
||||
nsString name;
|
||||
mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
|
||||
if (!name.IsEmpty()) {
|
||||
fields->SetAttribute(nsGkAtoms::radioLabel, std::move(name));
|
||||
} else if (aUpdateType != CacheUpdateType::Initial) {
|
||||
// It's possible we used to have a name and it's since been
|
||||
// removed. Send a delete entry.
|
||||
fields->SetAttribute(nsGkAtoms::radioLabel, DeleteEntry());
|
||||
}
|
||||
}
|
||||
|
||||
for (auto const& data : kRelationTypeAtoms) {
|
||||
nsTArray<uint64_t> ids;
|
||||
nsStaticAtom* const relAtom = data.mAtom;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "HTMLFormControlAccessible.h"
|
||||
|
||||
#include "CacheConstants.h"
|
||||
#include "DocAccessible-inl.h"
|
||||
#include "LocalAccessible-inl.h"
|
||||
#include "nsAccUtils.h"
|
||||
|
@ -90,6 +91,20 @@ void HTMLRadioButtonAccessible::GetPositionAndSetSize(int32_t* aPosInSet,
|
|||
Unused << ComputeGroupAttributes(aPosInSet, aSetSize);
|
||||
}
|
||||
|
||||
void HTMLRadioButtonAccessible::DOMAttributeChanged(
|
||||
int32_t aNameSpaceID, nsAtom* aAttribute, int32_t aModType,
|
||||
const nsAttrValue* aOldValue, uint64_t aOldState) {
|
||||
if (aAttribute == nsGkAtoms::name) {
|
||||
// If our name changed, it's possible our MEMBER_OF relation
|
||||
// also changed. Push a cache update for Relations.
|
||||
mDoc->QueueCacheUpdate(this, CacheDomain::Relations);
|
||||
} else {
|
||||
// Otherwise, handle this attribute change the way our parent
|
||||
// class wants us to handle it.
|
||||
RadioButtonAccessible::DOMAttributeChanged(aNameSpaceID, aAttribute, aModType, aOldValue, aOldState);
|
||||
}
|
||||
}
|
||||
|
||||
Relation HTMLRadioButtonAccessible::ComputeGroupAttributes(
|
||||
int32_t* aPosInSet, int32_t* aSetSize) const {
|
||||
Relation rel = Relation();
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "FormControlAccessible.h"
|
||||
#include "HyperTextAccessibleWrap.h"
|
||||
#include "mozilla/a11y/AccTypes.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "AccAttributes.h"
|
||||
#include "nsAccUtils.h"
|
||||
|
@ -27,6 +28,7 @@ class HTMLRadioButtonAccessible : public RadioButtonAccessible {
|
|||
// Ignore "RadioStateChange" DOM event in lieu of document observer
|
||||
// state change notification.
|
||||
mStateFlags |= eIgnoreDOMUIEvent;
|
||||
mType = eHTMLRadioButtonType;
|
||||
}
|
||||
|
||||
// LocalAccessible
|
||||
|
@ -37,6 +39,11 @@ class HTMLRadioButtonAccessible : public RadioButtonAccessible {
|
|||
virtual void GetPositionAndSetSize(int32_t* aPosInSet,
|
||||
int32_t* aSetSize) override;
|
||||
|
||||
virtual void DOMAttributeChanged(int32_t aNameSpaceID, nsAtom* aAttribute,
|
||||
int32_t aModType,
|
||||
const nsAttrValue* aOldValue,
|
||||
uint64_t aOldState) override;
|
||||
|
||||
private:
|
||||
Relation ComputeGroupAttributes(int32_t* aPosInSet, int32_t* aSetSize) const;
|
||||
};
|
||||
|
|
|
@ -1006,6 +1006,19 @@ RemoteAccessibleBase<Derived>::GetCachedARIAAttributes() const {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
nsString RemoteAccessibleBase<Derived>::GetCachedHTMLRadioNameAttribute()
|
||||
const {
|
||||
if (mCachedFields) {
|
||||
if (auto maybeName =
|
||||
mCachedFields->GetAttribute<nsString>(nsGkAtoms::radioLabel)) {
|
||||
return *maybeName;
|
||||
}
|
||||
}
|
||||
|
||||
return nsString();
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
uint64_t RemoteAccessibleBase<Derived>::State() {
|
||||
uint64_t state = 0;
|
||||
|
|
|
@ -348,6 +348,8 @@ class RemoteAccessibleBase : public Accessible, public HyperTextAccessibleBase {
|
|||
RefPtr<const AccAttributes> GetCachedTextAttributes();
|
||||
RefPtr<const AccAttributes> GetCachedARIAAttributes() const;
|
||||
|
||||
nsString GetCachedHTMLRadioNameAttribute() const;
|
||||
|
||||
virtual HyperTextAccessibleBase* AsHyperTextBase() override {
|
||||
return IsHyperText() ? static_cast<HyperTextAccessibleBase*>(this)
|
||||
: nullptr;
|
||||
|
|
Загрузка…
Ссылка в новой задаче