summaryrefslogtreecommitdiffstats
path: root/accessible/tests/mochitest/relations
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/tests/mochitest/relations')
-rw-r--r--accessible/tests/mochitest/relations/a11y.ini12
-rw-r--r--accessible/tests/mochitest/relations/test_bindings.xhtml103
-rw-r--r--accessible/tests/mochitest/relations/test_embeds.xul122
-rw-r--r--accessible/tests/mochitest/relations/test_general.html406
-rw-r--r--accessible/tests/mochitest/relations/test_general.xul238
-rw-r--r--accessible/tests/mochitest/relations/test_tabbrowser.xul103
-rw-r--r--accessible/tests/mochitest/relations/test_tree.xul106
-rw-r--r--accessible/tests/mochitest/relations/test_ui_modalprompt.html107
-rw-r--r--accessible/tests/mochitest/relations/test_update.html225
9 files changed, 1422 insertions, 0 deletions
diff --git a/accessible/tests/mochitest/relations/a11y.ini b/accessible/tests/mochitest/relations/a11y.ini
new file mode 100644
index 000000000..a2da0cf2e
--- /dev/null
+++ b/accessible/tests/mochitest/relations/a11y.ini
@@ -0,0 +1,12 @@
+[DEFAULT]
+support-files =
+ !/accessible/tests/mochitest/*.js
+
+[test_bindings.xhtml]
+[test_embeds.xul]
+[test_general.html]
+[test_general.xul]
+[test_tabbrowser.xul]
+[test_tree.xul]
+[test_ui_modalprompt.html]
+[test_update.html]
diff --git a/accessible/tests/mochitest/relations/test_bindings.xhtml b/accessible/tests/mochitest/relations/test_bindings.xhtml
new file mode 100644
index 000000000..65a7a0875
--- /dev/null
+++ b/accessible/tests/mochitest/relations/test_bindings.xhtml
@@ -0,0 +1,103 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+ <title>Accessible relations for bindings</title>
+
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <style>
+ .button {
+ -moz-binding: url('#custombutton');
+ }
+
+ .button2 {
+ -moz-binding: url('#custombutton2');
+ }
+ </style>
+
+ <bindings xmlns="http://www.mozilla.org/xbl">
+ <binding id="custombutton">
+ <content aria-labelledby="button.label label">
+ <label xmlns="http://www.w3.org/1999/xhtml" anonid="button.label">
+ anon label
+ </label>
+ <button xmlns="http://www.w3.org/1999/xhtml" anonid="button.button"
+ aria-labelledby="button.label label">
+ a button
+ </button>
+ <div xmlns="http://www.w3.org/1999/xhtml"
+ anonid="button.button2" class="button2"
+ aria-labelledby="button.label"></div>
+ <div xmlns="http://www.w3.org/1999/xhtml"
+ anonid="button.button3" class="button2"></div>
+ </content>
+ </binding>
+ <binding id="custombutton2">
+ <content aria-labelledby="button2.label">
+ <label xmlns="http://www.w3.org/1999/xhtml" anonid="button2.label">
+ nested anon label
+ </label>
+ </content>
+ </binding>
+ </bindings>
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../relations.js"></script>
+
+ <script type="application/javascript">
+ function doTests()
+ {
+ var button = document.getElementById("button");
+ var anonLabel = document.
+ getAnonymousElementByAttribute(button, "anonid", "button.label");
+ var anonButton = document.
+ getAnonymousElementByAttribute(button, "anonid", "button.button");
+ var anonButton2 = document.
+ getAnonymousElementByAttribute(button, "anonid", "button.button2");
+ var anonButton3 = document.
+ getAnonymousElementByAttribute(button, "anonid", "button.button3");
+ var anonAnonLabel = document.
+ getAnonymousElementByAttribute(anonButton3, "anonid", "button2.label");
+
+ testRelation("label", RELATION_LABEL_FOR, button);
+ testRelation(anonLabel, RELATION_LABEL_FOR, [button, anonButton, anonButton2]);
+ testRelation(button, RELATION_LABELLED_BY, [anonLabel, "label"]);
+ testRelation(anonButton, RELATION_LABELLED_BY, anonLabel);
+ testRelation(anonButton2, RELATION_LABELLED_BY, anonLabel);
+ testRelation(anonButton3, RELATION_LABELLED_BY, anonAnonLabel);
+ testRelation(anonAnonLabel, RELATION_LABEL_FOR, anonButton3);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTests);
+ </script>
+</head>
+
+<body>
+
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=421242"
+ title="Allow relations in anonymous content for binding parent">
+ Mozilla Bug 421242
+ </a>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+ <div id="eventdump"></div>
+
+ <label id="label">explicit label</label>
+ <div id="button" class="button"></div>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/relations/test_embeds.xul b/accessible/tests/mochitest/relations/test_embeds.xul
new file mode 100644
index 000000000..0cb6d6c65
--- /dev/null
+++ b/accessible/tests/mochitest/relations/test_embeds.xul
@@ -0,0 +1,122 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+ type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Embeds relation tests">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+ <script type="application/javascript"
+ src="../common.js"></script>
+ <script type="application/javascript"
+ src="../role.js"></script>
+ <script type="application/javascript"
+ src="../states.js"></script>
+ <script type="application/javascript"
+ src="../events.js"></script>
+ <script type="application/javascript"
+ src="../relations.js"></script>
+ <script type="application/javascript"
+ src="../browser.js"></script>
+
+ <script type="application/javascript">
+ <![CDATA[
+ ////////////////////////////////////////////////////////////////////////////
+ // Invokers
+
+ function loadURI(aURI)
+ {
+ this.invoke = function loadURI_invoke()
+ {
+ tabBrowser().loadURI(aURI);
+ }
+
+ this.eventSeq = [
+ new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument)
+ ];
+
+ this.finalCheck = function loadURI_finalCheck()
+ {
+ testRelation(browserDocument(), RELATION_EMBEDS,
+ getAccessible(currentTabDocument()));
+ }
+
+ this.getID = function loadURI_getID()
+ {
+ return "load uri " + aURI;
+ }
+ }
+
+ function loadOneTab(aURI)
+ {
+ this.invoke = function loadOneTab_invoke()
+ {
+ tabBrowser().loadOneTab(aURI, null, null, null, false);
+ }
+
+ this.eventSeq = [
+ new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument)
+ ];
+
+ this.finalCheck = function loadURI_finalCheck()
+ {
+ testRelation(browserDocument(), RELATION_EMBEDS,
+ getAccessible(currentTabDocument()));
+ }
+
+ this.getID = function loadOneTab_getID()
+ {
+ return "load uri '" + aURI + "' in new tab";
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Testing
+
+ //gA11yEventDumpToConsole = true; // debug
+
+ var gQueue = null;
+ function doTests()
+ {
+ testRelation(browserDocument(), RELATION_EMBEDS,
+ getAccessible(currentTabDocument()));
+
+ enableLogging("docload");
+ gQueue = new eventQueue();
+
+ gQueue.push(new loadURI("about:about"));
+ gQueue.push(new loadOneTab("about:mozilla"));
+
+ gQueue.onFinish = function()
+ {
+ disableLogging();
+ closeBrowserWindow();
+ }
+ gQueue.invoke();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ openBrowserWindow(doTests, "about:");
+ ]]>
+ </script>
+
+ <vbox flex="1" style="overflow: auto;">
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=707654"
+ title="Embeds relation on root accessible can return not content document">
+ Mozilla Bug 707654
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+ </vbox>
+</window>
diff --git a/accessible/tests/mochitest/relations/test_general.html b/accessible/tests/mochitest/relations/test_general.html
new file mode 100644
index 000000000..bcb1d282a
--- /dev/null
+++ b/accessible/tests/mochitest/relations/test_general.html
@@ -0,0 +1,406 @@
+<html>
+
+<head>
+ <title>nsIAccessible::getAccessibleRelated() 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="../relations.js"></script>
+ <script type="application/javascript"
+ src="../role.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ // html:label@for
+ testRelation("label1_1", RELATION_LABEL_FOR, "control1_1");
+ testRelation("control1_1", RELATION_LABELLED_BY, "label1_1");
+
+ // html:label@for, multiple
+ testRelation("label1_2", RELATION_LABEL_FOR, "control1_2");
+ testRelation("label1_3", RELATION_LABEL_FOR, "control1_2");
+ testRelation("control1_2", RELATION_LABELLED_BY,
+ [ "label1_2", "label1_3" ]);
+
+ // ancestor html:label (implicit association)
+ testRelation("label1_4", RELATION_LABEL_FOR, "control1_4");
+ testRelation("control1_4", RELATION_LABELLED_BY, "label1_4");
+ testRelation("control1_4_option1", RELATION_LABELLED_BY, null);
+ testRelation("label1_5", RELATION_LABEL_FOR, "control1_5");
+ testRelation("control1_5", RELATION_LABELLED_BY, "label1_5");
+ testRelation("label1_6", RELATION_LABEL_FOR, "control1_6");
+ testRelation("control1_6", RELATION_LABELLED_BY, "label1_6");
+ testRelation("label1_7", RELATION_LABEL_FOR, "control1_7");
+ testRelation("control1_7", RELATION_LABELLED_BY, "label1_7");
+ testRelation("label1_8", RELATION_LABEL_FOR, "control1_8");
+ testRelation("control1_8", RELATION_LABELLED_BY, "label1_8");
+ testRelation("label1_9", RELATION_LABEL_FOR, "control1_9");
+ testRelation("control1_9", RELATION_LABELLED_BY, "label1_9");
+ testRelation("label1_10", RELATION_LABEL_FOR, "control1_10");
+ testRelation("control1_10", RELATION_LABELLED_BY, "label1_10");
+ testRelation("label1_11", RELATION_LABEL_FOR, "control1_11");
+ testRelation("control1_11", RELATION_LABELLED_BY, "label1_11");
+ testRelation("label1_12", RELATION_LABEL_FOR, "control1_12");
+ testRelation("control1_12", RELATION_LABELLED_BY, "label1_12");
+
+ testRelation("label1_13", RELATION_LABEL_FOR, null);
+ testRelation("control1_13", RELATION_LABELLED_BY, null);
+ testRelation("control1_14", RELATION_LABELLED_BY, "label1_14");
+
+ // aria-labelledby
+ testRelation("label2", RELATION_LABEL_FOR, "checkbox2");
+ testRelation("checkbox2", RELATION_LABELLED_BY, "label2");
+
+ // aria-labelledby, multiple relations
+ testRelation("label3", RELATION_LABEL_FOR, "checkbox3");
+ testRelation("label4", RELATION_LABEL_FOR, "checkbox3");
+ testRelation("checkbox3", RELATION_LABELLED_BY, ["label3", "label4"]);
+
+ // aria-describedby
+ testRelation("descr1", RELATION_DESCRIPTION_FOR, "checkbox4");
+ testRelation("checkbox4", RELATION_DESCRIBED_BY, "descr1");
+
+ // aria-describedby, multiple relations
+ testRelation("descr2", RELATION_DESCRIPTION_FOR, "checkbox5");
+ testRelation("descr3", RELATION_DESCRIPTION_FOR, "checkbox5");
+ testRelation("checkbox5", RELATION_DESCRIBED_BY, ["descr2", "descr3"]);
+
+ // aria_owns, multiple relations
+ testRelation("treeitem1", RELATION_NODE_CHILD_OF, "tree");
+ testRelation("treeitem2", RELATION_NODE_CHILD_OF, "tree");
+
+ // 'node child of' relation for outlineitem role
+ testRelation("treeitem3", RELATION_NODE_CHILD_OF, "tree");
+ testRelation("treeitem4", RELATION_NODE_CHILD_OF, "tree");
+ testRelation("treeitem5", RELATION_NODE_CHILD_OF, "treeitem4");
+ testRelation("treeitem6", RELATION_NODE_CHILD_OF, "tree");
+ testRelation("treeitem7", RELATION_NODE_CHILD_OF, "treeitem6");
+ testRelation("tree2_ti1", RELATION_NODE_CHILD_OF, "tree2");
+ testRelation("tree2_ti1a", RELATION_NODE_CHILD_OF, "tree2_ti1");
+ testRelation("tree2_ti1b", RELATION_NODE_CHILD_OF, "tree2_ti1");
+
+ // 'node child of' relation for row role in grid.
+ // Relation for row associated using aria-level should exist.
+ testRelation("simplegrid-row3", RELATION_NODE_CHILD_OF,
+ "simplegrid-row2");
+ // Relations for hierarchical children elements shouldn't exist.
+ testAbsentRelation("simplegrid-row1", RELATION_NODE_CHILD_OF,
+ "simplegrid");
+ testAbsentRelation("simplegrid-row2", RELATION_NODE_CHILD_OF,
+ "simplegrid");
+
+ // 'node child of' relation for row role of treegrid
+ testRelation("treegridrow1", RELATION_NODE_CHILD_OF, "treegrid");
+ testRelation("treegridrow2", RELATION_NODE_CHILD_OF, "treegrid");
+ testRelation("treegridrow3", RELATION_NODE_CHILD_OF, "treegridrow2");
+
+ // 'node child of' relation for lists organized by groups
+ testRelation("listitem1", RELATION_NODE_CHILD_OF, "list");
+ testRelation("listitem1.1", RELATION_NODE_CHILD_OF, "listitem1");
+ testRelation("listitem1.2", RELATION_NODE_CHILD_OF, "listitem1");
+
+ // 'node child of' relation for the document having window, returns
+ // direct accessible parent (fixed in bug 419770).
+ var iframeElmObj = {};
+ var iframeAcc = getAccessible("iframe", null, iframeElmObj);
+ var iframeDoc = iframeElmObj.value.contentDocument;
+ var iframeDocAcc = getAccessible(iframeDoc);
+ testRelation(iframeDocAcc, RELATION_NODE_CHILD_OF, iframeAcc);
+
+ // 'node parent of' relation on ARIA tree and treegrid.
+ testRelation("tree", RELATION_NODE_PARENT_OF,
+ ["treeitem1", "treeitem2", // aria-owns
+ "treeitem3", "treeitem4", "treeitem6"]); // children
+ testRelation("treeitem4", RELATION_NODE_PARENT_OF,
+ "treeitem5"); // aria-level
+ testRelation("treeitem6", RELATION_NODE_PARENT_OF,
+ "treeitem7"); // // group role
+ testRelation("tree2", RELATION_NODE_PARENT_OF, "tree2_ti1"); // group role
+ testRelation("tree2_ti1", RELATION_NODE_PARENT_OF,
+ ["tree2_ti1a", "tree2_ti1b"]); // group role
+
+ testRelation("treegridrow2", RELATION_NODE_PARENT_OF, "treegridrow3");
+ testRelation("treegrid", RELATION_NODE_PARENT_OF,
+ ["treegridrow1", "treegridrow2"]);
+
+ // 'node parent of' relation on ARIA grid.
+ // 'node parent of' relation on ARIA grid's row.
+ // Should only have relation to child through aria-level.
+ testRelation("simplegrid-row2", RELATION_NODE_PARENT_OF,
+ "simplegrid-row3");
+
+ // 'node parent of' relation on ARIA list structured by groups
+ testRelation("list", RELATION_NODE_PARENT_OF,
+ "listitem1");
+ testRelation("listitem1", RELATION_NODE_PARENT_OF,
+ [ "listitem1.1", "listitem1.2" ]);
+
+ // aria-atomic
+ testRelation(getNode("atomic").firstChild, RELATION_MEMBER_OF, "atomic");
+
+ // aria-controls
+ getAccessible("tab");
+ todo(false,
+ "Getting an accessible tab, otherwise relations for tabpanel aren't cached. Bug 606924 will fix that.");
+ testRelation("tabpanel", RELATION_CONTROLLED_BY, "tab");
+ testRelation("tab", RELATION_CONTROLLER_FOR, "tabpanel");
+
+ // aria-controls, multiple relations
+ testRelation("lr1", RELATION_CONTROLLED_BY, "button");
+ testRelation("lr2", RELATION_CONTROLLED_BY, "button");
+ testRelation("button", RELATION_CONTROLLER_FOR, ["lr1", "lr2"]);
+
+ // aria-flowto
+ testRelation("flowto", RELATION_FLOWS_TO, "flowfrom");
+ testRelation("flowfrom", RELATION_FLOWS_FROM, "flowto");
+
+ // aria-flowto, multiple relations
+ testRelation("flowto1", RELATION_FLOWS_TO, ["flowfrom1", "flowfrom2"]);
+ testRelation("flowfrom1", RELATION_FLOWS_FROM, "flowto1");
+ testRelation("flowfrom2", RELATION_FLOWS_FROM, "flowto1");
+
+ // 'default button' relation
+ testRelation("input", RELATION_DEFAULT_BUTTON, "submit");
+
+ // output 'for' relations
+ testRelation("output", RELATION_CONTROLLED_BY, ["input", "input2"]);
+ testRelation("output2", RELATION_CONTROLLED_BY, ["input", "input2"]);
+ testRelation("input", RELATION_CONTROLLER_FOR, ["output", "output2"]);
+ testRelation("input2", RELATION_CONTROLLER_FOR, ["output", "output2"]);
+
+ // 'described by'/'description for' relation for html:table and
+ // html:caption
+ testRelation("caption", RELATION_LABEL_FOR, "table");
+ testRelation("table", RELATION_LABELLED_BY, "caption");
+
+ // 'labelled by'/'label for' relation for html:fieldset and
+ // html:legend
+ testRelation("legend", RELATION_LABEL_FOR, "fieldset");
+ testRelation("fieldset", RELATION_LABELLED_BY, "legend");
+
+ // containing relations
+ testRelation("control1_1", RELATION_CONTAINING_DOCUMENT, document);
+ testRelation("control1_1", RELATION_CONTAINING_TAB_PANE, getTabDocAccessible("control1_1"));
+ testRelation("control1_1", RELATION_CONTAINING_APPLICATION, getApplicationAccessible());
+
+ // details
+ testRelation("has_details", RELATION_DETAILS, "details");
+ testRelation("details", RELATION_DETAILS_FOR, "has_details");
+
+ // error
+ testRelation("has_error", RELATION_ERRORMSG, "error");
+ testRelation("error", RELATION_ERRORMSG_FOR, "has_error");
+
+ // finish test
+ SimpleTest.finish();
+ }
+
+ disableLogging(); // from test_embeds.xul
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+
+</head>
+
+<body>
+
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=475298"
+ title="mochitests for accessible relations">
+ Bug 475298
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=527461"
+ title="Implement RELATION_NODE_PARENT_OF">
+ Bug 527461
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=558036"
+ title="make HTML <output> accessible">
+ Bug 558036
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=682790"
+ title="Ignore implicit label association when it's associated explicitly">
+ Bug 682790
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=687393"
+ title="HTML select options gets relation from containing label">
+ Bug 687393
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=864224"
+ title="Support nested ARIA listitems structured by role='group'">
+ Bug 864224
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <label id="label1_1" for="control1_1">label</label>
+ <input id="control1_1">
+
+ <label id="label1_2" for="control1_2">label</label>
+ <label id="label1_3" for="control1_2">label</label>
+ <input id="control1_2">
+
+ <label id="label1_4">Label
+ <select id="control1_4">
+ <option id="control1_4_option1">option</option>
+ </select>
+ </label>
+ <label id="label1_5">Label
+ <button id="control1_5">button</button>
+ </label>
+ <label id="label1_6">Label
+ <input id="control1_6">
+ </label>
+ <label id="label1_7">Label
+ <input id="control1_7" type="checkbox">
+ </label>
+ <label id="label1_8">Label
+ <input id="control1_8" type="radio">
+ </label>
+ <label id="label1_9">Label
+ <input id="control1_9" type="button" value="button">
+ </label>
+ <label id="label1_10">Label
+ <input id="control1_10" type="submit">
+ </label>
+ <label id="label1_11">Label
+ <input id="control1_11" type="image">
+ </label>
+ <label id="label1_12">Label
+ <progress id="control1_12"></progress>
+ </label>
+
+ <label id="label1_13" for="">Label
+ <input id="control1_13">
+ </label>
+ <label id="label1_14" for="control1_14">Label
+ <input id="control1_14">
+ </label>
+
+ <span id="label2">label</span>
+ <span role="checkbox" id="checkbox2" aria-labelledby="label2"></span>
+
+ <span id="label3">label1</span>
+ <span id="label4">label2</span>
+ <span role="checkbox" id="checkbox3" aria-labelledby="label3 label4"></span>
+
+ <span id="descr1">description</span>
+ <span role="checkbox" id="checkbox4" aria-describedby="descr1"></span>
+
+ <span id="descr2">description1</span>
+ <span id="descr3">description2</span>
+ <span role="checkbox" id="checkbox5" aria-describedby="descr2 descr3"></span>
+
+ <div role="treeitem" id="treeitem1">Yellow</div>
+ <div role="treeitem" id="treeitem2">Orange</div>
+ <div id="tree" role="tree" aria-owns="treeitem1 treeitem2">
+ <div role="treeitem" id="treeitem3">Blue</div>
+ <div role="treeitem" id="treeitem4" aria-level="1">Green</div>
+ <div role="treeitem" id="treeitem5" aria-level="2">Light green</div>
+ <div role="treeitem" id="treeitem6" aria-level="1">Green2</div>
+ <div role="group">
+ <div role="treeitem" id="treeitem7">Super light green</div>
+ </div>
+ </div>
+
+ <div role="grid" id="simplegrid">
+ <div role="row" id="simplegrid-row1" aria-level="1">
+ <div role="gridcell">cell 1,1</div>
+ <div role="gridcell">cell 1,2</div>
+ </div>
+ <div role="row" id="simplegrid-row2" aria-level="1">
+ <div role="gridcell">cell 2,1</div>
+ <div role="gridcell">cell 2,2</div>
+ </div>
+ <div role="row" id="simplegrid-row3" aria-level="2">
+ <div role="gridcell">cell 3,1</div>
+ <div role="gridcell">cell 3,2</div>
+ </div>
+ </div>
+
+ <ul role="tree" id="tree2">
+ <li role="treeitem" id="tree2_ti1">Item 1
+ <ul role="group">
+ <li role="treeitem" id="tree2_ti1a">Item 1A</li>
+ <li role="treeitem" id="tree2_ti1b">Item 1B</li>
+ </ul>
+ </li>
+ </ul>
+
+ <div role="treegrid" id="treegrid">
+ <div role="row" id="treegridrow1">
+ <span role="gridcell">cell1</span><span role="gridcell">cell2</span>
+ </div>
+ <div role="row" id="treegridrow2" aria-level="1">
+ <span role="gridcell">cell3</span><span role="gridcell">cell4</span>
+ </div>
+ <div role="row" id="treegridrow3" aria-level="2">
+ <span role="gridcell">cell5</span><span role="gridcell">cell6</span>
+ </div>
+ </div>
+
+ <div role="list" id="list">
+ <div role="listitem" id="listitem1">Item 1
+ <div role="group">
+ <div role="listitem" id="listitem1.1">Item 1A</div>
+ <div role="listitem" id="listitem1.2">Item 1B</div>
+ </div>
+ </div>
+ </div>
+
+ <iframe id="iframe"></iframe>
+
+ <div id="tablist" role="tablist">
+ <div id="tab" role="tab" aria-controls="tabpanel">tab</div>
+ </div>
+ <div id="tabpanel" role="tabpanel">tabpanel</div>
+
+ <div id="lr1" aria-live="assertive">1</div>
+ <div id="lr2" aria-live="assertive">a</div>
+ <input type="button" id="button" aria-controls="lr1 lr2"
+ onclick="getNode('lr1').textContent += '1'; getNode('lr2').textContent += 'a';"/>
+
+ <div id="atomic" aria-atomic="true">live region</div>
+
+ <span id="flowto" aria-flowto="flowfrom">flow to</span>
+ <span id="flowfrom">flow from</span>
+
+ <span id="flowto1" aria-flowto="flowfrom1 flowfrom2">flow to</span>
+ <span id="flowfrom1">flow from</span>
+ <span id="flowfrom2">flow from</span>
+
+ <form id="form">
+ <input id="input" />
+ <input id="input2" />
+ <input type="submit" id="submit" />
+ <output id="output" style="display:block" for="input input2"></output>
+ <output id="output2" for="input input2"></output>
+ </form>
+
+ <table id="table">
+ <caption id="caption">tabple caption</caption>
+ <tr>
+ <td>cell1</td><td>cell2</td>
+ </tr>
+ </table>
+
+ <fieldset id="fieldset">
+ <legend id="legend">legend</legend>
+ <input />
+ </fieldset>
+
+ <input id="has_details" aria-details="details"><section id="details"></section>
+ <input id="has_error" aria-errormessage="error"><section id="error"></section>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/relations/test_general.xul b/accessible/tests/mochitest/relations/test_general.xul
new file mode 100644
index 000000000..23bf7276b
--- /dev/null
+++ b/accessible/tests/mochitest/relations/test_general.xul
@@ -0,0 +1,238 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+ type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="nsIAccessible::getAccessibleRelated() tests">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+ <script type="application/javascript"
+ src="../common.js" />
+ <script type="application/javascript"
+ src="../relations.js" />
+ <script type="application/javascript"
+ src="../role.js" />
+
+ <script type="application/javascript">
+ <![CDATA[
+ function doTest()
+ {
+ // xul:label@control
+ testRelation("label1", RELATION_LABEL_FOR, "checkbox1");
+ testRelation("checkbox1", RELATION_LABELLED_BY, "label1");
+
+ // xul:label@control, multiple
+ testRelation("label1_1", RELATION_LABEL_FOR, "checkbox1_1");
+ testRelation("label1_2", RELATION_LABEL_FOR, "checkbox1_1");
+ testRelation("checkbox1_1", RELATION_LABELLED_BY,
+ [ "label1_1", "label1_2" ]);
+
+ // aria-labelledby
+ testRelation("label2", RELATION_LABEL_FOR, "checkbox2");
+ testRelation("checkbox2", RELATION_LABELLED_BY, "label2");
+
+ // aria-labelledby, multiple relations
+ testRelation("label3", RELATION_LABEL_FOR, "checkbox3");
+ testRelation("label4", RELATION_LABEL_FOR, "checkbox3");
+ testRelation("checkbox3", RELATION_LABELLED_BY, ["label3", "label4"]);
+
+ // aria-describedby
+ testRelation("descr1", RELATION_DESCRIPTION_FOR, "checkbox4");
+ testRelation("checkbox4", RELATION_DESCRIBED_BY, "descr1");
+
+ // aria-describedby, multiple relations
+ testRelation("descr2", RELATION_DESCRIPTION_FOR, "checkbox5");
+ testRelation("descr3", RELATION_DESCRIPTION_FOR, "checkbox5");
+ testRelation("checkbox5", RELATION_DESCRIBED_BY, ["descr2", "descr3"]);
+
+ // xul:description@control
+ testRelation("descr4", RELATION_DESCRIPTION_FOR, "checkbox6");
+ testRelation("checkbox6", RELATION_DESCRIBED_BY, "descr4");
+
+ // xul:description@control, multiple
+ testRelation("descr5", RELATION_DESCRIPTION_FOR, "checkbox7");
+ testRelation("descr6", RELATION_DESCRIPTION_FOR, "checkbox7");
+ testRelation("checkbox7", RELATION_DESCRIBED_BY,
+ [ "descr5", "descr6" ]);
+
+ // aria_owns, multiple relations
+ testRelation("treeitem1", RELATION_NODE_CHILD_OF, "tree");
+ testRelation("treeitem2", RELATION_NODE_CHILD_OF, "tree");
+
+ // 'node child of' relation for outlineitem role
+ testRelation("treeitem3", RELATION_NODE_CHILD_OF, "tree");
+ testRelation("treeitem4", RELATION_NODE_CHILD_OF, "tree");
+ testRelation("treeitem5", RELATION_NODE_CHILD_OF, "treeitem4");
+
+ // no relation node_child_of for accessible contained in an unexpected
+ // parent
+ testRelation("treeitem6", RELATION_NODE_CHILD_OF, null);
+
+ // 'node child of' relation for the document having window, returns
+ // direct accessible parent (fixed in bug 419770).
+ var iframeElmObj = {};
+ var iframeAcc = getAccessible("iframe", null, iframeElmObj);
+ var iframeDoc = iframeElmObj.value.contentDocument;
+ var iframeDocAcc = getAccessible(iframeDoc);
+ testRelation(iframeDocAcc, RELATION_NODE_CHILD_OF, iframeAcc);
+
+ // aria-controls
+ getAccessible("tab");
+ todo(false,
+ "Getting an accessible tab, otherwise relations for tabpanel aren't cached. Bug 606924 will fix that.");
+ testRelation("tabpanel", RELATION_CONTROLLED_BY, "tab");
+ testRelation("tab", RELATION_CONTROLLER_FOR, "tabpanel");
+
+ // aria-controls, multiple relations
+ testRelation("lr1", RELATION_CONTROLLED_BY, "button");
+ testRelation("lr2", RELATION_CONTROLLED_BY, "button");
+ testRelation("button", RELATION_CONTROLLER_FOR, ["lr1", "lr2"]);
+
+ // aria-flowto
+ testRelation("flowto", RELATION_FLOWS_TO, "flowfrom");
+ testRelation("flowfrom", RELATION_FLOWS_FROM, "flowto");
+
+ // aria-flowto, multiple relations
+ testRelation("flowto1", RELATION_FLOWS_TO, ["flowfrom1", "flowfrom2"]);
+ testRelation("flowfrom1", RELATION_FLOWS_FROM, "flowto1");
+ testRelation("flowfrom2", RELATION_FLOWS_FROM, "flowto1");
+
+ // 'default button' relation
+ testRelation("textbox", RELATION_DEFAULT_BUTTON, "submit");
+
+ // 'labelled by'/'label for' relation for xul:goupbox and xul:label of
+ // xul:caption
+ var groupboxAcc = getAccessible("groupbox");
+ var labelAcc = groupboxAcc.firstChild;
+ testRelation(labelAcc, RELATION_LABEL_FOR, groupboxAcc);
+ testRelation(groupboxAcc, RELATION_LABELLED_BY, labelAcc);
+
+ // 'labelled by'/'label for' relations for xul:tab and xul:tabpanel
+ // (fixed in bug 366527)
+ testRelation("tabpanel1", RELATION_LABELLED_BY, "tab1");
+ testRelation("tab1", RELATION_LABEL_FOR, "tabpanel1");
+ testRelation("tabpanel2", RELATION_LABELLED_BY, "tab2");
+ testRelation("tab2", RELATION_LABEL_FOR, "tabpanel2");
+ testRelation("tabpanel3", RELATION_LABELLED_BY, "tab3");
+ testRelation("tab3", RELATION_LABEL_FOR, "tabpanel3");
+
+ // finish test
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ ]]>
+ </script>
+
+ <vbox style="overflow: auto;" flex="1">
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=475298"
+ title="mochitests for accessible relations">
+ Mozilla Bug 475298
+ </a><br/>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=673389"
+ title="node_child_of on an item not in a proper container">
+ Mozilla Bug 67389
+ </a><br/>
+
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <label id="label1" control="checkbox1">label</label>
+ <checkbox id="checkbox1"/>
+
+ <label id="label1_1" control="checkbox1_1">label</label>
+ <label id="label1_2" control="checkbox1_1">label</label>
+ <checkbox id="checkbox1_1"/>
+
+ <description id="label2">label</description>
+ <description role="checkbox" id="checkbox2" aria-labelledby="label2"/>
+
+ <description id="label3">label</description>
+ <description id="label4">label</description>
+ <description role="checkbox" id="checkbox3"
+ aria-labelledby="label3 label4"/>
+
+ <description id="descr1">description</description>
+ <description role="checkbox" id="checkbox4" aria-describedby="descr1"/>
+
+ <description id="descr2">label</description>
+ <description id="descr3">label</description>
+ <description role="checkbox" id="checkbox5"
+ aria-describedby="descr2 descr3"/>
+
+ <description id="descr4" control="checkbox6">description</description>
+ <checkbox id="checkbox6"/>
+
+ <description id="descr5" control="checkbox7">description</description>
+ <description id="descr6" control="checkbox7">description</description>
+ <checkbox id="checkbox7"/>
+
+ <description role="treeitem" id="treeitem1">Yellow</description>
+ <description role="treeitem" id="treeitem2">Orange</description>
+ <vbox id="tree" role="tree" aria-owns="treeitem1 treeitem2">
+ <description role="treeitem" id="treeitem3">Blue</description>
+ <description role="treeitem" id="treeitem4" aria-level="1">Green</description>
+ <description role="treeitem" id="treeitem5" aria-level="2">Light green</description>
+ </vbox>
+
+ <description role="treeitem" id="treeitem6">Dark green</description>
+
+ <iframe id="iframe"/>
+
+ <hbox id="tablist" role="tablist">
+ <description id="tab" role="tab" aria-controls="tabpanel">tab</description>
+ </hbox>
+ <description id="tabpanel" role="tabpanel">tabpanel</description>
+
+ <description id="lr1" aria-live="assertive">1</description>
+ <description id="lr2" aria-live="assertive">a</description>
+ <button id="button" aria-controls="lr1 lr2" label="button"
+ oncommand="getNode('lr1').textContent += '1'; getNode('lr2').textContent += 'a';"/>
+
+ <description id="flowto1" aria-flowto="flowfrom1 flowfrom2">flow to</description>
+ <description id="flowfrom1">flow from</description>
+ <description id="flowfrom2">flow from</description>
+
+ <description id="flowto" aria-flowto="flowfrom">flow to</description>
+ <description id="flowfrom">flow from</description>
+
+ <textbox id="textbox"/>
+ <button id="submit" default="true" label="Default"/>
+
+ <groupbox id="groupbox">
+ <caption label="caption"/>
+ </groupbox>
+
+ <tabbox>
+ <tabs>
+ <tab label="tab1" id="tab1"/>
+ <tab label="tab2" id="tab2" linkedpanel="tabpanel2"/>
+ <tab label="tab3" id="tab3" linkedpanel="tabpanel3"/>
+ </tabs>
+ <tabpanels>
+ <tabpanel id="tabpanel1">
+ <description>tabpanel1</description>
+ </tabpanel>
+ <tabpanel id="tabpanel3">
+ <description>tabpanel3</description>
+ </tabpanel>
+ <tabpanel id="tabpanel2">
+ <description>tabpanel2</description>
+ </tabpanel>
+ </tabpanels>
+ </tabbox>
+
+ </vbox>
+</window>
+
diff --git a/accessible/tests/mochitest/relations/test_tabbrowser.xul b/accessible/tests/mochitest/relations/test_tabbrowser.xul
new file mode 100644
index 000000000..8fd340fec
--- /dev/null
+++ b/accessible/tests/mochitest/relations/test_tabbrowser.xul
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+ type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Accessible XUL tabbrowser relation tests">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
+
+ <script type="application/javascript"
+ src="../common.js" />
+ <script type="application/javascript"
+ src="../role.js" />
+ <script type="application/javascript"
+ src="../relations.js" />
+ <script type="application/javascript"
+ src="../events.js" />
+ <script type="application/javascript"
+ src="../browser.js"></script>
+
+ <script type="application/javascript">
+ <![CDATA[
+ ////////////////////////////////////////////////////////////////////////////
+ // Invoker
+ function testTabRelations()
+ {
+ this.eventSeq = [
+ new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 0),
+ new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
+ ];
+
+ this.invoke = function testTabRelations_invoke()
+ {
+ var docURIs = ["about:", "about:mozilla"];
+ tabBrowser().loadTabs(docURIs, false, true);
+ }
+
+ this.finalCheck = function testTabRelations_finalCheck(aEvent)
+ {
+ ////////////////////////////////////////////////////////////////////////
+ // 'labelled by'/'label for' relations for xul:tab and xul:tabpanel
+
+ var tabs = tabBrowser().tabContainer.childNodes;
+ var panels = tabBrowser().mTabBox.tabpanels.childNodes;
+
+ testRelation(panels[0], RELATION_LABELLED_BY, tabs[0]);
+ testRelation(tabs[0], RELATION_LABEL_FOR, panels[0]);
+ testRelation(panels[1], RELATION_LABELLED_BY, tabs[1]);
+ testRelation(tabs[1], RELATION_LABEL_FOR, panels[1]);
+ }
+
+ this.getID = function testTabRelations_getID()
+ {
+ return "relations of tabs";
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Test
+
+ //gA11yEventDumpToConsole = true; // debug stuff
+
+ var gQueue = null;
+ function doTest()
+ {
+ // Load documents into tabs and wait for DocLoadComplete events caused by
+ // these documents load before we start the test.
+
+ gQueue = new eventQueue();
+
+ gQueue.push(new testTabRelations());
+ gQueue.onFinish = function() { closeBrowserWindow(); }
+ gQueue.invoke(); // Will call SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ openBrowserWindow(doTest);
+ ]]>
+ </script>
+
+ <vbox flex="1" style="overflow: auto;">
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=552944"
+ title="No relationship between tabs and associated property page in new tabbrowser construct">
+ Mozilla Bug 552944
+ </a><br/>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <vbox id="eventdump"></vbox>
+ </vbox>
+
+</window>
+
diff --git a/accessible/tests/mochitest/relations/test_tree.xul b/accessible/tests/mochitest/relations/test_tree.xul
new file mode 100644
index 000000000..300fa5bc3
--- /dev/null
+++ b/accessible/tests/mochitest/relations/test_tree.xul
@@ -0,0 +1,106 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+ type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Accessible XUL tree relations tests">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+ <script type="application/javascript"
+ src="../treeview.js" />
+
+ <script type="application/javascript"
+ src="../common.js" />
+ <script type="application/javascript"
+ src="../events.js" />
+ <script type="application/javascript"
+ src="../relations.js" />
+
+ <script type="application/javascript">
+ <![CDATA[
+ ////////////////////////////////////////////////////////////////////////////
+ // Test
+
+ function doTest()
+ {
+ var treeNode = getNode("tree");
+
+ var tree = getAccessible(treeNode);
+ var treeitem1 = tree.firstChild.nextSibling;
+ testRelation(treeitem1, RELATION_NODE_CHILD_OF, [tree]);
+
+ var treeitem2 = treeitem1.nextSibling;
+ testRelation(treeitem2, RELATION_NODE_CHILD_OF, [tree]);
+
+ var treeitem3 = treeitem2.nextSibling;
+ testRelation(treeitem3, RELATION_NODE_CHILD_OF, [treeitem2]);
+
+ var treeitem4 = treeitem3.nextSibling;
+ testRelation(treeitem4, RELATION_NODE_CHILD_OF, [treeitem2]);
+
+ var treeitem5 = treeitem4.nextSibling;
+ testRelation(treeitem5, RELATION_NODE_CHILD_OF, [tree]);
+
+ var treeitem6 = treeitem5.nextSibling;
+ testRelation(treeitem6, RELATION_NODE_CHILD_OF, [tree]);
+
+ testRelation(tree, RELATION_NODE_PARENT_OF,
+ [treeitem1, treeitem2, treeitem5, treeitem6]);
+ testRelation(treeitem2, RELATION_NODE_PARENT_OF,
+ [treeitem3, treeitem4]);
+
+ // treeitems and treecells shouldn't pick up relations from tree
+ testRelation(treeitem1, RELATION_LABELLED_BY, null);
+ testRelation(treeitem1.firstChild, RELATION_LABELLED_BY, null);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yXULTreeLoadEvent(doTest, "tree", new nsTreeTreeView());
+ ]]>
+ </script>
+
+ <hbox flex="1" style="overflow: auto;">
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=503727"
+ title="Reorganize implementation of XUL tree accessibility">
+ Bug 503727
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=527461"
+ title="Implement RELATION_NODE_PARENT_OF">
+ Bug 527461
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=691248"
+ title="XUL tree items shouldn't pick up relations from XUL tree">
+ Bug 691248
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <vbox flex="1">
+ <label control="tree" value="It's a tree"/>
+ <tree id="tree" flex="1">
+ <treecols>
+ <treecol id="col" flex="1" primary="true" label="column"/>
+ <treecol id="col2" flex="1" label="column2"/>
+ </treecols>
+ <treechildren/>
+ </tree>
+
+ <vbox id="debug"/>
+ </vbox>
+ </hbox>
+
+</window>
+
diff --git a/accessible/tests/mochitest/relations/test_ui_modalprompt.html b/accessible/tests/mochitest/relations/test_ui_modalprompt.html
new file mode 100644
index 000000000..21918b33c
--- /dev/null
+++ b/accessible/tests/mochitest/relations/test_ui_modalprompt.html
@@ -0,0 +1,107 @@
+<html>
+
+<head>
+ <title>Modal prompts</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="chrome://mochikit/content/tests/SimpleTest/EventUtils.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"
+ src="../browser.js"></script>
+
+ <script type="application/javascript">
+ function hasTabModalPrompts() {
+ try {
+ return SpecialPowers.getBoolPref("prompts.tab_modal.enabled");
+ } catch (ex) {
+ return false;
+ }
+ }
+
+ function showAlert()
+ {
+ this.eventSeq = [
+ {
+ type: EVENT_SHOW,
+ match: function(aEvent)
+ {
+ return aEvent.accessible.role == ROLE_DIALOG;
+ }
+ }
+ ];
+
+ this.invoke = function showAlert_invoke()
+ {
+ window.setTimeout(
+ function()
+ {
+ currentTabDocument().defaultView.alert("hello");
+ }, 0);
+ }
+
+ this.check = function showAlert_finalCheck(aEvent)
+ {
+ var dialog = aEvent.accessible.DOMNode;
+ var info = dialog.ui.infoBody;
+ testRelation(info, RELATION_DESCRIPTION_FOR, dialog);
+ testRelation(dialog, RELATION_DESCRIBED_BY, info);
+ }
+
+ this.getID = function showAlert_getID()
+ {
+ return "show alert";
+ }
+ }
+
+ //gA11yEventDumpToConsole = true; // debug
+
+ var gQueue = null;
+ function doTests()
+ {
+ gQueue = new eventQueue();
+ gQueue.push(new showAlert());
+ gQueue.onFinish = function()
+ {
+ synthesizeKey("VK_RETURN", {}, browserWindow());
+ closeBrowserWindow();
+ }
+ gQueue.invoke(); // will call SimpleTest.finish()
+ }
+
+ if (!hasTabModalPrompts()) {
+ todo(false, "Test disabled when tab modal prompts are not enabled.");
+ } else {
+ SimpleTest.waitForExplicitFinish();
+ openBrowserWindow(doTests);
+ }
+ </script>
+
+</head>
+
+<body id="body">
+
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=661293"
+ title="The tabmodalprompt dialog's prompt label doesn't get the text properly associated for accessibility">
+ Mozilla Bug 661293
+ </a>
+ <br>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/relations/test_update.html b/accessible/tests/mochitest/relations/test_update.html
new file mode 100644
index 000000000..a04831427
--- /dev/null
+++ b/accessible/tests/mochitest/relations/test_update.html
@@ -0,0 +1,225 @@
+<html>
+
+<head>
+ <title>Test updating of accessible relations</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="../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.style.overflow = "visible";
+ }
+
+ 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>