summaryrefslogtreecommitdiffstats
path: root/accessible/tests/mochitest/states
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/tests/mochitest/states')
-rw-r--r--accessible/tests/mochitest/states/a11y.ini37
-rw-r--r--accessible/tests/mochitest/states/test_aria.html629
-rw-r--r--accessible/tests/mochitest/states/test_aria.xul60
-rw-r--r--accessible/tests/mochitest/states/test_aria_imgmap.html79
-rw-r--r--accessible/tests/mochitest/states/test_aria_widgetitems.html162
-rw-r--r--accessible/tests/mochitest/states/test_buttons.html85
-rw-r--r--accessible/tests/mochitest/states/test_controls.html53
-rw-r--r--accessible/tests/mochitest/states/test_controls.xul182
-rw-r--r--accessible/tests/mochitest/states/test_doc.html89
-rw-r--r--accessible/tests/mochitest/states/test_doc_busy.html79
-rw-r--r--accessible/tests/mochitest/states/test_docarticle.html80
-rw-r--r--accessible/tests/mochitest/states/test_editablebody.html46
-rw-r--r--accessible/tests/mochitest/states/test_expandable.xul118
-rw-r--r--accessible/tests/mochitest/states/test_frames.html95
-rw-r--r--accessible/tests/mochitest/states/test_inputs.html271
-rw-r--r--accessible/tests/mochitest/states/test_link.html144
-rw-r--r--accessible/tests/mochitest/states/test_popup.xul55
-rw-r--r--accessible/tests/mochitest/states/test_selects.html203
-rw-r--r--accessible/tests/mochitest/states/test_stale.html115
-rw-r--r--accessible/tests/mochitest/states/test_tabs.xul70
-rw-r--r--accessible/tests/mochitest/states/test_textbox.xul153
-rw-r--r--accessible/tests/mochitest/states/test_tree.xul152
-rw-r--r--accessible/tests/mochitest/states/test_visibility.html175
-rw-r--r--accessible/tests/mochitest/states/test_visibility.xul152
-rw-r--r--accessible/tests/mochitest/states/z_frames.html11
-rw-r--r--accessible/tests/mochitest/states/z_frames_article.html11
-rw-r--r--accessible/tests/mochitest/states/z_frames_checkbox.html11
-rw-r--r--accessible/tests/mochitest/states/z_frames_textbox.html11
-rw-r--r--accessible/tests/mochitest/states/z_frames_update.html22
29 files changed, 3350 insertions, 0 deletions
diff --git a/accessible/tests/mochitest/states/a11y.ini b/accessible/tests/mochitest/states/a11y.ini
new file mode 100644
index 000000000..f07afc3e9
--- /dev/null
+++ b/accessible/tests/mochitest/states/a11y.ini
@@ -0,0 +1,37 @@
+[DEFAULT]
+support-files =
+ z_frames.html
+ z_frames_article.html
+ z_frames_checkbox.html
+ z_frames_textbox.html
+ z_frames_update.html
+ !/accessible/tests/mochitest/*.js
+ !/accessible/tests/mochitest/dumbfile.zip
+ !/accessible/tests/mochitest/formimage.png
+ !/accessible/tests/mochitest/treeview.css
+
+[test_aria.html]
+[test_aria.xul]
+[test_aria_imgmap.html]
+[test_aria_widgetitems.html]
+[test_buttons.html]
+[test_controls.html]
+[test_controls.xul]
+[test_doc.html]
+[test_doc_busy.html]
+skip-if = os == 'mac' && os_version == '10.6'
+[test_docarticle.html]
+[test_editablebody.html]
+[test_expandable.xul]
+[test_frames.html]
+[test_inputs.html]
+[test_link.html]
+[test_popup.xul]
+[test_selects.html]
+[test_stale.html]
+[test_tabs.xul]
+[test_textbox.xul]
+[test_tree.xul]
+[test_visibility.html]
+[test_visibility.xul]
+skip-if = buildapp == "mulet"
diff --git a/accessible/tests/mochitest/states/test_aria.html b/accessible/tests/mochitest/states/test_aria.html
new file mode 100644
index 000000000..7d1ecf650
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_aria.html
@@ -0,0 +1,629 @@
+<html>
+
+<head>
+ <title>ARIA based nsIAccessible states testing</title>
+
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <style type="text/css">
+ .offscreen {
+ position: absolute;
+ left: -5000px;
+ top: -5000px;
+ height: 100px;
+ width: 100px;
+ }
+ </style>
+
+ <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="../states.js"></script>
+
+ <script type="application/javascript">
+ function testAriaDisabledTree(aAccOrElmOrID)
+ {
+ // test accessible and its subtree for propagated state.
+ var acc = getAccessible(aAccOrElmOrID);
+ if (!acc)
+ return;
+
+ var [state, extraState] = getStates(aAccOrElmOrID);
+ if (state & STATE_UNAVAILABLE) {
+ var role = getRole(acc);
+ if (role != ROLE_GROUPING) {
+ testStates(acc, STATE_FOCUSABLE);
+ }
+ }
+
+ // Iterate over its children to see if the state got propagated.
+ var children = null;
+ try {
+ children = acc.children;
+ } catch(e) {}
+ ok(children, "Could not get children for " + aAccOrElmOrID +"!");
+
+ if (children) {
+ for (var i = 0; i < children.length; i++) {
+ var childAcc = children.queryElementAt(i, nsIAccessible);
+ testAriaDisabledTree(childAcc);
+ }
+ }
+ }
+
+ function doTest()
+ {
+ // aria_autocomplete
+ testStates("textbox_autocomplete_inline", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("textbox_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("textbox_autocomplete_both", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("combobox_autocomplete_inline", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("combobox_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("combobox_autocomplete_both", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+
+ testStates("htmltext_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("htmltextarea_autocomplete_list", STATE_HASPOPUP, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+
+ // aria-busy
+ testStates("textbox_busy_false", 0, 0, STATE_BUSY);
+ testStates("textbox_busy_true", STATE_BUSY);
+ testStates("textbox_busy_error", STATE_INVALID);
+
+ // aria-expanded
+ testStates("combobox", STATE_COLLAPSED);
+ testStates("combobox_expanded", STATE_EXPANDED);
+
+ // tri-state checkbox
+ var checkboxElem = getNode("check1");
+ if (checkboxElem) {
+ testStates(checkboxElem, STATE_CHECKED);
+ checkboxElem.checked = false;
+ testStates(checkboxElem, 0, 0, STATE_CHECKED);
+ checkboxElem.indeterminate = true;
+ testStates(checkboxElem, STATE_MIXED, 0);
+ }
+
+ // aria-checked
+ testStates("aria_checked_checkbox", STATE_CHECKED);
+ testStates("aria_mixed_checkbox", STATE_MIXED);
+ testStates("aria_checked_switch", STATE_CHECKED);
+ testStates("aria_mixed_switch", 0, 0, STATE_MIXED); // unsupported
+
+ // test disabled group and all its descendants to see if they are
+ // disabled, too. See bug 429285.
+ testAriaDisabledTree("group");
+
+ // aria-modal
+ testStates("aria_modal", 0, EXT_STATE_MODAL);
+ testStates("aria_modal_false", 0, 0, 0, EXT_STATE_MODAL);
+
+ // aria-multiline
+ testStates("aria_multiline_textbox", 0, EXT_STATE_MULTI_LINE);
+
+ // aria-multiselectable
+ testStates("aria_multiselectable_listbox",
+ STATE_MULTISELECTABLE | STATE_EXTSELECTABLE);
+
+ // aria-pressed
+ testStates("aria_pressed_button", STATE_PRESSED, 0, STATE_CHECKABLE);
+ testStates("aria_pressed_native_button", STATE_PRESSED, 0, STATE_CHECKABLE);
+
+ // aria-readonly
+ testStates("aria_readonly_textbox", STATE_READONLY);
+
+ // readonly/editable on grid and gridcell
+ testStates("aria_grid_default", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_grid_default_colheader_readonly", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_grid_default_colheader_inherited", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_grid_default_rowheader_readonly", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_grid_default_rowheader_inherited", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_grid_default_cell_readonly", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_grid_default_cell_inherited", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+
+ testStates("aria_grid_readonly", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_grid_readonly_colheader_editable", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_grid_readonly_colheader_inherited", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_grid_readonly_rowheader_editable", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_grid_readonly_rowheader_inherited", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_grid_readonly_cell_editable", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_grid_readonly_cell_inherited", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+
+ // readonly/editable on treegrid and gridcell
+ testStates("aria_treegrid_default", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_treegrid_default_colheader_readonly", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_treegrid_default_colheader_inherited", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_treegrid_default_rowheader_readonly", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_treegrid_default_rowheader_inherited", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_treegrid_default_cell_readonly", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_treegrid_default_cell_inherited", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+
+ testStates("aria_treegrid_readonly", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_treegrid_readonly_colheader_editable", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_treegrid_readonly_colheader_inherited", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_treegrid_readonly_rowheader_editable", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_treegrid_readonly_rowheader_inherited", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+ testStates("aria_treegrid_readonly_cell_editable", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, 0);
+ testStates("aria_treegrid_readonly_cell_inherited", STATE_READONLY, 0,
+ 0, EXT_STATE_EDITABLE);
+
+ // aria-selectable
+ testStates("aria_selectable_listitem", STATE_SELECTABLE | STATE_SELECTED);
+
+ // active state caused by aria-activedescendant
+ testStates("as_item1", 0, EXT_STATE_ACTIVE);
+ testStates("as_item2", 0, 0, 0, EXT_STATE_ACTIVE);
+
+ // universal ARIA properties inherited from file input control
+ var fileBrowseButton = getAccessible("fileinput").firstChild;
+ testStates(fileBrowseButton,
+ STATE_BUSY | STATE_UNAVAILABLE | STATE_REQUIRED | STATE_HASPOPUP | STATE_INVALID);
+ // No states on the label.
+
+ // offscreen test
+ testStates("aria_offscreen_textbox", STATE_OFFSCREEN);
+
+ //
+ // This section tests aria roles on links/anchors for underlying
+ // HTMLLinkAccessible creation. (see closed bug 494807)
+ //
+
+ // strong roles
+ testStates("aria_menuitem_link", 0, 0, STATE_LINKED);
+ testStates("aria_button_link", 0, 0, STATE_LINKED);
+ testStates("aria_checkbox_link", 0, 0, STATE_LINKED);
+
+ // strong landmark
+ testStates("aria_application_link", 0, 0, STATE_LINKED);
+ testStates("aria_application_anchor", 0, 0, STATE_SELECTABLE);
+
+ // strange cases
+ testStates("aria_link_link", STATE_LINKED);
+ testStates("aria_link_anchor", STATE_SELECTABLE);
+
+ // some weak landmarks
+ testStates("aria_main_link", STATE_LINKED);
+ testStates("aria_navigation_link", STATE_LINKED);
+ testStates("aria_main_anchor", STATE_SELECTABLE);
+ testStates("aria_navigation_anchor", STATE_SELECTABLE);
+
+ // aria-orientation
+ testStates("aria_combobox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_hcombobox", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vcombobox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_listbox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_hlistbox", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vlistbox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_menu", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_hmenu", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vmenu", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_menubar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_hmenubar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vmenubar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_radiogroup", 0, 0, 0, EXT_STATE_HORIZONTAL | EXT_STATE_VERTICAL);
+ testStates("aria_hradiogroup", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vradiogroup", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_scrollbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_hscrollbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vscrollbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_separator", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_hseparator", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vseparator", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_slider", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_hslider", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vslider", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_tablist", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_htablist", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vtablist", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_toolbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_htoolbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vtoolbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_tree", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_htree", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vtree", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_treegrid", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+ testStates("aria_htreegrid", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
+ testStates("aria_vtreegrid", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
+
+ // indeterminate ARIA progressbars (no aria-valuenow or aria-valuetext attribute)
+ // should expose mixed state
+ testStates("aria_progressbar", STATE_MIXED);
+ testStates("aria_progressbar_valuenow", 0, 0, STATE_MIXED);
+ testStates("aria_progressbar_valuetext", 0, 0, STATE_MIXED);
+
+ testStates("aria_listbox", STATE_FOCUSABLE);
+ testStates("aria_grid", STATE_FOCUSABLE);
+ testStates("aria_tree", STATE_FOCUSABLE);
+ testStates("aria_treegrid", STATE_FOCUSABLE);
+ testStates("aria_listbox_disabled", 0, 0, STATE_FOCUSABLE);
+ testStates("aria_grid_disabled", 0, 0, STATE_FOCUSABLE);
+ testStates("aria_tree_disabled", 0, 0, STATE_FOCUSABLE);
+ testStates("aria_treegrid_disabled", 0, 0, STATE_FOCUSABLE);
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+
+</head>
+
+<body>
+
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=457219"
+ title="nsIAccessible states testing">
+ Mozilla Bug 457219
+ </a><br />
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=429285"
+ title="Propagate aria-disabled to descendants">
+ Mozilla Bug 429285
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=457226"
+ title="Mochitests for ARIA states">
+ Mozilla Bug 457226
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=499653"
+ title="Unify ARIA state attributes mapping rules">
+ Mozilla Bug 499653
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=681674"
+ title="aria-autocomplete not supported on standard form text input controls">
+ Mozilla Bug 681674
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=681674"
+ title="aria-orientation should be applied to separator and slider roles">
+ Mozilla Bug 681674
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=689847"
+ title="Expose active state on current item of selectable widgets">
+ Mozilla Bug 689847
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=699017"
+ title="File input control should be propogate states to descendants">
+ Mozilla Bug 699017
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=690199"
+ title="ARIA select widget should expose focusable state regardless the way they manage its children">
+ Mozilla Bug 690199
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=740851"
+ title="ARIA undetermined progressmeters should expose mixed state">
+ Mozilla Bug 740851
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=762876"
+ title="fix default horizontal / vertical state of role=scrollbar and ensure only one of horizontal / vertical states is exposed">
+ Mozilla Bug 762876
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=892091"
+ title="ARIA treegrid should be editable by default">
+ Bug 892091
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=835121"
+ title="ARIA grid should be editable by default">
+ Mozilla Bug 835121
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=989958"
+ title="Pressed state is not exposed on a button element with aria-pressed attribute">
+ Mozilla Bug 989958
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=1136563"
+ title="Support ARIA 1.1 switch role">
+ Mozilla Bug 1136563
+ </a>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <div id="textbox_autocomplete_inline" role="textbox" aria-autocomplete="inline"></div>
+ <div id="textbox_autocomplete_list" role="textbox" aria-autocomplete="list"></div>
+ <div id="textbox_autocomplete_both" role="textbox" aria-autocomplete="both"></div>
+ <div id="combobox_autocomplete_inline" role="combobox" aria-autocomplete="inline"></div>
+ <div id="combobox_autocomplete_list" role="combobox" aria-autocomplete="list"></div>
+ <div id="combobox_autocomplete_both" role="combobox" aria-autocomplete="both"></div>
+
+ <input id="htmltext_autocomplete_list" type="text" aria-autocomplete="list" />
+ <textarea id="htmltextarea_autocomplete_list" aria-autocomplete="list"></textarea>
+
+ <div id="textbox_busy_false" role="textbox" aria-busy="false"></div>
+ <div id="textbox_busy_true" role="textbox" aria-busy="true"></div>
+ <div id="textbox_busy_error" role="textbox" aria-busy="error"></div>
+
+ <div id="combobox" role="combobox">combobox</div>
+ <div id="combobox_expanded" role="combobox"
+ aria-expanded="true">combobox</div>
+
+ <input type="checkbox" id="check1" value="I agree" checked="true"/>
+
+ <div id="aria_checked_checkbox" role="checkbox" aria-checked="true">
+ I agree
+ </div>
+
+ <div id="aria_mixed_checkbox" role="checkbox" aria-checked="mixed">
+ I might agree
+ </div>
+
+ <div id="aria_checked_switch" role="switch" aria-checked="true">
+ I am switched on
+ </div>
+
+ <div id="aria_mixed_switch" role="switch" aria-checked="mixed">
+ I am unsupported
+ </div>
+
+ <div id="aria_modal" aria-modal="true">modal stuff</div>
+ <div id="aria_modal_false" aria-modal="false">non modal stuff</div>div>
+ <div id="aria_multiline_textbox" role="textbox" aria-multiline="true"></div>
+ <div id="aria_multiselectable_listbox" role="listbox" aria-multiselectable="true"></div>
+ <div id="aria_pressed_button" role="button" aria-pressed="true">Button</div>
+ <button id="aria_pressed_native_button" aria-pressed="true">Button</button>
+
+ <div id="aria_readonly_textbox"
+ role="textbox" aria-readonly="true">This text should be readonly</div>
+
+ <div id="aria_grid_default" role="grid">
+ <div role="row">
+ <div id="aria_grid_default_colheader_readonly"
+ role="columnheader" aria-readonly="true">colheader1</div>
+ <div id="aria_grid_default_colheader_inherited"
+ role="columnheader">colheader2</div>
+ </div>
+ <div role="row">
+ <div id="aria_grid_default_rowheader_readonly"
+ role="rowheader" aria-readonly="true">rowheader1</div>
+ <div id="aria_grid_default_rowheader_inherited"
+ role="rowheader">rowheader2</div>
+ </div>
+ <div role="row">
+ <div id="aria_grid_default_cell_readonly"
+ role="gridcell" aria-readonly="true">gridcell1</div>
+ <div id="aria_grid_default_cell_inherited"
+ role="gridcell">gridcell2</div>
+ </div>
+ </div>
+
+ <div id="aria_grid_readonly" role="grid" aria-readonly="true">
+ <div role="row">
+ <div id="aria_grid_readonly_colheader_editable"
+ role="columnheader" aria-readonly="false">colheader1</div>
+ <div id="aria_grid_readonly_colheader_inherited"
+ role="columnheader">colheader2</div>
+ </div>
+ <div role="row">
+ <div id="aria_grid_readonly_rowheader_editable"
+ role="rowheader" aria-readonly="false">rowheader1</div>
+ <div id="aria_grid_readonly_rowheader_inherited"
+ role="rowheader">rowheader2</div>
+ </div>
+ <div role="row">
+ <div id="aria_grid_readonly_cell_editable"
+ role="gridcell" aria-readonly="false">gridcell1</div>
+ <div id="aria_grid_readonly_cell_inherited"
+ role="gridcell">gridcell2</div>
+ </div>
+ </div>
+
+ <div id="aria_treegrid_default" role="grid">
+ <div role="row">
+ <div id="aria_treegrid_default_colheader_readonly"
+ role="columnheader" aria-readonly="true">colheader1</div>
+ <div id="aria_treegrid_default_colheader_inherited"
+ role="columnheader">colheader2</div>
+ </div>
+ <div role="row">
+ <div id="aria_treegrid_default_rowheader_readonly"
+ role="rowheader" aria-readonly="true">rowheader1</div>
+ <div id="aria_treegrid_default_rowheader_inherited"
+ role="rowheader">rowheader2</div>
+ </div>
+ <div role="row">
+ <div id="aria_treegrid_default_cell_readonly"
+ role="gridcell" aria-readonly="true">gridcell1</div>
+ <div id="aria_treegrid_default_cell_inherited"
+ role="gridcell">gridcell2</div>
+ </div>
+ </div>
+
+ <div id="aria_treegrid_readonly" role="grid" aria-readonly="true">
+ <div role="row">
+ <div id="aria_treegrid_readonly_colheader_editable"
+ role="columnheader" aria-readonly="false">colheader1</div>
+ <div id="aria_treegrid_readonly_colheader_inherited"
+ role="columnheader">colheader2</div>
+ </div>
+ <div role="row">
+ <div id="aria_treegrid_readonly_rowheader_editable"
+ role="rowheader" aria-readonly="false">rowheader1</div>
+ <div id="aria_treegrid_readonly_rowheader_inherited"
+ role="rowheader">rowheader2</div>
+ </div>
+ <div role="row">
+ <div id="aria_treegrid_readonly_cell_editable"
+ role="gridcell" aria-readonly="false">gridcell1</div>
+ <div id="aria_treegrid_readonly_cell_inherited"
+ role="gridcell">gridcell2</div>
+ </div>
+ </div>
+
+ <div role="listbox">
+ <div id="aria_selectable_listitem" role="option" aria-selected="true">Item1</div>
+ </div>
+
+ <!-- Test that aria-disabled state gets propagated to all descendants -->
+ <div id="group" role="group" aria-disabled="true">
+ <button>hi</button>
+ <div tabindex="0" role="listbox" aria-activedescendant="item1"
+ aria-owns="item5">
+ <div role="option" id="item1">Item 1</div>
+ <div role="option" id="item2">Item 2</div>
+ <div role="option" id="item3">Item 3</div>
+ <div role="option" id="item4">Item 4</div>
+ </div>
+ <div role="slider" tabindex="0">A slider</div>
+ </div>
+ <div role="option" id="item5">Item 5</div>
+
+ <!-- Test active state -->
+ <div id="as_listbox" tabindex="0" role="listbox"
+ aria-activedescendant="as_item1">
+ <div role="option" id="as_item1">Item 1</div>
+ <div role="option" id="as_item2">Item 2</div>
+ </div>
+
+ <!-- universal ARIA properties should be inherited by text field of file input -->
+ <input type="file" id="fileinput"
+ aria-busy="true"
+ aria-disabled="true"
+ aria-required="true"
+ aria-haspopup="true"
+ aria-invalid="true">
+
+ <div id="offscreen_log" role="log" class="offscreen">
+ <div id="aria_offscreen_textbox" role="textbox" aria-readonly="true">This text should be offscreen</div>
+ </div>
+
+ <a id="aria_menuitem_link" role="menuitem" href="foo">menuitem</a>
+ <a id="aria_button_link" role="button" href="foo">button</a>
+ <a id="aria_checkbox_link" role="checkbox" href="foo">checkbox</a>
+
+ <!-- strange edge case: please don't do this in the wild -->
+ <a id="aria_link_link" role="link" href="foo">link</a>
+ <a id="aria_link_anchor" role="link" name="link_anchor">link</a>
+
+ <!-- landmarks: links -->
+ <a id="aria_application_link" role="application" href="foo">app</a>
+ <a id="aria_main_link" role="main" href="foo">main</a>
+ <a id="aria_navigation_link" role="navigation" href="foo">nav</a>
+
+ <!-- landmarks: anchors -->
+ <a id="aria_application_anchor" role="application" name="app_anchor">app</a>
+ <a id="aria_main_anchor" role="main" name="main_anchor">main</a>
+ <a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a>
+
+ <!-- aria-orientation -->
+ <div id="aria_combobox" role="combobox">combobox</div>
+ <div id="aria_hcombobox" role="combobox" aria-orientation="horizontal">horizontal combobox</div>
+ <div id="aria_vcombobox" role="combobox" aria-orientation="vertical">vertical combobox</div>
+ <div id="aria_listbox" role="listbox">listbox</div>
+ <div id="aria_hlistbox" role="listbox" aria-orientation="horizontal">horizontal listbox</div>
+ <div id="aria_vlistbox" role="listbox" aria-orientation="vertical">vertical listbox</div>
+ <div id="aria_menu" role="menu">menu</div>
+ <div id="aria_hmenu" role="menu" aria-orientation="horizontal">horizontal menu</div>
+ <div id="aria_vmenu" role="menu" aria-orientation="vertical">vertical menu</div>
+ <div id="aria_menubar" role="menubar">menubar</div>
+ <div id="aria_hmenubar" role="menubar" aria-orientation="horizontal">horizontal menubar</div>
+ <div id="aria_vmenubar" role="menubar" aria-orientation="vertical">vertical menubar</div>
+ <div id="aria_radiogroup" role="radiogroup">radiogroup</div>
+ <div id="aria_hradiogroup" role="radiogroup" aria-orientation="horizontal">horizontal radiogroup</div>
+ <div id="aria_vradiogroup" role="radiogroup" aria-orientation="vertical">vertical radiogroup</div>
+ <div id="aria_scrollbar" role="scrollbar">scrollbar</div>
+ <div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</div>
+ <div id="aria_vscrollbar" role="scrollbar" aria-orientation="vertical">vertical scrollbar</div>
+ <div id="aria_separator" role="separator">separator</div>
+ <div id="aria_hseparator" role="separator" aria-orientation="horizontal">horizontal separator</div>
+ <div id="aria_vseparator" role="separator" aria-orientation="vertical">vertical separator</div>
+ <div id="aria_slider" role="slider">slider</div>
+ <div id="aria_hslider" role="slider" aria-orientation="horizontal">horizontal slider</div>
+ <div id="aria_vslider" role="slider" aria-orientation="vertical">vertical slider</div>
+
+ <div id="aria_tablist" role="tablist">tablist</div>
+ <div id="aria_htablist" role="tablist" aria-orientation="horizontal">horizontal tablist</div>
+ <div id="aria_vtablist" role="tablist" aria-orientation="vertical">vertical tablist</div>
+ <div id="aria_toolbar" role="toolbar">toolbar</div>
+ <div id="aria_htoolbar" role="toolbar" aria-orientation="horizontal">horizontal toolbar</div>
+ <div id="aria_vtoolbar" role="toolbar" aria-orientation="vertical">vertical toolbar</div>
+ <div id="aria_tree" role="tree">tree</div>
+ <div id="aria_htree" role="tree" aria-orientation="horizontal">horizontal tree</div>
+ <div id="aria_vtree" role="tree" aria-orientation="vertical">vertical tree</div>
+ <div id="aria_treegrid" role="treegrid">treegrid</div>
+ <div id="aria_htreegrid" role="treegrid" aria-orientation="horizontal">horizontal treegrid</div>
+ <div id="aria_vtreegrid" role="treegrid" aria-orientation="vertical">vertical treegrid</div>
+
+ <!-- indeterminate ARIA progressbars should expose mixed state -->
+ <div id="aria_progressbar" role="progressbar"></div>
+ <div id="aria_progressbar_valuenow" role="progressbar" aria-valuenow="1"></div>
+ <div id="aria_progressbar_valuetext" role="progressbar" aria-valuetext="value"></div>
+
+ <!-- ARIA select widget should expose focusable state regardless the way they manage its children -->
+ <div id="aria_listbox" role="listbox">
+ <div role="option" tabindex="0">A</div>
+ <div role="option" tabindex="0">a</div>
+ </div>
+ <div id="aria_grid" role="grid">
+ <div role="row"><div role="gridcell" tabindex="0">B</div></div></div>
+ <div role="row"><div role="gridcell" tabindex="0">b</div></div></div>
+ <div id="aria_tree" role="tree">
+ <div role="treeitem" tabindex="0">C</div>
+ <div role="treeitem" tabindex="0">c</div>
+ </div>
+ <div id="aria_treegrid" role="treegrid">
+ <div role="row"><div role="gridcell" tabindex="0">D</div></div>
+ <div role="row"><div role="gridcell" tabindex="0">d</div></div>
+ </div>
+ <div id="aria_listbox_disabled" role="listbox" aria-disabled="true">
+ <div role="option">E</div>
+ <div role="option">e</div>
+ </div>
+ <div id="aria_grid_disabled" role="grid" aria-disabled="true">
+ <div role="row"><div role="gridcell">F</div></div>
+ <div role="row"><div role="gridcell">f</div></div>
+ </div>
+ <div id="aria_tree_disabled" role="tree" aria-disabled="true">
+ <div role="treeitem">G</div>
+ <div role="treeitem">g</div>
+ </div>
+ <div id="aria_treegrid_disabled" role="treegrid" aria-disabled="true">
+ <div role="row"><div role="gridcell">H</div></div>
+ <div role="row"><div role="gridcell">h</div></div>
+ </div>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_aria.xul b/accessible/tests/mochitest/states/test_aria.xul
new file mode 100644
index 000000000..b15cc7781
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_aria.xul
@@ -0,0 +1,60 @@
+<?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 ARIA state 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="../role.js" />
+ <script type="application/javascript"
+ src="../states.js" />
+
+ <script type="application/javascript">
+ <![CDATA[
+ function doTest()
+ {
+ // aria-pressed
+ testStates("pressed_button", STATE_PRESSED, 0, STATE_CHECKABLE);
+ testStates("pressed_menu_button", STATE_PRESSED | STATE_HASPOPUP, 0, STATE_CHECKABLE);
+
+ SimpleTest.finish()
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ ]]>
+ </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=1033283"
+ title="Expose pressed state on XUL menu toggle buttons">
+ Mozilla Bug 1033283
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <vbox flex="1">
+ <button id="pressed_button" aria-pressed="true" label="I am pressed" />
+ <button id="pressed_menu_button" aria-pressed="true" label="I am pressed" type="menu-button">
+ <menupopup>
+ <menuitem label="I am a menu item" />
+ </menupopup>
+ </button>
+ </vbox>
+ </hbox>
+
+</window>
+
diff --git a/accessible/tests/mochitest/states/test_aria_imgmap.html b/accessible/tests/mochitest/states/test_aria_imgmap.html
new file mode 100644
index 000000000..1dfe355bd
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_aria_imgmap.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Test usemap elements and ARIA</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="../role.js"></script>
+ <script type="application/javascript"
+ src="../events.js"></script>
+ <script type="application/javascript"
+ src="../states.js"></script>
+
+ <script type="application/javascript">
+ //gA11yEventDumpToConsole = true;
+ function doPreTest()
+ {
+ waitForImageMap("imagemap", doTest);
+ }
+
+ function doTest()
+ {
+ var imageMap = getAccessible("imagemap");
+
+ var t1 = imageMap.getChildAt(0);
+ testStates(t1, 0, EXT_STATE_EDITABLE, STATE_LINKED);
+ var t2 = imageMap.getChildAt(1);
+ testStates(t2, 0, EXT_STATE_EDITABLE, STATE_LINKED);
+ var rb1 = imageMap.getChildAt(2);
+ testStates(rb1, (STATE_CHECKABLE | STATE_CHECKED), 0, STATE_LINKED);
+ var rb2 = imageMap.getChildAt(3);
+ testStates(rb2, STATE_CHECKABLE, 0, STATE_CHECKED, STATE_LINKED);
+ var cb1 = imageMap.getChildAt(4);
+ testStates(cb1, (STATE_CHECKABLE | STATE_CHECKED), 0, STATE_LINKED);
+ var cbox = imageMap.getChildAt(5);
+ testStates(cbox, (STATE_HASPOPUP | STATE_COLLAPSED),
+ EXT_STATE_EXPANDABLE, STATE_LINKED);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doPreTest);
+ </script>
+
+</head>
+<body>
+
+<a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=548291"
+ title="ARIA states on image maps">
+Mozilla Bug 548291
+</a>
+<p id="display"></p>
+<div id="content" style="display: none"></div>
+<pre id="test">
+</pre>
+
+<img id="imagemap" src="../formimage.png" width="219" height="229" border="0" usemap="#ariaMap">
+<map id="ariaMap" name="ariaMap">
+ <area id="t1" role="textbox" shape="rect" tabindex="0" alt="" title="first name" coords="4,20,108,48" href="#" />
+ <area id="t2" role="textbox" shape="rect" alt="" title="last name" coords="111,21,215,50" href="#" />
+ <area id="rb1" role="radio" aria-checked="true" shape="circle" alt="" title="male" coords="60,75,11" href="#" />
+ <area id="rb2" role="radio" shape="circle" alt="" title="female" coords="73,94,11" href="#" />
+ <area id="cb1" role="checkbox" aria-checked="true" shape="rect" alt="" title="have bike" coords="95,123,118,145" href="#" />
+ <area id="cbox" role="combobox" shape="rect" alt="" title="bike model" coords="120,124,184,146" href="#" />
+ <area id="cb2" role="checkbox" shape="rect" alt="" title="have car" coords="90,145,114,164" href="#" />
+ <area id="cb3" role="checkbox" shape="rect" alt="" title="have airplane" coords="130,163,152,184" href="#" />
+ <area id="b1" role="button" shape="rect" alt="" title="submit" coords="4,198,67,224" href="#" />
+</map>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_aria_widgetitems.html b/accessible/tests/mochitest/states/test_aria_widgetitems.html
new file mode 100644
index 000000000..81bce4194
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_aria_widgetitems.html
@@ -0,0 +1,162 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <title>Test ARIA tab accessible selected state</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="../states.js"></script>
+ <script type="application/javascript"
+ src="../events.js"></script>
+
+ <script type="application/javascript">
+ function focusARIAItem(aID, aIsSelected)
+ {
+ this.DOMNode = getNode(aID);
+
+ this.invoke = function focusARIAItem_invoke()
+ {
+ this.DOMNode.focus();
+ }
+
+ this.check = function focusARIAItem_check(aEvent)
+ {
+ testStates(this.DOMNode, aIsSelected ? STATE_SELECTED : 0, 0,
+ aIsSelected ? 0 : STATE_SELECTED);
+ }
+
+ this.getID = function focusARIAItem_getID()
+ {
+ return "Focused ARIA widget item with aria-selected='" +
+ (aIsSelected ? "true', should" : "false', shouldn't") +
+ " have selected state on " + prettyName(aID);
+ }
+ }
+
+ function focusActiveDescendantItem(aItemID, aWidgetID, aIsSelected)
+ {
+ this.DOMNode = getNode(aItemID);
+ this.widgetDOMNode = getNode(aWidgetID);
+
+ this.invoke = function focusActiveDescendantItem_invoke()
+ {
+ this.widgetDOMNode.setAttribute("aria-activedescendant", aItemID);
+ this.widgetDOMNode.focus();
+ }
+
+ this.check = function focusActiveDescendantItem_check(aEvent)
+ {
+ testStates(this.DOMNode, aIsSelected ? STATE_SELECTED : 0, 0,
+ aIsSelected ? 0 : STATE_SELECTED);
+ }
+
+ this.getID = function tabActiveDescendant_getID()
+ {
+ return "ARIA widget item managed by activedescendant " +
+ (aIsSelected ? "should" : "shouldn't") +
+ " have the selected state on " + prettyName(aItemID);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Test
+
+ //gA11yEventDumpID = "eventdump"; // debug stuff
+ //gA11yEventDumpToConsole = true;
+
+ var gQueue = null;
+
+ function doTest()
+ {
+ // aria-selected
+ testStates("aria_tab1", 0, 0, STATE_SELECTED);
+ testStates("aria_tab2", STATE_SELECTED);
+ testStates("aria_tab3", 0, 0, STATE_SELECTED);
+ testStates("aria_option1", 0, 0, STATE_SELECTED);
+ testStates("aria_option2", STATE_SELECTED);
+ testStates("aria_option3", 0, 0, STATE_SELECTED);
+ testStates("aria_treeitem1", 0, 0, STATE_SELECTED);
+ testStates("aria_treeitem2", STATE_SELECTED);
+ testStates("aria_treeitem3", 0, 0, STATE_SELECTED);
+
+ // selected state when widget item is focused
+ gQueue = new eventQueue(EVENT_FOCUS);
+
+ gQueue.push(new focusARIAItem("aria_tab1", true));
+ gQueue.push(new focusARIAItem("aria_tab2", true));
+ gQueue.push(new focusARIAItem("aria_tab3", false));
+ gQueue.push(new focusARIAItem("aria_option1", true));
+ gQueue.push(new focusARIAItem("aria_option2", true));
+ gQueue.push(new focusARIAItem("aria_option3", false));
+ gQueue.push(new focusARIAItem("aria_treeitem1", true));
+ gQueue.push(new focusARIAItem("aria_treeitem2", true));
+ gQueue.push(new focusARIAItem("aria_treeitem3", false));
+
+ // selected state when widget item is focused (by aria-activedescendant)
+ gQueue.push(new focusActiveDescendantItem("aria_tab5", "aria_tablist2", true));
+ gQueue.push(new focusActiveDescendantItem("aria_tab6", "aria_tablist2", true));
+ gQueue.push(new focusActiveDescendantItem("aria_tab4", "aria_tablist2", false));
+
+ gQueue.invoke(); // SimpleTest.finish() will be called in the end
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+<body>
+
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=653601"
+ title="aria-selected ignored for ARIA tabs">
+ Mozilla Bug 653601
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=526703"
+ title="Focused widget item should expose selected state by default">
+ Mozilla Bug 526703
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <!-- tab -->
+ <div id="aria_tablist" role="tablist">
+ <div id="aria_tab1" role="tab" tabindex="0">unselected tab</div>
+ <div id="aria_tab2" role="tab" tabindex="0" aria-selected="true">selected tab</div>
+ <div id="aria_tab3" role="tab" tabindex="0" aria-selected="false">focused explicitly unselected tab</div>
+ </div>
+
+ <!-- listbox -->
+ <div id="aria_listbox" role="listbox">
+ <div id="aria_option1" role="option" tabindex="0">unselected option</div>
+ <div id="aria_option2" role="option" tabindex="0" aria-selected="true">selected option</div>
+ <div id="aria_option3" role="option" tabindex="0" aria-selected="false">focused explicitly unselected option</div>
+ </div>
+
+ <!-- tree -->
+ <div id="aria_tree" role="tree">
+ <div id="aria_treeitem1" role="treeitem" tabindex="0">unselected treeitem</div>
+ <div id="aria_treeitem2" role="treeitem" tabindex="0" aria-selected="true">selected treeitem</div>
+ <div id="aria_treeitem3" role="treeitem" tabindex="0" aria-selected="false">focused explicitly unselected treeitem</div>
+ </div>
+
+ <!-- tab managed by active-descendant -->
+ <div id="aria_tablist2" role="tablist" tabindex="0">
+ <div id="aria_tab4" role="tab" aria-selected="false">focused explicitly unselected tab</div>
+ <div id="aria_tab5" role="tab">initially selected tab</div>
+ <div id="aria_tab6" role="tab">later selected tab</div>
+ </div>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_buttons.html b/accessible/tests/mochitest/states/test_buttons.html
new file mode 100644
index 000000000..52c642ce5
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_buttons.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>HTML button accessible states</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="../states.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ // Default state.
+ testStates("f1_image", STATE_DEFAULT | STATE_FOCUSABLE);
+ testStates("f2_submit", STATE_DEFAULT | STATE_FOCUSABLE);
+ testStates("f3_submitbutton", STATE_DEFAULT | STATE_FOCUSABLE);
+ testStates("f3_disabled_reset", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE, 0);
+ testStates("f4_button", STATE_FOCUSABLE, 0, STATE_DEFAULT);
+ testStates("f4_disabled_button", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE, 0);
+ testStates("f4_image1", STATE_DEFAULT | STATE_FOCUSABLE);
+ testStates("f4_image2", STATE_FOCUSABLE, 0, STATE_DEFAULT);
+ testStates("f4_submit", STATE_FOCUSABLE, 0, STATE_DEFAULT);
+ testStates("f4_submitbutton", STATE_FOCUSABLE, 0, STATE_DEFAULT);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+
+<body>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=664142"
+ title="DEFAULT state exposed incorrectly for HTML">
+ Mozilla Bug 664142
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <p>A form with an image button</p>
+ <form name="form1" method="get">
+ <input type="text" name="hi">
+
+ <input id="f1_image" type="image" value="image-button">
+ </form>
+
+ <p>A form with a submit button:</p>
+ <form name="form2" method="get">
+ <input type="text" name="hi">
+ <input id="f2_submit" type="submit">
+ </form>
+
+ <p>A form with a HTML4 submit button:</p>
+ <form name="form3" method="get">
+ <input type="text" name="hi">
+ <button id="f3_submitbutton" type="submit">submit</button>
+ <button id="f3_disabled_reset" type="reset" disabled>reset</button>
+ </form>
+
+ <p>A form with normal button, two image buttons, submit button,
+ HTML4 submit button:</p>
+ <form name="form4" method="get">
+ <input type="text" name="hi">
+ <input id="f4_button" type="button" value="normal" name="normal-button">
+ <input id="f4_disabled_button" type="button" value="disabled" name="disabled-button" disabled>
+ <input id="f4_image1" type="image" value="image-button1" name="image-button1">
+ <input id="f4_image2" type="image" value="image-button2" name="image-button2">
+ <input id="f4_submit" type="submit" value="real-submit" name="real-submit">
+ <button id="f4_submitbutton" type="submit">submit</button>
+ </form>
+
+ </body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_controls.html b/accessible/tests/mochitest/states/test_controls.html
new file mode 100644
index 000000000..7369f6d01
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_controls.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>HTML control states</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="../states.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ // Undetermined progressbar (no value or aria-value attribute): mixed state
+ testStates("progress", STATE_MIXED);
+ // Determined progressbar (has value): shouldn't have mixed state
+ testStates("progress2", 0, 0, STATE_MIXED);
+ // Determined progressbar (has aria-value): shouldn't have mixed state
+ // testStates("progress3", 0, 0, STATE_MIXED);
+ todo(false, "we should respect ARIA");
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+
+<body>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=670853"
+ title="Bug 670853 - undetermined progressmeters should expose mixed state">
+ Mozilla Bug 670853
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <progress id="progress"></progress>
+ <progress id="progress2" value="1"></progress>
+ <progress id="progress3" aria-valuenow="1"></progress>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_controls.xul b/accessible/tests/mochitest/states/test_controls.xul
new file mode 100644
index 000000000..83de45256
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_controls.xul
@@ -0,0 +1,182 @@
+<?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 input control state 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="../role.js" />
+ <script type="application/javascript"
+ src="../states.js" />
+ <script type="application/javascript"
+ src="../events.js" />
+
+ <script type="application/javascript">
+ <![CDATA[
+ function openColorpicker(aID)
+ {
+ this.popupNode = getNode(aID).mPicker.parentNode;
+ this.popup = getAccessible(this.popupNode);
+
+ this.eventSeq = [
+ new invokerChecker(EVENT_REORDER, this.popupNode)
+ ];
+
+ this.invoke = function openColorpicker_invoke()
+ {
+ getNode(aID).showPopup();
+ }
+
+ this.finalCheck = function openColorpicker_finalCheck()
+ {
+ testStates(this.popup.firstChild,
+ STATE_FOCUSABLE | STATE_SELECTABLE, 0,
+ STATE_UNAVAILABLE);
+ }
+
+ this.getID = function openColorpicker_getID()
+ {
+ return "open colorpicker";
+ }
+ }
+
+ var gQueue = null;
+ function doTest()
+ {
+ testStates("checkbox", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
+ testStates("checkbox2", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE);
+ testStates("radiogroup", 0, 0, STATE_FOCUSABLE | STATE_UNAVAILABLE);
+ testStates("radio", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
+ testStates("radio-disabled", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE);
+ testStates("radiogroup-disabled", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE);
+ testStates("radio-disabledradiogroup", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE);
+ testStates("button", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
+ testStates("button-disabled", STATE_UNAVAILABLE, 0 , STATE_FOCUSABLE);
+ testStates("colorpicker", STATE_FOCUSABLE | STATE_HASPOPUP, 0, STATE_UNAVAILABLE);
+ testStates("colorpicker-disabled", STATE_HASPOPUP, 0, STATE_FOCUSABLE);
+ testStates("combobox", STATE_FOCUSABLE | STATE_HASPOPUP, 0, STATE_UNAVAILABLE);
+ testStates("combobox-disabled", STATE_UNAVAILABLE | STATE_HASPOPUP, 0, STATE_FOCUSABLE);
+ testStates("listbox", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
+ testStates("listitem", STATE_FOCUSABLE | STATE_SELECTABLE, 0, STATE_UNAVAILABLE);
+ testStates("listbox-disabled", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE);
+ testStates("listitem-disabledlistbox", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE);
+ testStates("menubar", 0, 0, STATE_FOCUSABLE);
+ testStates("menu", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
+ testStates("menu-disabled", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE);
+ testStates("scale", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
+ testStates("scale-disabled", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE);
+ testStates("tab", STATE_FOCUSABLE | STATE_SELECTABLE | STATE_SELECTED, 0, STATE_UNAVAILABLE);
+ testStates("tab-disabled", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE | STATE_SELECTED);
+
+ gQueue = new eventQueue();
+ gQueue.push(new openColorpicker("colorpicker"));
+ gQueue.invoke(); // Will call SimpleTest.finish()
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ ]]>
+ </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=599163"
+ title="check disabled state instead of attribute">
+ Mozilla Bug 599163
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=756983"
+ title="Isolate focusable and unavailable states from State()">
+ Mozilla Bug 756983
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <vbox flex="1">
+
+ <checkbox id="checkbox" checked="true" label="Steak"/>
+ <checkbox id="checkbox2" checked="true" label="Salad" disabled="true"/>
+
+ <radiogroup id="radiogroup">
+ <radio id="radio" label="Orange"/>
+ <radio id="radio-disabled" selected="true" label="Violet" disabled="true"/>
+ </radiogroup>
+
+ <radiogroup id="radiogroup-disabled" disabled="true">
+ <radio id="radio-disabledradiogroup" label="Orange"/>
+ <radio id="violet2" selected="true" label="Violet"/>
+ </radiogroup>
+
+ <button id="button" value="button"/>
+ <button id="button-disabled" disabled="true" value="button"/>
+
+ <colorpicker id="colorpicker" type="button"/>
+ <colorpicker id="colorpicker-disabled" type="button" disabled="true"/>
+
+ <menulist id="combobox">
+ <menupopup>
+ <menuitem label="item1"/>
+ </menupopup>
+ </menulist>
+
+ <menulist id="combobox-disabled" disabled="true">
+ <menupopup>
+ <menuitem label="item1"/>
+ </menupopup>
+ </menulist>
+
+ <listbox id="listbox">
+ <listitem id="listitem" label="list item"/>
+ </listbox>
+
+ <listbox id="listbox-disabled" disabled="true">
+ <listitem id="listitem-disabledlistbox" label="list item"/>
+ </listbox>
+
+ <toolbox>
+ <menubar id="menubar">
+ <menu id="menu" label="menu1">
+ <menupopup>
+ <menuitem id="menu1-item1" label="menuitem1.1"/>
+ </menupopup>
+ </menu>
+ <menu id="menu-disabled" label="menu2" disabled="true">
+ <menupopup>
+ <menuitem id="menu-disabled-item1" label="menuitem2.1"/>
+ </menupopup>
+ </menu>
+ </menubar>
+ </toolbox>
+
+ <scale id="scale" min="1" max="10"/>
+ <scale id="scale-disabled" min="1" max="10" disabled="true"/>
+
+ <tabbox>
+ <tabs>
+ <tab id="tab" label="tab1" tooltip="tooltip"/>
+ <tab id="tab-disabled" label="tab1" disabled="true"/>
+ </tabs>
+ <tabpanels>
+ <tabpanel/>
+ <tabpanel/>
+ </tabpanels>
+ </tabbox>
+
+ <tooltip id="tooltip"><description>tooltip</description></tooltip>
+ </vbox>
+ </hbox>
+
+</window>
+
diff --git a/accessible/tests/mochitest/states/test_doc.html b/accessible/tests/mochitest/states/test_doc.html
new file mode 100644
index 000000000..83edd9dac
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_doc.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>states of document</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="../states.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ // Bug 566542: root accesible should expose active state when focused.
+ testStates(getRootAccessible(), 0, EXT_STATE_ACTIVE);
+
+ // Bug 509696, 607219.
+ testStates(document, STATE_READONLY, 0); // role=""
+
+ document.body.setAttribute("role","banner"); // no platform mapping
+ testStates(document, STATE_READONLY);
+ document.body.setAttribute("role","foo"); // bogus role
+ testStates(document, STATE_READONLY);
+ document.body.removeAttribute("role");
+ testStates(document, STATE_READONLY);
+
+ // Bugs 454997 and 467387
+ testStates(document, STATE_READONLY);
+ testStates("document", STATE_READONLY);
+ testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+
+ document.designMode = "on";
+
+ testStates(document, 0, EXT_STATE_EDITABLE, STATE_READONLY);
+ testStates("p", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+ testStates("document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+ testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+
+ document.designMode = "off";
+
+ testStates(document, STATE_READONLY);
+ testStates("document", STATE_READONLY);
+ testStates("editable_document", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+
+<body role="">
+
+ <a target="_blank"
+ title="<body contenteditable='true'> exposed incorrectly"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=454997">Mozilla Bug 454997</a>
+ <a target="_blank"
+ title="nsIAccessible states tests of editable document"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=467387">Mozilla Bug 467387</a>
+ <a target="_blank"
+ title="Role attribute on body with empty string causes DocAccessible not to have read-only state."
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=509696">Mozilla Bug 509696</a>
+ <a target="_blank"
+ title="Frame for firefox does not implement the state "active" when firefox is the active frame"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=566542">Mozilla Bug 566542</a>
+ <a target="_blank"
+ title="Dynamic role attribute change on body doesn't affect on document role"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=607219">Mozilla Bug 607219</a>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <p id="p">hello</p>
+
+ <div id="document" role="document">document</div>
+ <div id="editable_document" role="document" contentEditable="true">editable document</doc>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_doc_busy.html b/accessible/tests/mochitest/states/test_doc_busy.html
new file mode 100644
index 000000000..8e1422da1
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_doc_busy.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>states of document</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="../role.js"></script>
+ <script type="application/javascript"
+ src="../states.js"></script>
+ <script type="application/javascript"
+ src="../events.js"></script>
+
+ <script type="application/javascript">
+ //gA11yEventDumpToConsole = true; // debugging stuff
+
+ function loadFile()
+ {
+ var eventSeq = [
+ new stateChangeChecker(STATE_BUSY, false, true, document, null, false, true),
+ new stateChangeChecker(STATE_BUSY, false, false, document)
+ ];
+ defineScenario(this, eventSeq); // both events were fired
+
+ var unexpectedEventSeq = [
+ new stateChangeChecker(STATE_BUSY, false, true, document),
+ new stateChangeChecker(STATE_BUSY, false, false, document)
+ ];
+ defineScenario(this, [], unexpectedEventSeq); // events were coalesced
+
+ this.invoke = function loadFile_invoke()
+ {
+ synthesizeMouse(getNode("link"), 1, 1, {});
+ }
+
+ this.getID = function loadFile_getID()
+ {
+ return "load file: state busy change events on document";
+ }
+ }
+
+ var gQueue = null;
+ function doTest()
+ {
+ // State busy change event on file loading.
+ //enableLogging("docload"); // debugging
+ gQueue = new eventQueue();
+ gQueue.push(new loadFile());
+ //gQueue.onFinish = function() { disableLogging(); } // debugging
+ gQueue.invoke(); // Will call SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+
+<body>
+
+ <a target="_blank"
+ title="Missing busy state change event when downloading files"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=446469">Bug 446469</a>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <a id="link" href="http://example.com/a11y/accessible/tests/mochitest/dumbfile.zip">a file</a>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_docarticle.html b/accessible/tests/mochitest/states/test_docarticle.html
new file mode 100644
index 000000000..1ac62ee4b
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_docarticle.html
@@ -0,0 +1,80 @@
+<html>
+<head>
+ <title>states of document article</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="../states.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ var docAcc = getAccessible(document, [nsIAccessibleDocument]);
+ if (docAcc) {
+ testStates(docAcc, STATE_READONLY);
+ testStates("aria_article", STATE_READONLY);
+ testStates("editable_aria_article", 0, EXT_STATE_EDITABLE,
+ STATE_READONLY);
+ testStates("article", STATE_READONLY);
+ testStates("editable_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+
+ document.designMode = "on";
+
+ testStates(docAcc, 0, EXT_STATE_EDITABLE, STATE_READONLY);
+ testStates("aria_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+ testStates("editable_aria_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+ testStates("article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+ testStates("editable_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+
+ document.designMode = "off";
+
+ testStates(docAcc, STATE_READONLY);
+ testStates("aria_article", STATE_READONLY);
+ testStates("editable_aria_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+ testStates("article", STATE_READONLY);
+ testStates("editable_article", 0, EXT_STATE_EDITABLE, STATE_READONLY);
+ }
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+
+<body role="article">
+
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=467387"
+ title="Expose non-editable documents as readonly, regardless of role">
+ Mozilla Bug 467387
+ </a><br/>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=613502"
+ title="Map <article> like we do aria role article">
+ Mozilla Bug 613502
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <div id="aria_article" role="article">aria article</div>
+ <div id="editable_aria_article" role="article" contentEditable="true">
+ editable aria article</div>
+
+ <article id="article">article</article>
+ <article id="editable_article" contentEditable="true">
+ editable article</article>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_editablebody.html b/accessible/tests/mochitest/states/test_editablebody.html
new file mode 100644
index 000000000..3b1486876
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_editablebody.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=454997
+-->
+<head>
+ <title>nsIAccessible states tests of contenteditable body</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="../states.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ testStates(document, 0, EXT_STATE_EDITABLE);
+ testStates("p", 0, EXT_STATE_EDITABLE);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+
+<body contentEditable="true">
+
+ <a target="_blank"
+ title="nsIAccessible states tests of contenteditable body"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=454997">Mozilla Bug 454997</a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <p id="p">hello</p>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_expandable.xul b/accessible/tests/mochitest/states/test_expandable.xul
new file mode 100644
index 000000000..1e210a0ef
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_expandable.xul
@@ -0,0 +1,118 @@
+<?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"?>
+
+<!-- Firefox searchbar -->
+<?xml-stylesheet href="chrome://browser/content/browser.css"
+ type="text/css"?>
+<!-- SeaMonkey searchbar -->
+<?xml-stylesheet href="chrome://navigator/content/navigator.css"
+ type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Expanded state change events tests for comboboxes and autocompletes.">
+
+ <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 type="application/javascript"
+ src="../autocomplete.js" />
+
+ <script type="application/javascript"
+ src="../common.js" />
+ <script type="application/javascript"
+ src="../role.js" />
+ <script type="application/javascript"
+ src="../states.js" />
+ <script type="application/javascript"
+ src="../events.js" />
+
+ <script type="application/javascript">
+ <![CDATA[
+ //gA11yEventDumpToConsole = true; // debuggin
+
+ var gQueue = null;
+ function doTest()
+ {
+ gQueue = new eventQueue();
+
+ gQueue.push(new openCombobox("menulist"));
+ gQueue.push(new closeCombobox("menulist"));
+
+ todo(false, "Autocompletes don't fire expanded state change events when popup open. See bug 688480!");
+ //gQueue.push(new openCombobox("autocomplete"));
+ //gQueue.push(new closeCombobox("autocomplete"));
+
+ // XXX: searchbar doesn't fire state change events because accessible
+ // parent of combobox_list accessible is pushbutton accessible.
+ //var searchbar = document.getElementById("searchbar");
+ //gQueue.push(new openHideCombobox(searchbar, true));
+ //gQueue.push(new openHideCombobox(searchbar, false));
+ todo(false, "Enable states test for XUL searchbar widget!");
+
+ gQueue.onFinish = function()
+ {
+ // unregister 'test-a11y-search' autocomplete search
+ shutdownAutoComplete();
+ }
+
+ gQueue.invoke(); // Will call SimpleTest.finish();
+ }
+
+ // This is the hacks needed to use a searchbar without browser.js.
+ function getBrowser()
+ {
+ return {
+ mCurrentBrowser: { engines: new Array() }
+ };
+ }
+ var BrowserSearch = {
+ updateOpenSearchBadge: function() {}
+ };
+
+ SimpleTest.waitForExplicitFinish();
+
+ // Register 'test-a11y-search' autocomplete search.
+ // XPFE AutoComplete needs to register early.
+ initAutoComplete([ "hello", "hi" ],
+ [ "Beep beep'm beep beep yeah", "Baby you can drive my car" ]);
+
+ addA11yLoadEvent(doTest);
+ ]]>
+ </script>
+
+ <hbox 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=467057"
+ title="xul menulist doesn't fire expand/collapse state change events">
+ Mozilla Bug 467057
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <vbox flex="1">
+ <menulist id="menulist">
+ <menupopup>
+ <menuitem label="item1"/>
+ <menuitem label="item2"/>
+ <menuitem label="item3"/>
+ </menupopup>
+ </menulist>
+
+ <textbox id="autocomplete" type="autocomplete"
+ autocompletesearch="test-a11y-search"/>
+
+ <searchbar id="searchbar"/>
+ </vbox>
+ </hbox>
+
+</window>
+
diff --git a/accessible/tests/mochitest/states/test_frames.html b/accessible/tests/mochitest/states/test_frames.html
new file mode 100644
index 000000000..cb3bca844
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_frames.html
@@ -0,0 +1,95 @@
+<html>
+
+<head>
+ <title>frame based document testing</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="../states.js"></script>
+
+ <script type="application/javascript">
+ if (navigator.platform.startsWith("Win")) {
+ SimpleTest.expectAssertions(0, 2);
+ }
+
+ function doTest()
+ {
+ frameDoc = document.getElementById("frame_doc").contentDocument;
+ frameDocArticle = document.getElementById("frame_doc_article").contentDocument;
+ frameDocCheckbox = document.getElementById("frame_doc_checkbox").contentDocument;
+ frameDocTextbox = document.getElementById("frame_doc_textbox").contentDocument;
+
+ testStates(frameDoc, STATE_READONLY, 0, 0, 0,
+ "test1: frameDoc");
+ testStates(frameDocArticle, STATE_READONLY, 0, 0, 0,
+ "test1: frameDocArticle");
+ testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0,
+ "test1: frameDocCheckbox");
+ testStates(frameDocTextbox, 0, EXT_STATE_EDITABLE, STATE_READONLY, 0,
+ "test1: frameDocTextbox");
+ frameDoc.designMode = "on";
+ testStates(frameDoc, 0, EXT_STATE_EDITABLE, STATE_READONLY, 0,
+ "test2: frameDoc");
+ testStates(frameDocArticle, STATE_READONLY, 0, 0, 0,
+ "test2: frameDocArticle");
+ testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0,
+ "test2: frameDocCheckbox");
+ testStates(frameDocTextbox, 0, EXT_STATE_EDITABLE, STATE_READONLY, 0,
+ "test2: frameDocTextbox");
+
+ frameDocArticle.designMode = "on";
+ testStates(frameDocArticle, 0, EXT_STATE_EDITABLE, STATE_READONLY, 0,
+ "test3: frameDocArticle");
+
+ frameDocCheckbox.designMode = "on";
+ testStates(frameDocCheckbox, 0, 0, STATE_READONLY, 0,
+ "test4: frameDocCheckbox");
+
+ // Replace iframe document body before the document accessible tree is
+ // created. Check the states are updated for new body.
+ var frameUpdateDoc =
+ document.getElementById("frame_updatedoc").contentDocument;
+ testStates(frameUpdateDoc, 0, EXT_STATE_EDITABLE,
+ STATE_READONLY, EXT_STATE_STALE, "test5: frameUpdateDoc");
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+
+<body>
+
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=467387"
+ title="Expose non-editable documents as readonly, regardless of role">
+ Mozilla Bug 467387
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=638106"
+ title="CKEditor document should be editable">
+ Mozilla Bug 638106
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <iframe id="frame_doc" src="z_frames.html"></iframe>
+ <iframe id="frame_doc_article" src="z_frames_article.html"></iframe>
+ <iframe id="frame_doc_checkbox" src="z_frames_checkbox.html"></iframe>
+ <iframe id="frame_doc_textbox" src="z_frames_textbox.html"></iframe>
+ <iframe id="frame_updatedoc" src="z_frames_update.html"></iframe>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_inputs.html b/accessible/tests/mochitest/states/test_inputs.html
new file mode 100644
index 000000000..20c6deaf8
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_inputs.html
@@ -0,0 +1,271 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>HTML input states</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="../role.js"></script>
+ <script type="application/javascript"
+ src="../states.js"></script>
+
+ <script type="application/javascript">
+ function doTest()
+ {
+ ////////////////////////////////////////////////////////////////////////////
+ // 'editable' and 'multiline' states.
+ testStates("input", 0, EXT_STATE_EDITABLE, 0, EXT_STATE_MULTI_LINE);
+ testStates("textarea", 0, EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE);
+
+ testStates("input_readonly", 0, EXT_STATE_EDITABLE);
+ testStates("input_disabled", 0, EXT_STATE_EDITABLE);
+ testStates("textarea_readonly", 0, EXT_STATE_EDITABLE);
+ testStates("textarea_disabled", 0, EXT_STATE_EDITABLE);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // 'required', 'readonly' and 'unavailable' states.
+ var maybe_required = ["input","search","radio","checkbox","textarea"];
+ var never_required = ["submit","button","reset","image"];
+
+ var i;
+ for (i in maybe_required) {
+ testStates(maybe_required[i],
+ STATE_FOCUSABLE, 0,
+ STATE_REQUIRED | STATE_READONLY | STATE_UNAVAILABLE);
+
+ testStates(maybe_required[i] + "_required",
+ STATE_FOCUSABLE | STATE_REQUIRED, 0,
+ STATE_UNAVAILABLE | STATE_READONLY);
+
+ var readonlyID = maybe_required[i] + "_readonly";
+ if (document.getElementById(readonlyID)) {
+ testStates(readonlyID,
+ STATE_FOCUSABLE | STATE_READONLY, 0,
+ STATE_UNAVAILABLE | STATE_REQUIRED);
+ }
+
+ testStates(maybe_required[i] + "_disabled",
+ STATE_UNAVAILABLE, 0,
+ STATE_FOCUSABLE | STATE_READONLY | STATE_REQUIRED);
+ }
+
+ for (i in never_required) {
+ testStates(never_required[i], 0, 0, STATE_REQUIRED | EXT_STATE_EDITABLE);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // inherited 'unavailable' state
+ testStates("f", STATE_UNAVAILABLE);
+ testStates("f_input", STATE_UNAVAILABLE);
+ testStates("f_input_disabled", STATE_UNAVAILABLE);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // inherited from file control
+ var fileBrowseButton = getAccessible("file").firstChild;
+ testStates(fileBrowseButton, STATE_UNAVAILABLE | STATE_REQUIRED);
+ // No states on the label.
+
+ ////////////////////////////////////////////////////////////////////////////
+ // 'invalid' state
+ var invalid = ["pattern","email","url"];
+ for (i in invalid) {
+ testStates(invalid[i], STATE_INVALID);
+ testStates(invalid[i] + "2", 0, 0, STATE_INVALID);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // not 'invalid' state
+ // (per spec, min/maxlength are always valid until interactively edited)
+ var validInput = document.createElement("input");
+ validInput.maxLength = '0';
+ validInput.value = 'a';
+ ok(validInput.validity.valid,
+ "input should be valid despite maxlength (no interactive edits)");
+
+ var validInput2 = document.createElement("input");
+ validInput2.minLength = '1';
+ validInput2.value = '';
+ ok(validInput2.validity.valid,
+ "input should be valid despite minlength (no interactive edits)");
+
+ var valid = ["minlength","maxlength"];
+ for (i in valid) {
+ testStates(valid[i], 0, 0, STATE_INVALID);
+ testStates(valid[i] + "2", 0, 0, STATE_INVALID);
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // 'invalid' state
+ // (per spec, min/maxlength validity is affected by interactive edits)
+ var mininp = document.getElementById("minlength");
+ mininp.focus();
+ mininp.setSelectionRange(mininp.value.length, mininp.value.length);
+ synthesizeKey("VK_BACK_SPACE", {});
+ ok(!mininp.validity.valid,
+ "input should be invalid after interactive edits");
+ testStates(mininp, STATE_INVALID);
+ // inputs currently cannot be made longer than maxlength interactively,
+ // so we're not testing that case.
+
+ ////////////////////////////////////////////////////////////////////////////
+ // autocomplete states
+ testStates("autocomplete-default", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("autocomplete-off", 0, 0, 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("autocomplete-formoff", 0, 0, 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("autocomplete-list", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("autocomplete-list2", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("autocomplete-tel", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("autocomplete-email", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+ testStates("autocomplete-search", 0, EXT_STATE_SUPPORTS_AUTOCOMPLETION);
+
+ ////////////////////////////////////////////////////////////////////////////
+ // haspopup
+ testStates("autocomplete-list", STATE_HASPOPUP);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+
+<body>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=559275"
+ title="map attribute required to STATE_REQUIRED">
+ Bug 559275
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=389238"
+ title="Support disabled state on fieldset">
+ Bug 389238
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=599163"
+ title="check disabled state instead of attribute">
+ Bug 599163
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=601205"
+ title="Expose intrinsic invalid state to accessibility API">
+ Bug 601205
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=601205"
+ title="Expose intrinsic invalid state to accessibility API">
+ Bug 601205
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=559766"
+ title="Add accessibility support for @list on HTML input and for HTML datalist">
+ Bug 559766
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=699017"
+ title="File input control should be propogate states to descendants">
+ Bug 699017
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=733382"
+ title="Editable state bit should be present on readonly inputs">
+ Bug 733382
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=878590"
+ title="HTML5 datalist is not conveyed by haspopup property">
+ Bug 878590
+ </a>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+
+ <form>
+ <input id="input" type="input">
+ <input id="input_required" type="input" required>
+ <input id="input_readonly" type="input" readonly>
+ <input id="input_disabled" type="input" disabled>
+ <input id="search" type="search">
+ <input id="search_required" type="search" required>
+ <input id="search_readonly" type="search" readonly>
+ <input id="search_disabled" type="search" disabled>
+ <input id="radio" type="radio">
+ <input id="radio_required" type="radio" required>
+ <input id="radio_disabled" type="radio" disabled>
+ <input id="checkbox" type="checkbox">
+ <input id="checkbox_required" type="checkbox" required>
+ <input id="checkbox_disabled" type="checkbox" disabled>
+ <textarea id="textarea"></textarea>
+ <textarea id="textarea_required" required></textarea>
+ <textarea id="textarea_readonly" readonly></textarea>
+ <textarea id="textarea_disabled" disabled></textarea>
+ </form>
+
+ <!-- bogus required usage -->
+ <input id="submit" type="submit" required>
+ <input id="button" type="button" required>
+ <input id="reset" type="reset" required>
+ <input id="image" type="image" required>
+
+ <!-- inherited disabled -->
+ <fieldset id="f" disabled>
+ <input id="f_input">
+ <input id="f_input_disabled" disabled>
+ </fieldset>
+
+ <!-- inherited from input@type="file" -->
+ <input id="file" type="file" required disabled>
+
+ <!-- invalid/valid -->
+ <input id="maxlength" maxlength="1" value="f">
+ <input id="maxlength2" maxlength="100" value="foo">
+ <input id="minlength" minlength="2" value="fo">
+ <input id="minlength2" minlength="1" value="foo">
+ <input id="pattern" pattern="bar" value="foo">
+ <input id="pattern2" pattern="bar" value="bar">
+ <input id="email" type="email" value="foo">
+ <input id="email2" type="email" value="foo@bar.com">
+ <input id="url" type="url" value="foo">
+ <input id="url2" type="url" value="http://mozilla.org/">
+
+ <!-- autocomplete -->
+ <input id="autocomplete-default">
+ <input id="autocomplete-off" autocomplete="off">
+ <form autocomplete="off">
+ <input id="autocomplete-formoff">
+ </form>
+ <datalist id="cities">
+ <option>Paris</option>
+ <option>San Francisco</option>
+ </datalist>
+ <input id="autocomplete-list" list="cities">
+ <input id="autocomplete-list2" list="cities" autocomplete="off">
+ <input id="autocomplete-tel" type="tel">
+
+ Email Address:
+ <input id="autocomplete-email" type="email" list="contacts" value="xyzzy">
+ <datalist id="contacts">
+ <option>xyzzy@plughs.com</option>
+ <option>nobody@mozilla.org</option>
+ </datalist>
+
+ </br>Search for:
+ <input id="autocomplete-search" type="search" list="searchhisty" value="Gamma">
+ <datalist id="searchhisty">
+ <option>Gamma Rays</option>
+ <option>Gamma Ray Bursts</option>
+ </datalist>
+
+ </body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_link.html b/accessible/tests/mochitest/states/test_link.html
new file mode 100644
index 000000000..3f89f9f7f
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_link.html
@@ -0,0 +1,144 @@
+<html>
+
+<head>
+ <title>HTML link states testing</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="../role.js"></script>
+ <script type="application/javascript"
+ src="../states.js"></script>
+ <script type="application/javascript"
+ src="../events.js"></script>
+
+ <script type="application/javascript">
+ //gA11yEventDumpToConsole = true; // debug stuff
+
+ var gLinkWindow = null;
+ function closeDocChecker()
+ {
+ this.__proto__ = new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE);
+
+ this.check = function closeDocChecker_check(aEvent)
+ {
+ gLinkWindow = aEvent.accessible.rootDocument.window;
+ }
+
+ this.match = function closeDocChecker_match(aEvent)
+ {
+ // A temporary about:blank document gets loaded before 'example.com'
+ // document.
+ return aEvent.DOMNode.URL == "http://www.example.com/";
+ }
+ }
+
+ function clickLink(aID)
+ {
+ this.eventSeq = [
+ new stateChangeChecker(STATE_TRAVERSED, false, true, "link_traversed"),
+ new closeDocChecker()
+ ];
+
+ this.invoke = function clickLink_invoke()
+ {
+ synthesizeMouse(getNode("link_traversed"), 1, 1, { shiftKey: true });
+ }
+
+ this.getID = function clickLink_getID()
+ {
+ return "link + '" + aID + "' clicked.";
+ }
+ }
+
+ var gQueue = null;
+ function doTest()
+ {
+ // a@href and its text node
+ testStates("link_href", STATE_LINKED);
+ testStates(getAccessible("link_href").firstChild, STATE_LINKED);
+
+ // a@onclick
+ testStates("link_click", STATE_LINKED);
+
+ // a@onmousedown
+ testStates("link_mousedown", STATE_LINKED);
+
+ // a@onmouseup
+ testStates("link_mouseup", STATE_LINKED);
+
+ // a@role="link"
+ testStates("link_arialink", STATE_LINKED);
+
+ // a@role="button"
+ testStates("link_ariabutton", 0, 0, STATE_LINKED);
+
+ // a (no @href, no click event listener)
+ testStates("link_notlink", 0, 0, STATE_LINKED);
+
+ // a: no traversed state
+ testStates("link_traversed", 0, 0, STATE_TRAVERSED);
+
+ // a: traversed state
+ //enableLogging("docload"); // debug stuff
+
+ gQueue = new eventQueue();
+ gQueue.push(new clickLink("link_traversed"));
+ gQueue.onFinish =
+ function()
+ {
+ gLinkWindow.close();
+ //disableLogging(); // debug stuff
+ }
+
+ gQueue.invoke(); // will call SimpleTest.finsih();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+
+</head>
+
+<body>
+
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=423409"
+ title="Expose click action if mouseup and mousedown are registered">
+ Mozilla Bug 423409
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=754830"
+ title="Calculate link states separately">
+ Mozilla Bug 754830
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=757774"
+ title="Fire state change event when link is traversed">
+ Mozilla Bug 757774
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <a id="link_href" href="http://mozilla.org">link</a>
+ <a id="link_click" onclick="">link</a>
+ <a id="link_mousedown" onmousedown="">link</a>
+ <a id="link_mouseup" onmouseup="">link</a>
+ <a id="link_arialink" role="link">aria link</a>
+ <a id="link_ariabutton" role="button">aria button</a>
+ <a id="link_notlink">not link</a>
+
+ <a id="link_traversed" href="http://www.example.com" target="_top">example.com</a>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_popup.xul b/accessible/tests/mochitest/states/test_popup.xul
new file mode 100644
index 000000000..bc40a8b70
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_popup.xul
@@ -0,0 +1,55 @@
+<?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="XUL popup attribute test">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+ <script type="application/javascript"
+ src="../common.js" />
+ <script type="application/javascript"
+ src="../role.js" />
+ <script type="application/javascript"
+ src="../states.js" />
+
+ <script type="application/javascript">
+ <![CDATA[
+ function doTest()
+ {
+ // label with popup
+ testStates("labelWithPopup", STATE_HASPOPUP);
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ ]]>
+ </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=504252"
+ title="Expose STATE_HASPOPUP on XUL elements that have an @popup attribute">
+ Mozilla Bug 504252
+ </a><br/>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <!-- label with popup attribute -->
+ <label id="labelWithPopup" value="file name"
+ popup="fileContext"
+ tabindex="0"/>
+ </hbox>
+
+</window>
+
diff --git a/accessible/tests/mochitest/states/test_selects.html b/accessible/tests/mochitest/states/test_selects.html
new file mode 100644
index 000000000..0029fcbe4
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_selects.html
@@ -0,0 +1,203 @@
+<html>
+
+<head>
+ <title>HTML selects accessible states 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="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">
+ function openComboboxNCheckStates(aID)
+ {
+ this.combobox = getAccessible(aID);
+ this.comboboxList = this.combobox.firstChild;
+ this.comboboxOption = this.comboboxList.firstChild;
+
+ this.eventSeq = [
+ new invokerChecker(EVENT_FOCUS, this.comboboxOption)
+ ];
+
+ this.invoke = function openComboboxNCheckStates_invoke()
+ {
+ getNode(aID).focus();
+ synthesizeKey("VK_DOWN", { altKey: true });
+ }
+
+ this.finalCheck = function openComboboxNCheckStates_invoke()
+ {
+ // Expanded state on combobox.
+ testStates(this.combobox, STATE_EXPANDED);
+
+ // Floating state on combobox list.
+ testStates(this.comboboxList, STATE_FLOATING);
+ }
+
+ this.getID = function openComboboxNCheckStates_getID()
+ {
+ return "open combobox and test states";
+ }
+ }
+
+ //gA11yEventDumpToConsole = true;
+
+ var gQueue = null;
+ function doTest()
+ {
+ // combobox
+ var combobox = getAccessible("combobox");
+ testStates(combobox,
+ STATE_HASPOPUP | STATE_COLLAPSED | STATE_FOCUSABLE, 0,
+ STATE_FOCUSED, 0);
+
+ var comboboxList = combobox.firstChild;
+ testStates(comboboxList, STATE_INVISIBLE, 0, STATE_FOCUSABLE, 0);
+
+ var opt1 = comboboxList.firstChild;
+ testStates(opt1, STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE,
+ EXT_STATE_ACTIVE, STATE_FOCUSED, 0);
+
+ var opt2 = comboboxList.lastChild;
+ testStates(opt2, STATE_SELECTABLE | STATE_FOCUSABLE, 0, STATE_SELECTED, 0,
+ STATE_FOCUSED, EXT_STATE_ACTIVE);
+
+ // collapsed combobox
+ testStates("collapsedcombobox",
+ STATE_COLLAPSED | STATE_FOCUSABLE, 0,
+ STATE_FOCUSED, 0);
+
+ testStates("collapsed-1",
+ STATE_FOCUSABLE | STATE_SELECTABLE, 0,
+ STATE_OFFSCREEN | STATE_INVISIBLE, 0);
+
+ testStates("collapsed-2",
+ STATE_OFFSCREEN, 0,
+ STATE_INVISIBLE, 0);
+
+ // listbox
+ testStates("listbox",
+ STATE_FOCUSABLE, 0,
+ STATE_HASPOPUP | STATE_COLLAPSED | STATE_FOCUSED);
+
+ testStates("listitem-active",
+ STATE_FOCUSABLE | STATE_SELECTABLE, EXT_STATE_ACTIVE,
+ STATE_SELECTED | STATE_FOCUSED);
+
+ testStates("listitem",
+ STATE_FOCUSABLE | STATE_SELECTABLE, 0,
+ STATE_SELECTED | STATE_FOCUSED, EXT_STATE_ACTIVE);
+
+ testStates("listitem-disabled",
+ STATE_UNAVAILABLE, 0,
+ STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE,
+ EXT_STATE_ACTIVE);
+
+ testStates("listgroup",
+ 0, 0,
+ STATE_UNAVAILABLE | STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE,
+ EXT_STATE_ACTIVE);
+
+ testStates("listgroup-disabled",
+ STATE_UNAVAILABLE, 0,
+ STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE,
+ EXT_STATE_ACTIVE);
+
+ todo(false, "no unavailable state on option in disabled group (bug 759666)");
+// testStates("listitem-disabledgroup",
+// STATE_UNAVAILABLE, 0,
+// STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE,
+// EXT_STATE_ACTIVE);
+
+ testStates("listbox-disabled",
+ STATE_UNAVAILABLE, 0,
+ STATE_FOCUSABLE);
+
+ todo(false, "no unavailable state on option in disabled select (bug 759666)");
+// testStates("listitem-disabledlistbox",
+// STATE_UNAVAILABLE, 0,
+// STATE_SELECTABLE | STATE_SELECTED | STATE_FOCUSABLE,
+// EXT_STATE_ACTIVE);
+
+ // open combobox
+ gQueue = new eventQueue();
+ gQueue.push(new openComboboxNCheckStates("combobox"));
+ gQueue.invoke(); // Will call */SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+
+</head>
+
+<body>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=443889"
+ title="mochitest for selects and lists">
+ Mozilla Bug 443889
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=640716"
+ title="mochitest for selects and lists">
+ Mozilla Bug 640716
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=689847"
+ title="Expose active state on current item of selectable widgets">
+ Mozilla Bug 689847
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=756983"
+ title="Isolate focusable and unavailable states from State()">
+ Mozilla Bug 756983
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=907682"
+ title=" HTML:option group position is not correct when select is collapsed">
+ Mozilla Bug 907682
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <select id="combobox">
+ <option>item 1</option>
+ <option>item 2</option>
+ </select>
+
+ <select id="collapsedcombobox">
+ <option id="collapsed-1">item 1</option>
+ <option id="collapsed-2">item 2</option>
+ </select>
+
+ <select id="listbox" name="component" size="3">
+ <option id="listitem-active">Build</option>
+ <option id="listitem">Disability Access APIs</option>
+ <option id="listitem-disabled" disabled>General</option>
+ <optgroup id="listgroup" label="group">
+ <option>option</option>
+ </optgroup>
+ <optgroup id="listgroup-disabled" disabled label="group2">
+ <option id="listitem-disabledgroup">UI</option>
+ </optgroup>
+ </select>
+
+ <select id="listbox-disabled" size="3" disabled>
+ <option id="listitem-disabledlistbox">option</option>
+ </select>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_stale.html b/accessible/tests/mochitest/states/test_stale.html
new file mode 100644
index 000000000..8f85a1995
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_stale.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Stale state testing</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="../states.js"></script>
+ <script type="application/javascript"
+ src="../events.js"></script>
+
+ <script type="application/javascript">
+ function addChild(aContainerID)
+ {
+ this.containerNode = getNode(aContainerID);
+ this.childNode = null;
+
+ this.eventSeq = [
+ new invokerChecker(EVENT_REORDER, this.containerNode)
+ ];
+
+ this.invoke = function addChild_invoke()
+ {
+ this.childNode = document.createElement("div");
+ this.containerNode.appendChild(this.childNode);
+ }
+
+ this.finalCheck = function addChild_finalCheck()
+ {
+ // no stale state should be set
+ testStates(this.childNode, 0, 0, 0, EXT_STATE_STALE);
+ }
+
+ this.getID = function addChild_getID()
+ {
+ return "add child for " + prettyName(aContainerID);
+ }
+ }
+
+ function removeChildChecker(aInvoker)
+ {
+ this.type = EVENT_HIDE;
+ this.__defineGetter__("target", function() { return aInvoker.child; });
+
+ this.check = function removeChildChecker_check()
+ {
+ // stale state should be set
+ testStates(aInvoker.child, 0, EXT_STATE_STALE);
+ }
+ }
+
+ function removeChild(aContainerID)
+ {
+ this.containerNode = getNode(aContainerID);
+ this.child = null;
+
+ this.eventSeq = [
+ new removeChildChecker(this)
+ ];
+
+ this.invoke = function removeChild_invoke()
+ {
+ var childNode = this.containerNode.firstChild;
+ this.child = getAccessible(childNode);
+
+ this.containerNode.removeChild(childNode);
+ }
+
+ this.getID = function removeChild_getID()
+ {
+ return "remove child from " + prettyName(aContainerID);
+ }
+ }
+
+ //gA11yEventDumpToConsole = true; //debugging
+
+ var gQueue = null;
+ function doTest()
+ {
+ gQueue = new eventQueue();
+
+ gQueue.push(new addChild("container"));
+ gQueue.push(new removeChild("container"));
+
+ gQueue.invoke(); // will call SimpleTest.finish()
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ </script>
+</head>
+
+<body role="">
+
+ <a target="_blank"
+ title="Expose stale state on accessibles unattached from tree"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=676267">Mozilla Bug 676267</a>
+
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <div id="container"></div>
+
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_tabs.xul b/accessible/tests/mochitest/states/test_tabs.xul
new file mode 100644
index 000000000..a596e178b
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_tabs.xul
@@ -0,0 +1,70 @@
+<?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 tabbox hierarchy tests">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/MochiKit/packed.js" />
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+ <script type="application/javascript"
+ src="../common.js" />
+ <script type="application/javascript"
+ src="../role.js" />
+ <script type="application/javascript"
+ src="../states.js" />
+
+ <script type="application/javascript">
+ <![CDATA[
+ ////////////////////////////////////////////////////////////////////////////
+ // Test
+
+ function doTest()
+ {
+ testStates("tab1", 0, EXT_STATE_PINNED);
+ testStates("tab2", 0, 0, 0, EXT_STATE_PINNED);
+ testStates("tab3", 0, 0, 0, EXT_STATE_PINNED);
+
+ SimpleTest.finish()
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ ]]>
+ </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=577727"
+ title="Make pinned tabs distinguishable from other tabs for accessibility">
+ Mozilla Bug 577727
+ </a><br/>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <vbox flex="1">
+ <tabbox>
+ <tabs id="tabs">
+ <tab id="tab1" label="tab1" pinned="true"/>
+ <tab id="tab2" label="tab2" pinned="false"/>
+ <tab id="tab3" label="tab3"/>
+ </tabs>
+ <tabpanels id="tabpanels">
+ <tabpanel/>
+ <tabpanel/>
+ </tabpanels>
+ </tabbox>
+ </vbox>
+ </hbox>
+
+</window>
+
diff --git a/accessible/tests/mochitest/states/test_textbox.xul b/accessible/tests/mochitest/states/test_textbox.xul
new file mode 100644
index 000000000..3daf2abe1
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_textbox.xul
@@ -0,0 +1,153 @@
+<?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 XUL textboxes states 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="../role.js" />
+ <script type="application/javascript"
+ src="../states.js" />
+
+ <script type="application/javascript">
+ <![CDATA[
+ function getInput(aID)
+ {
+ return getNode(aID).inputField;
+ }
+
+ function doTest()
+ {
+ //////////////////////////////////////////////////////////////////////////
+ // Ordinary textbox
+ testStates(getInput("textbox"),
+ STATE_FOCUSABLE,
+ EXT_STATE_EDITABLE,
+ STATE_PROTECTED | STATE_UNAVAILABLE,
+ EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+ "ordinary textbox");
+
+ //////////////////////////////////////////////////////////////////////////
+ // Password textbox
+ testStates(getInput("password"),
+ STATE_FOCUSABLE | STATE_PROTECTED,
+ EXT_STATE_EDITABLE,
+ STATE_UNAVAILABLE,
+ EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+ "password textbox");
+
+ //////////////////////////////////////////////////////////////////////////
+ // Textarea
+ testStates(getInput("textarea"),
+ STATE_FOCUSABLE,
+ EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE,
+ STATE_PROTECTED | STATE_UNAVAILABLE,
+ EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+ "multiline textbox");
+
+ //////////////////////////////////////////////////////////////////////////
+ // Readonly textbox
+ testStates(getInput("readonly_textbox"),
+ STATE_FOCUSABLE | STATE_READONLY,
+ EXT_STATE_EDITABLE,
+ STATE_PROTECTED | STATE_UNAVAILABLE,
+ EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+ "readonly textbox");
+
+ //////////////////////////////////////////////////////////////////////////
+ // Disabled textbox
+ testStates(getInput("disabled_textbox"),
+ STATE_UNAVAILABLE,
+ EXT_STATE_EDITABLE,
+ STATE_FOCUSABLE | STATE_PROTECTED,
+ EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+ "readonly textbox");
+
+ //////////////////////////////////////////////////////////////////////////
+ // Readonly textarea
+ testStates(getInput("readonly_textarea"),
+ STATE_FOCUSABLE | STATE_READONLY,
+ EXT_STATE_EDITABLE | EXT_STATE_MULTI_LINE,
+ STATE_PROTECTED | STATE_UNAVAILABLE,
+ EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+ "readonly multiline textbox");
+
+ //////////////////////////////////////////////////////////////////////////
+ // Disabled textarea
+ testStates(getInput("disabled_textarea"),
+ STATE_UNAVAILABLE,
+ EXT_STATE_EDITABLE| EXT_STATE_MULTI_LINE,
+ STATE_PROTECTED | STATE_FOCUSABLE,
+ EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+ "readonly multiline textbox");
+
+ //////////////////////////////////////////////////////////////////////////
+ // Search textbox without search button, searches as you type and filters
+ // a separate control.
+ testStates(getInput("searchbox"),
+ STATE_FOCUSABLE,
+ EXT_STATE_EDITABLE | EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+ STATE_PROTECTED | STATE_UNAVAILABLE,
+ 0,
+ "searchbox");
+
+ //////////////////////////////////////////////////////////////////////////
+ // Search textbox with search button, does not support autoCompletion.
+ testStates(getInput("searchfield"),
+ STATE_FOCUSABLE,
+ EXT_STATE_EDITABLE,
+ STATE_PROTECTED | STATE_UNAVAILABLE,
+ EXT_STATE_SUPPORTS_AUTOCOMPLETION,
+ "searchfield");
+
+ SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ ]]>
+ </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=442648">
+ Mozilla Bug 442648
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=648235"
+ title="XUL textbox can inherit more states from underlying HTML input">
+ Mozilla Bug 648235
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <vbox flex="1">
+ <textbox id="textbox"/>
+ <textbox id="password" type="password"/>
+ <textbox id="textarea" multiline="true" cols="80" rows="5"/>
+
+ <textbox id="readonly_textbox" readonly="true"/>
+ <textbox id="disabled_textbox" disabled="true"/>
+ <textbox id="readonly_textarea" multiline="true" readonly="true"
+ cols="80" rows="5"/>
+ <textbox id="disabled_textarea" multiline="true" disabled="true"
+ cols="80" rows="5"/>
+
+ <textbox id="searchbox" flex="1" type="search" results="historyTree"/>
+ <textbox id="searchfield" placeholder="Search all add-ons"
+ type="search" searchbutton="true"/>
+ </vbox>
+ </hbox>
+</window>
diff --git a/accessible/tests/mochitest/states/test_tree.xul b/accessible/tests/mochitest/states/test_tree.xul
new file mode 100644
index 000000000..878a8d25b
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_tree.xul
@@ -0,0 +1,152 @@
+<?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"?>
+<?xml-stylesheet href="../treeview.css"
+ type="text/css"?>
+
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Accessible XUL tree states 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="../role.js" />
+ <script type="application/javascript"
+ src="../states.js" />
+ <script type="application/javascript"
+ src="../events.js" />
+
+ <script type="application/javascript">
+ <![CDATA[
+ ////////////////////////////////////////////////////////////////////////////
+ // Test
+
+ /**
+ * Event queue invoker object to test accessible states for XUL tree
+ * accessible.
+ */
+ function statesChecker(aTreeID, aView)
+ {
+ this.DOMNode = getNode(aTreeID);
+
+ this.invoke = function statesChecker_invoke()
+ {
+ this.DOMNode.view = aView;
+ }
+
+ this.check = function statesChecker_check()
+ {
+ var tree = getAccessible(this.DOMNode);
+
+ // tree states
+ testStates(tree, STATE_READONLY);
+
+ if (this.DOMNode.getAttribute("seltype") != "single")
+ testStates(tree, STATE_MULTISELECTABLE);
+ else
+ testStates(tree, 0, 0, STATE_MULTISELECTABLE);
+
+ // tree item states
+ var expandedItem = tree.getChildAt(2);
+ testStates(expandedItem,
+ STATE_SELECTABLE | STATE_FOCUSABLE | STATE_EXPANDED);
+
+ var collapsedItem = tree.getChildAt(5);
+ testStates(collapsedItem,
+ STATE_SELECTABLE | STATE_FOCUSABLE | STATE_COLLAPSED);
+
+ // cells states if any
+ var cells = collapsedItem.children;
+ if (cells && cells.length) {
+ for (var idx = 0; idx < cells.length; idx++) {
+ var cell = cells.queryElementAt(idx, nsIAccessible);
+ testStates(cell, STATE_SELECTABLE);
+ }
+
+ var checkboxCell = cells.queryElementAt(3, nsIAccessible);
+ testStates(checkboxCell, STATE_CHECKABLE | STATE_CHECKED);
+ }
+ }
+
+ this.getID = function statesChecker_getID()
+ {
+ return "tree processor for " + prettyName(aTreeID);
+ }
+ }
+
+ gA11yEventDumpToConsole = true; // debug stuff
+
+ var gQueue = null;
+
+ function doTest()
+ {
+ gQueue = new eventQueue(EVENT_REORDER);
+ gQueue.push(new statesChecker("tree", new nsTreeTreeView()));
+ gQueue.push(new statesChecker("treesingle", new nsTreeTreeView()));
+ gQueue.push(new statesChecker("tabletree", new nsTreeTreeView()));
+
+ gQueue.invoke(); // Will call SimpleTest.finish();
+ }
+
+ if (MAC && (navigator.userAgent.indexOf("Mac OS X 10.6") != -1)) {
+ todo(false,
+ "Re-enable on Mac OS 10.6 after fixing bug 845095 - intermittent orange");
+ } else {
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ }
+ ]]>
+ </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">
+ Mozilla Bug 503727
+ </a><br/>
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <vbox flex="1">
+ <tree id="tree" flex="1">
+ <treecols>
+ <treecol id="col" flex="1" primary="true" label="column"/>
+ </treecols>
+ <treechildren/>
+ </tree>
+
+ <tree id="treesingle" flex="1" seltype="single">
+ <treecols>
+ <treecol id="col_single" flex="1" primary="true" label="column"/>
+ </treecols>
+ <treechildren/>
+ </tree>
+
+ <tree id="tabletree" flex="1" editable="true">
+ <treecols>
+ <treecol id="tabletree_col1" cycler="true" label="cycler"/>
+ <treecol id="tabletree_col2" flex="1" primary="true" label="column1"/>
+ <treecol id="tabletree_col3" flex="1" label="column2"/>
+ <treecol id="tabletree_col4" flex="1" label="checker"
+ type="checkbox" editable="true"/>
+ </treecols>
+ <treechildren/>
+ </tree>
+
+ <vbox id="debug"/>
+ </vbox>
+ </hbox>
+
+</window>
diff --git a/accessible/tests/mochitest/states/test_visibility.html b/accessible/tests/mochitest/states/test_visibility.html
new file mode 100644
index 000000000..a2e4a34e6
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_visibility.html
@@ -0,0 +1,175 @@
+<html>
+<head>
+ <title>visibility state testing</title>
+
+ <link rel="stylesheet" type="text/css"
+ href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/MochiKit/packed.js"></script>
+ <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="../states.js"></script>
+ <script type="application/javascript"
+ src="../events.js"></script>
+ <script type="application/javascript"
+ src="../browser.js"></script>
+
+ <script type="application/javascript">
+ ////////////////////////////////////////////////////////////////////////////
+ // Invokers
+
+ function loadURIInvoker(aURI, aFunc)
+ {
+ this.invoke = function loadURIInvoker_invoke()
+ {
+ tabBrowser().loadURI(aURI);
+ }
+
+ this.eventSeq = [
+ new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument)
+ ];
+
+ this.finalCheck = function loadURIInvoker_finalCheck()
+ {
+ aFunc.call();
+ }
+
+ this.getID = function loadURIInvoker_getID()
+ {
+ return "load uri " + aURI;
+ }
+ }
+
+ function addTabInvoker(aURL, aFunc)
+ {
+ this.eventSeq = [
+ new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
+ ];
+
+ this.invoke = function addTabInvoker_invoke()
+ {
+ tabBrowser().loadOneTab(aURL, null, "", null, false);
+ }
+
+ this.finalCheck = function addTabInvoker_finalCheck()
+ {
+ aFunc.call();
+ }
+
+ this.getID = function addTabInvoker_getID()
+ {
+ return "add tab: " + aURL;
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // Tests
+
+ function testBackgroundTab()
+ {
+ // Accessibles in background tab should have offscreen state and no
+ // invisible state.
+ var tabDoc = tabDocumentAt(0);
+ var input = getAccessible(tabDoc.getElementById("input"));
+ testStates(input, STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+ }
+
+ function testScrolledOff()
+ {
+ var tabDoc = tabDocumentAt(1);
+
+ // scrolled off
+ input = getAccessible(tabDoc.getElementById("input_scrolledoff"));
+ testStates(input, STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+
+ // scrolled off item (twice)
+ var lastLiNode = tabDoc.getElementById("li_last");
+ var lastLi = getAccessible(lastLiNode);
+ testStates(lastLi, STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+
+ // scroll into view the item
+ lastLiNode.scrollIntoView(true);
+ testStates(lastLi, 0, 0, STATE_OFFSCREEN | STATE_INVISIBLE);
+
+ // first item is scrolled off now (testcase for bug 768786)
+ var firstLi = getAccessible(tabDoc.getElementById("li_first"));
+ testStates(firstLi, STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+ }
+
+ var gInputDocURI = "data:text/html,<html><body>";
+ gInputDocURI += "<input id='input'></body></html>";
+
+ var gDocURI = "data:text/html,<html><body>";
+ gDocURI += "<div style='border:2px solid blue; width: 500px; height: 600px;'></div>";
+ gDocURI += "<input id='input_scrolledoff'>";
+ gDocURI += "<ul style='border:2px solid red; width: 100px; height: 50px; overflow: auto;'>";
+ gDocURI += " <li id='li_first'>item1</li><li>item2</li><li>item3</li>";
+ gDocURI += " <li>item4</li><li>item5</li><li id='li_last'>item6</li>";
+ gDocURI += "</ul>";
+ gDocURI += "</body></html>";
+
+ function doTests()
+ {
+ testStates("div", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
+ testStates("div_off", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+ testStates("div_transformed", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+ testStates("div_abschild", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
+
+ gQueue = new eventQueue();
+
+ gQueue.push(new addTabInvoker("about:blank", testBackgroundTab));
+ gQueue.push(new loadURIInvoker(gDocURI, testScrolledOff));
+
+ gQueue.onFinish = function() { closeBrowserWindow(); }
+ gQueue.invoke(); // Will call SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ openBrowserWindow(doTests, gInputDocURI, { width: 600, height: 600 });
+ </script>
+
+</head>
+
+<body>
+
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=591363"
+ title="(in)visible state is not always correct?">
+ Mozilla Bug 591363
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=768786"
+ title="Offscreen state is not exposed under certain circumstances">
+ Mozilla Bug 768786
+ </a>
+ <p id="display"></p>
+ <div id="content" style="display: none"></div>
+ <pre id="test">
+ </pre>
+
+ <div id="outer_div">
+
+ <!-- trivial cases -->
+ <div id="div">div</div>
+ <div id="div_off" style="position: absolute; left:-999px; top:-999px">
+ offscreen!
+ </div>
+ <div id="div_transformed" style="transform: translate(-999px, -999px);">
+ transformed!
+ </div>
+
+ <!-- edge case: no rect but has out of flow child -->
+ <div id="div_abschild">
+ <p style="position: absolute; left: 120px; top:120px;">absolute</p>
+ </div>
+
+ </div>
+</body>
+</html>
diff --git a/accessible/tests/mochitest/states/test_visibility.xul b/accessible/tests/mochitest/states/test_visibility.xul
new file mode 100644
index 000000000..8b2ac990c
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_visibility.xul
@@ -0,0 +1,152 @@
+<?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="XUL elements visibility states testing">
+
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
+
+ <script type="application/javascript"
+ src="../common.js" />
+ <script type="application/javascript"
+ src="../role.js" />
+ <script type="application/javascript"
+ src="../states.js" />
+ <script type="application/javascript"
+ src="../events.js" />
+
+ <script type="application/javascript">
+ <![CDATA[
+ function openMenu(aID, aSubID, aOffscreenSubID)
+ {
+ this.menuNode = getNode(aID);
+
+ this.eventSeq = [
+ new invokerChecker(EVENT_FOCUS, this.menuNode)
+ ];
+
+ this.invoke = function openMenu_invoke()
+ {
+ this.menuNode.open = true;
+ }
+
+ this.finalCheck = function openMenu_finalCheck()
+ {
+ testStates(aID, 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
+ testStates(aSubID, 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
+ if (aOffscreenSubID)
+ testStates(aOffscreenSubID, STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+ }
+
+ this.getID = function openMenu_invoke()
+ {
+ return "open menu '" + aID + "' and test states";
+ }
+ }
+
+ function closeMenu(aID, aSubID, aSub2ID)
+ {
+ this.menuNode = getNode(aID);
+
+ this.eventSeq = [
+ new invokerChecker(EVENT_FOCUS, document)
+ ];
+
+ this.invoke = function openMenu_invoke()
+ {
+ this.menuNode.open = false;
+ }
+
+ this.finalCheck = function openMenu_finalCheck()
+ {
+ testStates(aID, 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
+ testStates(aSubID, STATE_INVISIBLE, 0, STATE_OFFSCREEN);
+ testStates(aSub2ID, STATE_INVISIBLE, 0, STATE_OFFSCREEN);
+ }
+
+ this.getID = function openMenu_invoke()
+ {
+ return "open menu and test states";
+ }
+ }
+
+ var gQueue = null;
+ function doTest()
+ {
+ testStates("deck_pane2", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
+ testStates("tabs_pane1", 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
+ testStates("tabs_pane2", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+
+ gQueue = new eventQueue();
+ gQueue.push(new openMenu("mi_file1", "mi_file1.1"));
+ gQueue.push(new openMenu("mi_file1.2", "mi_file1.2.1", "mi_file1.2.4"));
+ gQueue.push(new closeMenu("mi_file1", "mi_file1.1", "mi_file1.2.1"));
+ gQueue.invoke(); // Will call SimpleTest.finish();
+ }
+
+ SimpleTest.waitForExplicitFinish();
+ addA11yLoadEvent(doTest);
+ ]]>
+ </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=810260"
+ title="xul:deck hidden pages shouldn't be offscreen">
+ Mozilla Bug 810260
+ </a>
+ <a target="_blank"
+ href="https://bugzilla.mozilla.org/show_bug.cgi?id=865591"
+ title="Visible menu item have offscreen state">
+ Mozilla Bug 865591
+ </a>
+
+ <p id="display"></p>
+ <div id="content" style="display: none">
+ </div>
+ <pre id="test">
+ </pre>
+ </body>
+
+ <vbox flex="1">
+
+ <deck selectedIndex="1">
+ <description value="This is the first page" id="deck_pane1"/>
+ <button label="This is the second page" id="deck_pane2"/>
+ </deck>
+
+ <tabbox>
+ <tabs>
+ <tab>tab1</tab>
+ <tab>tab2</tab>
+ </tabs>
+ <tabpanels>
+ <description value="This is the first page" id="tabs_pane1"/>
+ <button label="This is the second page" id="tabs_pane2"/>
+ </tabpanels>
+ </tabbox>
+
+ <menubar>
+ <menu label="File" id="mi_file1">
+ <menupopup>
+ <menuitem label="SubFile" id="mi_file1.1"/>
+ <menu label="SubFile2" id="mi_file1.2">
+ <menupopup style="max-height: 5em;">
+ <menuitem label="SubSubFile" id="mi_file1.2.1"/>
+ <menuitem label="SubSubFile2" id="mi_file1.2.2"/>
+ <menuitem label="SubSubFile3" id="mi_file1.2.3"/>
+ <menuitem label="SubSubFile4" id="mi_file1.2.4"/>
+ </menupopup>
+ </menu>
+ </menupopup>
+ </menu>
+ </menubar>
+ </vbox>
+ </hbox>
+
+</window>
+
diff --git a/accessible/tests/mochitest/states/z_frames.html b/accessible/tests/mochitest/states/z_frames.html
new file mode 100644
index 000000000..819adee63
--- /dev/null
+++ b/accessible/tests/mochitest/states/z_frames.html
@@ -0,0 +1,11 @@
+<html>
+<!--
+Auxilliary file used as frame source.
+-->
+<head>
+</head>
+<body>
+<p>Frame source body has no role</p>
+</body>
+</html>
+
diff --git a/accessible/tests/mochitest/states/z_frames_article.html b/accessible/tests/mochitest/states/z_frames_article.html
new file mode 100644
index 000000000..a7a69b4da
--- /dev/null
+++ b/accessible/tests/mochitest/states/z_frames_article.html
@@ -0,0 +1,11 @@
+<html>
+<!--
+Auxilliary file used as frame source.
+-->
+<head>
+</head>
+<body role="article">
+<p>Article</p>
+</body>
+</html>
+
diff --git a/accessible/tests/mochitest/states/z_frames_checkbox.html b/accessible/tests/mochitest/states/z_frames_checkbox.html
new file mode 100644
index 000000000..799764424
--- /dev/null
+++ b/accessible/tests/mochitest/states/z_frames_checkbox.html
@@ -0,0 +1,11 @@
+<html>
+<!--
+Auxilliary file used as frame source.
+-->
+<head>
+</head>
+<body role="checkbox">
+<p>Checkbox</p>
+</body>
+</html>
+
diff --git a/accessible/tests/mochitest/states/z_frames_textbox.html b/accessible/tests/mochitest/states/z_frames_textbox.html
new file mode 100644
index 000000000..0f4e1b9d6
--- /dev/null
+++ b/accessible/tests/mochitest/states/z_frames_textbox.html
@@ -0,0 +1,11 @@
+<html>
+<!--
+Auxilliary file used as frame source.
+-->
+<head>
+</head>
+<body role="textbox">
+<p>Texbox</p>
+</body>
+</html>
+
diff --git a/accessible/tests/mochitest/states/z_frames_update.html b/accessible/tests/mochitest/states/z_frames_update.html
new file mode 100644
index 000000000..90d756afe
--- /dev/null
+++ b/accessible/tests/mochitest/states/z_frames_update.html
@@ -0,0 +1,22 @@
+<html>
+<head>
+<script>
+function replaceBody()
+{
+ var accService = Components.classes["@mozilla.org/accessibilityService;1"].
+ getService(Components.interfaces.nsIAccessibilityService);
+ accService.getAccessibleFor(document);
+
+ var newBody = document.createElement("body");
+ newBody.setAttribute("contentEditable", "true");
+ newBody.textContent = "New Hello";
+ document.documentElement.replaceChild(newBody, document.body);
+ getComputedStyle(newBody, "").color;
+}
+</script>
+</head>
+<body onload="replaceBody();">
+OLD hello
+</body>
+</html>
+