mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 07:42:04 +00:00
Bug 806996 part.6 Test if nsIWidget::OnIMEFocusChange() is called by nsTextStateManager properly r=smaug
This commit is contained in:
parent
074b802eac
commit
0bc2b12b46
@ -36,6 +36,8 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "TextComposition.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsAsyncDOMEvent.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::widget;
|
||||
@ -83,6 +85,7 @@ nsIContent* nsIMEStateManager::sContent = nullptr;
|
||||
nsPresContext* nsIMEStateManager::sPresContext = nullptr;
|
||||
bool nsIMEStateManager::sInstalledMenuKeyboardListener = false;
|
||||
bool nsIMEStateManager::sInSecureInputMode = false;
|
||||
bool nsIMEStateManager::sIsTestingIME = false;
|
||||
|
||||
nsTextStateManager* nsIMEStateManager::sTextStateObserver = nullptr;
|
||||
TextCompositionArray* nsIMEStateManager::sTextCompositions = nullptr;
|
||||
@ -730,6 +733,12 @@ nsTextStateManager::nsTextStateManager(nsIWidget* aWidget,
|
||||
}
|
||||
NS_ENSURE_TRUE_VOID(mRootContent);
|
||||
|
||||
if (nsIMEStateManager::sIsTestingIME) {
|
||||
nsIDocument* doc = aPresContext->Document();
|
||||
(new nsAsyncDOMEvent(doc, NS_LITERAL_STRING("MozIMEFocusIn"),
|
||||
false, false))->RunDOMEventWhenSafe();
|
||||
}
|
||||
|
||||
nsresult rv = mWidget->OnIMEFocusChange(true);
|
||||
if (rv == NS_ERROR_NOT_IMPLEMENTED) {
|
||||
return;
|
||||
@ -762,6 +771,11 @@ nsTextStateManager::ObserveEditableNode()
|
||||
void
|
||||
nsTextStateManager::Destroy(void)
|
||||
{
|
||||
if (nsIMEStateManager::sIsTestingIME && mEditableNode) {
|
||||
nsIDocument* doc = mEditableNode->OwnerDoc();
|
||||
(new nsAsyncDOMEvent(doc, NS_LITERAL_STRING("MozIMEFocusOut"),
|
||||
false, false))->RunDOMEventWhenSafe();
|
||||
}
|
||||
mWidget->OnIMEFocusChange(false);
|
||||
if (mObserving && mSel) {
|
||||
nsCOMPtr<nsISelectionPrivate> selPrivate(do_QueryInterface(mSel));
|
||||
@ -1028,6 +1042,12 @@ nsIMEStateManager::CreateTextStateManager()
|
||||
return;
|
||||
}
|
||||
|
||||
static bool sInitializeIsTestingIME = true;
|
||||
if (sInitializeIsTestingIME) {
|
||||
Preferences::AddBoolVarCache(&sIsTestingIME, "test.IME", false);
|
||||
sInitializeIsTestingIME = false;
|
||||
}
|
||||
|
||||
sTextStateObserver = new nsTextStateManager(widget, sPresContext, sContent);
|
||||
NS_ADDREF(sTextStateObserver);
|
||||
}
|
||||
|
@ -129,6 +129,7 @@ protected:
|
||||
static nsPresContext* sPresContext;
|
||||
static bool sInstalledMenuKeyboardListener;
|
||||
static bool sInSecureInputMode;
|
||||
static bool sIsTestingIME;
|
||||
|
||||
static nsTextStateManager* sTextStateObserver;
|
||||
|
||||
|
@ -115,6 +115,17 @@
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function hitEventLoop(aFunc, aTimes)
|
||||
{
|
||||
SpecialPowers.getDOMWindowUtils(window).advanceTimeAndRefresh(100);
|
||||
|
||||
if (--aTimes) {
|
||||
setTimeout(hitEventLoop, 0, aFunc, aTimes);
|
||||
} else {
|
||||
setTimeout(aFunc, 20);
|
||||
}
|
||||
}
|
||||
|
||||
var gUtils = window.
|
||||
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
@ -134,7 +145,7 @@ function runBasicTest(aIsEditable, aInDesignMode, aDescription)
|
||||
{
|
||||
function test(aTest)
|
||||
{
|
||||
function moveFocus(aTest)
|
||||
function moveFocus(aTest, aFocusEventHandler)
|
||||
{
|
||||
if (aInDesignMode) {
|
||||
if (document.activeElement) {
|
||||
@ -149,10 +160,28 @@ function runBasicTest(aIsEditable, aInDesignMode, aDescription)
|
||||
}
|
||||
var previousFocusedElement = gFM.focusedElement;
|
||||
var element = document.getElementById(aTest.id);
|
||||
var subDocument = null;
|
||||
if (element.contentDocument) {
|
||||
subDocument = element.contentDocument;
|
||||
element = element.contentDocument.documentElement;
|
||||
}
|
||||
|
||||
document.addEventListener("MozIMEFocusIn", aFocusEventHandler, true);
|
||||
document.addEventListener("MozIMEFocusOut", aFocusEventHandler, true);
|
||||
if (subDocument) {
|
||||
subDocument.addEventListener("MozIMEFocusIn", aFocusEventHandler, true);
|
||||
subDocument.addEventListener("MozIMEFocusOut", aFocusEventHandler, true);
|
||||
}
|
||||
|
||||
element.focus();
|
||||
|
||||
document.removeEventListener("MozIMEFocusIn", aFocusEventHandler, true);
|
||||
document.removeEventListener("MozIMEFocusOut", aFocusEventHandler, true);
|
||||
if (element.contentDocument) {
|
||||
subDocument.removeEventListener("MozIMEFocusIn", aFocusEventHandler, true);
|
||||
subDocument.removeEventListener("MozIMEFocusOut", aFocusEventHandler, true);
|
||||
}
|
||||
|
||||
var focusedElement = gFM.focusedElement;
|
||||
if (focusedElement) {
|
||||
var bindingParent = document.getBindingParent(focusedElement);
|
||||
@ -186,9 +215,90 @@ function runBasicTest(aIsEditable, aInDesignMode, aDescription)
|
||||
// IME Enabled state testing
|
||||
var enabled = gUtils.IME_STATUS_ENABLED;
|
||||
if (kIMEEnabledSupported) {
|
||||
if (!moveFocus(aTest)) {
|
||||
var mozIMEFocusInCount = 0;
|
||||
var mozIMEFocusOutCount = 0;
|
||||
var IMEHasFocus = false;
|
||||
|
||||
function onFocus(aEvent)
|
||||
{
|
||||
switch (aEvent.type) {
|
||||
case "MozIMEFocusIn":
|
||||
mozIMEFocusInCount++;
|
||||
IMEHasFocus = true;
|
||||
is(gUtils.IMEStatus, aTest.expectedEnabled,
|
||||
aDescription + ": " + aTest.description +
|
||||
", MozIMEFocusIn event must be fired after IME state is updated");
|
||||
break;
|
||||
case "MozIMEFocusOut":
|
||||
mozIMEFocusOutCount++;
|
||||
IMEHasFocus = false;
|
||||
is_not(gUtils.IMEStatus, aTest.expectedEnabled,
|
||||
aDescription + ": " + aTest.description +
|
||||
", MozIMEFocusOut event must be fired before IME state is updated");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!moveFocus(aTest, onFocus)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (aTest.focusable) {
|
||||
if (!aTest.focusEventNotFired) {
|
||||
if (aTest.expectedEnabled == gUtils.IME_STATUS_ENABLED || aTest.expectedEnabled == gUtils.IME_STATUS_PASSWORD) {
|
||||
var toDesignModeEditor = (document.activeElement.contentDocument &&
|
||||
(document.activeElement.contentDocument.designMode == "on"));
|
||||
if (aInDesignMode && toDesignModeEditor) {
|
||||
is(mozIMEFocusOutCount, 0,
|
||||
aDescription + ": " + aTest.description +
|
||||
", MozIMEFocusOut event shouldn't be fired in designMode since focus isn't moved from another editor");
|
||||
todo(mozIMEFocusInCount > 0,
|
||||
aDescription + ": " + aTest.description + ", MozIMEFocusIn event should be fired"); // bug 805766
|
||||
} else {
|
||||
ok(mozIMEFocusOutCount > 0,
|
||||
aDescription + ": " + aTest.description +
|
||||
", MozIMEFocusOut event should be fired for the previous focused editor");
|
||||
if (toDesignModeEditor) {
|
||||
todo(mozIMEFocusInCount > 0,
|
||||
aDescription + ": " + aTest.description + ", MozIMEFocusIn event should be fired"); // bug 805766
|
||||
} else {
|
||||
ok(mozIMEFocusInCount > 0,
|
||||
aDescription + ": " + aTest.description + ", MozIMEFocusIn event should be fired");
|
||||
}
|
||||
}
|
||||
if (aInDesignMode || toDesignModeEditor) { // bug 805766
|
||||
todo(IMEHasFocus,
|
||||
aDescription + ": " + aTest.description +
|
||||
", The latest MozIMEFocus* event must be MozIMEFocusIn");
|
||||
} else {
|
||||
ok(IMEHasFocus,
|
||||
aDescription + ": " + aTest.description +
|
||||
", The latest MozIMEFocus* event must be MozIMEFocusIn");
|
||||
}
|
||||
} else {
|
||||
is(mozIMEFocusInCount, 0,
|
||||
aDescription + ": " + aTest.description +
|
||||
", MozIMEFocusIn event shouldn't be fired");
|
||||
ok(mozIMEFocusOutCount > 0,
|
||||
aDescription + ": " + aTest.description +
|
||||
", MozIMEFocusOut event should be fired");
|
||||
ok(!IMEHasFocus,
|
||||
aDescription + ": " + aTest.description +
|
||||
", The latest MozIMEFocus* event must be MozIMEFocusOut");
|
||||
}
|
||||
} else {
|
||||
todo(false, aDescription + ": " + aTest.description +
|
||||
", In this case, focus event isn't fired, it's a bug, so, couldn't test it");
|
||||
}
|
||||
} else {
|
||||
is(mozIMEFocusInCount, 0,
|
||||
aDescription + ": " + aTest.description +
|
||||
", MozIMEFocusIn event shouldn't be fired at testing non-focusable element");
|
||||
is(mozIMEFocusOutCount, 0,
|
||||
aDescription + ": " + aTest.description +
|
||||
", MozIMEFocusOut event shouldn't be fired at testing non-focusable element");
|
||||
}
|
||||
|
||||
enabled = gUtils.IMEStatus;
|
||||
inputtype = gUtils.focusedInputType;
|
||||
is(enabled, aTest.expectedEnabled,
|
||||
@ -254,10 +364,12 @@ function runBasicTest(aIsEditable, aInDesignMode, aDescription)
|
||||
{ id: "checkbox",
|
||||
description: "input[type=checkbox]",
|
||||
focusable: !aInDesignMode,
|
||||
focusEventNotFired: aIsEditable && !aInDesignMode,
|
||||
expectedEnabled: kEnabledStateOnNonEditableElement },
|
||||
{ id: "radio",
|
||||
description: "input[type=radio]",
|
||||
focusable: !aInDesignMode,
|
||||
focusEventNotFired: aIsEditable && !aInDesignMode,
|
||||
expectedEnabled: kEnabledStateOnNonEditableElement },
|
||||
{ id: "submit",
|
||||
description: "input[type=submit]",
|
||||
@ -270,6 +382,7 @@ function runBasicTest(aIsEditable, aInDesignMode, aDescription)
|
||||
{ id: "file",
|
||||
description: "input[type=file]",
|
||||
focusable: !aInDesignMode,
|
||||
focusEventNotFired: aIsEditable && !aInDesignMode,
|
||||
expectedEnabled: kEnabledStateOnNonEditableElement },
|
||||
{ id: "button",
|
||||
description: "input[type=button]",
|
||||
@ -321,10 +434,12 @@ function runBasicTest(aIsEditable, aInDesignMode, aDescription)
|
||||
{ id: "select",
|
||||
description: "select (dropdown list)",
|
||||
focusable: !aInDesignMode,
|
||||
focusEventNotFired: aIsEditable && !aInDesignMode,
|
||||
expectedEnabled: kEnabledStateOnNonEditableElement },
|
||||
{ id: "select_multiple",
|
||||
description: "select (list box)",
|
||||
focusable: !aInDesignMode,
|
||||
focusEventNotFired: aIsEditable && !aInDesignMode,
|
||||
expectedEnabled: kEnabledStateOnNonEditableElement },
|
||||
|
||||
// a element
|
||||
@ -1242,11 +1357,66 @@ function runTestPasswordFieldOnDialog()
|
||||
}
|
||||
}
|
||||
|
||||
function runBug580388Tests(aCallback)
|
||||
{
|
||||
if (document.activeElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
|
||||
var input = document.getElementById("text");
|
||||
input.focus();
|
||||
input.style.overflow = "visible";
|
||||
|
||||
var mozIMEFocusIn = 0;
|
||||
var mozIMEFocusOut = 0;
|
||||
var IMEHasFocus = false;
|
||||
|
||||
var handler = function (aEvent) {
|
||||
switch (aEvent.type) {
|
||||
case "MozIMEFocusIn":
|
||||
mozIMEFocusIn++;
|
||||
IMEHasFocus = true;
|
||||
break;
|
||||
case "MozIMEFocusOut":
|
||||
mozIMEFocusOut++;
|
||||
IMEHasFocus = false;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
var onInput = function (aEvent) {
|
||||
aEvent.target.style.overflow = "hidden";
|
||||
}
|
||||
|
||||
document.addEventListener("MozIMEFocusIn", handler, true);
|
||||
document.addEventListener("MozIMEFocusOut", handler, true);
|
||||
input.addEventListener("input", onInput, true);
|
||||
|
||||
sendChar("a");
|
||||
|
||||
hitEventLoop(function () {
|
||||
ok(mozIMEFocusOut > 0, "runBug580388Tests(): IME focus must be lost at reframing");
|
||||
ok(mozIMEFocusIn > 0, "runBug580388Tests(): IME focus must be restored after reframing");
|
||||
ok(IMEHasFocus, "runBug580388Tests(): IME must have focus after reframing");
|
||||
|
||||
document.removeEventListener("MozIMEFocusIn", handler, true);
|
||||
document.removeEventListener("MozIMEFocusOut", handler, true);
|
||||
input.removeEventListener("input", onInput, true);
|
||||
|
||||
input.style.overflow = "visible";
|
||||
input.value = "";
|
||||
|
||||
hitEventLoop(aCallback, 20);
|
||||
}, 20);
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
if (!kIMEEnabledSupported && !kIMEOpenSupported)
|
||||
return;
|
||||
|
||||
SpecialPowers.setBoolPref("test.IME", true);
|
||||
|
||||
// test for normal contents.
|
||||
runBasicTest(false, false, "Testing of normal contents");
|
||||
|
||||
@ -1291,17 +1461,16 @@ function runTests()
|
||||
// XXX temporary disable against failure
|
||||
//runTestPasswordFieldOnDialog();
|
||||
|
||||
runASyncTests();
|
||||
}
|
||||
|
||||
function runASyncTests()
|
||||
{
|
||||
// The tests must call onFinish() method.
|
||||
runEditableSubframeTests();
|
||||
// Asynchronous tests
|
||||
runBug580388Tests(function () {
|
||||
// This will call onFinish(), so, this test must be the last.
|
||||
runEditableSubframeTests();
|
||||
});
|
||||
}
|
||||
|
||||
function onFinish()
|
||||
{
|
||||
SpecialPowers.clearUserPref("test.IME");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user