diff --git a/accessible/src/base/nsRootAccessible.cpp b/accessible/src/base/nsRootAccessible.cpp index a06a8ac40ae5..5e0e49e69f6c 100644 --- a/accessible/src/base/nsRootAccessible.cpp +++ b/accessible/src/base/nsRootAccessible.cpp @@ -550,7 +550,21 @@ nsRootAccessible::FireCurrentFocusEvent() nsCOMPtr 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 targetContent(do_QueryInterface(targetNode)); + if (targetContent) { + nsCOMPtr 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); } } diff --git a/accessible/tests/mochitest/events.js b/accessible/tests/mochitest/events.js index c53f7a74e563..6b8a60376345 100644 --- a/accessible/tests/mochitest/events.js +++ b/accessible/tests/mochitest/events.js @@ -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. */ diff --git a/accessible/tests/mochitest/events/test_focus.html b/accessible/tests/mochitest/events/test_focus.html index 3de8fc5863a5..00e91ed8d491 100644 --- a/accessible/tests/mochitest/events/test_focus.html +++ b/accessible/tests/mochitest/events/test_focus.html @@ -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")); diff --git a/accessible/tests/mochitest/events/test_focus.xul b/accessible/tests/mochitest/events/test_focus.xul index 6cefc831ea1f..133430879801 100644 --- a/accessible/tests/mochitest/events/test_focus.xul +++ b/accessible/tests/mochitest/events/test_focus.xul @@ -10,6 +10,8 @@ src="chrome://mochikit/content/MochiKit/packed.js" />