Bug 318817 r=beng: Import, store, and use bookmark keywords.

This commit is contained in:
brettw%gmail.com 2006-02-16 00:42:46 +00:00
Родитель 7ca5ab3faa
Коммит 32a2998fbc
5 изменённых файлов: 218 добавлений и 1 удалений

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

@ -1828,7 +1828,16 @@ function getShortcutOrURI(aURL, aPostDataRef)
{
// rjc: added support for URL shortcuts (3/30/1999)
try {
var shortcutURL = BMSVC.resolveKeyword(aURL, aPostDataRef);
var shortcutURL = null;
#ifdef MOZ_PLACES
var bookmarkService = Components.classes["@mozilla.org/browser/nav-bookmarks-service;1"]
.getService(nsCI.nsINavBookmarksService);
var shortcutURI = bookmarkService.getURIForKeyword(aURL);
if (shortcutURI)
shortcutURL = shortcutURI.spec;
#else
shortcutURL = BMSVC.resolveKeyword(aURL, aPostDataRef);
#endif
if (!shortcutURL) {
// rjc: add support for string substitution with shortcuts (4/4/2000)
// (see bug # 29871 for details)
@ -1836,7 +1845,13 @@ function getShortcutOrURI(aURL, aPostDataRef)
if (aOffset > 0) {
var cmd = aURL.substr(0, aOffset);
var text = aURL.substr(aOffset+1);
#ifdef MOZ_PLACES
shortcutURI = bookmarkService.getURIForKeyword(cmd);
if (shortcutURI)
shortcutURL = shortcutURI.spec;
#else
shortcutURL = BMSVC.resolveKeyword(cmd, aPostDataRef);
#endif
if (shortcutURL && text) {
var encodedText = null;
var charset = "";
@ -1846,6 +1861,8 @@ function getShortcutOrURI(aURL, aPostDataRef)
shortcutURL = matches[1];
charset = matches[2];
}
#ifndef MOZ_PLACES
// FIXME: Bug 327328, we don't have last charset in places yet.
else if (/%s/.test(shortcutURL) ||
(aPostDataRef && /%s/.test(aPostDataRef.value))) {
try {
@ -1853,6 +1870,7 @@ function getShortcutOrURI(aURL, aPostDataRef)
} catch (ex) {
}
}
#endif
if (charset)
encodedText = escape(convertFromUnicode(charset, text));

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

@ -364,6 +364,30 @@ interface nsINavBookmarksService : nsISupports
*/
PRInt32 indexOfFolder(in PRInt64 parent, in PRInt64 folder);
/**
* Associates the given keyword with the given URI.
*
* Use an empty keyword to clear the keyword associated with the URI. Use an
* empty URI to clear the URI associated with that keyword. In both of these
* cases, succeeds but does nothing if the URL/keyword is not found.
*
* When setting a keyword (both URI and keyword are specified), the URI must
* be bookmarked for the keyword to be persistent.
*/
void setKeywordForURI(in nsIURI uri, in AString keyword);
/**
* Retrieves the keyword for the given URI. Will be empty if no such
* keyword is found.
*/
AString getKeywordForURI(in nsIURI uri);
/**
* Returns the URI associated with the given keyword. Empty if no such
* keyword is found.
*/
nsIURI getURIForKeyword(in AString keyword);
/**
* Adds a bookmark observer. If ownsWeak is false, the bookmark service will
* keep an owning reference to the observer. If ownsWeak is true, then

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

@ -113,6 +113,7 @@ static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
#define KEY_FEEDURL_LOWER "feedurl"
#define KEY_LASTCHARSET_LOWER "last_charset"
#define KEY_ICON_LOWER "icon"
#define KEY_SHORTCUTURL_LOWER "shortcuturl"
#define BOOKMARKS_MENU_ICON_URI "chrome://browser/skin/places/bookmarks_menu.png"
#define BOOKMARKS_TOOLBAR_ICON_URI "chrome://browser/skin/places/bookmarks_toolbar.png"
@ -565,6 +566,7 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node)
nsAutoString feedUrl;
nsAutoString icon;
nsAutoString lastCharset;
nsAutoString keyword;
PRInt32 attrCount = node.GetAttributeCount();
for (PRInt32 i = 0; i < attrCount; i ++) {
const nsAString& key = node.GetKeyAt(i);
@ -576,12 +578,15 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node)
icon = node.GetValueAt(i);
} else if (key.LowerCaseEqualsLiteral(KEY_LASTCHARSET_LOWER)) {
lastCharset = node.GetValueAt(i);
} else if (key.LowerCaseEqualsLiteral(KEY_SHORTCUTURL_LOWER)) {
keyword = node.GetValueAt(i);
}
}
href.Trim(kWhitespace);
feedUrl.Trim(kWhitespace);
icon.Trim(kWhitespace);
lastCharset.Trim(kWhitespace);
keyword.Trim(kWhitespace);
// ignore <a> tags that have no href: we don't know what to do with them
if (href.IsEmpty()) {
@ -613,6 +618,10 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node)
if (! icon.IsEmpty())
SetFaviconForURI(frame.mPreviousLink, NS_ConvertUTF16toUTF8(icon));
// save the keyword, ignore errors
if (! keyword.IsEmpty())
mBookmarksService->SetKeywordForURI(frame.mPreviousLink, keyword);
// FIXME: save the last charset
}

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

@ -44,6 +44,7 @@
#include "nsNetUtil.h"
#include "nsIAnnotationService.h"
#include "nsIRemoteContainer.h"
#include "nsUnicharUtils.h"
const PRInt32 nsNavBookmarks::kFindBookmarksIndex_ItemChild = 0;
const PRInt32 nsNavBookmarks::kFindBookmarksIndex_FolderChild = 1;
@ -102,6 +103,17 @@ nsNavBookmarks::Init()
"parent INTEGER, "
"position INTEGER)"));
NS_ENSURE_SUCCESS(rv, rv);
// this index will make it faster to determine if a given item is
// bookmarked (used by history queries and vacuuming, for example)
rv = dbConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE INDEX moz_bookmarks_itemindex ON moz_bookmarks (item_child)"));
NS_ENSURE_SUCCESS(rv, rv);
// the most common operation is to find the children given a parent
rv = dbConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE INDEX moz_bookmarks_parentindex ON moz_bookmarks (parent)"));
NS_ENSURE_SUCCESS(rv, rv);
}
// moz_bookmarks_folders
@ -123,6 +135,24 @@ nsNavBookmarks::Init()
NS_ENSURE_SUCCESS(rv, rv);
}
// moz_keywords
dbConn->TableExists(NS_LITERAL_CSTRING("moz_keywords"), &exists);
if (! exists) {
rv = dbConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TABLE moz_keywords ("
"keyword VARCHAR(32) UNIQUE,"
"page_id INTEGER)"));
NS_ENSURE_SUCCESS(rv, rv);
// it should be fast to go url->ID and ID->url
rv = dbConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE INDEX moz_keywords_keywordindex ON moz_keywords (keyword)"));
NS_ENSURE_SUCCESS(rv, rv);
rv = dbConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE INDEX moz_keywords_pageindex ON moz_keywords (page_id)"));
NS_ENSURE_SUCCESS(rv, rv);
}
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING("SELECT id, name, type FROM moz_bookmarks_folders WHERE id = ?1"),
getter_AddRefs(mDBGetFolderInfo));
NS_ENSURE_SUCCESS(rv, rv);
@ -225,6 +255,20 @@ nsNavBookmarks::Init()
getter_AddRefs(mDBGetChildAt));
NS_ENSURE_SUCCESS(rv, rv);
// keywords
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT k.keyword FROM moz_history h "
"JOIN moz_keywords k ON h.id = k.page_id "
"WHERE h.url = ?1"),
getter_AddRefs(mDBGetKeywordForURI));
NS_ENSURE_SUCCESS(rv, rv);
rv = dbConn->CreateStatement(NS_LITERAL_CSTRING(
"SELECT url FROM moz_keywords k "
"JOIN moz_history h ON k.page_id = h.id "
"WHERE k.keyword = ?1"),
getter_AddRefs(mDBGetURIForKeyword));
NS_ENSURE_SUCCESS(rv, rv);
rv = InitRoots();
NS_ENSURE_SUCCESS(rv, rv);
@ -1495,6 +1539,124 @@ nsNavBookmarks::IndexOfFolder(PRInt64 aParent,
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::SetKeywordForURI(nsIURI* aURI, const nsAString& aKeyword)
{
nsresult rv;
mozStorageTransaction transaction(DBConn(), PR_FALSE);
nsNavHistory *history = History();
NS_ENSURE_TRUE(history, NS_ERROR_UNEXPECTED);
PRInt64 pageId;
nsCOMPtr<mozIStorageStatement> statement;
// Shortcuts are always lowercased internally.
nsAutoString kwd(aKeyword);
ToLowerCase(kwd);
if (kwd.IsEmpty()) {
// delete any existing keyword for the given URI
rv = history->GetUrlIdFor(aURI, &pageId, PR_FALSE);
if (! pageId)
return NS_OK; // URL not found: no keyword
rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING(
"DELETE FROM moz_keywords WHERE page_id = ?1"),
getter_AddRefs(statement));
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindInt64Parameter(0, pageId);
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->Execute();
NS_ENSURE_SUCCESS(rv, rv);
return transaction.Commit();
} else if (! aURI) {
// delete any existing URIs associated with the given keyword
rv = history->GetUrlIdFor(aURI, &pageId, PR_FALSE);
if (! pageId)
return NS_OK; // URL not found: no keyword
rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING(
"DELETE FROM moz_keywords WHERE keyword = ?1"),
getter_AddRefs(statement));
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindStringParameter(0, kwd);
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->Execute();
NS_ENSURE_SUCCESS(rv, rv);
return transaction.Commit();
}
// otherwise, we have a URI/keyword pair and want to create it...
rv = history->GetUrlIdFor(aURI, &pageId, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
// this statement will overwrite any old keyword with that value since the
// keyword column is unique and we use "OR REPLACE" conflict resolution
rv = DBConn()->CreateStatement(NS_LITERAL_CSTRING(
"INSERT OR REPLACE INTO moz_keywords (keyword, page_id) VALUES (?1, ?2)"),
getter_AddRefs(statement));
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindStringParameter(0, kwd);
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->BindInt64Parameter(1, pageId);
NS_ENSURE_SUCCESS(rv, rv);
rv = statement->Execute();
NS_ENSURE_SUCCESS(rv, rv);
return transaction.Commit();
}
NS_IMETHODIMP
nsNavBookmarks::GetKeywordForURI(nsIURI* aURI, nsAString& aKeyword)
{
aKeyword.Truncate(0);
mozStorageStatementScoper scoper(mDBGetKeywordForURI);
nsresult rv = BindStatementURI(mDBGetKeywordForURI, 0, aURI);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasMore = PR_FALSE;
rv = mDBGetKeywordForURI->ExecuteStep(&hasMore);
if (NS_FAILED(rv) || ! hasMore)
return NS_OK; // not found: leave keyword field empty
// found, get the keyword
return mDBGetKeywordForURI->GetString(0, aKeyword);
}
NS_IMETHODIMP
nsNavBookmarks::GetURIForKeyword(const nsAString& aKeyword, nsIURI** aURI)
{
*aURI = nsnull;
if (aKeyword.IsEmpty())
return NS_ERROR_INVALID_ARG;
// Shortcuts are always lowercased internally.
nsAutoString kwd(aKeyword);
ToLowerCase(kwd);
mozStorageStatementScoper scoper(mDBGetURIForKeyword);
nsresult rv = mDBGetURIForKeyword->BindStringParameter(0, kwd);
NS_ENSURE_SUCCESS(rv, rv);
PRBool hasMore = PR_FALSE;
rv = mDBGetURIForKeyword->ExecuteStep(&hasMore);
if (NS_FAILED(rv) || ! hasMore)
return NS_OK; // not found: leave URI null
// found, get the URI
nsCAutoString spec;
rv = mDBGetURIForKeyword->GetUTF8String(0, spec);
NS_ENSURE_SUCCESS(rv, rv);
return NS_NewURI(aURI, spec);
}
NS_IMETHODIMP
nsNavBookmarks::BeginUpdateBatch()
{

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

@ -138,6 +138,10 @@ private:
nsCOMPtr<mozIStorageStatement> mDBIndexOfFolder;
nsCOMPtr<mozIStorageStatement> mDBGetChildAt;
// keywords
nsCOMPtr<mozIStorageStatement> mDBGetKeywordForURI;
nsCOMPtr<mozIStorageStatement> mDBGetURIForKeyword;
nsCOMPtr<nsIStringBundle> mBundle;
// in nsBookmarksHTML