fix for bug #373353: add favicons to the results in the location bar

r=mano
This commit is contained in:
sspitzer@mozilla.org 2007-07-20 14:55:18 -07:00
Родитель db95de1c59
Коммит d629c97e68
16 изменённых файлов: 159 добавлений и 27 удалений

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

@ -194,6 +194,15 @@ SuggestAutoCompleteResult.prototype = {
return "suggesthint"; // category label on any other line of results
},
/**
* Retrieves an image url.
* @param index the index of the image url requested
* @return the image url at the specified index
*/
getImageAt: function(index) {
return "";
},
/**
* Removes a result from the resultset
* @param index the index of the result to remove

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

@ -985,6 +985,12 @@ statusbarpanel#statusbar-display {
/* ----- AUTOCOMPLETE ----- */
.autocomplete-treebody::-moz-tree-image(favicon, treecolAutoCompleteValue) {
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
width: 16px;
height: 16px;
}
.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
color: #555566;
}

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

@ -986,6 +986,12 @@ statusbarpanel#statusbar-display {
/* ::::: autocomplete ::::: */
.autocomplete-treebody::-moz-tree-image(favicon, treecolAutoCompleteValue) {
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
width: 16px;
height: 16px;
}
.autocomplete-treebody::-moz-tree-cell-text(treecolAutoCompleteComment) {
color: #555566;
}

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

