Bug 1130858 - Recipient autocomplete suggestion overrides ANY manual address input if quickly entered/pasted and confirmed with Enter/Tab before autocomplete suggestions disappear. r=mak

--HG--
extra : rebase_source : acc6290ed31c40cf83f467e86c5bb83d73c60915
This commit is contained in:
Magnus Melin 2015-07-15 16:21:52 +03:00
Родитель 63df848907
Коммит ee6b010108
2 изменённых файлов: 75 добавлений и 21 удалений

Просмотреть файл

@ -1365,7 +1365,7 @@ nsAutoCompleteController::EnterMatch(bool aIsPopupSelection)
value = defaultIndexValue;
}
if (forceComplete && value.IsEmpty()) {
if (forceComplete && value.IsEmpty() && shouldComplete) {
// See if inputValue is one of the autocomplete results. It can be an
// identical value, or if it matched the middle of a result it can be
// something like "bar >> foobar" (user entered bar and foobar is
@ -1384,34 +1384,39 @@ nsAutoCompleteController::EnterMatch(bool aIsPopupSelection)
suggestedValue = inputValue;
}
nsAutoString defaultValue;
for (uint32_t i = 0; i < mResults.Length(); ++i) {
nsIAutoCompleteResult *result = mResults[i];
if (result) {
if (defaultValue.IsEmpty()) {
int32_t defaultIndex;
result->GetDefaultIndex(&defaultIndex);
if (defaultIndex >= 0) {
result->GetFinalCompleteValueAt(defaultIndex, defaultValue);
}
}
uint32_t matchCount = 0;
result->GetMatchCount(&matchCount);
for (uint32_t j = 0; j < matchCount; ++j) {
nsAutoString matchValue;
result->GetFinalCompleteValueAt(j, matchValue);
result->GetValueAt(j, matchValue);
if (suggestedValue.Equals(matchValue, nsCaseInsensitiveStringComparator())) {
value = matchValue;
nsAutoString finalMatchValue;
result->GetFinalCompleteValueAt(j, finalMatchValue);
value = finalMatchValue;
break;
}
}
}
}
if (value.IsEmpty()) {
// Since nothing was selected, and forceComplete is specified, that means
// we have to enter the first default match instead.
value = defaultValue;
// The value should have been set at this point. If not, then it's not
// a value that should be autocompleted.
}
else if (forceComplete && value.IsEmpty() && completeSelection) {
// Since nothing was selected, and forceComplete is specified, that means
// we have to find the first default match and enter it instead.
for (uint32_t i = 0; i < mResults.Length(); ++i) {
nsIAutoCompleteResult *result = mResults[i];
if (result) {
int32_t defaultIndex;
result->GetDefaultIndex(&defaultIndex);
if (defaultIndex >= 0) {
result->GetFinalCompleteValueAt(defaultIndex, value);
break;
}
}
}
}
}
@ -1760,6 +1765,7 @@ nsAutoCompleteController::CompleteValue(nsString &aValue)
* contained in mSearchString. */
{
MOZ_ASSERT(mInput, "Must have a valid input");
nsCOMPtr<nsIAutoCompleteInput> input(mInput);
const int32_t mSearchStringLength = mSearchString.Length();
int32_t endSelect = aValue.Length(); // By default, select all of aValue.

Просмотреть файл

@ -19,17 +19,59 @@ function run_test() {
run_next_test();
}
add_test(function test_handleEnter() {
doSearch("", "mozilla.com", "http://www.mozilla.com", function(aController) {
do_check_eq(aController.input.textValue, "");
add_test(function test_handleEnterWithDirectMatchCompleteSelectedIndex() {
doSearch("moz", "mozilla.com", "http://www.mozilla.com",
{ forceComplete: true, completeSelectedIndex: true }, function(aController) {
do_check_eq(aController.input.textValue, "moz");
do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
aController.input.forceComplete = true;
aController.handleEnter(false);
// After enter the final complete value should be shown in the input.
do_check_eq(aController.input.textValue, "http://www.mozilla.com");
});
});
function doSearch(aSearchString, aResultValue, aFinalCompleteValue, aOnCompleteCallback) {
add_test(function test_handleEnterWithDirectMatch() {
doSearch("mozilla", "mozilla.com", "http://www.mozilla.com",
{ forceComplete: true, completeDefaultIndex: true }, function(aController) {
// Should autocomplete the search string to a suggestion.
do_check_eq(aController.input.textValue, "mozilla.com");
do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
aController.handleEnter(false);
// After enter the final complete value should be shown in the input.
do_check_eq(aController.input.textValue, "http://www.mozilla.com");
});
});
add_test(function test_handleEnterWithNoMatch() {
doSearch("mozilla", "mozilla.com", "http://www.mozilla.com",
{ forceComplete: true, completeDefaultIndex: true }, function(aController) {
// Should autocomplete the search string to a suggestion.
do_check_eq(aController.input.textValue, "mozilla.com");
do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
// Now input something that does not match...
aController.input.textValue = "mozillax";
// ... and confirm. We don't want one of the values from the previous
// results to be taken, since what's now in the input field doesn't match.
aController.handleEnter(false);
do_check_eq(aController.input.textValue, "mozillax");
});
});
add_test(function test_handleEnterWithIndirectMatch() {
doSearch("com", "mozilla.com", "http://www.mozilla.com",
{ forceComplete: true, completeDefaultIndex: true }, function(aController) {
// Should autocomplete the search string to a suggestion.
do_check_eq(aController.input.textValue, "com >> mozilla.com");
do_check_eq(aController.getFinalCompleteValueAt(0), "http://www.mozilla.com");
aController.handleEnter(false);
// After enter the final complete value from the suggestion should be shown
// in the input.
do_check_eq(aController.input.textValue, "http://www.mozilla.com");
});
});
function doSearch(aSearchString, aResultValue, aFinalCompleteValue,
aInputProps, aOnCompleteCallback) {
let search = new AutoCompleteSearchBase(
"search",
new AutoCompleteResult([ aResultValue ], [ aFinalCompleteValue ])
@ -41,7 +83,13 @@ function doSearch(aSearchString, aResultValue, aFinalCompleteValue, aOnCompleteC
// Make an AutoCompleteInput that uses our searches and confirms results.
let input = new AutoCompleteInput([ search.name ]);
for (var p in aInputProps) {
input[p] = aInputProps[p];
}
input.textValue = aSearchString;
// Place the cursor at the end of the input so that completion to
// default index will kick in.
input.selectTextRange(aSearchString.length, aSearchString.length);
controller.input = input;
controller.startSearch(aSearchString);