зеркало из https://github.com/mozilla/pjs.git
bug IME candidate list is hidden by autocomplete window (r=dbaron,bryner,smontagu,jst,sr=dbaron,bryner,neil) : patch by Masayuki Nakano
This commit is contained in:
Родитель
745019c654
Коммит
8669b7866a
|
@ -59,7 +59,8 @@ static const char* const sEventNames[] = {
|
|||
"mouseout", "mousemove", "contextmenu", "keydown", "keyup", "keypress",
|
||||
"focus", "blur", "load", "beforeunload", "unload", "abort", "error",
|
||||
"submit", "reset", "change", "select", "input", "paint" ,"text",
|
||||
"popupshowing", "popupshown", "popuphiding", "popuphidden", "close", "command", "broadcast", "commandupdate",
|
||||
"compositionstart", "compositionend", "popupshowing", "popupshown",
|
||||
"popuphiding", "popuphidden", "close", "command", "broadcast", "commandupdate",
|
||||
"dragenter", "dragover", "dragexit", "dragdrop", "draggesture", "resize",
|
||||
"scroll","overflow", "underflow", "overflowchanged",
|
||||
"DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved",
|
||||
|
@ -407,6 +408,11 @@ nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
|
|||
mEvent->message = NS_KEY_UP;
|
||||
else if (atom == nsLayoutAtoms::onkeypress)
|
||||
mEvent->message = NS_KEY_PRESS;
|
||||
} else if (mEvent->eventStructType == NS_COMPOSITION_EVENT) {
|
||||
if (atom == nsLayoutAtoms::oncompositionstart)
|
||||
mEvent->message = NS_COMPOSITION_START;
|
||||
else if (atom == nsLayoutAtoms::oncompositionend)
|
||||
mEvent->message = NS_COMPOSITION_END;
|
||||
} else if (mEvent->eventStructType == NS_EVENT) {
|
||||
if (atom == nsLayoutAtoms::onfocus)
|
||||
mEvent->message = NS_FOCUS_CONTENT;
|
||||
|
@ -765,6 +771,10 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
|||
return sEventNames[eDOMEvents_keydown];
|
||||
case NS_KEY_PRESS:
|
||||
return sEventNames[eDOMEvents_keypress];
|
||||
case NS_COMPOSITION_START:
|
||||
return sEventNames[eDOMEvents_compositionstart];
|
||||
case NS_COMPOSITION_END:
|
||||
return sEventNames[eDOMEvents_compositionend];
|
||||
case NS_FOCUS_CONTENT:
|
||||
return sEventNames[eDOMEvents_focus];
|
||||
case NS_BLUR_CONTENT:
|
||||
|
|
|
@ -92,6 +92,8 @@ public:
|
|||
eDOMEvents_input,
|
||||
eDOMEvents_paint,
|
||||
eDOMEvents_text,
|
||||
eDOMEvents_compositionstart,
|
||||
eDOMEvents_compositionend,
|
||||
eDOMEvents_popupShowing,
|
||||
eDOMEvents_popupShown,
|
||||
eDOMEvents_popupHiding,
|
||||
|
|
|
@ -1001,6 +1001,14 @@ nsEventListenerManager::GetIdentifiersForType(nsIAtom* aType,
|
|||
*aArrayType = eEventArrayType_DOMUI;
|
||||
*aFlags = NS_EVENT_BITS_UI_FOCUSOUT;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::oncompositionstart) {
|
||||
*aArrayType = eEventArrayType_Composition;
|
||||
*aFlags = NS_EVENT_BITS_COMPOSITION_START;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::oncompositionend) {
|
||||
*aArrayType = eEventArrayType_Composition;
|
||||
*aFlags = NS_EVENT_BITS_COMPOSITION_END;
|
||||
}
|
||||
else {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
|
|
@ -176,6 +176,8 @@ LAYOUT_ATOM(oninput, "oninput")
|
|||
LAYOUT_ATOM(onkeydown, "onkeydown")
|
||||
LAYOUT_ATOM(onkeypress, "onkeypress")
|
||||
LAYOUT_ATOM(onkeyup, "onkeyup")
|
||||
LAYOUT_ATOM(oncompositionstart, "oncompositionstart")
|
||||
LAYOUT_ATOM(oncompositionend, "oncompositionend")
|
||||
LAYOUT_ATOM(onload, "onload")
|
||||
LAYOUT_ATOM(onmousedown, "onmousedown")
|
||||
LAYOUT_ATOM(onmousemove, "onmousemove")
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
interface nsIAutoCompleteInput;
|
||||
|
||||
[scriptable, uuid(75866768-ED00-4ff4-B950-485449A67A88)]
|
||||
[scriptable, uuid(CF2ACA0C-4FB1-42e4-8A54-23E832CB2A98)]
|
||||
interface nsIAutoCompleteController : nsISupports
|
||||
{
|
||||
/*
|
||||
|
@ -104,6 +104,16 @@ interface nsIAutoCompleteController : nsISupports
|
|||
*/
|
||||
boolean handleEscape();
|
||||
|
||||
/*
|
||||
* Notify the controller that the user wishes to start composition
|
||||
*/
|
||||
void handleStartComposition();
|
||||
|
||||
/*
|
||||
* Notify the controller that the user wishes to end composition
|
||||
*/
|
||||
void handleEndComposition();
|
||||
|
||||
/*
|
||||
* Handle tab. Just closes up.
|
||||
*/
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* Joe Hewitt <hewitt@netscape.com> (Original Author)
|
||||
* Dean Tessman <dean_tessman@hotmail.com>
|
||||
* Johnny Stenback <jst@mozilla.jstenback.com>
|
||||
* Masayuki Nakano <masayuki@d-toybox.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -58,6 +59,9 @@ nsAutoCompleteController::nsAutoCompleteController() :
|
|||
mEnterAfterSearch(PR_FALSE),
|
||||
mDefaultIndexCompleted(PR_FALSE),
|
||||
mBackspaced(PR_FALSE),
|
||||
mPopupClosedByCompositionStart(PR_FALSE),
|
||||
mIsIMEComposing(PR_FALSE),
|
||||
mIgnoreHandleText(PR_FALSE),
|
||||
mSearchStatus(0),
|
||||
mRowCount(0),
|
||||
mSearchesOngoing(0)
|
||||
|
@ -165,12 +169,11 @@ nsAutoCompleteController::StartSearch(const nsAString &aSearchString)
|
|||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::HandleText(PRBool aIgnoreSelection)
|
||||
{
|
||||
if (!mInput) {
|
||||
// Stop current search in case it's async.
|
||||
StopSearch();
|
||||
// Stop the queued up search on a timer
|
||||
ClearSearchTimer();
|
||||
|
||||
if (!mInput) {
|
||||
// Note: if now is after blur and IME end composition,
|
||||
// check mInput before calling.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=193544#c31
|
||||
|
@ -178,13 +181,34 @@ nsAutoCompleteController::HandleText(PRBool aIgnoreSelection)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsAutoString newValue;
|
||||
mInput->GetTextValue(newValue);
|
||||
|
||||
// Note: the events occur in the following order when IME is used.
|
||||
// 1. composition start event(HandleStartComposition)
|
||||
// 2. composition end event(HandleEndComposition)
|
||||
// 3. input event(HandleText)
|
||||
// Note that the input event occurs if IME composition is cancelled, as well.
|
||||
// In HandleEndComposition, we are processing the popup properly.
|
||||
// Therefore, the input event after composition end event should do nothing.
|
||||
// (E.g., calling StopSearch(), ClearSearchTimer() and ClosePopup().)
|
||||
// If it is not, popup is always closed after composition end.
|
||||
if (mIgnoreHandleText) {
|
||||
mIgnoreHandleText = PR_FALSE;
|
||||
if (newValue.Equals(mSearchString))
|
||||
return NS_OK;
|
||||
NS_ERROR("Now is after composition end event. But the value was changed.");
|
||||
}
|
||||
|
||||
// Stop current search in case it's async.
|
||||
StopSearch();
|
||||
// Stop the queued up search on a timer
|
||||
ClearSearchTimer();
|
||||
|
||||
PRBool disabled;
|
||||
mInput->GetDisableAutoComplete(&disabled);
|
||||
NS_ENSURE_TRUE(!disabled, NS_OK);
|
||||
|
||||
nsAutoString newValue;
|
||||
mInput->GetTextValue(newValue);
|
||||
|
||||
// Don't search again if the new string is the same as the last search
|
||||
if (newValue.Length() > 0 && newValue.Equals(mSearchString))
|
||||
return NS_OK;
|
||||
|
@ -262,6 +286,62 @@ nsAutoCompleteController::HandleEscape(PRBool *_retval)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::HandleStartComposition()
|
||||
{
|
||||
NS_ENSURE_TRUE(!mIsIMEComposing, NS_OK);
|
||||
|
||||
mPopupClosedByCompositionStart = PR_FALSE;
|
||||
mIsIMEComposing = PR_TRUE;
|
||||
|
||||
if (!mInput)
|
||||
return NS_OK;
|
||||
|
||||
PRBool disabled;
|
||||
mInput->GetDisableAutoComplete(&disabled);
|
||||
if (disabled)
|
||||
return NS_OK;
|
||||
|
||||
StopSearch();
|
||||
ClearSearchTimer();
|
||||
|
||||
PRBool isOpen;
|
||||
mInput->GetPopupOpen(&isOpen);
|
||||
if (isOpen)
|
||||
ClosePopup();
|
||||
mPopupClosedByCompositionStart = isOpen;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::HandleEndComposition()
|
||||
{
|
||||
NS_ENSURE_TRUE(mIsIMEComposing, NS_OK);
|
||||
|
||||
mIsIMEComposing = PR_FALSE;
|
||||
PRBool forceOpenPopup = mPopupClosedByCompositionStart;
|
||||
mPopupClosedByCompositionStart = PR_FALSE;
|
||||
|
||||
if (!mInput)
|
||||
return NS_OK;
|
||||
|
||||
nsAutoString value;
|
||||
mInput->GetTextValue(value);
|
||||
SetSearchString(EmptyString());
|
||||
if (!value.IsEmpty()) {
|
||||
// Show the popup with a filtered result set
|
||||
HandleText(PR_TRUE);
|
||||
} else if (forceOpenPopup) {
|
||||
PRBool cancel;
|
||||
HandleKeyNavigation(nsIAutoCompleteController::KEY_DOWN, &cancel);
|
||||
}
|
||||
// On here, |value| and |mSearchString| are same. Therefore, next HandleText should be
|
||||
// ignored. Because there are no reason to research.
|
||||
mIgnoreHandleText = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAutoCompleteController::HandleTab()
|
||||
{
|
||||
|
@ -275,6 +355,14 @@ nsAutoCompleteController::HandleKeyNavigation(PRUint16 aKey, PRBool *_retval)
|
|||
// By default, don't cancel the event
|
||||
*_retval = PR_FALSE;
|
||||
|
||||
if (!mInput) {
|
||||
// Note: if now is after blur and IME end composition,
|
||||
// check mInput before calling.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=193544#c31
|
||||
NS_ERROR("Called before attaching to the control or after detaching from the control");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAutoCompletePopup> popup;
|
||||
mInput->GetPopup(getter_AddRefs(popup));
|
||||
NS_ENSURE_TRUE(popup != nsnull, NS_ERROR_FAILURE);
|
||||
|
|
|
@ -104,6 +104,9 @@ protected:
|
|||
PRPackedBool mEnterAfterSearch;
|
||||
PRPackedBool mDefaultIndexCompleted;
|
||||
PRPackedBool mBackspaced;
|
||||
PRPackedBool mPopupClosedByCompositionStart;
|
||||
PRPackedBool mIsIMEComposing;
|
||||
PRPackedBool mIgnoreHandleText;
|
||||
PRUint16 mSearchStatus;
|
||||
PRUint32 mRowCount;
|
||||
PRUint32 mSearchesOngoing;
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsIContentViewer.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIDOMCompositionListener.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMNSHTMLInputElement.h"
|
||||
|
@ -79,6 +80,7 @@ NS_INTERFACE_MAP_BEGIN(nsFormFillController)
|
|||
NS_INTERFACE_MAP_ENTRY(nsIDOMFormListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMLoadListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMCompositionListener)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIFormFillController)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMFocusListener)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
@ -646,6 +648,49 @@ nsFormFillController::KeyPress(nsIDOMEvent* aEvent)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//// nsIDOMCompositionListener
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormFillController::HandleStartComposition(nsIDOMEvent* aCompositionEvent)
|
||||
{
|
||||
NS_ASSERTION(mController, "should have a controller!");
|
||||
|
||||
if (mController && mFocusedInput)
|
||||
mController->HandleStartComposition();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormFillController::HandleEndComposition(nsIDOMEvent* aCompositionEvent)
|
||||
{
|
||||
NS_ASSERTION(mController, "should have a controller!");
|
||||
|
||||
if (mController && mFocusedInput)
|
||||
mController->HandleEndComposition();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormFillController::HandleQueryComposition(nsIDOMEvent* aCompositionEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormFillController::HandleQueryReconversion(nsIDOMEvent* aCompositionEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFormFillController::HandleQueryCaretRect(nsIDOMEvent* aCompostionEvent)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
//// nsIDOMFormListener
|
||||
|
||||
|
@ -864,6 +909,14 @@ nsFormFillController::AddWindowListeners(nsIDOMWindow *aWindow)
|
|||
target->AddEventListener(NS_LITERAL_STRING("unload"),
|
||||
NS_STATIC_CAST(nsIDOMLoadListener *, this),
|
||||
PR_TRUE);
|
||||
|
||||
target->AddEventListener(NS_LITERAL_STRING("compositionstart"),
|
||||
NS_STATIC_CAST(nsIDOMCompositionListener *, this),
|
||||
PR_TRUE);
|
||||
|
||||
target->AddEventListener(NS_LITERAL_STRING("compositionend"),
|
||||
NS_STATIC_CAST(nsIDOMCompositionListener *, this),
|
||||
PR_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -907,6 +960,14 @@ nsFormFillController::RemoveWindowListeners(nsIDOMWindow *aWindow)
|
|||
target->RemoveEventListener(NS_LITERAL_STRING("unload"),
|
||||
NS_STATIC_CAST(nsIDOMLoadListener *, this),
|
||||
PR_TRUE);
|
||||
|
||||
target->RemoveEventListener(NS_LITERAL_STRING("compositionstart"),
|
||||
NS_STATIC_CAST(nsIDOMCompositionListener *, this),
|
||||
PR_TRUE);
|
||||
|
||||
target->RemoveEventListener(NS_LITERAL_STRING("compositionend"),
|
||||
NS_STATIC_CAST(nsIDOMCompositionListener *, this),
|
||||
PR_TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "nsIAutoCompletePopup.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsIDOMCompositionListener.h"
|
||||
#include "nsIDOMFormListener.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMLoadListener.h"
|
||||
|
@ -62,6 +63,7 @@ class nsFormFillController : public nsIFormFillController,
|
|||
public nsIAutoCompleteSearch,
|
||||
public nsIDOMFocusListener,
|
||||
public nsIDOMKeyListener,
|
||||
public nsIDOMCompositionListener,
|
||||
public nsIDOMFormListener,
|
||||
public nsIDOMMouseListener,
|
||||
public nsIDOMLoadListener
|
||||
|
@ -82,6 +84,13 @@ public:
|
|||
NS_IMETHOD KeyUp(nsIDOMEvent* aKeyEvent);
|
||||
NS_IMETHOD KeyPress(nsIDOMEvent* aKeyEvent);
|
||||
|
||||
// nsIDOMCompositionListener
|
||||
NS_IMETHOD HandleStartComposition(nsIDOMEvent* aCompositionEvent);
|
||||
NS_IMETHOD HandleEndComposition(nsIDOMEvent* aCompositionEvent);
|
||||
NS_IMETHOD HandleQueryComposition(nsIDOMEvent* aCompositionEvent);
|
||||
NS_IMETHOD HandleQueryReconversion(nsIDOMEvent* aCompositionEvent);
|
||||
NS_IMETHOD HandleQueryCaretRect(nsIDOMEvent* aCompositionEvent);
|
||||
|
||||
// nsIDOMFormListener
|
||||
NS_IMETHOD Submit(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD Reset(nsIDOMEvent* aEvent);
|
||||
|
|
|
@ -438,6 +438,12 @@
|
|||
<handler event="keypress" phase="capturing"
|
||||
action="return this.onKeyPress(event);"/>
|
||||
|
||||
<handler event="compositionstart" phase="capturing"
|
||||
action="if (this.mController.input == this) this.mController.handleStartComposition();"/>
|
||||
|
||||
<handler event="compositionend" phase="capturing"
|
||||
action="if (this.mController.input == this) this.mController.handleEndComposition();"/>
|
||||
|
||||
<handler event="focus" phase="capturing"
|
||||
action="this.attachController();"/>
|
||||
|
||||
|
|
|
@ -931,6 +931,15 @@
|
|||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- -->
|
||||
<method name="processStartComposition">
|
||||
<body><![CDATA[
|
||||
this.finishAutoComplete(false, false, null);
|
||||
this.clearTimer();
|
||||
this.closeResultPopup();
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- -->
|
||||
<method name="keyNavigation">
|
||||
<parameter name="aEvent"/>
|
||||
|
@ -1317,6 +1326,9 @@
|
|||
<handler event="keypress" phase="capturing"
|
||||
action="return this.processKeyPress(event);"/>
|
||||
|
||||
<handler event="compositionstart" phase="capturing"
|
||||
action="this.processStartComposition();"/>
|
||||
|
||||
<handler event="focus" phase="capturing"
|
||||
action="this.userAction = 'typing';"/>
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче