NS_IMETHODIMP nsAutoCompleteController::HandleEndComposition() { NS_ENSURE_TRUE(mIsIMEComposing, NS_OK); mIsIMEComposing = false; bool forceOpenPopup = mPopupClosedByCompositionStart; mPopupClosedByCompositionStart = 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(); } else if (forceOpenPopup) { bool cancel; HandleKeyNavigation(nsIDOMKeyEvent::DOM_VK_DOWN, &cancel); } // On here, |value| and |mSearchString| are same. Therefore, next HandleText should be // ignored. Because there are no reason to research. mIgnoreHandleText = true; return NS_OK; }
NS_IMETHODIMP nsAutoCompleteController::HandleText() { // Note: the events occur in the following order when IME is used. // 1. a compositionstart event(HandleStartComposition) // 2. some input events (HandleText), eCompositionState_Composing // 3. a compositionend event(HandleEndComposition) // 4. an input event(HandleText), eCompositionState_Committing // We should do nothing during composition. if (mCompositionState == eCompositionState_Composing) { return NS_OK; } bool handlingCompositionCommit = (mCompositionState == eCompositionState_Committing); bool popupClosedByCompositionStart = mPopupClosedByCompositionStart; if (handlingCompositionCommit) { mCompositionState = eCompositionState_None; mPopupClosedByCompositionStart = false; } if (!mInput) { // Stop all searches in case they are async. StopSearch(); // 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; } nsAutoString newValue; nsCOMPtr<nsIAutoCompleteInput> input(mInput); input->GetTextValue(newValue); // Stop all searches in case they are async. StopSearch(); if (!mInput) { // StopSearch() can call PostSearchCleanup() which might result // in a blur event, which could null out mInput, so we need to check it // again. See bug #395344 for more details return NS_OK; } bool disabled; input->GetDisableAutoComplete(&disabled); NS_ENSURE_TRUE(!disabled, NS_OK); // Don't search again if the new string is the same as the last search // However, if this is called immediately after compositionend event, // we need to search the same value again since the search was canceled // at compositionstart event handler. if (!handlingCompositionCommit && newValue.Length() > 0 && newValue.Equals(mSearchString)) { return NS_OK; } // Determine if the user has removed text from the end (probably by backspacing) if (newValue.Length() < mSearchString.Length() && Substring(mSearchString, 0, newValue.Length()).Equals(newValue)) { // We need to throw away previous results so we don't try to search through them again ClearResults(); mBackspaced = true; } else mBackspaced = false; mSearchString = newValue; // Don't search if the value is empty if (newValue.Length() == 0) { // If autocomplete popup was closed by compositionstart event handler, // we should reopen it forcibly even if the value is empty. if (popupClosedByCompositionStart && handlingCompositionCommit) { bool cancel; HandleKeyNavigation(nsIDOMKeyEvent::DOM_VK_DOWN, &cancel); return NS_OK; } ClosePopup(); return NS_OK; } StartSearches(); return NS_OK; }