зеркало из https://github.com/mozilla/pjs.git
Bug 582893 IME isn't disabled when password fields on sheet dialog get focus r=smichaud, b2.0=final+
This commit is contained in:
Родитель
9e435b667a
Коммит
f9c3117ab6
|
@ -259,6 +259,10 @@ public:
|
|||
static CFArrayRef CreateAllIMEModeList();
|
||||
static void DebugPrintAllIMEModes(PRLogModuleInfo* aLogModuleInfo);
|
||||
|
||||
// Don't use ::TSMGetActiveDocument() API directly, the document may not
|
||||
// be what you want.
|
||||
static TSMDocumentID GetCurrentTSMDocumentID();
|
||||
|
||||
protected:
|
||||
// The owner of this instance. The result of mOwnerWidget->TextInputHandler
|
||||
// returns this instance. This must not be null after initialized.
|
||||
|
|
|
@ -682,6 +682,17 @@ nsCocoaIMEHandler::DebugPrintAllIMEModes(PRLogModuleInfo* aLogModuleInfo)
|
|||
::CFRelease(list);
|
||||
}
|
||||
|
||||
//static
|
||||
TSMDocumentID
|
||||
nsCocoaIMEHandler::GetCurrentTSMDocumentID()
|
||||
{
|
||||
// On OS X 10.6.x at least, ::TSMGetActiveDocument() has a bug that prevents
|
||||
// it from returning accurate results unless
|
||||
// [NSInputManager currentInputManager] is called first.
|
||||
// So, we need to call [NSInputManager currentInputManager] first here.
|
||||
[NSInputManager currentInputManager];
|
||||
return ::TSMGetActiveDocument();
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
@ -706,8 +717,8 @@ nsCocoaIMEHandler::ResetIMEWindowLevel()
|
|||
#ifdef DEBUG_IME_HANDLER
|
||||
DebugPrintPointer(this);
|
||||
NSLog(@"nsCocoaIMEHandler::ResetIMEWindowLevel");
|
||||
NSLog(@" IsFocused:%s ::TSMGetActiveDocument():%p",
|
||||
TrueOrFalse(IsFocused()), ::TSMGetActiveDocument());
|
||||
NSLog(@" IsFocused:%s GetCurrentTSMDocumentID():%p",
|
||||
TrueOrFalse(IsFocused()), GetCurrentTSMDocumentID());
|
||||
#endif // DEBUG_IME_HANDLER
|
||||
|
||||
if (!mView)
|
||||
|
@ -719,7 +730,7 @@ nsCocoaIMEHandler::ResetIMEWindowLevel()
|
|||
return;
|
||||
}
|
||||
|
||||
TSMDocumentID doc = ::TSMGetActiveDocument();
|
||||
TSMDocumentID doc = GetCurrentTSMDocumentID();
|
||||
if (!doc) {
|
||||
// retry
|
||||
mPendingMethods |= kResetIMEWindowLevel;
|
||||
|
@ -752,7 +763,7 @@ nsCocoaIMEHandler::ResetIMEWindowLevel()
|
|||
if (windowLevel == NSNormalWindowLevel)
|
||||
windowLevel++;
|
||||
|
||||
::TSMSetDocumentProperty(::TSMGetActiveDocument(),
|
||||
::TSMSetDocumentProperty(GetCurrentTSMDocumentID(),
|
||||
kTSMDocumentWindowLevelPropertyTag,
|
||||
sizeof(windowLevel), &windowLevel);
|
||||
|
||||
|
@ -803,8 +814,8 @@ nsCocoaIMEHandler::SyncASCIICapableOnly()
|
|||
#ifdef DEBUG_IME_HANDLER
|
||||
DebugPrintPointer(this);
|
||||
NSLog(@"nsCocoaIMEHandler::SyncASCIICapableOnly");
|
||||
NSLog(@" IsFocused:%s ::TSMGetActiveDocument():%p",
|
||||
TrueOrFalse(IsFocused()), ::TSMGetActiveDocument());
|
||||
NSLog(@" IsFocused:%s GetCurrentTSMDocumentID():%p",
|
||||
TrueOrFalse(IsFocused()), GetCurrentTSMDocumentID());
|
||||
#endif
|
||||
|
||||
if (!mView)
|
||||
|
@ -816,7 +827,7 @@ nsCocoaIMEHandler::SyncASCIICapableOnly()
|
|||
return;
|
||||
}
|
||||
|
||||
TSMDocumentID doc = ::TSMGetActiveDocument();
|
||||
TSMDocumentID doc = GetCurrentTSMDocumentID();
|
||||
if (!doc) {
|
||||
// retry
|
||||
mPendingMethods |= kSyncASCIICapableOnly;
|
||||
|
@ -847,12 +858,9 @@ nsCocoaIMEHandler::ResetTimer()
|
|||
"There are not pending methods, why this is called?");
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
return;
|
||||
}
|
||||
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
if (!mTimer) {
|
||||
NS_ERROR("mTimer is null");
|
||||
return;
|
||||
} else {
|
||||
mTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
NS_ENSURE_TRUE(mTimer, );
|
||||
}
|
||||
mTimer->InitWithFuncCallback(FlushPendingMethods, this, 0,
|
||||
nsITimer::TYPE_ONE_SHOT);
|
||||
|
@ -863,6 +871,11 @@ nsCocoaIMEHandler::ExecutePendingMethods()
|
|||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nsnull;
|
||||
}
|
||||
|
||||
if (![[NSApplication sharedApplication] isActive]) {
|
||||
mIsInFocusProcessing = PR_FALSE;
|
||||
// If we're not active, we should retry at focus event
|
||||
|
@ -873,10 +886,6 @@ nsCocoaIMEHandler::ExecutePendingMethods()
|
|||
// First, reset the pending method flags because if each methods cannot
|
||||
// run now, they can reentry to the pending flags by theirselves.
|
||||
mPendingMethods = 0;
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nsnull;
|
||||
}
|
||||
|
||||
if (pendingMethods & kDiscardIMEComposition)
|
||||
DiscardIMEComposition();
|
||||
|
@ -1164,7 +1173,8 @@ nsCocoaIMEHandler::IsFocused()
|
|||
NS_ENSURE_TRUE(mView, PR_FALSE);
|
||||
NSWindow* window = [mView window];
|
||||
NS_ENSURE_TRUE(window, PR_FALSE);
|
||||
return [window firstResponder] == mView && [window isMainWindow] &&
|
||||
return [window firstResponder] == mView &&
|
||||
([window isMainWindow] || [window isSheet]) &&
|
||||
[[NSApplication sharedApplication] isActive];
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(PR_FALSE);
|
||||
|
|
|
@ -861,6 +861,79 @@ function runEditableSubframeTests()
|
|||
"width=600,height=600");
|
||||
}
|
||||
|
||||
function runTestPasswordFieldOnDialog()
|
||||
{
|
||||
if (!kIMEEnabledSupported) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (document.activeElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
|
||||
var dialog;
|
||||
|
||||
function WindowObserver()
|
||||
{
|
||||
Components.classes["@mozilla.org/observer-service;1"].
|
||||
getService(Components.interfaces.nsIObserverService).
|
||||
addObserver(this, "domwindowopened", false);
|
||||
}
|
||||
|
||||
WindowObserver.prototype = {
|
||||
QueryInterface: function (iid)
|
||||
{
|
||||
if (iid.equals(Components.interfaces.nsIObserver) ||
|
||||
iid.equals(Components.interfaces.nsISupports)) {
|
||||
return this;
|
||||
}
|
||||
},
|
||||
|
||||
observe: function (subject, topic, data)
|
||||
{
|
||||
if (topic === "domwindowopened") {
|
||||
ok(true, "dialog window is created");
|
||||
dialog = subject.QueryInterface(Components.interfaces.nsIDOMWindow);
|
||||
dialog.addEventListener("load", onPasswordDialogLoad, false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var observer = new WindowObserver();
|
||||
var arg1 = new Object(), arg2 = new Object();
|
||||
Components.classes["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(Components.interfaces.nsIPromptService).
|
||||
promptPassword(window, "title", "text", arg1, "msg", arg2);
|
||||
|
||||
ok(true, "password dialog was closed");
|
||||
|
||||
Components.classes["@mozilla.org/observer-service;1"].
|
||||
getService(Components.interfaces.nsIObserverService).
|
||||
removeObserver(observer, "domwindowopened");
|
||||
|
||||
var passwordField;
|
||||
|
||||
function onPasswordDialogLoad()
|
||||
{
|
||||
ok(true, "onPasswordDialogLoad is called");
|
||||
dialog.removeEventListener("load", onPasswordDialogLoad, false);
|
||||
passwordField = dialog.document.getElementById("password1Textbox");
|
||||
passwordField.addEventListener("focus", onPasswordFieldFocus, false);
|
||||
}
|
||||
|
||||
function onPasswordFieldFocus()
|
||||
{
|
||||
ok(true, "onPasswordFieldFocus is called");
|
||||
passwordField.removeEventListener("focus", onPasswordFieldFocus, false);
|
||||
var utils = dialog.
|
||||
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
|
||||
getInterface(Components.interfaces.nsIDOMWindowUtils);
|
||||
is(utils.IMEStatus, utils.IME_STATUS_PASSWORD,
|
||||
"IME isn't disabled on a password field of password dialog");
|
||||
synthesizeKey("VK_ESCAPE", { }, dialog);
|
||||
}
|
||||
}
|
||||
|
||||
function runTests()
|
||||
{
|
||||
if (!kIMEEnabledSupported && !kIMEOpenSupported)
|
||||
|
@ -908,6 +981,9 @@ function runTests()
|
|||
// test whether the IME state and composition are not changed unexpectedly
|
||||
runEditorFlagChangeTests();
|
||||
|
||||
// test password field on dialog
|
||||
runTestPasswordFieldOnDialog();
|
||||
|
||||
runASyncTests();
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче