Bug 552368 - fire focus event on document accessible whenever the root or body element is focused, r=marcoz, davidb

This commit is contained in:
Alexander Surkov 2010-03-18 13:44:57 +08:00
parent c34dbe846c
commit 1f163b3cb8
4 changed files with 90 additions and 24 deletions

View File

@ -550,7 +550,21 @@ nsRootAccessible::FireCurrentFocusEvent()
nsCOMPtr<nsIDOMNode> targetNode;
accService->GetRelevantContentNodeFor(focusedNode,
getter_AddRefs(targetNode));
if (targetNode) {
// If the focused element is document element or HTML body element
// then simulate the focus event for the document.
nsCOMPtr<nsIContent> targetContent(do_QueryInterface(targetNode));
if (targetContent) {
nsCOMPtr<nsIDOMNode> document =
do_QueryInterface(targetContent->GetOwnerDoc());
if (targetContent == nsCoreUtils::GetRoleContent(document)) {
HandleEventWithTarget(event, document);
return;
}
}
// Otherwise simulate the focus event for currently focused node.
HandleEventWithTarget(event, targetNode);
}
}

View File

@ -599,7 +599,8 @@ function synthClick(aNodeOrID, aChecker, aEventType)
this.invoke = function synthClick_invoke()
{
// Scroll the node into view, otherwise synth click may fail.
this.DOMNode.scrollIntoView(true);
if (this.DOMNode instanceof nsIDOMNSHTMLElement)
this.DOMNode.scrollIntoView(true);
synthesizeMouse(this.DOMNode, 1, 1, {});
}
@ -610,6 +611,25 @@ function synthClick(aNodeOrID, aChecker, aEventType)
}
}
/**
* Mouse move invoker.
*/
function synthMouseMove(aNodeOrID, aChecker, aEventType)
{
this.__proto__ = new synthAction(aNodeOrID, aChecker, aEventType);
this.invoke = function synthMouseMove_invoke()
{
synthesizeMouse(this.DOMNode, 1, 1, { type: "mousemove" });
synthesizeMouse(this.DOMNode, 2, 2, { type: "mousemove" });
}
this.getID = function synthMouseMove_getID()
{
return prettyName(aNodeOrID) + " mouse move";
}
}
/**
* General key press invoker.
*/
@ -719,6 +739,25 @@ function synthFocus(aNodeOrID, aChecker, aEventType)
}
}
/**
* Focus invoker. Focus the HTML body of content document of iframe.
*/
function synthFocusOnFrame(aNodeOrID, aChecker, aEventType)
{
this.__proto__ = new synthAction(getNode(aNodeOrID).contentDocument,
aChecker, aEventType);
this.invoke = function synthFocus_invoke()
{
this.DOMNode.body.focus();
}
this.getID = function synthFocus_getID()
{
return prettyName(aNodeOrID) + " frame document focus";
}
}
/**
* Select all invoker.
*/

View File

@ -35,21 +35,6 @@
}
}
function focusDocument(aFrameID)
{
this.DOMNode = getNode(aFrameID).contentDocument;
this.invoke = function focusDocument_invoke()
{
this.DOMNode.body.focus();
}
this.getID = function focusDocument_getID()
{
return "Focus document of " + prettyName(aFrameID);
}
}
function focusElmWhileSubdocIsFocused(aID)
{
this.DOMNode = getNode(aID);
@ -92,7 +77,7 @@
gQueue.push(new openCloseDialog("button"));
var frameNode = getNode("editabledoc");
gQueue.push(new focusDocument(frameNode));
gQueue.push(new synthFocusOnFrame(frameNode));
gQueue.push(new openCloseDialog(frameNode.contentDocument));
gQueue.push(new focusElmWhileSubdocIsFocused("button"));

View File

@ -10,6 +10,8 @@
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="chrome://mochikit/content/a11y/accessible/common.js" />
@ -18,23 +20,29 @@
<script type="application/javascript">
/**
* Focus invoker.
* Click menu item invoker.
*/
function synthFocus(aNodeOrID)
function clickMenuItem(aNodeOrID, aFocusNodeOrID)
{
this.DOMNode = getNode(aNodeOrID);
this.DOMNode = getNode(aFocusNodeOrID);
this.invoke = function synthFocus_invoke()
this.invoke = function clickMenuItem_invoke()
{
this.DOMNode.focus();
synthesizeMouse(getNode(aNodeOrID), 1, 1, {});
}
this.getID = function synthFocus_getID() { return aNodeOrID + " focus"; }
this.getID = function clickMenuItem_getID()
{
return prettyName(aNodeOrID) + " click menu item";
}
}
/**
* Do tests.
*/
// gA11yEventDumpID = "eventdump"; // debug stuff
var gQueue = null;
function doTests()
@ -44,6 +52,11 @@
gQueue.push(new synthFocus("textbox"));
gQueue.push(new synthFocus("scale"));
gQueue.push(new synthFocusOnFrame("editabledoc"));
gQueue.push(new synthClick("menu"));
gQueue.push(new synthMouseMove("menuitem"));
gQueue.push(new clickMenuItem("menuitem",
getNode("editabledoc").contentDocument));
gQueue.invoke(); // Will call SimpleTest.finish();
}
@ -59,6 +72,11 @@
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">
@ -68,6 +86,16 @@
<vbox flex="1">
<textbox id="textbox" value="hello"/>
<scale id="scale" min="0" max="9" value="5"/>
<menubar>
<menu id="menu" label="menu">
<menupopup>
<menuitem id="menuitem" label="menuitem"/>
</menupopup>
</menu>
</menubar>
<iframe id="editabledoc" src="focus.html"/>
<vbox id="eventdump"/>
</vbox>
</hbox>
</window>