Issue #1509 - Invalidate previous result when datalist is changed.

Even if `<datalist>` 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 `<datalist>` 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.

This resolves #1509.
This commit is contained in:
Moonchild 2022-05-10 21:03:53 +00:00 • committed by roytam1
commit 046b81d062
4 changed files with 31 additions and 5 deletions

View file

@ -1183,12 +1183,17 @@ nsAutoCompleteController::BeforeSearches()
mSearchStatus = nsIAutoCompleteController::STATUS_SEARCHING; mSearchStatus = nsIAutoCompleteController::STATUS_SEARCHING;
mDefaultIndexCompleted = false; mDefaultIndexCompleted = false;
// The first search result will clear mResults array, though we should pass bool invalidatePreviousResult = false;
// the previous result to each search to allow them to reuse it. So we mInput->GetInvalidatePreviousResult(&invalidatePreviousResult);
// temporarily cache current results till AfterSearches().
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)) { if (!mResultCache.AppendObjects(mResults)) {
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
}
mSearchesOngoing = mSearches.Length(); mSearchesOngoing = mSearches.Length();
mSearchesFailed = 0; mSearchesFailed = 0;

View file

@ -178,4 +178,11 @@ interface nsIAutoCompleteInput : nsISupports
* The userContextId of the current browser. * The userContextId of the current browser.
*/ */
readonly attribute unsigned long userContextId; 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;
}; };

View file

@ -670,6 +670,13 @@ nsFormFillController::GetUserContextId(uint32_t* aUserContextId)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsFormFillController::GetInvalidatePreviousResult(
bool* aInvalidatePreviousResult) {
*aInvalidatePreviousResult = mInvalidatePreviousResult;
return NS_OK;
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//// nsIAutoCompleteSearch //// nsIAutoCompleteSearch
@ -807,6 +814,8 @@ void nsFormFillController::RevalidateDataList()
return; return;
} }
// We cannot use previous result since any items in search target are updated.
mInvalidatePreviousResult = true;
controller->StartSearch(mLastSearchString); controller->StartSearch(mLastSearchString);
return; return;
} }
@ -817,6 +826,8 @@ void nsFormFillController::RevalidateDataList()
nsCOMPtr<nsIAutoCompleteResult> result; nsCOMPtr<nsIAutoCompleteResult> result;
// We cannot use previous result since any items in search target are updated.
mInvalidatePreviousResult = true;
rv = inputListAutoComplete->AutoCompleteSearch(mLastSearchString, rv = inputListAutoComplete->AutoCompleteSearch(mLastSearchString,
mFocusedInput, mFocusedInput,
getter_AddRefs(result)); getter_AddRefs(result));
@ -864,6 +875,8 @@ nsFormFillController::OnSearchCompletion(nsIAutoCompleteResult *aResult)
NS_IMETHODIMP NS_IMETHODIMP
nsFormFillController::HandleEvent(nsIDOMEvent* aEvent) nsFormFillController::HandleEvent(nsIDOMEvent* aEvent)
{ {
mInvalidatePreviousResult = false;
nsAutoString type; nsAutoString type;
aEvent->GetType(type); aEvent->GetType(type);

View file

@ -120,6 +120,7 @@ protected:
bool mCompleteSelectedIndex; bool mCompleteSelectedIndex;
bool mForceComplete; bool mForceComplete;
bool mSuppressOnInput; bool mSuppressOnInput;
bool mInvalidatePreviousResult = false;
}; };
#endif // __nsFormFillController__ #endif // __nsFormFillController__