mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-30 04:17:31 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
67
accessible/tests/mochitest/events/a11y.ini
Normal file
67
accessible/tests/mochitest/events/a11y.ini
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
docload_wnd.html
|
||||
focus.html
|
||||
scroll.html
|
||||
!/accessible/tests/mochitest/*.js
|
||||
!/accessible/tests/mochitest/letters.gif
|
||||
|
||||
[test_aria_alert.html]
|
||||
[test_aria_menu.html]
|
||||
[test_aria_objattr.html]
|
||||
[test_aria_owns.html]
|
||||
[test_aria_statechange.html]
|
||||
[test_attrs.html]
|
||||
[test_bug1322593.html]
|
||||
[test_bug1322593-2.html]
|
||||
[test_caretmove.html]
|
||||
[test_caretmove.xul]
|
||||
[test_coalescence.html]
|
||||
[test_contextmenu.html]
|
||||
[test_descrchange.html]
|
||||
[test_docload.html]
|
||||
[test_docload.xul]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[test_docload_aria.html]
|
||||
[test_dragndrop.html]
|
||||
[test_flush.html]
|
||||
[test_focus_aria_activedescendant.html]
|
||||
[test_focus_autocomplete.xul]
|
||||
# Disabled on Linux and Windows due to frequent failures - bug 695019, bug 890795
|
||||
skip-if = os == 'win' || os == 'linux'
|
||||
[test_focus_browserui.xul]
|
||||
[test_focus_canvas.html]
|
||||
[test_focus_contextmenu.xul]
|
||||
[test_focus_controls.html]
|
||||
[test_focus_dialog.html]
|
||||
[test_focus_doc.html]
|
||||
[test_focus_general.html]
|
||||
[test_focus_general.xul]
|
||||
[test_focus_listcontrols.xul]
|
||||
[test_focus_menu.xul]
|
||||
[test_focus_name.html]
|
||||
[test_focus_selects.html]
|
||||
[test_focus_tabbox.xul]
|
||||
[test_focus_tree.xul]
|
||||
[test_fromUserInput.html]
|
||||
[test_label.xul]
|
||||
[test_menu.xul]
|
||||
[test_mutation.html]
|
||||
[test_mutation.xhtml]
|
||||
[test_namechange.xul]
|
||||
[test_namechange.html]
|
||||
[test_scroll.xul]
|
||||
[test_scroll_caret.xul]
|
||||
[test_selection.html]
|
||||
skip-if = buildapp == 'mulet' || os == 'mac'
|
||||
[test_selection.xul]
|
||||
skip-if = os == 'mac'
|
||||
[test_selection_aria.html]
|
||||
[test_statechange.html]
|
||||
[test_text.html]
|
||||
[test_text_alg.html]
|
||||
[test_textattrchange.html]
|
||||
[test_textselchange.html]
|
||||
[test_tree.xul]
|
||||
[test_valuechange.html]
|
||||
skip-if = os == 'mac'
|
||||
39
accessible/tests/mochitest/events/docload_wnd.html
Normal file
39
accessible/tests/mochitest/events/docload_wnd.html
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Accessible events testing for document</title>
|
||||
<script>
|
||||
const STATE_BUSY = Components.interfaces.nsIAccessibleStates.STATE_BUSY;
|
||||
|
||||
var gService = null;
|
||||
function waitForDocLoad()
|
||||
{
|
||||
if (!gService) {
|
||||
gService = Components.classes["@mozilla.org/accessibilityService;1"].
|
||||
getService(Components.interfaces.nsIAccessibilityService);
|
||||
}
|
||||
|
||||
var accDoc = gService.getAccessibleFor(document);
|
||||
|
||||
var state = {};
|
||||
accDoc.getState(state, {});
|
||||
if (state.value & STATE_BUSY) {
|
||||
window.setTimeout(waitForDocLoad, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
hideIFrame();
|
||||
}
|
||||
|
||||
function hideIFrame()
|
||||
{
|
||||
var iframe = document.getElementById("iframe");
|
||||
gService.getAccessibleFor(iframe.contentDocument);
|
||||
iframe.style.display = 'none';
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="waitForDocLoad();">
|
||||
<iframe id="iframe"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
10
accessible/tests/mochitest/events/focus.html
Normal file
10
accessible/tests/mochitest/events/focus.html
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>editable document</title>
|
||||
</head>
|
||||
|
||||
<body contentEditable="true">
|
||||
editable document
|
||||
</body>
|
||||
</html>
|
||||
181
accessible/tests/mochitest/events/scroll.html
Normal file
181
accessible/tests/mochitest/events/scroll.html
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>nsIAccessible actions testing for anchors</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
</p>
|
||||
<a name="link1">link1</a>
|
||||
|
||||
<p style="color: blue">
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
</p>
|
||||
|
||||
<h1 id="heading_1">heading 1</h1>
|
||||
<p style="color: blue">
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
text text text text text text text text text text text text text text <br>
|
||||
</p>
|
||||
</body>
|
||||
<html>
|
||||
92
accessible/tests/mochitest/events/test_aria_alert.html
Normal file
92
accessible/tests/mochitest/events/test_aria_alert.html
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>ARIA alert event 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 showAlert(aID)
|
||||
{
|
||||
this.DOMNode = document.createElement("div");
|
||||
|
||||
this.invoke = function showAlert_invoke()
|
||||
{
|
||||
this.DOMNode.setAttribute("role", "alert");
|
||||
this.DOMNode.setAttribute("id", aID);
|
||||
var text = document.createTextNode("alert");
|
||||
this.DOMNode.appendChild(text);
|
||||
document.body.appendChild(this.DOMNode);
|
||||
};
|
||||
|
||||
this.getID = function showAlert_getID()
|
||||
{
|
||||
return "Show ARIA alert " + aID;
|
||||
};
|
||||
}
|
||||
|
||||
function changeAlert(aID)
|
||||
{
|
||||
this.__defineGetter__("DOMNode", function() { return getNode(aID) });
|
||||
|
||||
this.invoke = function changeAlert_invoke()
|
||||
{
|
||||
this.DOMNode.textContent = "new alert";
|
||||
}
|
||||
|
||||
this.getID = function showAlert_getID()
|
||||
{
|
||||
return "Change ARIA alert " + aID;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debuging
|
||||
//enableLogging("tree,events,verbose");
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue(nsIAccessibleEvent.EVENT_ALERT);
|
||||
|
||||
gQueue.push(new showAlert("alert"));
|
||||
gQueue.push(new changeAlert("alert"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=591199"
|
||||
title="mochitest for bug 334386: fire alert event when ARIA alert is shown or new its children are inserted">
|
||||
Mozilla Bug 591199
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
285
accessible/tests/mochitest/events/test_aria_menu.html
Normal file
285
accessible/tests/mochitest/events/test_aria_menu.html
Normal file
|
|
@ -0,0 +1,285 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>ARIA menu events 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">
|
||||
const kViaDisplayStyle = 0;
|
||||
const kViaVisibilityStyle = 1;
|
||||
|
||||
function focusMenu(aMenuBarID, aMenuID, aActiveMenuBarID)
|
||||
{
|
||||
this.eventSeq = [];
|
||||
|
||||
if (aActiveMenuBarID) {
|
||||
this.eventSeq.push(new invokerChecker(EVENT_MENU_END,
|
||||
getNode(aActiveMenuBarID)));
|
||||
}
|
||||
|
||||
this.eventSeq.push(new invokerChecker(EVENT_MENU_START, getNode(aMenuBarID)));
|
||||
this.eventSeq.push(new invokerChecker(EVENT_FOCUS, getNode(aMenuID)));
|
||||
|
||||
this.invoke = function focusMenu_invoke()
|
||||
{
|
||||
getNode(aMenuID).focus();
|
||||
}
|
||||
|
||||
this.getID = function focusMenu_getID()
|
||||
{
|
||||
return "focus menu '" + aMenuID + "'";
|
||||
}
|
||||
}
|
||||
|
||||
function showMenu(aMenuID, aParentMenuID, aHow)
|
||||
{
|
||||
this.menuNode = getNode(aMenuID);
|
||||
|
||||
// Because of aria-owns processing we may have menupopup start fired before
|
||||
// related show event.
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, this.menuNode),
|
||||
new invokerChecker(EVENT_REORDER, getNode(aParentMenuID)),
|
||||
new invokerChecker(EVENT_MENUPOPUP_START, this.menuNode)
|
||||
];
|
||||
|
||||
this.invoke = function showMenu_invoke()
|
||||
{
|
||||
if (aHow == kViaDisplayStyle)
|
||||
this.menuNode.style.display = "block";
|
||||
else
|
||||
this.menuNode.style.visibility = "visible";
|
||||
};
|
||||
|
||||
this.getID = function showMenu_getID()
|
||||
{
|
||||
return "Show ARIA menu '" + aMenuID + "' by " +
|
||||
(aHow == kViaDisplayStyle ? "display" : "visibility") +
|
||||
" style tricks";
|
||||
};
|
||||
}
|
||||
|
||||
function closeMenu(aMenuID, aParentMenuID, aHow)
|
||||
{
|
||||
this.menuNode = getNode(aMenuID);
|
||||
this.menu = null;
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getMenu, this),
|
||||
new invokerChecker(EVENT_MENUPOPUP_END, getMenu, this),
|
||||
new invokerChecker(EVENT_REORDER, getNode(aParentMenuID))
|
||||
];
|
||||
|
||||
this.invoke = function closeMenu_invoke()
|
||||
{
|
||||
// Store menu accessible reference while menu is still open.
|
||||
this.menu = getAccessible(this.menuNode);
|
||||
|
||||
// Hide menu.
|
||||
if (aHow == kViaDisplayStyle)
|
||||
this.menuNode.style.display = "none";
|
||||
else
|
||||
this.menuNode.style.visibility = "hidden";
|
||||
}
|
||||
|
||||
this.getID = function closeMenu_getID()
|
||||
{
|
||||
return "Close ARIA menu " + aMenuID + " by " +
|
||||
(aHow == kViaDisplayStyle ? "display" : "visibility") +
|
||||
" style tricks";
|
||||
}
|
||||
|
||||
function getMenu(aThisObj)
|
||||
{
|
||||
return aThisObj.menu;
|
||||
}
|
||||
}
|
||||
|
||||
function focusInsideMenu(aMenuID, aMenuBarID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, getNode(aMenuID))
|
||||
];
|
||||
|
||||
this.unexpectedEventSeq = [
|
||||
new invokerChecker(EVENT_MENU_END, getNode(aMenuBarID))
|
||||
];
|
||||
|
||||
this.invoke = function focusInsideMenu_invoke()
|
||||
{
|
||||
getNode(aMenuID).focus();
|
||||
}
|
||||
|
||||
this.getID = function focusInsideMenu_getID()
|
||||
{
|
||||
return "focus menu '" + aMenuID + "'";
|
||||
}
|
||||
}
|
||||
|
||||
function blurMenu(aMenuBarID)
|
||||
{
|
||||
var eventSeq = [
|
||||
new invokerChecker(EVENT_MENU_END, getNode(aMenuBarID)),
|
||||
new invokerChecker(EVENT_FOCUS, getNode("outsidemenu"))
|
||||
];
|
||||
|
||||
this.__proto__ = new synthClick("outsidemenu", eventSeq);
|
||||
|
||||
this.getID = function blurMenu_getID()
|
||||
{
|
||||
return "blur menu";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debuging
|
||||
//enableLogging("tree,events,verbose");
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new focusMenu("menubar2", "menu-help"));
|
||||
gQueue.push(new focusMenu("menubar", "menu-file", "menubar2"));
|
||||
gQueue.push(new showMenu("menupopup-file", "menu-file", kViaDisplayStyle));
|
||||
gQueue.push(new closeMenu("menupopup-file", "menu-file", kViaDisplayStyle));
|
||||
gQueue.push(new showMenu("menupopup-edit", "menu-edit", kViaVisibilityStyle));
|
||||
gQueue.push(new closeMenu("menupopup-edit", "menu-edit", kViaVisibilityStyle));
|
||||
gQueue.push(new focusInsideMenu("menu-edit", "menubar"));
|
||||
gQueue.push(new blurMenu("menubar"));
|
||||
|
||||
gQueue.push(new focusMenu("menubar3", "mb3-mi-outside"));
|
||||
gQueue.push(new showMenu("mb4-menu", document, kViaDisplayStyle));
|
||||
gQueue.push(new focusMenu("menubar4", "mb4-item1"));
|
||||
gQueue.push(new focusMenu("menubar5", "mb5-mi"));
|
||||
|
||||
gQueue.push(new synthFocus("mi6"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=606207"
|
||||
title="Dojo dropdown buttons are broken">
|
||||
Bug 606207
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=614829"
|
||||
title="Menupopup end event isn't fired for ARIA menus">
|
||||
Bug 614829
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=615189"
|
||||
title="Clean up FireAccessibleFocusEvent">
|
||||
Bug 615189
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=673958"
|
||||
title="Rework accessible focus handling">
|
||||
Bug 673958
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=933322"
|
||||
title="menustart/end events are missing when aria-owns makes a menu hierarchy">
|
||||
Bug 933322
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=934460"
|
||||
title="menustart/end events may be missed when top level menuitem is focused">
|
||||
Bug 934460
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=970005"
|
||||
title="infinite long loop in a11y:FocusManager::ProcessFocusEvent">
|
||||
Bug 970005
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="menubar" role="menubar">
|
||||
<div id="menu-file" role="menuitem" tabindex="0">
|
||||
File
|
||||
<div id="menupopup-file" role="menu" style="display: none;">
|
||||
<div id="menuitem-newtab" role="menuitem" tabindex="0">New Tab</div>
|
||||
<div id="menuitem-newwindow" role="menuitem" tabindex="0">New Window</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="menu-edit" role="menuitem" tabindex="0">
|
||||
Edit
|
||||
<div id="menupopup-edit" role="menu" style="visibility: hidden;">
|
||||
<div id="menuitem-undo" role="menuitem" tabindex="0">Undo</div>
|
||||
<div id="menuitem-redo" role="menuitem" tabindex="0">Redo</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="menubar2" role="menubar">
|
||||
<div id="menu-help" role="menuitem" tabindex="0">
|
||||
Help
|
||||
<div id="menupopup-help" role="menu" style="display: none;">
|
||||
<div id="menuitem-about" role="menuitem" tabindex="0">About</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div tabindex="0" id="outsidemenu">outsidemenu</div>
|
||||
|
||||
<!-- aria-owns relations -->
|
||||
<div id="menubar3" role="menubar" aria-owns="mb3-mi-outside"></div>
|
||||
<div id="mb3-mi-outside" role="menuitem" tabindex="0">Outside</div>
|
||||
|
||||
<div id="menubar4" role="menubar">
|
||||
<div id="mb4_topitem" role="menuitem" aria-haspopup="true"
|
||||
aria-owns="mb4-menu">Item</div>
|
||||
</div>
|
||||
<div id="mb4-menu" role="menu" style="display:none;">
|
||||
<div role="menuitem" id="mb4-item1" tabindex="0">Item 1.1</div>
|
||||
<div role="menuitem" tabindex="0">Item 1.2</div>
|
||||
</div>
|
||||
|
||||
<!-- focus top-level menu item having haspopup -->
|
||||
<div id="menubar5" role="menubar">
|
||||
<div role="menuitem" aria-haspopup="true" id="mb5-mi" tabindex="0">
|
||||
Item
|
||||
<div role="menu" style="display:none;">
|
||||
<div role="menuitem" tabindex="0">Item 1.1</div>
|
||||
<div role="menuitem" tabindex="0">Item 1.2</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- other aria-owns relations -->
|
||||
<div id="mi6" tabindex="0" role="menuitem">aria-owned item</div>
|
||||
<div aria-owns="mi6">Obla</div>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
118
accessible/tests/mochitest/events/test_aria_objattr.html
Normal file
118
accessible/tests/mochitest/events/test_aria_objattr.html
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible ARIA object attribute changes</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="../attributes.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
function updateAttribute(aID, aAttr, aValue)
|
||||
{
|
||||
this.node = getNode(aID);
|
||||
this.accessible = getAccessible(this.node);
|
||||
|
||||
this.eventSeq = [
|
||||
new objAttrChangedChecker(aID, aAttr),
|
||||
];
|
||||
|
||||
this.invoke = function updateAttribute_invoke()
|
||||
{
|
||||
this.node.setAttribute(aAttr, aValue);
|
||||
};
|
||||
|
||||
this.getID = function updateAttribute_getID()
|
||||
{
|
||||
return aAttr + " for " + aID + " " + aValue;
|
||||
};
|
||||
}
|
||||
|
||||
function updateARIAHidden(aID, aIsDefined, aChildId)
|
||||
{
|
||||
this.__proto__ = new updateAttribute(aID, "aria-hidden",
|
||||
aIsDefined ? "true" : "false");
|
||||
|
||||
this.finalCheck = function updateARIAHidden()
|
||||
{
|
||||
if (aIsDefined) {
|
||||
testAttrs(aID, {"hidden" : "true"}, true);
|
||||
testAttrs(aChildId, {"hidden" : "true"}, true);
|
||||
} else {
|
||||
testAbsentAttrs(aID, { "hidden": "true"});
|
||||
testAbsentAttrs(aChildId, { "hidden": "true"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Debug stuff.
|
||||
// gA11yEventDumpID = "eventdump";
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new updateARIAHidden("hideable", true, "hideable_child"));
|
||||
gQueue.push(new updateARIAHidden("hideable", false, "hideable_child"));
|
||||
|
||||
gQueue.push(new updateAttribute("sortable", "aria-sort", "ascending"));
|
||||
|
||||
// For experimental ARIA extensions
|
||||
gQueue.push(new updateAttribute("custom", "aria-blah", "true"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=581096"
|
||||
title="Add support for aria-hidden">
|
||||
Mozilla Bug 581096
|
||||
</a>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=640707"
|
||||
title="Add event support for aria-sort">
|
||||
Mozilla Bug 640707
|
||||
</a>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=640707"
|
||||
title="Expand support for aria attribute change events">
|
||||
Mozilla Bug 563862
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<div id="hideable"><div id="hideable_child">Hi</div><div>there</div></div>
|
||||
|
||||
<div id="sortable" role="columnheader" aria-sort="none">aria-sort</div>
|
||||
|
||||
<div id="custom" role="custom" aria-blah="false">Fat free cheese</div>
|
||||
</body>
|
||||
</html>
|
||||
129
accessible/tests/mochitest/events/test_aria_owns.html
Normal file
129
accessible/tests/mochitest/events/test_aria_owns.html
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Aria-owns targets shouldn't be on invalidation list so shouldn't have
|
||||
show/hide events</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="../states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests.
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
//enableLogging("tree,eventTree,verbose");
|
||||
|
||||
/**
|
||||
* Aria-owns target shouldn't have a show event.
|
||||
* Markup:
|
||||
* <div id="t1_fc" aria-owns="t1_owns"></div>
|
||||
* <span id="t1_owns"></div>
|
||||
*/
|
||||
function testAriaOwns()
|
||||
{
|
||||
this.parent = getNode("t1");
|
||||
this.fc = document.createElement("div");
|
||||
this.fc.setAttribute("id", "t1_fc");
|
||||
this.owns = document.createElement("span");
|
||||
this.owns.setAttribute("id", "t1_owns");
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, this.fc),
|
||||
new unexpectedInvokerChecker(EVENT_SHOW, this.owns)
|
||||
];
|
||||
|
||||
this.invoke = function testAriaOwns_invoke()
|
||||
{
|
||||
getNode("t1").appendChild(this.fc);
|
||||
getNode("t1").appendChild(this.owns);
|
||||
getNode("t1_fc").setAttribute("aria-owns", "t1_owns");
|
||||
};
|
||||
|
||||
this.getID = function testAriaOwns_getID() {
|
||||
return "Aria-owns target shouldn't have show event";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Target of both aria-owns and other aria attribute like aria-labelledby
|
||||
* shouldn't have a show event.
|
||||
* Markup:
|
||||
* <div id="t2_fc" aria-owns="t1_owns"></div>
|
||||
* <div id="t2_sc" aria-labelledby="t2_owns"></div>
|
||||
* <span id="t2_owns"></div>
|
||||
*/
|
||||
function testAriaOwnsAndLabelledBy()
|
||||
{
|
||||
this.parent = getNode("t2");
|
||||
this.fc = document.createElement("div");
|
||||
this.fc.setAttribute("id", "t2_fc");
|
||||
this.sc = document.createElement("div");
|
||||
this.sc.setAttribute("id", "t2_sc");
|
||||
this.owns = document.createElement("span");
|
||||
this.owns.setAttribute("id", "t2_owns");
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, this.fc),
|
||||
new invokerChecker(EVENT_SHOW, this.sc),
|
||||
new unexpectedInvokerChecker(EVENT_SHOW, this.owns)
|
||||
];
|
||||
|
||||
this.invoke = function testAriaOwns_invoke()
|
||||
{
|
||||
getNode("t2").appendChild(this.fc);
|
||||
getNode("t2").appendChild(this.sc);
|
||||
getNode("t2").appendChild(this.owns);
|
||||
getNode("t2_fc").setAttribute("aria-owns", "t2_owns");
|
||||
getNode("t2_sc").setAttribute("aria-labelledby", "t2_owns");
|
||||
};
|
||||
|
||||
this.getID = function testAriaOwns_getID() {
|
||||
return "Aria-owns and aria-labelledby target shouldn't have show event";
|
||||
};
|
||||
}
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
gQueue.push(new testAriaOwns());
|
||||
gQueue.push(new testAriaOwnsAndLabelledBy());
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1296420"
|
||||
title="Aria-owns targets shouldn't be on invalidation list so shouldn't
|
||||
have show/hide events">
|
||||
Mozilla Bug 1296420
|
||||
</a><br>
|
||||
|
||||
<div id="testContainer">
|
||||
<div id="t1"></div>
|
||||
|
||||
<div id="t2"></div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
208
accessible/tests/mochitest/events/test_aria_statechange.html
Normal file
208
accessible/tests/mochitest/events/test_aria_statechange.html
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>ARIA state change event 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">
|
||||
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
|
||||
//gA11yEventDumpID = "eventdump"; // debugging
|
||||
//gA11yEventDumpToConsole = true; // debugging
|
||||
|
||||
function expandNode(aID, aIsExpanded)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new expandedStateChecker(aIsExpanded, this.DOMNode)
|
||||
];
|
||||
|
||||
this.invoke = function expandNode_invoke()
|
||||
{
|
||||
this.DOMNode.setAttribute("aria-expanded",
|
||||
(aIsExpanded ? "true" : "false"));
|
||||
};
|
||||
|
||||
this.getID = function expandNode_getID()
|
||||
{
|
||||
return prettyName(aID) + " aria-expanded changed to '" + aIsExpanded + "'";
|
||||
};
|
||||
}
|
||||
|
||||
function busyify(aID, aIsBusy)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new stateChangeChecker(STATE_BUSY, kOrdinalState, aIsBusy, this.DOMNode)
|
||||
];
|
||||
|
||||
this.invoke = function busyify_invoke()
|
||||
{
|
||||
this.DOMNode.setAttribute("aria-busy", (aIsBusy ? "true" : "false"));
|
||||
};
|
||||
|
||||
this.getID = function busyify_getID()
|
||||
{
|
||||
return prettyName(aID) + " aria-busy changed to '" + aIsBusy + "'";
|
||||
};
|
||||
}
|
||||
|
||||
function setAttrOfMixedType(aID, aAttr, aState, aValue)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new stateChangeChecker(aState, kOrdinalState,
|
||||
aValue == "true", this.DOMNode)
|
||||
];
|
||||
|
||||
if (hasState(aID, STATE_MIXED) || aValue == "mixed") {
|
||||
this.eventSeq.push(
|
||||
new stateChangeChecker(STATE_MIXED, kOrdinalState,
|
||||
aValue == "mixed", this.DOMNode)
|
||||
);
|
||||
}
|
||||
|
||||
this.invoke = function setAttrOfMixedType_invoke()
|
||||
{
|
||||
this.DOMNode.setAttribute(aAttr, aValue);
|
||||
};
|
||||
|
||||
this.getID = function setAttrOfMixedType_getID()
|
||||
{
|
||||
return prettyName(aID) + " " + aAttr + " changed to '" + aValue + "'";
|
||||
};
|
||||
}
|
||||
|
||||
function setPressed(aID, aValue)
|
||||
{
|
||||
this.__proto__ =
|
||||
new setAttrOfMixedType(aID, "aria-pressed", STATE_PRESSED, aValue);
|
||||
}
|
||||
|
||||
function setChecked(aID, aValue)
|
||||
{
|
||||
this.__proto__ =
|
||||
new setAttrOfMixedType(aID, "aria-checked", STATE_CHECKED, aValue);
|
||||
}
|
||||
|
||||
function buildQueueForAttr(aList, aQueue, aID, aInvokerFunc)
|
||||
{
|
||||
for (var i = 0; i < aList.length; i++) {
|
||||
for (var j = i + 1; j < aList.length; j++) {
|
||||
// XXX: changes from/to "undefined"/"" shouldn't fire state change
|
||||
// events, bug 472142.
|
||||
aQueue.push(new aInvokerFunc(aID, aList[i]));
|
||||
aQueue.push(new aInvokerFunc(aID, aList[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildQueueForAttrOfMixedType(aQueue, aID, aInvokerFunc)
|
||||
{
|
||||
var list = [ "", "undefined", "false", "true", "mixed" ];
|
||||
buildQueueForAttr(list, aQueue, aID, aInvokerFunc);
|
||||
}
|
||||
|
||||
function buildQueueForAttrOfBoolType(aQueue, aID, aInvokerFunc)
|
||||
{
|
||||
var list = [ "", "undefined", "false", "true" ];
|
||||
buildQueueForAttr(list, aQueue, aID, aInvokerFunc);
|
||||
}
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new expandNode("section", true));
|
||||
gQueue.push(new expandNode("section", false));
|
||||
gQueue.push(new expandNode("div", true));
|
||||
gQueue.push(new expandNode("div", false));
|
||||
|
||||
gQueue.push(new busyify("aria_doc", true));
|
||||
gQueue.push(new busyify("aria_doc", false));
|
||||
|
||||
buildQueueForAttrOfMixedType(gQueue, "pressable", setPressed);
|
||||
buildQueueForAttrOfMixedType(gQueue, "pressable_native", setPressed);
|
||||
buildQueueForAttrOfMixedType(gQueue, "checkable", setChecked);
|
||||
buildQueueForAttrOfBoolType(gQueue, "checkableBool", setChecked);
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=551684"
|
||||
title="No statechange event for aria-expanded on native HTML elements, is fired on ARIA widgets">
|
||||
Mozilla Bug 551684
|
||||
</a><br>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=648133"
|
||||
title="fire state change event for aria-busy">
|
||||
Mozilla Bug 648133
|
||||
</a><br>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=467143"
|
||||
title="mixed state change event is fired for focused accessible only">
|
||||
Mozilla Bug 467143
|
||||
</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="eventdump"></div>
|
||||
|
||||
<!-- aria-expanded -->
|
||||
<div id="section" role="section" aria-expanded="false">expandable section</div>
|
||||
<div id="div" aria-expanded="false">expandable native div</div>
|
||||
|
||||
<!-- aria-busy -->
|
||||
<div id="aria_doc" role="document" tabindex="0">A document</div>
|
||||
|
||||
<!-- aria-pressed -->
|
||||
<div id="pressable" role="button"></div>
|
||||
<button id="pressable_native"></button>
|
||||
|
||||
<!-- aria-checked -->
|
||||
<div id="checkable" role="checkbox"></div>
|
||||
<div id="checkableBool" role="switch"></div>
|
||||
</body>
|
||||
</html>
|
||||
90
accessible/tests/mochitest/events/test_attrs.html
Normal file
90
accessible/tests/mochitest/events/test_attrs.html
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Event object attributes 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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../attributes.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
/**
|
||||
* Test "event-from-input" object attribute.
|
||||
*/
|
||||
function eventFromInputChecker(aEventType, aID, aValue, aNoTargetID)
|
||||
{
|
||||
this.type = aEventType;
|
||||
this.target = getAccessible(aID);
|
||||
|
||||
this.noTarget = getNode(aNoTargetID);
|
||||
|
||||
this.check = function checker_check(aEvent)
|
||||
{
|
||||
testAttrs(aEvent.accessible, { "event-from-input": aValue }, true);
|
||||
|
||||
var accessible = getAccessible(this.noTarget);
|
||||
testAbsentAttrs(accessible, { "event-from-input": "" });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
|
||||
// gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
var id = "textbox", noTargetId = "textarea";
|
||||
var checker =
|
||||
new eventFromInputChecker(EVENT_FOCUS, id, "false", noTargetId);
|
||||
gQueue.push(new synthFocus(id, checker));
|
||||
|
||||
if (!MAC) { // Mac failure is bug 541093
|
||||
var checker =
|
||||
new eventFromInputChecker(EVENT_TEXT_CARET_MOVED, id, "true", noTargetId);
|
||||
gQueue.push(new synthHomeKey(id, checker));
|
||||
}
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=540285"
|
||||
title="Event object attributes testing">
|
||||
Mozilla Bug 540285
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<input id="textbox" value="hello">
|
||||
<textarea id="textarea"></textarea>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
83
accessible/tests/mochitest/events/test_bug1322593-2.html
Normal file
83
accessible/tests/mochitest/events/test_bug1322593-2.html
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible mutation events 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="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function changeMultipleElements()
|
||||
{
|
||||
this.node1 = getNode("span1");
|
||||
this.node2 = getNode("span2");
|
||||
|
||||
this.eventSeq = [
|
||||
new textChangeChecker("container", 0, 5, "hello", false, undefined, true),
|
||||
new textChangeChecker("container", 6, 11, "world", false, undefined, true),
|
||||
new orderChecker(),
|
||||
new textChangeChecker("container", 0, 1, "a", true, undefined, true),
|
||||
new textChangeChecker("container", 7, 8, "b", true, undefined, true)
|
||||
];
|
||||
|
||||
this.invoke = function changeMultipleElements_invoke()
|
||||
{
|
||||
this.node1.textContent = "a";
|
||||
this.node2.textContent = "b";
|
||||
}
|
||||
|
||||
this.getID = function changeMultipleElements_invoke_getID()
|
||||
{
|
||||
return "Change the text content of multiple sibling divs";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
// gA11yEventDumpToConsole = true; // debugging
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new changeMultipleElements());
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322593"
|
||||
title="missing text change events when multiple elements updated at once">
|
||||
Mozilla Bug 1322593
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="container">
|
||||
<span id="span1">hello</span>
|
||||
<span>your</span>
|
||||
<span id="span2">world</span>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
80
accessible/tests/mochitest/events/test_bug1322593.html
Normal file
80
accessible/tests/mochitest/events/test_bug1322593.html
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible mutation events 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="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function changeMultipleElements()
|
||||
{
|
||||
this.node1 = getNode("div1");
|
||||
this.node2 = getNode("div2");
|
||||
|
||||
this.eventSeq = [
|
||||
new textChangeChecker("div1", 0, 5, "hello", false, undefined, true),
|
||||
new textChangeChecker("div2", 0, 5, "world", false, undefined, true),
|
||||
new orderChecker(),
|
||||
new textChangeChecker("div1", 0, 1, "a", true, undefined, true),
|
||||
new textChangeChecker("div2", 0, 1, "b", true, undefined, true)
|
||||
];
|
||||
|
||||
this.invoke = function changeMultipleElements_invoke()
|
||||
{
|
||||
this.node1.textContent = "a";
|
||||
this.node2.textContent = "b";
|
||||
}
|
||||
|
||||
this.getID = function changeMultipleElements_invoke_getID()
|
||||
{
|
||||
return "Change the text content of multiple sibling divs";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
// gA11yEventDumpToConsole = true; // debugging
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new changeMultipleElements());
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1322593"
|
||||
title="missing text change events when multiple elements updated at once">
|
||||
Mozilla Bug 1322593
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="div1">hello</div>
|
||||
<div id="div2">world</div>
|
||||
</body>
|
||||
</html>
|
||||
140
accessible/tests/mochitest/events/test_caretmove.html
Normal file
140
accessible/tests/mochitest/events/test_caretmove.html
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible caret move events 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="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
/**
|
||||
* Click checker.
|
||||
*/
|
||||
function clickChecker(aCaretOffset, aID, aExtraNodeOrID, aExtraCaretOffset)
|
||||
{
|
||||
this.__proto__ = new caretMoveChecker(aCaretOffset, aID);
|
||||
|
||||
this.extraNode = getNode(aExtraNodeOrID);
|
||||
|
||||
this.check = function clickChecker_check(aEvent)
|
||||
{
|
||||
this.__proto__.check(aEvent);
|
||||
|
||||
if (this.extraNode) {
|
||||
var acc = getAccessible(this.extraNode, [nsIAccessibleText]);
|
||||
is(acc.caretOffset, aExtraCaretOffset,
|
||||
"Wrong caret offset for " + aExtraNodeOrID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
|
||||
// gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
// test caret move events and caret offsets
|
||||
gQueue = new eventQueue();
|
||||
|
||||
var id = "textbox";
|
||||
gQueue.push(new synthFocus(id, new caretMoveChecker(5, id)));
|
||||
gQueue.push(new synthSelectAll(id, new caretMoveChecker(5, id)));
|
||||
gQueue.push(new synthClick(id, new caretMoveChecker(0, id)));
|
||||
gQueue.push(new synthRightKey(id, new caretMoveChecker(1, id)));
|
||||
|
||||
id = "textarea";
|
||||
gQueue.push(new synthClick(id, new caretMoveChecker(0, id)));
|
||||
gQueue.push(new synthRightKey(id, new caretMoveChecker(1, id)));
|
||||
gQueue.push(new synthDownKey(id, new caretMoveChecker(12, id)));
|
||||
|
||||
id = "textarea_wrapped";
|
||||
gQueue.push(new setCaretOffset(id, 4, id));
|
||||
gQueue.push(new synthLeftKey(id, new caretMoveChecker(4, id)));
|
||||
|
||||
id = "p";
|
||||
gQueue.push(new synthClick(id, new caretMoveChecker(0, id)));
|
||||
gQueue.push(new synthRightKey(id, new caretMoveChecker(1, id)));
|
||||
gQueue.push(new synthDownKey(id, new caretMoveChecker(6, id)));
|
||||
|
||||
id = "p1_in_div";
|
||||
gQueue.push(new synthClick(id, new clickChecker(0, id, "p2_in_div", -1)));
|
||||
|
||||
id = "p";
|
||||
gQueue.push(new synthShiftTab(id, new caretMoveChecker(0, id)));
|
||||
id = "textarea";
|
||||
gQueue.push(new synthShiftTab(id, new caretMoveChecker(12, id)));
|
||||
id = "p";
|
||||
gQueue.push(new synthTab(id, new caretMoveChecker(0, id)));
|
||||
|
||||
// Set caret after a child of span element, i.e. after 'text' text.
|
||||
gQueue.push(new moveCaretToDOMPoint("test1", getNode("test1_span"), 1,
|
||||
4, "test1"));
|
||||
gQueue.push(new moveCaretToDOMPoint("test2", getNode("test2_span"), 1,
|
||||
4, "test2"));
|
||||
|
||||
// empty text element
|
||||
gQueue.push(new moveCaretToDOMPoint("test3", getNode("test3"), 0,
|
||||
0, "test3"));
|
||||
gQueue.push(new moveCaretToDOMPoint("test4", getNode("test4_span"), 0,
|
||||
0, "test4"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=454377"
|
||||
title="Accessible caret move events testing">
|
||||
Bug 454377
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=567571"
|
||||
title="caret-moved events missing at the end of a wrapped line of text">
|
||||
Bug 567571
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=824901"
|
||||
title="HyperTextAccessible::DOMPointToHypertextOffset fails for node and offset equal to node child count">
|
||||
Bug 824901
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<input id="textbox" value="hello"/>
|
||||
<textarea id="textarea">text<br>text</textarea>
|
||||
<p id="p" contentEditable="true"><span>text</span><br/>text</p>
|
||||
<div id="div" contentEditable="true"><p id="p1_in_div">text</p><p id="p2_in_div">text</p></div>
|
||||
|
||||
<p contentEditable="true" id="test1"><span id="test1_span">text</span>ohoho</p>
|
||||
<p contentEditable="true" id="test2"><span><span id="test2_span">text</span></span>ohoho</p>
|
||||
<p contentEditable="true" id="test3"></p>
|
||||
<p contentEditable="true" id="test4"><span id="test4_span"></span></p>
|
||||
|
||||
<textarea id="textarea_wrapped" cols="5">hey friend</textarea>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
72
accessible/tests/mochitest/events/test_caretmove.xul
Normal file
72
accessible/tests/mochitest/events/test_caretmove.xul
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?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="Caret move event testing">
|
||||
|
||||
<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="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
if (MAC) {
|
||||
todo(false, "Make these tests pass on OSX (bug 650294)");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
gQueue = new eventQueue(EVENT_TEXT_CARET_MOVED);
|
||||
|
||||
var id = "textbox";
|
||||
var input = getNode(id).inputField;
|
||||
gQueue.push(new synthFocus(id, new caretMoveChecker(5, input)));
|
||||
gQueue.push(new synthSelectAll(id, new caretMoveChecker(5, input)));
|
||||
gQueue.push(new synthHomeKey(id, new caretMoveChecker(0, input)));
|
||||
gQueue.push(new synthRightKey(id, new caretMoveChecker(1, input)));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</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=634240"
|
||||
title="No caret move events are fired for XUL textbox accessible">
|
||||
Mozilla Bug 634240
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<textbox id="textbox" value="hello"/>
|
||||
|
||||
<vbox id="eventdump"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
||||
864
accessible/tests/mochitest/events/test_coalescence.html
Normal file
864
accessible/tests/mochitest/events/test_coalescence.html
Normal file
|
|
@ -0,0 +1,864 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible mutation events coalescence 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="../states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invoker base classes
|
||||
|
||||
const kRemoveElm = 1;
|
||||
const kHideElm = 2;
|
||||
const kAddElm = 3;
|
||||
const kShowElm = 4;
|
||||
|
||||
/**
|
||||
* Base class to test of mutation events coalescence.
|
||||
*/
|
||||
function coalescenceBase(aChildAction, aParentAction,
|
||||
aPerformActionOnChildInTheFirstPlace)
|
||||
{
|
||||
// Invoker interface
|
||||
|
||||
this.invoke = function coalescenceBase_invoke()
|
||||
{
|
||||
if (aPerformActionOnChildInTheFirstPlace) {
|
||||
this.invokeAction(this.childNode, aChildAction);
|
||||
this.invokeAction(this.parentNode, aParentAction);
|
||||
} else {
|
||||
this.invokeAction(this.parentNode, aParentAction);
|
||||
this.invokeAction(this.childNode, aChildAction);
|
||||
}
|
||||
}
|
||||
|
||||
this.getID = function coalescenceBase_getID()
|
||||
{
|
||||
var childAction = this.getActionName(aChildAction) + " child";
|
||||
var parentAction = this.getActionName(aParentAction) + " parent";
|
||||
|
||||
if (aPerformActionOnChildInTheFirstPlace)
|
||||
return childAction + " and then " + parentAction;
|
||||
|
||||
return parentAction + " and then " + childAction;
|
||||
}
|
||||
|
||||
this.finalCheck = function coalescenceBase_check()
|
||||
{
|
||||
if (this.getEventType(aChildAction) == EVENT_HIDE) {
|
||||
testIsDefunct(this.child);
|
||||
}
|
||||
if (this.getEventType(aParentAction) == EVENT_HIDE) {
|
||||
testIsDefunct(this.parent);
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation details
|
||||
|
||||
this.invokeAction = function coalescenceBase_invokeAction(aNode, aAction)
|
||||
{
|
||||
switch (aAction) {
|
||||
case kRemoveElm:
|
||||
aNode.parentNode.removeChild(aNode);
|
||||
break;
|
||||
|
||||
case kHideElm:
|
||||
aNode.style.display = "none";
|
||||
break;
|
||||
|
||||
case kAddElm:
|
||||
if (aNode == this.parentNode)
|
||||
this.hostNode.appendChild(this.parentNode);
|
||||
else
|
||||
this.parentNode.appendChild(this.childNode);
|
||||
break;
|
||||
|
||||
case kShowElm:
|
||||
aNode.style.display = "block";
|
||||
break;
|
||||
|
||||
default:
|
||||
return INVOKER_ACTION_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
this.getEventType = function coalescenceBase_getEventType(aAction)
|
||||
{
|
||||
switch (aAction) {
|
||||
case kRemoveElm: case kHideElm:
|
||||
return EVENT_HIDE;
|
||||
case kAddElm: case kShowElm:
|
||||
return EVENT_SHOW;
|
||||
}
|
||||
}
|
||||
|
||||
this.getActionName = function coalescenceBase_getActionName(aAction)
|
||||
{
|
||||
switch (aAction) {
|
||||
case kRemoveElm:
|
||||
return "remove";
|
||||
case kHideElm:
|
||||
return "hide";
|
||||
case kAddElm:
|
||||
return "add";
|
||||
case kShowElm:
|
||||
return "show";
|
||||
default:
|
||||
return "??";
|
||||
}
|
||||
}
|
||||
|
||||
this.initSequence = function coalescenceBase_initSequence()
|
||||
{
|
||||
// expected events
|
||||
var eventType = this.getEventType(aParentAction);
|
||||
this.eventSeq = [
|
||||
new invokerChecker(eventType, this.parentNode),
|
||||
new invokerChecker(EVENT_REORDER, this.hostNode)
|
||||
];
|
||||
|
||||
// unexpected events
|
||||
this.unexpectedEventSeq = [
|
||||
new invokerChecker(this.getEventType(aChildAction), this.childNode),
|
||||
new invokerChecker(EVENT_REORDER, this.parentNode)
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove or hide mutation events coalescence testing.
|
||||
*/
|
||||
function removeOrHideCoalescenceBase(aChildID, aParentID,
|
||||
aChildAction, aParentAction,
|
||||
aPerformActionOnChildInTheFirstPlace)
|
||||
{
|
||||
this.__proto__ = new coalescenceBase(aChildAction, aParentAction,
|
||||
aPerformActionOnChildInTheFirstPlace);
|
||||
|
||||
this.init = function removeOrHideCoalescenceBase_init()
|
||||
{
|
||||
this.childNode = getNode(aChildID);
|
||||
this.parentNode = getNode(aParentID);
|
||||
this.child = getAccessible(this.childNode);
|
||||
this.parent = getAccessible(this.parentNode);
|
||||
this.hostNode = this.parentNode.parentNode;
|
||||
}
|
||||
|
||||
// Initalization
|
||||
|
||||
this.init();
|
||||
this.initSequence();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
/**
|
||||
* Remove child node and then its parent node from DOM tree.
|
||||
*/
|
||||
function removeChildNParent(aChildID, aParentID)
|
||||
{
|
||||
this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
|
||||
kRemoveElm, kRemoveElm,
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove parent node and then its child node from DOM tree.
|
||||
*/
|
||||
function removeParentNChild(aChildID, aParentID)
|
||||
{
|
||||
this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
|
||||
kRemoveElm, kRemoveElm,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide child node and then its parent node.
|
||||
*/
|
||||
function hideChildNParent(aChildID, aParentID)
|
||||
{
|
||||
this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
|
||||
kHideElm, kHideElm,
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide parent node and then its child node.
|
||||
*/
|
||||
function hideParentNChild(aChildID, aParentID)
|
||||
{
|
||||
this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
|
||||
kHideElm, kHideElm,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide child node and then remove its parent node.
|
||||
*/
|
||||
function hideChildNRemoveParent(aChildID, aParentID)
|
||||
{
|
||||
this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
|
||||
kHideElm, kRemoveElm,
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide parent node and then remove its child node.
|
||||
*/
|
||||
function hideParentNRemoveChild(aChildID, aParentID)
|
||||
{
|
||||
this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
|
||||
kRemoveElm, kHideElm,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove child node and then hide its parent node.
|
||||
*/
|
||||
function removeChildNHideParent(aChildID, aParentID)
|
||||
{
|
||||
this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
|
||||
kRemoveElm, kHideElm,
|
||||
true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove parent node and then hide its child node.
|
||||
*/
|
||||
function removeParentNHideChild(aChildID, aParentID)
|
||||
{
|
||||
this.__proto__ = new removeOrHideCoalescenceBase(aChildID, aParentID,
|
||||
kHideElm, kRemoveElm,
|
||||
false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and append parent node and create and append child node to it.
|
||||
*/
|
||||
function addParentNChild(aHostID, aPerformActionOnChildInTheFirstPlace)
|
||||
{
|
||||
this.init = function addParentNChild_init()
|
||||
{
|
||||
this.hostNode = getNode(aHostID);
|
||||
this.parentNode = document.createElement("select");
|
||||
this.childNode = document.createElement("option");
|
||||
this.childNode.textContent = "testing";
|
||||
}
|
||||
|
||||
this.__proto__ = new coalescenceBase(kAddElm, kAddElm,
|
||||
aPerformActionOnChildInTheFirstPlace);
|
||||
|
||||
this.init();
|
||||
this.initSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show parent node and show child node to it.
|
||||
*/
|
||||
function showParentNChild(aParentID, aChildID,
|
||||
aPerformActionOnChildInTheFirstPlace)
|
||||
{
|
||||
this.init = function showParentNChild_init()
|
||||
{
|
||||
this.parentNode = getNode(aParentID);
|
||||
this.hostNode = this.parentNode.parentNode;
|
||||
this.childNode = getNode(aChildID);
|
||||
}
|
||||
|
||||
this.__proto__ = new coalescenceBase(kShowElm, kShowElm,
|
||||
aPerformActionOnChildInTheFirstPlace);
|
||||
|
||||
this.init();
|
||||
this.initSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and append child node to the DOM and then show parent node.
|
||||
*/
|
||||
function showParentNAddChild(aParentID,
|
||||
aPerformActionOnChildInTheFirstPlace)
|
||||
{
|
||||
this.init = function showParentNAddChild_init()
|
||||
{
|
||||
this.parentNode = getNode(aParentID);
|
||||
this.hostNode = this.parentNode.parentNode;
|
||||
this.childNode = document.createElement("option");
|
||||
this.childNode.textContent = "testing";
|
||||
}
|
||||
|
||||
this.__proto__ = new coalescenceBase(kAddElm, kShowElm,
|
||||
aPerformActionOnChildInTheFirstPlace);
|
||||
|
||||
this.init();
|
||||
this.initSequence();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove children and parent
|
||||
*/
|
||||
function removeGrandChildrenNHideParent(aChild1Id, aChild2Id, aParentId)
|
||||
{
|
||||
this.child1 = getNode(aChild1Id);
|
||||
this.child2 = getNode(aChild2Id);
|
||||
this.parent = getNode(aParentId);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getAccessible(aParentId)),
|
||||
new invokerChecker(EVENT_REORDER, getNode(aParentId).parentNode),
|
||||
new unexpectedInvokerChecker(EVENT_HIDE, getAccessible(aChild1Id)),
|
||||
new unexpectedInvokerChecker(EVENT_HIDE, getAccessible(aChild2Id)),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, getAccessible(aParentId))
|
||||
];
|
||||
|
||||
this.invoke = function removeGrandChildrenNHideParent_invoke()
|
||||
{
|
||||
this.child1.parentNode.removeChild(this.child1);
|
||||
this.child2.parentNode.removeChild(this.child2);
|
||||
this.parent.hidden = true;
|
||||
}
|
||||
|
||||
this.getID = function removeGrandChildrenNHideParent_getID() {
|
||||
return "remove grand children of different parents and then hide their grand parent";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a child, and then its parent.
|
||||
*/
|
||||
function test3()
|
||||
{
|
||||
this.o = getAccessible("t3_o");
|
||||
this.ofc = getAccessible("t3_o").firstChild;
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, this.o),
|
||||
new invokerChecker(EVENT_REORDER, "t3_lb"),
|
||||
new unexpectedInvokerChecker(EVENT_HIDE, this.ofc),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, this.o)
|
||||
];
|
||||
|
||||
this.invoke = function test3_invoke()
|
||||
{
|
||||
getNode("t3_o").textContent = "";
|
||||
getNode("t3_lb").removeChild(getNode("t3_o"));
|
||||
}
|
||||
|
||||
this.finalCheck = function test3_finalCheck()
|
||||
{
|
||||
testIsDefunct(this.o);
|
||||
testIsDefunct(this.ofc);
|
||||
}
|
||||
|
||||
this.getID = function test3_getID() {
|
||||
return "remove a child, and then its parent";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove children, and then a parent of 2nd child.
|
||||
*/
|
||||
function test4()
|
||||
{
|
||||
this.o1 = getAccessible("t4_o1");
|
||||
this.o1fc = this.o1.firstChild;
|
||||
this.o2 = getAccessible("t4_o2");
|
||||
this.o2fc = this.o2.firstChild;
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, this.o1fc),
|
||||
new invokerChecker(EVENT_HIDE, this.o2),
|
||||
new invokerChecker(EVENT_REORDER, "t4_lb"),
|
||||
new unexpectedInvokerChecker(EVENT_HIDE, this.o2fc),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, this.o1),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, this.o2)
|
||||
];
|
||||
|
||||
this.invoke = function test4_invoke()
|
||||
{
|
||||
getNode("t4_o1").textContent = "";
|
||||
getNode("t4_o2").textContent = "";
|
||||
getNode("t4_lb").removeChild(getNode("t4_o2"));
|
||||
}
|
||||
|
||||
this.finalCheck = function test4_finalCheck()
|
||||
{
|
||||
testIsDefunct(this.o1fc);
|
||||
testIsDefunct(this.o2);
|
||||
testIsDefunct(this.o2fc);
|
||||
}
|
||||
|
||||
this.getID = function test4_getID() {
|
||||
return "remove children, and then a parent of 2nd child";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a child, remove a parent sibling, remove the parent
|
||||
*/
|
||||
function test5()
|
||||
{
|
||||
this.o = getAccessible("t5_o");
|
||||
this.ofc = this.o.firstChild;
|
||||
this.b = getAccessible("t5_b");
|
||||
this.lb = getAccessible("t5_lb");
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, this.b),
|
||||
new invokerChecker(EVENT_HIDE, this.o),
|
||||
new invokerChecker(EVENT_REORDER, "t5"),
|
||||
new unexpectedInvokerChecker(EVENT_HIDE, this.ofc),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, this.o),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, this.lb)
|
||||
];
|
||||
|
||||
this.invoke = function test5_invoke()
|
||||
{
|
||||
getNode("t5_o").textContent = "";
|
||||
getNode("t5").removeChild(getNode("t5_b"));
|
||||
getNode("t5_lb").removeChild(getNode("t5_o"));
|
||||
}
|
||||
|
||||
this.finalCheck = function test5_finalCheck()
|
||||
{
|
||||
testIsDefunct(this.ofc);
|
||||
testIsDefunct(this.o);
|
||||
testIsDefunct(this.b);
|
||||
}
|
||||
|
||||
this.getID = function test5_getID() {
|
||||
return "remove a child, remove a parent sibling, remove the parent";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert accessibles with a child node moved by aria-owns
|
||||
* Markup:
|
||||
* <div id="t6_fc">
|
||||
* <div id="t6_owns"></div>
|
||||
* </div>
|
||||
* <div id="t6_sc" aria-owns="t6_owns"></div>
|
||||
*/
|
||||
function test6()
|
||||
{
|
||||
this.parent = getNode("t6");
|
||||
this.fc = document.createElement("div");
|
||||
this.fc.setAttribute("id", "t6_fc");
|
||||
this.owns = document.createElement("div");
|
||||
this.owns.setAttribute("id", "t6_owns");
|
||||
this.sc = document.createElement("div");
|
||||
this.sc.setAttribute("id", "t6_sc");
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, this.fc),
|
||||
new invokerChecker(EVENT_SHOW, this.sc),
|
||||
new invokerChecker(EVENT_REORDER, this.parent),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, this.fc),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, this.sc),
|
||||
new unexpectedInvokerChecker(EVENT_HIDE, this.owns),
|
||||
new unexpectedInvokerChecker(EVENT_SHOW, this.owns)
|
||||
];
|
||||
|
||||
this.invoke = function test6_invoke()
|
||||
{
|
||||
getNode("t6").appendChild(this.fc);
|
||||
getNode("t6_fc").appendChild(this.owns);
|
||||
getNode("t6").appendChild(this.sc);
|
||||
getNode("t6_sc").setAttribute("aria-owns", "t6_owns");
|
||||
};
|
||||
|
||||
this.getID = function test6_getID() {
|
||||
return "Insert accessibles with a child node moved by aria-owns";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert text nodes under direct and grand children, and then hide
|
||||
* their container by means of aria-owns.
|
||||
*
|
||||
* Markup:
|
||||
* <div id="t7_moveplace" aria-owns="t7_c"></div>
|
||||
* <div id="t7_c">
|
||||
* <div id="t7_c_directchild">ha</div>
|
||||
* <div><div id="t7_c_grandchild">ha</div></div>
|
||||
* </div>
|
||||
*/
|
||||
function test7()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getNode('t7_c')),
|
||||
new invokerChecker(EVENT_SHOW, getNode('t7_c')),
|
||||
new invokerChecker(EVENT_REORDER, getNode('t7')),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, getNode('t7_c_directchild')),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, getNode('t7_c_grandchild')),
|
||||
new unexpectedInvokerChecker(EVENT_SHOW, () => getNode('t7_c_directchild').firstChild),
|
||||
new unexpectedInvokerChecker(EVENT_SHOW, () => getNode('t7_c_grandchild').firstChild)
|
||||
];
|
||||
|
||||
this.invoke = function test7_invoke()
|
||||
{
|
||||
getNode('t7_c_directchild').textContent = 'ha';
|
||||
getNode('t7_c_grandchild').textContent = 'ha';
|
||||
getNode('t7_moveplace').setAttribute('aria-owns', 't7_c');
|
||||
};
|
||||
|
||||
this.getID = function test7_getID() {
|
||||
return "Show child accessibles and then hide their container";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a node by aria-owns from right to left in the tree, so that
|
||||
* the eventing looks this way:
|
||||
* reorder for 't8_c1'
|
||||
* hide for 't8_c1_child'
|
||||
* show for 't8_c2_moved'
|
||||
* reorder for 't8_c2'
|
||||
* hide for 't8_c2_moved'
|
||||
*
|
||||
* The hide event should be delivered before the paired show event.
|
||||
*/
|
||||
function test8()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getNode('t8_c1_child')),
|
||||
new invokerChecker(EVENT_HIDE, 't8_c2_moved'),
|
||||
new invokerChecker(EVENT_SHOW, 't8_c2_moved'),
|
||||
new invokerChecker(EVENT_REORDER, 't8_c2'),
|
||||
new invokerChecker(EVENT_REORDER, 't8_c1'),
|
||||
];
|
||||
|
||||
this.invoke = function test8_invoke()
|
||||
{
|
||||
// Remove a node from 't8_c1' container to give the event tree a
|
||||
// desired structure (the 't8_c1' container node goes first in the event
|
||||
// tree)
|
||||
getNode('t8_c1_child').remove();
|
||||
// then move 't8_c2_moved' from 't8_c2' to 't8_c1'.
|
||||
getNode('t8_c1').setAttribute('aria-owns', 't8_c2_moved');
|
||||
};
|
||||
|
||||
this.getID = function test8_getID() {
|
||||
return "Move a node by aria-owns to left within the tree";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Move 't9_c3_moved' node under 't9_c2_moved', and then move 't9_c2_moved'
|
||||
* node by aria-owns (same as test10 but has different aria-owns
|
||||
* ordering), the eventing looks same way as in test10:
|
||||
* reorder for 't9_c1'
|
||||
* hide for 't9_c1_child'
|
||||
* show for 't9_c2_moved'
|
||||
* reorder for 't9_c2'
|
||||
* hide for 't9_c2_child'
|
||||
* hide for 't9_c2_moved'
|
||||
* reorder for 't9_c3'
|
||||
* hide for 't9_c3_moved'
|
||||
*
|
||||
* The hide events for 't9_c2_moved' and 't9_c3_moved' should be delivered
|
||||
* before the show event for 't9_c2_moved'.
|
||||
*/
|
||||
function test9()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getNode('t9_c1_child')),
|
||||
new invokerChecker(EVENT_HIDE, getNode('t9_c2_child')),
|
||||
new invokerChecker(EVENT_HIDE, 't9_c3_moved'),
|
||||
new invokerChecker(EVENT_HIDE, 't9_c2_moved'),
|
||||
new invokerChecker(EVENT_SHOW, 't9_c2_moved'),
|
||||
new invokerChecker(EVENT_REORDER, 't9_c3'),
|
||||
new invokerChecker(EVENT_REORDER, 't9_c2'),
|
||||
new invokerChecker(EVENT_REORDER, 't9_c1'),
|
||||
new unexpectedInvokerChecker(EVENT_SHOW, 't9_c3_moved')
|
||||
];
|
||||
|
||||
this.invoke = function test9_invoke()
|
||||
{
|
||||
// Remove child nodes from 't9_c1' and 't9_c2' containers to give
|
||||
// the event tree a needed structure ('t9_c1' and 't9_c2' nodes go
|
||||
// first in the event tree),
|
||||
getNode('t9_c1_child').remove();
|
||||
getNode('t9_c2_child').remove();
|
||||
// then do aria-owns magic.
|
||||
getNode('t9_c2_moved').setAttribute('aria-owns', 't9_c3_moved');
|
||||
getNode('t9_c1').setAttribute('aria-owns', 't9_c2_moved');
|
||||
};
|
||||
|
||||
this.getID = function test9_getID() {
|
||||
return "Move node #1 by aria-owns and then move node #2 into node #1";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a node 't10_c3_moved' by aria-owns under a node 't10_c2_moved',
|
||||
* moved by under 't10_1', so that the eventing looks this way:
|
||||
* reorder for 't10_c1'
|
||||
* hide for 't10_c1_child'
|
||||
* show for 't10_c2_moved'
|
||||
* reorder for 't10_c2'
|
||||
* hide for 't10_c2_child'
|
||||
* hide for 't10_c2_moved'
|
||||
* reorder for 't10_c3'
|
||||
* hide for 't10_c3_moved'
|
||||
*
|
||||
* The hide events for 't10_c2_moved' and 't10_c3_moved' should be delivered
|
||||
* before the show event for 't10_c2_moved'.
|
||||
*/
|
||||
function test10()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getNode('t10_c1_child')),
|
||||
new invokerChecker(EVENT_HIDE, getNode('t10_c2_child')),
|
||||
new invokerChecker(EVENT_HIDE, getNode('t10_c2_moved')),
|
||||
new invokerChecker(EVENT_HIDE, getNode('t10_c3_moved')),
|
||||
new invokerChecker(EVENT_SHOW, getNode('t10_c2_moved')),
|
||||
new invokerChecker(EVENT_REORDER, 't10_c2'),
|
||||
new invokerChecker(EVENT_REORDER, 't10_c1'),
|
||||
new invokerChecker(EVENT_REORDER, 't10_c3')
|
||||
];
|
||||
|
||||
this.invoke = function test10_invoke()
|
||||
{
|
||||
// Remove child nodes from 't10_c1' and 't10_c2' containers to give
|
||||
// the event tree a needed structure ('t10_c1' and 't10_c2' nodes go first
|
||||
// in the event tree),
|
||||
getNode('t10_c1_child').remove();
|
||||
getNode('t10_c2_child').remove();
|
||||
// then do aria-owns stuff.
|
||||
getNode('t10_c1').setAttribute('aria-owns', 't10_c2_moved');
|
||||
getNode('t10_c2_moved').setAttribute('aria-owns', 't10_c3_moved');
|
||||
};
|
||||
|
||||
this.getID = function test10_getID() {
|
||||
return "Move a node by aria-owns into a node moved by aria-owns to left within the tree";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Move a node by aria-owns from right to left in the tree, and then
|
||||
* move its parent too by aria-owns. No hide event should be fired for
|
||||
* original node.
|
||||
*/
|
||||
function test11()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getNode('t11_c1_child')),
|
||||
new invokerChecker(EVENT_HIDE, getNode('t11_c2')),
|
||||
new orderChecker(),
|
||||
new asyncInvokerChecker(EVENT_SHOW, 't11_c2_child'),
|
||||
new asyncInvokerChecker(EVENT_SHOW, 't11_c2'),
|
||||
new orderChecker(),
|
||||
new invokerChecker(EVENT_REORDER, 't11'),
|
||||
new unexpectedInvokerChecker(EVENT_HIDE, 't11_c2_child'),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, 't11_c1'),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, 't11_c2'),
|
||||
new unexpectedInvokerChecker(EVENT_REORDER, 't11_c3')
|
||||
];
|
||||
|
||||
this.invoke = function test11_invoke()
|
||||
{
|
||||
// Remove a node from 't11_c1' container to give the event tree a
|
||||
// desired structure (the 't11_c1' container node goes first in
|
||||
// the event tree),
|
||||
getNode('t11_c1_child').remove();
|
||||
// then move 't11_c2_moved' from 't11_c2' to 't11_c1', and then move
|
||||
// 't11_c2' to 't11_c3'.
|
||||
getNode('t11_c1').setAttribute('aria-owns', 't11_c2_child');
|
||||
getNode('t11_c3').setAttribute('aria-owns', 't11_c2');
|
||||
};
|
||||
|
||||
this.getID = function test11_getID() {
|
||||
return "Move a node by aria-owns to left within the tree";
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests.
|
||||
|
||||
gA11yEventDumpToConsole = true; // debug stuff
|
||||
//enableLogging("eventTree");
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new removeChildNParent("option1", "select1"));
|
||||
gQueue.push(new removeParentNChild("option2", "select2"));
|
||||
gQueue.push(new hideChildNParent("option3", "select3"));
|
||||
gQueue.push(new hideParentNChild("option4", "select4"));
|
||||
gQueue.push(new hideChildNRemoveParent("option5", "select5"));
|
||||
gQueue.push(new hideParentNRemoveChild("option6", "select6"));
|
||||
gQueue.push(new removeChildNHideParent("option7", "select7"));
|
||||
gQueue.push(new removeParentNHideChild("option8", "select8"));
|
||||
|
||||
gQueue.push(new addParentNChild("testContainer", false));
|
||||
gQueue.push(new addParentNChild("testContainer", true));
|
||||
gQueue.push(new showParentNChild("select9", "option9", false));
|
||||
gQueue.push(new showParentNChild("select10", "option10", true));
|
||||
gQueue.push(new showParentNAddChild("select11", false));
|
||||
gQueue.push(new showParentNAddChild("select12", true));
|
||||
|
||||
gQueue.push(new removeGrandChildrenNHideParent("t1_child1", "t1_child2", "t1_parent"));
|
||||
gQueue.push(new test3());
|
||||
gQueue.push(new test4());
|
||||
gQueue.push(new test5());
|
||||
gQueue.push(new test6());
|
||||
gQueue.push(new test7());
|
||||
gQueue.push(new test8());
|
||||
gQueue.push(new test9());
|
||||
gQueue.push(new test10());
|
||||
gQueue.push(new test11());
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=513213"
|
||||
title="coalesce events when new event is appended to the queue">
|
||||
Mozilla Bug 513213
|
||||
</a><br>
|
||||
<a target="_blank"
|
||||
title="Rework accessible tree update code"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=570275">
|
||||
Mozilla Bug 570275
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="testContainer">
|
||||
<select id="select1">
|
||||
<option id="option1">option</option>
|
||||
</select>
|
||||
<select id="select2">
|
||||
<option id="option2">option</option>
|
||||
</select>
|
||||
<select id="select3">
|
||||
<option id="option3">option</option>
|
||||
</select>
|
||||
<select id="select4">
|
||||
<option id="option4">option</option>
|
||||
</select>
|
||||
<select id="select5">
|
||||
<option id="option5">option</option>
|
||||
</select>
|
||||
<select id="select6">
|
||||
<option id="option6">option</option>
|
||||
</select>
|
||||
<select id="select7">
|
||||
<option id="option7">option</option>
|
||||
</select>
|
||||
<select id="select8">
|
||||
<option id="option8">option</option>
|
||||
</select>
|
||||
|
||||
<select id="select9" style="display: none">
|
||||
<option id="option9" style="display: none">testing</option>
|
||||
</select>
|
||||
<select id="select10" style="display: none">
|
||||
<option id="option10" style="display: none">testing</option>
|
||||
</select>
|
||||
<select id="select11" style="display: none"></select>
|
||||
<select id="select12" style="display: none"></select>
|
||||
</div>
|
||||
|
||||
<div id="testContainer2">
|
||||
<div id="t1_parent">
|
||||
<div id="t1_mid1"><div id="t1_child1"></div></div>
|
||||
<div id="t1_mid2"><div id="t1_child2"></div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="t3">
|
||||
<div role="listbox" id="t3_lb">
|
||||
<div role="option" id="t3_o">opt</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="t4">
|
||||
<div role="listbox" id="t4_lb">
|
||||
<div role="option" id="t4_o1">opt1</div>
|
||||
<div role="option" id="t4_o2">opt2</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="t5">
|
||||
<div role="button" id="t5_b">btn</div>
|
||||
<div role="listbox" id="t5_lb">
|
||||
<div role="option" id="t5_o">opt</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="t6">
|
||||
</div>
|
||||
|
||||
<div id="t7">
|
||||
<div id="t7_moveplace"></div>
|
||||
<div id="t7_c">
|
||||
<div><div id="t7_c_grandchild"></div></div>
|
||||
<div id="t7_c_directchild"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="t8">
|
||||
<div id="t8_c1"><div id="t8_c1_child"></div></div>
|
||||
<div id="t8_c2">
|
||||
<div id="t8_c2_moved"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="t9">
|
||||
<div id="t9_c1"><div id="t9_c1_child"></div></div>
|
||||
<div id="t9_c2">
|
||||
<div id="t9_c2_child"></div>
|
||||
<div id="t9_c2_moved"></div>
|
||||
</div>
|
||||
<div id="t9_c3">
|
||||
<div id="t9_c3_moved"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="t10">
|
||||
<div id="t10_c1"><div id="t10_c1_child"></div></div>
|
||||
<div id="t10_c2">
|
||||
<div id="t10_c2_child"></div>
|
||||
<div id="t10_c2_moved"></div>
|
||||
</div>
|
||||
<div id="t10_c3">
|
||||
<div id="t10_c3_moved"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="t11">
|
||||
<div id="t11_c1"><div id="t11_c1_child"></div></div>
|
||||
<div id="t11_c2"><div id="t11_c2_child"></div></div>
|
||||
<div id="t11_c3"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
139
accessible/tests/mochitest/events/test_contextmenu.html
Normal file
139
accessible/tests/mochitest/events/test_contextmenu.html
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Context menu 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">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function showContextMenu(aID)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_MENUPOPUP_START, getContextMenuNode()),
|
||||
];
|
||||
|
||||
this.invoke = function showContextMenu_invoke()
|
||||
{
|
||||
synthesizeMouse(this.DOMNode, 4, 4, { type: "contextmenu", button: 2 });
|
||||
}
|
||||
|
||||
this.getID = function showContextMenu_getID()
|
||||
{
|
||||
return "show context menu";
|
||||
}
|
||||
}
|
||||
|
||||
function selectMenuItem()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, getFocusedMenuItem)
|
||||
];
|
||||
|
||||
this.invoke = function selectMenuItem_invoke()
|
||||
{
|
||||
synthesizeKey("VK_DOWN", { });
|
||||
}
|
||||
|
||||
this.getID = function selectMenuItem_getID()
|
||||
{
|
||||
return "select first menuitem";
|
||||
}
|
||||
}
|
||||
|
||||
function closeContextMenu(aID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_MENUPOPUP_END,
|
||||
getAccessible(getContextMenuNode()))
|
||||
];
|
||||
|
||||
this.invoke = function closeContextMenu_invoke()
|
||||
{
|
||||
synthesizeKey("VK_ESCAPE", { });
|
||||
}
|
||||
|
||||
this.getID = function closeContextMenu_getID()
|
||||
{
|
||||
return "close context menu";
|
||||
}
|
||||
}
|
||||
|
||||
function getContextMenuNode()
|
||||
{
|
||||
return getRootAccessible().DOMDocument.
|
||||
getElementById("contentAreaContextMenu");
|
||||
}
|
||||
|
||||
function getFocusedMenuItem()
|
||||
{
|
||||
var menu = getAccessible(getAccessible(getContextMenuNode()));
|
||||
for (var idx = 0; idx < menu.childCount; idx++) {
|
||||
var item = menu.getChildAt(idx);
|
||||
|
||||
if (hasState(item, STATE_FOCUSED))
|
||||
return getAccessible(item);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
|
||||
var gQueue = null;
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new showContextMenu("input"));
|
||||
gQueue.push(new selectMenuItem());
|
||||
gQueue.push(new closeContextMenu());
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=580535"
|
||||
title="Broken accessibility in context menus">
|
||||
Mozilla Bug 580535
|
||||
</a><br>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<input id="input">
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
85
accessible/tests/mochitest/events/test_descrchange.html
Normal file
85
accessible/tests/mochitest/events/test_descrchange.html
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible description change event 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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function setAttr(aID, aAttr, aValue, aChecker)
|
||||
{
|
||||
this.eventSeq = [ aChecker ];
|
||||
this.invoke = function setAttr_invoke()
|
||||
{
|
||||
getNode(aID).setAttribute(aAttr, aValue);
|
||||
}
|
||||
|
||||
this.getID = function setAttr_getID()
|
||||
{
|
||||
return "set attr '" + aAttr + "', value '" + aValue + "'";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debuggin
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new setAttr("tst1", "aria-describedby", "display",
|
||||
new invokerChecker(EVENT_DESCRIPTION_CHANGE, "tst1")));
|
||||
gQueue.push(new setAttr("tst1", "title", "title",
|
||||
new unexpectedInvokerChecker(EVENT_DESCRIPTION_CHANGE, "tst1")));
|
||||
|
||||
gQueue.push(new setAttr("tst2", "title", "title",
|
||||
new invokerChecker(EVENT_NAME_CHANGE, "tst2")));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=991969"
|
||||
title="Event not fired when description changes">
|
||||
Bug 991969
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<button id="tst1">btn1</button>
|
||||
<button id="tst2">btn2</button>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
360
accessible/tests/mochitest/events/test_docload.html
Normal file
360
accessible/tests/mochitest/events/test_docload.html
Normal file
|
|
@ -0,0 +1,360 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible events testing for 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">
|
||||
// Front end stuff sometimes likes to stuff things in the hidden window(s)
|
||||
// in which case there's accessibles for that content.
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Force the creation of an accessible for the hidden window's document.
|
||||
var doc = Services.appShell.hiddenDOMWindow.document;
|
||||
gAccService.getAccessibleFor(doc);
|
||||
|
||||
// The private hidden window will be lazily created that's why we need to do
|
||||
// it here *before* loading '../events.js' or else we'll have a duplicate
|
||||
// reorder event.
|
||||
var privateDoc = Services.appShell.hiddenPrivateDOMWindow.document;
|
||||
|
||||
// Force the creation of an accessible for the private hidden window's doc.
|
||||
gAccService.getAccessibleFor(privateDoc);
|
||||
</script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function changeIframeSrc(aIdentifier, aURL)
|
||||
{
|
||||
this.DOMNode = getNode(aIdentifier);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, getAccessible(this.DOMNode)),
|
||||
new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, getIframeDoc)
|
||||
];
|
||||
|
||||
this.invoke = function changeIframeSrc_invoke()
|
||||
{
|
||||
this.DOMNode.src = aURL;
|
||||
}
|
||||
|
||||
this.finalCheck = function changeIframeSrc_finalCheck()
|
||||
{
|
||||
var accTree = {
|
||||
role: ROLE_INTERNAL_FRAME,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_DOCUMENT,
|
||||
name: aURL == "about:" ? "About:" : aURL
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
testAccessibleTree(this.DOMNode, accTree);
|
||||
}
|
||||
|
||||
this.getID = function changeIframeSrc_getID()
|
||||
{
|
||||
return "change iframe src on " + aURL;
|
||||
}
|
||||
|
||||
function getIframeDoc()
|
||||
{
|
||||
return getAccessible(getNode(aIdentifier).contentDocument);
|
||||
}
|
||||
}
|
||||
|
||||
const kHide = 1;
|
||||
const kShow = 2;
|
||||
const kRemove = 3;
|
||||
function morphIFrame(aIdentifier, aAction)
|
||||
{
|
||||
this.DOMNode = getNode(aIdentifier);
|
||||
this.IFrameContainerDOMNode = this.DOMNode.parentNode;
|
||||
|
||||
this.eventSeq = [];
|
||||
|
||||
var checker = null;
|
||||
if (aAction == kShow)
|
||||
checker = new invokerChecker(EVENT_SHOW, this.DOMNode);
|
||||
else
|
||||
checker = new invokerChecker(EVENT_HIDE, this.DOMNode);
|
||||
this.eventSeq.push(checker);
|
||||
|
||||
var reorderChecker =
|
||||
new invokerChecker(EVENT_REORDER, this.IFrameContainerDOMNode);
|
||||
this.eventSeq.push(reorderChecker);
|
||||
|
||||
this.invoke = function morphIFrame_invoke()
|
||||
{
|
||||
if (aAction == kHide) {
|
||||
this.DOMNode.style.display = "none";
|
||||
} else if (aAction == kShow) {
|
||||
this.DOMNode.style.display = "block";
|
||||
} else {
|
||||
this.IFrameContainerDOMNode.removeChild(this.DOMNode);
|
||||
}
|
||||
}
|
||||
|
||||
this.finalCheck = function morphIFrame_finalCheck()
|
||||
{
|
||||
var accTree = {
|
||||
role: ROLE_SECTION,
|
||||
children: (aAction == kHide || aAction == kRemove) ? [ ] :
|
||||
[
|
||||
{
|
||||
role: ROLE_INTERNAL_FRAME,
|
||||
children: [
|
||||
{ role: ROLE_DOCUMENT }
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
testAccessibleTree(this.IFrameContainerDOMNode, accTree);
|
||||
}
|
||||
|
||||
this.getID = function morphIFrame_getID()
|
||||
{
|
||||
if (aAction == kRemove)
|
||||
return "remove iframe";
|
||||
|
||||
return "change display style of iframe to " +
|
||||
((aAction == kHide) ? "none" : "block");
|
||||
}
|
||||
}
|
||||
|
||||
function makeIFrameVisible(aID)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, this.DOMNode.parentNode)
|
||||
];
|
||||
|
||||
this.invoke = function makeIFrameVisible_invoke()
|
||||
{
|
||||
this.DOMNode.style.visibility = "visible";
|
||||
}
|
||||
|
||||
this.getID = function makeIFrameVisible_getID()
|
||||
{
|
||||
return "The accessible for DOM document loaded before it's shown shouldn't have busy state.";
|
||||
}
|
||||
}
|
||||
|
||||
function openDialogWnd(aURL)
|
||||
{
|
||||
// Get application root accessible.
|
||||
var docAcc = getAccessible(document);
|
||||
while (docAcc) {
|
||||
this.mRootAcc = docAcc;
|
||||
try {
|
||||
docAcc = docAcc.parent;
|
||||
} catch (e) {
|
||||
ok(false, "Can't get parent for " + prettyName(docAcc));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, this.mRootAcc)
|
||||
];
|
||||
|
||||
this.invoke = function openDialogWnd_invoke()
|
||||
{
|
||||
this.mDialog = window.openDialog(aURL);
|
||||
}
|
||||
|
||||
this.finalCheck = function openDialogWnd_finalCheck()
|
||||
{
|
||||
this.finalCheckImpl();
|
||||
}
|
||||
|
||||
this.finalCheckImpl = function openDialogWnd_finalCheckImpl()
|
||||
{
|
||||
var accTree = {
|
||||
role: ROLE_APP_ROOT,
|
||||
children: [
|
||||
{
|
||||
role: ROLE_CHROME_WINDOW
|
||||
},
|
||||
{
|
||||
role: ROLE_CHROME_WINDOW
|
||||
},
|
||||
{
|
||||
role: ROLE_CHROME_WINDOW
|
||||
},
|
||||
{
|
||||
role: ROLE_CHROME_WINDOW
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
testAccessibleTree(this.mRootAcc, accTree);
|
||||
|
||||
var dlgDoc = this.mDialog.document;
|
||||
ok(isAccessibleInCache(dlgDoc),
|
||||
"The document accessible for '" + aURL + "' is not in cache!");
|
||||
|
||||
this.mDialog.close();
|
||||
|
||||
// close() is asynchronous.
|
||||
SimpleTest.executeSoon(function() {
|
||||
ok(!isAccessibleInCache(dlgDoc),
|
||||
"The document accessible for '" + aURL + "' is in cache still!");
|
||||
});
|
||||
}
|
||||
|
||||
this.getID = function openDialogWnd_getID()
|
||||
{
|
||||
return "open dialog '" + aURL + "'";
|
||||
}
|
||||
}
|
||||
|
||||
function openWndShutdownDoc()
|
||||
{
|
||||
this.__proto__ =
|
||||
new openDialogWnd("../events/docload_wnd.html");
|
||||
|
||||
var thisObj = this;
|
||||
var docChecker = {
|
||||
type: EVENT_HIDE,
|
||||
get target()
|
||||
{
|
||||
var iframe = this.invoker.mDialog.document.getElementById("iframe");
|
||||
this.invoker.iframeDoc = iframe.contentDocument;
|
||||
return iframe;
|
||||
},
|
||||
get targetDescr()
|
||||
{
|
||||
return "inner iframe of docload_wnd.html document";
|
||||
},
|
||||
invoker: thisObj
|
||||
};
|
||||
|
||||
this.eventSeq.push(docChecker);
|
||||
|
||||
this.finalCheck = function openWndShutdownDoc_finalCheck()
|
||||
{
|
||||
// After timeout after event hide for iframe was handled the document
|
||||
// accessible for iframe's document is in cache still.
|
||||
ok(!isAccessibleInCache(this.iframeDoc),
|
||||
"The document accessible for iframe is in cache still after iframe hide!");
|
||||
|
||||
this.finalCheckImpl();
|
||||
|
||||
// After the window is closed all alive subdocument accessibles should
|
||||
// be shut down.
|
||||
ok(!isAccessibleInCache(this.iframeDoc),
|
||||
"The document accessible for iframe is in cache still!");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
// Debug stuff.
|
||||
// gA11yEventDumpID = "eventdump";
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new changeIframeSrc("iframe", "about:"));
|
||||
gQueue.push(new changeIframeSrc("iframe", "about:buildconfig"));
|
||||
gQueue.push(new morphIFrame("iframe", kHide));
|
||||
gQueue.push(new morphIFrame("iframe", kShow));
|
||||
gQueue.push(new morphIFrame("iframe", kRemove));
|
||||
gQueue.push(new makeIFrameVisible("iframe2"));
|
||||
gQueue.push(new openDialogWnd("about:"));
|
||||
gQueue.push(new openWndShutdownDoc());
|
||||
|
||||
gQueue.onFinish = doLastCallTests;
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
function doLastCallTests()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// makeIFrameVisible() test, part2
|
||||
|
||||
// The document shouldn't have busy state (the DOM document was loaded
|
||||
// before its accessible was created). Do this test lately to make sure
|
||||
// the content of document accessible was created initially, prior to this
|
||||
// the document accessible keeps busy state. The initial creation happens
|
||||
// asynchronously after document creation, there are no events we could
|
||||
// use to catch it.
|
||||
var iframeDoc = getAccessible("iframe2").firstChild;
|
||||
testStates(iframeDoc, 0, 0, STATE_BUSY);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=420845"
|
||||
title="Fire event_reorder on any embedded frames/iframes whos document has just loaded">
|
||||
Mozilla Bug 420845
|
||||
</a><br>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=506206"
|
||||
title="Fire event_reorder application root accessible">
|
||||
Mozilla Bug 506206
|
||||
</a><br>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=566103"
|
||||
title="Reorganize accessible document handling">
|
||||
Mozilla Bug 566103
|
||||
</a><br>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=571459"
|
||||
title="Shutdown document accessible when presshell goes away">
|
||||
Mozilla Bug 571459
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=658185"
|
||||
title="The DOM document loaded before it's shown shouldn't have busy state">
|
||||
Mozilla Bug 658185
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=754165"
|
||||
title="Fire document load events on iframes too">
|
||||
Mozilla Bug 754165
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="testContainer"><iframe id="iframe"></iframe></div>
|
||||
<div id="testContainer2"><iframe id="iframe2" src="about:" style="visibility: hidden;"></iframe></div>
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
243
accessible/tests/mochitest/events/test_docload.xul
Normal file
243
accessible/tests/mochitest/events/test_docload.xul
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
<?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="Accessibility Loading Document Events Test.">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../browser.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invoker checkers.
|
||||
function stateBusyChecker(aIsEnabled)
|
||||
{
|
||||
this.type = EVENT_STATE_CHANGE;
|
||||
this.__defineGetter__("target", currentTabDocument);
|
||||
|
||||
this.check = function stateBusyChecker_check(aEvent)
|
||||
{
|
||||
var event = null;
|
||||
try {
|
||||
var event = aEvent.QueryInterface(nsIAccessibleStateChangeEvent);
|
||||
} catch (e) {
|
||||
ok(false, "State change event was expected");
|
||||
}
|
||||
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
is(event.state, STATE_BUSY, "Wrong state of statechange event.");
|
||||
is(event.isEnabled, aIsEnabled,
|
||||
"Wrong value of state of statechange event");
|
||||
|
||||
testStates(event.accessible, (aIsEnabled ? STATE_BUSY : 0), 0,
|
||||
(aIsEnabled ? 0 : STATE_BUSY), 0);
|
||||
}
|
||||
}
|
||||
|
||||
function documentReloadChecker(aIsFromUserInput)
|
||||
{
|
||||
this.type = EVENT_DOCUMENT_RELOAD;
|
||||
this.__defineGetter__("target", currentTabDocument);
|
||||
|
||||
this.check = function documentReloadChecker_check(aEvent)
|
||||
{
|
||||
is(aEvent.isFromUserInput, aIsFromUserInput,
|
||||
"Wrong value of isFromUserInput");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers.
|
||||
|
||||
/**
|
||||
* Load URI.
|
||||
*/
|
||||
function loadURIInvoker(aURI)
|
||||
{
|
||||
this.invoke = function loadURIInvoker_invoke()
|
||||
{
|
||||
tabBrowser().loadURI(aURI);
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
// We don't expect state change event for busy true since things happen
|
||||
// quickly and it's coalesced.
|
||||
new asyncInvokerChecker(EVENT_REORDER, currentBrowser),
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
|
||||
new stateBusyChecker(false)
|
||||
];
|
||||
|
||||
this.getID = function loadURIInvoker_getID()
|
||||
{
|
||||
return "load uri " + aURI;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the document having sub document. No document loading events for
|
||||
* nested document.
|
||||
*/
|
||||
function loadNestedDocURIInvoker(aNestedDocURI)
|
||||
{
|
||||
this.__proto__ = new loadURIInvoker(aNestedDocURI);
|
||||
|
||||
// Remove reorder event checker since the event is likely coalesced by
|
||||
// reorder event on Firefox UI (refer to bug 759670 for details).
|
||||
this.eventSeq.shift();
|
||||
|
||||
this.unexpectedEventSeq = [
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, getNestedDoc),
|
||||
new invokerChecker(EVENT_STATE_CHANGE, getNestedDoc)
|
||||
];
|
||||
|
||||
function getNestedDoc()
|
||||
{
|
||||
var iframeNodes = currentTabDocument().getElementsByTagName("iframe");
|
||||
return iframeNodes && iframeNodes.length > 0 ?
|
||||
iframeNodes[0].firstChild : null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the page by F5 (isFromUserInput flag is true).
|
||||
*/
|
||||
function userReloadInvoker()
|
||||
{
|
||||
this.invoke = function userReloadInvoker_invoke()
|
||||
{
|
||||
synthesizeKey("VK_F5", {}, browserWindow());
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new documentReloadChecker(true),
|
||||
new asyncInvokerChecker(EVENT_REORDER, currentBrowser),
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
|
||||
new stateBusyChecker(false)
|
||||
];
|
||||
|
||||
this.getID = function userReloadInvoker_getID()
|
||||
{
|
||||
return "user reload page";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the page (isFromUserInput flag is false).
|
||||
*/
|
||||
function reloadInvoker()
|
||||
{
|
||||
this.invoke = function reloadInvoker_invoke()
|
||||
{
|
||||
tabBrowser().reload();
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new documentReloadChecker(false),
|
||||
new asyncInvokerChecker(EVENT_REORDER, currentBrowser),
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
|
||||
new stateBusyChecker(false)
|
||||
];
|
||||
|
||||
this.getID = function reloadInvoker_getID()
|
||||
{
|
||||
return "reload page";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load wrong URI what results in error page loading.
|
||||
*/
|
||||
function loadErrorPageInvoker(aURL, aURLDescr)
|
||||
{
|
||||
this.invoke = function loadErrorPageInvoker_invoke()
|
||||
{
|
||||
tabBrowser().loadURI(aURL);
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
// We don't expect state change for busy true, load stopped events since
|
||||
// things happen quickly and it's coalesced.
|
||||
new asyncInvokerChecker(EVENT_REORDER, currentBrowser),
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
|
||||
new stateBusyChecker(false)
|
||||
];
|
||||
|
||||
this.getID = function loadErrorPageInvoker_getID()
|
||||
{
|
||||
return "load error page: '" + aURLDescr + "'";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Tests
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debug
|
||||
//gA11yEventDumpFeature = "parentchain:reorder";
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
var dataURL =
|
||||
"data:text/html,<html><body><iframe src='http://example.com'></iframe></body></html>";
|
||||
gQueue.push(new loadNestedDocURIInvoker(dataURL));
|
||||
|
||||
gQueue.push(new loadURIInvoker("about:"));
|
||||
gQueue.push(new userReloadInvoker());
|
||||
gQueue.push(new loadURIInvoker("about:mozilla"));
|
||||
gQueue.push(new reloadInvoker());
|
||||
gQueue.push(new loadErrorPageInvoker("www.wronguri.wronguri",
|
||||
"Server not found"));
|
||||
gQueue.push(new loadErrorPageInvoker("https://nocert.example.com:443",
|
||||
"Untrusted Connection"));
|
||||
|
||||
gQueue.onFinish = function() { closeBrowserWindow(); }
|
||||
gQueue.invoke();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
openBrowserWindow(doTests);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<vbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=566103"
|
||||
title=" reorganize accessible document handling">
|
||||
Mozilla Bug 566103
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=754165"
|
||||
title="Fire document load events on iframes too">
|
||||
Mozilla Bug 754165
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox id="eventdump"></vbox>
|
||||
</vbox>
|
||||
</window>
|
||||
83
accessible/tests/mochitest/events/test_docload_aria.html
Normal file
83
accessible/tests/mochitest/events/test_docload_aria.html
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible events testing for ARIA 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"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function showARIADialog(aID)
|
||||
{
|
||||
this.dialogNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, this.dialogNode)
|
||||
];
|
||||
|
||||
this.invoke = function showARIADialog_invoke()
|
||||
{
|
||||
this.dialogNode.style.display = "block";
|
||||
}
|
||||
|
||||
this.getID = function showARIADialog_getID()
|
||||
{
|
||||
return "show ARIA dialog";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
// Debug stuff.
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new showARIADialog("dialog"));
|
||||
gQueue.push(new showARIADialog("document"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=759833"
|
||||
title="ARIA documents should fire document loading events">
|
||||
Mozilla Bug 759833
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div role="dialog" id="dialog" style="display: none;">It's a dialog</div>
|
||||
<div role="document" id="document" style="display: none;">It's a document</div>
|
||||
</body>
|
||||
</html>
|
||||
110
accessible/tests/mochitest/events/test_dragndrop.html
Normal file
110
accessible/tests/mochitest/events/test_dragndrop.html
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible drag and drop event 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="../events.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../attributes.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
|
||||
// aria grabbed invoker
|
||||
function changeGrabbed(aNodeOrID, aGrabValue)
|
||||
{
|
||||
this.DOMNode = getNode(aNodeOrID);
|
||||
|
||||
this.invoke = function changeGrabbed_invoke() {
|
||||
if (aGrabValue != undefined) {
|
||||
this.DOMNode.setAttribute("aria-grabbed", aGrabValue);
|
||||
}
|
||||
}
|
||||
|
||||
this.check = function changeGrabbed_check() {
|
||||
testAttrs(aNodeOrID, {"grabbed" : aGrabValue}, true);
|
||||
}
|
||||
|
||||
this.getID = function changeGrabbed_getID() {
|
||||
return prettyName(aNodeOrID) + " aria-grabbed changed";
|
||||
}
|
||||
}
|
||||
|
||||
// aria dropeffect invoker
|
||||
function changeDropeffect(aNodeOrID, aDropeffectValue)
|
||||
{
|
||||
this.DOMNode = getNode(aNodeOrID);
|
||||
|
||||
this.invoke = function changeDropeffect_invoke() {
|
||||
if (aDropeffectValue != undefined) {
|
||||
this.DOMNode.setAttribute("aria-dropeffect", aDropeffectValue);
|
||||
}
|
||||
}
|
||||
|
||||
this.check = function changeDropeffect_check() {
|
||||
testAttrs(aNodeOrID, {"dropeffect" : aDropeffectValue}, true);
|
||||
}
|
||||
|
||||
this.getID = function changeDropeffect_getID() {
|
||||
return prettyName(aNodeOrID) + " aria-dropeffect changed";
|
||||
}
|
||||
}
|
||||
|
||||
function doTests()
|
||||
{
|
||||
// Test aria attribute mutation events
|
||||
gQueue = new eventQueue(nsIAccessibleEvent.EVENT_OBJECT_ATTRIBUTE_CHANGED);
|
||||
|
||||
var id="grabbable";
|
||||
gQueue.push(new changeGrabbed(id, "true"));
|
||||
gQueue.push(new changeGrabbed(id, "false"));
|
||||
todo(false, "uncomment this test when 472142 is fixed.");
|
||||
//gQueue.push(new changeGrabbed(id, "undefined"));
|
||||
|
||||
var id="dropregion";
|
||||
gQueue.push(new changeDropeffect(id, "copy"));
|
||||
gQueue.push(new changeDropeffect(id, "execute"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=510441"
|
||||
title="Add support for nsIAccessibleEvent::OBJECT_ATTRIBUTE_CHANGED">
|
||||
Mozilla Bug 510441
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<!-- ARIA grabbed -->
|
||||
<div id="grabbable" role="button" aria-grabbed="foo">button</div>
|
||||
|
||||
<!-- ARIA dropeffect -->
|
||||
<div id="dropregion" role="region" aria-dropeffect="none">button</div>
|
||||
</body>
|
||||
</html>
|
||||
77
accessible/tests/mochitest/events/test_flush.html
Normal file
77
accessible/tests/mochitest/events/test_flush.html
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Flush delayed events 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="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
SimpleTest.expectAssertions(0, 1);
|
||||
|
||||
var gFocusHandler = {
|
||||
handleEvent: function(aEvent) {
|
||||
switch (this.count) {
|
||||
case 0:
|
||||
is(aEvent.DOMNode, getNode("input1"),
|
||||
"Focus event for input1 was expected!");
|
||||
getAccessible("input2").takeFocus();
|
||||
break;
|
||||
|
||||
case 1:
|
||||
is(aEvent.DOMNode, getNode("input2"),
|
||||
"Focus event for input2 was expected!");
|
||||
|
||||
unregisterA11yEventListener(EVENT_FOCUS, gFocusHandler);
|
||||
SimpleTest.finish();
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "Wrong focus event!");
|
||||
}
|
||||
|
||||
this.count++;
|
||||
},
|
||||
|
||||
count: 0
|
||||
};
|
||||
|
||||
function doTests()
|
||||
{
|
||||
registerA11yEventListener(EVENT_FOCUS, gFocusHandler);
|
||||
|
||||
getAccessible("input1").takeFocus();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=477551"
|
||||
title="DocAccessible::FlushPendingEvents isn't robust">
|
||||
Mozilla Bug 477551
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<input id="input1">
|
||||
<input id="input2">
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=429547
|
||||
-->
|
||||
<head>
|
||||
<title>aria-activedescendant focus tests</title>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
//gA11yEventDumpToConsole = true; // debugging
|
||||
|
||||
function changeARIAActiveDescendant(aID, aItemID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new focusChecker(aItemID)
|
||||
];
|
||||
|
||||
this.invoke = function changeARIAActiveDescendant_invoke()
|
||||
{
|
||||
getNode(aID).setAttribute("aria-activedescendant", aItemID);
|
||||
}
|
||||
|
||||
this.getID = function changeARIAActiveDescendant_getID()
|
||||
{
|
||||
return "change aria-activedescendant on " + aItemID;
|
||||
}
|
||||
}
|
||||
|
||||
function insertItemNFocus(aID, aNewItemID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, aNewItemID),
|
||||
new focusChecker(aNewItemID)
|
||||
];
|
||||
|
||||
this.invoke = function insertItemNFocus_invoke()
|
||||
{
|
||||
var container = getNode(aID);
|
||||
var itemNode = document.createElement("div");
|
||||
itemNode.setAttribute("id", aNewItemID);
|
||||
itemNode.textContent = aNewItemID;
|
||||
container.appendChild(itemNode);
|
||||
|
||||
container.setAttribute("aria-activedescendant", aNewItemID);
|
||||
}
|
||||
|
||||
this.getID = function insertItemNFocus_getID()
|
||||
{
|
||||
return "insert new node and focus it with ID: " + aNewItemID;
|
||||
}
|
||||
}
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new synthFocus("listbox", new focusChecker("item1")));
|
||||
gQueue.push(new changeARIAActiveDescendant("listbox", "item2"));
|
||||
gQueue.push(new changeARIAActiveDescendant("listbox", "item3"));
|
||||
|
||||
gQueue.push(new synthFocus("combobox_entry", new focusChecker("combobox_entry")));
|
||||
gQueue.push(new changeARIAActiveDescendant("combobox", "combobox_option2"));
|
||||
|
||||
todo(false, "No focus for inserted element, bug 687011");
|
||||
//gQueue.push(new insertItemNFocus("listbox", "item4"));
|
||||
|
||||
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=429547"
|
||||
title="Support aria-activedescendant usage in nsIAccesible::TakeFocus()">
|
||||
Mozilla Bug 429547
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=761102"
|
||||
title="Focus may be missed when ARIA active-descendant is changed on active composite widget">
|
||||
Mozilla Bug 761102
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div role="listbox" aria-activedescendant="item1" id="listbox" tabindex="1"
|
||||
aria-owns="item3">
|
||||
<div role="listitem" id="item1">item1</div>
|
||||
<div role="listitem" id="item2">item2</div>
|
||||
</div>
|
||||
<div role="listitem" id="item3">item3</div>
|
||||
|
||||
<div role="combobox" id="combobox">
|
||||
<input id="combobox_entry">
|
||||
<ul>
|
||||
<li role="option" id="combobox_option1">option1</li>
|
||||
<li role="option" id="combobox_option2">option2</li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
518
accessible/tests/mochitest/events/test_focus_autocomplete.xul
Normal file
518
accessible/tests/mochitest/events/test_focus_autocomplete.xul
Normal file
|
|
@ -0,0 +1,518 @@
|
|||
<?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="Accessible focus event testing">
|
||||
|
||||
<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="../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"
|
||||
src="../autocomplete.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Hacky stuffs
|
||||
|
||||
// This is the hacks needed to use a searchbar without browser.js.
|
||||
function getBrowser()
|
||||
{
|
||||
return {
|
||||
mCurrentBrowser: { engines: new Array() }
|
||||
};
|
||||
}
|
||||
|
||||
var BrowserSearch = {
|
||||
updateOpenSearchBadge: function() {}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function loadFormAutoComplete(aIFrameID)
|
||||
{
|
||||
this.iframeNode = getNode(aIFrameID);
|
||||
this.iframe = getAccessible(aIFrameID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, this.iframe)
|
||||
];
|
||||
|
||||
this.invoke = function loadFormAutoComplete_invoke()
|
||||
{
|
||||
var url = "data:text/html,<html><body><form id='form'>" +
|
||||
"<input id='input' name='a11ytest-formautocomplete'>" +
|
||||
"</form></body></html>";
|
||||
this.iframeNode.setAttribute("src", url);
|
||||
}
|
||||
|
||||
this.getID = function loadFormAutoComplete_getID()
|
||||
{
|
||||
return "load form autocomplete page";
|
||||
}
|
||||
}
|
||||
|
||||
function initFormAutoCompleteBy(aIFrameID, aAutoCompleteValue)
|
||||
{
|
||||
this.iframe = getAccessible(aIFrameID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, this.iframe)
|
||||
];
|
||||
|
||||
this.invoke = function initFormAutoCompleteBy_invoke()
|
||||
{
|
||||
var iframeDOMDoc = getIFrameDOMDoc(aIFrameID);
|
||||
|
||||
var inputNode = iframeDOMDoc.getElementById("input");
|
||||
inputNode.value = aAutoCompleteValue;
|
||||
var formNode = iframeDOMDoc.getElementById("form");
|
||||
formNode.submit();
|
||||
}
|
||||
|
||||
this.getID = function initFormAutoCompleteBy_getID()
|
||||
{
|
||||
return "init form autocomplete by '" + aAutoCompleteValue + "'";
|
||||
}
|
||||
}
|
||||
|
||||
function loadHTML5ListAutoComplete(aIFrameID)
|
||||
{
|
||||
this.iframeNode = getNode(aIFrameID);
|
||||
this.iframe = getAccessible(aIFrameID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, this.iframe)
|
||||
];
|
||||
|
||||
this.invoke = function loadHTML5ListAutoComplete_invoke()
|
||||
{
|
||||
var url = "data:text/html,<html><body>" +
|
||||
"<datalist id='cities'><option>hello</option><option>hi</option></datalist>" +
|
||||
"<input id='input' list='cities'>" +
|
||||
"</body></html>";
|
||||
this.iframeNode.setAttribute("src", url);
|
||||
}
|
||||
|
||||
this.getID = function loadHTML5ListAutoComplete_getID()
|
||||
{
|
||||
return "load HTML5 list autocomplete page";
|
||||
}
|
||||
}
|
||||
|
||||
function removeChar(aID, aCheckerOrEventSeq)
|
||||
{
|
||||
this.__proto__ = new synthAction(aID, aCheckerOrEventSeq);
|
||||
|
||||
this.invoke = function removeChar_invoke()
|
||||
{
|
||||
synthesizeKey("VK_LEFT", { shiftKey: true });
|
||||
synthesizeKey("VK_DELETE", {});
|
||||
}
|
||||
|
||||
this.getID = function removeChar_getID()
|
||||
{
|
||||
return "remove char on " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function replaceOnChar(aID, aChar, aCheckerOrEventSeq)
|
||||
{
|
||||
this.__proto__ = new synthAction(aID, aCheckerOrEventSeq);
|
||||
|
||||
this.invoke = function replaceOnChar_invoke()
|
||||
{
|
||||
this.DOMNode.select();
|
||||
synthesizeKey(aChar, {});
|
||||
}
|
||||
|
||||
this.getID = function replaceOnChar_getID()
|
||||
{
|
||||
return "replace on char '" + aChar + "' for" + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function focusOnMouseOver(aIDFunc, aIDFuncArg)
|
||||
{
|
||||
this.eventSeq = [ new focusChecker(aIDFunc, aIDFuncArg) ];
|
||||
|
||||
this.invoke = function focusOnMouseOver_invoke()
|
||||
{
|
||||
this.id = aIDFunc.call(null, aIDFuncArg);
|
||||
this.node = getNode(this.id);
|
||||
this.window = this.node.ownerDocument.defaultView;
|
||||
|
||||
if (this.node.localName == "tree") {
|
||||
var tree = getAccessible(this.node);
|
||||
var accessible = getAccessible(this.id);
|
||||
if (tree != accessible) {
|
||||
var itemX = {}, itemY = {}, treeX = {}, treeY = {};
|
||||
accessible.getBounds(itemX, itemY, {}, {});
|
||||
tree.getBounds(treeX, treeY, {}, {});
|
||||
this.x = itemX.value - treeX.value;
|
||||
this.y = itemY.value - treeY.value;
|
||||
}
|
||||
}
|
||||
|
||||
// Generate mouse move events in timeouts until autocomplete popup list
|
||||
// doesn't have it, the reason is do that because autocomplete popup
|
||||
// ignores mousemove events firing in too short range.
|
||||
synthesizeMouse(this.node, this.x, this.y, { type: "mousemove" });
|
||||
this.doMouseMoveFlood(this);
|
||||
}
|
||||
|
||||
this.finalCheck = function focusOnMouseOver_getID()
|
||||
{
|
||||
this.isFlooding = false;
|
||||
}
|
||||
|
||||
this.getID = function focusOnMouseOver_getID()
|
||||
{
|
||||
return "mouse over on " + prettyName(aIDFunc.call(null, aIDFuncArg));
|
||||
}
|
||||
|
||||
this.doMouseMoveFlood = function focusOnMouseOver_doMouseMoveFlood(aThis)
|
||||
{
|
||||
synthesizeMouse(aThis.node, aThis.x + 1, aThis.y + 1,
|
||||
{ type: "mousemove" }, aThis.window);
|
||||
|
||||
if (aThis.isFlooding)
|
||||
aThis.window.setTimeout(aThis.doMouseMoveFlood, 0, aThis);
|
||||
}
|
||||
|
||||
this.id = null;
|
||||
this.node = null;
|
||||
this.window = null;
|
||||
|
||||
this.isFlooding = true;
|
||||
this.x = 1;
|
||||
this.y = 1;
|
||||
}
|
||||
|
||||
function selectByClick(aIDFunc, aIDFuncArg,
|
||||
aFocusTargetFunc, aFocusTargetFuncArg)
|
||||
{
|
||||
this.eventSeq = [ new focusChecker(aFocusTargetFunc, aFocusTargetFuncArg) ];
|
||||
|
||||
this.invoke = function selectByClick_invoke()
|
||||
{
|
||||
var id = aIDFunc.call(null, aIDFuncArg);
|
||||
var node = getNode(id);
|
||||
var targetWindow = node.ownerDocument.defaultView;
|
||||
|
||||
var x = 0, y = 0;
|
||||
if (node.localName == "tree") {
|
||||
var tree = getAccessible(node);
|
||||
var accessible = getAccessible(id);
|
||||
if (tree != accessible) {
|
||||
var itemX = {}, itemY = {}, treeX = {}, treeY = {};
|
||||
accessible.getBounds(itemX, itemY, {}, {});
|
||||
tree.getBounds(treeX, treeY, {}, {});
|
||||
x = itemX.value - treeX.value;
|
||||
y = itemY.value - treeY.value;
|
||||
}
|
||||
}
|
||||
|
||||
synthesizeMouseAtCenter(node, {}, targetWindow);
|
||||
}
|
||||
|
||||
this.getID = function selectByClick_getID()
|
||||
{
|
||||
return "select by click " + prettyName(aIDFunc.call(null, aIDFuncArg));
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Target getters
|
||||
|
||||
function getItem(aItemObj)
|
||||
{
|
||||
var autocomplete = aItemObj.autocomplete;
|
||||
var autocompleteNode = aItemObj.autocompleteNode;
|
||||
|
||||
// XUL searchbar
|
||||
if (autocompleteNode.localName == "searchbar") {
|
||||
var popupNode = autocompleteNode._popup;
|
||||
if (popupNode) {
|
||||
var list = getAccessible(popupNode);
|
||||
return list.getChildAt(aItemObj.index);
|
||||
}
|
||||
}
|
||||
|
||||
// XUL autocomplete
|
||||
var popupNode = autocompleteNode.popup;
|
||||
if (!popupNode) {
|
||||
// HTML form autocomplete
|
||||
var controller = Components.classes["@mozilla.org/autocomplete/controller;1"].
|
||||
getService(Components.interfaces.nsIAutoCompleteController);
|
||||
popupNode = controller.input.popup.QueryInterface(nsIDOMNode);
|
||||
}
|
||||
|
||||
if (popupNode) {
|
||||
if ("richlistbox" in popupNode) {
|
||||
var list = getAccessible(popupNode.richlistbox);
|
||||
return list.getChildAt(aItemObj.index);
|
||||
}
|
||||
|
||||
var list = getAccessible(popupNode.tree);
|
||||
return list.getChildAt(aItemObj.index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
function getTextEntry(aID)
|
||||
{
|
||||
// For form autocompletes the autocomplete widget and text entry widget
|
||||
// is the same widget, for XUL autocompletes the text entry is a first
|
||||
// child.
|
||||
var localName = getNode(aID).localName;
|
||||
|
||||
// XUL autocomplete
|
||||
if (localName == "textbox")
|
||||
return getAccessible(aID).firstChild;
|
||||
|
||||
// HTML form autocomplete
|
||||
if (localName == "input")
|
||||
return getAccessible(aID);
|
||||
|
||||
// XUL searchbar
|
||||
if (localName == "searchbar")
|
||||
return getAccessible(getNode(aID).textbox.inputField);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function itemObj(aID, aIdx)
|
||||
{
|
||||
this.autocompleteNode = getNode(aID);
|
||||
|
||||
this.autocomplete = this.autocompleteNode.localName == "searchbar" ?
|
||||
getAccessible(this.autocompleteNode.textbox) :
|
||||
getAccessible(this.autocompleteNode);
|
||||
|
||||
this.index = aIdx;
|
||||
}
|
||||
|
||||
function getIFrameDOMDoc(aIFrameID)
|
||||
{
|
||||
return getNode(aIFrameID).contentDocument;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test helpers
|
||||
|
||||
function queueAutoCompleteTests(aID)
|
||||
{
|
||||
// focus autocomplete text entry
|
||||
gQueue.push(new synthFocus(aID, new focusChecker(getTextEntry, aID)));
|
||||
|
||||
// open autocomplete popup
|
||||
gQueue.push(new synthDownKey(aID, new nofocusChecker()));
|
||||
|
||||
// select second option ('hi' option), focus on it
|
||||
gQueue.push(new synthUpKey(aID,
|
||||
new focusChecker(getItem, new itemObj(aID, 1))));
|
||||
|
||||
// choose selected option, focus on text entry
|
||||
gQueue.push(new synthEnterKey(aID, new focusChecker(getTextEntry, aID)));
|
||||
|
||||
// remove char, autocomplete popup appears
|
||||
gQueue.push(new removeChar(aID, new nofocusChecker()));
|
||||
|
||||
// select first option ('hello' option), focus on it
|
||||
gQueue.push(new synthDownKey(aID,
|
||||
new focusChecker(getItem, new itemObj(aID, 0))));
|
||||
|
||||
// mouse move on second option ('hi' option), focus on it
|
||||
gQueue.push(new focusOnMouseOver(getItem, new itemObj(aID, 1)));
|
||||
|
||||
// autocomplete popup updated (no selected item), focus on textentry
|
||||
gQueue.push(new synthKey(aID, "e", null, new focusChecker(getTextEntry, aID)));
|
||||
|
||||
// select first option ('hello' option), focus on it
|
||||
gQueue.push(new synthDownKey(aID,
|
||||
new focusChecker(getItem, new itemObj(aID, 0))));
|
||||
|
||||
// popup gets hidden, focus on textentry
|
||||
gQueue.push(new synthRightKey(aID, new focusChecker(getTextEntry, aID)));
|
||||
|
||||
// popup gets open, no focus
|
||||
gQueue.push(new synthOpenComboboxKey(aID, new nofocusChecker()));
|
||||
|
||||
// select first option again ('hello' option), focus on it
|
||||
gQueue.push(new synthDownKey(aID,
|
||||
new focusChecker(getItem, new itemObj(aID, 0))));
|
||||
|
||||
// no option is selected, focus on text entry
|
||||
gQueue.push(new synthUpKey(aID, new focusChecker(getTextEntry, aID)));
|
||||
|
||||
// close popup, no focus
|
||||
gQueue.push(new synthEscapeKey(aID, new nofocusChecker()));
|
||||
|
||||
// autocomplete popup appears (no selected item), focus stays on textentry
|
||||
gQueue.push(new replaceOnChar(aID, "h", new nofocusChecker()));
|
||||
|
||||
// mouse move on first option ('hello' option), focus on it
|
||||
gQueue.push(new focusOnMouseOver(getItem, new itemObj(aID, 0)));
|
||||
|
||||
// click first option ('hello' option), popup closes, focus on text entry
|
||||
gQueue.push(new selectByClick(getItem, new itemObj(aID, 0), getTextEntry, aID));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Tests
|
||||
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gInitQueue = null;
|
||||
function initTests()
|
||||
{
|
||||
if (SEAMONKEY || MAC) {
|
||||
todo(false, "Skipping this test on SeaMonkey ftb. (Bug 718237), and on Mac (bug 746177)");
|
||||
shutdownAutoComplete();
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
gInitQueue = new eventQueue();
|
||||
gInitQueue.push(new loadFormAutoComplete("iframe"));
|
||||
gInitQueue.push(new initFormAutoCompleteBy("iframe", "hello"));
|
||||
gInitQueue.push(new initFormAutoCompleteBy("iframe", "hi"));
|
||||
gInitQueue.push(new loadHTML5ListAutoComplete("iframe2"));
|
||||
gInitQueue.onFinish = function initQueue_onFinish()
|
||||
{
|
||||
SimpleTest.executeSoon(doTests);
|
||||
return DO_NOT_FINISH_TEST;
|
||||
}
|
||||
gInitQueue.invoke();
|
||||
}
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
// Test focus events.
|
||||
gQueue = new eventQueue();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// tree popup autocomplete tests
|
||||
queueAutoCompleteTests("autocomplete");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// richlistbox popup autocomplete tests
|
||||
queueAutoCompleteTests("richautocomplete");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// HTML form autocomplete tests
|
||||
queueAutoCompleteTests(getIFrameDOMDoc("iframe").getElementById("input"));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// HTML5 list autocomplete tests
|
||||
queueAutoCompleteTests(getIFrameDOMDoc("iframe2").getElementById("input"));
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// searchbar tests
|
||||
|
||||
// focus searchbar, focus on text entry
|
||||
gQueue.push(new synthFocus("searchbar",
|
||||
new focusChecker(getTextEntry, "searchbar")));
|
||||
// open search engine popup, no focus
|
||||
gQueue.push(new synthOpenComboboxKey("searchbar", new nofocusChecker()));
|
||||
// select first item, focus on it
|
||||
gQueue.push(new synthDownKey("searchbar",
|
||||
new focusChecker(getItem, new itemObj("searchbar", 0))));
|
||||
// mouse over on second item, focus on it
|
||||
gQueue.push(new focusOnMouseOver(getItem, new itemObj("searchbar", 1)));
|
||||
// press enter key, focus on text entry
|
||||
gQueue.push(new synthEnterKey("searchbar",
|
||||
new focusChecker(getTextEntry, "searchbar")));
|
||||
// click on search button, open popup, focus goes to document
|
||||
var searchBtn = getAccessible(getNode("searchbar").searchButton);
|
||||
gQueue.push(new synthClick(searchBtn, new focusChecker(document)));
|
||||
// select first item, focus on it
|
||||
gQueue.push(new synthDownKey("searchbar",
|
||||
new focusChecker(getItem, new itemObj("searchbar", 0))));
|
||||
// close popup, focus goes on document
|
||||
gQueue.push(new synthEscapeKey("searchbar", new focusChecker(document)));
|
||||
|
||||
gQueue.onFinish = function()
|
||||
{
|
||||
// unregister 'test-a11y-search' autocomplete search
|
||||
shutdownAutoComplete();
|
||||
}
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
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(initTests);
|
||||
]]>
|
||||
</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=383759"
|
||||
title="Focus event inconsistent for search box autocomplete">
|
||||
Mozilla Bug 383759
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=673958"
|
||||
title="Rework accessible focus handling">
|
||||
Mozilla Bug 673958
|
||||
</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">
|
||||
Mozilla Bug 559766
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<textbox id="autocomplete" type="autocomplete"
|
||||
autocompletesearch="test-a11y-search"/>
|
||||
|
||||
<textbox id="richautocomplete" type="autocomplete"
|
||||
autocompletesearch="test-a11y-search"
|
||||
autocompletepopup="richpopup"/>
|
||||
<panel id="richpopup" type="autocomplete-richlistbox" noautofocus="true"/>
|
||||
|
||||
<iframe id="iframe"/>
|
||||
|
||||
<iframe id="iframe2"/>
|
||||
|
||||
<searchbar id="searchbar"/>
|
||||
|
||||
<vbox id="eventdump"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
||||
149
accessible/tests/mochitest/events/test_focus_browserui.xul
Normal file
149
accessible/tests/mochitest/events/test_focus_browserui.xul
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
<?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="Accessibility Loading Document Events Test.">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../browser.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
function inputInDocument()
|
||||
{
|
||||
var tabdoc = currentTabDocument();
|
||||
return tabdoc.getElementById("input");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function loadURI(aURI)
|
||||
{
|
||||
this.invoke = function loadURI_invoke()
|
||||
{
|
||||
tabBrowser().loadURI(aURI);
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new focusChecker(currentTabDocument)
|
||||
];
|
||||
|
||||
this.getID = function loadURI_getID()
|
||||
{
|
||||
return "load uri " + aURI;
|
||||
}
|
||||
}
|
||||
|
||||
function goBack()
|
||||
{
|
||||
this.invoke = function goBack_invoke()
|
||||
{
|
||||
tabBrowser().goBack();
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new focusChecker(inputInDocument)
|
||||
];
|
||||
|
||||
this.getID = function goBack_getID()
|
||||
{
|
||||
return "go back one page in history ";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Testing
|
||||
|
||||
var gInputDocURI = "data:text/html,<html><input id='input'></html>";
|
||||
var gButtonDocURI = "data:text/html,<html><input id='input' type='button' value='button'></html>";
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debug
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
var tabDocument = currentTabDocument();
|
||||
var input = inputInDocument();
|
||||
|
||||
// move focus to input inside tab document
|
||||
gQueue.push(new synthTab(tabDocument, new focusChecker(input),
|
||||
browserWindow()));
|
||||
|
||||
// open new url, focus moves to new document
|
||||
gQueue.push(new loadURI(gButtonDocURI));
|
||||
|
||||
// back one page in history, moves moves on input of tab document
|
||||
gQueue.push(new goBack());
|
||||
|
||||
// open new tab, focus moves to urlbar
|
||||
gQueue.push(new synthKey(tabDocument, "t", { accelKey: true, window: browserWindow() },
|
||||
new focusChecker(urlbarInput)));
|
||||
|
||||
// close open tab, focus goes on input of tab document
|
||||
gQueue.push(new synthKey(tabDocument, "w", { accelKey: true, window: browserWindow() },
|
||||
new focusChecker(inputInDocument)));
|
||||
|
||||
gQueue.onFinish = function()
|
||||
{
|
||||
closeBrowserWindow();
|
||||
}
|
||||
gQueue.invoke();
|
||||
}
|
||||
|
||||
if (navigator.oscpu.startsWith("Windows NT 6.1") || navigator.oscpu.startsWith("Windows NT 6.2")) {
|
||||
todo(false, "fix the leak!");
|
||||
} else {
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
openBrowserWindow(doTests, gInputDocURI);
|
||||
}
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<vbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=644452"
|
||||
title="Focus not set when switching to cached document with back or forward if anything other than the document was last focused">
|
||||
Mozilla Bug 644452
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=665412"
|
||||
title="Broken focus when returning to editable text field after closing a tab while focused in the Navigation toolbar">
|
||||
Mozilla Bug 665412
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=673958"
|
||||
title="Rework accessible focus handling">
|
||||
Mozilla Bug 673958
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox id="eventdump"></vbox>
|
||||
</vbox>
|
||||
</window>
|
||||
61
accessible/tests/mochitest/events/test_focus_canvas.html
Normal file
61
accessible/tests/mochitest/events/test_focus_canvas.html
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible focus testing in canvas subdom</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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new synthFocus("button"));
|
||||
gQueue.push(new synthTab("button", new focusChecker("textbox")));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a target="_blank"
|
||||
title="Expose content in Canvas element"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=495912">
|
||||
Mozilla Bug 495912
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<canvas>
|
||||
<input id="button" type="button">
|
||||
<input id="textbox">
|
||||
</canvas>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
99
accessible/tests/mochitest/events/test_focus_contextmenu.xul
Normal file
99
accessible/tests/mochitest/events/test_focus_contextmenu.xul
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
<?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="Context nenu focus testing">
|
||||
|
||||
<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="../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">
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var winLowerThanVista = navigator.platform.indexOf("Win") == 0;
|
||||
if (winLowerThanVista) {
|
||||
var version = Components.classes["@mozilla.org/system-info;1"]
|
||||
.getService(Components.interfaces.nsIPropertyBag2)
|
||||
.getProperty("version");
|
||||
version = parseFloat(version);
|
||||
winLowerThanVista = !(version >= 6.0);
|
||||
}
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
// bug 746183 - Whole file times out on OS X
|
||||
if (MAC || winLowerThanVista) {
|
||||
todo(false, "Reenable on mac after fixing bug 746183!");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// Test focus events.
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new synthFocus("button"));
|
||||
gQueue.push(new synthContextMenu("button",
|
||||
new invokerChecker(EVENT_MENUPOPUP_START, "contextmenu")));
|
||||
gQueue.push(new synthEscapeKey("contextmenu", new focusChecker("button")));
|
||||
|
||||
gQueue.push(new synthContextMenu("button",
|
||||
new invokerChecker(EVENT_MENUPOPUP_START, "contextmenu")));
|
||||
gQueue.push(new synthDownKey("contextmenu", new focusChecker("item1")));
|
||||
gQueue.push(new synthDownKey("item1", new focusChecker("item2")));
|
||||
gQueue.push(new synthRightKey("item2", new focusChecker("item2.1")));
|
||||
if (WIN) {
|
||||
todo(false, "synthEscapeKey for item2.1 and item2 disabled due to bug 691580");
|
||||
} else {
|
||||
gQueue.push(new synthEscapeKey("item2.1", new focusChecker("item2")));
|
||||
gQueue.push(new synthEscapeKey("item2", new focusChecker("button")));
|
||||
}
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</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=673958"
|
||||
title="Rework accessible focus handling">
|
||||
Mozilla Bug 673958
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<button id="button" context="contextmenu" label="button"/>
|
||||
<menupopup id="contextmenu">
|
||||
<menuitem id="item1" label="item1"/>
|
||||
<menu id="item2" label="item2">
|
||||
<menupopup>
|
||||
<menuitem id="item2.1" label="item2.1"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
|
||||
<vbox id="eventdump"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
||||
75
accessible/tests/mochitest/events/test_focus_controls.html
Normal file
75
accessible/tests/mochitest/events/test_focus_controls.html
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible focus testing on HTML controls</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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue(EVENT_FOCUS);
|
||||
|
||||
gQueue.push(new synthFocus("textbox"));
|
||||
gQueue.push(new synthFocus("textarea"));
|
||||
gQueue.push(new synthFocus("button1"));
|
||||
gQueue.push(new synthFocus("button2"));
|
||||
gQueue.push(new synthFocus("checkbox"));
|
||||
gQueue.push(new synthFocus("radio1"));
|
||||
gQueue.push(new synthDownKey("radio1", new focusChecker("radio2")));
|
||||
|
||||
// no focus events for checkbox or radio inputs when they are checked
|
||||
// programmatically
|
||||
gQueue.push(new changeCurrentItem("checkbox"));
|
||||
gQueue.push(new changeCurrentItem("radio1"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=673958"
|
||||
title="Rework accessible focus handling">
|
||||
Mozilla Bug 673958
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<input id="textbox">
|
||||
<textarea id="textarea"></textarea>
|
||||
|
||||
<input id="button1" type="button" value="button">
|
||||
<button id="button2">button</button>
|
||||
<input id="checkbox" type="checkbox">
|
||||
<input id="radio1" type="radio" name="radiogroup">
|
||||
<input id="radio2" type="radio" name="radiogroup">
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
164
accessible/tests/mochitest/events/test_focus_dialog.html
Normal file
164
accessible/tests/mochitest/events/test_focus_dialog.html
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible focus 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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function openCloseDialog(aID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new focusChecker(getNode(aID))
|
||||
];
|
||||
|
||||
this.invoke = function openCloseDialog_invoke()
|
||||
{
|
||||
var wnd = window.open("focus.html");
|
||||
wnd.close();
|
||||
}
|
||||
|
||||
this.getID = function openCloseDialog_getID()
|
||||
{
|
||||
return "Open close dialog while focus on " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
var gDialogWnd = null;
|
||||
function getDialogDocument()
|
||||
{
|
||||
return gDialogWnd.document;
|
||||
}
|
||||
|
||||
function openDialog(aID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new focusChecker(getDialogDocument)
|
||||
];
|
||||
|
||||
this.invoke = function openDialog_invoke()
|
||||
{
|
||||
gDialogWnd = window.open("focus.html");
|
||||
}
|
||||
|
||||
this.getID = function openDialog_getID()
|
||||
{
|
||||
return "Open dialog while focus on " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function closeDialog(aID)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new focusChecker(aID)
|
||||
];
|
||||
|
||||
this.invoke = function closeDialog_invoke()
|
||||
{
|
||||
gDialogWnd.close();
|
||||
}
|
||||
|
||||
this.getID = function closeDialog_getID()
|
||||
{
|
||||
return "Close dialog while focus on " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function showNFocusAlertDialog()
|
||||
{
|
||||
this.ID = "alertdialog";
|
||||
this.DOMNode = getNode(this.ID);
|
||||
|
||||
this.invoke = function showNFocusAlertDialog_invoke()
|
||||
{
|
||||
document.getElementById(this.ID).style.display = 'block';
|
||||
document.getElementById(this.ID).focus();
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, this.DOMNode),
|
||||
new focusChecker(this.DOMNode)
|
||||
];
|
||||
|
||||
this.getID = function showNFocusAlertDialog_getID()
|
||||
{
|
||||
return "Show and focus alert dialog " + prettyName(this.ID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue(EVENT_FOCUS);
|
||||
|
||||
gQueue.push(new synthFocus("button"));
|
||||
gQueue.push(new openDialog("button"));
|
||||
gQueue.push(new closeDialog("button"));
|
||||
|
||||
var frameNode = getNode("editabledoc");
|
||||
gQueue.push(new synthFocusOnFrame(frameNode));
|
||||
gQueue.push(new openCloseDialog(frameNode.contentDocument));
|
||||
|
||||
gQueue.push(new showNFocusAlertDialog());
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=551679"
|
||||
title="focus is not fired for focused document when switching between windows">
|
||||
Mozilla Bug 551679
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=580464"
|
||||
title="Accessible focus incorrect after JS focus() but correct after switching apps or using menu bar">
|
||||
Mozilla Bug 580464
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<button id="button">button</button>
|
||||
<iframe id="editabledoc" src="focus.html"></iframe>
|
||||
|
||||
<div id="alertdialog" style="display: none" tabindex="-1" role="alertdialog" aria-labelledby="title2" aria-describedby="desc2">
|
||||
<div id="title2">Blah blah</div>
|
||||
<div id="desc2">Woof woof woof.</div>
|
||||
<button>Close</button>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
95
accessible/tests/mochitest/events/test_focus_doc.html
Normal file
95
accessible/tests/mochitest/events/test_focus_doc.html
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible document focus event 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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
var gQueue = null;
|
||||
|
||||
//var gA11yEventDumpID = "eventdump";
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
// setup
|
||||
var frameDoc = document.getElementById("iframe").contentDocument;
|
||||
frameDoc.designMode = "on";
|
||||
var frameDocAcc = getAccessible(frameDoc, [nsIAccessibleDocument]);
|
||||
var buttonAcc = getAccessible("b1");
|
||||
|
||||
var frame2Doc = document.getElementById("iframe2").contentDocument;
|
||||
var frame2Input = frame2Doc.getElementById("input");
|
||||
var frame2DocAcc = getAccessible(frame2Doc);
|
||||
var frame2InputAcc = getAccessible(frame2Input);
|
||||
|
||||
// Test focus events.
|
||||
gQueue = new eventQueue();
|
||||
|
||||
// try to give focus to contentEditable frame twice to cover bug 512059
|
||||
gQueue.push(new synthFocus(buttonAcc));
|
||||
gQueue.push(new synthTab(frameDocAcc, new focusChecker(frameDocAcc)));
|
||||
gQueue.push(new synthFocus(buttonAcc));
|
||||
gQueue.push(new synthTab(frameDocAcc, new focusChecker(frameDocAcc)));
|
||||
|
||||
// focus on not editable document
|
||||
gQueue.push(new synthFocus(frame2InputAcc));
|
||||
gQueue.push(new synthShiftTab(frame2DocAcc, new focusChecker(frame2DocAcc)));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=512058"
|
||||
title="Can't set focus to designMode document via accessibility APIs">
|
||||
Mozilla Bug 512058
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=512059"
|
||||
title="Accessibility focus event never fired for designMode document after the first focus">
|
||||
Mozilla Bug 512059
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=618046"
|
||||
title="No focus change event when Shift+Tab at top of screen">
|
||||
Mozilla Bug 618046
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<div id="testContainer">
|
||||
<button id="b1">a button</button>
|
||||
<iframe id="iframe" src="about:blank"></iframe>
|
||||
<button id="b2">a button</button>
|
||||
<iframe id="iframe2" src="data:text/html,<html><input id='input'></html>"></iframe>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
179
accessible/tests/mochitest/events/test_focus_general.html
Normal file
179
accessible/tests/mochitest/events/test_focus_general.html
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible focus 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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function focusElmWhileSubdocIsFocused(aID)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.invoke = function focusElmWhileSubdocIsFocused_invoke()
|
||||
{
|
||||
this.DOMNode.focus();
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new focusChecker(this.DOMNode)
|
||||
];
|
||||
|
||||
this.unexpectedEventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, this.DOMNode.ownerDocument)
|
||||
];
|
||||
|
||||
this.getID = function focusElmWhileSubdocIsFocused_getID()
|
||||
{
|
||||
return "Focus element while subdocument is focused " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function imageMapChecker(aID)
|
||||
{
|
||||
var node = getNode(aID);
|
||||
this.type = EVENT_FOCUS;
|
||||
this.match = function imageMapChecker_match(aEvent)
|
||||
{
|
||||
return aEvent.DOMNode == node;
|
||||
}
|
||||
}
|
||||
|
||||
function topMenuChecker()
|
||||
{
|
||||
this.type = EVENT_FOCUS;
|
||||
this.match = function topMenuChecker_match(aEvent)
|
||||
{
|
||||
return aEvent.accessible.role == ROLE_PARENT_MENUITEM;
|
||||
}
|
||||
}
|
||||
|
||||
function contextMenuChecker()
|
||||
{
|
||||
this.type = EVENT_MENUPOPUP_START;
|
||||
this.match = function contextMenuChecker_match(aEvent)
|
||||
{
|
||||
return aEvent.accessible.role == ROLE_MENUPOPUP;
|
||||
}
|
||||
}
|
||||
|
||||
function focusContextMenuItemChecker()
|
||||
{
|
||||
this.__proto__ = new focusChecker();
|
||||
|
||||
this.match = function focusContextMenuItemChecker_match(aEvent)
|
||||
{
|
||||
return aEvent.accessible.role == ROLE_MENUITEM;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
var frameDoc = document.getElementById("iframe").contentDocument;
|
||||
|
||||
var editableDoc = document.getElementById('editabledoc').contentDocument;
|
||||
editableDoc.designMode = 'on';
|
||||
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new synthFocus("editablearea"));
|
||||
gQueue.push(new synthFocus("navarea"));
|
||||
gQueue.push(new synthTab("navarea", new focusChecker(frameDoc)));
|
||||
gQueue.push(new focusElmWhileSubdocIsFocused("link"));
|
||||
|
||||
gQueue.push(new synthTab(editableDoc, new focusChecker(editableDoc)));
|
||||
if (WIN || LINUX) {
|
||||
// Alt key is used to active menubar and focus menu item on Windows,
|
||||
// other platforms requires setting a ui.key.menuAccessKeyFocuses
|
||||
// preference.
|
||||
gQueue.push(new toggleTopMenu(editableDoc, new topMenuChecker()));
|
||||
gQueue.push(new toggleTopMenu(editableDoc, new focusChecker(editableDoc)));
|
||||
}
|
||||
gQueue.push(new synthContextMenu(editableDoc, new contextMenuChecker()));
|
||||
gQueue.push(new synthDownKey(editableDoc, new focusContextMenuItemChecker()));
|
||||
gQueue.push(new synthEscapeKey(editableDoc, new focusChecker(editableDoc)));
|
||||
if (SEAMONKEY) {
|
||||
todo(false, "shift tab from editable document fails on (Windows) SeaMonkey! (Bug 718235)");
|
||||
} else {
|
||||
if (LINUX || MAC)
|
||||
todo(false, "shift tab from editable document fails on linux and Mac, bug 746519!");
|
||||
else
|
||||
gQueue.push(new synthShiftTab("link", new focusChecker("link")));
|
||||
} // ! SEAMONKEY
|
||||
|
||||
gQueue.push(new synthFocus("a", new imageMapChecker("a")));
|
||||
gQueue.push(new synthFocus("b", new imageMapChecker("b")));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=352220"
|
||||
title="Inconsistent focus events when returning to a document frame">
|
||||
Mozilla Bug 352220
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=550338"
|
||||
title="Broken focus when returning to editable documents from menus">
|
||||
Mozilla Bug 550338
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=673958"
|
||||
title="Rework accessible focus handling">
|
||||
Mozilla Bug 673958
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=961696"
|
||||
title="Accessible object:state-changed:focused events for imagemap links are broken">
|
||||
Mozilla Bug 961696
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="editablearea" contentEditable="true">editable area</div>
|
||||
<div id="navarea" tabindex="0">navigable area</div>
|
||||
<iframe id="iframe" src="data:text/html,<html></html>"></iframe>
|
||||
<a id="link" href="">link</a>
|
||||
<iframe id="editabledoc" src="about:blank"></iframe>
|
||||
|
||||
<map name="atoz_map">
|
||||
<area id="a" coords="0,0,13,14" shape="rect">
|
||||
<area id="b" coords="17,0,30,14" shape="rect">
|
||||
</map>
|
||||
<img width="447" height="15" usemap="#atoz_map" src="../letters.gif">
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
179
accessible/tests/mochitest/events/test_focus_general.xul
Normal file
179
accessible/tests/mochitest/events/test_focus_general.xul
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<?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 focus event testing">
|
||||
|
||||
<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="../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">
|
||||
function getColorBtn(aBtnObj)
|
||||
{
|
||||
var colorpicker = aBtnObj.colorpicker;
|
||||
var container = colorpicker.firstChild;
|
||||
var btn = container.getChildAt(aBtnObj.btnIndex);
|
||||
return btn;
|
||||
}
|
||||
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
// Test focus events.
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new synthFocus("textbox",
|
||||
new focusChecker(getNode("textbox").inputField)));
|
||||
gQueue.push(new synthFocus("textbox_multiline",
|
||||
new focusChecker(getNode("textbox_multiline").inputField)));
|
||||
gQueue.push(new synthFocus("scale"));
|
||||
gQueue.push(new synthFocusOnFrame("editabledoc"));
|
||||
gQueue.push(new synthFocus("radioclothes",
|
||||
new focusChecker("radiosweater")));
|
||||
gQueue.push(new synthDownKey("radiosweater",
|
||||
new focusChecker("radiojacket")));
|
||||
gQueue.push(new synthFocus("checkbox"));
|
||||
gQueue.push(new synthFocus("button"));
|
||||
gQueue.push(new synthFocus("checkbutton"));
|
||||
gQueue.push(new synthFocus("radiobutton"));
|
||||
|
||||
// focus menubutton
|
||||
gQueue.push(new synthFocus("menubutton"));
|
||||
// click menubutton, open popup, focus stays on menu button
|
||||
gQueue.push(new synthClick("menubutton", new nofocusChecker()));
|
||||
// select first menu item ("item 1"), focus on menu item
|
||||
gQueue.push(new synthDownKey("menubutton", new focusChecker("mb_item1")));
|
||||
// choose select menu item, focus gets back to menubutton
|
||||
gQueue.push(new synthEnterKey("mb_item1", new focusChecker("menubutton")));
|
||||
// press enter to open popup, focus stays on menubutton
|
||||
gQueue.push(new synthEnterKey("menubutton", new nofocusChecker()));
|
||||
// select second menu item ("item 2"), focus on menu item
|
||||
gQueue.push(new synthUpKey("menubutton", new focusChecker("mb_item2")));
|
||||
|
||||
// clicking on button having associated popup doesn't change a focus
|
||||
gQueue.push(new synthClick("popupbutton", new nofocusChecker()));
|
||||
// select first menu item ("item 1"), focus on menu item
|
||||
gQueue.push(new synthDownKey("popupbutton", new focusChecker("bp_item1")));
|
||||
// choose select menu item, focus gets back to menubutton
|
||||
gQueue.push(new synthEnterKey("bp_item1", new focusChecker("menubutton")));
|
||||
// show popup again for the next test
|
||||
gQueue.push(new synthClick("popupbutton", new nofocusChecker()));
|
||||
|
||||
if (!MAC) {
|
||||
// click menubutton of the 'menubutton' button while popup of button open.
|
||||
gQueue.push(new synthClick("mbb", new focusChecker("mbb"), { where: "right" }));
|
||||
// close popup, focus stays on menubutton, fire focus event
|
||||
gQueue.push(new synthEscapeKey("mbb", new focusChecker("mbb")));
|
||||
// click menubutton, open popup, focus stays on menubutton
|
||||
gQueue.push(new synthClick("mbb", new nofocusChecker(), { where: "right" }));
|
||||
// select first menu item ("item 1"), focus on menu item
|
||||
gQueue.push(new synthDownKey("mbb", new focusChecker("mbb_item1")));
|
||||
// choose select menu item, focus gets back to menubutton
|
||||
gQueue.push(new synthEnterKey("mbb_item1", new focusChecker("mbb")));
|
||||
// open popup, focus stays on menubutton
|
||||
gQueue.push(new synthOpenComboboxKey("mbb", new nofocusChecker()));
|
||||
// select second menu item ("item 2"), focus on menu item
|
||||
gQueue.push(new synthUpKey("menubutton", new focusChecker("mbb_item2")));
|
||||
// click on menu item of menubutton menu, focus menubutton
|
||||
gQueue.push(new synthClick("mbb_item2", new focusChecker("mbb")));
|
||||
} else {
|
||||
todo(false, "mbb tests time out on OS X, fix bug 746970 and reenable!");
|
||||
}
|
||||
|
||||
// focus colorpicker button
|
||||
gQueue.push(new synthFocus("colorpicker"));
|
||||
// click on button, open popup, focus goes to current color button
|
||||
var btnObj = { colorpicker: getAccessible("colorpicker"), btnIndex: 0 };
|
||||
var checker = new focusChecker(getColorBtn, btnObj);
|
||||
gQueue.push(new synthClick("colorpicker", checker));
|
||||
// select sibling color button, focus on it
|
||||
btnObj = { colorpicker: getAccessible("colorpicker"), btnIndex: 1 };
|
||||
var checker = new focusChecker(getColorBtn, btnObj);
|
||||
gQueue.push(new synthRightKey("colorpicker", checker));
|
||||
// choose selected color button, close popup, focus on colorpicker button
|
||||
gQueue.push(new synthEnterKey("colorpicker", new focusChecker("colorpicker")));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</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=492518"
|
||||
title="xul:slider accessible of xul:scale is accessible illegally">
|
||||
Mozilla Bug 492518
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=552368"
|
||||
title=" fire focus event on document accessible whenever the root or body element is focused">
|
||||
Mozilla Bug 552368
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<textbox id="textbox" value="hello"/>
|
||||
<textbox id="textbox_multiline" multiline="true" value="hello"/>
|
||||
<scale id="scale" min="0" max="9" value="5"/>
|
||||
<iframe id="editabledoc" src="focus.html"/>
|
||||
<radiogroup id="radioclothes">
|
||||
<radio id="radiosweater" label="radiosweater"/>
|
||||
<radio id="radiocap" label="radiocap" disabled="true"/>
|
||||
<radio id="radiojacket" label="radiojacket"/>
|
||||
</radiogroup>
|
||||
<checkbox id="checkbox" label="checkbox"/>
|
||||
<button id="button" label="button"/>
|
||||
<button id="checkbutton" type="checkbox" label="checkbutton"/>
|
||||
<button id="radiobutton" type="radio" group="rbgroup" label="radio1"/>
|
||||
|
||||
<button id="menubutton" type="menu" label="menubutton">
|
||||
<menupopup>
|
||||
<menuitem id="mb_item1" label="item1"/>
|
||||
<menuitem id="mb_item2" label="item2"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
<button id="mbb" type="menu-button" label="menubutton button">
|
||||
<menupopup>
|
||||
<menuitem id="mbb_item1" label="item1"/>
|
||||
<menuitem id="mbb_item2" label="item2"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
|
||||
<colorpicker id="colorpicker" type="button" label="color picker"
|
||||
color="#FFFFFF"/>
|
||||
|
||||
<popupset>
|
||||
<menupopup id="backpopup" position="after_start">
|
||||
<menuitem id="bp_item1" label="Page 1"/>
|
||||
<menuitem id="bp_item2" label="Page 2"/>
|
||||
</menupopup>
|
||||
</popupset>
|
||||
<button id="popupbutton" label="Pop Me Up" popup="backpopup"/>
|
||||
|
||||
<vbox id="eventdump"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
||||
189
accessible/tests/mochitest/events/test_focus_listcontrols.xul
Normal file
189
accessible/tests/mochitest/events/test_focus_listcontrols.xul
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
<?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 focus event testing">
|
||||
|
||||
<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="../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">
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
// Test focus events.
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new synthFocus("listbox", new focusChecker("lb_item1")));
|
||||
gQueue.push(new synthDownKey("lb_item1", new focusChecker("lb_item2")));
|
||||
gQueue.push(new synthTab("lb_item2", new focusChecker("mslb_item1")));
|
||||
gQueue.push(new synthDownKey("mslb_item1", new focusChecker("mslb_item2"), { shiftKey: true }));
|
||||
gQueue.push(new synthTab("mslb_item2", new focusChecker("emptylistbox")));
|
||||
gQueue.push(new synthFocus("mcolumnlistbox", new focusChecker("mclb_item1")));
|
||||
gQueue.push(new synthDownKey("mclb_item1", new focusChecker("mclb_item2")));
|
||||
gQueue.push(new synthFocus("headerlistbox", new focusChecker("hlb_item1")));
|
||||
gQueue.push(new synthDownKey("hlb_item1", new focusChecker("hlb_item2")));
|
||||
|
||||
gQueue.push(new synthFocus("richlistbox", new focusChecker("rlb_item1")));
|
||||
gQueue.push(new synthDownKey("rlb_item1", new focusChecker("rlb_item2")));
|
||||
gQueue.push(new synthFocus("multiselrichlistbox", new focusChecker("msrlb_item1")));
|
||||
gQueue.push(new synthDownKey("msrlb_item1", new focusChecker("msrlb_item2"), { shiftKey: true }));
|
||||
gQueue.push(new synthFocus("emptyrichlistbox", new focusChecker("emptyrichlistbox")));
|
||||
|
||||
gQueue.push(new synthFocus("menulist"));
|
||||
gQueue.push(new synthClick("menulist", new focusChecker("ml_tangerine")));
|
||||
gQueue.push(new synthDownKey("ml_tangerine", new focusChecker("ml_marmalade")));
|
||||
gQueue.push(new synthEscapeKey("ml_marmalade", new focusChecker("menulist")));
|
||||
if (!MAC) {
|
||||
// On Windows, items get selected during navigation.
|
||||
let expectedItem = WIN ? "ml_tangerine" : "ml_marmalade";
|
||||
gQueue.push(new synthDownKey("menulist", new nofocusChecker(expectedItem)));
|
||||
gQueue.push(new synthOpenComboboxKey("menulist", new focusChecker(expectedItem)));
|
||||
gQueue.push(new synthEnterKey(expectedItem, new focusChecker("menulist")));
|
||||
} else {
|
||||
todo(false, "Bug 746531 - timeouts of last three menulist tests on OS X");
|
||||
}
|
||||
|
||||
var textentry = getAccessible("emenulist").firstChild;
|
||||
gQueue.push(new synthFocus("emenulist", new focusChecker(textentry)));
|
||||
gQueue.push(new synthDownKey(textentry, new nofocusChecker("eml_tangerine")));
|
||||
gQueue.push(new synthUpKey(textentry, new focusChecker("eml_marmalade")));
|
||||
gQueue.push(new synthEnterKey("eml_marmalade", new focusChecker(textentry)));
|
||||
gQueue.push(new synthOpenComboboxKey("emenulist", new focusChecker("eml_marmalade")));
|
||||
gQueue.push(new synthEscapeKey("eml_marmalade", new focusChecker(textentry)));
|
||||
|
||||
// no focus events for unfocused list controls when current item is
|
||||
// changed.
|
||||
gQueue.push(new synthFocus("emptylistbox"));
|
||||
|
||||
gQueue.push(new changeCurrentItem("listbox", "lb_item1"));
|
||||
gQueue.push(new changeCurrentItem("richlistbox", "rlb_item1"));
|
||||
if (!MAC) {
|
||||
gQueue.push(new changeCurrentItem("menulist", WIN ? "ml_marmalade" : "ml_tangerine"));
|
||||
}
|
||||
gQueue.push(new changeCurrentItem("emenulist", "eml_tangerine"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</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=433418"
|
||||
title="Accessibles for focused HTML Select elements are not getting focused state">
|
||||
Mozilla Bug 433418
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=474893"
|
||||
title="List controls should fire a focus event on the selected child when tabbing or when the selected child changes while the list is focused">
|
||||
Mozilla Bug 474893
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=552368"
|
||||
title=" fire focus event on document accessible whenever the root or body element is focused">
|
||||
Mozilla Bug 552368
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<listbox id="listbox" rows="3">
|
||||
<listitem id="lb_item1" label="item1"/>
|
||||
<listitem id="lb_item2" label="item1"/>
|
||||
</listbox>
|
||||
<listbox id="multisellistbox" rows="3" seltype="multiple">
|
||||
<listitem id="mslb_item1" label="item1"/>
|
||||
<listitem id="mslb_item2" label="item1"/>
|
||||
</listbox>
|
||||
<listbox id="emptylistbox" rows="3"/>
|
||||
<listbox id="mcolumnlistbox" rows="3">
|
||||
<listcols>
|
||||
<listcol/>
|
||||
<listcol/>
|
||||
</listcols>
|
||||
<listitem id="mclb_item1">
|
||||
<listcell label="George"/>
|
||||
<listcell label="House Painter"/>
|
||||
</listitem>
|
||||
<listitem id="mclb_item2">
|
||||
<listcell label="Mary Ellen"/>
|
||||
<listcell label="Candle Maker"/>
|
||||
</listitem>
|
||||
</listbox>
|
||||
<listbox id="headerlistbox" rows="3">
|
||||
<listhead>
|
||||
<listheader label="Name"/>
|
||||
<listheader label="Occupation"/>
|
||||
</listhead>
|
||||
<listcols>
|
||||
<listcol/>
|
||||
<listcol flex="1"/>
|
||||
</listcols>
|
||||
<listitem id="hlb_item1">
|
||||
<listcell label="George"/>
|
||||
<listcell label="House Painter"/>
|
||||
</listitem>
|
||||
<listitem id="hlb_item2">
|
||||
<listcell label="Mary Ellen"/>
|
||||
<listcell label="Candle Maker"/>
|
||||
</listitem>
|
||||
</listbox>
|
||||
|
||||
<richlistbox id="richlistbox">
|
||||
<richlistitem id="rlb_item1">
|
||||
<description>A XUL Description!</description>
|
||||
</richlistitem>
|
||||
<richlistitem id="rlb_item2">
|
||||
<button label="A XUL Button"/>
|
||||
</richlistitem>
|
||||
</richlistbox>
|
||||
<richlistbox id="multiselrichlistbox" seltype="multiple">
|
||||
<richlistitem id="msrlb_item1">
|
||||
<description>A XUL Description!</description>
|
||||
</richlistitem>
|
||||
<richlistitem id="msrlb_item2">
|
||||
<button label="A XUL Button"/>
|
||||
</richlistitem>
|
||||
</richlistbox>
|
||||
<richlistbox id="emptyrichlistbox" seltype="multiple"/>
|
||||
|
||||
<menulist id="menulist">
|
||||
<menupopup>
|
||||
<menuitem id="ml_tangerine" label="tangerine trees"/>
|
||||
<menuitem id="ml_marmalade" label="marmalade skies"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<menulist id="emenulist" editable="true">
|
||||
<menupopup>
|
||||
<menuitem id="eml_tangerine" label="tangerine trees"/>
|
||||
<menuitem id="eml_marmalade" label="marmalade skies"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
|
||||
<vbox id="eventdump"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
||||
119
accessible/tests/mochitest/events/test_focus_menu.xul
Normal file
119
accessible/tests/mochitest/events/test_focus_menu.xul
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
<?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="Menu focus testing">
|
||||
|
||||
<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="../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">
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
// Test focus events.
|
||||
gQueue = new eventQueue();
|
||||
|
||||
if (WIN) {
|
||||
gQueue.push(new toggleTopMenu("fruit", new focusChecker("fruit")));
|
||||
gQueue.push(new synthRightKey("fruit", new focusChecker("vehicle")));
|
||||
gQueue.push(new synthEscapeKey("vehicle", new focusChecker(document)));
|
||||
}
|
||||
|
||||
// mouse move activate items but no focus event until menubar is active
|
||||
gQueue.push(new synthMouseMove("fruit", new nofocusChecker("apple")));
|
||||
|
||||
// mouseover and click on menuitem makes it active before menubar is
|
||||
// active
|
||||
gQueue.push(new synthClick("fruit", new focusChecker("fruit")));
|
||||
|
||||
// mouseover on menuitem when menubar is active
|
||||
gQueue.push(new synthMouseMove("apple", new focusChecker("apple")));
|
||||
|
||||
// keydown on disabled menuitem (disabled items are skipped on linux)
|
||||
if (WIN)
|
||||
gQueue.push(new synthDownKey("apple", new focusChecker("orange")));
|
||||
|
||||
// menu and menuitem are both active
|
||||
// XXX: intermitent failure because two focus events may be coalesced,
|
||||
// think to workaround or fix this issue, when done enable queue invoker
|
||||
// below and remove next two.
|
||||
//gQueue.push(new synthRightKey("apple",
|
||||
// [ new focusChecker("vehicle"),
|
||||
// new focusChecker("cycle")]));
|
||||
gQueue.push(new synthClick("vehicle", new focusChecker("vehicle")));
|
||||
gQueue.push(new synthDownKey("cycle", new focusChecker("cycle")));
|
||||
|
||||
// open submenu
|
||||
gQueue.push(new synthRightKey("cycle", new focusChecker("tricycle")));
|
||||
|
||||
// move to first menu in cycle, DOMMenuItemActive is fired for fruit,
|
||||
// cycle and apple menuitems (bug 685191)
|
||||
todo(false, "focus is fired for 'cycle' menuitem");
|
||||
//gQueue.push(new synthRightKey("vehicle", new focusChecker("apple")));
|
||||
|
||||
// click menuitem to close menu, focus gets back to document
|
||||
gQueue.push(new synthClick("tricycle", new focusChecker(document)));
|
||||
|
||||
//enableLogging("focus,DOMEvents,tree"); // logging for bug708927
|
||||
//gQueue.onFinish = function() { disableLogging(); }
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</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=673958"
|
||||
title="Rework accessible focus handling">
|
||||
Mozilla Bug 673958
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<menubar>
|
||||
<menu id="fruit" label="Fruit">
|
||||
<menupopup>
|
||||
<menuitem id="apple" label="Apple"/>
|
||||
<menuitem id="orange" label="Orange" disabled="true"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menu id="vehicle" label="Vehicle">
|
||||
<menupopup>
|
||||
<menu id="cycle" label="cycle">
|
||||
<menupopup>
|
||||
<menuitem id="tricycle" label="tricycle"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuitem id="car" label="Car" disabled="true"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menubar>
|
||||
|
||||
<vbox id="eventdump"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
||||
122
accessible/tests/mochitest/events/test_focus_name.html
Normal file
122
accessible/tests/mochitest/events/test_focus_name.html
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible name testing on focus</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="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
/**
|
||||
* Checker for invokers.
|
||||
*/
|
||||
function actionChecker(aID, aDescription)
|
||||
{
|
||||
this.__proto__ = new invokerChecker(EVENT_FOCUS, aID);
|
||||
|
||||
this.check = function actionChecker_check(aEvent)
|
||||
{
|
||||
var target = aEvent.accessible;
|
||||
is(target.description, aDescription,
|
||||
"Wrong description for " + prettyName(target));
|
||||
}
|
||||
}
|
||||
|
||||
var gFocusHandler = {
|
||||
handleEvent: function gFocusHandler_handleEvent(aEvent) {
|
||||
var elm = aEvent.target;
|
||||
if (elm.nodeType != nsIDOMNode.ELEMENT_NODE)
|
||||
return;
|
||||
|
||||
gTooltipElm.style.display = "block";
|
||||
|
||||
elm.setAttribute("aria-describedby", "tooltip");
|
||||
}
|
||||
};
|
||||
|
||||
var gBlurHandler = {
|
||||
handleEvent: function gBlurHandler_handleEvent(aEvent) {
|
||||
gTooltipElm.style.display = "none";
|
||||
|
||||
var elm = aEvent.target;
|
||||
if (elm.nodeType == nsIDOMNode.ELEMENT_NODE)
|
||||
elm.removeAttribute("aria-describedby");
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
|
||||
// gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
var gButtonElm = null;
|
||||
var gTextboxElm = null;
|
||||
var gTooltipElm = null;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gButtonElm = getNode("button");
|
||||
gTextboxElm = getNode("textbox");
|
||||
gTooltipElm = getNode("tooltip");
|
||||
|
||||
gButtonElm.addEventListener("focus", gFocusHandler, false);
|
||||
gButtonElm.addEventListener("blur", gBlurHandler, false);
|
||||
gTextboxElm.addEventListener("focus", gFocusHandler, false);
|
||||
gTextboxElm.addEventListener("blur", gBlurHandler, false);
|
||||
|
||||
// The aria-describedby is changed on DOM focus. Accessible description
|
||||
// should be updated when a11y focus is fired.
|
||||
gQueue = new eventQueue(nsIAccessibleEvent.EVENT_FOCUS);
|
||||
gQueue.onFinish = function()
|
||||
{
|
||||
gButtonElm.removeEventListener("focus", gFocusHandler, false);
|
||||
gButtonElm.removeEventListener("blur", gBlurHandler, false);
|
||||
gTextboxElm.removeEventListener("focus", gFocusHandler, false);
|
||||
gTextboxElm.removeEventListener("blur", gBlurHandler, false);
|
||||
}
|
||||
|
||||
var descr = "It's a tooltip";
|
||||
gQueue.push(new synthFocus("button", new actionChecker("button", descr)));
|
||||
gQueue.push(new synthTab("textbox", new actionChecker("textbox", descr)));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=520709"
|
||||
title="mochitest to ensure name/description are updated on a11y focus if they were changed on DOM focus">
|
||||
Mozilla Bug 520709
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="tooltip" style="display: none" aria-hidden="true">It's a tooltip</div>
|
||||
<button id="button">button</button>
|
||||
<input id="textbox">
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
118
accessible/tests/mochitest/events/test_focus_selects.html
Normal file
118
accessible/tests/mochitest/events/test_focus_selects.html
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible focus 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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
// Bug 746534 - File causes crash or hang on OS X
|
||||
if (MAC) {
|
||||
todo(false, "Bug 746534 - test file causes crash or hang on OS X");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
gQueue = new eventQueue();
|
||||
|
||||
// first item is focused until there's selection
|
||||
gQueue.push(new synthFocus("list", new focusChecker("orange")));
|
||||
|
||||
// item is selected and stays focused
|
||||
gQueue.push(new synthDownKey("list", new nofocusChecker()));
|
||||
|
||||
// last selected item is focused
|
||||
gQueue.push(new synthDownKey("list", new focusChecker("apple"), { shiftKey: true }));
|
||||
|
||||
// no focus event if nothing is changed
|
||||
gQueue.push(new synthDownKey("list", new nofocusChecker("apple")));
|
||||
|
||||
// current item is focused
|
||||
gQueue.push(new synthUpKey("list", new focusChecker("orange"), { ctrlKey: true }));
|
||||
|
||||
// focus on empty list (no items to be focused)
|
||||
gQueue.push(new synthTab("list", new focusChecker("emptylist")));
|
||||
|
||||
// current item is focused
|
||||
gQueue.push(new synthShiftTab("emptylist", new focusChecker("orange")));
|
||||
|
||||
// collapsed combobox keeps a focus
|
||||
gQueue.push(new synthFocus("combobox", new focusChecker("combobox")));
|
||||
gQueue.push(new synthDownKey("combobox", new nofocusChecker("combobox")));
|
||||
|
||||
// selected item is focused for expanded combobox
|
||||
gQueue.push(new synthOpenComboboxKey("combobox", new focusChecker("cb_apple")));
|
||||
gQueue.push(new synthUpKey("combobox", new focusChecker("cb_orange")));
|
||||
|
||||
// collapsed combobx keeps a focus
|
||||
gQueue.push(new synthEscapeKey("combobox", new focusChecker("combobox")));
|
||||
|
||||
// no focus events for unfocused list controls when current item is
|
||||
// changed
|
||||
gQueue.push(new synthFocus("emptylist"));
|
||||
|
||||
gQueue.push(new changeCurrentItem("list", "orange"));
|
||||
gQueue.push(new changeCurrentItem("combobox", "cb_apple"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=433418"
|
||||
title="Accessibles for focused HTML Select elements are not getting focused state">
|
||||
Mozilla Bug 433418
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=474893"
|
||||
title="List controls should fire a focus event on the selected child when tabbing or when the selected child changes while the list is focused">
|
||||
Mozilla Bug 474893
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<select id="list" size="5" multiple="">
|
||||
<option id="orange">Orange</option>
|
||||
<option id="apple">Apple</option>
|
||||
</select>
|
||||
|
||||
<select id="emptylist" size="5"></select>
|
||||
|
||||
<select id="combobox">
|
||||
<option id="cb_orange">Orange</option>
|
||||
<option id="cb_apple">Apple</option>
|
||||
</select>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
103
accessible/tests/mochitest/events/test_focus_tabbox.xul
Normal file
103
accessible/tests/mochitest/events/test_focus_tabbox.xul
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Tabbox focus testing">
|
||||
|
||||
<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="../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">
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
if (MAC) {
|
||||
todo(false, "Tests disabled because of imminent failure.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
// Test focus events.
|
||||
gQueue = new eventQueue();
|
||||
|
||||
var textbox = getNode("textbox").inputField;
|
||||
gQueue.push(new synthClick("tab1", new focusChecker("tab1")));
|
||||
gQueue.push(new synthTab("tab1", new focusChecker("checkbox1")));
|
||||
gQueue.push(new synthKey("tab1", "VK_TAB", { ctrlKey: true },
|
||||
new focusChecker(textbox)));
|
||||
gQueue.push(new synthKey("tab2", "VK_TAB", { ctrlKey: true },
|
||||
new focusChecker("tab3")));
|
||||
gQueue.push(new synthKey("tab3", "VK_TAB", { ctrlKey: true },
|
||||
new focusChecker("tab1")));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</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=370396"
|
||||
title="Control+Tab to an empty tab panel in a tabbox causes focus to leave the tabbox">
|
||||
Mozilla Bug 370396
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<tabbox>
|
||||
<tabs>
|
||||
<tab id="tab1" label="Tab1" selected="true"/>
|
||||
<tab id="tab2" label="Tab2" />
|
||||
<tab id="tab3" label="Tab3" />
|
||||
</tabs>
|
||||
<tabpanels>
|
||||
<tabpanel orient="vertical">
|
||||
<groupbox orient="vertical">
|
||||
<checkbox id="checkbox1" label="Monday" width="75"/>
|
||||
<checkbox label="Tuesday" width="75"/>
|
||||
<checkbox label="Wednesday" width="75"/>
|
||||
<checkbox label="Thursday" width="75"/>
|
||||
<checkbox label="Friday" width="75"/>
|
||||
<checkbox label="Saturday" width="75"/>
|
||||
<checkbox label="Sunday" width="75"/>
|
||||
</groupbox>
|
||||
|
||||
<spacer style="height: 10px" />
|
||||
<label value="Label After checkboxes" />
|
||||
</tabpanel>
|
||||
<tabpanel orient="vertical">
|
||||
<textbox id="textbox" />
|
||||
</tabpanel>
|
||||
<tabpanel orient="vertical">
|
||||
<description>Tab 3 content</description>
|
||||
</tabpanel>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
|
||||
<vbox id="eventdump"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
||||
122
accessible/tests/mochitest/events/test_focus_tree.xul
Normal file
122
accessible/tests/mochitest/events/test_focus_tree.xul
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="XUL tree focus testing">
|
||||
|
||||
<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="chrome://mochikit/content/tests/SimpleTest/EventUtils.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[
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function focusTree(aTreeID)
|
||||
{
|
||||
var checker = new focusChecker(getFirstTreeItem, aTreeID);
|
||||
this.__proto__ = new synthFocus(aTreeID, [ checker ]);
|
||||
}
|
||||
|
||||
function moveToNextItem(aTreeID)
|
||||
{
|
||||
var checker = new focusChecker(getSecondTreeItem, aTreeID);
|
||||
this.__proto__ = new synthDownKey(aTreeID, [ checker ]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
function getTreeItemAt(aTreeID, aIdx)
|
||||
{ return getAccessible(aTreeID).getChildAt(aIdx + 1); }
|
||||
|
||||
function getFirstTreeItem(aTreeID)
|
||||
{ return getTreeItemAt(aTreeID, 0); }
|
||||
|
||||
function getSecondTreeItem(aTreeID)
|
||||
{ return getTreeItemAt(aTreeID, 1); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
//gA11yEventDumpID = "debug"; // debugging
|
||||
//gA11yEventDumpToConsole = true; // debugging
|
||||
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new focusTree("tree"));
|
||||
gQueue.push(new moveToNextItem("tree"));
|
||||
gQueue.push(new synthFocus("emptytree"));
|
||||
|
||||
// no focus event for changed current item for unfocused tree
|
||||
gQueue.push(new changeCurrentItem("tree", 0));
|
||||
|
||||
gQueue.invoke();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yXULTreeLoadEvent(doTest, "tree", new nsTableTreeView(5));
|
||||
]]>
|
||||
</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=386821"
|
||||
title="Need better solution for firing delayed event against xul tree">
|
||||
Mozilla Bug 386821
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=406308"
|
||||
title="Don't fire accessible focus events if widget is not actually in focus, confuses screen readers">
|
||||
Mozilla Bug 406308
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox id="debug"/>
|
||||
<tree id="tree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col1" flex="1" primary="true" label="column"/>
|
||||
<treecol id="col2" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren id="treechildren"/>
|
||||
</tree>
|
||||
<tree id="emptytree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="emptytree_col1" flex="1" primary="true" label="column"/>
|
||||
<treecol id="emptytree_col2" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren id="emptytree_treechildren"/>
|
||||
</tree>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
||||
127
accessible/tests/mochitest/events/test_fromUserInput.html
Normal file
127
accessible/tests/mochitest/events/test_fromUserInput.html
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Testing of isFromUserInput in text events</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="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
/**
|
||||
* Remove text data from HTML input.
|
||||
*/
|
||||
function removeTextFromInput(aID, aStart, aEnd, aText, aFromUser)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new textChangeChecker(aID, aStart, aEnd, aText, false, aFromUser)
|
||||
];
|
||||
|
||||
this.invoke = function removeTextFromInput_invoke()
|
||||
{
|
||||
const nsIDOMNSEditableElement =
|
||||
Components.interfaces.nsIDOMNSEditableElement;
|
||||
|
||||
this.DOMNode.focus();
|
||||
this.DOMNode.setSelectionRange(aStart, aEnd);
|
||||
|
||||
synthesizeKey("VK_DELETE", {});
|
||||
}
|
||||
|
||||
this.getID = function removeTextFromInput_getID()
|
||||
{
|
||||
return "Remove text from " + aStart + " to " + aEnd + " for " +
|
||||
prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove text data from text node.
|
||||
*/
|
||||
function removeTextFromContentEditable(aID, aStart, aEnd, aText, aFromUser)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new textChangeChecker(aID, aStart, aEnd, aText, false, aFromUser)
|
||||
];
|
||||
|
||||
this.invoke = function removeTextFromContentEditable_invoke()
|
||||
{
|
||||
const nsIDOMNSEditableElement =
|
||||
Components.interfaces.nsIDOMNSEditableElement;
|
||||
|
||||
this.DOMNode.focus();
|
||||
this.textNode = getNode(aID).firstChild;
|
||||
var selection = window.getSelection();
|
||||
var range = document.createRange();
|
||||
range.setStart(this.textNode, aStart);
|
||||
range.setEnd(this.textNode, aEnd);
|
||||
selection.addRange(range);
|
||||
|
||||
synthesizeKey("VK_DELETE", {});
|
||||
}
|
||||
|
||||
this.getID = function removeTextFromContentEditable_getID()
|
||||
{
|
||||
return "Remove text from " + aStart + " to " + aEnd + " for " +
|
||||
prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
// gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
// Focused editable text node
|
||||
gQueue.push(new removeTextFromContentEditable("div", 0, 3, "hel", true));
|
||||
|
||||
// Focused editable HTML input
|
||||
gQueue.push(new removeTextFromInput("input", 1, 2, "n", true));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish()
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=686909"
|
||||
title="isFromUserInput flag on accessible text change events not correct">
|
||||
Mozilla Bug 686909
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<div id="div" contentEditable="true">hello</div>
|
||||
<input id="input" value="input">
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
177
accessible/tests/mochitest/events/test_label.xul
Normal file
177
accessible/tests/mochitest/events/test_label.xul
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
<?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="Tests: accessible XUL label/description events">
|
||||
|
||||
<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="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
const kRecreated = 0;
|
||||
const kTextRemoved = 1;
|
||||
const kTextChanged = 2;
|
||||
|
||||
const kNoValue = 0;
|
||||
|
||||
/**
|
||||
* Set/remove @value attribute.
|
||||
*/
|
||||
function setValue(aID, aValue, aResult, aOldValue)
|
||||
{
|
||||
this.labelNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [];
|
||||
|
||||
switch (aResult) {
|
||||
case kRecreated:
|
||||
this.eventSeq.push(new invokerChecker(EVENT_HIDE, this.labelNode));
|
||||
this.eventSeq.push(new invokerChecker(EVENT_SHOW, this.labelNode));
|
||||
break;
|
||||
case kTextRemoved:
|
||||
this.eventSeq.push(
|
||||
new textChangeChecker(this.labelNode, 0, aOldValue.length,
|
||||
aOldValue, false));
|
||||
break;
|
||||
case kTextChanged:
|
||||
this.eventSeq.push(
|
||||
new textChangeChecker(this.labelNode, 0, aOldValue.length,
|
||||
aOldValue, false));
|
||||
this.eventSeq.push(
|
||||
new textChangeChecker(this.labelNode, 0, aValue.length,
|
||||
aValue, true));
|
||||
break;
|
||||
}
|
||||
|
||||
this.invoke = function setValue_invoke()
|
||||
{
|
||||
if (aValue === kNoValue)
|
||||
this.labelNode.removeAttribute("value");
|
||||
else
|
||||
this.labelNode.setAttribute("value", aValue);
|
||||
}
|
||||
|
||||
this.finalCheck = function setValue_finalCheck()
|
||||
{
|
||||
var tree =
|
||||
{ LABEL: [
|
||||
{ TEXT_LEAF: [ ] }
|
||||
] };
|
||||
testAccessibleTree(aID, tree);
|
||||
}
|
||||
|
||||
this.getID = function setValue_getID()
|
||||
{
|
||||
return "set @value='" + aValue + "' for label " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change @crop attribute.
|
||||
*/
|
||||
function setCrop(aID, aCropValue, aRemovedText, aInsertedText)
|
||||
{
|
||||
this.labelNode = getNode(aID);
|
||||
this.width = this.labelNode.boxObject.width;
|
||||
this.charWidth = this.width / this.labelNode.value.length;
|
||||
|
||||
this.eventSeq = [
|
||||
new textChangeChecker(this.labelNode, 0, -1, aRemovedText, false),
|
||||
new textChangeChecker(this.labelNode, 0, -1, aInsertedText, true)
|
||||
];
|
||||
|
||||
this.invoke = function setCrop_invoke()
|
||||
{
|
||||
if (!this.labelNode.hasAttribute("crop"))
|
||||
this.labelNode.width = Math.floor(this.width - 2 * this.charWidth);
|
||||
|
||||
this.labelNode.setAttribute("crop", aCropValue);
|
||||
}
|
||||
|
||||
this.getID = function setCrop_finalCheck()
|
||||
{
|
||||
return "set crop " + aCropValue;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new setValue("label", "shiroka strana", kRecreated));
|
||||
gQueue.push(new setValue("label", "?<>!+_", kTextChanged, "shiroka strana"));
|
||||
gQueue.push(new setValue("label", "", kTextRemoved, "?<>!+_"));
|
||||
gQueue.push(new setValue("label", kNoValue, kRecreated));
|
||||
|
||||
gQueue.push(new setValue("descr", "hello world", kRecreated));
|
||||
gQueue.push(new setValue("descr", "si_ya", kTextChanged, "hello world"));
|
||||
gQueue.push(new setValue("descr", "", kTextRemoved, "si_ya"));
|
||||
gQueue.push(new setValue("descr", kNoValue, kRecreated));
|
||||
|
||||
if (MAC) {
|
||||
// "valuetocro" -> "…etocro"
|
||||
gQueue.push(new setCrop("croplabel", "left", "valu", "…"));
|
||||
// "…etocro", "val…cro"
|
||||
gQueue.push(new setCrop("croplabel", "center", "…eto", "val…"));
|
||||
} else {
|
||||
// "valuetocro" -> "…uetocro"
|
||||
gQueue.push(new setCrop("croplabel", "left", "val", "…"));
|
||||
// "…uetocro" -> "valu…cro"
|
||||
gQueue.push(new setCrop("croplabel", "center", "…ueto", "valu…"));
|
||||
}
|
||||
|
||||
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=396166"
|
||||
title="xul:label@value accessible should implement nsIAccessibleText">
|
||||
Bug 396166
|
||||
</a>
|
||||
<br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<label id="label">hello</label>
|
||||
<description id="descr">hello</description>
|
||||
|
||||
<hbox>
|
||||
<label id="croplabel" value="valuetocro"
|
||||
style="font-family: monospace;"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
||||
202
accessible/tests/mochitest/events/test_menu.xul
Normal file
202
accessible/tests/mochitest/events/test_menu.xul
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
<?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 menu events testing for XUL menu">
|
||||
|
||||
<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="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
function openFileMenu()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_MENU_START, getNode("menubar")),
|
||||
new invokerChecker(EVENT_MENUPOPUP_START, getNode("menupopup-file"))
|
||||
// new invokerChecker(EVENT_FOCUS, getNode("menuitem-newtab")) intermitent failure
|
||||
];
|
||||
|
||||
this.invoke = function openFileMenu_invoke()
|
||||
{
|
||||
synthesizeKey("F", { altKey: true, shiftKey: true });
|
||||
}
|
||||
|
||||
this.getID = function openFileMenu_getID()
|
||||
{
|
||||
return "open file menu by alt+F press";
|
||||
}
|
||||
}
|
||||
|
||||
function openEditMenu()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_MENUPOPUP_END, getNode("menupopup-file")),
|
||||
new invokerChecker(EVENT_MENUPOPUP_START, getNode("menupopup-edit"))
|
||||
// new invokerChecker(EVENT_FOCUS, getNode("menuitem-undo")) intermitent failure
|
||||
];
|
||||
|
||||
this.invoke = function openEditMenu_invoke()
|
||||
{
|
||||
synthesizeKey("VK_RIGHT", { });
|
||||
}
|
||||
|
||||
this.getID = function openEditMenu_getID()
|
||||
{
|
||||
return "open edit menu by lef arrow press";
|
||||
}
|
||||
}
|
||||
|
||||
function closeEditMenu()
|
||||
{
|
||||
this.eventSeq = [
|
||||
//new invokerChecker(EVENT_FOCUS, document), intermitent failure
|
||||
new invokerChecker(EVENT_MENUPOPUP_END, getNode("menupopup-edit")),
|
||||
new invokerChecker(EVENT_MENU_END, getNode("menubar"))
|
||||
];
|
||||
|
||||
this.invoke = function closeEditMenu_invoke()
|
||||
{
|
||||
synthesizeKey("VK_ESCAPE", { });
|
||||
}
|
||||
|
||||
this.getID = function closeEditMenu_getID()
|
||||
{
|
||||
return "close edit menu, leave menubar";
|
||||
}
|
||||
}
|
||||
|
||||
function focusFileMenu()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_MENU_START, getNode("menubar"))
|
||||
// new invokerChecker(EVENT_FOCUS, getNode("menuitem-file")) //intermitent failure
|
||||
];
|
||||
|
||||
this.invoke = function focusFileMenu_invoke()
|
||||
{
|
||||
synthesizeKey("VK_ALT", { });
|
||||
}
|
||||
|
||||
this.getID = function focusFileMenu_getID()
|
||||
{
|
||||
return "activate menubar, focus file menu (atl press)";
|
||||
}
|
||||
}
|
||||
|
||||
function focusEditMenu()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_FOCUS, getNode("menuitem-edit"))
|
||||
];
|
||||
|
||||
this.invoke = function focusEditMenu_invoke()
|
||||
{
|
||||
synthesizeKey("VK_RIGHT", { });
|
||||
}
|
||||
|
||||
this.getID = function focusEditMenu_getID()
|
||||
{
|
||||
return "focus edit menu";
|
||||
}
|
||||
}
|
||||
|
||||
function leaveMenubar()
|
||||
{
|
||||
this.eventSeq = [
|
||||
//new invokerChecker(EVENT_FOCUS, document), intermitent failure
|
||||
new invokerChecker(EVENT_MENU_END, getNode("menubar"))
|
||||
];
|
||||
|
||||
this.invoke = function leaveMenubar_invoke()
|
||||
{
|
||||
synthesizeKey("VK_ESCAPE", { });
|
||||
}
|
||||
|
||||
this.getID = function leaveMenubar_getID()
|
||||
{
|
||||
return "leave menubar";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
|
||||
//gA11yEventDumpID = "eventdump";
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
if (!WIN) {
|
||||
todo(false, "Enable this test on other platforms.");
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
todo(false,
|
||||
"Fix intermitent failures. Focus may randomly occur before or after menupopup events!");
|
||||
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new openFileMenu());
|
||||
gQueue.push(new openEditMenu());
|
||||
gQueue.push(new closeEditMenu());
|
||||
|
||||
// Alt key is used to active menubar and focus menu item on Windows,
|
||||
// other platforms requires setting a ui.key.menuAccessKeyFocuses
|
||||
// preference.
|
||||
if (WIN || LINUX) {
|
||||
gQueue.push(new focusFileMenu());
|
||||
gQueue.push(new focusEditMenu());
|
||||
gQueue.push(new leaveMenubar());
|
||||
}
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</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=615189"
|
||||
title="Clean up FireAccessibleFocusEvent">
|
||||
Mozilla Bug 615189
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<menubar id="menubar">
|
||||
<menu id="menuitem-file" label="File" accesskey="F">
|
||||
<menupopup id="menupopup-file">
|
||||
<menuitem id="menuitem-newtab" label="New Tab"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menu id="menuitem-edit" label="Edit" accesskey="E">
|
||||
<menupopup id="menupopup-edit">
|
||||
<menuitem id="menuitem-undo" label="Undo"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menubar>
|
||||
|
||||
<vbox id="eventdump" role="log"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</window>
|
||||
632
accessible/tests/mochitest/events/test_mutation.html
Normal file
632
accessible/tests/mochitest/events/test_mutation.html
Normal file
|
|
@ -0,0 +1,632 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible mutation events testing</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<style>
|
||||
div.displayNone a { display:none; }
|
||||
div.visibilityHidden a { visibility:hidden; }
|
||||
</style>
|
||||
|
||||
<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="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
/**
|
||||
* Invokers.
|
||||
*/
|
||||
var kNoEvents = 0;
|
||||
|
||||
var kShowEvent = 1;
|
||||
var kHideEvent = 2;
|
||||
var kReorderEvent = 4;
|
||||
var kShowEvents = kShowEvent | kReorderEvent;
|
||||
var kHideEvents = kHideEvent | kReorderEvent;
|
||||
var kHideAndShowEvents = kHideEvents | kShowEvent;
|
||||
|
||||
/**
|
||||
* Base class to test mutation a11y events.
|
||||
*
|
||||
* @param aNodeOrID [in] node invoker's action is executed for
|
||||
* @param aEventTypes [in] events to register (see constants above)
|
||||
* @param aDoNotExpectEvents [in] boolean indicates if events are expected
|
||||
*/
|
||||
function mutateA11yTree(aNodeOrID, aEventTypes, aDoNotExpectEvents)
|
||||
{
|
||||
// Interface
|
||||
this.DOMNode = getNode(aNodeOrID);
|
||||
this.doNotExpectEvents = aDoNotExpectEvents;
|
||||
this.eventSeq = [];
|
||||
this.unexpectedEventSeq = [];
|
||||
|
||||
/**
|
||||
* Change default target (aNodeOrID) registered for the given event type.
|
||||
*/
|
||||
this.setTarget = function mutateA11yTree_setTarget(aEventType, aTarget)
|
||||
{
|
||||
var type = this.getA11yEventType(aEventType);
|
||||
for (var idx = 0; idx < this.getEventSeq().length; idx++) {
|
||||
if (this.getEventSeq()[idx].type == type) {
|
||||
this.getEventSeq()[idx].target = aTarget;
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replace the default target currently registered for a given event type
|
||||
* with the nodes in the targets array.
|
||||
*/
|
||||
this.setTargets = function mutateA11yTree_setTargets(aEventType, aTargets) {
|
||||
var targetIdx = this.setTarget(aEventType, aTargets[0]);
|
||||
|
||||
var type = this.getA11yEventType(aEventType);
|
||||
for (var i = 1; i < aTargets.length; i++) {
|
||||
var checker = new invokerChecker(type, aTargets[i]);
|
||||
this.getEventSeq().splice(++targetIdx, 0, checker);
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation
|
||||
this.getA11yEventType = function mutateA11yTree_getA11yEventType(aEventType)
|
||||
{
|
||||
if (aEventType == kReorderEvent)
|
||||
return nsIAccessibleEvent.EVENT_REORDER;
|
||||
|
||||
if (aEventType == kHideEvent)
|
||||
return nsIAccessibleEvent.EVENT_HIDE;
|
||||
|
||||
if (aEventType == kShowEvent)
|
||||
return nsIAccessibleEvent.EVENT_SHOW;
|
||||
}
|
||||
|
||||
this.getEventSeq = function mutateA11yTree_getEventSeq()
|
||||
{
|
||||
return this.doNotExpectEvents ? this.unexpectedEventSeq : this.eventSeq;
|
||||
}
|
||||
|
||||
if (aEventTypes & kHideEvent) {
|
||||
var checker = new invokerChecker(this.getA11yEventType(kHideEvent),
|
||||
this.DOMNode);
|
||||
this.getEventSeq().push(checker);
|
||||
}
|
||||
|
||||
if (aEventTypes & kShowEvent) {
|
||||
var checker = new invokerChecker(this.getA11yEventType(kShowEvent),
|
||||
this.DOMNode);
|
||||
this.getEventSeq().push(checker);
|
||||
}
|
||||
|
||||
if (aEventTypes & kReorderEvent) {
|
||||
var checker = new invokerChecker(this.getA11yEventType(kReorderEvent),
|
||||
this.DOMNode.parentNode);
|
||||
this.getEventSeq().push(checker);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change CSS style for the given node.
|
||||
*/
|
||||
function changeStyle(aNodeOrID, aProp, aValue, aEventTypes)
|
||||
{
|
||||
this.__proto__ = new mutateA11yTree(aNodeOrID, aEventTypes, false);
|
||||
|
||||
this.invoke = function changeStyle_invoke()
|
||||
{
|
||||
this.DOMNode.style[aProp] = aValue;
|
||||
}
|
||||
|
||||
this.getID = function changeStyle_getID()
|
||||
{
|
||||
return aNodeOrID + " change style " + aProp + " on value " + aValue;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change class name for the given node.
|
||||
*/
|
||||
function changeClass(aParentNodeOrID, aNodeOrID, aClassName, aEventTypes)
|
||||
{
|
||||
this.__proto__ = new mutateA11yTree(aNodeOrID, aEventTypes, false);
|
||||
|
||||
this.invoke = function changeClass_invoke()
|
||||
{
|
||||
this.parentDOMNode.className = aClassName;
|
||||
}
|
||||
|
||||
this.getID = function changeClass_getID()
|
||||
{
|
||||
return aNodeOrID + " change class " + aClassName;
|
||||
}
|
||||
|
||||
this.parentDOMNode = getNode(aParentNodeOrID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone the node and append it to its parent.
|
||||
*/
|
||||
function cloneAndAppendToDOM(aNodeOrID, aEventTypes,
|
||||
aTargetsFunc, aReorderTargetFunc)
|
||||
{
|
||||
var eventTypes = aEventTypes || kShowEvents;
|
||||
var doNotExpectEvents = (aEventTypes == kNoEvents);
|
||||
|
||||
this.__proto__ = new mutateA11yTree(aNodeOrID, eventTypes,
|
||||
doNotExpectEvents);
|
||||
|
||||
this.invoke = function cloneAndAppendToDOM_invoke()
|
||||
{
|
||||
var newElm = this.DOMNode.cloneNode(true);
|
||||
newElm.removeAttribute('id');
|
||||
|
||||
var targets = aTargetsFunc ?
|
||||
aTargetsFunc.call(null, newElm) : [newElm];
|
||||
this.setTargets(kShowEvent, targets);
|
||||
|
||||
if (aReorderTargetFunc) {
|
||||
var reorderTarget = aReorderTargetFunc.call(null, this.DOMNode);
|
||||
this.setTarget(kReorderEvent, reorderTarget);
|
||||
}
|
||||
|
||||
this.DOMNode.parentNode.appendChild(newElm);
|
||||
}
|
||||
|
||||
this.getID = function cloneAndAppendToDOM_getID()
|
||||
{
|
||||
return aNodeOrID + " clone and append to DOM.";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the node from DOM.
|
||||
*/
|
||||
function removeFromDOM(aNodeOrID, aEventTypes,
|
||||
aTargetsFunc, aReorderTargetFunc)
|
||||
{
|
||||
var eventTypes = aEventTypes || kHideEvents;
|
||||
var doNotExpectEvents = (aEventTypes == kNoEvents);
|
||||
|
||||
this.__proto__ = new mutateA11yTree(aNodeOrID, eventTypes,
|
||||
doNotExpectEvents);
|
||||
|
||||
this.invoke = function removeFromDOM_invoke()
|
||||
{
|
||||
this.DOMNode.parentNode.removeChild(this.DOMNode);
|
||||
}
|
||||
|
||||
this.getID = function removeFromDOM_getID()
|
||||
{
|
||||
return prettyName(aNodeOrID) + " remove from DOM.";
|
||||
}
|
||||
|
||||
if (aTargetsFunc && (eventTypes & kHideEvent))
|
||||
this.setTargets(kHideEvent, aTargetsFunc.call(null, this.DOMNode));
|
||||
|
||||
if (aReorderTargetFunc && (eventTypes & kReorderEvent))
|
||||
this.setTarget(kReorderEvent,
|
||||
aReorderTargetFunc.call(null, this.DOMNode));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clone the node and replace the original node by cloned one.
|
||||
*/
|
||||
function cloneAndReplaceInDOM(aNodeOrID)
|
||||
{
|
||||
this.__proto__ = new mutateA11yTree(aNodeOrID, kHideAndShowEvents,
|
||||
false);
|
||||
|
||||
this.invoke = function cloneAndReplaceInDOM_invoke()
|
||||
{
|
||||
this.DOMNode.parentNode.replaceChild(this.newElm, this.DOMNode);
|
||||
}
|
||||
|
||||
this.getID = function cloneAndReplaceInDOM_getID()
|
||||
{
|
||||
return aNodeOrID + " clone and replace in DOM.";
|
||||
}
|
||||
|
||||
this.newElm = this.DOMNode.cloneNode(true);
|
||||
this.newElm.removeAttribute('id');
|
||||
this.setTarget(kShowEvent, this.newElm);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger content insertion (flush layout), removal and insertion of
|
||||
* the same element for the same parent.
|
||||
*/
|
||||
function test1(aContainerID)
|
||||
{
|
||||
this.divNode = document.createElement("div");
|
||||
this.divNode.setAttribute("id", "div-test1");
|
||||
this.containerNode = getNode(aContainerID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, this.divNode),
|
||||
new invokerChecker(EVENT_REORDER, this.containerNode)
|
||||
];
|
||||
|
||||
this.invoke = function test1_invoke()
|
||||
{
|
||||
this.containerNode.appendChild(this.divNode);
|
||||
getComputedStyle(this.divNode, "").color;
|
||||
this.containerNode.removeChild(this.divNode);
|
||||
this.containerNode.appendChild(this.divNode);
|
||||
}
|
||||
|
||||
this.getID = function test1_getID()
|
||||
{
|
||||
return "fuzzy test #1: content insertion (flush layout), removal and" +
|
||||
"reinsertion";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger content insertion (flush layout), removal and insertion of
|
||||
* the same element for the different parents.
|
||||
*/
|
||||
function test2(aContainerID, aTmpContainerID)
|
||||
{
|
||||
this.divNode = document.createElement("div");
|
||||
this.divNode.setAttribute("id", "div-test2");
|
||||
this.containerNode = getNode(aContainerID);
|
||||
this.tmpContainerNode = getNode(aTmpContainerID);
|
||||
this.container = getAccessible(this.containerNode);
|
||||
this.tmpContainer = getAccessible(this.tmpContainerNode);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, this.divNode),
|
||||
new invokerChecker(EVENT_REORDER, this.containerNode)
|
||||
];
|
||||
|
||||
this.unexpectedEventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, this.tmpContainerNode)
|
||||
];
|
||||
|
||||
this.invoke = function test2_invoke()
|
||||
{
|
||||
this.tmpContainerNode.appendChild(this.divNode);
|
||||
getComputedStyle(this.divNode, "").color;
|
||||
this.tmpContainerNode.removeChild(this.divNode);
|
||||
this.containerNode.appendChild(this.divNode);
|
||||
}
|
||||
|
||||
this.getID = function test2_getID()
|
||||
{
|
||||
return "fuzzy test #2: content insertion (flush layout), removal and" +
|
||||
"reinsertion under another container";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Content insertion (flush layout) and then removal (nothing was changed).
|
||||
*/
|
||||
function test3(aContainerID)
|
||||
{
|
||||
this.divNode = document.createElement("div");
|
||||
this.divNode.setAttribute("id", "div-test3");
|
||||
this.containerNode = getNode(aContainerID);
|
||||
|
||||
this.unexpectedEventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, this.divNode),
|
||||
new invokerChecker(EVENT_HIDE, this.divNode),
|
||||
new invokerChecker(EVENT_REORDER, this.containerNode)
|
||||
];
|
||||
|
||||
this.invoke = function test3_invoke()
|
||||
{
|
||||
this.containerNode.appendChild(this.divNode);
|
||||
getComputedStyle(this.divNode, "").color;
|
||||
this.containerNode.removeChild(this.divNode);
|
||||
}
|
||||
|
||||
this.getID = function test3_getID()
|
||||
{
|
||||
return "fuzzy test #3: content insertion (flush layout) and removal";
|
||||
}
|
||||
}
|
||||
|
||||
function insertReferredElm(aContainerID)
|
||||
{
|
||||
this.containerNode = getNode(aContainerID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, function(aNode) { return aNode.firstChild; }, this.containerNode),
|
||||
new invokerChecker(EVENT_SHOW, function(aNode) { return aNode.lastChild; }, this.containerNode),
|
||||
new invokerChecker(EVENT_REORDER, this.containerNode)
|
||||
];
|
||||
|
||||
this.invoke = function insertReferredElm_invoke()
|
||||
{
|
||||
this.containerNode.innerHTML =
|
||||
"<span id='insertReferredElms_span'></span><input aria-labelledby='insertReferredElms_span'>";
|
||||
}
|
||||
|
||||
this.getID = function insertReferredElm_getID()
|
||||
{
|
||||
return "insert inaccessible element and then insert referring element to make it accessible";
|
||||
}
|
||||
}
|
||||
|
||||
function showHiddenParentOfVisibleChild()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getNode("c4_child")),
|
||||
new invokerChecker(EVENT_SHOW, getNode("c4_middle")),
|
||||
new invokerChecker(EVENT_REORDER, getNode("c4"))
|
||||
];
|
||||
|
||||
this.invoke = function showHiddenParentOfVisibleChild_invoke()
|
||||
{
|
||||
getNode("c4_middle").style.visibility = 'visible';
|
||||
}
|
||||
|
||||
this.getID = function showHiddenParentOfVisibleChild_getID()
|
||||
{
|
||||
return "show hidden parent of visible child";
|
||||
}
|
||||
}
|
||||
|
||||
function hideNDestroyDoc()
|
||||
{
|
||||
this.txt = null;
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, function() { return this.txt; }.bind(this))
|
||||
];
|
||||
|
||||
this.invoke = function hideNDestroyDoc_invoke()
|
||||
{
|
||||
this.txt = getAccessible('c5').firstChild.firstChild;
|
||||
this.txt.DOMNode.parentNode.removeChild(this.txt.DOMNode);
|
||||
}
|
||||
|
||||
this.check = function hideNDestroyDoc_check()
|
||||
{
|
||||
getNode('c5').parentNode.removeChild(getNode('c5'));
|
||||
}
|
||||
|
||||
this.getID = function hideNDestroyDoc_getID()
|
||||
{
|
||||
return "remove text node and destroy a document on hide event";
|
||||
}
|
||||
}
|
||||
|
||||
function hideHideNDestroyDoc()
|
||||
{
|
||||
this.target = null;
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, function() { return this.target; }.bind(this))
|
||||
];
|
||||
|
||||
this.invoke = function hideHideNDestroyDoc_invoke()
|
||||
{
|
||||
var doc = getAccessible('c6').firstChild;
|
||||
var l1 = doc.firstChild;
|
||||
this.target = l1.firstChild;
|
||||
var l2 = doc.lastChild;
|
||||
l1.DOMNode.removeChild(l1.DOMNode.firstChild);
|
||||
l2.DOMNode.removeChild(l2.DOMNode.firstChild);
|
||||
}
|
||||
|
||||
this.check = function hideHideNDestroyDoc_check()
|
||||
{
|
||||
getNode('c6').parentNode.removeChild(getNode('c6'));
|
||||
}
|
||||
|
||||
this.getID = function hideHideNDestroyDoc_getID()
|
||||
{
|
||||
return "remove text nodes (2 events in the queue) and destroy a document on first hide event";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Target getters.
|
||||
*/
|
||||
function getFirstChild(aNode)
|
||||
{
|
||||
return [aNode.firstChild];
|
||||
}
|
||||
function getLastChild(aNode)
|
||||
{
|
||||
return [aNode.lastChild];
|
||||
}
|
||||
|
||||
function getNEnsureFirstChild(aNode)
|
||||
{
|
||||
var node = aNode.firstChild;
|
||||
getAccessible(node);
|
||||
return [node];
|
||||
}
|
||||
|
||||
function getNEnsureChildren(aNode)
|
||||
{
|
||||
var children = [];
|
||||
var node = aNode.firstChild;
|
||||
do {
|
||||
children.push(node);
|
||||
getAccessible(node);
|
||||
node = node.nextSibling;
|
||||
} while (node);
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
function getParent(aNode)
|
||||
{
|
||||
return aNode.parentNode;
|
||||
}
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
//enableLogging("events,verbose");
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
// Show/hide events by changing of display style of accessible DOM node
|
||||
// from 'inline' to 'none', 'none' to 'inline'.
|
||||
var id = "link1";
|
||||
getAccessible(id); // ensure accessible is created
|
||||
gQueue.push(new changeStyle(id, "display", "none", kHideEvents));
|
||||
gQueue.push(new changeStyle(id, "display", "inline", kShowEvents));
|
||||
|
||||
// Show/hide events by changing of visibility style of accessible DOM node
|
||||
// from 'visible' to 'hidden', 'hidden' to 'visible'.
|
||||
var id = "link2";
|
||||
getAccessible(id);
|
||||
gQueue.push(new changeStyle(id, "visibility", "hidden", kHideEvents));
|
||||
gQueue.push(new changeStyle(id, "visibility", "visible", kShowEvents));
|
||||
|
||||
// Show/hide events by changing of display style of accessible DOM node
|
||||
// from 'inline' to 'block', 'block' to 'inline'.
|
||||
var id = "link3";
|
||||
getAccessible(id); // ensure accessible is created
|
||||
gQueue.push(new changeStyle(id, "display", "block", kHideAndShowEvents));
|
||||
gQueue.push(new changeStyle(id, "display", "inline", kHideAndShowEvents));
|
||||
|
||||
// Show/hide events by changing of visibility style of accessible DOM node
|
||||
// from 'collapse' to 'visible', 'visible' to 'collapse'.
|
||||
var id = "link4";
|
||||
gQueue.push(new changeStyle(id, "visibility", "visible", kShowEvents));
|
||||
gQueue.push(new changeStyle(id, "visibility", "collapse", kHideEvents));
|
||||
|
||||
// Show/hide events by adding new accessible DOM node and removing old one.
|
||||
var id = "link5";
|
||||
gQueue.push(new cloneAndAppendToDOM(id));
|
||||
gQueue.push(new removeFromDOM(id));
|
||||
|
||||
// No show/hide events by adding new not accessible DOM node and removing
|
||||
// old one, no reorder event for their parent.
|
||||
var id = "child1";
|
||||
gQueue.push(new cloneAndAppendToDOM(id, kNoEvents));
|
||||
gQueue.push(new removeFromDOM(id, kNoEvents));
|
||||
|
||||
// Show/hide events by adding new accessible DOM node and removing
|
||||
// old one, there is reorder event for their parent.
|
||||
var id = "child2";
|
||||
gQueue.push(new cloneAndAppendToDOM(id));
|
||||
gQueue.push(new removeFromDOM(id));
|
||||
|
||||
// Show/hide events by adding new DOM node containing accessible DOM and
|
||||
// removing old one, there is reorder event for their parent.
|
||||
var id = "child3";
|
||||
gQueue.push(new cloneAndAppendToDOM(id, kShowEvents, getFirstChild,
|
||||
getParent));
|
||||
|
||||
// Hide event for accessible child of unaccessible removed DOM node and
|
||||
// reorder event for its parent.
|
||||
gQueue.push(new removeFromDOM(id, kHideEvents,
|
||||
getNEnsureFirstChild, getParent));
|
||||
|
||||
// Hide events for accessible children of unaccessible removed DOM node
|
||||
// and reorder event for its parent.
|
||||
gQueue.push(new removeFromDOM("child4", kHideEvents,
|
||||
getNEnsureChildren, getParent));
|
||||
|
||||
// Show/hide events by creating new accessible DOM node and replacing
|
||||
// old one.
|
||||
getAccessible("link6"); // ensure accessible is created
|
||||
gQueue.push(new cloneAndReplaceInDOM("link6"));
|
||||
|
||||
// Show/hide events by changing class name on the parent node.
|
||||
gQueue.push(new changeClass("container2", "link7", "", kShowEvents));
|
||||
gQueue.push(new changeClass("container2", "link7", "displayNone",
|
||||
kHideEvents));
|
||||
|
||||
gQueue.push(new changeClass("container3", "link8", "", kShowEvents));
|
||||
gQueue.push(new changeClass("container3", "link8", "visibilityHidden",
|
||||
kHideEvents));
|
||||
|
||||
gQueue.push(new test1("testContainer"));
|
||||
gQueue.push(new test2("testContainer", "testContainer2"));
|
||||
gQueue.push(new test2("testContainer", "testNestedContainer"));
|
||||
gQueue.push(new test3("testContainer"));
|
||||
gQueue.push(new insertReferredElm("testContainer3"));
|
||||
gQueue.push(new showHiddenParentOfVisibleChild());
|
||||
|
||||
gQueue.push(new hideNDestroyDoc());
|
||||
gQueue.push(new hideHideNDestroyDoc());
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=469985"
|
||||
title=" turn the test from bug 354745 into mochitest">
|
||||
Mozilla Bug 469985</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=472662"
|
||||
title="no reorder event when html:link display property is changed from 'none' to 'inline'">
|
||||
Mozilla Bug 472662</a>
|
||||
<a target="_blank"
|
||||
title="Rework accessible tree update code"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=570275">
|
||||
Mozilla Bug 570275</a>
|
||||
<a target="_blank"
|
||||
title="Develop a way to handle visibility style"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=606125">
|
||||
Mozilla Bug 606125</a>
|
||||
<a target="_blank"
|
||||
title="Update accessible tree on content insertion after layout"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=498015">
|
||||
Mozilla Bug 498015</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<div id="testContainer">
|
||||
<a id="link1" href="http://www.google.com">Link #1</a>
|
||||
<a id="link2" href="http://www.google.com">Link #2</a>
|
||||
<a id="link3" href="http://www.google.com">Link #3</a>
|
||||
<a id="link4" href="http://www.google.com" style="visibility:collapse">Link #4</a>
|
||||
<a id="link5" href="http://www.google.com">Link #5</a>
|
||||
|
||||
<div id="container" role="list">
|
||||
<span id="child1"></span>
|
||||
<span id="child2" role="listitem"></span>
|
||||
<span id="child3"><span role="listitem"></span></span>
|
||||
<span id="child4"><span id="child4_1" role="listitem"></span><span id="child4_2" role="listitem"></span></span>
|
||||
</div>
|
||||
|
||||
<a id="link6" href="http://www.google.com">Link #6</a>
|
||||
|
||||
<div id="container2" class="displayNone"><a id="link7">Link #7</a></div>
|
||||
<div id="container3" class="visibilityHidden"><a id="link8">Link #8</a></div>
|
||||
<div id="testNestedContainer"></div>
|
||||
</div>
|
||||
<div id="testContainer2"></div>
|
||||
<div id="testContainer3"></div>
|
||||
|
||||
<div id="c4">
|
||||
<div style="visibility:hidden" id="c4_middle">
|
||||
<div style="visibility:visible" id="c4_child"></div>
|
||||
</div>
|
||||
|
||||
<iframe id="c5" src="data:text/html,hey"></iframe>
|
||||
<iframe id="c6" src="data:text/html,<label>l</label><label>l</label>"></iframe>
|
||||
</body>
|
||||
</html>
|
||||
97
accessible/tests/mochitest/events/test_mutation.xhtml
Normal file
97
accessible/tests/mochitest/events/test_mutation.xhtml
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
|
||||
<head>
|
||||
<title>Accessible mutation events testing</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<bindings xmlns="http://www.mozilla.org/xbl" >
|
||||
<binding id="button">
|
||||
<content>
|
||||
<button xmlns="http://www.w3.org/1999/xhtml">a button</button>
|
||||
</content>
|
||||
</binding>
|
||||
</bindings>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
/**
|
||||
* Insert a not accessible bound element containing an accessible element
|
||||
* in anonymous content.
|
||||
*/
|
||||
function insertBinding(aContainerID)
|
||||
{
|
||||
this.containerNode = getNode(aContainerID);
|
||||
|
||||
function getButtonFromBinding(aNode)
|
||||
{
|
||||
try { return document.getAnonymousNodes(aNode.firstChild)[0]; }
|
||||
catch (e) { return null; }
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SHOW, getButtonFromBinding, this.containerNode),
|
||||
new invokerChecker(EVENT_REORDER, this.containerNode)
|
||||
];
|
||||
|
||||
this.invoke = function insertBinding_invoke()
|
||||
{
|
||||
var span = document.createElement("span");
|
||||
span.setAttribute("style", "-moz-binding:url(#button)");
|
||||
this.containerNode.appendChild(span);
|
||||
}
|
||||
|
||||
this.getID = function insertBinding_getID()
|
||||
{
|
||||
return "insert button binding";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new insertBinding("testContainer"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=646369"
|
||||
title="UpdateTree should rely on accessible tree walker rather than DOM tree traversal">
|
||||
Mozilla Bug 646369</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<div id="testContainer"></div>
|
||||
</body>
|
||||
</html>
|
||||
123
accessible/tests/mochitest/events/test_namechange.html
Normal file
123
accessible/tests/mochitest/events/test_namechange.html
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible name change event 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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function setAttr(aID, aAttr, aValue, aChecker)
|
||||
{
|
||||
this.eventSeq = [ aChecker ];
|
||||
this.invoke = function setAttr_invoke()
|
||||
{
|
||||
getNode(aID).setAttribute(aAttr, aValue);
|
||||
}
|
||||
|
||||
this.getID = function setAttr_getID()
|
||||
{
|
||||
return "set attr '" + aAttr + "', value '" + aValue + "'";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* No name change on an accessible, because the accessible is recreated.
|
||||
*/
|
||||
function setAttr_recreate(aID, aAttr, aValue)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_HIDE, getAccessible(aID)),
|
||||
new invokerChecker(EVENT_SHOW, aID)
|
||||
];
|
||||
this.invoke = function setAttr_recreate_invoke()
|
||||
{
|
||||
todo(false, "No accessible recreation should happen, just name change event");
|
||||
getNode(aID).setAttribute(aAttr, aValue);
|
||||
}
|
||||
|
||||
this.getID = function setAttr_recreate_getID()
|
||||
{
|
||||
return "set attr '" + aAttr + "', value '" + aValue + "'";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debuggin
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new setAttr("tst1", "aria-label", "hi",
|
||||
new invokerChecker(EVENT_NAME_CHANGE, "tst1")));
|
||||
gQueue.push(new setAttr("tst1", "aria-labelledby", "display",
|
||||
new unexpectedInvokerChecker(EVENT_NAME_CHANGE, "tst1")));
|
||||
gQueue.push(new setAttr("tst1", "alt", "alt",
|
||||
new unexpectedInvokerChecker(EVENT_NAME_CHANGE, "tst1")));
|
||||
gQueue.push(new setAttr("tst1", "title", "title",
|
||||
new unexpectedInvokerChecker(EVENT_NAME_CHANGE, "tst1")));
|
||||
|
||||
gQueue.push(new setAttr("tst2", "aria-labelledby", "display",
|
||||
new invokerChecker(EVENT_NAME_CHANGE, "tst2")));
|
||||
gQueue.push(new setAttr("tst2", "alt", "alt",
|
||||
new unexpectedInvokerChecker(EVENT_NAME_CHANGE, "tst2")));
|
||||
gQueue.push(new setAttr("tst2", "title", "title",
|
||||
new unexpectedInvokerChecker(EVENT_NAME_CHANGE, "tst2")));
|
||||
|
||||
gQueue.push(new setAttr_recreate("tst3", "alt", "alt"));
|
||||
gQueue.push(new setAttr("tst3", "title", "title",
|
||||
new unexpectedInvokerChecker(EVENT_NAME_CHANGE, "tst3")));
|
||||
|
||||
gQueue.push(new setAttr("tst4", "title", "title",
|
||||
new invokerChecker(EVENT_NAME_CHANGE, "tst4")));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=991969"
|
||||
title="Event not fired when description changes">
|
||||
Bug 991969
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<img id="tst1">
|
||||
<img id="tst2">
|
||||
<img id="tst3">
|
||||
<img id="tst4">
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
92
accessible/tests/mochitest/events/test_namechange.xul
Normal file
92
accessible/tests/mochitest/events/test_namechange.xul
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
<?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">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.js"/>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
/**
|
||||
* Check name changed a11y event.
|
||||
*/
|
||||
function nameChangeChecker(aMsg, aID)
|
||||
{
|
||||
this.type = EVENT_NAME_CHANGE;
|
||||
|
||||
function targetGetter()
|
||||
{
|
||||
return getAccessible(aID);
|
||||
}
|
||||
Object.defineProperty(this, "target", { get: targetGetter });
|
||||
|
||||
this.getID = function getID()
|
||||
{
|
||||
return aMsg + " name changed";
|
||||
}
|
||||
}
|
||||
|
||||
function changeRichListItemChild()
|
||||
{
|
||||
this.invoke = function changeRichListItemChild_invoke()
|
||||
{
|
||||
getNode('childcontent').setAttribute('value', 'Changed.');
|
||||
}
|
||||
|
||||
this.eventSeq =
|
||||
[
|
||||
new nameChangeChecker("changeRichListItemChild: ", "listitem")
|
||||
];
|
||||
|
||||
this.getID = function changeRichListItemChild_getID()
|
||||
{
|
||||
return "changeRichListItemChild";
|
||||
}
|
||||
}
|
||||
|
||||
function doTest()
|
||||
{
|
||||
var queue = new eventQueue();
|
||||
queue.push(new changeRichListItemChild());
|
||||
queue.invoke();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<vbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=986054"
|
||||
title="Propagate name change events">
|
||||
Mozilla Bug 986054
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<richlistbox>
|
||||
<richlistitem id="listitem">
|
||||
<description id="childcontent" value="This will be changed."/>
|
||||
</richlistitem>
|
||||
</richlistbox>
|
||||
</vbox>
|
||||
</window>
|
||||
131
accessible/tests/mochitest/events/test_scroll.xul
Normal file
131
accessible/tests/mochitest/events/test_scroll.xul
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
<?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">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.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"
|
||||
src="../browser.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Tests
|
||||
|
||||
function getAnchorJumpInTabDocument(aTabIdx)
|
||||
{
|
||||
var tabDoc = aTabIdx ? tabDocumentAt(aTabIdx) : currentTabDocument();
|
||||
return tabDoc.querySelector("a[name='link1']");
|
||||
}
|
||||
|
||||
function loadTab(aURL)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
|
||||
new asyncInvokerChecker(EVENT_SCROLLING_START, getAnchorJumpInTabDocument)
|
||||
];
|
||||
|
||||
this.invoke = function loadTab_invoke()
|
||||
{
|
||||
tabBrowser().loadURI(aURL);
|
||||
}
|
||||
|
||||
this.getID = function loadTab_getID()
|
||||
{
|
||||
return "load tab: " + aURL;
|
||||
}
|
||||
}
|
||||
|
||||
function loadTabInBackground(aURL)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
|
||||
];
|
||||
|
||||
this.unexpectedEventSeq = [
|
||||
new invokerChecker(EVENT_SCROLLING_START, getAnchorJumpInTabDocument, 1)
|
||||
];
|
||||
|
||||
this.invoke = function loadTabInBackground_invoke()
|
||||
{
|
||||
tabBrowser().loadOneTab(aURL, null, "", null, true);
|
||||
}
|
||||
|
||||
this.getID = function loadTabInBackground_getID()
|
||||
{
|
||||
return "load tab in background: " + aURL;
|
||||
}
|
||||
}
|
||||
|
||||
function switchToBackgroundTab()
|
||||
{
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SCROLLING_START, getAnchorJumpInTabDocument)
|
||||
];
|
||||
|
||||
this.invoke = function switchToBackgroundTab_invoke()
|
||||
{
|
||||
tabBrowser().selectTabAtIndex(1);
|
||||
}
|
||||
|
||||
this.getID = function switchToBackgroundTab_getID()
|
||||
{
|
||||
return "switch to background tab";
|
||||
}
|
||||
}
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
var url = "http://mochi.test:8888/a11y/accessible/tests/mochitest/events/scroll.html#link1";
|
||||
gQueue.push(new loadTab(url));
|
||||
gQueue.push(new loadTabInBackground(url));
|
||||
gQueue.push(new switchToBackgroundTab());
|
||||
gQueue.onFinish = function() { closeBrowserWindow(); }
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
openBrowserWindow(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<vbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=691734"
|
||||
title="Make sure scrolling start event is fired when document receive focus">
|
||||
Mozilla Bug 691734
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox id="eventdump"></vbox>
|
||||
</vbox>
|
||||
</window>
|
||||
91
accessible/tests/mochitest/events/test_scroll_caret.xul
Normal file
91
accessible/tests/mochitest/events/test_scroll_caret.xul
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
<?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">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/chrome-harness.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"
|
||||
src="../browser.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Tests
|
||||
|
||||
function getAnchorJumpInTabDocument(aTabIdx)
|
||||
{
|
||||
var tabDoc = aTabIdx ? tabDocumentAt(aTabIdx) : currentTabDocument();
|
||||
return tabDoc.querySelector("h1[id='heading_1']");
|
||||
}
|
||||
|
||||
function loadTab(aURL)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, currentTabDocument),
|
||||
new asyncCaretMoveChecker(0, getAnchorJumpInTabDocument)
|
||||
];
|
||||
|
||||
this.invoke = function loadTab_invoke()
|
||||
{
|
||||
tabBrowser().loadURI(aURL);
|
||||
}
|
||||
|
||||
this.getID = function loadTab_getID()
|
||||
{
|
||||
return "load tab: " + aURL;
|
||||
}
|
||||
}
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
var gQueue = null;
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
var url = "http://mochi.test:8888/a11y/accessible/tests/mochitest/events/scroll.html#heading_1";
|
||||
gQueue.push(new loadTab(url));
|
||||
gQueue.onFinish = function() { closeBrowserWindow(); }
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
openBrowserWindow(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<vbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1056459"
|
||||
title="Make sure caret move event is fired when document receive focus">
|
||||
Mozilla Bug 1056459
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox id="eventdump"></vbox>
|
||||
</vbox>
|
||||
</window>
|
||||
118
accessible/tests/mochitest/events/test_selection.html
Normal file
118
accessible/tests/mochitest/events/test_selection.html
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible selection event 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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debuggin
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
// open combobox
|
||||
gQueue.push(new synthClick("combobox",
|
||||
new invokerChecker(EVENT_FOCUS, "cb1_item1")));
|
||||
gQueue.push(new synthDownKey("cb1_item1",
|
||||
selChangeSeq("cb1_item1", "cb1_item2")));
|
||||
|
||||
// closed combobox
|
||||
gQueue.push(new synthEscapeKey("combobox",
|
||||
new invokerChecker(EVENT_FOCUS, "combobox")));
|
||||
gQueue.push(new synthDownKey("cb1_item2",
|
||||
selChangeSeq("cb1_item2", "cb1_item3")));
|
||||
|
||||
// listbox
|
||||
gQueue.push(new synthClick("lb1_item1",
|
||||
new invokerChecker(EVENT_SELECTION, "lb1_item1")));
|
||||
gQueue.push(new synthDownKey("lb1_item1",
|
||||
selChangeSeq("lb1_item1", "lb1_item2")));
|
||||
|
||||
// multiselectable listbox
|
||||
gQueue.push(new synthClick("lb2_item1",
|
||||
selChangeSeq(null, "lb2_item1")));
|
||||
gQueue.push(new synthDownKey("lb2_item1",
|
||||
selAddSeq("lb2_item2"),
|
||||
{ shiftKey: true }));
|
||||
gQueue.push(new synthUpKey("lb2_item2",
|
||||
selRemoveSeq("lb2_item2"),
|
||||
{ shiftKey: true }));
|
||||
gQueue.push(new synthKey("lb2_item1", " ", { ctrlKey: true },
|
||||
selRemoveSeq("lb2_item1")));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=414302"
|
||||
title="Incorrect selection events in HTML, XUL and ARIA">
|
||||
Bug 414302
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=810268"
|
||||
title="There's no way to know unselected item when selection in single selection was changed">
|
||||
Bug 810268
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<select id="combobox">
|
||||
<option id="cb1_item1" value="mushrooms">mushrooms
|
||||
<option id="cb1_item2" value="greenpeppers">green peppers
|
||||
<option id="cb1_item3" value="onions" id="onions">onions
|
||||
<option id="cb1_item4" value="tomatoes">tomatoes
|
||||
<option id="cb1_item5" value="olives">olives
|
||||
</select>
|
||||
|
||||
<select id="listbox" size=5>
|
||||
<option id="lb1_item1" value="mushrooms">mushrooms
|
||||
<option id="lb1_item2" value="greenpeppers">green peppers
|
||||
<option id="lb1_item3" value="onions" id="onions">onions
|
||||
<option id="lb1_item4" value="tomatoes">tomatoes
|
||||
<option id="lb1_item5" value="olives">olives
|
||||
</select>
|
||||
|
||||
<p>Pizza</p>
|
||||
<select id="listbox2" multiple size=5>
|
||||
<option id="lb2_item1" value="mushrooms">mushrooms
|
||||
<option id="lb2_item2" value="greenpeppers">green peppers
|
||||
<option id="lb2_item3" value="onions" id="onions">onions
|
||||
<option id="lb2_item4" value="tomatoes">tomatoes
|
||||
<option id="lb2_item5" value="olives">olives
|
||||
</select>
|
||||
</body>
|
||||
</html>
|
||||
255
accessible/tests/mochitest/events/test_selection.xul
Normal file
255
accessible/tests/mochitest/events/test_selection.xul
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
<?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="Selection event 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="chrome://mochikit/content/tests/SimpleTest/EventUtils.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">
|
||||
function advanceTab(aTabsID, aDirection, aNextTabID)
|
||||
{
|
||||
var eventSeq1 = [
|
||||
new invokerChecker(EVENT_SELECTION, aNextTabID)
|
||||
]
|
||||
defineScenario(this, eventSeq1);
|
||||
|
||||
var eventSeq2 = [
|
||||
new invokerChecker(EVENT_HIDE, getAccessible(aNextTabID)),
|
||||
new invokerChecker(EVENT_SHOW, aNextTabID)
|
||||
];
|
||||
defineScenario(this, eventSeq2);
|
||||
|
||||
this.invoke = function advanceTab_invoke()
|
||||
{
|
||||
todo(false, "No accessible recreation should happen, just selection event");
|
||||
getNode(aTabsID).advanceSelectedTab(aDirection, true);
|
||||
}
|
||||
|
||||
this.getID = function synthFocus_getID()
|
||||
{
|
||||
return "advanceTab on " + prettyName(aTabsID) + " to " + prettyName(aNextTabID);
|
||||
}
|
||||
}
|
||||
|
||||
function select4FirstItems(aID)
|
||||
{
|
||||
this.listboxNode = getNode(aID);
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SELECTION_ADD, this.listboxNode.getItemAtIndex(0)),
|
||||
new invokerChecker(EVENT_SELECTION_ADD, this.listboxNode.getItemAtIndex(1)),
|
||||
new invokerChecker(EVENT_SELECTION_ADD, this.listboxNode.getItemAtIndex(2)),
|
||||
new invokerChecker(EVENT_SELECTION_ADD, this.listboxNode.getItemAtIndex(3))
|
||||
];
|
||||
|
||||
this.invoke = function select4FirstItems_invoke()
|
||||
{
|
||||
synthesizeKey("VK_DOWN", { shiftKey: true }); // selects two items
|
||||
synthesizeKey("VK_DOWN", { shiftKey: true });
|
||||
synthesizeKey("VK_DOWN", { shiftKey: true });
|
||||
}
|
||||
|
||||
this.getID = function select4FirstItems_getID()
|
||||
{
|
||||
return "select 4 first items for " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function unselect4FirstItems(aID)
|
||||
{
|
||||
this.listboxNode = getNode(aID);
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SELECTION_REMOVE, this.listboxNode.getItemAtIndex(3)),
|
||||
new invokerChecker(EVENT_SELECTION_REMOVE, this.listboxNode.getItemAtIndex(2)),
|
||||
new invokerChecker(EVENT_SELECTION_REMOVE, this.listboxNode.getItemAtIndex(1)),
|
||||
new invokerChecker(EVENT_SELECTION_REMOVE, this.listboxNode.getItemAtIndex(0))
|
||||
];
|
||||
|
||||
this.invoke = function unselect4FirstItems_invoke()
|
||||
{
|
||||
synthesizeKey("VK_UP", { shiftKey: true });
|
||||
synthesizeKey("VK_UP", { shiftKey: true });
|
||||
synthesizeKey("VK_UP", { shiftKey: true });
|
||||
synthesizeKey(" ", { ctrlKey: true }); // unselect first item
|
||||
}
|
||||
|
||||
this.getID = function unselect4FirstItems_getID()
|
||||
{
|
||||
return "unselect 4 first items for " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function selectAllItems(aID)
|
||||
{
|
||||
this.listboxNode = getNode(aID);
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SELECTION_WITHIN, getAccessible(this.listboxNode))
|
||||
];
|
||||
|
||||
this.invoke = function selectAllItems_invoke()
|
||||
{
|
||||
synthesizeKey("VK_END", { shiftKey: true });
|
||||
}
|
||||
|
||||
this.getID = function selectAllItems_getID()
|
||||
{
|
||||
return "select all items for " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function unselectAllItemsButFirst(aID)
|
||||
{
|
||||
this.listboxNode = getNode(aID);
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SELECTION_WITHIN, getAccessible(this.listboxNode))
|
||||
];
|
||||
|
||||
this.invoke = function unselectAllItemsButFirst_invoke()
|
||||
{
|
||||
synthesizeKey("VK_HOME", { shiftKey: true });
|
||||
}
|
||||
|
||||
this.getID = function unselectAllItemsButFirst_getID()
|
||||
{
|
||||
return "unselect all items for " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function unselectSelectItem(aID)
|
||||
{
|
||||
this.listboxNode = getNode(aID);
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SELECTION_REMOVE, this.listboxNode.getItemAtIndex(0)),
|
||||
new invokerChecker(EVENT_SELECTION_ADD, this.listboxNode.getItemAtIndex(0))
|
||||
];
|
||||
|
||||
this.invoke = function unselectSelectItem_invoke()
|
||||
{
|
||||
synthesizeKey(" ", { ctrlKey: true }); // select item
|
||||
synthesizeKey(" ", { ctrlKey: true }); // unselect item
|
||||
}
|
||||
|
||||
this.getID = function unselectSelectItem_getID()
|
||||
{
|
||||
return "unselect and then select first item for " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
|
||||
//enableLogging("events");
|
||||
//gA11yEventDumpToConsole = true; // debuggin
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// tabbox
|
||||
gQueue.push(new advanceTab("tabs", 1, "tab3"));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// listbox
|
||||
gQueue.push(new synthClick("lb1_item1",
|
||||
new invokerChecker(EVENT_SELECTION, "lb1_item1")));
|
||||
gQueue.push(new synthDownKey("lb1_item1",
|
||||
new invokerChecker(EVENT_SELECTION, "lb1_item2")));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// multiselectable listbox
|
||||
gQueue.push(new synthClick("lb2_item1",
|
||||
new invokerChecker(EVENT_SELECTION, "lb2_item1")));
|
||||
gQueue.push(new synthDownKey("lb2_item1",
|
||||
new invokerChecker(EVENT_SELECTION_ADD, "lb2_item2"),
|
||||
{ shiftKey: true }));
|
||||
gQueue.push(new synthUpKey("lb2_item2",
|
||||
new invokerChecker(EVENT_SELECTION_REMOVE, "lb2_item2"),
|
||||
{ shiftKey: true }));
|
||||
gQueue.push(new synthKey("lb2_item1", " ", { ctrlKey: true },
|
||||
new invokerChecker(EVENT_SELECTION_REMOVE, "lb2_item1")));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// selection event coalescence
|
||||
|
||||
// fire 4 selection_add events
|
||||
gQueue.push(new select4FirstItems("listbox2"));
|
||||
// fire 4 selection_remove events
|
||||
gQueue.push(new unselect4FirstItems("listbox2"));
|
||||
// fire selection_within event
|
||||
gQueue.push(new selectAllItems("listbox2"));
|
||||
// fire selection_within event
|
||||
gQueue.push(new unselectAllItemsButFirst("listbox2"));
|
||||
// fire selection_remove/add events
|
||||
gQueue.push(new unselectSelectItem("listbox2"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</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=414302"
|
||||
title="Incorrect selection events in HTML, XUL and ARIA">
|
||||
Mozilla Bug 414302
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<tabbox id="tabbox" selectedIndex="1">
|
||||
<tabs id="tabs">
|
||||
<tab id="tab1" label="tab1"/>
|
||||
<tab id="tab2" label="tab2"/>
|
||||
<tab id="tab3" label="tab3"/>
|
||||
<tab id="tab4" label="tab4"/>
|
||||
</tabs>
|
||||
<tabpanels>
|
||||
<tabpanel><!-- tabpanel First elements go here --></tabpanel>
|
||||
<tabpanel><button id="b1" label="b1"/></tabpanel>
|
||||
<tabpanel><button id="b2" label="b2"/></tabpanel>
|
||||
<tabpanel></tabpanel>
|
||||
</tabpanels>
|
||||
</tabbox>
|
||||
|
||||
<listbox id="listbox">
|
||||
<listitem id="lb1_item1" label="item1"/>
|
||||
<listitem id="lb1_item2" label="item2"/>
|
||||
</listbox>
|
||||
|
||||
<listbox id="listbox2" seltype="multiple">
|
||||
<listitem id="lb2_item1" label="item1"/>
|
||||
<listitem id="lb2_item2" label="item2"/>
|
||||
<listitem id="lb2_item3" label="item3"/>
|
||||
<listitem id="lb2_item4" label="item4"/>
|
||||
<listitem id="lb2_item5" label="item5"/>
|
||||
<listitem id="lb2_item6" label="item6"/>
|
||||
<listitem id="lb2_item7" label="item7"/>
|
||||
</listbox>
|
||||
|
||||
</hbox>
|
||||
</window>
|
||||
127
accessible/tests/mochitest/events/test_selection_aria.html
Normal file
127
accessible/tests/mochitest/events/test_selection_aria.html
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>ARIA selection event 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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function selectItem(aSelectID, aItemID)
|
||||
{
|
||||
this.selectNode = getNode(aSelectID);
|
||||
this.itemNode = getNode(aItemID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_SELECTION, aItemID)
|
||||
];
|
||||
|
||||
this.invoke = function selectItem_invoke() {
|
||||
var itemNode = this.selectNode.querySelector("*[aria-selected='true']");
|
||||
if (itemNode)
|
||||
itemNode.removeAttribute("aria-selected");
|
||||
|
||||
this.itemNode.setAttribute("aria-selected", "true");
|
||||
}
|
||||
|
||||
this.getID = function selectItem_getID()
|
||||
{
|
||||
return "select item " + prettyName(aItemID);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new selectItem("tablist", "tab1"));
|
||||
gQueue.push(new selectItem("tablist", "tab2"));
|
||||
|
||||
gQueue.push(new selectItem("tree", "treeitem1"));
|
||||
gQueue.push(new selectItem("tree", "treeitem1a"));
|
||||
gQueue.push(new selectItem("tree", "treeitem1a1"));
|
||||
|
||||
gQueue.push(new selectItem("tree2", "tree2item1"));
|
||||
gQueue.push(new selectItem("tree2", "tree2item1a"));
|
||||
gQueue.push(new selectItem("tree2", "tree2item1a1"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=569653"
|
||||
title="Make selection events async">
|
||||
Mozilla Bug 569653
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=804040"
|
||||
title="Selection event not fired when selection of ARIA tab changes">
|
||||
Mozilla Bug 804040
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div role="tablist" id="tablist">
|
||||
<div role="tab" id="tab1">tab1</div>
|
||||
<div role="tab" id="tab2">tab2</div>
|
||||
</div>
|
||||
|
||||
<div id="tree" role="tree">
|
||||
<div id="treeitem1" role="treeitem">Canada
|
||||
<div id="treeitem1a" role="treeitem">- Ontario
|
||||
<div id="treeitem1a1" role="treeitem">-- Toronto</div>
|
||||
</div>
|
||||
<div id="treeitem1b" role="treeitem">- Manitoba</div>
|
||||
</div>
|
||||
<div id="treeitem2" role="treeitem">Germany</div>
|
||||
<div id="treeitem3" role="treeitem">Russia</div>
|
||||
</div>
|
||||
|
||||
<div id="tree2" role="tree" aria-multiselectable="true">
|
||||
<div id="tree2item1" role="treeitem">Canada
|
||||
<div id="tree2item1a" role="treeitem">- Ontario
|
||||
<div id="tree2item1a1" role="treeitem">-- Toronto</div>
|
||||
</div>
|
||||
<div id="tree2item1b" role="treeitem">- Manitoba</div>
|
||||
</div>
|
||||
<div id="tree2item2" role="treeitem">Germany</div>
|
||||
<div id="tree2item3" role="treeitem">Russia</div>
|
||||
</div>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
287
accessible/tests/mochitest/events/test_statechange.html
Normal file
287
accessible/tests/mochitest/events/test_statechange.html
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible state change event 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="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function makeEditableDoc(aDocNode, aIsEnabled)
|
||||
{
|
||||
this.DOMNode = aDocNode;
|
||||
|
||||
this.invoke = function editabledoc_invoke() {
|
||||
// Note: this should fire an EVENT_STATE_CHANGE
|
||||
this.DOMNode.designMode = 'on';
|
||||
};
|
||||
|
||||
this.check = function editabledoc_check(aEvent) {
|
||||
|
||||
testStates(aDocNode, 0, EXT_STATE_EDITABLE);
|
||||
|
||||
var event = null;
|
||||
try {
|
||||
var event = aEvent.QueryInterface(nsIAccessibleStateChangeEvent);
|
||||
} catch (e) {
|
||||
ok(false, "State change event was expected");
|
||||
}
|
||||
|
||||
if (!event) { return; }
|
||||
|
||||
ok(event.isExtraState, "Extra state change was expected");
|
||||
is(event.state, EXT_STATE_EDITABLE, "Wrong state of statechange event");
|
||||
ok(event.isEnabled, "Expected editable state to be enabled");
|
||||
}
|
||||
|
||||
this.getID = function editabledoc_getID() {
|
||||
return prettyName(aDocNode) + " editable state changed";
|
||||
};
|
||||
}
|
||||
|
||||
function invalidInput(aNodeOrID)
|
||||
{
|
||||
this.DOMNode = getNode(aNodeOrID);
|
||||
|
||||
this.invoke = function invalidInput_invoke() {
|
||||
// Note: this should fire an EVENT_STATE_CHANGE
|
||||
this.DOMNode.value = "I am not an email";
|
||||
};
|
||||
|
||||
this.check = function invalidInput_check() {
|
||||
testStates(aNodeOrID, STATE_INVALID);
|
||||
};
|
||||
|
||||
this.getID = function invalidInput_getID() {
|
||||
return prettyName(aNodeOrID) + " became invalid";
|
||||
};
|
||||
}
|
||||
|
||||
function changeCheckInput(aID, aIsChecked)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new stateChangeChecker(STATE_CHECKED, false, aIsChecked, this.DOMNode)
|
||||
];
|
||||
|
||||
this.invoke = function changeCheckInput_invoke()
|
||||
{
|
||||
this.DOMNode.checked = aIsChecked;
|
||||
}
|
||||
|
||||
this.getID = function changeCheckInput_getID()
|
||||
{
|
||||
return "change checked state to '" + aIsChecked + "' for " +
|
||||
prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function stateChangeOnFileInput(aID, aAttr, aValue,
|
||||
aState, aIsExtraState, aIsEnabled)
|
||||
{
|
||||
this.fileControlNode = getNode(aID);
|
||||
this.fileControl = getAccessible(this.fileControlNode);
|
||||
this.browseButton = this.fileControl.firstChild;
|
||||
// No state change events on the label.
|
||||
|
||||
this.invoke = function stateChangeOnFileInput_invoke()
|
||||
{
|
||||
this.fileControlNode.setAttribute(aAttr, aValue);
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
new stateChangeChecker(aState, aIsExtraState, aIsEnabled, this.fileControl),
|
||||
new stateChangeChecker(aState, aIsExtraState, aIsEnabled, this.browseButton)
|
||||
];
|
||||
|
||||
this.getID = function stateChangeOnFileInput_getID()
|
||||
{
|
||||
return "inherited state change on file input on attribute '" + aAttr + "' change";
|
||||
}
|
||||
}
|
||||
|
||||
function dupeStateChange(aID, aAttr, aValue,
|
||||
aState, aIsExtraState, aIsEnabled)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new stateChangeChecker(aState, aIsExtraState, aIsEnabled, getNode(aID))
|
||||
];
|
||||
|
||||
this.invoke = function dupeStateChange_invoke()
|
||||
{
|
||||
getNode(aID).setAttribute(aAttr, aValue);
|
||||
getNode(aID).setAttribute(aAttr, aValue);
|
||||
}
|
||||
|
||||
this.getID = function dupeStateChange_getID()
|
||||
{
|
||||
return "duped state change events";
|
||||
}
|
||||
}
|
||||
|
||||
function oppositeStateChange(aID, aAttr, aState, aIsExtraState)
|
||||
{
|
||||
this.eventSeq = [ ];
|
||||
this.unexpectedEventSeq = [
|
||||
new stateChangeChecker(aState, aIsExtraState, false, getNode(aID)),
|
||||
new stateChangeChecker(aState, aIsExtraState, true, getNode(aID))
|
||||
];
|
||||
|
||||
this.invoke = function oppositeStateChange_invoke()
|
||||
{
|
||||
getNode(aID).setAttribute(aAttr, "false");
|
||||
getNode(aID).setAttribute(aAttr, "true");
|
||||
}
|
||||
|
||||
this.getID = function oppositeStateChange_getID()
|
||||
{
|
||||
return "opposite state change events";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change concomitant ARIA and native attribute at once.
|
||||
*/
|
||||
function echoingStateChange(aID, aARIAAttr, aAttr, aValue,
|
||||
aState, aIsExtraState, aIsEnabled)
|
||||
{
|
||||
this.eventSeq = [
|
||||
new stateChangeChecker(aState, aIsExtraState, aIsEnabled, getNode(aID))
|
||||
];
|
||||
|
||||
this.invoke = function echoingStateChange_invoke()
|
||||
{
|
||||
if (aValue == null) {
|
||||
getNode(aID).removeAttribute(aARIAAttr);
|
||||
getNode(aID).removeAttribute(aAttr);
|
||||
|
||||
} else {
|
||||
getNode(aID).setAttribute(aARIAAttr, aValue);
|
||||
getNode(aID).setAttribute(aAttr, aValue);
|
||||
}
|
||||
}
|
||||
|
||||
this.getID = function echoingStateChange_getID()
|
||||
{
|
||||
return "enchoing ARIA and native attributes change";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
// var gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true; // debug stuff
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue(nsIAccessibleEvent.EVENT_STATE_CHANGE);
|
||||
|
||||
// Test delayed editable state change
|
||||
var doc = document.getElementById("iframe").contentDocument;
|
||||
gQueue.push(new makeEditableDoc(doc));
|
||||
|
||||
// invalid state change
|
||||
gQueue.push(new invalidInput("email"));
|
||||
|
||||
// checked state change
|
||||
gQueue.push(new changeCheckInput("checkbox", true));
|
||||
gQueue.push(new changeCheckInput("checkbox", false));
|
||||
gQueue.push(new changeCheckInput("radio", true));
|
||||
gQueue.push(new changeCheckInput("radio", false));
|
||||
|
||||
// file input inherited state changes
|
||||
gQueue.push(new stateChangeOnFileInput("file", "aria-busy", "true",
|
||||
STATE_BUSY, false, true));
|
||||
gQueue.push(new stateChangeOnFileInput("file", "aria-required", "true",
|
||||
STATE_REQUIRED, false, true));
|
||||
gQueue.push(new stateChangeOnFileInput("file", "aria-invalid", "true",
|
||||
STATE_INVALID, false, true));
|
||||
|
||||
gQueue.push(new dupeStateChange("div", "aria-busy", "true",
|
||||
STATE_BUSY, false, true));
|
||||
gQueue.push(new oppositeStateChange("div", "aria-busy",
|
||||
STATE_BUSY, false));
|
||||
|
||||
gQueue.push(new echoingStateChange("text1", "aria-disabled", "disabled", "true",
|
||||
EXT_STATE_ENABLED, true, false));
|
||||
gQueue.push(new echoingStateChange("text1", "aria-disabled", "disabled", null,
|
||||
EXT_STATE_ENABLED, true, true));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=564471"
|
||||
title="Make state change events async">
|
||||
Bug 564471
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=555728"
|
||||
title="Fire a11y event based on HTML5 constraint validation">
|
||||
Bug 555728
|
||||
</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=788389"
|
||||
title="Fire statechange event whenever checked state is changed not depending on focused state">
|
||||
Bug 788389
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=926812"
|
||||
title="State change event not fired when both disabled and aria-disabled are toggled">
|
||||
Bug 926812
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="testContainer">
|
||||
<iframe id="iframe"></iframe>
|
||||
</div>
|
||||
|
||||
<input id="email" type='email'>
|
||||
|
||||
<input id="checkbox" type="checkbox">
|
||||
<input id="radio" type="radio">
|
||||
|
||||
<input id="file" type="file">
|
||||
|
||||
<div id="div"></div>
|
||||
|
||||
<input id="text1">
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
339
accessible/tests/mochitest/events/test_text.html
Normal file
339
accessible/tests/mochitest/events/test_text.html
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible mutation events 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="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
/**
|
||||
* Base text remove invoker and checker.
|
||||
*/
|
||||
function textRemoveInvoker(aID, aStart, aEnd, aText)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new textChangeChecker(aID, aStart, aEnd, aText, false)
|
||||
];
|
||||
}
|
||||
|
||||
function textInsertInvoker(aID, aStart, aEnd, aText)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new textChangeChecker(aID, aStart, aEnd, aText, true)
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove inaccessible child node containing accessibles.
|
||||
*/
|
||||
function removeChildSpan(aID)
|
||||
{
|
||||
this.__proto__ = new textRemoveInvoker(aID, 0, 5, "33322");
|
||||
|
||||
this.invoke = function removeChildSpan_invoke()
|
||||
{
|
||||
// remove HTML span, a first child of the node
|
||||
this.DOMNode.removeChild(this.DOMNode.firstChild);
|
||||
}
|
||||
|
||||
this.getID = function removeChildSpan_getID()
|
||||
{
|
||||
return "Remove inaccessible span containing accessible nodes" + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert inaccessible child node containing accessibles.
|
||||
*/
|
||||
function insertChildSpan(aID, aInsertAllTogether)
|
||||
{
|
||||
this.__proto__ = new textInsertInvoker(aID, 0, 5, "33322");
|
||||
|
||||
this.invoke = function insertChildSpan_invoke()
|
||||
{
|
||||
// <span><span>333</span><span>22</span></span>
|
||||
if (aInsertAllTogether) {
|
||||
var topSpan = document.createElement("span");
|
||||
var fSpan = document.createElement("span");
|
||||
fSpan.textContent = "333";
|
||||
topSpan.appendChild(fSpan);
|
||||
var sSpan = document.createElement("span");
|
||||
sSpan.textContent = "22";
|
||||
topSpan.appendChild(sSpan);
|
||||
|
||||
this.DOMNode.insertBefore(topSpan, this.DOMNode.childNodes[0]);
|
||||
|
||||
} else {
|
||||
var topSpan = document.createElement("span");
|
||||
this.DOMNode.insertBefore(topSpan, this.DOMNode.childNodes[0]);
|
||||
|
||||
var fSpan = document.createElement("span");
|
||||
fSpan.textContent = "333";
|
||||
topSpan.appendChild(fSpan);
|
||||
|
||||
var sSpan = document.createElement("span");
|
||||
sSpan.textContent = "22";
|
||||
topSpan.appendChild(sSpan);
|
||||
}
|
||||
}
|
||||
|
||||
this.getID = function insertChildSpan_getID()
|
||||
{
|
||||
return "Insert inaccessible span containing accessibles" +
|
||||
prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove child embedded accessible.
|
||||
*/
|
||||
function removeChildDiv(aID)
|
||||
{
|
||||
this.__proto__ = new textRemoveInvoker(aID, 5, 6, kEmbedChar);
|
||||
|
||||
this.invoke = function removeChildDiv_invoke()
|
||||
{
|
||||
var childDiv = this.DOMNode.childNodes[1];
|
||||
|
||||
// Ensure accessible is created to get text remove event when it's
|
||||
// removed.
|
||||
getAccessible(childDiv);
|
||||
|
||||
this.DOMNode.removeChild(childDiv);
|
||||
}
|
||||
|
||||
this.getID = function removeChildDiv_getID()
|
||||
{
|
||||
return "Remove accessible div from the middle of text accessible " +
|
||||
prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert child embedded accessible.
|
||||
*/
|
||||
function insertChildDiv(aID)
|
||||
{
|
||||
this.__proto__ = new textInsertInvoker(aID, 5, 6, kEmbedChar);
|
||||
|
||||
this.invoke = function insertChildDiv_invoke()
|
||||
{
|
||||
var childDiv = document.createElement("div");
|
||||
this.DOMNode.insertBefore(childDiv, this.DOMNode.childNodes[1]);
|
||||
}
|
||||
|
||||
this.getID = function insertChildDiv_getID()
|
||||
{
|
||||
return "Insert accessible div into the middle of text accessible " +
|
||||
prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove children from text container from first to last child or vice
|
||||
* versa.
|
||||
*/
|
||||
function removeChildren(aID, aLastToFirst, aStart, aEnd, aText)
|
||||
{
|
||||
this.__proto__ = new textRemoveInvoker(aID, aStart, aEnd, aText);
|
||||
|
||||
this.invoke = function removeChildren_invoke()
|
||||
{
|
||||
if (aLastToFirst) {
|
||||
while (this.DOMNode.firstChild)
|
||||
this.DOMNode.removeChild(this.DOMNode.lastChild);
|
||||
} else {
|
||||
while (this.DOMNode.firstChild)
|
||||
this.DOMNode.removeChild(this.DOMNode.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
this.getID = function removeChildren_getID()
|
||||
{
|
||||
return "remove children of " + prettyName(aID) +
|
||||
(aLastToFirst ? " from last to first" : " from first to last");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove text from HTML input.
|
||||
*/
|
||||
function removeTextFromInput(aID, aStart, aEnd, aText)
|
||||
{
|
||||
this.__proto__ = new textRemoveInvoker(aID, aStart, aEnd, aText);
|
||||
|
||||
this.eventSeq.push(new invokerChecker(EVENT_TEXT_VALUE_CHANGE,
|
||||
this.DOMNode));
|
||||
|
||||
this.invoke = function removeTextFromInput_invoke()
|
||||
{
|
||||
const nsIDOMNSEditableElement =
|
||||
Components.interfaces.nsIDOMNSEditableElement;
|
||||
|
||||
this.DOMNode.focus();
|
||||
this.DOMNode.setSelectionRange(aStart, aEnd);
|
||||
|
||||
synthesizeKey("VK_DELETE", {});
|
||||
}
|
||||
|
||||
this.getID = function removeTextFromInput_getID()
|
||||
{
|
||||
return "Remove text from " + aStart + " to " + aEnd + " for " +
|
||||
prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add text into HTML input.
|
||||
*/
|
||||
function insertTextIntoInput(aID, aStart, aEnd, aText)
|
||||
{
|
||||
this.__proto__ = new textInsertInvoker(aID, aStart, aEnd, aText);
|
||||
|
||||
this.eventSeq.push(new invokerChecker(EVENT_TEXT_VALUE_CHANGE,
|
||||
this.DOMNode));
|
||||
|
||||
this.invoke = function insertTextIntoInput_invoke()
|
||||
{
|
||||
this.DOMNode.focus();
|
||||
synthesizeKey("a", {});
|
||||
}
|
||||
|
||||
this.getID = function insertTextIntoInput_getID()
|
||||
{
|
||||
return "Insert text to " + aStart + " for " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove text data from text node of editable area.
|
||||
*/
|
||||
function removeTextFromEditable(aID, aStart, aEnd, aText, aTextNode)
|
||||
{
|
||||
this.__proto__ = new textRemoveInvoker(aID, aStart, aEnd, aText);
|
||||
|
||||
this.invoke = function removeTextFromEditable_invoke()
|
||||
{
|
||||
this.DOMNode.focus();
|
||||
|
||||
var selection = window.getSelection();
|
||||
var range = document.createRange();
|
||||
range.setStart(this.textNode, aStart);
|
||||
range.setEnd(this.textNode, aEnd);
|
||||
selection.addRange(range);
|
||||
|
||||
synthesizeKey("VK_DELETE", {});
|
||||
}
|
||||
|
||||
this.getID = function removeTextFromEditable_getID()
|
||||
{
|
||||
return "Remove text from " + aStart + " to " + aEnd + " for " +
|
||||
prettyName(aID);
|
||||
}
|
||||
|
||||
this.textNode = getNode(aTextNode);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
gA11yEventDumpToConsole = true; // debugging
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
// Text remove event on inaccessible child HTML span removal containing
|
||||
// accessible text nodes.
|
||||
gQueue.push(new removeChildSpan("p"));
|
||||
gQueue.push(new insertChildSpan("p"), true);
|
||||
gQueue.push(new insertChildSpan("p"), false);
|
||||
|
||||
// Remove embedded character.
|
||||
gQueue.push(new removeChildDiv("div"));
|
||||
gQueue.push(new insertChildDiv("div"));
|
||||
|
||||
// Remove all children.
|
||||
var text = kEmbedChar + "txt" + kEmbedChar;
|
||||
gQueue.push(new removeChildren("div2", true, 0, 5, text));
|
||||
gQueue.push(new removeChildren("div3", false, 0, 5, text));
|
||||
|
||||
// Text remove from text node within hypertext accessible.
|
||||
gQueue.push(new removeTextFromInput("input", 1, 3, "al"));
|
||||
gQueue.push(new insertTextIntoInput("input", 1, 2, "a"));
|
||||
|
||||
// bug 570691
|
||||
todo(false, "Fix text change events from editable area, see bug 570691");
|
||||
//var textNode = getNode("editable").firstChild;
|
||||
//gQueue.push(new removeTextFromEditable("editable", 1, 3, "al", textNode));
|
||||
//textNode = getNode("editable2").firstChild.firstChild;
|
||||
//gQueue.push(new removeTextFromEditable("editable2", 1, 3, "al", textNode));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=566293"
|
||||
title=" wrong length of text remove event when inaccessible node containing accessible nodes is removed">
|
||||
Mozilla Bug 566293
|
||||
</a><br>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=570710"
|
||||
title="Avoid extra array traversal during text event creation">
|
||||
Mozilla Bug 570710
|
||||
</a><br>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=574003"
|
||||
title="Coalesce text events on nodes removal">
|
||||
Mozilla Bug 574003
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=575052"
|
||||
title="Cache text offsets within hypertext accessible">
|
||||
Mozilla Bug 575052
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=570275"
|
||||
title="Rework accessible tree update code">
|
||||
Mozilla Bug 570275
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<p id="p"><span><span>333</span><span>22</span></span>1111</p>
|
||||
<div id="div">hello<div>hello</div>hello</div>
|
||||
<div id="div2"><div>txt</div>txt<div>txt</div></div>
|
||||
<div id="div3"><div>txt</div>txt<div>txt</div></div>
|
||||
<input id="input" value="value">
|
||||
<div contentEditable="true" id="editable">value</div>
|
||||
<div contentEditable="true" id="editable2"><span>value</span></div>
|
||||
</body>
|
||||
</html>
|
||||
249
accessible/tests/mochitest/events/test_text_alg.html
Normal file
249
accessible/tests/mochitest/events/test_text_alg.html
Normal file
|
|
@ -0,0 +1,249 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible text update algorithm 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="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
const kRemoval = false;
|
||||
const kInsertion = true;
|
||||
const kUnexpected = true;
|
||||
|
||||
function changeText(aContainerID, aValue, aEventList)
|
||||
{
|
||||
this.containerNode = getNode(aContainerID);
|
||||
this.textNode = this.containerNode.firstChild;
|
||||
this.textData = this.textNode.data;
|
||||
|
||||
this.eventSeq = [ ];
|
||||
this.unexpectedEventSeq = [ ];
|
||||
|
||||
for (var i = 0; i < aEventList.length; i++) {
|
||||
var event = aEventList[i];
|
||||
|
||||
var isInserted = event[0];
|
||||
var str = event[1];
|
||||
var offset = event[2];
|
||||
var checker = new textChangeChecker(this.containerNode, offset,
|
||||
offset + str.length, str,
|
||||
isInserted);
|
||||
|
||||
if (event[3] == kUnexpected)
|
||||
this.unexpectedEventSeq.push(checker);
|
||||
else
|
||||
this.eventSeq.push(checker);
|
||||
}
|
||||
|
||||
this.invoke = function changeText_invoke()
|
||||
{
|
||||
this.textNode.data = aValue;
|
||||
}
|
||||
|
||||
this.getID = function changeText_getID()
|
||||
{
|
||||
return "change text '" + shortenString(this.textData) + "' -> '" +
|
||||
shortenString(this.textNode.data) + "' for " +
|
||||
prettyName(this.containerNode);
|
||||
}
|
||||
}
|
||||
|
||||
function expStr(x, doublings)
|
||||
{
|
||||
for (var i = 0; i < doublings; ++i)
|
||||
x = x + x;
|
||||
return x;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Do tests
|
||||
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// wqrema -> tqb: substitution coalesced with removal
|
||||
|
||||
var events = [
|
||||
[ kRemoval, "w", 0 ], // wqrema -> qrema
|
||||
[ kInsertion, "t", 0], // qrema -> tqrema
|
||||
[ kRemoval, "rema", 2 ], // tqrema -> tq
|
||||
[ kInsertion, "b", 2] // tq -> tqb
|
||||
];
|
||||
gQueue.push(new changeText("p1", "tqb", events));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// b -> insa: substitution coalesced with insertion (complex substitution)
|
||||
|
||||
events = [
|
||||
[ kRemoval, "b", 0 ], // b ->
|
||||
[ kInsertion, "insa", 0] // -> insa
|
||||
];
|
||||
gQueue.push(new changeText("p2", "insa", events));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// abc -> def: coalesced substitutions
|
||||
|
||||
events = [
|
||||
[ kRemoval, "abc", 0 ], // abc ->
|
||||
[ kInsertion, "def", 0] // -> def
|
||||
];
|
||||
gQueue.push(new changeText("p3", "def", events));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// abcabc -> abcDEFabc: coalesced insertions
|
||||
|
||||
events = [
|
||||
[ kInsertion, "DEF", 3] // abcabc -> abcDEFabc
|
||||
];
|
||||
gQueue.push(new changeText("p4", "abcDEFabc", events));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// abc -> defabc: insertion into begin
|
||||
|
||||
events = [
|
||||
[ kInsertion, "def", 0] // abc -> defabc
|
||||
];
|
||||
gQueue.push(new changeText("p5", "defabc", events));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// abc -> abcdef: insertion into end
|
||||
|
||||
events = [
|
||||
[ kInsertion, "def", 3] // abc -> abcdef
|
||||
];
|
||||
gQueue.push(new changeText("p6", "abcdef", events));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// defabc -> abc: removal from begin
|
||||
|
||||
events = [
|
||||
[ kRemoval, "def", 0] // defabc -> abc
|
||||
];
|
||||
gQueue.push(new changeText("p7", "abc", events));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// abcdef -> abc: removal from the end
|
||||
|
||||
events = [
|
||||
[ kRemoval, "def", 3] // abcdef -> abc
|
||||
];
|
||||
gQueue.push(new changeText("p8", "abc", events));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// abcDEFabc -> abcabc: coalesced removals
|
||||
|
||||
events = [
|
||||
[ kRemoval, "DEF", 3] // abcDEFabc -> abcabc
|
||||
];
|
||||
gQueue.push(new changeText("p9", "abcabc", events));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// !abcdef@ -> @axbcef!: insertion, deletion and substitutions
|
||||
|
||||
events = [
|
||||
[ kRemoval, "!", 0 ], // !abcdef@ -> abcdef@
|
||||
[ kInsertion, "@", 0], // abcdef@ -> @abcdef@
|
||||
[ kInsertion, "x", 2 ], // @abcdef@ -> @axbcdef@
|
||||
[ kRemoval, "d", 5], // @axbcdef@ -> @axbcef@
|
||||
[ kRemoval, "@", 7 ], // @axbcef@ -> @axbcef
|
||||
[ kInsertion, "!", 7 ], // @axbcef -> @axbcef!
|
||||
];
|
||||
gQueue.push(new changeText("p10", "@axbcef!", events));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// meilenstein -> levenshtein: insertion, complex and simple substitutions
|
||||
|
||||
events = [
|
||||
[ kRemoval, "m", 0 ], // meilenstein -> eilenstein
|
||||
[ kInsertion, "l", 0], // eilenstein -> leilenstein
|
||||
[ kRemoval, "il", 2 ], // leilenstein -> leenstein
|
||||
[ kInsertion, "v", 2], // leenstein -> levenstein
|
||||
[ kInsertion, "h", 6 ], // levenstein -> levenshtein
|
||||
];
|
||||
gQueue.push(new changeText("p11", "levenshtein", events));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// long strings, remove/insert pair as the old string was replaced on
|
||||
// new one
|
||||
|
||||
var longStr1 = expStr("x", 16);
|
||||
var longStr2 = expStr("X", 16);
|
||||
|
||||
var newStr = "a" + longStr1 + "b", insStr = longStr1, rmStr = "";
|
||||
events = [
|
||||
[ kRemoval, rmStr, 1, kUnexpected ],
|
||||
[ kInsertion, insStr, 1 ]
|
||||
];
|
||||
gQueue.push(new changeText("p12", newStr, events));
|
||||
|
||||
newStr = "a" + longStr2 + "b", insStr = longStr2, rmStr = longStr1;
|
||||
events = [
|
||||
[ kRemoval, rmStr, 1 ],
|
||||
[ kInsertion, insStr, 1]
|
||||
];
|
||||
gQueue.push(new changeText("p12", newStr, events));
|
||||
|
||||
newStr = "ab", insStr = "", rmStr = longStr2;
|
||||
events = [
|
||||
[ kRemoval, rmStr, 1 ],
|
||||
[ kInsertion, insStr, 1, kUnexpected ]
|
||||
];
|
||||
gQueue.push(new changeText("p12", newStr, events));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=626660"
|
||||
title="Cache rendered text on a11y side">
|
||||
Mozilla Bug 626660
|
||||
</a>
|
||||
<br>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<p id="p1">wqrema</p>
|
||||
<p id="p2">b</p>
|
||||
<p id="p3">abc</p>
|
||||
<p id="p4">abcabc</p>
|
||||
<p id="p5">abc</p>
|
||||
<p id="p6">abc</p>
|
||||
<p id="p7">defabc</p>
|
||||
<p id="p8">abcdef</p>
|
||||
<p id="p9">abcDEFabc</p>
|
||||
<p id="p10">!abcdef@</p>
|
||||
<p id="p11">meilenstein</p>
|
||||
<p id="p12">ab</p>
|
||||
</body>
|
||||
</html>
|
||||
115
accessible/tests/mochitest/events/test_textattrchange.html
Normal file
115
accessible/tests/mochitest/events/test_textattrchange.html
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Text attribute changed event for misspelled text</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"
|
||||
src="../attributes.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
const nsIDOMNSEditableElement =
|
||||
Components.interfaces.nsIDOMNSEditableElement;
|
||||
|
||||
Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm");
|
||||
|
||||
function spelledTextInvoker(aID)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_TEXT_ATTRIBUTE_CHANGED, this.DOMNode)
|
||||
];
|
||||
|
||||
this.invoke = function spelledTextInvoker_invoke()
|
||||
{
|
||||
var editor = this.DOMNode.QueryInterface(nsIDOMNSEditableElement).editor;
|
||||
var spellChecker = new InlineSpellChecker(editor);
|
||||
spellChecker.enabled = true;
|
||||
|
||||
//var spellchecker = editor.getInlineSpellChecker(true);
|
||||
//spellchecker.enableRealTimeSpell = true;
|
||||
|
||||
this.DOMNode.value = "valid text inalid tixt";
|
||||
}
|
||||
|
||||
this.finalCheck = function spelledTextInvoker_finalCheck()
|
||||
{
|
||||
var defAttrs = buildDefaultTextAttrs(this.DOMNode, kInputFontSize,
|
||||
kNormalFontWeight,
|
||||
kInputFontFamily);
|
||||
testDefaultTextAttrs(aID, defAttrs);
|
||||
|
||||
var attrs = { };
|
||||
var misspelledAttrs = {
|
||||
"invalid": "spelling"
|
||||
};
|
||||
|
||||
testTextAttrs(aID, 0, attrs, defAttrs, 0, 11);
|
||||
testTextAttrs(aID, 11, misspelledAttrs, defAttrs, 11, 17);
|
||||
testTextAttrs(aID, 17, attrs, defAttrs, 17, 18);
|
||||
testTextAttrs(aID, 18, misspelledAttrs, defAttrs, 18, 22);
|
||||
}
|
||||
|
||||
this.getID = function spelledTextInvoker_getID()
|
||||
{
|
||||
return "text attribute change for misspelled text";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
function doTests()
|
||||
{
|
||||
// Synth focus before spellchecking turning on to make sure editor
|
||||
// gets a time for initialization.
|
||||
|
||||
gQueue = new eventQueue();
|
||||
gQueue.push(new synthFocus("input"));
|
||||
gQueue.push(new spelledTextInvoker("input"));
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=345759"
|
||||
title="Implement text attributes">
|
||||
Mozilla Bug 345759
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<input id="input"/>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
86
accessible/tests/mochitest/events/test_textselchange.html
Normal file
86
accessible/tests/mochitest/events/test_textselchange.html
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible text selection change events 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="../text.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
var gQueue = null;
|
||||
|
||||
// gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
function getOnclickSeq(aID)
|
||||
{
|
||||
return [
|
||||
new caretMoveChecker(0, aID),
|
||||
new unexpectedInvokerChecker(EVENT_TEXT_SELECTION_CHANGED, aID)
|
||||
];
|
||||
}
|
||||
|
||||
function doTests()
|
||||
{
|
||||
// test caret move events and caret offsets
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new synthClick("c1_p1", getOnclickSeq("c1_p1")));
|
||||
gQueue.push(new synthDownKey("c1", new textSelectionChecker("c1", 0, 1), { shiftKey: true }));
|
||||
gQueue.push(new synthDownKey("c1", new textSelectionChecker("c1", 0, 2), { shiftKey: true }));
|
||||
|
||||
gQueue.push(new synthClick("ta1", getOnclickSeq("ta1")));
|
||||
gQueue.push(new synthRightKey("ta1",
|
||||
new textSelectionChecker("ta1", 0, 1),
|
||||
{ shiftKey: true }));
|
||||
gQueue.push(new synthLeftKey("ta1",
|
||||
[new textSelectionChecker("ta1", 0, 0),
|
||||
new caretMoveChecker(0, "ta1")]));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=762934"
|
||||
title="Text selection change event has a wrong target when selection is spanned through several objects">
|
||||
Bug 762934
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=956032"
|
||||
title="Text selection change event missed when selected text becomes unselected">
|
||||
Bug 956032
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="c1" contentEditable="true">
|
||||
<p id="c1_p1">paragraph</p>
|
||||
<p id="c1_p2">paragraph</p>
|
||||
</div>
|
||||
|
||||
<textarea id="ta1">Hello world</textarea>
|
||||
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
348
accessible/tests/mochitest/events/test_tree.xul
Normal file
348
accessible/tests/mochitest/events/test_tree.xul
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
<?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="DOM TreeRowCountChanged and a11y name change events.">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../treeview.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invoker's checkers
|
||||
|
||||
/**
|
||||
* Check TreeRowCountChanged event.
|
||||
*/
|
||||
function rowCountChangedChecker(aMsg, aIdx, aCount)
|
||||
{
|
||||
this.type = "TreeRowCountChanged";
|
||||
this.target = gTree;
|
||||
this.check = function check(aEvent)
|
||||
{
|
||||
var propBag = aEvent.detail.QueryInterface(Components.interfaces.nsIPropertyBag2);
|
||||
var index = propBag.getPropertyAsInt32("index");
|
||||
is(index, aIdx, "Wrong 'index' data of 'treeRowCountChanged' event.");
|
||||
|
||||
var count = propBag.getPropertyAsInt32("count");
|
||||
is(count, aCount, "Wrong 'count' data of 'treeRowCountChanged' event.");
|
||||
}
|
||||
this.getID = function getID()
|
||||
{
|
||||
return aMsg + "TreeRowCountChanged";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check TreeInvalidated event.
|
||||
*/
|
||||
function treeInvalidatedChecker(aMsg, aStartRow, aEndRow, aStartCol, aEndCol)
|
||||
{
|
||||
this.type = "TreeInvalidated";
|
||||
this.target = gTree;
|
||||
this.check = function check(aEvent)
|
||||
{
|
||||
var propBag = aEvent.detail.QueryInterface(Components.interfaces.nsIPropertyBag2);
|
||||
try {
|
||||
var startRow = propBag.getPropertyAsInt32("startrow");
|
||||
} catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
|
||||
startRow = null;
|
||||
}
|
||||
is(startRow, aStartRow,
|
||||
"Wrong 'startrow' of 'treeInvalidated' event on " + aMsg);
|
||||
|
||||
try {
|
||||
var endRow = propBag.getPropertyAsInt32("endrow");
|
||||
} catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
|
||||
endRow = null;
|
||||
}
|
||||
is(endRow, aEndRow,
|
||||
"Wrong 'endrow' of 'treeInvalidated' event on " + aMsg);
|
||||
|
||||
try {
|
||||
var startCol = propBag.getPropertyAsInt32("startcolumn");
|
||||
} catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
|
||||
startCol = null;
|
||||
}
|
||||
is(startCol, aStartCol,
|
||||
"Wrong 'startcolumn' of 'treeInvalidated' event on " + aMsg);
|
||||
|
||||
try {
|
||||
var endCol = propBag.getPropertyAsInt32("endcolumn");
|
||||
} catch (e if e.name == 'NS_ERROR_NOT_AVAILABLE') {
|
||||
endCol = null;
|
||||
}
|
||||
is(endCol, aEndCol,
|
||||
"Wrong 'endcolumn' of 'treeInvalidated' event on " + aMsg);
|
||||
}
|
||||
this.getID = function getID()
|
||||
{
|
||||
return "TreeInvalidated on " + aMsg;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check name changed a11y event.
|
||||
*/
|
||||
function nameChangeChecker(aMsg, aRow, aCol)
|
||||
{
|
||||
this.type = EVENT_NAME_CHANGE;
|
||||
|
||||
function targetGetter()
|
||||
{
|
||||
var acc = getAccessible(gTree);
|
||||
|
||||
var tableAcc = getAccessible(acc, [nsIAccessibleTable]);
|
||||
return tableAcc.getCellAt(aRow, aCol);
|
||||
}
|
||||
Object.defineProperty(this, "target", { get: targetGetter });
|
||||
|
||||
this.getID = function getID()
|
||||
{
|
||||
return aMsg + "name changed";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check name changed a11y event for a row.
|
||||
*/
|
||||
function rowNameChangeChecker(aMsg, aRow)
|
||||
{
|
||||
this.type = EVENT_NAME_CHANGE;
|
||||
|
||||
function targetGetter()
|
||||
{
|
||||
var acc = getAccessible(gTree);
|
||||
return acc.getChildAt(aRow + 1);
|
||||
}
|
||||
Object.defineProperty(this, "target", { get: targetGetter });
|
||||
|
||||
this.getID = function getID()
|
||||
{
|
||||
return aMsg + "name changed";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
/**
|
||||
* Set tree view.
|
||||
*/
|
||||
function setTreeView()
|
||||
{
|
||||
this.invoke = function setTreeView_invoke()
|
||||
{
|
||||
gTreeBox.view = gView;
|
||||
}
|
||||
|
||||
this.getID = function setTreeView_getID() { return "set tree view"; }
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, gTree)
|
||||
];
|
||||
};
|
||||
|
||||
/**
|
||||
* Insert row at 0 index and checks TreeRowCountChanged and TreeInvalidated
|
||||
* event.
|
||||
*/
|
||||
function insertRow()
|
||||
{
|
||||
this.invoke = function insertRow_invoke()
|
||||
{
|
||||
gView.appendItem("last");
|
||||
gTreeBox.rowCountChanged(0, 1);
|
||||
}
|
||||
|
||||
this.eventSeq =
|
||||
[
|
||||
new rowCountChangedChecker("insertRow: ", 0, 1),
|
||||
new treeInvalidatedChecker("insertRow", 0, 5, null, null)
|
||||
];
|
||||
|
||||
this.getID = function insertRow_getID()
|
||||
{
|
||||
return "insert row";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates first column and checks six name changed events for each
|
||||
* treeitem plus TreeInvalidated event.
|
||||
*/
|
||||
function invalidateColumn()
|
||||
{
|
||||
this.invoke = function invalidateColumn_invoke()
|
||||
{
|
||||
// Make sure accessible subtree of XUL tree is created otherwise no
|
||||
// name change events for cell accessibles are emitted.
|
||||
var tree = getAccessible(gTree);
|
||||
var child = tree.firstChild;
|
||||
var walkDown = true;
|
||||
while (child != tree) {
|
||||
if (walkDown) {
|
||||
var grandChild = child.firstChild;
|
||||
if (grandChild) {
|
||||
child = grandChild;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
var sibling = child.nextSibling;
|
||||
if (sibling) {
|
||||
child = sibling;
|
||||
walkDown = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
child = child.parent;
|
||||
walkDown = false;
|
||||
}
|
||||
|
||||
// Fire 'TreeInvalidated' event by InvalidateColumn()
|
||||
var firstCol = gTree.columns.getFirstColumn();
|
||||
for (var i = 0; i < gView.rowCount; i++)
|
||||
gView.setCellText(i, firstCol, "hey " + String(i) + "x0");
|
||||
|
||||
gTreeBox.invalidateColumn(firstCol);
|
||||
}
|
||||
|
||||
this.eventSeq =
|
||||
[
|
||||
new nameChangeChecker("invalidateColumn: ", 0, 0),
|
||||
new nameChangeChecker("invalidateColumn: ", 1, 0),
|
||||
new nameChangeChecker("invalidateColumn: ", 2, 0),
|
||||
new nameChangeChecker("invalidateColumn: ", 3, 0),
|
||||
new nameChangeChecker("invalidateColumn: ", 4, 0),
|
||||
new nameChangeChecker("invalidateColumn: ", 5, 0),
|
||||
new treeInvalidatedChecker("invalidateColumn", null, null, 0, 0)
|
||||
];
|
||||
|
||||
this.getID = function invalidateColumn_getID()
|
||||
{
|
||||
return "invalidate column";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates second row and checks name changed event for first treeitem
|
||||
* (note, there are two name changed events on linux due to different
|
||||
* accessible tree for xul:tree element) plus TreeInvalidated event.
|
||||
*/
|
||||
function invalidateRow()
|
||||
{
|
||||
this.invoke = function invalidateRow_invoke()
|
||||
{
|
||||
// Fire 'TreeInvalidated' event by InvalidateRow()
|
||||
var colCount = gTree.columns.count;
|
||||
var column = gTree.columns.getFirstColumn();
|
||||
while (column) {
|
||||
gView.setCellText(1, column, "aloha 1x" + String(column.index));
|
||||
column = column.getNext();
|
||||
}
|
||||
|
||||
gTreeBox.invalidateRow(1);
|
||||
}
|
||||
|
||||
this.eventSeq =
|
||||
[
|
||||
new nameChangeChecker("invalidateRow: ", 1, 0),
|
||||
new nameChangeChecker("invalidateRow: ", 1, 1),
|
||||
new rowNameChangeChecker("invalidateRow: ", 1),
|
||||
new treeInvalidatedChecker("invalidateRow", 1, 1, null, null)
|
||||
];
|
||||
|
||||
this.getID = function invalidateRow_getID()
|
||||
{
|
||||
return "invalidate row";
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
var gTree = null;
|
||||
var gTreeBox = null;
|
||||
var gTreeView = null;
|
||||
var gQueue = null;
|
||||
|
||||
// gA11yEventDumpID = "debug";
|
||||
gA11yEventDumpToConsole = true; // debuggin
|
||||
|
||||
function doTest()
|
||||
{
|
||||
// Initialize the tree
|
||||
gTree = document.getElementById("tree");
|
||||
gTreeBox = gTree.treeBoxObject;
|
||||
gView = new nsTableTreeView(5);
|
||||
|
||||
// Perform actions
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new setTreeView());
|
||||
gQueue.push(new insertRow());
|
||||
gQueue.push(new invalidateColumn());
|
||||
gQueue.push(new invalidateRow());
|
||||
|
||||
gQueue.invoke();
|
||||
}
|
||||
|
||||
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=368835"
|
||||
title="Fire TreeViewChanged/TreeRowCountChanged events.">
|
||||
Mozilla Bug 368835
|
||||
</a><br/>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=308564"
|
||||
title="No accessibility events when data in a tree row changes.">
|
||||
Mozilla Bug 308564
|
||||
</a><br/>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=739524"
|
||||
title="replace TreeViewChanged DOM event on direct call from XUL tree.">
|
||||
Mozilla Bug 739524
|
||||
</a><br/>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=743568"
|
||||
title="Thunderbird message list tree emitting incorrect focus signals after message deleted.">
|
||||
Mozilla Bug 743568
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox id="debug"/>
|
||||
<tree id="tree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col1" flex="1" primary="true" label="column"/>
|
||||
<treecol id="col2" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren id="treechildren"/>
|
||||
</tree>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
||||
255
accessible/tests/mochitest/events/test_valuechange.html
Normal file
255
accessible/tests/mochitest/events/test_valuechange.html
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible value change events 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="../events.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../value.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
/**
|
||||
* Do tests.
|
||||
*/
|
||||
var gQueue = null;
|
||||
|
||||
// Value change invoker
|
||||
function changeARIAValue(aNodeOrID, aValuenow, aValuetext)
|
||||
{
|
||||
this.DOMNode = getNode(aNodeOrID);
|
||||
this.eventSeq = [ new invokerChecker(aValuetext ?
|
||||
EVENT_TEXT_VALUE_CHANGE :
|
||||
EVENT_VALUE_CHANGE, this.DOMNode)
|
||||
];
|
||||
|
||||
this.invoke = function changeARIAValue_invoke() {
|
||||
|
||||
// Note: this should not fire an EVENT_VALUE_CHANGE when aria-valuetext
|
||||
// is not empty
|
||||
if (aValuenow != undefined)
|
||||
this.DOMNode.setAttribute("aria-valuenow", aValuenow);
|
||||
|
||||
// Note: this should always fire an EVENT_VALUE_CHANGE
|
||||
if (aValuetext != undefined)
|
||||
this.DOMNode.setAttribute("aria-valuetext", aValuetext);
|
||||
}
|
||||
|
||||
this.check = function changeARIAValue_check() {
|
||||
var acc = getAccessible(aNodeOrID, [nsIAccessibleValue]);
|
||||
if (!acc)
|
||||
return;
|
||||
|
||||
// Note: always test against valuetext first because the existence of
|
||||
// aria-valuetext takes precedence over aria-valuenow in gecko.
|
||||
is(acc.value, (aValuetext != undefined)? aValuetext : aValuenow,
|
||||
"Wrong value of " + prettyName(aNodeOrID));
|
||||
}
|
||||
|
||||
this.getID = function changeARIAValue_getID() {
|
||||
return prettyName(aNodeOrID) + " value changed";
|
||||
}
|
||||
}
|
||||
|
||||
function changeValue(aID, aValue)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
this.eventSeq = [new invokerChecker(EVENT_TEXT_VALUE_CHANGE,
|
||||
this.DOMNode)
|
||||
];
|
||||
|
||||
this.invoke = function changeValue_invoke()
|
||||
{
|
||||
this.DOMNode.value = aValue;
|
||||
}
|
||||
|
||||
this.check = function changeValue_check()
|
||||
{
|
||||
var acc = getAccessible(this.DOMNode);
|
||||
is(acc.value, aValue, "Wrong value for " + prettyName(aID));
|
||||
}
|
||||
|
||||
this.getID = function changeValue_getID()
|
||||
{
|
||||
return prettyName(aID) + " value changed";
|
||||
}
|
||||
}
|
||||
|
||||
function changeProgressValue(aID, aValue)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
this.eventSeq = [new invokerChecker(EVENT_VALUE_CHANGE, this.DOMNode)];
|
||||
|
||||
this.invoke = function changeProgressValue_invoke()
|
||||
{
|
||||
this.DOMNode.value = aValue;
|
||||
}
|
||||
|
||||
this.check = function changeProgressValue_check()
|
||||
{
|
||||
var acc = getAccessible(this.DOMNode);
|
||||
is(acc.value, aValue+"%", "Wrong value for " + prettyName(aID));
|
||||
}
|
||||
|
||||
this.getID = function changeProgressValue_getID()
|
||||
{
|
||||
return prettyName(aID) + " value changed";
|
||||
}
|
||||
}
|
||||
|
||||
function changeRangeValue(aID)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
this.eventSeq = [new invokerChecker(EVENT_VALUE_CHANGE, this.DOMNode)];
|
||||
|
||||
this.invoke = function changeRangeValue_invoke()
|
||||
{
|
||||
synthesizeMouse(getNode(aID), 5, 5, { });
|
||||
}
|
||||
|
||||
this.finalCheck = function changeRangeValue_finalCheck()
|
||||
{
|
||||
var acc = getAccessible(this.DOMNode);
|
||||
is(acc.value, "0", "Wrong value for " + prettyName(aID));
|
||||
}
|
||||
|
||||
this.getID = function changeRangeValue_getID()
|
||||
{
|
||||
return prettyName(aID) + " range value changed";
|
||||
}
|
||||
}
|
||||
|
||||
function changeSelectValue(aID, aKey, aValue)
|
||||
{
|
||||
this.eventSeq =
|
||||
[ new invokerChecker(EVENT_TEXT_VALUE_CHANGE, getAccessible(aID)) ];
|
||||
|
||||
this.invoke = function changeSelectValue_invoke()
|
||||
{
|
||||
getNode(aID).focus();
|
||||
synthesizeKey(aKey, {}, window);
|
||||
}
|
||||
|
||||
this.finalCheck = function changeSelectValue_finalCheck()
|
||||
{
|
||||
is(getAccessible(aID).value, aValue, "Wrong value for " + prettyName(aID));
|
||||
}
|
||||
|
||||
this.getID = function changeSelectValue_getID()
|
||||
{
|
||||
return `${prettyName(aID)} closed select value change on '${aKey}'' key press`;
|
||||
}
|
||||
}
|
||||
|
||||
//enableLogging("DOMEvents");
|
||||
//gA11yEventDumpToConsole = true;
|
||||
function doTests()
|
||||
{
|
||||
// Test initial values
|
||||
testValue("slider_vn", "5", 5, 0, 1000, 0);
|
||||
testValue("slider_vnvt", "plain", 0, 0, 5, 0);
|
||||
testValue("slider_vt", "hi", 0, 0, 3, 0);
|
||||
testValue("scrollbar", "5", 5, 0, 1000, 0);
|
||||
testValue("progress", "22%", 22, 0, 100, 0);
|
||||
testValue("range", "6", 6, 0, 10, 1);
|
||||
|
||||
// Test value change events
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new changeARIAValue("slider_vn", "6", undefined));
|
||||
gQueue.push(new changeARIAValue("slider_vt", undefined, "hey!"));
|
||||
gQueue.push(new changeARIAValue("slider_vnvt", "3", "sweet"));
|
||||
gQueue.push(new changeARIAValue("scrollbar", "6", undefined));
|
||||
|
||||
gQueue.push(new changeValue("combobox", "hello"));
|
||||
|
||||
gQueue.push(new changeProgressValue("progress", "50"));
|
||||
gQueue.push(new changeRangeValue("range"));
|
||||
|
||||
gQueue.push(new changeSelectValue("select", "VK_DOWN", "2nd"));
|
||||
gQueue.push(new changeSelectValue("select", "3", "3rd"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=478032"
|
||||
title=" Fire delayed value changed event for aria-valuetext changes">
|
||||
Mozilla Bug 478032
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=529289"
|
||||
title="We dont expose new aria role 'scrollbar' and property aria-orientation">
|
||||
Mozilla Bug 529289
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=559764"
|
||||
title="Make HTML5 input@type=range element accessible">
|
||||
Mozilla Bug 559764
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=703202"
|
||||
title="ARIA comboboxes don't fire value change events">
|
||||
Mozilla Bug 703202
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=761901"
|
||||
title=" HTML5 progress accessible should fire value change event">
|
||||
Mozilla Bug 761901
|
||||
</a>
|
||||
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<div id="eventdump"></div>
|
||||
|
||||
<!-- ARIA sliders -->
|
||||
<div id="slider_vn" role="slider" aria-valuenow="5"
|
||||
aria-valuemin="0" aria-valuemax="1000">slider</div>
|
||||
|
||||
<div id="slider_vt" role="slider" aria-valuetext="hi"
|
||||
aria-valuemin="0" aria-valuemax="3">greeting slider</div>
|
||||
|
||||
<div id="slider_vnvt" role="slider" aria-valuenow="0" aria-valuetext="plain"
|
||||
aria-valuemin="0" aria-valuemax="5">sweetness slider</div>
|
||||
|
||||
<!-- ARIA scrollbar -->
|
||||
<div id="scrollbar" role="scrollbar" aria-valuenow="5"
|
||||
aria-valuemin="0" aria-valuemax="1000">slider</div>
|
||||
|
||||
<!-- ARIA combobox -->
|
||||
<input id="combobox" role="combobox" aria-autocomplete="inline">
|
||||
|
||||
<!-- progress bar -->
|
||||
<progress id="progress" value="22" max="100"></progress>
|
||||
|
||||
<!-- input@type="range" -->
|
||||
<input type="range" id="range" min="0" max="10" value="6">
|
||||
|
||||
<select id="select">
|
||||
<option>1st</option>
|
||||
<option>2nd</option>
|
||||
<option>3rd</option>
|
||||
</select>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue