1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
|
<html>
<head>
<title>Test updating of accessible relations</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../relations.js"></script>
<script type="application/javascript"
src="../role.js"></script>
<script type="application/javascript"
src="../events.js"></script>
<script type="application/javascript">
function testRelated(aRelAttr, aHostRelation, aDependentRelation,
aHostID, aHostNodeID, aDependent1ID, aDependent2ID) {
// no attribute
testRelation(aDependent1ID, aDependentRelation, null);
testRelation(aDependent2ID, aDependentRelation, null);
if (aHostRelation)
testRelation(aHostID, aHostRelation, null);
// set attribute
getNode(aHostNodeID).setAttribute(aRelAttr, aDependent1ID);
testRelation(aDependent1ID, aDependentRelation, aHostID);
testRelation(aDependent2ID, aDependentRelation, null);
if (aHostRelation)
testRelation(aHostID, aHostRelation, aDependent1ID);
// change attribute
getNode(aHostNodeID).setAttribute(aRelAttr, aDependent2ID);
testRelation(aDependent1ID, aDependentRelation, null);
testRelation(aDependent2ID, aDependentRelation, aHostID);
if (aHostRelation)
testRelation(aHostID, aHostRelation, aDependent2ID);
// remove attribute
getNode(aHostNodeID).removeAttribute(aRelAttr);
testRelation(aDependent1ID, aDependentRelation, null);
testRelation(aDependent2ID, aDependentRelation, null);
if (aHostRelation)
testRelation(aHostID, aHostRelation, null);
}
function insertRelated(aHostRelAttr, aDependentID, aInsertHostFirst,
aHostRelation, aDependentRelation) {
this.eventSeq = [
new invokerChecker(EVENT_REORDER, document),
];
this.invoke = function insertRelated_invoke() {
this.hostNode = document.createElement("div");
this.hostNode.setAttribute(aHostRelAttr, aDependentID);
this.dependentNode = document.createElement("div");
this.dependentNode.setAttribute("id", aDependentID);
if (aInsertHostFirst) {
document.body.appendChild(this.hostNode);
document.body.appendChild(this.dependentNode);
} else {
document.body.appendChild(this.dependentNode);
document.body.appendChild(this.hostNode);
}
};
this.finalCheck = function insertRelated_finalCheck() {
testRelation(this.dependentNode, aDependentRelation, this.hostNode);
if (aHostRelation)
testRelation(this.hostNode, aHostRelation, this.dependentNode);
};
this.getID = function insertRelated_getID() {
return "Insert " + aHostRelAttr + "='" + aDependentID + "' node" +
(aInsertHostFirst ? " before" : "after") + " dependent node";
};
}
/**
* Relative accessible recreation shouldn't break accessible relations.
* Note: modify this case if the invoke function doesn't change accessible
* tree due to changes in layout module. It can be changed on any case
* when accessibles are recreated.
*/
function recreateRelatives(aContainerID, aLabelID, aElmID) {
this.containerNode = getNode(aContainerID);
this.container = getNode(this.containerNode);
this.eventSeq = [
new invokerChecker(EVENT_HIDE, this.container),
new invokerChecker(EVENT_SHOW, this.containerNode),
];
this.invoke = function recreateRelatives_invoke() {
testRelation(aLabelID, RELATION_LABEL_FOR, aElmID);
testRelation(aElmID, RELATION_LABELLED_BY, aLabelID);
this.containerNode.setAttribute('role', 'group');
};
this.finalCheck = function recreateRelatives_finalCheck() {
testRelation(aLabelID, RELATION_LABEL_FOR, aElmID);
testRelation(aElmID, RELATION_LABELLED_BY, aLabelID);
};
this.getID = function recreateRelatives_getID() {
return "recreate relatives ";
};
}
// gA11yEventDumpToConsole = true; // debug
var gQueue = null;
function doTest() {
// Relation updates on ARIA attribute changes.
testRelated("aria-labelledby",
RELATION_LABELLED_BY, RELATION_LABEL_FOR,
"host", "host", "dependent1", "dependent2");
testRelated("aria-describedby",
RELATION_DESCRIBED_BY, RELATION_DESCRIPTION_FOR,
"host", "host", "dependent1", "dependent2");
testRelated("aria-controls",
RELATION_CONTROLLER_FOR, RELATION_CONTROLLED_BY,
"host", "host", "dependent1", "dependent2");
testRelated("aria-flowto",
RELATION_FLOWS_TO, RELATION_FLOWS_FROM,
"host", "host", "dependent1", "dependent2");
// Document relation updates on ARIA attribute change.
testRelated("aria-labelledby",
RELATION_LABELLED_BY, RELATION_LABEL_FOR,
document, "body", "dependent1", "dependent2");
// Insert related accessibles into tree.
gQueue = new eventQueue();
gQueue.push(new insertRelated("aria-labelledby", "dependent3", true,
RELATION_LABELLED_BY, RELATION_LABEL_FOR));
gQueue.push(new insertRelated("aria-labelledby", "dependent4", false,
RELATION_LABELLED_BY, RELATION_LABEL_FOR));
gQueue.push(new insertRelated("aria-describedby", "dependent5", true,
RELATION_DESCRIBED_BY,
RELATION_DESCRIPTION_FOR));
gQueue.push(new insertRelated("aria-describedby", "dependent6", false,
RELATION_DESCRIBED_BY,
RELATION_DESCRIPTION_FOR));
gQueue.push(new insertRelated("aria-controls", "dependent9", true,
RELATION_CONTROLLER_FOR,
RELATION_CONTROLLED_BY));
gQueue.push(new insertRelated("aria-controls", "dependent10", false,
RELATION_CONTROLLER_FOR,
RELATION_CONTROLLED_BY));
gQueue.push(new insertRelated("aria-flowto", "dependent11", true,
RELATION_FLOWS_TO, RELATION_FLOWS_FROM));
gQueue.push(new insertRelated("aria-flowto", "dependent12", false,
RELATION_FLOWS_TO, RELATION_FLOWS_FROM));
// Update relations when accessibles are recreated
gQueue.push(new recreateRelatives("container", "label", "input"));
gQueue.invoke(); // will call SimpleTest.finish()
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body id="body">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=573469"
title="Cache relations defined by ARIA attributes">
Mozilla Bug 573469
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=631068"
title="Accessible recreation breaks relations">
Mozilla Bug 631068
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=635346"
title="Allow relations for document defined on document content">
Mozilla Bug 635346
</a>
<br>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="dependent1">label</div>
<div id="dependent2">label2</div>
<div role="checkbox" id="host"></div>
<form id="container" style="overflow: hidden;">
<label for="input" id="label">label</label>
<input id="input">
</form>
</body>
</html>
|