From 649005d1208df649f666adb73a9f74584105113c Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Sat, 14 May 2022 14:07:16 -0500 Subject: [Components:Autocomplete] Invalidate previous result when datalist is changed. Even if `` is dynamically changed, the autocomplete controller still uses the previous search result. If changed, we have to ignore the previous result that may now be invalid. Also, even if `` is changed, we have to keep the selected index (See Mozilla Bug 595069), so we cannot use `ResetInternalState` in this situation because it resets the selected index. --- components/autocomplete/nsAutoCompleteController.cpp | 15 ++++++++++----- components/autocomplete/nsIAutoCompleteInput.idl | 9 ++++++++- components/satchel/nsFormFillController.cpp | 13 +++++++++++++ components/satchel/nsFormFillController.h | 1 + 4 files changed, 32 insertions(+), 6 deletions(-) diff --git a/components/autocomplete/nsAutoCompleteController.cpp b/components/autocomplete/nsAutoCompleteController.cpp index 37b2e5dfa..971a7abaf 100644 --- a/components/autocomplete/nsAutoCompleteController.cpp +++ b/components/autocomplete/nsAutoCompleteController.cpp @@ -1160,11 +1160,16 @@ nsAutoCompleteController::BeforeSearches() mSearchStatus = nsIAutoCompleteController::STATUS_SEARCHING; mDefaultIndexCompleted = false; - // The first search result will clear mResults array, though we should pass - // the previous result to each search to allow them to reuse it. So we - // temporarily cache current results till AfterSearches(). - if (!mResultCache.AppendObjects(mResults)) { - return NS_ERROR_OUT_OF_MEMORY; + bool invalidatePreviousResult = false; + mInput->GetInvalidatePreviousResult(&invalidatePreviousResult); + + if (!invalidatePreviousResult) { + // ClearResults will clear the mResults array, but we should pass the + // previous result to each search to allow reusing it. So we temporarily + // cache the current results until AfterSearches(). + if (!mResultCache.AppendObjects(mResults)) { + return NS_ERROR_OUT_OF_MEMORY; + } } mSearchesOngoing = mSearches.Length(); diff --git a/components/autocomplete/nsIAutoCompleteInput.idl b/components/autocomplete/nsIAutoCompleteInput.idl index 26a75ea77..98f36d11b 100644 --- a/components/autocomplete/nsIAutoCompleteInput.idl +++ b/components/autocomplete/nsIAutoCompleteInput.idl @@ -7,7 +7,7 @@ interface nsIAutoCompletePopup; -[scriptable, uuid(B068E70F-F82C-4C12-AD87-82E271C5C180)] +[scriptable, uuid(224d9847-d743-47e3-8c9e-07e1bcedf569)] interface nsIAutoCompleteInput : nsISupports { /* @@ -178,4 +178,11 @@ interface nsIAutoCompleteInput : nsISupports * The userContextId of the current browser. */ readonly attribute unsigned long userContextId; + + /** + * Indicates whether the previous result should be invalidated due to dynamic + * list updates. If search content is updated, we shouldn't use the previous + * search result. + */ + readonly attribute boolean invalidatePreviousResult; }; diff --git a/components/satchel/nsFormFillController.cpp b/components/satchel/nsFormFillController.cpp index 880ca79b2..7ac7c40a4 100644 --- a/components/satchel/nsFormFillController.cpp +++ b/components/satchel/nsFormFillController.cpp @@ -670,6 +670,13 @@ nsFormFillController::GetUserContextId(uint32_t* aUserContextId) return NS_OK; } +NS_IMETHODIMP +nsFormFillController::GetInvalidatePreviousResult( + bool* aInvalidatePreviousResult) { + *aInvalidatePreviousResult = mInvalidatePreviousResult; + return NS_OK; +} + //////////////////////////////////////////////////////////////////////// //// nsIAutoCompleteSearch @@ -807,6 +814,8 @@ void nsFormFillController::RevalidateDataList() return; } + // We cannot use previous result since any items in search target are updated. + mInvalidatePreviousResult = true; controller->StartSearch(mLastSearchString); return; } @@ -817,6 +826,8 @@ void nsFormFillController::RevalidateDataList() nsCOMPtr result; + // We cannot use previous result since any items in search target are updated. + mInvalidatePreviousResult = true; rv = inputListAutoComplete->AutoCompleteSearch(mLastSearchString, mFocusedInput, getter_AddRefs(result)); @@ -864,6 +875,8 @@ nsFormFillController::OnSearchCompletion(nsIAutoCompleteResult *aResult) NS_IMETHODIMP nsFormFillController::HandleEvent(nsIDOMEvent* aEvent) { + mInvalidatePreviousResult = false; + nsAutoString type; aEvent->GetType(type); diff --git a/components/satchel/nsFormFillController.h b/components/satchel/nsFormFillController.h index 27fb1edbd..b11835d1d 100644 --- a/components/satchel/nsFormFillController.h +++ b/components/satchel/nsFormFillController.h @@ -120,6 +120,7 @@ protected: bool mCompleteSelectedIndex; bool mForceComplete; bool mSuppressOnInput; + bool mInvalidatePreviousResult = false; }; #endif // __nsFormFillController__ -- cgit v1.2.3