Bug 491520 - Tag autocomplete prevents changing the case of tags, when adding tags, r=mano a=blocking191

This commit is contained in:
Marco Bonardo 2009-05-20 13:31:49 +02:00
Родитель b58b309760
Коммит fa629c426a
3 изменённых файлов: 87 добавлений и 14 удалений

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

@ -509,6 +509,8 @@ nsAutoCompleteController::HandleKeyNavigation(PRUint32 aKey, PRBool *_retval)
if (isOpen) {
PRInt32 selectedIndex;
popup->GetSelectedIndex(&selectedIndex);
PRBool shouldComplete;
mInput->GetCompleteDefaultIndex(&shouldComplete);
if (selectedIndex >= 0) {
// The pop-up is open and has a selection, take its value
nsAutoString value;
@ -517,6 +519,18 @@ nsAutoCompleteController::HandleKeyNavigation(PRUint32 aKey, PRBool *_retval)
input->SelectTextRange(value.Length(), value.Length());
}
}
else if (shouldComplete) {
// We usually try to preserve the casing of what user has typed, but
// if he wants to autocomplete, we will replace the value with the
// actual autocomplete result.
// The user wants explicitely to use that result, so this ensures
// association of the result with the autocompleted text.
nsAutoString value;
if (NS_SUCCEEDED(GetDefaultCompleteValue(selectedIndex, PR_FALSE, value))) {
input->SetTextValue(value);
input->SelectTextRange(value.Length(), value.Length());
}
}
// Close the pop-up even if nothing was selected
ClearSearchTimer();
ClosePopup();
@ -1348,20 +1362,67 @@ nsAutoCompleteController::CompleteDefaultIndex(PRInt32 aSearchIndex)
if (!shouldComplete)
return NS_OK;
nsIAutoCompleteResult *result = mResults.SafeObjectAt(aSearchIndex);
nsAutoString resultValue;
if (NS_SUCCEEDED(GetDefaultCompleteValue(aSearchIndex, PR_TRUE, resultValue)))
CompleteValue(resultValue);
mDefaultIndexCompleted = PR_TRUE;
return NS_OK;
}
nsresult
nsAutoCompleteController::GetDefaultCompleteValue(PRInt32 aSearchIndex,
PRBool aPreserveCasing,
nsAString &_retval)
{
PRInt32 defaultIndex = -1;
PRInt32 index = aSearchIndex;
if (index < 0) {
PRUint32 count = mResults.Count();
for (PRUint32 i = 0; i < count; ++i) {
nsIAutoCompleteResult *result = mResults[i];
if (result && NS_SUCCEEDED(result->GetDefaultIndex(&defaultIndex)) &&
defaultIndex >= 0) {
index = i;
break;
}
}
}
NS_ENSURE_TRUE(index >= 0, NS_ERROR_FAILURE);
nsIAutoCompleteResult *result = mResults.SafeObjectAt(index);
NS_ENSURE_TRUE(result != nsnull, NS_ERROR_FAILURE);
// The search must explicitly provide a default index in order
// for us to be able to complete
PRInt32 defaultIndex;
result->GetDefaultIndex(&defaultIndex);
NS_ENSURE_TRUE(defaultIndex >= 0, NS_OK);
if (defaultIndex < 0) {
// The search must explicitly provide a default index in order
// for us to be able to complete.
result->GetDefaultIndex(&defaultIndex);
}
NS_ENSURE_TRUE(defaultIndex >= 0, NS_ERROR_FAILURE);
nsAutoString resultValue;
result->GetValueAt(defaultIndex, resultValue);
CompleteValue(resultValue);
mDefaultIndexCompleted = PR_TRUE;
if (aPreserveCasing &&
StringBeginsWith(resultValue, mSearchString,
nsCaseInsensitiveStringComparator())) {
// We try to preserve user casing, otherwise we would end up changing
// the case of what he typed, if we have a result with a different casing.
// For example if we have result "Test", and user starts writing "tuna",
// after digiting t, we would convert it to T trying to autocomplete "Test".
// We will still complete to cased "Test" if the user explicitely choose
// that result, by either selecting it in the results popup, or with
// keyboard navigation or if autocompleting in the middle.
nsAutoString casedResultValue;
casedResultValue.Assign(mSearchString);
// Use what the user has typed so far.
casedResultValue.Append(Substring(resultValue,
mSearchString.Length(),
resultValue.Length()));
_retval = casedResultValue;
}
else
_retval = resultValue;
return NS_OK;
}

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

@ -87,11 +87,14 @@ protected:
nsresult CompleteDefaultIndex(PRInt32 aSearchIndex);
nsresult CompleteValue(nsString &aValue);
nsresult GetResultValueAt(PRInt32 aIndex, PRBool aValueOnly, nsAString & _retval);
nsresult GetResultValueAt(PRInt32 aIndex, PRBool aValueOnly,
nsAString & _retval);
nsresult GetDefaultCompleteValue(PRInt32 aSearchIndex, PRBool aPreserveCasing,
nsAString &_retval);
nsresult ClearResults();
nsresult RowIndexToSearch(PRInt32 aRowIndex, PRInt32 *aSearchIndex, PRInt32 *aItemIndex);
nsresult RowIndexToSearch(PRInt32 aRowIndex,
PRInt32 *aSearchIndex, PRInt32 *aItemIndex);
// members //////////////////////////////////////////

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

@ -31,7 +31,7 @@ function nsAutoCompleteSimpleResult(aString)
if (returnResult) {
this.searchResult = ACR.RESULT_SUCCESS;
this.matchCount = 1;
this._param = "result";
this._param = "Result";
}
}
@ -93,7 +93,7 @@ const tests = [
start: 1, end: 1 },
{ completeDefaultIndex: "true", key: "e", result: "result",
start: 2, end: 6 },
{ completeDefaultIndex: "true", key: "t", result: "ret >> result",
{ completeDefaultIndex: "true", key: "t", result: "ret >> Result",
start: 3, end: 13 }
];
@ -151,6 +151,15 @@ function checkResult() {
if (currentTest < tests.length)
setTimeout(checkNext, 0);
else {
// Test result if user accepts autocomplete suggestion.
synthesizeKey("VK_RIGHT", {});
is(autocomplete.value, "Result",
"Test complete: autocomplete.value should equal 'Result'");
is(autocomplete.selectionStart, 6,
"Test complete: autocomplete selection should start at 6");
is(autocomplete.selectionEnd, 6,
"Test complete: autocomplete selection should end at 6");
setTimeout(function() {
// Unregister the factory so that we don't get in the way of other tests
componentManager.unregisterFactory(autoCompleteSimpleID, autoCompleteSimple);