зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1349223 - cut aria-hidden tree, r=yzen
This commit is contained in:
Родитель
d0d6e91dfa
Коммит
32562a67f0
|
@ -1431,12 +1431,10 @@ aria::AttrCharacteristicsFor(nsAtom* aAtom)
|
|||
bool
|
||||
aria::HasDefinedARIAHidden(nsIContent* aContent)
|
||||
{
|
||||
return aContent &&
|
||||
nsAccUtils::HasDefinedARIAToken(aContent, nsGkAtoms::aria_hidden) &&
|
||||
!aContent->AsElement()->AttrValueIs(kNameSpaceID_None,
|
||||
nsGkAtoms::aria_hidden,
|
||||
nsGkAtoms::_false,
|
||||
eCaseMatters);
|
||||
return aContent && aContent->IsElement() &&
|
||||
aContent->AsElement()->AttrValueIs(kNameSpaceID_None,
|
||||
nsGkAtoms::aria_hidden,
|
||||
nsGkAtoms::_true, eCaseMatters);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -750,9 +750,11 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
|
|||
}
|
||||
#endif
|
||||
|
||||
Accessible* container = mDocument->AccessibleOrTrueContainer(containerNode);
|
||||
MOZ_ASSERT(container,
|
||||
MOZ_ASSERT(mDocument->AccessibleOrTrueContainer(containerNode),
|
||||
"Text node having rendered text hasn't accessible document!");
|
||||
|
||||
Accessible* container = mDocument->AccessibleOrTrueContainer(
|
||||
containerNode, DocAccessible::eNoContainerIfARIAHidden);
|
||||
if (container) {
|
||||
nsTArray<nsCOMPtr<nsIContent>>* list =
|
||||
mContentInsertions.LookupOrAdd(container);
|
||||
|
|
|
@ -1049,10 +1049,16 @@ nsAccessibilityService::CreateAccessible(nsINode* aNode,
|
|||
return nullptr;
|
||||
|
||||
nsIContent* content = aNode->AsContent();
|
||||
nsIFrame* frame = content->GetPrimaryFrame();
|
||||
if (aria::HasDefinedARIAHidden(content)) {
|
||||
if (aIsSubtreeHidden) {
|
||||
*aIsSubtreeHidden = true;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Check frame and its visibility. Note, hidden frame allows visible
|
||||
// elements in subtree.
|
||||
nsIFrame* frame = content->GetPrimaryFrame();
|
||||
if (!frame || !frame->StyleVisibility()->IsVisible()) {
|
||||
// display:contents element doesn't have a frame, but retains the semantics.
|
||||
// All its children are unaffected.
|
||||
|
|
|
@ -895,13 +895,6 @@ RuleCache::ApplyFilter(Accessible* aAccessible, uint16_t* aResult)
|
|||
!(state & states::FOCUSABLE))
|
||||
return NS_OK;
|
||||
|
||||
if (nsIAccessibleTraversalRule::PREFILTER_ARIA_HIDDEN & mPreFilter) {
|
||||
if (aAccessible->IsARIAHidden()) {
|
||||
*aResult |= nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if ((nsIAccessibleTraversalRule::PREFILTER_TRANSPARENT & mPreFilter) &&
|
||||
!(state & states::OPAQUE1)) {
|
||||
nsIFrame* frame = aAccessible->GetFrame();
|
||||
|
|
|
@ -982,11 +982,6 @@ 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.
|
||||
const nsRoleMapEntry* roleMapEntry = ARIARoleMap();
|
||||
|
@ -2113,9 +2108,6 @@ Accessible::BindToParent(Accessible* aParent, uint32_t aIndexInParent)
|
|||
else
|
||||
mContextFlags &= ~eHasNameDependentParent;
|
||||
|
||||
if (mParent->IsARIAHidden() || aria::HasDefinedARIAHidden(mContent))
|
||||
SetARIAHidden(true);
|
||||
|
||||
mContextFlags |=
|
||||
static_cast<uint32_t>((mParent->IsAlert() ||
|
||||
mParent->IsInsideAlert())) & eInsideAlert;
|
||||
|
@ -2642,20 +2634,6 @@ 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
|
||||
|
||||
|
|
|
@ -940,13 +940,6 @@ 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);
|
||||
|
||||
/**
|
||||
* Return true if the element is inside an alert.
|
||||
*/
|
||||
|
@ -1048,8 +1041,7 @@ protected:
|
|||
*/
|
||||
enum ContextFlags {
|
||||
eHasNameDependentParent = 1 << 0, // Parent's name depends on this accessible.
|
||||
eARIAHidden = 1 << 1,
|
||||
eInsideAlert = 1 << 2,
|
||||
eInsideAlert = 1 << 1,
|
||||
|
||||
eLastContextFlag = eInsideAlert
|
||||
};
|
||||
|
@ -1142,7 +1134,7 @@ protected:
|
|||
int32_t mIndexInParent;
|
||||
|
||||
static const uint8_t kStateFlagsBits = 12;
|
||||
static const uint8_t kContextFlagsBits = 3;
|
||||
static const uint8_t kContextFlagsBits = 2;
|
||||
static const uint8_t kTypeBits = 6;
|
||||
static const uint8_t kGenericTypesBits = 16;
|
||||
|
||||
|
|
|
@ -23,11 +23,11 @@ namespace mozilla {
|
|||
namespace a11y {
|
||||
|
||||
inline Accessible*
|
||||
DocAccessible::AccessibleOrTrueContainer(nsINode* aNode) const
|
||||
DocAccessible::AccessibleOrTrueContainer(nsINode* aNode, int aIgnoreARIAHidden) const
|
||||
{
|
||||
// HTML comboboxes have no-content list accessible as an intermediate
|
||||
// containing all options.
|
||||
Accessible* container = GetAccessibleOrContainer(aNode);
|
||||
Accessible* container = GetAccessibleOrContainer(aNode, aIgnoreARIAHidden);
|
||||
if (container && container->IsHTMLCombobox()) {
|
||||
return container->FirstChild();
|
||||
}
|
||||
|
|
|
@ -769,6 +769,19 @@ DocAccessible::AttributeChanged(dom::Element* aElement,
|
|||
if (UpdateAccessibleOnAttrChange(aElement, aAttribute))
|
||||
return;
|
||||
|
||||
// Update the accessible tree on aria-hidden change. Make sure to not create
|
||||
// a tree under aria-hidden='true'.
|
||||
if (aAttribute == nsGkAtoms::aria_hidden) {
|
||||
if (aria::HasDefinedARIAHidden(aElement)) {
|
||||
ContentRemoved(aElement);
|
||||
}
|
||||
else {
|
||||
ContentInserted(aElement->GetFlattenedTreeParent(),
|
||||
aElement, aElement->GetNextSibling());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore attribute change if the element doesn't have an accessible (at all
|
||||
// or still) iff the element is not a root content of this document accessible
|
||||
// (which is treated as attribute change on this document accessible).
|
||||
|
@ -992,22 +1005,6 @@ DocAccessible::ARIAAttributeChanged(Accessible* aAccessible, nsAtom* aAttribute)
|
|||
|
||||
dom::Element* elm = aAccessible->GetContent()->AsElement();
|
||||
|
||||
// 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() || !aAccessible->Parent()->IsARIAHidden())) {
|
||||
aAccessible->SetARIAHidden(isDefined);
|
||||
|
||||
RefPtr<AccEvent> event =
|
||||
new AccObjectAttrChangedEvent(aAccessible, aAttribute);
|
||||
FireDelayedEvent(event);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (aAttribute == nsGkAtoms::aria_checked ||
|
||||
(aAccessible->IsButton() &&
|
||||
aAttribute == nsGkAtoms::aria_pressed)) {
|
||||
|
@ -1233,13 +1230,21 @@ DocAccessible::GetAccessibleByUniqueIDInSubtree(void* aUniqueID)
|
|||
}
|
||||
|
||||
Accessible*
|
||||
DocAccessible::GetAccessibleOrContainer(nsINode* aNode) const
|
||||
DocAccessible::GetAccessibleOrContainer(nsINode* aNode,
|
||||
int aARIAHiddenFlag) const
|
||||
{
|
||||
if (!aNode || !aNode->GetComposedDoc())
|
||||
return nullptr;
|
||||
|
||||
for (nsINode* currNode = aNode; currNode;
|
||||
currNode = currNode->GetFlattenedTreeParentNode()) {
|
||||
|
||||
// No container if is inside of aria-hidden subtree.
|
||||
if (aARIAHiddenFlag == eNoContainerIfARIAHidden && currNode->IsElement() &&
|
||||
aria::HasDefinedARIAHidden(currNode->AsElement())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (Accessible* accessible = GetAccessible(currNode)) {
|
||||
return accessible;
|
||||
}
|
||||
|
@ -1797,7 +1802,8 @@ InsertIterator::Next()
|
|||
// what means there's no container. Ignore the insertion too.
|
||||
nsIContent* prevNode = mNodes->SafeElementAt(mNodesIdx - 1);
|
||||
nsIContent* node = mNodes->ElementAt(mNodesIdx++);
|
||||
Accessible* container = Document()->AccessibleOrTrueContainer(node);
|
||||
Accessible* container = Document()->
|
||||
AccessibleOrTrueContainer(node, DocAccessible::eNoContainerIfARIAHidden);
|
||||
if (container != Context()) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -278,7 +278,12 @@ public:
|
|||
* Return an accessible for the given DOM node or container accessible if
|
||||
* the node is not accessible.
|
||||
*/
|
||||
Accessible* GetAccessibleOrContainer(nsINode* aNode) const;
|
||||
enum {
|
||||
eIgnoreARIAHidden = 0,
|
||||
eNoContainerIfARIAHidden = 1
|
||||
};
|
||||
Accessible* GetAccessibleOrContainer(nsINode* aNode,
|
||||
int aARIAHiddenFlag = eIgnoreARIAHidden) const;
|
||||
|
||||
/**
|
||||
* Return a container accessible for the given DOM node.
|
||||
|
@ -292,7 +297,8 @@ public:
|
|||
* Return an accessible for the given node if any, or an immediate accessible
|
||||
* container for it.
|
||||
*/
|
||||
Accessible* AccessibleOrTrueContainer(nsINode* aNode) const;
|
||||
Accessible* AccessibleOrTrueContainer(nsINode* aNode,
|
||||
int aARIAHiddenFlag = eIgnoreARIAHidden) const;
|
||||
|
||||
/**
|
||||
* Return an accessible for the given node or its first accessible descendant.
|
||||
|
|
|
@ -229,8 +229,7 @@ interface nsIAccessibleTraversalRule : nsISupports
|
|||
const unsigned long PREFILTER_INVISIBLE = 0x00000001;
|
||||
const unsigned long PREFILTER_OFFSCREEN = 0x00000002;
|
||||
const unsigned long PREFILTER_NOT_FOCUSABLE = 0x00000004;
|
||||
const unsigned long PREFILTER_ARIA_HIDDEN = 0x00000008;
|
||||
const unsigned long PREFILTER_TRANSPARENT = 0x00000010;
|
||||
const unsigned long PREFILTER_TRANSPARENT = 0x00000008;
|
||||
|
||||
/**
|
||||
* Pre-filter bitfield to filter out obviously ignorable nodes and lighten
|
||||
|
|
|
@ -215,21 +215,6 @@ this.EventManager.prototype = {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case Events.OBJECT_ATTRIBUTE_CHANGED:
|
||||
{
|
||||
let evt = aEvent.QueryInterface(
|
||||
Ci.nsIAccessibleObjectAttributeChangedEvent);
|
||||
if (evt.changedAttribute !== "aria-hidden") {
|
||||
// Only handle aria-hidden attribute change.
|
||||
break;
|
||||
}
|
||||
let hidden = Utils.isHidden(aEvent.accessible);
|
||||
this[hidden ? "_handleHide" : "_handleShow"](evt);
|
||||
if (this.inTest) {
|
||||
this.sendMsgFunc("AccessFu:AriaHidden", { hidden });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Events.SHOW:
|
||||
{
|
||||
this._handleShow(aEvent);
|
||||
|
@ -629,7 +614,16 @@ const AccessibilityEventObserver = {
|
|||
Logger.accessibleToString(event.accessible));
|
||||
return;
|
||||
}
|
||||
let content = event.accessibleDocument.window;
|
||||
let content;
|
||||
try {
|
||||
content = event.accessibleDocument.window;
|
||||
} catch (e) {
|
||||
Logger.warning(
|
||||
"AccessibilityEventObserver.observe: no window for accessible document:",
|
||||
Logger.eventToString(event), "accessible:",
|
||||
Logger.accessibleToString(event.accessible));
|
||||
return;
|
||||
}
|
||||
// Match the content window to its EventManager.
|
||||
let eventManager = this.getListener(content);
|
||||
if (!eventManager || !eventManager._started) {
|
||||
|
|
|
@ -177,7 +177,6 @@ var gSimpleMatchFunc = function gSimpleMatchFunc(aAccessible) {
|
|||
|
||||
var gSimplePreFilter = Prefilters.DEFUNCT |
|
||||
Prefilters.INVISIBLE |
|
||||
Prefilters.ARIA_HIDDEN |
|
||||
Prefilters.TRANSPARENT;
|
||||
|
||||
var TraversalRules = { // jshint ignore:line
|
||||
|
@ -185,7 +184,7 @@ var TraversalRules = { // jshint ignore:line
|
|||
|
||||
SimpleOnScreen: new BaseTraversalRule(
|
||||
gSimpleTraversalRoles, gSimpleMatchFunc,
|
||||
Prefilters.DEFUNCT | Prefilters.INVISIBLE | Prefilters.ARIA_HIDDEN |
|
||||
Prefilters.DEFUNCT | Prefilters.INVISIBLE |
|
||||
Prefilters.TRANSPARENT | Prefilters.OFFSCREEN),
|
||||
|
||||
Anchor: new BaseTraversalRule(
|
||||
|
|
|
@ -277,32 +277,14 @@ var Utils = { // jshint ignore:line
|
|||
return false;
|
||||
},
|
||||
|
||||
isHidden: function isHidden(aAccessible) {
|
||||
// Need to account for aria-hidden, so can't just check for INVISIBLE
|
||||
// state.
|
||||
let hidden = Utils.getAttributes(aAccessible).hidden;
|
||||
return hidden && hidden === "true";
|
||||
},
|
||||
|
||||
visibleChildCount: function visibleChildCount(aAccessible) {
|
||||
let count = 0;
|
||||
for (let child = aAccessible.firstChild; child; child = child.nextSibling) {
|
||||
if (!this.isHidden(child)) {
|
||||
++count;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
},
|
||||
|
||||
inHiddenSubtree: function inHiddenSubtree(aAccessible) {
|
||||
for (let acc = aAccessible; acc; acc = acc.parent) {
|
||||
if (this.isHidden(acc)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
isAliveAndVisible: function isAliveAndVisible(aAccessible, aIsOnScreen) {
|
||||
if (!aAccessible) {
|
||||
return false;
|
||||
|
@ -311,8 +293,7 @@ var Utils = { // jshint ignore:line
|
|||
try {
|
||||
let state = this.getState(aAccessible);
|
||||
if (state.contains(States.DEFUNCT) || state.contains(States.INVISIBLE) ||
|
||||
(aIsOnScreen && state.contains(States.OFFSCREEN)) ||
|
||||
Utils.inHiddenSubtree(aAccessible)) {
|
||||
(aIsOnScreen && state.contains(States.OFFSCREEN))) {
|
||||
return false;
|
||||
}
|
||||
} catch (x) {
|
||||
|
@ -731,12 +712,7 @@ PivotContext.prototype = {
|
|||
}
|
||||
let child = aAccessible.firstChild;
|
||||
while (child) {
|
||||
let include;
|
||||
if (this._includeInvisible) {
|
||||
include = true;
|
||||
} else {
|
||||
include = !Utils.isHidden(child);
|
||||
}
|
||||
let include = true;
|
||||
if (include) {
|
||||
if (aPreorder) {
|
||||
yield child;
|
||||
|
|
|
@ -44,8 +44,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
|
|||
testAttrs("haspopupListbox", { "haspopup": "listbox" }, true);
|
||||
testAttrs("haspopupMenu", { "haspopup": "menu" }, true);
|
||||
testAttrs("haspopupTree", { "haspopup": "tree" }, true);
|
||||
testAttrs("hidden", {"hidden": "true"}, true);
|
||||
testAbsentAttrs("hidden_false", { "hidden": "false" });
|
||||
testAbsentAttrs("modal", {"modal": "true"});
|
||||
testAttrs("sortAscending", {"sort": "ascending"}, true);
|
||||
testAttrs("sortDescending", {"sort": "descending"}, true);
|
||||
|
@ -155,51 +153,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
|
|||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=475006"
|
||||
title="Extend nsARIAMap to capture ARIA attribute characteristics">
|
||||
Mozilla Bug 475006
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=391829"
|
||||
title="Add support for container-live-role to object attributes">
|
||||
Mozilla Bug 391829
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=581952"
|
||||
title="Make explicit that aria-label is not an object attribute">
|
||||
Mozilla Bug 475006
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=558036"
|
||||
title="make HTML <output> accessible">
|
||||
Mozilla Bug 558036
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=896400"
|
||||
title="Tablist should no longer be an implicit live region">
|
||||
Mozilla Bug 896400
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=563862"
|
||||
title="Expand support for nsIAccessibleEvent::OBJECT_ATTRIBUTE_CHANGE">
|
||||
Mozilla Bug 563862
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=819303"
|
||||
title="crash in nsTextEquivUtils::AppendTextEquivFromTextContent">
|
||||
Mozilla Bug 819303
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=838407"
|
||||
title="aria-hidden false value shouldn't be exposed via object attributes">
|
||||
Mozilla Bug 838407
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1121518"
|
||||
title="ARIA 1.1: Support role 'searchbox'">
|
||||
Mozilla Bug 1121518
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
|
@ -226,8 +179,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=558036
|
|||
<div id="haspopupListbox" aria-haspopup="listbox"></div>
|
||||
<div id="haspopupMenu" aria-haspopup="menu"></div>
|
||||
<div id="haspopupTree" aria-haspopup="tree"></div>
|
||||
<div id="hidden" aria-hidden="true"></div>
|
||||
<div id="hidden_false" aria-hidden="false"></div>
|
||||
<div id="modal" aria-modal="true"></div>
|
||||
<div id="sortAscending" role="columnheader" aria-sort="ascending"></div>
|
||||
<div id="sortDescending" role="columnheader" aria-sort="descending"></div>
|
||||
|
|
|
@ -113,6 +113,28 @@ function waitForEvent(aEventType, aTargetOrFunc, aFunc, aContext, aArg1, aArg2)
|
|||
registerA11yEventListener(aEventType, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* A promise based version of waitForEvent function.
|
||||
*/
|
||||
function waitForEventPromise(eventType, target) {
|
||||
return new Promise(resolve => {
|
||||
let eventObserver = {
|
||||
observe(subject, topic, data) {
|
||||
let event = subject.QueryInterface(nsIAccessibleEvent);
|
||||
if (event.eventType !== eventType) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.accessible == getAccessible(target)) {
|
||||
Services.obs.removeObserver(this, "accessible-event");
|
||||
resolve(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
Services.obs.addObserver(eventObserver, "accessible-event");
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate mouse move over image map what creates image map accessible (async).
|
||||
* See waitForImageMap() function.
|
||||
|
|
|
@ -39,31 +39,10 @@
|
|||
};
|
||||
}
|
||||
|
||||
function updateARIAHidden(aID, aIsDefined, aChildId) {
|
||||
this.__proto__ = new updateAttribute(aID, "aria-hidden",
|
||||
aIsDefined ? "true" : "false");
|
||||
|
||||
this.finalCheck = function updateARIAHidden_finalCheck() {
|
||||
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;
|
||||
|
||||
function doTests() {
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new updateARIAHidden("hideable", true, "hideable_child"));
|
||||
gQueue.push(new updateARIAHidden("hideable", false, "hideable_child"));
|
||||
|
||||
gQueue.push(new updateAttribute("sortable", "aria-sort", "ascending"));
|
||||
|
||||
// For experimental ARIA extensions
|
||||
|
@ -78,32 +57,10 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=581096"
|
||||
title="Add support for aria-hidden">
|
||||
Mozilla Bug 581096
|
||||
</a>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=640707"
|
||||
title="Add event support for aria-sort">
|
||||
Mozilla Bug 640707
|
||||
</a>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=640707"
|
||||
title="Expand support for aria attribute change events">
|
||||
Mozilla Bug 563862
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="eventdump"></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>
|
||||
|
||||
|
|
|
@ -294,7 +294,10 @@
|
|||
// Changing aria-hidden attribute twice and making sure that the event
|
||||
// is fired only once when the actual change happens.
|
||||
doc.getElementById("back").setAttribute("aria-hidden", true);
|
||||
let onShow = waitForEventPromise(EVENT_SHOW, doc.getElementById("back"));
|
||||
doc.getElementById("back").setAttribute("aria-hidden", false);
|
||||
await onShow;
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Back", "button"]);
|
||||
|
@ -311,13 +314,14 @@
|
|||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
|
||||
|
||||
|
||||
evt = await runner.expectAndroidEvents(() => {
|
||||
doc.getElementById("iframe").setAttribute("aria-hidden", true);
|
||||
}, AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Home", "button"]);
|
||||
runner.eventTextMatches(evt, ["Traversal Rule test document", "Home", "button"]);
|
||||
|
||||
onShow = waitForEventPromise(EVENT_SHOW, doc.getElementById("iframe"));
|
||||
doc.getElementById("iframe").setAttribute("aria-hidden", false);
|
||||
await onShow;
|
||||
await runner.clearCursor();
|
||||
|
||||
// aria-hidden element and auto Move
|
||||
|
@ -330,7 +334,9 @@
|
|||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
|
||||
|
||||
onShow = waitForEventPromise(EVENT_SHOW, doc.getElementById("back"));
|
||||
doc.getElementById("back").setAttribute("aria-hidden", false);
|
||||
await onShow;
|
||||
runner.blur();
|
||||
await runner.clearCursor();
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
// Constants
|
||||
|
||||
const PREFILTER_INVISIBLE = nsIAccessibleTraversalRule.PREFILTER_INVISIBLE;
|
||||
const PREFILTER_ARIA_HIDDEN = nsIAccessibleTraversalRule.PREFILTER_ARIA_HIDDEN;
|
||||
const PREFILTER_TRANSPARENT = nsIAccessibleTraversalRule.PREFILTER_TRANSPARENT;
|
||||
const FILTER_MATCH = nsIAccessibleTraversalRule.FILTER_MATCH;
|
||||
const FILTER_IGNORE = nsIAccessibleTraversalRule.FILTER_IGNORE;
|
||||
|
@ -47,7 +46,7 @@ var ObjectTraversalRule =
|
|||
return 0;
|
||||
},
|
||||
|
||||
preFilter: PREFILTER_INVISIBLE | PREFILTER_ARIA_HIDDEN | PREFILTER_TRANSPARENT,
|
||||
preFilter: PREFILTER_INVISIBLE | PREFILTER_TRANSPARENT,
|
||||
|
||||
match(aAccessible) {
|
||||
var rv = FILTER_IGNORE;
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
};
|
||||
|
||||
queueTraversalSequence(gQueue, docAcc, HeadersTraversalRule, null,
|
||||
["heading-1-1", "heading-2-1", "heading-2-2"]);
|
||||
["heading-1-1", "heading-2-2"]);
|
||||
|
||||
queueTraversalSequence(
|
||||
gQueue, docAcc, ObjectTraversalRule, null,
|
||||
|
@ -93,13 +93,7 @@
|
|||
gQueue.push(new setModalRootInvoker(docAcc, docAcc.parent,
|
||||
NS_ERROR_INVALID_ARG));
|
||||
|
||||
// Put cursor in an ignored subtree
|
||||
// set isFromUserInput to false, just to test..
|
||||
gQueue.push(new setVCPosInvoker(docAcc, null, null,
|
||||
getAccessible(doc.getElementById("hidden-link")),
|
||||
false));
|
||||
// Next item shoud be outside of that subtree
|
||||
gQueue.push(new setVCPosInvoker(docAcc, "moveNext", ObjectTraversalRule, "An "));
|
||||
gQueue.push(new setVCPosInvoker(docAcc, "moveNext", ObjectTraversalRule, "dolor"));
|
||||
|
||||
gQueue.invoke();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
"flowto",
|
||||
"grabbed",
|
||||
"haspopup",
|
||||
"hidden",
|
||||
"invalid",
|
||||
"label",
|
||||
"labelledby",
|
||||
|
@ -94,7 +93,6 @@
|
|||
<span id="flowto" aria-flowto="pawn"></span>
|
||||
<span id="grabbed" aria-grabbed="false"></span>
|
||||
<span id="haspopup" aria-haspopup="false"></span>
|
||||
<span id="hidden" aria-hidden="true"></span>
|
||||
<span id="invalid" aria-invalid="false"></span>
|
||||
<span id="label" aria-label="hi"></span>
|
||||
<span id="labelledby" aria-labelledby="label"></span>
|
||||
|
@ -115,7 +113,6 @@
|
|||
<td id="td_flowto" aria-flowto="pawn"></td>
|
||||
<td id="td_grabbed" aria-grabbed="false"></td>
|
||||
<td id="td_haspopup" aria-haspopup="false"></td>
|
||||
<td id="td_hidden" aria-hidden="true"></td>
|
||||
<td id="td_invalid" aria-invalid="false"></td>
|
||||
<td id="td_label" aria-label="hi"></td>
|
||||
<td id="td_labelledby" aria-labelledby="label"></td>
|
||||
|
|
|
@ -44,17 +44,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=483573
|
|||
// name: "0:00 of 0:02 elapsed",
|
||||
children: []
|
||||
},
|
||||
{
|
||||
role: ROLE_TEXT_CONTAINER,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_TEXT_LEAF, // position text
|
||||
},
|
||||
{
|
||||
role: ROLE_TEXT_LEAF, // duration text
|
||||
}
|
||||
]
|
||||
},
|
||||
{ // mute button
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "Mute",
|
||||
|
|
|
@ -5,6 +5,7 @@ support-files =
|
|||
!/accessible/tests/mochitest/moz.png
|
||||
|
||||
[test_ariadialog.html]
|
||||
[test_ariahidden.html]
|
||||
[test_ariaowns.html]
|
||||
[test_bug852150.xhtml]
|
||||
[test_bug883708.xhtml]
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>aria-hidden tree update tests</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function t1_setARIAHidden() {
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, "t1")
|
||||
];
|
||||
|
||||
this.invoke = function t1_setARIAHidden_invoke() {
|
||||
getNode("t1_child").setAttribute("aria-hidden", "true");
|
||||
};
|
||||
|
||||
this.finalCheck = function t1_setARIAHidden_finalCheck() {
|
||||
ok(!isAccessible("t1_child"), "No accessible for aria-hidden");
|
||||
};
|
||||
|
||||
this.getID = function t1_setARIAHidden_getID() {
|
||||
return "aria-hidden set to true";
|
||||
};
|
||||
}
|
||||
|
||||
function t1_removeARIAHidden() {
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, "t1")
|
||||
];
|
||||
|
||||
this.invoke = function t1_removeARIAHidden_invoke() {
|
||||
getNode("t1_child").removeAttribute("aria-hidden");
|
||||
};
|
||||
|
||||
this.finalCheck = function t1_removeARIAHidden_finalCheck() {
|
||||
ok(isAccessible("t1_child"), "No aria-hidden, has to be accessible");
|
||||
};
|
||||
|
||||
this.getID = function t1_removeARIAHidden_getID() {
|
||||
return "remove aria-hidden";
|
||||
};
|
||||
}
|
||||
|
||||
function t2_setARIAHidden() {
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, "t2")
|
||||
];
|
||||
|
||||
this.invoke = function t2_setARIAHidden_invoke() {
|
||||
getNode("t2_child").setAttribute("aria-hidden", "true");
|
||||
};
|
||||
|
||||
this.finalCheck = function t2_setARIAHidden_finalCheck() {
|
||||
testAccessibleTree("t2", { SECTION: []});
|
||||
};
|
||||
|
||||
this.getID = function t2_setARIAHidden_getID() {
|
||||
return "t2: set aria-hidden";
|
||||
};
|
||||
}
|
||||
|
||||
function t2_insertUnderARIAHidden() {
|
||||
this.eventSeq = [
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, "t2")
|
||||
];
|
||||
|
||||
this.invoke = function t2_insertUnderARIAHidden_invoke() {
|
||||
getNode("t2_child").innerHTML = "<input>";
|
||||
};
|
||||
|
||||
this.finalCheck = function t2_insertUnderARIAHidden_finalCheck() {
|
||||
testAccessibleTree("t2", { SECTION: []});
|
||||
};
|
||||
|
||||
this.getID = function t2_insertUnderARIAHidden_getID() {
|
||||
return "t2: insert under aria-hidden";
|
||||
};
|
||||
}
|
||||
|
||||
// gA11yEventDumpToConsole = true;
|
||||
function doTests() {
|
||||
ok(!isAccessible("t1_child"), "No accessible for aria-hidden");
|
||||
|
||||
gQueue = new eventQueue();
|
||||
gQueue.push(new t1_removeARIAHidden());
|
||||
gQueue.push(new t1_setARIAHidden());
|
||||
gQueue.push(new t2_setARIAHidden());
|
||||
gQueue.push(new t2_insertUnderARIAHidden());
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="t1"><div id="t1_child" aria-hidden="true">Hi</div><div>there</div></div>
|
||||
<div id="t2">
|
||||
<span id="t2_child">hoho</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче