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