Bug 1349223 - cut aria-hidden tree, r=yzen

This commit is contained in:
Alexander Surkov 2018-07-04 10:18:43 -04:00 коммит произвёл Yura Zenevich
Родитель d0d6e91dfa
Коммит 32562a67f0
23 изменённых файлов: 219 добавлений и 235 удалений

Просмотреть файл

@ -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>