зеркало из https://github.com/mozilla/gecko-dev.git
Bug 318817 r=beng: Import, store, and use bookmark keywords.
This commit is contained in:
Родитель
cb482bf585
Коммит
24ed20fbe1
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче