mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 786143 - inherit aria-hidden through subtree, r=yzen
This commit is contained in:
parent
729f2d8fe8
commit
8a6810240e
@ -711,7 +711,7 @@ static const AttrCharacteristics gWAIUnivAttrMap[] = {
|
||||
{&nsGkAtoms::aria_flowto, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_grabbed, ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_haspopup, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_hidden, ATTR_BYPASSOBJ_IF_FALSE | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_hidden, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL }, /* handled special way */
|
||||
{&nsGkAtoms::aria_invalid, ATTR_BYPASSOBJ | ATTR_VALTOKEN | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_label, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
{&nsGkAtoms::aria_labelledby, ATTR_BYPASSOBJ | ATTR_GLOBAL },
|
||||
@ -798,6 +798,15 @@ aria::AttrCharacteristicsFor(nsIAtom* aAtom)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
aria::HasDefinedARIAHidden(nsIContent* aContent)
|
||||
{
|
||||
return aContent &&
|
||||
nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_hidden) &&
|
||||
!aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_hidden,
|
||||
nsGkAtoms::_false, eCaseMatters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AttrIterator class
|
||||
|
||||
|
@ -227,6 +227,11 @@ uint64_t UniversalStatesFor(mozilla::dom::Element* aElement);
|
||||
*/
|
||||
uint8_t AttrCharacteristicsFor(nsIAtom* aAtom);
|
||||
|
||||
/**
|
||||
* Return true if the element has defined aria-hidden.
|
||||
*/
|
||||
bool HasDefinedARIAHidden(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Represents a simple enumerator for iterating through ARIA attributes
|
||||
* exposed as object attributes on a given accessible.
|
||||
|
@ -892,11 +892,7 @@ RuleCache::ApplyFilter(Accessible* aAccessible, uint16_t* aResult)
|
||||
return NS_OK;
|
||||
|
||||
if (nsIAccessibleTraversalRule::PREFILTER_ARIA_HIDDEN & mPreFilter) {
|
||||
nsIContent* content = aAccessible->GetContent();
|
||||
if (content &&
|
||||
nsAccUtils::HasDefinedARIAToken(content, nsGkAtoms::aria_hidden) &&
|
||||
!content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_hidden,
|
||||
nsGkAtoms::_false, eCaseMatters)) {
|
||||
if (aAccessible->IsARIAHidden()) {
|
||||
*aResult |= nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -873,6 +873,11 @@ Accessible::Attributes()
|
||||
while(attribIter.Next(name, value))
|
||||
attributes->SetStringProperty(NS_ConvertUTF16toUTF8(name), value, unused);
|
||||
|
||||
if (IsARIAHidden()) {
|
||||
nsAccUtils::SetAccAttr(attributes, nsGkAtoms::hidden,
|
||||
NS_LITERAL_STRING("true"));
|
||||
}
|
||||
|
||||
// If there is no aria-live attribute then expose default value of 'live'
|
||||
// object attribute used for ARIA role of this accessible.
|
||||
if (mRoleMapEntry) {
|
||||
@ -1920,6 +1925,9 @@ Accessible::BindToParent(Accessible* aParent, uint32_t aIndexInParent)
|
||||
mContextFlags |= eHasNameDependentParent;
|
||||
else
|
||||
mContextFlags &= ~eHasNameDependentParent;
|
||||
|
||||
if (mParent->IsARIAHidden() || aria::HasDefinedARIAHidden(mContent))
|
||||
SetARIAHidden(true);
|
||||
}
|
||||
|
||||
// Accessible protected
|
||||
@ -2377,6 +2385,20 @@ Accessible::ContainerWidget() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
Accessible::SetARIAHidden(bool aIsDefined)
|
||||
{
|
||||
if (aIsDefined)
|
||||
mContextFlags |= eARIAHidden;
|
||||
else
|
||||
mContextFlags &= ~eARIAHidden;
|
||||
|
||||
uint32_t length = mChildren.Length();
|
||||
for (uint32_t i = 0; i < length; i++) {
|
||||
mChildren[i]->SetARIAHidden(aIsDefined);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Accessible protected methods
|
||||
|
||||
|
@ -889,6 +889,13 @@ public:
|
||||
bool HasNameDependentParent() const
|
||||
{ return mContextFlags & eHasNameDependentParent; }
|
||||
|
||||
/**
|
||||
* Return true if aria-hidden="true" is applied to the accessible or inherited
|
||||
* from the parent.
|
||||
*/
|
||||
bool IsARIAHidden() const { return mContextFlags & eARIAHidden; }
|
||||
void SetARIAHidden(bool aIsDefined);
|
||||
|
||||
protected:
|
||||
|
||||
virtual ~Accessible();
|
||||
@ -975,8 +982,9 @@ protected:
|
||||
*/
|
||||
enum ContextFlags {
|
||||
eHasNameDependentParent = 1 << 0, // Parent's name depends on this accessible.
|
||||
eARIAHidden = 1 << 1,
|
||||
|
||||
eLastContextFlag = eHasNameDependentParent
|
||||
eLastContextFlag = eARIAHidden
|
||||
};
|
||||
|
||||
protected:
|
||||
@ -1082,7 +1090,7 @@ protected:
|
||||
|
||||
static const uint8_t kChildrenFlagsBits = 2;
|
||||
static const uint8_t kStateFlagsBits = 9;
|
||||
static const uint8_t kContextFlagsBits = 1;
|
||||
static const uint8_t kContextFlagsBits = 2;
|
||||
static const uint8_t kTypeBits = 6;
|
||||
static const uint8_t kGenericTypesBits = 13;
|
||||
|
||||
|
@ -955,6 +955,22 @@ DocAccessible::ARIAAttributeChanged(Accessible* aAccessible, nsIAtom* aAttribute
|
||||
|
||||
nsIContent* elm = aAccessible->GetContent();
|
||||
|
||||
// Update aria-hidden flag for the whole subtree iff aria-hidden is changed
|
||||
// on the root, i.e. ignore any affiliated aria-hidden changes in the subtree
|
||||
// of top aria-hidden.
|
||||
if (aAttribute == nsGkAtoms::aria_hidden) {
|
||||
bool isDefined = aria::HasDefinedARIAHidden(elm);
|
||||
if (isDefined != aAccessible->IsARIAHidden() &&
|
||||
!aAccessible->Parent()->IsARIAHidden()) {
|
||||
aAccessible->SetARIAHidden(isDefined);
|
||||
|
||||
nsRefPtr<AccEvent> event =
|
||||
new AccObjectAttrChangedEvent(aAccessible, aAttribute);
|
||||
FireDelayedEvent(event);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (aAttribute == nsGkAtoms::aria_checked ||
|
||||
(aAccessible->IsButton() &&
|
||||
aAttribute == nsGkAtoms::aria_pressed)) {
|
||||
|
@ -11,6 +11,8 @@
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../attributes.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
@ -40,6 +42,23 @@
|
||||
};
|
||||
}
|
||||
|
||||
function updateARIAHidden(aID, aIsDefined, aChildId)
|
||||
{
|
||||
this.__proto__ = new updateAttribute(aID, "aria-hidden",
|
||||
aIsDefined ? "true" : "false");
|
||||
|
||||
this.finalCheck = function updateARIAHidden()
|
||||
{
|
||||
if (aIsDefined) {
|
||||
testAttrs(aID, {"hidden" : "true"}, true);
|
||||
testAttrs(aChildId, {"hidden" : "true"}, true);
|
||||
} else {
|
||||
testAbsentAttrs(aID, { "hidden": "true"});
|
||||
testAbsentAttrs(aChildId, { "hidden": "true"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Debug stuff.
|
||||
// gA11yEventDumpID = "eventdump";
|
||||
//gA11yEventDumpToConsole = true;
|
||||
@ -48,7 +67,8 @@
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new updateAttribute("hideable", "aria-hidden", "true"));
|
||||
gQueue.push(new updateARIAHidden("hideable", true, "hideable_child"));
|
||||
gQueue.push(new updateARIAHidden("hideable", false, "hideable_child"));
|
||||
|
||||
gQueue.push(new updateAttribute("sortable", "aria-sort", "ascending"));
|
||||
|
||||
@ -89,7 +109,7 @@
|
||||
</pre>
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<div id="hideable"><div>Hi</div><div>there</div></div>
|
||||
<div id="hideable"><div id="hideable_child">Hi</div><div>there</div></div>
|
||||
|
||||
<div id="sortable" role="columnheader" aria-sort="none">aria-sort</div>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user