@ -41,7 +41,7 @@
interface nsIAutoCompleteInput;
[scriptable, uuid(476E1472-4357-4CD0-AFE3-FEA3112617B2)]
[scriptable, uuid(b865d5cf-2ce1-4a5b-bb99-3d8a71df5ee9)]
interface nsIAutoCompleteController : nsISupports
{
/*
@ -137,6 +137,11 @@ interface nsIAutoCompleteController : nsISupports
*/
AString getStyleAt(in long index);
/*
* Get the url of the image of the result at a given index in the last completed search
*/
AString getImageAt(in long index);
/*
* Set the current search string, but don't start searching
*/

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

@ -37,7 +37,7 @@
#include "nsISupports.idl"
[scriptable, uuid(eb43e1dc-2060-4d8e-aebf-3efec4e21cf8)]
[scriptable, uuid(78c49e44-4613-48c4-b502-29df82231222)]
interface nsIAutoCompleteResult : nsISupports
{
/**
@ -88,6 +88,11 @@ interface nsIAutoCompleteResult : nsISupports
*/
AString getStyleAt(in long index);
/**
* Get the image of the result at the given index
*/
AString getImageAt(in long index);
/**
* Remove the value at the given index from the autocomplete results.
* If removeFromDb is set to true, the value should be removed from

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

@ -47,7 +47,7 @@ interface nsIAutoCompleteSimpleResultListener;
* an array.
*/
[scriptable, uuid(916e3d78-4622-446b-924a-20f7021793b7)]
[scriptable, uuid(f9841787-ad26-49e6-a2dd-ba9020ee1c64)]
interface nsIAutoCompleteSimpleResult : nsIAutoCompleteResult
{
/**
@ -75,10 +75,12 @@ interface nsIAutoCompleteSimpleResult : nsIAutoCompleteResult
void setSearchResult(in unsigned short aSearchResult);
/**
* Appends a result item consisting of the given value and comment. This is
* how you add results.
* Appends a result item consisting of the given value, comment, image and style.
* This is how you add results. Note: image and style are optional.
*/
void appendMatch(in AString aValue, in AString aComment);
void appendMatch(in AString aValue, in AString aComment,
[optional] in AString aImage,
[optional] in AString aStyle);
/**
* Sets a listener for changes in the result.

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

@ -581,9 +581,7 @@ nsAutoCompleteController::GetCommentAt(PRInt32 aIndex, nsAString & _retval)
mResults->GetElementAt(searchIndex, getter_AddRefs(result));
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
result->GetCommentAt(rowIndex, _retval);
return NS_OK;
return result->GetCommentAt(rowIndex, _retval);
}
NS_IMETHODIMP
@ -598,9 +596,22 @@ nsAutoCompleteController::GetStyleAt(PRInt32 aIndex, nsAString & _retval)
mResults->GetElementAt(searchIndex, getter_AddRefs(result));
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
result->GetStyleAt(rowIndex, _retval);
return result->GetStyleAt(rowIndex, _retval);
}
return NS_OK;
NS_IMETHODIMP
nsAutoCompleteController::GetImageAt(PRInt32 aIndex, nsAString & _retval)
{
PRInt32 searchIndex;
PRInt32 rowIndex;
RowIndexToSearch(aIndex, &searchIndex, &rowIndex);
NS_ENSURE_TRUE(searchIndex >= 0 && rowIndex >= 0, NS_ERROR_FAILURE);
nsCOMPtr<nsIAutoCompleteResult> result;
mResults->GetElementAt(searchIndex, getter_AddRefs(result));
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
return result->GetImageAt(rowIndex, _retval);
}
NS_IMETHODIMP
@ -726,6 +737,12 @@ nsAutoCompleteController::GetColumnProperties(nsITreeColumn* col, nsISupportsArr
NS_IMETHODIMP
nsAutoCompleteController::GetImageSrc(PRInt32 row, nsITreeColumn* col, nsAString& _retval)
{
const PRUnichar* colID;
col->GetIdConst(&colID);
if (NS_LITERAL_STRING("treecolAutoCompleteValue").Equals(colID))
return GetImageAt(row, _retval);
return NS_OK;
}

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

@ -161,6 +161,12 @@ nsAutoCompleteMdbResult::GetStyleAt(PRInt32 aIndex, nsAString & _retval)
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsAutoCompleteMdbResult::GetImageAt(PRInt32 aIndex, nsAString & _retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
////////////////////////////////////////////////////////////////////////
//// nsIAutoCompleteBaseResult

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

@ -106,15 +106,31 @@ nsAutoCompleteSimpleResult::SetErrorDescription(
NS_IMETHODIMP
nsAutoCompleteSimpleResult::AppendMatch(const nsAString& aValue,
const nsAString& aComment)
const nsAString& aComment,
const nsAString& aImage,
const nsAString& aStyle)
{
NS_ASSERTION(mValues.Count() == mComments.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mImages.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mStyles.Count(), "Arrays out of sync");
if (! mValues.AppendString(aValue))
return NS_ERROR_OUT_OF_MEMORY;
if (! mComments.AppendString(aComment)) {
mValues.RemoveStringAt(mValues.Count() - 1);
return NS_ERROR_OUT_OF_MEMORY;
}
if (! mImages.AppendString(aImage)) {
mValues.RemoveStringAt(mValues.Count() - 1);
mComments.RemoveStringAt(mComments.Count() - 1);
return NS_ERROR_OUT_OF_MEMORY;
}
if (! mStyles.AppendString(aStyle)) {
mValues.RemoveStringAt(mValues.Count() - 1);
mComments.RemoveStringAt(mComments.Count() - 1);
mImages.RemoveStringAt(mImages.Count() - 1);
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
@ -122,6 +138,9 @@ NS_IMETHODIMP
nsAutoCompleteSimpleResult::GetMatchCount(PRUint32 *aMatchCount)
{
NS_ASSERTION(mValues.Count() == mComments.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mImages.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mStyles.Count(), "Arrays out of sync");
*aMatchCount = mValues.Count();
return NS_OK;
}
@ -132,6 +151,8 @@ nsAutoCompleteSimpleResult::GetValueAt(PRInt32 aIndex, nsAString& _retval)
NS_ENSURE_TRUE(aIndex >= 0 && aIndex < mValues.Count(),
NS_ERROR_ILLEGAL_VALUE);
NS_ASSERTION(mValues.Count() == mComments.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mImages.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mStyles.Count(), "Arrays out of sync");
mValues.StringAt(aIndex, _retval);
return NS_OK;
}
@ -142,14 +163,34 @@ nsAutoCompleteSimpleResult::GetCommentAt(PRInt32 aIndex, nsAString& _retval)
NS_ENSURE_TRUE(aIndex >= 0 && aIndex < mComments.Count(),
NS_ERROR_ILLEGAL_VALUE);
NS_ASSERTION(mValues.Count() == mComments.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mImages.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mStyles.Count(), "Arrays out of sync");
mComments.StringAt(aIndex, _retval);
return NS_OK;
}
NS_IMETHODIMP
nsAutoCompleteSimpleResult::GetImageAt(PRInt32 aIndex, nsAString& _retval)
{
NS_ENSURE_TRUE(aIndex >= 0 && aIndex < mImages.Count(),
NS_ERROR_ILLEGAL_VALUE);
NS_ASSERTION(mValues.Count() == mComments.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mImages.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mStyles.Count(), "Arrays out of sync");
mImages.StringAt(aIndex, _retval);
return NS_OK;
}
NS_IMETHODIMP
nsAutoCompleteSimpleResult::GetStyleAt(PRInt32 aIndex, nsAString& _retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
NS_ENSURE_TRUE(aIndex >= 0 && aIndex < mStyles.Count(),
NS_ERROR_ILLEGAL_VALUE);
NS_ASSERTION(mValues.Count() == mComments.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mImages.Count(), "Arrays out of sync");
NS_ASSERTION(mValues.Count() == mStyles.Count(), "Arrays out of sync");
mStyles.StringAt(aIndex, _retval);
return NS_OK;
}
NS_IMETHODIMP
@ -159,7 +200,6 @@ nsAutoCompleteSimpleResult::SetListener(nsIAutoCompleteSimpleResultListener* aLi
return NS_OK;
}
NS_IMETHODIMP
nsAutoCompleteSimpleResult::RemoveValueAt(PRInt32 aRowIndex,
PRBool aRemoveFromDb)
@ -170,6 +210,8 @@ nsAutoCompleteSimpleResult::RemoveValueAt(PRInt32 aRowIndex,
nsAutoString removedValue(*mValues.StringAt(aRowIndex));
mValues.RemoveStringAt(aRowIndex);
mComments.RemoveStringAt(aRowIndex);
mImages.RemoveStringAt(aRowIndex);
mStyles.RemoveStringAt(aRowIndex);
if (mListener)
mListener->OnValueRemoved(this, removedValue, aRemoveFromDb);

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

@ -60,11 +60,13 @@ private:
protected:
// What we really want is an array of structs with value/comment contents.
// What we really want is an array of structs with value/comment/image/style contents.
// But then we'd either have to use COM or manage object lifetimes ourselves.
// Having two arrays of string simplifies this, but is stupid.
// Having four arrays of string simplifies this, but is stupid.
nsStringArray mValues;
nsStringArray mComments;
nsStringArray mImages;
nsStringArray mStyles;
nsString mSearchString;
nsString mErrorDescription;

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

@ -149,6 +149,10 @@ AutoCompleteResult.prototype = {
return this._styles[aIndex];
},
getImageAt: function(aIndex) {
return "";
},
removeValueAt: function (aRowIndex, aRemoveFromDb) {},
// nsISupports implementation

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

@ -1280,6 +1280,10 @@ UserAutoCompleteResult.prototype = {
return "";
},
getImageAt : function (index) {
return "";
},
removeValueAt : function (index, removeFromDB) {
if (index < 0 || index >= this.logins.length)
throw "Index out of range.";

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

@ -161,10 +161,13 @@ nsresult NormalizeAutocompleteInput(const nsAString& aInput,
struct AutoCompleteIntermediateResult
{
AutoCompleteIntermediateResult(const nsString& aUrl, const nsString& aTitle,
const nsString& aImage,
PRInt32 aVisitCount, PRInt32 aPriority) :
url(aUrl), title(aTitle), visitCount(aVisitCount), priority(aPriority) {}
url(aUrl), title(aTitle), image(aImage),
visitCount(aVisitCount), priority(aPriority) {}
nsString url;
nsString title;
nsString image;
PRInt32 visitCount;
PRInt32 priority;
};
@ -271,8 +274,9 @@ nsNavHistory::CreateAutoCompleteQuery()
if (mAutoCompleteOnlyTyped) {
sql = NS_LITERAL_CSTRING(
"SELECT p.url, p.title, p.visit_count, p.typed, "
"(SELECT b.fk FROM moz_bookmarks b WHERE b.fk = p.id) "
"(SELECT b.fk FROM moz_bookmarks b WHERE b.fk = p.id), f.url "
"FROM moz_places p "
"LEFT OUTER JOIN moz_favicons f ON p.favicon_id = f.id "
"WHERE p.url >= ?1 AND p.url < ?2 "
"AND p.typed = 1 "
"ORDER BY p.visit_count DESC "
@ -280,8 +284,9 @@ nsNavHistory::CreateAutoCompleteQuery()
} else {
sql = NS_LITERAL_CSTRING(
"SELECT p.url, p.title, p.visit_count, p.typed, "
"(SELECT b.fk FROM moz_bookmarks b WHERE b.fk = p.id) "
"(SELECT b.fk FROM moz_bookmarks b WHERE b.fk = p.id), f.url "
"FROM moz_places p "
"LEFT OUTER JOIN moz_favicons f ON p.favicon_id = f.id "
"WHERE p.url >= ?1 AND p.url < ?2 "
"AND (p.hidden <> 1 OR p.typed = 1) "
"ORDER BY p.visit_count DESC "
@ -372,8 +377,9 @@ nsresult nsNavHistory::AutoCompleteTypedSearch(
// need to get more than the required minimum number since some will be dupes
nsCOMPtr<mozIStorageStatement> dbSelectStatement;
nsCString sql = NS_LITERAL_CSTRING(
"SELECT url, title "
"SELECT h.url, title, f.url "
"FROM moz_historyvisits v JOIN moz_places h ON v.place_id = h.id "
"LEFT OUTER JOIN moz_favicons f ON h.favicon_id = f.id "
"WHERE h.typed = 1 ORDER BY visit_date DESC LIMIT ");
sql.AppendInt(AUTOCOMPLETE_MAX_PER_TYPED * 3);
nsresult rv = mDBConn->CreateStatement(sql, getter_AddRefs(dbSelectStatement));
@ -389,13 +395,14 @@ nsresult nsNavHistory::AutoCompleteTypedSearch(
PRBool hasMore = PR_FALSE;
while (count < AUTOCOMPLETE_MAX_PER_TYPED &&
NS_SUCCEEDED(dbSelectStatement->ExecuteStep(&hasMore)) && hasMore) {
nsAutoString entryURL, entryTitle;
nsAutoString entryURL, entryTitle, entryImage;
dbSelectStatement->GetString(0, entryURL);
dbSelectStatement->GetString(1, entryTitle);
dbSelectStatement->GetString(2, entryImage);
if (! urls.Get(entryURL, &dummy)) {
// new item
rv = result->AppendMatch(entryURL, entryTitle);
rv = result->AppendMatch(entryURL, entryTitle, entryImage, NS_LITERAL_STRING("favicon"));
NS_ENSURE_SUCCESS(rv, rv);
urls.Put(entryURL, 1);
@ -496,13 +503,13 @@ nsNavHistory::AutoCompleteFullHistorySearch(const nsAString& aSearchString,
AutoCompleteResultComparator comparator(this);
matches.Sort(comparator);
rv = aResult->AppendMatch(matches[0].url, matches[0].title);
rv = aResult->AppendMatch(matches[0].url, matches[0].title, matches[0].image, NS_LITERAL_STRING("favicon"));
NS_ENSURE_SUCCESS(rv, rv);
for (i = 1; i < matches.Length(); i ++) {
// only add ones that are NOT the same as the previous one. It's possible
// to get duplicates from the queries.
if (!matches[i].url.Equals(matches[i-1].url)) {
rv = aResult->AppendMatch(matches[i].url, matches[i].title);
rv = aResult->AppendMatch(matches[i].url, matches[i].title, matches[i].image, NS_LITERAL_STRING("favicon"));
NS_ENSURE_SUCCESS(rv, rv);
}
}
@ -587,7 +594,7 @@ nsNavHistory::AutoCompleteQueryOnePrefix(const nsString& aSearchString,
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasMore;
nsAutoString url, title;
nsAutoString url, title, image;
while (NS_SUCCEEDED(mDBAutoCompleteQuery->ExecuteStep(&hasMore)) && hasMore) {
mDBAutoCompleteQuery->GetString(0, url);
mDBAutoCompleteQuery->GetString(1, title);
@ -595,8 +602,9 @@ nsNavHistory::AutoCompleteQueryOnePrefix(const nsString& aSearchString,
PRInt32 priority = ComputeAutoCompletePriority(url, visitCount,
mDBAutoCompleteQuery->AsInt32(3) > 0,
mDBAutoCompleteQuery->AsInt32(4) > 0) + aPriorityDelta;
mDBAutoCompleteQuery->GetString(5, image);
aResult->AppendElement(AutoCompleteIntermediateResult(
url, title, visitCount, priority));
url, title, image, visitCount, priority));
}
}
return NS_OK;

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

@ -101,6 +101,8 @@ public:
{ return mResult->GetCommentAt(aIndex, _result); }
NS_IMETHOD GetStyleAt(PRInt32 aIndex, nsAString &_result)
{ return mResult->GetStyleAt(aIndex, _result); }
NS_IMETHOD GetImageAt(PRInt32 aIndex, nsAString &_result)
{ return mResult->GetImageAt(aIndex, _result); }
NS_IMETHOD RemoveValueAt(PRInt32 aRowIndex, PRBool aRemoveFromDB);
NS_FORWARD_NSIAUTOCOMPLETESIMPLERESULT(mResult->)
@ -620,7 +622,7 @@ nsFormHistory::AutoCompleteSearch(const nsAString &aInputName,
// filters out irrelevant results
if(StringBeginsWith(entryString, aInputValue,
nsCaseInsensitiveStringComparator())) {
result->AppendMatch(entryString, EmptyString());
result->AppendMatch(entryString, EmptyString(), EmptyString(), EmptyString());
++count;
}
}

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

@ -177,6 +177,12 @@ NS_IMETHODIMP nsFileResult::GetStyleAt(PRInt32 index, nsAString & aStyle)
return NS_OK;
}
NS_IMETHODIMP nsFileResult::GetImageAt(PRInt32 index, nsAString & aImage)
{
aImage.Truncate();
return NS_OK;
}
NS_IMETHODIMP nsFileResult::RemoveValueAt(PRInt32 rowIndex, PRBool removeFromDb)
{
return NS_OK;

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

@ -4185,6 +4185,14 @@ nsGlobalHistory::GetStyleAt(PRInt32 aIndex, nsAString& aValue)
return NS_OK;
}
NS_IMETHODIMP
nsGlobalHistory::GetImageAt(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)
{