mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 341504 global history toolkit autocomplete interface r=IanN,biesi sr=jag
This commit is contained in:
parent
437cb983e4
commit
298042b3a1
@ -86,7 +86,7 @@
|
||||
<vbox id="LinkLocationBox">
|
||||
<label control="hrefInput" accesskey="&LinkURLEditField.accessKey;" width="1">&LinkURLEditField.label;</label>
|
||||
<textbox id="hrefInput" type="autocomplete"
|
||||
searchSessions="history" timeout="50" maxrows="6"
|
||||
autocompletesearch="history" timeout="50" maxrows="6"
|
||||
disablehistory="false" class="uri-element"
|
||||
oninput="ChangeLinkLocation();">
|
||||
<menupopup class="autocomplete-history-popup"
|
||||
|
@ -47,9 +47,10 @@
|
||||
|
||||
<hbox id="bxURLBarContainer" flex="1">
|
||||
<hbox align="center" flex="1">
|
||||
<!-- request both autocomplete implementations for compatibility -->
|
||||
<textbox id="tfURLBar" type="autocomplete" flex="1"
|
||||
searchSessions="history" timeout="50" maxrows="6"
|
||||
observes="cmdGotoURL">
|
||||
autocompletesearch="history file" observes="cmdGotoURL">
|
||||
<image id="imgURLBarIcon"/>
|
||||
|
||||
</textbox>
|
||||
|
@ -100,7 +100,7 @@
|
||||
control="mailnewsStartPageUrl"/>
|
||||
<textbox id="mailnewsStartPageUrl" flex="1" preftype="localizedstring"
|
||||
type="autocomplete" prefstring="mailnews.start_page.url"
|
||||
searchSessions="history" timeout="50" maxrows="6" class="uri-element"/>
|
||||
autocompletesearch="history" timeout="50" maxrows="6" class="uri-element"/>
|
||||
</hbox>
|
||||
|
||||
<hbox pack="end">
|
||||
|
@ -63,7 +63,7 @@
|
||||
|
||||
<hbox align="center">
|
||||
<textbox id="dialog.input" flex="1" type="autocomplete"
|
||||
searchSessions="history" timeout="50" maxrows="6"
|
||||
autocompletesearch="history" timeout="50" maxrows="6"
|
||||
disablehistory="false" class="uri-element"
|
||||
oninput="doEnabling();">
|
||||
<menupopup id="ubhist-popup" class="autocomplete-history-popup"
|
||||
|
@ -178,7 +178,7 @@
|
||||
receives focus needs a text name -->
|
||||
<label control="urlbar" hidden="true" value="&locationBar.title;"/>
|
||||
<textbox id="urlbar" class="chromeclass-location uri-element" flex="1"
|
||||
type="autocomplete" searchSessions="history"
|
||||
type="autocomplete" autocompletesearch="history file"
|
||||
timeout="50" maxrows="6"
|
||||
disablehistory="false" accesskey="&locationBar.accesskey;"
|
||||
defaultSearchEngine="true" tabScrolling="true"
|
||||
|
@ -73,7 +73,7 @@
|
||||
|
||||
<hbox align="center">
|
||||
<textbox id="dialog.input" flex="1" type="autocomplete"
|
||||
searchSessions="history" timeout="50" maxrows="6"
|
||||
autocompletesearch="history file" timeout="50" maxrows="6"
|
||||
disablehistory="false" class="uri-element"
|
||||
oninput="doEnabling();">
|
||||
<menupopup id="ubhist-popup" class="autocomplete-history-popup"
|
||||
|
@ -100,7 +100,7 @@
|
||||
<hbox align="center">
|
||||
<label value="&location.label;" accesskey="&location.accesskey;" control="browserStartupHomepage"/>
|
||||
<textbox id="browserStartupHomepage" type="autocomplete" flex="1" class="uri-element"
|
||||
searchSessions="history" timeout="50" maxrows="6"
|
||||
autocompletesearch="history" timeout="50" maxrows="6"
|
||||
oninput="locationInputHandler();"/>
|
||||
<button label="&browseFile.label;" accesskey="&browseFile.accesskey;"
|
||||
oncommand="selectFile();"
|
||||
|
@ -82,6 +82,7 @@ REQUIRES = xpcom \
|
||||
browser \
|
||||
txmgr \
|
||||
chardet \
|
||||
autocomplete \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = nsModule.cpp
|
||||
|
@ -97,6 +97,6 @@ interface nsIBrowserHistory : nsIGlobalHistory2
|
||||
%{ C++
|
||||
|
||||
#define NS_GLOBALHISTORY_AUTOCOMPLETE_CONTRACTID \
|
||||
"@mozilla.org/autocompleteSession;1?type=history"
|
||||
"@mozilla.org/autocomplete/search;1?name=history"
|
||||
|
||||
%}
|
||||
|
@ -57,6 +57,7 @@ REQUIRES = xpcom \
|
||||
unicharutil \
|
||||
uconv \
|
||||
appcomps \
|
||||
autocomplete \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = nsGlobalHistory.cpp \
|
||||
|
@ -538,7 +538,8 @@ NS_INTERFACE_MAP_BEGIN(nsGlobalHistory)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRDFDataSource)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIRDFRemoteDataSource)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAutoCompleteSession)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAutoCompleteSearch)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAutoCompleteResult)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIBrowserHistory)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
@ -801,16 +802,21 @@ nsGlobalHistory::AddNewPageToDatabase(const char *aURL,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGlobalHistory::RemovePageInternal(const char *aSpec)
|
||||
nsGlobalHistory::RemovePageInternal(const nsCString& aSpec)
|
||||
{
|
||||
if (!mTable) return NS_ERROR_NOT_INITIALIZED;
|
||||
// find the old row, ignore it if we don't have it
|
||||
nsCOMPtr<nsIMdbRow> row;
|
||||
nsresult rv = FindRow(kToken_URLColumn, aSpec, getter_AddRefs(row));
|
||||
nsresult rv = FindRow(kToken_URLColumn, aSpec.get(), getter_AddRefs(row));
|
||||
if (NS_FAILED(rv)) return NS_OK;
|
||||
|
||||
// remove the row
|
||||
mdb_err err = mTable->CutRow(mEnv, row);
|
||||
return RemovePageInternal(aSpec, row);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGlobalHistory::RemovePageInternal(const nsCString& aSpec, nsIMdbRow *aRow)
|
||||
{
|
||||
mdb_err err = mTable->CutRow(mEnv, aRow);
|
||||
NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
|
||||
|
||||
// if there are batches in progress, we don't want to notify
|
||||
@ -819,12 +825,12 @@ nsGlobalHistory::RemovePageInternal(const char *aSpec)
|
||||
if (!mBatchesInProgress) {
|
||||
// get the resource so we can do the notification
|
||||
nsCOMPtr<nsIRDFResource> oldRowResource;
|
||||
gRDFService->GetResource(nsDependentCString(aSpec), getter_AddRefs(oldRowResource));
|
||||
NotifyFindUnassertions(oldRowResource, row);
|
||||
gRDFService->GetResource(aSpec, getter_AddRefs(oldRowResource));
|
||||
NotifyFindUnassertions(oldRowResource, aRow);
|
||||
}
|
||||
|
||||
// not a fatal error if we can't cut all column
|
||||
err = row->CutAllColumns(mEnv);
|
||||
err = aRow->CutAllColumns(mEnv);
|
||||
NS_ASSERTION(err == 0, "couldn't cut all columns");
|
||||
|
||||
return Commit(kCompressCommit);
|
||||
@ -1029,6 +1035,22 @@ nsGlobalHistory::GetRowValue(nsIMdbRow *aRow, mdb_column aCol,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGlobalHistory::GetRowURL(nsIMdbRow *aRow, nsAString& aResult)
|
||||
{
|
||||
mdbYarn yarn;
|
||||
mdb_err err = aRow->AliasCellYarn(mEnv, kToken_URLColumn, &yarn);
|
||||
if (err != 0) return NS_ERROR_FAILURE;
|
||||
|
||||
const char* startPtr = (const char*)yarn.mYarn_Buf;
|
||||
if (startPtr)
|
||||
CopyUTF8toUTF16(Substring(startPtr, startPtr + yarn.mYarn_Fill), aResult);
|
||||
else
|
||||
aResult.Truncate();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::GetCount(PRUint32* aCount)
|
||||
{
|
||||
@ -1109,7 +1131,7 @@ nsGlobalHistory::RemovePage(nsIURI *aURI)
|
||||
nsCAutoString spec;
|
||||
nsresult rv = aURI->GetSpec(spec);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = RemovePageInternal(spec.get());
|
||||
rv = RemovePageInternal(spec);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1297,10 +1319,7 @@ nsGlobalHistory::GetLastPageVisited(nsACString& _retval)
|
||||
|
||||
NS_ENSURE_STATE(mMetaRow);
|
||||
|
||||
mdb_err err = GetRowValue(mMetaRow, kToken_LastPageVisited, _retval);
|
||||
NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
|
||||
|
||||
return NS_OK;
|
||||
return GetRowValue(mMetaRow, kToken_LastPageVisited, _retval);
|
||||
}
|
||||
|
||||
// Set the byte order in the history file. The given string value should
|
||||
@ -1330,8 +1349,8 @@ nsGlobalHistory::GetByteOrder(char **_retval)
|
||||
NS_ENSURE_STATE(mMetaRow);
|
||||
|
||||
nsCAutoString byteOrder;
|
||||
mdb_err err = GetRowValue(mMetaRow, kToken_ByteOrder, byteOrder);
|
||||
NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
|
||||
nsresult rv = GetRowValue(mMetaRow, kToken_ByteOrder, byteOrder);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*_retval = ToNewCString(byteOrder);
|
||||
NS_ENSURE_TRUE(*_retval, NS_ERROR_OUT_OF_MEMORY);
|
||||
@ -1444,11 +1463,7 @@ nsGlobalHistory::GetURIGeckoFlags(nsIURI *aURI, PRUint32* aFlags)
|
||||
if (!HasCell(mEnv, row, kToken_GeckoFlagsColumn))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRInt32 val;
|
||||
mdb_err err = GetRowValue(row, kToken_GeckoFlagsColumn, &val);
|
||||
NS_ENSURE_TRUE(err == 0, NS_ERROR_FAILURE);
|
||||
*aFlags = val;
|
||||
return NS_OK;
|
||||
return GetRowValue(row, kToken_GeckoFlagsColumn, (PRInt32*)aFlags);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -2062,7 +2077,7 @@ nsGlobalHistory::Unassert(nsIRDFResource* aSource,
|
||||
}
|
||||
|
||||
// ignore any error
|
||||
rv = RemovePageInternal(targetUrl);
|
||||
rv = RemovePageInternal(nsDependentCString(targetUrl));
|
||||
if (NS_FAILED(rv)) return NS_RDF_ASSERTION_REJECTED;
|
||||
|
||||
return NS_OK;
|
||||
@ -2795,7 +2810,7 @@ nsGlobalHistory::CreateFindEnumerator(nsIRDFResource *aSource,
|
||||
|
||||
// the enumerator will take ownership of the query
|
||||
SearchEnumerator *result =
|
||||
new SearchEnumerator(query, kToken_HiddenColumn, this);
|
||||
new SearchEnumerator(query, this);
|
||||
if (!result) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = result->Init(mEnv, mTable);
|
||||
@ -3875,7 +3890,7 @@ nsGlobalHistory::GetFindUriPrefix(const searchQuery& aQuery,
|
||||
PRBool
|
||||
nsGlobalHistory::SearchEnumerator::IsResult(nsIMdbRow *aRow)
|
||||
{
|
||||
if (HasCell(mEnv, aRow, mHiddenColumn))
|
||||
if (HasCell(mEnv, aRow, mHistory->kToken_HiddenColumn))
|
||||
return PR_FALSE;
|
||||
|
||||
mdb_err err;
|
||||
@ -4104,65 +4119,99 @@ nsGlobalHistory::SearchEnumerator::ConvertToISupports(nsIMdbRow* aRow,
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// nsGlobalHistory::AutoCompleteEnumerator
|
||||
// nsIAutoCompleteResult implementation
|
||||
//
|
||||
// Implementation
|
||||
|
||||
nsGlobalHistory::AutoCompleteEnumerator::~AutoCompleteEnumerator()
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::GetSearchString(nsAString& aSearchString)
|
||||
{
|
||||
aSearchString = mSearchString;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
PRBool
|
||||
nsGlobalHistory::AutoCompleteEnumerator::IsResult(nsIMdbRow* aRow)
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::GetSearchResult(PRUint16 *aSearchResult)
|
||||
{
|
||||
if (!HasCell(mEnv, aRow, mTypedColumn)) {
|
||||
if (mMatchOnlyTyped || HasCell(mEnv, aRow, mHiddenColumn))
|
||||
return PR_FALSE;
|
||||
NS_ENSURE_ARG_POINTER(aSearchResult);
|
||||
*aSearchResult = mResults.Count() ? (PRUint16)RESULT_SUCCESS : (PRUint16)RESULT_NOMATCH;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::GetDefaultIndex(PRInt32 *aDefaultIndex)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aDefaultIndex);
|
||||
*aDefaultIndex = mResults.Count() ? 0 : -1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::GetErrorDescription(nsAString& aErrorDescription)
|
||||
{
|
||||
aErrorDescription.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::GetMatchCount(PRUint32* aMatchCount)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aMatchCount);
|
||||
*aMatchCount = mResults.Count();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::GetValueAt(PRInt32 aIndex, nsAString& aValue)
|
||||
{
|
||||
NS_ENSURE_ARG_RANGE(aIndex, 0, mResults.Count() - 1);
|
||||
return GetRowURL(mResults[aIndex], aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::GetCommentAt(PRInt32 aIndex, nsAString& aValue)
|
||||
{
|
||||
NS_ENSURE_ARG(aIndex >= 0 && aIndex < mResults.Count());
|
||||
return GetRowValue(mResults[aIndex], kToken_NameColumn, aValue);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::GetStyleAt(PRInt32 aIndex, nsAString& aValue)
|
||||
{
|
||||
NS_ENSURE_ARG(aIndex >= 0 && aIndex < mResults.Count());
|
||||
aValue.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::RemoveValueAt(PRInt32 aIndex, PRBool aRemoveFromDb)
|
||||
{
|
||||
NS_ENSURE_ARG(aIndex >= 0 && aIndex < mResults.Count());
|
||||
if (aRemoveFromDb) {
|
||||
nsCAutoString url;
|
||||
nsCOMPtr<nsIMdbRow> row = mResults[aIndex];
|
||||
nsresult rv = GetRowValue(row, kToken_URLColumn, url);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = RemovePageInternal(url, row);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCAutoString url;
|
||||
mHistory->GetRowValue(aRow, mURLColumn, url);
|
||||
|
||||
NS_ConvertUTF8toUTF16 utf8Url(url);
|
||||
|
||||
PRBool result = mHistory->AutoCompleteCompare(utf8Url, mSelectValue, mExclude);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGlobalHistory::AutoCompleteEnumerator::ConvertToISupports(nsIMdbRow* aRow, nsISupports** aResult)
|
||||
{
|
||||
nsCAutoString url;
|
||||
mHistory->GetRowValue(aRow, mURLColumn, url);
|
||||
nsAutoString comments;
|
||||
mHistory->GetRowValue(aRow, mCommentColumn, comments);
|
||||
|
||||
nsCOMPtr<nsIAutoCompleteItem> newItem(do_CreateInstance(NS_AUTOCOMPLETEITEM_CONTRACTID));
|
||||
NS_ENSURE_TRUE(newItem, NS_ERROR_FAILURE);
|
||||
|
||||
newItem->SetValue(NS_ConvertUTF8toUTF16(url.get()));
|
||||
newItem->SetParam(aRow);
|
||||
newItem->SetComment(comments.get());
|
||||
|
||||
*aResult = newItem;
|
||||
NS_ADDREF(*aResult);
|
||||
mResults.RemoveObjectAt(aIndex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// nsIAutoCompleteSession implementation
|
||||
// nsIAutoCompleteSearch implementation
|
||||
//
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::OnStartLookup(const PRUnichar *searchString,
|
||||
nsIAutoCompleteResults *previousSearchResult,
|
||||
nsIAutoCompleteListener *listener)
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::StartSearch(const nsAString& aSearchString,
|
||||
const nsAString& aSearchParam,
|
||||
nsIAutoCompleteResult* aPreviousResult,
|
||||
nsIAutoCompleteObserver* aListener)
|
||||
{
|
||||
NS_ASSERTION(searchString, "searchString can't be null, fix your caller");
|
||||
NS_ENSURE_ARG_POINTER(listener);
|
||||
NS_ENSURE_ARG_POINTER(aListener);
|
||||
NS_ENSURE_STATE(gPrefBranch);
|
||||
|
||||
NS_ENSURE_SUCCESS(OpenDB(), NS_ERROR_FAILURE);
|
||||
@ -4170,167 +4219,48 @@ nsGlobalHistory::OnStartLookup(const PRUnichar *searchString,
|
||||
PRBool enabled = PR_FALSE;
|
||||
gPrefBranch->GetBoolPref(PREF_AUTOCOMPLETE_ENABLED, &enabled);
|
||||
|
||||
if (!enabled || searchString[0] == 0) {
|
||||
listener->OnAutoComplete(nsnull, nsIAutoCompleteStatus::ignored);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIAutoCompleteResults> results;
|
||||
results = do_CreateInstance(NS_AUTOCOMPLETERESULTS_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
AutoCompleteStatus status = nsIAutoCompleteStatus::failed;
|
||||
|
||||
// if the search string is empty after it has had prefixes removed, then
|
||||
// there is no need to proceed with the search
|
||||
nsAutoString cut(searchString);
|
||||
nsAutoString cut(aSearchString);
|
||||
AutoCompleteCutPrefix(cut, nsnull);
|
||||
if (cut.IsEmpty()) {
|
||||
listener->OnAutoComplete(results, status);
|
||||
if (cut.IsEmpty() || !enabled) {
|
||||
mResults.Clear();
|
||||
mSearchString = aSearchString;
|
||||
aListener->OnSearchResult(this, this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// pass string through filter and then determine which prefixes to exclude
|
||||
// when chopping prefixes off of history urls during comparison
|
||||
nsString filtered = AutoCompletePrefilter(nsDependentString(searchString));
|
||||
|
||||
nsString filtered = AutoCompletePrefilter(aSearchString);
|
||||
AutocompleteExclude exclude;
|
||||
AutoCompleteGetExcludeInfo(filtered, &exclude);
|
||||
|
||||
// perform the actual search here
|
||||
rv = AutoCompleteSearch(filtered, &exclude, previousSearchResult, results);
|
||||
|
||||
// describe the search results
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
||||
results->SetSearchString(searchString);
|
||||
results->SetDefaultItemIndex(0);
|
||||
|
||||
// determine if we have found any matches or not
|
||||
nsCOMPtr<nsISupportsArray> array;
|
||||
rv = results->GetItems(getter_AddRefs(array));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
PRUint32 nbrOfItems;
|
||||
rv = array->Count(&nbrOfItems);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (nbrOfItems >= 1) {
|
||||
status = nsIAutoCompleteStatus::matchFound;
|
||||
} else {
|
||||
status = nsIAutoCompleteStatus::noMatch;
|
||||
}
|
||||
}
|
||||
if (aPreviousResult == this &&
|
||||
StringBeginsWith(filtered, AutoCompletePrefilter(mSearchString))) {
|
||||
nsAutoString value;
|
||||
PRUint32 count = mResults.Count();
|
||||
while (count--) {
|
||||
GetRowURL(mResults[count], value);
|
||||
if (!AutoCompleteCompare(value, filtered, &exclude))
|
||||
mResults.RemoveObjectAt(count);
|
||||
}
|
||||
|
||||
// notify the listener
|
||||
listener->OnAutoComplete(results, status);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::OnStopLookup()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::OnAutoComplete(const PRUnichar *searchString,
|
||||
nsIAutoCompleteResults *previousSearchResult,
|
||||
nsIAutoCompleteListener *listener)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// AutoComplete stuff
|
||||
//
|
||||
|
||||
nsresult
|
||||
nsGlobalHistory::AutoCompleteSearch(const nsAString& aSearchString,
|
||||
AutocompleteExclude* aExclude,
|
||||
nsIAutoCompleteResults* aPrevResults,
|
||||
nsIAutoCompleteResults* aResults)
|
||||
{
|
||||
// determine if we can skip searching the whole history and only search
|
||||
// through the previous search results
|
||||
PRBool searchPrevious = PR_FALSE;
|
||||
if (aPrevResults) {
|
||||
nsXPIDLString prevURL;
|
||||
aPrevResults->GetSearchString(getter_Copies(prevURL));
|
||||
// if search string begins with the previous search string, it's a go
|
||||
searchPrevious = StringBeginsWith(aSearchString, prevURL);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupportsArray> resultItems;
|
||||
nsresult rv = aResults->GetItems(getter_AddRefs(resultItems));
|
||||
|
||||
if (searchPrevious) {
|
||||
// searching through the previous results...
|
||||
|
||||
nsCOMPtr<nsISupportsArray> prevResultItems;
|
||||
aPrevResults->GetItems(getter_AddRefs(prevResultItems));
|
||||
|
||||
PRUint32 count;
|
||||
prevResultItems->Count(&count);
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsIAutoCompleteItem> item;
|
||||
prevResultItems->GetElementAt(i, getter_AddRefs(item));
|
||||
|
||||
// make a copy of the value because AutoCompleteCompare
|
||||
// is destructive
|
||||
nsAutoString url;
|
||||
item->GetValue(url);
|
||||
|
||||
if (AutoCompleteCompare(url, aSearchString, aExclude))
|
||||
resultItems->AppendElement(item);
|
||||
}
|
||||
} else {
|
||||
// searching through the entire history...
|
||||
|
||||
// prepare the search enumerator
|
||||
AutoCompleteEnumerator* enumerator;
|
||||
enumerator = new AutoCompleteEnumerator(this, kToken_URLColumn,
|
||||
kToken_NameColumn,
|
||||
kToken_HiddenColumn,
|
||||
kToken_TypedColumn,
|
||||
mAutocompleteOnlyTyped,
|
||||
aSearchString, aExclude);
|
||||
|
||||
nsCOMPtr<nsISupports> kungFuDeathGrip(enumerator);
|
||||
mResults.Clear();
|
||||
|
||||
rv = enumerator->Init(mEnv, mTable);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// store hits in an auto array initially
|
||||
nsAutoVoidArray array;
|
||||
|
||||
// not using nsCOMPtr here to avoid time spent
|
||||
// refcounting while passing these around between the 3 arrays
|
||||
nsISupports* entry;
|
||||
mdb_pos pos;
|
||||
nsCOMPtr<nsIMdbRow> current;
|
||||
nsCOMPtr<nsIMdbTableRowCursor> cursor;
|
||||
NS_ENSURE_TRUE(mTable->GetTableRowCursor(mEnv, -1, getter_AddRefs(cursor)) == 0, NS_ERROR_FAILURE);
|
||||
|
||||
// step through the enumerator to get the items into 'array'
|
||||
// because we don't know how many items there will be
|
||||
PRBool hasMore;
|
||||
while (PR_TRUE) {
|
||||
enumerator->HasMoreElements(&hasMore);
|
||||
if (!hasMore) break;
|
||||
|
||||
// addref's each entry as it enters 'array'
|
||||
enumerator->GetNext(&entry);
|
||||
array.AppendElement(entry);
|
||||
while (cursor->NextRow(mEnv, getter_AddRefs(current), &pos) == 0 && current) {
|
||||
if (!HasCell(mEnv, current, kToken_TypedColumn)) {
|
||||
if (mAutocompleteOnlyTyped || HasCell(mEnv, current, kToken_HiddenColumn))
|
||||
continue;
|
||||
}
|
||||
|
||||
nsAutoString url;
|
||||
GetRowURL(current, url);
|
||||
if (AutoCompleteCompare(url, filtered, &exclude))
|
||||
mResults.AppendObject(current);
|
||||
}
|
||||
|
||||
// turn auto array into flat array for quick sort, now that we
|
||||
// know how many items there are
|
||||
PRUint32 count = array.Count();
|
||||
nsIAutoCompleteItem** items = new nsIAutoCompleteItem*[count];
|
||||
PRUint32 i;
|
||||
for (i = 0; i < count; ++i)
|
||||
items[i] = (nsIAutoCompleteItem*)array.ElementAt(i);
|
||||
|
||||
// Setup the structure we pass into the sort function,
|
||||
// including a set of url prefixes to ignore. These prefixes
|
||||
// must match with the logic in nsGlobalHistory::nsGlobalHistory().
|
||||
@ -4352,25 +4282,25 @@ nsGlobalHistory::AutoCompleteSearch(const nsAString& aSearchString,
|
||||
closure.prefixes[3] = &prefixHSStr;
|
||||
closure.prefixes[4] = &prefixFFStr;
|
||||
closure.prefixes[5] = &prefixFStr;
|
||||
|
||||
// sort it
|
||||
NS_QuickSort(items, count, sizeof(nsIAutoCompleteItem*),
|
||||
AutoCompleteSortComparison,
|
||||
NS_STATIC_CAST(void*, &closure));
|
||||
|
||||
// place the sorted array into the autocomplete results
|
||||
for (i = 0; i < count; ++i) {
|
||||
nsISupports* item = (nsISupports*)items[i];
|
||||
resultItems->AppendElement(item);
|
||||
NS_IF_RELEASE(item); // release manually since we didn't use nsCOMPtr above
|
||||
}
|
||||
|
||||
delete[] items;
|
||||
mResults.Sort(AutoCompleteSortComparison, (void*)&closure);
|
||||
}
|
||||
|
||||
|
||||
mSearchString = aSearchString;
|
||||
aListener->OnSearchResult(this, this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalHistory::StopSearch()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// AutoComplete stuff
|
||||
//
|
||||
|
||||
// If aURL begins with a protocol or domain prefix from our lists,
|
||||
// then mark their index in an AutocompleteExclude struct.
|
||||
void
|
||||
@ -4468,26 +4398,13 @@ nsGlobalHistory::AutoCompleteCompare(nsAString& aHistoryURL,
|
||||
return StringBeginsWith(aHistoryURL, aUserURL);
|
||||
}
|
||||
|
||||
int PR_CALLBACK
|
||||
nsGlobalHistory::AutoCompleteSortComparison(const void *v1, const void *v2,
|
||||
void *closureVoid)
|
||||
int PR_CALLBACK
|
||||
nsGlobalHistory::AutoCompleteSortComparison(nsIMdbRow* row1, nsIMdbRow* row2,
|
||||
void* closureVoid)
|
||||
{
|
||||
//
|
||||
// NOTE: The design and reasoning behind the following autocomplete
|
||||
// sort implementation is documented in bug 78270.
|
||||
//
|
||||
|
||||
// cast our function parameters back into their real form
|
||||
nsIAutoCompleteItem *item1 = *(nsIAutoCompleteItem**) v1;
|
||||
nsIAutoCompleteItem *item2 = *(nsIAutoCompleteItem**) v2;
|
||||
AutoCompleteSortClosure* closure =
|
||||
NS_STATIC_CAST(AutoCompleteSortClosure*, closureVoid);
|
||||
|
||||
// get history rows
|
||||
nsCOMPtr<nsIMdbRow> row1, row2;
|
||||
item1->GetParam(getter_AddRefs(row1));
|
||||
item2->GetParam(getter_AddRefs(row2));
|
||||
|
||||
// get visit counts - we're ignoring all errors from GetRowValue(),
|
||||
// and relying on default values
|
||||
PRInt32 item1visits = 0, item2visits = 0;
|
||||
@ -4500,8 +4417,8 @@ nsGlobalHistory::AutoCompleteSortComparison(const void *v1, const void *v2,
|
||||
|
||||
// get URLs
|
||||
nsAutoString url1, url2;
|
||||
item1->GetValue(url1);
|
||||
item2->GetValue(url2);
|
||||
closure->history->GetRowURL(row1, url1);
|
||||
closure->history->GetRowURL(row2, url2);
|
||||
|
||||
// Favour websites and webpaths more than webpages by boosting
|
||||
// their visit counts. This assumes that URLs have been normalized,
|
||||
|
@ -54,10 +54,14 @@
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsAString.h"
|
||||
#include "nsString.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsIAutoCompleteSession.h"
|
||||
#include "nsIAutoCompleteSearch.h"
|
||||
#include "nsIAutoCompleteResult.h"
|
||||
#include "nsHashSets.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -130,7 +134,8 @@ class nsGlobalHistory : nsSupportsWeakReference,
|
||||
public nsIObserver,
|
||||
public nsIRDFDataSource,
|
||||
public nsIRDFRemoteDataSource,
|
||||
public nsIAutoCompleteSession,
|
||||
public nsIAutoCompleteSearch,
|
||||
public nsIAutoCompleteResult,
|
||||
public nsIGlobalHistory3
|
||||
{
|
||||
public:
|
||||
@ -143,7 +148,8 @@ public:
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSIRDFDATASOURCE
|
||||
NS_DECL_NSIRDFREMOTEDATASOURCE
|
||||
NS_DECL_NSIAUTOCOMPLETESESSION
|
||||
NS_DECL_NSIAUTOCOMPLETESEARCH
|
||||
NS_DECL_NSIAUTOCOMPLETERESULT
|
||||
|
||||
NS_METHOD Init();
|
||||
|
||||
@ -216,11 +222,9 @@ protected:
|
||||
PRBool mAutocompleteOnlyTyped;
|
||||
nsStringArray mIgnoreSchemes;
|
||||
nsStringArray mIgnoreHostnames;
|
||||
nsString mSearchString;
|
||||
nsCOMArray<nsIMdbRow> mResults;
|
||||
|
||||
nsresult AutoCompleteSearch(const nsAString& aSearchString,
|
||||
AutocompleteExclude* aExclude,
|
||||
nsIAutoCompleteResults* aPrevResults,
|
||||
nsIAutoCompleteResults* aResults);
|
||||
void AutoCompleteCutPrefix(nsAString& aURL, AutocompleteExclude* aExclude);
|
||||
void AutoCompleteGetExcludeInfo(const nsAString& aURL, AutocompleteExclude* aExclude);
|
||||
nsString AutoCompletePrefilter(const nsAString& aSearchString);
|
||||
@ -228,7 +232,7 @@ protected:
|
||||
const nsAString& aUserURL,
|
||||
AutocompleteExclude* aExclude);
|
||||
PR_STATIC_CALLBACK(int)
|
||||
AutoCompleteSortComparison(const void *v1, const void *v2, void *unused);
|
||||
AutoCompleteSortComparison(nsIMdbRow* v1, nsIMdbRow* v2, void *unused);
|
||||
|
||||
// AutoCompleteSortClosure - used to pass info into
|
||||
// AutoCompleteSortComparison from the NS_QuickSort() function
|
||||
@ -320,7 +324,8 @@ protected:
|
||||
const char *aReferrer,
|
||||
nsIMdbRow **aResult);
|
||||
|
||||
nsresult RemovePageInternal(const char *aSpec);
|
||||
nsresult RemovePageInternal(const nsCString& aSpec);
|
||||
nsresult RemovePageInternal(const nsCString& aSpec, nsIMdbRow *aRow);
|
||||
|
||||
//
|
||||
// generic routines for setting/retrieving various datatypes
|
||||
@ -335,6 +340,9 @@ protected:
|
||||
nsresult GetRowValue(nsIMdbRow *aRow, mdb_column aCol, PRTime* aResult);
|
||||
nsresult GetRowValue(nsIMdbRow *aRow, mdb_column aCol, PRInt32* aResult);
|
||||
|
||||
// specific routine to get a URL but convert it from UTF-8
|
||||
nsresult GetRowURL(nsIMdbRow *aRow, nsAString& aResult);
|
||||
|
||||
// Look up a row in mStore and returns success if it is found or failure
|
||||
// if it is not. |aResult| may be null if only testing for row existance.
|
||||
nsresult FindRow(mdb_column aCol, const char *aURL, nsIMdbRow **aResult);
|
||||
@ -413,10 +421,8 @@ protected:
|
||||
{
|
||||
public:
|
||||
SearchEnumerator(searchQuery *aQuery,
|
||||
mdb_column aHiddenColumn,
|
||||
nsGlobalHistory *aHistory) :
|
||||
mQuery(aQuery),
|
||||
mHiddenColumn(aHiddenColumn),
|
||||
mHistory(aHistory)
|
||||
{}
|
||||
|
||||
@ -424,7 +430,6 @@ protected:
|
||||
|
||||
protected:
|
||||
searchQuery *mQuery;
|
||||
mdb_column mHiddenColumn;
|
||||
nsGlobalHistory *mHistory;
|
||||
nsHashtable mUniqueRows;
|
||||
|
||||
@ -437,48 +442,8 @@ protected:
|
||||
PRBool RowMatches(nsIMdbRow* aRow, searchQuery *aQuery);
|
||||
};
|
||||
|
||||
// AutoCompleteEnumerator - for searching for a partial url match
|
||||
class AutoCompleteEnumerator : public nsMdbTableEnumerator
|
||||
{
|
||||
protected:
|
||||
nsGlobalHistory* mHistory;
|
||||
mdb_column mURLColumn;
|
||||
mdb_column mHiddenColumn;
|
||||
mdb_column mTypedColumn;
|
||||
mdb_column mCommentColumn;
|
||||
AutocompleteExclude* mExclude;
|
||||
const nsAString& mSelectValue;
|
||||
PRBool mMatchOnlyTyped;
|
||||
|
||||
virtual ~AutoCompleteEnumerator();
|
||||
|
||||
public:
|
||||
AutoCompleteEnumerator(nsGlobalHistory* aHistory,
|
||||
mdb_column aURLColumn,
|
||||
mdb_column aCommentColumn,
|
||||
mdb_column aHiddenColumn,
|
||||
mdb_column aTypedColumn,
|
||||
PRBool aMatchOnlyTyped,
|
||||
const nsAString& aSelectValue,
|
||||
AutocompleteExclude* aExclude) :
|
||||
mHistory(aHistory),
|
||||
mURLColumn(aURLColumn),
|
||||
mHiddenColumn(aHiddenColumn),
|
||||
mTypedColumn(aTypedColumn),
|
||||
mCommentColumn(aCommentColumn),
|
||||
mExclude(aExclude),
|
||||
mSelectValue(aSelectValue),
|
||||
mMatchOnlyTyped(aMatchOnlyTyped) {}
|
||||
|
||||
protected:
|
||||
virtual PRBool IsResult(nsIMdbRow* aRow);
|
||||
virtual nsresult ConvertToISupports(nsIMdbRow* aRow, nsISupports** aResult);
|
||||
};
|
||||
|
||||
|
||||
friend class URLEnumerator;
|
||||
friend class SearchEnumerator;
|
||||
friend class AutoCompleteEnumerator;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user