Bug 379211 - Use item IDs for annotating bookmark/folder items rather than place: URIs. r=dietrich.

This commit is contained in:
mozilla.mano%sent.com 2007-05-10 08:05:22 +00:00
Родитель 681d041bb8
Коммит c5bd30ba2d
30 изменённых файлов: 1860 добавлений и 913 удалений

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

@ -332,7 +332,7 @@ var gBookmarksObserver = {
onItemRemoved: function() { },
onItemChanged:
function G_BO_onItemChanged(aID, aBookmark, aProperty, aValue) {
function G_BO_onItemChanged(aID, aProperty, aIsAnnotationProperty, aValue) {
if (aProperty == "became_toolbar_folder" && this.toolbar)
this.toolbar.place = PlacesUtils.getQueryStringForFolder(aID);
},

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

@ -44,6 +44,10 @@ include $(DEPTH)/config/autoconf.mk
MODULE = microsummaries
XPIDL_MODULE = microsummaries
ifdef MOZ_PLACES_BOOKMARKS
XPIDLSRCS = nsIMicrosummaryService.idl
else
XPIDLSRCS = nsIMicrosummaryServiceNonPlaces.idl
endif
include $(topsrcdir)/config/rules.mk

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

@ -253,7 +253,7 @@ interface nsIMicrosummaryService : nsISupports
*
*/
nsIMicrosummarySet getMicrosummaries(in nsIURI pageURI,
in nsISupports bookmarkID);
in long long bookmarkID);
/**
* Get the current microsummary for the given bookmark.
@ -265,7 +265,7 @@ interface nsIMicrosummaryService : nsISupports
* if the bookmark does not have a current microsummary
*
*/
nsIMicrosummary getMicrosummary(in nsISupports bookmarkID);
nsIMicrosummary getMicrosummary(in long long bookmarkID);
/**
* Set the current microsummary for the given bookmark.
@ -277,7 +277,7 @@ interface nsIMicrosummaryService : nsISupports
* the microsummary to set as the current one
*
*/
void setMicrosummary(in nsISupports bookmarkID,
void setMicrosummary(in long long bookmarkID,
in nsIMicrosummary microsummary);
/**
@ -287,7 +287,7 @@ interface nsIMicrosummaryService : nsISupports
* the bookmark for which to remove the current microsummary
*
*/
void removeMicrosummary(in nsISupports bookmarkID);
void removeMicrosummary(in long long bookmarkID);
/**
* Whether or not the given bookmark has a current microsummary.
@ -299,7 +299,7 @@ interface nsIMicrosummaryService : nsISupports
* has a current microsummary
*
*/
boolean hasMicrosummary(in nsISupports bookmarkID);
boolean hasMicrosummary(in long long bookmarkID);
/**
* Whether or not the given microsummary is the current microsummary
@ -315,7 +315,7 @@ interface nsIMicrosummaryService : nsISupports
* for the bookmark
*
*/
boolean isMicrosummary(in nsISupports bookmarkID,
boolean isMicrosummary(in long long bookmarkID,
in nsIMicrosummary microsummary);
/**
@ -336,7 +336,7 @@ interface nsIMicrosummaryService : nsISupports
* @returns the microsummary being refreshed
*
*/
nsIMicrosummary refreshMicrosummary(in nsISupports bookmarkID);
nsIMicrosummary refreshMicrosummary(in long long bookmarkID);
};
[scriptable, uuid(f9e577a8-19d9-4ca0-a140-b9e43f014470)]
@ -346,7 +346,7 @@ interface nsILiveTitleNotificationSubject : nsISupports
// Note: in the old bookmarks code, this is an RDF resource. In Places
// it is currently a URI, but after the fix for bug 360133 lands it will
// become an integer.
readonly attribute nsISupports bookmarkID;
readonly attribute long long bookmarkID;
// The microsummary being displayed as the live title for the bookmark.
// The actual value of the microsummary (i.e. the string that gets displayed

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

@ -302,11 +302,10 @@ MicrosummaryService.prototype = {
oldValue = this._getField(bookmarkID, FIELD_GENERATED_TITLE);
// A string identifying the bookmark to use when logging the update.
var bookmarkIdentity =
#ifdef MOZ_PLACES_BOOKMARKS
bookmarkID.spec;
var bookmarkIdentity = bookmarkID;
#else
bookmarkID.Value + " (" + microsummary.pageURI.spec + ")";
var bookmarkIdentity = bookmarkID.Value + " (" + microsummary.pageURI.spec + ")";
#endif
if (oldValue == null || oldValue != microsummary.content) {
@ -613,7 +612,11 @@ MicrosummaryService.prototype = {
// If this is the current microsummary for this bookmark, load the content
// from the datastore so it shows up immediately in microsummary picking UI.
#ifdef MOZ_PLACES_BOOKMARKS
if (bookmarkID != -1 && this.isMicrosummary(bookmarkID, microsummary))
#else
if (bookmarkID && this.isMicrosummary(bookmarkID, microsummary))
#endif
microsummary._content = this._getField(bookmarkID, FIELD_GENERATED_TITLE);
microsummaries.AppendElement(microsummary);
@ -622,7 +625,11 @@ MicrosummaryService.prototype = {
// If a bookmark identifier has been provided, list its microsummary
// synchronously, if any.
#ifdef MOZ_PLACES_BOOKMARKS
if (bookmarkID != -1 && this.hasMicrosummary(bookmarkID)) {
#else
if (bookmarkID && this.hasMicrosummary(bookmarkID)) {
#endif
var currentMicrosummary = this.getMicrosummary(bookmarkID);
if (!microsummaries.hasItemForMicrosummary(currentMicrosummary))
microsummaries.AppendElement(currentMicrosummary);
@ -699,7 +706,7 @@ MicrosummaryService.prototype = {
// This try/catch block is a temporary workaround for bug 336194.
try {
bookmarks = this._ans.getPagesWithAnnotation(FIELD_MICSUM_GEN_URI, {});
bookmarks = this._ans.getItemsWithAnnotation(FIELD_MICSUM_GEN_URI, {});
}
catch(e) {
bookmarks = [];
@ -708,71 +715,56 @@ MicrosummaryService.prototype = {
return bookmarks;
},
_getField: function MSS__getField(aPlaceURI, aFieldName) {
aPlaceURI.QueryInterface(Ci.nsIURI);
_getField: function MSS__getField(aBookmarkId, aFieldName) {
var fieldValue;
switch(aFieldName) {
case FIELD_MICSUM_EXPIRATION:
fieldValue = this._ans.getAnnotationInt64(aPlaceURI, aFieldName);
fieldValue = this._ans.getItemAnnotationInt64(aBookmarkId, aFieldName);
break;
case FIELD_MICSUM_GEN_URI:
case FIELD_GENERATED_TITLE:
case FIELD_CONTENT_TYPE:
default:
fieldValue = this._ans.getAnnotationString(aPlaceURI, aFieldName);
fieldValue = this._ans.getItemAnnotationString(aBookmarkId, aFieldName);
break;
}
return fieldValue;
},
_setField: function MSS__setField(aPlaceURI, aFieldName, aFieldValue) {
aPlaceURI.QueryInterface(Ci.nsIURI);
_setField: function MSS__setField(aBookmarkId, aFieldName, aFieldValue) {
switch(aFieldName) {
case FIELD_MICSUM_EXPIRATION:
this._ans.setAnnotationInt64(aPlaceURI,
aFieldName,
aFieldValue,
0,
this._ans.EXPIRE_NEVER);
this._ans.setItemAnnotationInt64(aBookmarkId,
aFieldName,
aFieldValue,
0,
this._ans.EXPIRE_NEVER);
break;
case FIELD_MICSUM_GEN_URI:
case FIELD_GENERATED_TITLE:
case FIELD_CONTENT_TYPE:
default:
this._ans.setAnnotationString(aPlaceURI,
aFieldName,
aFieldValue,
0,
this._ans.EXPIRE_NEVER);
this._ans.setItemAnnotationString(aBookmarkId,
aFieldName,
aFieldValue,
0,
this._ans.EXPIRE_NEVER);
break;
}
},
_clearField: function MSS__clearField(aPlaceURI, aFieldName) {
aPlaceURI.QueryInterface(Ci.nsIURI);
this._ans.removeAnnotation(aPlaceURI, aFieldName);
_clearField: function MSS__clearField(aBookmarkId, aFieldName) {
this._ans.removeItemAnnotation(aBookmarkId, aFieldName);
},
_hasField: function MSS__hasField(aPlaceURI, fieldName) {
aPlaceURI.QueryInterface(Ci.nsIURI);
return this._ans.hasAnnotation(aPlaceURI, fieldName);
_hasField: function MSS__hasField(aBookmarkId, fieldName) {
return this._ans.itemHasAnnotation(aBookmarkId, fieldName);
},
_getPageForBookmark: function MSS__getPageForBookmark(aPlaceURI) {
aPlaceURI.QueryInterface(Ci.nsIURI);
// Manually get the bookmark identifier out of the place uri until
// the query system supports parsing this sort of place: uris
var matches = /moz_bookmarks.id=([0-9]+)/.exec(aPlaceURI.spec);
if (matches) {
var bookmarkId = parseInt(matches[1]);
return this._bms.getBookmarkURI(bookmarkId);
}
return null;
_getPageForBookmark: function MSS__getPageForBookmark(aBookmarkId) {
return this._bms.getBookmarkURI(aBookmarkId);
},
#else

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

@ -125,7 +125,7 @@ var BookmarkPropertiesPanel = {
_action: null,
_itemType: null,
_folderId: null,
_bookmarkId: null,
_bookmarkId: -1,
_bookmarkURI: null,
_loadBookmarkInSidebar: false,
_itemTitle: "",
@ -267,7 +267,6 @@ var BookmarkPropertiesPanel = {
const annos = PlacesUtils.annotations;
const bookmarks = PlacesUtils.bookmarks;
var placeURI;
switch (dialogInfo.type) {
case "bookmark":
NS_ASSERT("bookmarkId" in dialogInfo);
@ -275,7 +274,6 @@ var BookmarkPropertiesPanel = {
this._action = ACTION_EDIT;
this._itemType = BOOKMARK_ITEM;
this._bookmarkId = dialogInfo.bookmarkId;
placeURI = bookmarks.getItemURI(this._bookmarkId);
this._bookmarkURI = bookmarks.getBookmarkURI(this._bookmarkId);
this._itemTitle = bookmarks.getItemTitle(this._bookmarkId);
@ -286,7 +284,7 @@ var BookmarkPropertiesPanel = {
// Load In Sidebar
this._loadBookmarkInSidebar =
annos.hasAnnotation(placeURI, LOAD_IN_SIDEBAR_ANNO);
annos.itemHasAnnotation(this._bookmarkId, LOAD_IN_SIDEBAR_ANNO);
break;
case "folder":
@ -294,7 +292,6 @@ var BookmarkPropertiesPanel = {
this._action = ACTION_EDIT;
this._folderId = dialogInfo.folderId;
placeURI = bookmarks.getFolderURI(this._folderId);
const livemarks = PlacesUtils.livemarks;
if (livemarks.isLivemark(this._folderId)) {
@ -309,9 +306,11 @@ var BookmarkPropertiesPanel = {
}
// Description
if (annos.hasAnnotation(placeURI, DESCRIPTION_ANNO)) {
this._itemDescription =
annos.getAnnotationString(placeURI, DESCRIPTION_ANNO);
// XXXmano: unify the two id fields
var itemId = dialogInfo.type == "bookmark" ? this._bookmarkId : this._folderId;
if (annos.itemHasAnnotation(itemId, DESCRIPTION_ANNO)) {
this._itemDescription = annos.getItemAnnotationString(itemId,
DESCRIPTION_ANNO);
}
}
},
@ -382,10 +381,10 @@ var BookmarkPropertiesPanel = {
_initFolderMenuList: function BPP__initFolderMenuList() {
// List of recently used folders:
var annos = PlacesUtils.annotations;
var folderURIs = annos.getPagesWithAnnotation(LAST_USED_ANNO, { });
var folderIds = annos.getItemsWithAnnotation(LAST_USED_ANNO, { });
// Hide the folders-separator if no folder is annotated as recently-used
if (folderURIs.length == 0) {
if (folderIds.length == 0) {
this._element("foldersSeparator").hidden = true;
return;
}
@ -399,17 +398,9 @@ var BookmarkPropertiesPanel = {
* set. Then we sort it descendingly based on the time field.
*/
var folders = [];
var history = PlacesUtils.history;
for (var i=0; i < folderURIs.length; i++) {
var queryString = folderURIs[i].spec;
var queries = { };
history.queryStringToQueries(queryString, queries, { /* length */ },
{ /* options */ });
var folderId = queries.value[0].getFolders({})[0];
NS_ASSERT(queries.value[0].folderCount == 1,
"Bogus uri is annotated with the LAST_USED_ANNO annotation");
var lastUsed = annos.getAnnotationInt64(folderURIs[i], LAST_USED_ANNO);
folders.push({ folderId: folderId, lastUsed: lastUsed });
for (var i=0; i < folderIds.length; i++) {
var lastUsed = annos.getItemAnnotationInt64(folderIds[i], LAST_USED_ANNO);
folders.push({ folderId: folderIds[i], lastUsed: lastUsed });
}
folders.sort(function(a, b) {
if (b.lastUsed < a.lastUsed)
@ -551,14 +542,9 @@ var BookmarkPropertiesPanel = {
}
var itemToSelect = userEnteredNameField;
var placeURI = null;
if (this._action == ACTION_EDIT) {
NS_ASSERT(this._bookmarkId, "No bookmark identifier");
placeURI = PlacesUtils.bookmarks.getItemURI(this._bookmarkId);
}
try {
this._microsummaries = this._mss.getMicrosummaries(this._bookmarkURI,
placeURI);
this._bookmarkId);
}
catch(ex) {
// getMicrosummaries will throw an exception in at least two cases:
@ -583,7 +569,7 @@ var BookmarkPropertiesPanel = {
var menuItem = this._createMicrosummaryMenuItem(microsummary);
if (this._action == ACTION_EDIT &&
this._mss.isMicrosummary(placeURI, microsummary))
this._mss.isMicrosummary(this._bookmarkId, microsummary))
itemToSelect = menuItem;
menupopup.appendChild(menuItem);
@ -824,10 +810,9 @@ var BookmarkPropertiesPanel = {
// microsummary, but the bookmark previously had one, or the user
// selected a microsummary which is not the one the bookmark previously
// had.
var placeURI = PlacesUtils.bookmarks.getItemURI(itemId);
if ((newMicrosummary == null && this._mss.hasMicrosummary(placeURI)) ||
if ((newMicrosummary == null && this._mss.hasMicrosummary(itemId)) ||
(newMicrosummary != null &&
!this._mss.isMicrosummary(placeURI, newMicrosummary))) {
!this._mss.isMicrosummary(itemId, newMicrosummary))) {
transactions.push(
new PlacesEditBookmarkMicrosummaryTransaction(itemId,
newMicrosummary));
@ -1112,11 +1097,10 @@ var BookmarkPropertiesPanel = {
function BPP__markFolderAsRecentlyUsed(aFolderId) {
// We'll figure out when/if to expire the annotation if it turns out
// we keep this recently-used-folders implementation
var folderURI = PlacesUtils.bookmarks.getFolderURI(aFolderId);
PlacesUtils.annotations
.setAnnotationInt64(folderURI, LAST_USED_ANNO,
new Date().getTime(), 0,
Ci.nsIAnnotationService.EXPIRE_NEVER);
.setItemAnnotationInt64(aFolderId, LAST_USED_ANNO,
new Date().getTime(), 0,
Ci.nsIAnnotationService.EXPIRE_NEVER);
},
newFolder: function BPP_newFolder() {

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

@ -594,10 +594,10 @@ PlacesController.prototype = {
for (var j = 0; j < names.length; ++j)
nodeData[names[j]] = true;
// For bookmark-items also include the bookmark-specific annotations
if ("bookmark" in nodeData) {
var placeURI = PlacesUtils.bookmarks.getItemURI(node.bookmarkId);
names = PlacesUtils.annotations.getPageAnnotationNames(placeURI, {});
// For items also include the item-specific annotations
if ("bookmark" in nodeData || "folder" in nodeData) {
names = PlacesUtils.annotations
.getItemAnnotationNames(node.itemId, {});
for (j = 0; j < names.length; ++j)
nodeData[names[j]] = true;
}
@ -766,9 +766,8 @@ PlacesController.prototype = {
// Check whether the node is a bookmark which should be opened as
// a web panel
if (aWhere == "current" && PlacesUtils.nodeIsBookmark(node)) {
var placeURI = PlacesUtils.bookmarks.getItemURI(node.bookmarkId);
if (PlacesUtils.annotations
.hasAnnotation(placeURI, LOAD_IN_SIDEBAR_ANNO)) {
.itemHasAnnotation(node.itemId, LOAD_IN_SIDEBAR_ANNO)) {
var w = getTopWin();
if (w) {
w.openWebPanel(node.title, node.uri);
@ -792,7 +791,7 @@ PlacesController.prototype = {
if (PlacesUtils.nodeIsFolder(node))
PlacesUtils.showFolderProperties(asFolder(node).folderId);
else if (PlacesUtils.nodeIsBookmark(node))
PlacesUtils.showBookmarkProperties(node.bookmarkId);
PlacesUtils.showBookmarkProperties(node.itemId);
},
/**
@ -1121,7 +1120,7 @@ PlacesController.prototype = {
}
else if (PlacesUtils.nodeIsFolder(node.parent)) {
// A Bookmark in a Bookmark Folder.
transactions.push(new PlacesRemoveItemTransaction(node.bookmarkId,
transactions.push(new PlacesRemoveItemTransaction(node.itemId,
PlacesUtils._uri(node.uri), asFolder(node.parent).folderId, index));
}
}
@ -1645,10 +1644,9 @@ PlacesCreateFolderTransaction.prototype = {
doTransaction: function PCFT_doTransaction() {
var bookmarks = this.utils.bookmarks;
this._id = bookmarks.createFolder(this._container, this._name, this._index);
if (this._annotations.length > 0) {
var placeURI = bookmarks.getFolderURI(this._id);
this.utils.setAnnotationsForURI(placeURI, this._annotations);
}
if (this._annotations.length > 0)
this.utils.setAnnotationsForItem(this._id, this._annotations);
for (var i = 0; i < this._childItemsTransactions.length; ++i) {
var txn = this._childItemsTransactions[i];
txn.container = this._id;
@ -1715,10 +1713,8 @@ PlacesCreateItemTransaction.prototype = {
bookmarks.setItemTitle(this._id, this._title);
if (this._keyword)
bookmarks.setKeywordForBookmark(this._id, this._keyword);
if (this._annotations && this._annotations.length > 0) {
var placeURI = bookmarks.getItemURI(this._id);
this.utils.setAnnotationsForURI(placeURI, this._annotations);
}
if (this._annotations && this._annotations.length > 0)
this.utils.setAnnotationsForItem(this._id, this._annotations);
for (var i = 0; i < this._childTransactions.length; ++i) {
var txn = this._childTransactions[i];
@ -1804,10 +1800,8 @@ PlacesCreateLivemarkTransaction.prototype = {
this._id = this.utils.livemarks
.createLivemark(this._container, this._name, this._siteURI,
this._feedURI, this._index);
if (this._annotations) {
var placeURI = this.utils.bookmarks.getFolderURI(this._id);
this.utils.setAnnotationsForURI(placeURI, this._annotations);
}
if (this._annotations)
this.utils.setAnnotationsForItem(this._id, this._annotations);
},
undoTransaction: function PCLT_undoTransaction() {
@ -1860,26 +1854,21 @@ PlacesMoveItemTransaction.prototype = {
doTransaction: function PMIT_doTransaction() {
this.LOG("Move Item: " + this._uri.spec + " from: " + this._oldContainer + "," + this._oldIndex + " to: " + this._newContainer + "," + this._newIndex);
var title = this.bookmarks.getItemTitle(this._id);
var placeURI = this.bookmarks.getItemURI(this._id);
var annotations = this.utils.getAnnotationsForURI(placeURI);
var annotations = this.utils.getAnnotationsForItem(this._id);
this.bookmarks.removeItem(this._id);
this._id = this.bookmarks.insertItem(this._newContainer, this._uri, this._newIndex);
this.bookmarks.setItemTitle(this._id, title);
this.utils.setAnnotationsForURI(this.bookmarks.getItemURI(this._id),
annotations);
this.utils.setAnnotationsForItem(this._id, annotations);
},
undoTransaction: function PMIT_undoTransaction() {
this.LOG("UNMove Item: " + this._uri.spec + " from: " + this._oldContainer + "," + this._oldIndex + " to: " + this._newContainer + "," + this._newIndex);
var title = this.bookmarks.getItemTitle(this._id);
var placeURI = this.bookmarks.getItemURI(this._id);
var annotations = this.utils.getAnnotationsForURI(placeURI);
var annotations = this.utils.getAnnotationsForItem(this._id);
this.bookmarks.removeItem(this._id);
this._id = this.bookmarks.insertItem(this._oldContainer, this._uri, this._oldIndex);
this.bookmarks.setItemTitle(this._id, title);
placeURI = this.bookmarks.getItemURI(this._id);
this.utils.setAnnotationsForURI(this.bookmarks.getItemURI(this._id),
annotations);
this.utils.setAnnotationsForItem(this._id, annotations);
}
};
@ -1925,7 +1914,7 @@ PlacesRemoveFolderTransaction.prototype = {
txn = new PlacesRemoveSeparatorTransaction(this._id, i);
}
else {
txn = new PlacesRemoveItemTransaction(child.bookmarkId,
txn = new PlacesRemoveItemTransaction(child.itemId,
ios.newURI(child.uri, null, null),
this._id, i);
}
@ -1976,18 +1965,15 @@ PlacesRemoveItemTransaction.prototype = {
doTransaction: function PRIT_doTransaction() {
this.LOG("Remove Item: " + this._uri.spec + " from: " + this._oldContainer + "," + this._oldIndex);
this._title = this.bookmarks.getItemTitle(this._id);
this._placeURI = this.bookmarks.getItemURI(this._id);
this._annotations = this.utils.getAnnotationsForURI(this._placeURI);
PlacesUtils.annotations.removePageAnnotations(this._placeURI);
this.bookmarks.removeItem(this._id);
this._annotations = this.utils.getAnnotationsForItem(this._id);
this.utils.bookmarks.removeItem(this._id);
},
undoTransaction: function PRIT_undoTransaction() {
this.LOG("UNRemove Item: " + this._uri.spec + " from: " + this._oldContainer + "," + this._oldIndex);
this._id = this.bookmarks.insertItem(this._oldContainer, this._uri, this._oldIndex);
this.bookmarks.setItemTitle(this._id, this._title);
this._placeURI = this.bookmarks.getItemURI(this._id);
this.utils.setAnnotationsForURI(this._placeURI, this._annotations);
this.utils.setAnnotationsForItem(this._id, this._annotations);
}
};
@ -2075,19 +2061,14 @@ PlacesSetLoadInSidebarTransaction.prototype = {
},
doTransaction: function PSLIST_doTransaction() {
if (!("_placeURI" in this))
this._placeURI = this.utils.bookmarks.getItemURI(this.id);
this._wasSet = this.utils.annotations
.hasAnnotation(this._placeURI, this._anno.name);
.itemHasAnnotation(this.id, this._anno.name);
if (this._loadInSidebar) {
this.utils.setAnnotationsForURI(this._placeURI,
[this._anno]);
this.utils.setAnnotationsForItem(this.id, [this._anno]);
}
else {
try {
this.utils.annotations.removeAnnotation(this._placeURI,
this._anno.name);
this.utils.annotations.removeItemAnnotation(this.id, this._anno.name);
} catch(ex) { }
}
},
@ -2103,12 +2084,10 @@ PlacesSetLoadInSidebarTransaction.prototype = {
/**
* Edit a the description of a bookmark or a folder
*
* XXXmano: aIsFolder is a temporary workaround for bug 372508
*/
function PlacesEditItemDescriptionTransaction(aBookmarkId, aDescription, aIsFolder) {
this.id = aBookmarkId;
function PlacesEditItemDescriptionTransaction(aItemId, aDescription) {
this.id = aItemId;
this._newDescription = aDescription;
this._isFolder = aIsFolder;
this.redoTransaction = this.doTransaction;
}
PlacesEditItemDescriptionTransaction.prototype = {
@ -2120,37 +2099,30 @@ PlacesEditItemDescriptionTransaction.prototype = {
doTransaction: function PSLIST_doTransaction() {
const annos = this.utils.annotations;
if (!("_placeURI" in this)) {
if (this._isFolder)
this._placeURI = this.utils.bookmarks.getFolderURI(this.id);
else
this._placeURI = this.utils.bookmarks.getItemURI(this.id);
}
if (annos.hasAnnotation(this._placeURI, this.DESCRIPTION_ANNO)) {
if (annos.itemHasAnnotation(this.id, this.DESCRIPTION_ANNO)) {
this._oldDescription =
annos.getAnnotationString(this._placeURI, this.DESCRIPTION_ANNO);
annos.getItemAnnotationString(this.id, this.DESCRIPTION_ANNO);
}
if (this._newDescription) {
annos.setAnnotationString(this._placeURI, this.DESCRIPTION_ANNO,
this._newDescription, 0,
this.nsIAnnotationService.EXPIRE_NEVER);
annos.setItemAnnotationString(this.id, this.DESCRIPTION_ANNO,
this._newDescription, 0,
this.nsIAnnotationService.EXPIRE_NEVER);
}
else if (this._oldDescription)
annos.removeAnnotation(this._placeURI, this.DESCRIPTION_ANNO);
annos.removeItemAnnotation(this.id, this.DESCRIPTION_ANNO);
},
undoTransaction: function PSLIST_undoTransaction() {
const annos = this.utils.annotations;
if (this._oldDescription) {
annos.setAnnotationString(this._placeURI, this.DESCRIPTION_ANNO,
this._oldDescription, 0,
this.nsIAnnotationService.EXPIRE_NEVER);
annos.setItemAnnotationString(this.id, this.DESCRIPTION_ANNO,
this._oldDescription, 0,
this.nsIAnnotationService.EXPIRE_NEVER);
}
else if (this.utils.hasAnnotation(this._placeURI, this.DESCRIPTION_ANNO))
annos.removeAnnotation(this._placeURI, this.DESCRIPTION_ANNO);
else if (annos.itemHasAnnotation(this.id, this.DESCRIPTION_ANNO))
annos.removeItemAnnotation(this.id, this.DESCRIPTION_ANNO);
}
};
@ -2260,20 +2232,18 @@ PlacesEditBookmarkMicrosummaryTransaction.prototype = {
getService(Ci.nsIMicrosummaryService),
doTransaction: function PEBMT_doTransaction() {
var placeURI = this.bookmarks.getItemURI(this.id);
this._oldMicrosummary = this.mss.getMicrosummary(placeURI);
this._oldMicrosummary = this.mss.getMicrosummary(this.id);
if (this._newMicrosummary)
this.mss.setMicrosummary(placeURI, this._newMicrosummary);
this.mss.setMicrosummary(this.id, this._newMicrosummary);
else
this.mss.removeMicrosummary(placeURI);
this.mss.removeMicrosummary(this.id);
},
undoTransaction: function PEBMT_undoTransaction() {
var placeURI = this.bookmarks.getItemURI(this.id);
if (this._oldMicrosummary)
this.mss.setMicrosummary(placeURI, this._oldMicrosummary);
this.mss.setMicrosummary(this.id, this._oldMicrosummary);
else
this.mss.removeMicrosummary(placeURI);
this.mss.removeMicrosummary(this.id);
}
};

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

@ -83,7 +83,7 @@ var gMoveBookmarksDialog = {
}
else if (PlacesUtils.nodeIsBookmark(this._nodes[i])) {
transactions.push(new
PlacesMoveItemTransaction(this._nodes[i].bookmarkId,
PlacesMoveItemTransaction(this._nodes[i].itemId,
PlacesUtils._uri(this._nodes[i].uri),
parentId, nodeIndex, selectedFolderID, -1));
}

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

@ -162,20 +162,19 @@
var annotations = PlacesUtils.annotations;
// This try/catch block is a temporary workaround for bug 336194.
var placeURIs;
var bookmarks = [];
try {
placeURIs = annotations.getPagesWithAnnotation("bookmarks/generatedTitle", {});
}
catch(e) {
placeURIs = [];
bookmarks = annotations.getItemsWithAnnotation("bookmarks/generatedTitle", {});
}
catch(e) { }
// XXX It'd be faster to grab the annotations in a single query
// instead of querying separately for each one, but the annotation
// service provides no mechanism for doing so.
for ( var i = 0; i < placeURIs.length; i++)
this.__generatedTitles[placeURIs[i].spec] =
annotations.getAnnotationString(placeURIs[i], "bookmarks/generatedTitle");
for (var i = 0; i < bookmarks.length; i++) {
this.__generatedTitles[bookmarks[i]] =
annotations.getItemAnnotationString(bookmarks[i], "bookmarks/generatedTitle");
}
}
return this.__generatedTitles;
@ -247,9 +246,8 @@
if (PlacesUtils.nodeIsBookmark(child)) {
// If the item has a generated title, use that instead.
var placeURI = PlacesUtils.bookmarks.getItemURI(child.bookmarkId);
if (this._generatedTitles[placeURI.spec])
title = this._generatedTitles[placeURI.spec];
if (this._generatedTitles[child.itemId])
title = this._generatedTitles[child.itemId];
}
} else if (PlacesUtils.nodeIsSeparator(child)) {
button = document.createElementNS(XULNS, "toolbarseparator");
@ -263,11 +261,10 @@
// duplicate nsLivemarkService.getSiteURI to avoid instantiating
// the service on startup.
var containerURI = PlacesUtils.bookmarks.getFolderURI(folder);
var siteURIString;
try {
siteURIString =
this._anno.getAnnotationString(containerURI, "livemark/siteURI");
this._anno.getItemAnnotationString(folder, "livemark/siteURI");
}
catch (ex) {}
// end duplication
@ -776,18 +773,25 @@
// observer object, while "_self" points to the toolbar XBL object.
_self: this,
onAnnotationSet: function TBV_GTAO_onAnnotationSet(uri, annoName) {
NS_ASSERT(annoName == "bookmarks/generatedTitle",
"annotation " + annoName + ", is not 'bookmarks/generatedTitle'");
var newTitle = PlacesUtils.annotations.getAnnotationString(uri, annoName);
this._self._generatedTitles[uri.spec] = newTitle;
onPageAnnotationSet: function() { },
onPageAnnotationRemoved: function() { },
onItemAnnotationSet:
function TBV_GTAO_onItemAnnotationSet(aItemId, aAnnoName) {
NS_ASSERT(aAnnoName == "bookmarks/generatedTitle",
"annotation " + aAnnoName + ", is not 'bookmarks/generatedTitle'");
var newTitle =
PlacesUtils.annotations.getItemAnnotationString(aItemId, aAnnoName);
this._self._generatedTitles[aItemId] = newTitle;
this._doRebuild();
},
onAnnotationRemoved: function TBV_GTAO_onAnnotationRemoved(uri, annoName) {
NS_ASSERT(annoName == "bookmarks/generatedTitle",
"annotation " + annoName + ", is not 'bookmarks/generatedTitle'");
delete this._self._generatedTitles[uri.spec];
onItemAnnotationRemoved:
function TBV_GTAO_onItemAnnotationRemoved(aItemId, aAnnoName) {
NS_ASSERT(aAnnoName == "bookmarks/generatedTitle",
"annotation " + aAnnoName + ", is not 'bookmarks/generatedTitle'");
delete this._self._generatedTitles[aItemId];
this._doRebuild();
},
@ -797,7 +801,6 @@
}
setTimeout(hitch(this._self, this._self._rebuild), 1);
}
})]]></field>
<!-- nsIAnnotationObserver -->
@ -830,7 +833,7 @@
this._observers[annoName] =
this._observers[annoName].filter(function(i) { observer != i });
if (this._observers[annoName].length == 0)
delete this._observers[annoName];
},
@ -846,22 +849,45 @@
return true;
},
onAnnotationSet: function TBV_GAO_onAnnotationSet(uri, annoName) {
onPageAnnotationSet:
function TBV_GAO_onPageAnnotationSet(uri, annoName) {
if (!this._applies(uri, annoName))
return;
for ( var i = 0; i < this._observers[annoName].length; i++)
this._observers[annoName][i].onAnnotationSet(uri, annoName);
for (var i = 0; i < this._observers[annoName].length; i++)
this._observers[annoName][i].onPageAnnotationSet(uri, annoName);
},
onAnnotationRemoved: function TBV_GAO_onAnnotationRemoved(uri, annoName) {
onPageAnnotationRemoved:
function TBV_GAO_onPageAnnotationRemoved(uri, annoName) {
if (!this._applies(uri, annoName))
return;
for ( var i = 0; i < this._observers[annoName].length; i++)
this._observers[annoName][i].onAnnotationRemoved(uri, annoName);
}
this._observers[annoName][i].onPageAnnotationRemoved(uri, annoName);
},
onItemAnnotationSet:
function TBV_GAO_onItemAnnotationSet(aItemId, aAnnoName) {
if (!this._applies(aItemId, aAnnoName))
return;
for (var i = 0; i < this._observers[aAnnoName].length; i++) {
this._observers[aAnnoName][i]
.onItemAnnotationSet(aItemId, aAnnoName);
}
},
onItemAnnotationRemoved:
function TBV_GAO_onItemAnnotationRemoved(aItemId, aAnnoName) {
if (!this._applies(aItemId, aAnnoName))
return;
for (var i = 0; i < this._observers[aAnnoName].length; i++) {
this._observers[aAnnoName][i]
.onItemAnnotationRemoved(aItemId, aAnnoName);
}
}
})]]></field>
<method name="checkForMenuEvent">

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

@ -218,7 +218,8 @@ var PlacesUtils = {
*/
nodeIsBookmark: function PU_nodeIsBookmark(aNode) {
NS_ASSERT(aNode, "null node");
return aNode.bookmarkId > 0;
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_URI &&
aNode.itemId != -1;
},
/**
@ -369,8 +370,8 @@ var PlacesUtils = {
*/
nodeIsLivemarkItem: function PU_nodeIsLivemarkItem(aNode) {
if (this.nodeIsBookmark(aNode)) {
var placeURI = this.bookmarks.getItemURI(aNode.bookmarkId);
if (this.annotations.hasAnnotation(placeURI, "livemark/bookmarkFeedURI"))
if (this.annotations
.itemHasAnnotation(aNode.itemId, "livemark/bookmarkFeedURI"))
return true;
}
@ -430,15 +431,15 @@ var PlacesUtils = {
case this.TYPE_X_MOZ_PLACE:
case this.TYPE_X_MOZ_PLACE_SEPARATOR:
// Data is encoded like this:
// bookmarks folder: <folderId>\n<>\n<parentId>\n<indexInParent>
// bookmarks folder: <itemId>\n<>\n<parentId>\n<indexInParent>
// uri: 0\n<uri>\n<parentId>\n<indexInParent>
// bookmark: <bookmarkId>\n<uri>\n<parentId>\n<indexInParent>
// bookmark: <itemId>\n<uri>\n<parentId>\n<indexInParent>
// separator: 0\n<>\n<parentId>\n<indexInParent>
var wrapped = "";
if (this.nodeIsFolder(aNode))
wrapped += asFolder(aNode).folderId + NEWLINE;
else if (this.nodeIsBookmark(aNode))
wrapped += aNode.bookmarkId + NEWLINE;
wrapped += aNode.itemId + NEWLINE;
else
wrapped += "0" + NEWLINE;
@ -538,6 +539,7 @@ var PlacesUtils = {
if (self.nodeIsFolder(node)) {
var nodeFolderId = asFolder(node).folderId;
var title = self.bookmarks.getFolderTitle(nodeFolderId);
// XXXmano: use item-annotations once bug 372508 is fixed
var annos = self.getAnnotationsForURI(self._uri(node.uri));
var folderItemsTransactions =
getChildItemsTransactions(nodeFolderId);
@ -545,7 +547,7 @@ var PlacesUtils = {
folderItemsTransactions);
}
else if (self.nodeIsBookmark(node)) {
txn = self._getBookmarkItemCopyTransaction(node.bookmarkId, -1,
txn = self._getBookmarkItemCopyTransaction(node.itemId, -1,
aIndex);
}
else if (self.nodeIsURI(node) || self.nodeIsQuery(node)) {
@ -564,8 +566,7 @@ var PlacesUtils = {
}
var title = this.bookmarks.getFolderTitle(aData.id);
var annos =
this.getAnnotationsForURI(this.bookmarks.getFolderURI(aData.id));
var annos = this.getAnnotationsForItem(aData.id);
var createTxn =
new PlacesCreateFolderTransaction(title, aContainer, aIndex, annos,
getChildItemsTransactions(aData.id));
@ -1112,23 +1113,69 @@ var PlacesUtils = {
var annoNames = annosvc.getPageAnnotationNames(aURI, {});
for (var i = 0; i < annoNames.length; i++) {
var flags = {}, exp = {}, mimeType = {}, storageType = {};
annosvc.getAnnotationInfo(aURI, annoNames[i], flags, exp, mimeType, storageType);
annosvc.getPageAnnotationInfo(aURI, annoNames[i], flags, exp, mimeType, storageType);
switch (storageType.value) {
case annosvc.TYPE_INT32:
val = annosvc.getAnnotationInt32(aURI, annoNames[i]);
val = annosvc.getPageAnnotationInt32(aURI, annoNames[i]);
break;
case annosvc.TYPE_INT64:
val = annosvc.getAnnotationInt64(aURI, annoNames[i]);
val = annosvc.getPageAnnotationInt64(aURI, annoNames[i]);
break;
case annosvc.TYPE_DOUBLE:
val = annosvc.getAnnotationDouble(aURI, annoNames[i]);
val = annosvc.getPageAnnotationDouble(aURI, annoNames[i]);
break;
case annosvc.TYPE_STRING:
val = annosvc.getAnnotationString(aURI, annoNames[i]);
val = annosvc.getPageAnnotationString(aURI, annoNames[i]);
break;
case annosvc.TYPE_BINARY:
var data = {}, length = {}, mimeType = {};
annosvc.getAnnotationBinary(aURI, annoNames[i], data, length, mimeType);
annosvc.getPageAnnotationBinary(aURI, annoNames[i], data, length, mimeType);
val = data.value;
break;
}
annos.push({name: annoNames[i],
flags: flags.value,
expires: exp.value,
mimeType: mimeType.value,
type: storageType.value,
value: val});
}
return annos;
},
/**
* Fetch all annotations for a URI, including all properties of each
* annotation which would be required to recreate it.
* @param aItemId
* The identifier of the itme for which annotations are to be
* retrieved.
* @return Array of objects, each containing the following properties:
* name, flags, expires, mimeType, type, value
*/
getAnnotationsForItem: function PU_getAnnotationsForItem(aItemId) {
var annosvc = this.annotations;
var annos = [], val = null;
var annoNames = annosvc.getItemAnnotationNames(aItemId, {});
for (var i = 0; i < annoNames.length; i++) {
var flags = {}, exp = {}, mimeType = {}, storageType = {};
annosvc.getItemAnnotationInfo(aItemId, annoNames[i], flags, exp,
mimeType, storageType);
switch (storageType.value) {
case annosvc.TYPE_INT32:
val = annosvc.getItemAnnotationInt32(aItemId, annoNames[i]);
break;
case annosvc.TYPE_INT64:
val = annosvc.getItemAnnotationInt64(aItemId, annoNames[i]);
break;
case annosvc.TYPE_DOUBLE:
val = annosvc.getItemAnnotationDouble(aItemId, annoNames[i]);
break;
case annosvc.TYPE_STRING:
val = annosvc.getItemAnnotationString(aItemId, annoNames[i]);
break;
case annosvc.TYPE_BINARY:
var data = {}, length = {}, mimeType = {};
annosvc.getItemAnnotationBinary(aItemId, annoNames[i], data, length, mimeType);
val = data.value;
break;
}
@ -1145,7 +1192,7 @@ var PlacesUtils = {
/**
* Annotate a URI with a batch of annotations.
* @param aURI
* The URI for which annotations are to be retrieved.
* The URI for which annotations are to be set.
* @param aAnnotations
* Array of objects, each containing the following properties:
* name, flags, expires, type, mimeType (only used for binary
@ -1156,25 +1203,63 @@ var PlacesUtils = {
aAnnos.forEach(function(anno) {
switch (anno.type) {
case annosvc.TYPE_INT32:
annosvc.setAnnotationInt32(aURI, anno.name, anno.value,
anno.flags, anno.expires);
annosvc.setPageAnnotationInt32(aURI, anno.name, anno.value,
anno.flags, anno.expires);
break;
case annosvc.TYPE_INT64:
annosvc.setAnnotationInt64(aURI, anno.name, anno.value,
anno.flags, anno.expires);
annosvc.setPageAnnotationInt64(aURI, anno.name, anno.value,
anno.flags, anno.expires);
break;
case annosvc.TYPE_DOUBLE:
annosvc.setAnnotationDouble(aURI, anno.name, anno.value,
anno.flags, anno.expires);
annosvc.setPageAnnotationDouble(aURI, anno.name, anno.value,
anno.flags, anno.expires);
break;
case annosvc.TYPE_STRING:
annosvc.setAnnotationString(aURI, anno.name, anno.value,
anno.flags, anno.expires);
annosvc.setPageAnnotationString(aURI, anno.name, anno.value,
anno.flags, anno.expires);
break;
case annosvc.TYPE_BINARY:
annosvc.setAnnotationBinary(aURI, anno.name, anno.value,
anno.value.length, anno.mimeType,
anno.flags, anno.expires);
annosvc.setPageAnnotationBinary(aURI, anno.name, anno.value,
anno.value.length, anno.mimeType,
anno.flags, anno.expires);
break;
}
});
},
/**
* Annotate a URI with a batch of annotations.
* @param aItemId
* The identifier of the item for which annotations are to be set
* @param aAnnotations
* Array of objects, each containing the following properties:
* name, flags, expires, type, mimeType (only used for binary
* annotations) value.
*/
setAnnotationsForItem: function PU_setAnnotationsForItem(aItemId, aAnnos) {
var annosvc = this.annotations;
aAnnos.forEach(function(anno) {
switch (anno.type) {
case annosvc.TYPE_INT32:
annosvc.setItemAnnotationInt32(aItemId, anno.name, anno.value,
anno.flags, anno.expires);
break;
case annosvc.TYPE_INT64:
annosvc.setItemAnnotationInt64(aItemId, anno.name, anno.value,
anno.flags, anno.expires);
break;
case annosvc.TYPE_DOUBLE:
annosvc.setItemAnnotationDouble(aItemId, anno.name, anno.value,
anno.flags, anno.expires);
break;
case annosvc.TYPE_STRING:
annosvc.setItemAnnotationString(aItemId, anno.name, anno.value,
anno.flags, anno.expires);
break;
case annosvc.TYPE_BINARY:
annosvc.setItemAnnotationBinary(aItemId, anno.name, anno.value,
anno.value.length, anno.mimeType,
anno.flags, anno.expires);
break;
}
});

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

@ -824,16 +824,9 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node)
if (webPanel.LowerCaseEqualsLiteral("true")) {
// set load-in-sidebar annotation for the bookmark
nsCOMPtr<nsIURI> placeURI;
rv = mBookmarksService->GetItemURI(frame.mPreviousId,
getter_AddRefs(placeURI));
NS_ASSERTION(NS_SUCCEEDED(rv),
"failed to get a place: uri for a new bookmark");
if (NS_SUCCEEDED(rv)) {
mAnnotationService->SetAnnotationInt32(placeURI, LOAD_IN_SIDEBAR_ANNO,
1, 0,
nsIAnnotationService::EXPIRE_NEVER);
}
mAnnotationService->SetItemAnnotationInt32(frame.mPreviousId, LOAD_IN_SIDEBAR_ANNO,
1, 0,
nsIAnnotationService::EXPIRE_NEVER);
}
// FIXME bug 334408: save the last charset
}
@ -1515,16 +1508,16 @@ nsPlacesImportExportService::WriteItem(nsINavHistoryResultNode* aItem,
rv = WriteFaviconAttribute(uri, aOutput);
NS_ENSURE_SUCCESS(rv, rv);
// get bookmark id
PRInt64 bookmarkId;
rv = aItem->GetBookmarkId(&bookmarkId);
// get item id
PRInt64 itemId;
rv = aItem->GetItemId(&itemId);
NS_ENSURE_SUCCESS(rv, rv);
// write id
rv = aOutput->Write(kIdAttribute, sizeof(kIdAttribute)-1, &dummy);
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString id;
id.AppendInt(bookmarkId);
id.AppendInt(itemId);
rv = aOutput->Write(id.get(), id.Length(), &dummy);
NS_ENSURE_SUCCESS(rv, rv);
rv = aOutput->Write(kQuoteStr, sizeof(kQuoteStr)-1, &dummy);
@ -1532,7 +1525,7 @@ nsPlacesImportExportService::WriteItem(nsINavHistoryResultNode* aItem,
// keyword (shortcuturl)
nsAutoString keyword;
rv = mBookmarksService->GetKeywordForBookmark(bookmarkId, keyword);
rv = mBookmarksService->GetKeywordForBookmark(itemId, keyword);
NS_ENSURE_SUCCESS(rv, rv);
if (!keyword.IsEmpty()) {
rv = aOutput->Write(kKeywordAttribute, sizeof(kKeywordAttribute)-1, &dummy);
@ -1545,15 +1538,11 @@ nsPlacesImportExportService::WriteItem(nsINavHistoryResultNode* aItem,
NS_ENSURE_SUCCESS(rv, rv);
}
// get bookmark place URI for annotations
nsCOMPtr<nsIURI> placeURI;
rv = mBookmarksService->GetItemURI(bookmarkId, getter_AddRefs(placeURI));
NS_ENSURE_SUCCESS(rv, rv);
// Write WEB_PANEL="true" if the load-in-sidebar annotation is set for the
// item
PRBool loadInSidebar = PR_FALSE;
rv = mAnnotationService->HasAnnotation(placeURI, LOAD_IN_SIDEBAR_ANNO, &loadInSidebar);
rv = mAnnotationService->ItemHasAnnotation(itemId, LOAD_IN_SIDEBAR_ANNO,
&loadInSidebar);
NS_ENSURE_SUCCESS(rv, rv);
if (loadInSidebar)
aOutput->Write(kWebPanelAttribute, sizeof(kWebPanelAttribute)-1, &dummy);

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

@ -142,7 +142,7 @@ function testCanonicalBookmarks(aFolder) {
// title
do_check_eq("test post keyword", testBookmark1.title);
// keyword
do_check_eq("test", bmsvc.getKeywordForBookmark(testBookmark1.bookmarkId));
do_check_eq("test", bmsvc.getKeywordForBookmark(testBookmark1.itemId));
// sidebar
// add date
// last modified

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

@ -38,34 +38,29 @@
#include "nsISupports.idl"
%{C++
#include "nsTArray.h"
#include "nsCOMArray.h"
%}
interface nsIURI;
interface nsIVariant;
[ptr] native URIArray(nsCOMArray<nsIURI>);
[scriptable, uuid(d41c9510-2377-4728-b275-bdad6a0521f8)]
[scriptable, uuid(63fe98e0-6889-4c2c-ac9f-703e4bc25027)]
interface nsIAnnotationObserver : nsISupports
{
/**
* Called when an annotation value is set. It could be a new annotation,
* or it could be a new value for an existing annotation.
*/
void onAnnotationSet(in nsIURI aURI, in AUTF8String aName);
void onPageAnnotationSet(in nsIURI aPage, in AUTF8String aName);
void onItemAnnotationSet(in long long aItemId, in AUTF8String aName);
/**
* Called when an annotation is deleted. If aName is empty, then ALL
* annotations for the given URI have been deleted. This is not called when
* annotations are expired (normally happens when the app exits).
*/
void onAnnotationRemoved(in nsIURI aURI, in AUTF8String aName);
void onPageAnnotationRemoved(in nsIURI aURI, in AUTF8String aName);
void onItemAnnotationRemoved(in long long aItemId, in AUTF8String aName);
};
[scriptable, uuid(15999472-f158-11db-8314-0800200c9a66)]
[scriptable, uuid(1e2f77a8-7923-4c3d-9100-965687740acd)]
interface nsIAnnotationService : nsISupports
{
/**
@ -80,31 +75,31 @@ interface nsIAnnotationService : nsISupports
expiration policy. May be changed. Currently, use 0 for expiration.
*/
// For temporary stuff that can be discarded when the user exists
const PRInt32 EXPIRE_SESSION = 0;
const unsigned short EXPIRE_SESSION = 0;
// for short-lived temporary data that you still want to outlast a session
const PRInt32 EXPIRE_DAYS = 1;
const unsigned short EXPIRE_DAYS = 1;
// for general page settings, things the user is interested in seeing
// if they come back to this page some time in the future.
const PRInt32 EXPIRE_WEEKS = 2;
const unsigned short EXPIRE_WEEKS = 2;
// Something that the user will be interested in seeing in their
// history like favicons. If they haven't visited a page in a couple
// of months, they probably aren't interested in much other annotation,
// the positions of things, or other stuff you create, so put that in
// the weeks policy.
const PRInt32 EXPIRE_MONTHS = 3;
const unsigned short EXPIRE_MONTHS = 3;
// For small, user-entered data like notes that should never expire.
const PRInt32 EXPIRE_NEVER = 4;
const unsigned short EXPIRE_NEVER = 4;
// type constants
const PRInt32 TYPE_INT32 = 1;
const PRInt32 TYPE_DOUBLE = 2;
const PRInt32 TYPE_STRING = 3;
const PRInt32 TYPE_BINARY = 4;
const PRInt32 TYPE_INT64 = 5;
const unsigned short TYPE_INT32 = 1;
const unsigned short TYPE_DOUBLE = 2;
const unsigned short TYPE_STRING = 3;
const unsigned short TYPE_BINARY = 4;
const unsigned short TYPE_INT64 = 5;
/**
* Sets an annotation, overwriting any previous annotation with the same
@ -133,42 +128,61 @@ interface nsIAnnotationService : nsISupports
* service, but are special cased in the protocol handler so they look like
* annotations. Do not set favicons using this service, it will not work.
*/
void setAnnotationString(in nsIURI aURI, in AUTF8String aName,
in AString aValue, in PRInt32 aFlags,
in PRInt32 aExpiration);
void setPageAnnotationString(in nsIURI aURI, in AUTF8String aName,
in AString aValue, in long aFlags,
in unsigned short aExpiration);
void setItemAnnotationString(in long long aItemId, in AUTF8String aName,
in AString aValue, in long aFlags,
in unsigned short aExpiration);
/**
* Sets an annotation just like setAnnotationString, but takes an Int32 as
* input.
*/
void setAnnotationInt32(in nsIURI aURI, in AUTF8String aName,
in PRInt32 aValue, in PRInt32 aFlags,
in PRInt32 aExpiration);
void setPageAnnotationInt32(in nsIURI aURI, in AUTF8String aName,
in long aValue, in long aFlags,
in unsigned short aExpiration);
void setItemAnnotationInt32(in long long aItemId, in AUTF8String aName,
in long aValue, in long aFlags,
in unsigned short aExpiration);
/**
* Sets an annotation just like setAnnotationString, but takes an Int64 as
* input.
*/
void setAnnotationInt64(in nsIURI aURI, in AUTF8String aName,
in PRInt64 aValue, in PRInt32 aFlags,
in PRInt32 aExpiration);
void setPageAnnotationInt64(in nsIURI aURI, in AUTF8String aName,
in long long aValue, in long aFlags,
in unsigned short aExpiration);
void setItemAnnotationInt64(in long long aItemId, in AUTF8String aName,
in long long aValue, in long aFlags,
in unsigned short aExpiration);
/**
* Sets an annotation just like setAnnotationString, but takes a double as
* input.
*/
void setAnnotationDouble(in nsIURI aURI, in AUTF8String aName,
in double aValue, in PRInt32 aFlags,
in PRInt32 aExpiration);
void setPageAnnotationDouble(in nsIURI aURI, in AUTF8String aName,
in double aValue, in long aFlags,
in unsigned short aExpiration);
void setItemAnnotationDouble(in long long aItemId, in AUTF8String aName,
in double aValue, in long aFlags,
in unsigned short aExpiration);
/*
* Sets an annotation just like setAnnotationString, but takes binary data
* as input. You MUST supply a valid MIME type.
*/
void setAnnotationBinary(in nsIURI aURI, in AUTF8String aName,
[const,array,size_is(aDataLen)] in octet aData,
in PRUint32 aDataLen, in AUTF8String aMimeType,
in PRInt32 aFlags, in PRInt32 aExpiration);
void setPageAnnotationBinary(in nsIURI aURI, in AUTF8String aName,
[const,array,size_is(aDataLen)] in octet aData,
in unsigned long aDataLen,
in AUTF8String aMimeType,
in long aFlags,
in unsigned short aExpiration);
void setItemAnnotationBinary(in long long aItemId, in AUTF8String aName,
[const,array,size_is(aDataLen)] in octet aData,
in unsigned long aDataLen,
in AUTF8String aMimeType,
in long aFlags,
in unsigned short aExpiration);
/**
* Retrieves the string value of a given annotation. Throws an error if the
@ -178,7 +192,8 @@ interface nsIAnnotationService : nsISupports
* and errors will not be thrown in this case. (For example, doubles will
* lose precision when stringified.)
*/
AString getAnnotationString(in nsIURI aURI, in AUTF8String aName);
AString getPageAnnotationString(in nsIURI aURI, in AUTF8String aName);
AString getItemAnnotationString(in long long aItemId, in AUTF8String aName);
/**
* Same as getAnnotationString but for ints. If the value doesn't look like
@ -186,7 +201,8 @@ interface nsIAnnotationService : nsISupports
* int when there is not one, it will possibly change in the future if we
* start caching stuff).
*/
PRInt32 getAnnotationInt32(in nsIURI aURI, in AUTF8String aName);
long getPageAnnotationInt32(in nsIURI aURI, in AUTF8String aName);
long getItemAnnotationInt32(in long long aItemId, in AUTF8String aName);
/**
* Same as getAnnotationString for Int64s. If the value doesn't look like
@ -194,7 +210,8 @@ interface nsIAnnotationService : nsISupports
* int when there is not one, it will possibly change in the future if we
* start caching stuff).
*/
PRInt64 getAnnotationInt64(in nsIURI aURI, in AUTF8String aName);
long long getPageAnnotationInt64(in nsIURI aURI, in AUTF8String aName);
long long getItemAnnotationInt64(in long long aItemId, in AUTF8String aName);
/**
* Same as getAnnotationString but returns a double-precision float. If the
@ -202,16 +219,21 @@ interface nsIAnnotationService : nsISupports
* behavior when asking for an number when there is not one, it will
* possibly change in the future if we start caching stuff).
*/
double getAnnotationDouble(in nsIURI aURI, in AUTF8String aName);
double getPageAnnotationDouble(in nsIURI aURI, in AUTF8String aName);
double getItemAnnotationDouble(in long long aItemId, in AUTF8String aName);
/**
* Same as getAnnotationString but for binary data. This also returns the
* MIME type.
*/
void getAnnotationBinary(in nsIURI aURI, in AUTF8String aName,
void getPageAnnotationBinary(in nsIURI aURI, in AUTF8String aName,
[array,size_is(aDataLen)] out octet aData,
out PRUint32 aDataLen,
out unsigned long aDataLen,
out AUTF8String aMimeType);
void getItemAnnotationBinary(in long long aItemId, in AUTF8String aName,
[array,size_is(aDataLen)] out octet aData,
out unsigned long aDataLen,
out AUTF8String aMimeType);
/**
* Retrieves info about an existing annotation. aMimeType will be empty
@ -224,9 +246,14 @@ interface nsIAnnotationService : nsISupports
* annotator.getAnnotationInfo(myURI, "foo", flags, exp, mimeType);
* // now you can use 'exp.value' and 'flags.value'
*/
void getAnnotationInfo(in nsIURI aURI, in AUTF8String aName,
out PRInt32 aFlags, out PRInt32 aExpiration,
out AUTF8String aMimeType, out PRInt32 aType);
void getPageAnnotationInfo(in nsIURI aURI, in AUTF8String aName,
out PRInt32 aFlags, out unsigned short aExpiration,
out AUTF8String aMimeType,
out unsigned short aType);
void getItemAnnotationInfo(in long long aItemId, in AUTF8String aName,
out long aFlags, out unsigned short aExpiration,
out AUTF8String aMimeType,
out unsigned short aType);
/**
* Retrieves the type of an existing annotation
@ -239,62 +266,65 @@ interface nsIAnnotationService : nsISupports
* @return one of the TYPE_* constants above
* @throws if the annotation is not set
*/
PRInt32 getAnnotationType(in nsIURI aURI, in AUTF8String aName);
PRUint16 getPageAnnotationType(in nsIURI aURI, in AUTF8String aName);
PRUint16 getItemAnnotationType(in long long aItemId, in AUTF8String aName);
/**
* Returns a list of all URIs having a given annotation.
*/
void getPagesWithAnnotation(in AUTF8String name,
out PRUint32 resultCount,
out unsigned long resultCount,
[retval, array, size_is(resultCount)] out nsIURI results);
/**
* COMArray version of getPagesWithAnnotation for easier memory
* management from C++ code;
*/
[noscript] void GetPagesWithAnnotationCOMArray(in AUTF8String aName,
in URIArray aResults);
void getItemsWithAnnotation(in AUTF8String name,
out unsigned long resultCount,
[retval, array, size_is(resultCount)] out long long results);
/**
* Get the names of all annotations for this URI.
*
* example JS:
* var annotations = annotator.getPageAnnotations(myURI, {});
* You probably don't want to use this from C++, use
* GetPageAnnotationsTArray instead.
*/
void getPageAnnotationNames(in nsIURI aURI, out PRUint32 count,
void getPageAnnotationNames(in nsIURI aURI, out unsigned long count,
[retval, array, size_is(count)] out nsIVariant result);
void getItemAnnotationNames(in long long aItemId, out unsigned long count,
[retval, array, size_is(count)] out nsIVariant result);
/**
* Test for annotation existance.
*/
boolean hasAnnotation(in nsIURI aURI, in AUTF8String aName);
boolean pageHasAnnotation(in nsIURI aURI, in AUTF8String aName);
boolean itemHasAnnotation(in long long aItemId, in AUTF8String aName);
/**
* Removes a specific annotation. Succeeds even if the annotation is
* not found.
*/
void removeAnnotation(in nsIURI aURI, in AUTF8String aName);
void removePageAnnotation(in nsIURI aURI, in AUTF8String aName);
void removeItemAnnotation(in long long aItemId, in AUTF8String aName);
/**
* Removes all annotations for the given page.
* Removes all annotations for the given page/item.
* We may want some other similar functions to get annotations with given
* flags (once we have flags defined).
*/
void removePageAnnotations(in nsIURI aURI);
void removeItemAnnotations(in long long aItemId);
/**
* Copies all annotations from the source to the destination URI. If the
* destination already has an annotation with the same name as one on the
* source, it will be overwritten if aOverwriteDest is set. Otherwise,
* Copies all annotations from the source to the destination URI/item. If
* the destination already has an annotation with the same name as one on
* the source, it will be overwritten if aOverwriteDest is set. Otherwise,
* the destination URIs will be preferred.
*
* All the source annotations will stay as-is. If you don't want them
* any more, use removePageAnnotations on that URI.
*/
void copyAnnotations(in nsIURI aSourceURI, in nsIURI aDestURI,
in boolean aOverwriteDest);
void copyPageAnnotations(in nsIURI aSourceURI, in nsIURI aDestURI,
in boolean aOverwriteDest);
void copyItemAnnotations(in long long aSourceItemId,
in long long aDestItemId,
in boolean aOverwriteDest);
/**
* Adds an annotation observer. The annotation service will keep an owning

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

@ -54,7 +54,7 @@ interface nsITransaction;
* Observer for bookmark changes.
*/
[scriptable, uuid(860d786d-9bba-4011-a396-486a87af8f07)]
[scriptable, uuid(582af67b-cde2-4dc2-9ef5-9eb79e224135)]
interface nsINavBookmarkObserver : nsISupports
{
/**
@ -75,42 +75,52 @@ interface nsINavBookmarkObserver : nsISupports
* add took place. The rest of the bookmarks will be shifted down, but no
* additional notifications will be sent.
*
* @param bookmarkId The id of the bookmark that was added.
* @param bookmark The URI that was bookmarked.
* @param folder The folder that the item was added to.
* @param index The item's index in the folder.
* @param aBookmarkId
* The id of the bookmark that was added.
* @param aFolder
* The folder that the item was added to.
* @param aIndex
* The item's index in the folder.
*/
void onItemAdded(in PRInt64 bookmarkId, in nsIURI bookmark, in PRInt64 folder, in PRInt32 index);
void onItemAdded(in long long aBookmarkId, in long long aFolder,
in long aIndex);
/**
* Notify this observer that the bookmark was removed. Called after the
* actual remove took place. The bookmarks following the index will be
* shifted up, but no additional notifications will be sent.
*
* @param bookmarkId The id of the bookmark that was removed.
* @param bookmark The URI of the bookmark that will be removed.
* @param folder The folder that the item was removed from.
* @param index The bookmark's index in the folder.
* @param aBookmarkId
* The id of the bookmark that was removed.
* @param aFolder
* The folder that the item was removed from.
* @param aIndex
* The bookmark's index in the folder.
*/
void onItemRemoved(in PRInt64 bookmarkId, in nsIURI bookmark, in PRInt64 folder, in PRInt32 index);
void onItemRemoved(in long long aBookmarkId, in long long aFolder,
in long aIndex);
/**
* Notify this observer that a bookmark's information has changed. This
* will be called whenever any attributes like "title" are changed.
*
* @param bookmarkId The id of the bookmark that was changed.
* @param bookmark The URI of the bookmark which changed.
* @param property The property which changed.
* @param aBookmarkId
* The id of the bookmark that was changed.
* @param aProperty
* The property which changed.
* @param aIsAnnotationProperty
* Is aProperty the name of an item annotation
*
* property = "cleartime": (history was deleted, there is no last visit date):
* value = none
* property = "title": value = new title
* property = "favicon": value = new "moz-anno" URL of favicon image
* property = "uri": value = empty, get the value of the changed bookmark URI
* from the |bookmark| parameter.
* property = "uri": value = new uri spec
* aIsAnnotationProperty = true: value = empty string
*/
void onItemChanged(in PRInt64 bookmarkId, in nsIURI bookmark, in ACString property,
in AString value);
void onItemChanged(in long long aBookmarkId, in ACString aProperty,
in boolean aIsAnnotationProperty,
in AUTF8String aValue);
/**
* Notify that the item was visited. Normally in bookmarks we use the last
@ -118,61 +128,82 @@ interface nsINavBookmarkObserver : nsISupports
* recent, but this is not guaranteed. You should check to see if it's
* actually more recent before using this new time.
*
* @param bookmarkId The id of the bookmark that was visited.
* @see onItemChanged properth = "cleartime" for when all visit dates are
* @param aBookmarkId
* The id of the bookmark that was visited.
* @see onItemChanged property = "cleartime" for when all visit dates are
* deleted for the URI.
*/
void onItemVisited(in PRInt64 bookmarkId, in nsIURI bookmark, in PRInt64 aVisitID, in PRTime time);
void onItemVisited(in long long aBookmarkId, in long long aVisitID,
in PRTime time);
/**
* Notify this observer that a bookmark folder has been added.
* @param folder The id of the folder that was added.
* @param parent The id of the folder's parent.
* @param index The folder's index inside its parent.
* @param aFolder
* The id of the folder that was added.
* @param aParent
* The id of the folder's parent.
* @param aIndex
* The folder's index inside its parent.
*/
void onFolderAdded(in PRInt64 folder, in PRInt64 parent, in PRInt32 index);
void onFolderAdded(in long long aFolder, in long long aParent,
in long aIndex);
/**
* Notify this observer that a bookmark folder has been removed.
* @param folder The id of the folder that was removed.
* @param parent The id of the folder's old parent.
* @param index The folder's old index in its parent.
* @param aFolder
* The id of the folder that was removed.
* @param aParent
* The id of the folder's old parent.
* @param aIndex
* The folder's old index in its parent.
*/
void onFolderRemoved(in PRInt64 folder, in PRInt64 parent, in PRInt32 index);
void onFolderRemoved(in long long aFolder, in long long aParent,
in long aIndex);
/**
* Notify this observer that a bookmark folder has been moved.
* @param folder The id of the folder that was moved.
* @param oldParent The id of the folder's old parent.
* @param oldIndex The folder's old index inside oldParent.
* @param newParent The id of the folder's new parent.
* @param newIndex The folder's index inside newParent.
* @param aFolder
* The id of the folder that was moved.
* @param aOldParent
* The id of the folder's old parent.
* @param aOldIndex
* The folder's old index inside oldParent.
* @param aNewParent
* The id of the folder's new parent.
* @param aNewIndex
* The folder's index inside newParent.
*/
void onFolderMoved(in PRInt64 folder,
in PRInt64 oldParent, in PRInt32 oldIndex,
in PRInt64 newParent, in PRInt32 newIndex);
void onFolderMoved(in long long aFolder,
in long long aOldParent, in long aOldIndex,
in long long aNewParent, in long aNewIndex);
/**
* Notify this observer that a bookmark folder's information has changed.
* This will be called whenever any attributes like "title" are changed.
* @param folder The id of the folder that was changed.
* @param property The property that was changed.
* @param aFolder
* The id of the folder that was changed.
* @param aProperty
* The property that was changed.
*/
void onFolderChanged(in PRInt64 folder, in ACString property);
void onFolderChanged(in long long aFolder, in ACString aProperty);
/**
* Notify this observer that a separator has been added.
* @param parent The id of the separator's parent.
* @param index The separator's index inside its parent.
* @param aParent
* The id of the separator's parent.
* @param aIndex
* The separator's index inside its parent.
*/
void onSeparatorAdded(in PRInt64 parent, in PRInt32 index);
void onSeparatorAdded(in long long aParent, in long aIndex);
/**
* Notify this observer that a separator has been removed.
* @param parent The id of the separator's parent.
* @param index The separator's old index in its parent.
* @param aParent
* The id of the separator's parent.
* @param aIndex
* The separator's old index in its parent.
*/
void onSeparatorRemoved(in PRInt64 parent, in PRInt32 index);
void onSeparatorRemoved(in long long aParent, in long aIndex);
};
/**

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

@ -50,7 +50,7 @@ interface nsINavHistoryResult;
interface nsITreeColumn;
interface nsIWritablePropertyBag;
[scriptable, uuid(b21008ef-995d-4bd9-97ae-1f23868930ed)]
[scriptable, uuid(2cce631e-d7dd-4162-a05b-e8ecfbc34367)]
interface nsINavHistoryResultNode : nsISupports
{
/**
@ -159,10 +159,11 @@ interface nsINavHistoryResultNode : nsISupports
readonly attribute PRInt32 bookmarkIndex;
/**
* If the node is a bookmark, this value is the row ID of that bookmark
* in the database. For items not in a bookmark folder, this value is -1.
* If the node is an item (bookmark, folder or a separator) this value is the
* row ID of that bookmark in the database. For other nodes, this value is
* set to -1.
*/
readonly attribute PRInt64 bookmarkId;
readonly attribute PRInt64 itemId;
};

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

@ -157,8 +157,8 @@ nsAnnoProtocolHandler::NewChannel(nsIURI *aURI, nsIChannel **_retval)
}
} else {
// normal handling for annotations
rv = annotationService->GetAnnotationBinary(annoURI, annoName, &data,
&dataLen, mimeType);
rv = annotationService->GetPageAnnotationBinary(annoURI, annoName, &data,
&dataLen, mimeType);
NS_ENSURE_SUCCESS(rv, rv);
// disallow annotations with no MIME types

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -40,6 +40,7 @@
#define nsAnnotationService_h___
#include "nsIAnnotationService.h"
#include "nsTArray.h"
#include "nsCOMArray.h"
#include "nsCOMPtr.h"
#include "mozIStorageService.h"
@ -88,20 +89,26 @@ protected:
nsCOMPtr<mozIStorageConnection> mDBConn;
nsCOMPtr<mozIStorageStatement> mDBSetAnnotation;
nsCOMPtr<mozIStorageStatement> mDBSetItemAnnotation;
nsCOMPtr<mozIStorageStatement> mDBGetAnnotation;
nsCOMPtr<mozIStorageStatement> mDBGetItemAnnotation;
nsCOMPtr<mozIStorageStatement> mDBGetAnnotationNames;
nsCOMPtr<mozIStorageStatement> mDBGetItemAnnotationNames;
nsCOMPtr<mozIStorageStatement> mDBGetAnnotationFromURI;
nsCOMPtr<mozIStorageStatement> mDBGetAnnotationFromItemId;
nsCOMPtr<mozIStorageStatement> mDBGetAnnotationNameID;
nsCOMPtr<mozIStorageStatement> mDBAddAnnotationName;
nsCOMPtr<mozIStorageStatement> mDBAddAnnotation;
nsCOMPtr<mozIStorageStatement> mDBAddItemAnnotation;
nsCOMPtr<mozIStorageStatement> mDBRemoveAnnotation;
nsCOMPtr<mozIStorageStatement> mDBRemoveItemAnnotation;
nsCOMArray<nsIAnnotationObserver> mObservers;
static nsAnnotationService* gAnnotationService;
static const int kAnnoIndex_ID;
static const int kAnnoIndex_Page;
static const int kAnnoIndex_PageOrItem;
static const int kAnnoIndex_Name;
static const int kAnnoIndex_MimeType;
static const int kAnnoIndex_Content;
@ -109,18 +116,67 @@ protected:
static const int kAnnoIndex_Expiration;
static const int kAnnoIndex_Type;
nsresult HasAnnotationInternal(PRInt64 aURLID, const nsACString& aName,
PRBool* hasAnnotation, PRInt64* annotationID);
nsresult HasAnnotationInternal(PRInt64 aFkId, PRBool aIsBookmarkId,
const nsACString& aName, PRBool* hasAnnotation,
PRInt64* annotationID);
nsresult StartGetAnnotationFromURI(nsIURI* aURI,
const nsACString& aName);
nsresult StartSetAnnotation(nsIURI* aURI,
nsresult StartGetAnnotationFromItemId(PRInt64 aItemId,
const nsACString& aName);
nsresult StartSetAnnotation(PRInt64 aFkId,
PRBool aIsItemAnnotation,
const nsACString& aName,
PRInt32 aFlags, PRInt32 aExpiration,
PRInt32 aType, mozIStorageStatement** aStatement);
void CallSetObservers(nsIURI* aURI, const nsACString& aName);
PRInt32 aFlags,
PRUint16 aExpiration,
PRUint16 aType,
mozIStorageStatement** aStatement);
nsresult SetAnnotationStringInternal(PRInt64 aItemId,
PRBool aIsItemAnnotation,
const nsACString& aName,
const nsAString& aValue,
PRInt32 aFlags,
PRUint16 aExpiration);
nsresult SetAnnotationInt32Internal(PRInt64 aFkId,
PRBool aIsItemAnnotation,
const nsACString& aName,
PRInt32 aValue,
PRInt32 aFlags,
PRUint16 aExpiration);
nsresult SetAnnotationInt64Internal(PRInt64 aFkId,
PRBool aIsItemAnnotation,
const nsACString& aName,
PRInt64 aValue,
PRInt32 aFlags,
PRUint16 aExpiration);
nsresult SetAnnotationDoubleInternal(PRInt64 aFkId,
PRBool aIsItemAnnotation,
const nsACString& aName,
double aValue,
PRInt32 aFlags,
PRUint16 aExpiration);
nsresult SetAnnotationBinaryInternal(PRInt64 aFkId,
PRBool aIsItemAnnotation,
const nsACString& aName,
const PRUint8 *aData,
PRUint32 aDataLen,
const nsACString& aMimeType,
PRInt32 aFlags,
PRUint16 aExpiration);
nsresult RemoveAnnotationInternal(PRInt64 aFkId,
PRBool aIsItemAnnotation,
const nsACString& aName);
static nsresult GetPlaceIdForURI(nsIURI* aURI, PRInt64* _retval,
PRBool aAutoCreate = PR_TRUE);
static nsresult MigrateFromAlpha1(mozIStorageConnection* aDBConn);
nsresult GetPageAnnotationNamesTArray(nsIURI* aURI, nsTArray<nsCString>* aResult);
void CallSetForPageObservers(nsIURI* aURI, const nsACString& aName);
void CallSetForItemObservers(PRInt64 aItemId, const nsACString& aName);
nsresult GetPagesWithAnnotationCOMArray(const nsACString& aName,
nsCOMArray<nsIURI>* aResults);
nsresult GetItemsWithAnnotationTArray(const nsACString& aName,
nsTArray<PRInt64>* aResult);
nsresult GetAnnotationNamesTArray(PRInt64 aFkId, nsTArray<nsCString>* aResult,
PRBool aIsFkItemId);
};
#endif /* nsAnnotationService_h___ */

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

@ -124,21 +124,14 @@ function LivemarkService() {
// this is giving a reentrant getService warning in XPCShell. bug 194568.
this._ans = Cc[AS_CONTRACTID].getService(Ci.nsIAnnotationService);
var livemarks = this._ans.getPagesWithAnnotation(LMANNO_FEEDURI, {});
var livemarks = this._ans.getItemsWithAnnotation(LMANNO_FEEDURI, {});
for (var i = 0; i < livemarks.length; i++) {
var feedURI =
gIoService.newURI(
this._ans.getAnnotationString(livemarks[i], LMANNO_FEEDURI),
this._ans.getItemAnnotationString(livemarks[i], LMANNO_FEEDURI),
null, null
);
var queries = { }, options = { };
this._history.queryStringToQueries(livemarks[i].spec, queries, {}, options);
var count = {};
var folders = queries.value[0].getFolders(count);
if (!(queries.value.length && queries.value.length == 1) &&
count.value != 1)
continue; // invalid folder URI (should identify exactly one folder)
this._pushLivemark(folders[0], livemarks[i], feedURI);
this._pushLivemark(livemarks[i], feedURI);
}
}
@ -157,9 +150,8 @@ LivemarkService.prototype = {
},
// returns new length of _livemarks
_pushLivemark: function LS__pushLivemark(folderId, folderURI, feedURI) {
return this._livemarks.push({folderId: folderId, folderURI: folderURI,
feedURI: feedURI});
_pushLivemark: function LS__pushLivemark(folderId, feedURI) {
return this._livemarks.push({folderId: folderId, feedURI: feedURI});
},
_getLivemarkIndex: function LS__getLivemarkIndex(folderId) {
@ -184,25 +176,6 @@ LivemarkService.prototype = {
},
deleteLivemarkChildren: function LS_deleteLivemarkChildren(folderId) {
var query = this._history.getNewQuery();
query.setFolders([folderId], 1);
var options = this._history.getNewQueryOptions();
options.setGroupingMode([Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER], 1);
var result = this._history.executeQuery(query, options);
var root = result.root;
root.containerOpen = true;
var cc = root.childCount;
for (var i=0; i < cc; ++i) {
try {
var node = root.getChild(i);
var placeURI = this._bms.getItemURI(node.bookmarkId);
this._ans.removeAnnotation(placeURI, LMANNO_BMANNO);
}
catch (ex) {
// continue
}
}
this._bms.removeFolderChildren(folderId);
},
@ -224,8 +197,8 @@ LivemarkService.prototype = {
// then we assume it's never been loaded. We perform this
// check even when the update is being forced, in case the
// livemark has somehow never been loaded.
var exprTime = this._ans.getAnnotationInt64(livemark.feedURI,
LMANNO_EXPIRATION);
var exprTime = this._ans.getPageAnnotationInt64(livemark.feedURI,
LMANNO_EXPIRATION);
if (!forceUpdate && exprTime > Date.now()) {
// no need to refresh
livemark.locked = false;
@ -268,12 +241,12 @@ LivemarkService.prototype = {
// Don't add livemarks to livemarks
if (this.isLivemark(folder))
throw Cr.NS_ERROR_INVALID_ARG;
var [livemarkID, livemarkURI] =
this._createFolder(this._bms, folder, name, siteURI, feedURI, index);
var livemarkID = this._createFolder(this._bms, folder, name, siteURI,
feedURI, index);
// kick off http fetch
this._updateLivemarkChildren(
this._pushLivemark(livemarkID, livemarkURI, feedURI) - 1,
this._pushLivemark(livemarkID, feedURI) - 1,
false
);
@ -283,10 +256,10 @@ LivemarkService.prototype = {
createLivemarkFolderOnly:
function LS_createLivemarkFolderOnly(bms, folder, name, siteURI,
feedURI, index) {
var [livemarkID, livemarkURI] =
this._createFolder(bms, folder, name, siteURI, feedURI, index);
var livemarkID = this._createFolder(bms, folder, name, siteURI, feedURI,
index);
this.insertLivemarkLoadingItem(bms, livemarkID);
this._pushLivemark(livemarkID, livemarkURI, feedURI);
this._pushLivemark(livemarkID, feedURI);
return livemarkID;
},
@ -294,27 +267,26 @@ LivemarkService.prototype = {
_createFolder:
function LS__createFolder(bms, folder, name, siteURI, feedURI, index) {
var livemarkID = bms.createContainer(folder, name, LS_CONTRACTID, index);
var livemarkURI = bms.getFolderURI(livemarkID);
// Add an annotation to map the folder URI to the livemark feed URI
this._ans.setAnnotationString(livemarkURI, LMANNO_FEEDURI, feedURI.spec, 0,
this._ans.EXPIRE_NEVER);
this._ans.setItemAnnotationString(livemarkID, LMANNO_FEEDURI, feedURI.spec, 0,
this._ans.EXPIRE_NEVER);
// Set the favicon
var faviconService = Cc[FAV_CONTRACTID].getService(Ci.nsIFaviconService);
var livemarkURI = bms.getFolderURI(livemarkID);
faviconService.setFaviconUrlForPage(livemarkURI, this._iconURI);
if (siteURI) {
// Add an annotation to map the folder URI to the livemark site URI
this._ans.setAnnotationString(livemarkURI, LMANNO_SITEURI, siteURI.spec,
0, this._ans.EXPIRE_NEVER);
this._ans.setItemAnnotationString(livemarkID, LMANNO_SITEURI, siteURI.spec,
0, this._ans.EXPIRE_NEVER);
}
return [livemarkID, livemarkURI];
return livemarkID;
},
isLivemark: function LS_isLivemark(folder) {
var folderURI = this._bms.getFolderURI(folder);
return this._ans.hasAnnotation(folderURI, LMANNO_FEEDURI);
return this._ans.itemHasAnnotation(folder, LMANNO_FEEDURI);
},
_ensureLivemark: function LS__ensureLivemark(container) {
@ -330,11 +302,10 @@ LivemarkService.prototype = {
*/
getSiteURI: function LS_getSiteURI(container) {
this._ensureLivemark(container);
var containerURI = this._bms.getFolderURI(container);
var siteURIString;
try {
siteURIString =
this._ans.getAnnotationString(containerURI, LMANNO_SITEURI);
this._ans.getItemAnnotationString(container, LMANNO_SITEURI);
}
catch (ex) {
return null;
@ -345,31 +316,28 @@ LivemarkService.prototype = {
setSiteURI: function LS_setSiteURI(container, siteURI) {
this._ensureLivemark(container);
var containerURI = this._bms.getFolderURI(container);
if (!siteURI) {
this._ans.removeAnnotation(containerURI, LMANNO_SITEURI);
this._ans.removeItemAnnotation(container, LMANNO_SITEURI);
return;
}
this._ans.setAnnotationString(containerURI, LMANNO_SITEURI, siteURI.spec,
0, this._ans.EXPIRE_NEVER);
this._ans.setItemAnnotationString(container, LMANNO_SITEURI, siteURI.spec,
0, this._ans.EXPIRE_NEVER);
},
getFeedURI: function LS_getFeedURI(container) {
var containerURI = this._bms.getFolderURI(container);
return gIoService.newURI(this._ans.getAnnotationString(containerURI,
LMANNO_FEEDURI),
return gIoService.newURI(this._ans.getItemAnnotationString(container,
LMANNO_FEEDURI),
null, null);
},
setFeedURI: function LS_setFeedURI(container, feedURI) {
if (!feedURI)
throw Cr.NS_ERROR_INVALID_ARG;
var containerURI = this._bms.getFolderURI(container);
this._ans.setAnnotationString(containerURI, LMANNO_FEEDURI, feedURI.spec,
0, this._ans.EXPIRE_NEVER);
this._ans.setItemAnnotationString(container, LMANNO_FEEDURI, feedURI.spec,
0, this._ans.EXPIRE_NEVER);
// now update our internal table
var livemarkIndex = this._getLivemarkIndex(container);
@ -391,11 +359,7 @@ LivemarkService.prototype = {
onContainerRemoving: function LS_onContainerRemoving(container) {
var livemarkIndex = this._getLivemarkIndex(container);
var livemark = this._livemarks[livemarkIndex];
// Remove the annotations that link the folder URI to the
// Feed URI and Site URI
this._ans.removeAnnotation(livemark.folderURI, LMANNO_FEEDURI);
this._ans.removeAnnotation(livemark.folderURI, LMANNO_SITEURI);
var stillInUse = false;
stillInUse = this._livemarks.some(
function(mark) { return mark.feedURI.equals(livemark.feedURI) }
@ -403,7 +367,7 @@ LivemarkService.prototype = {
if (!stillInUse) {
// ??? the code in the C++ had "livemark_expiration" as
// the second arg... that must be wrong
this._ans.removeAnnotation(livemark.feedURI, LMANNO_EXPIRATION);
this._ans.removePageAnnotation(livemark.feedURI, LMANNO_EXPIRATION);
}
if (livemark.loadGroup)
@ -412,35 +376,8 @@ LivemarkService.prototype = {
this.deleteLivemarkChildren(container);
},
// XXXdietrich seems like the mutability of "place:" URIs is the only reason
// this code has to exist, which is kinda high-maintenance.
onContainerMoved:
function LS_onContainerMoved(container, newFolder, newIndex) {
var index = this._getLivemarkIndex(container);
// Update the annotation that maps the folder URI to the livemark feed URI
var newURI = this._bms.getFolderURI(container);
var oldURI = this._livemarks[index].folderURI;
var feedURIString = this._ans.getAnnotationString(oldURI, LMANNO_FEEDURI);
this._ans.removeAnnotation(oldURI, LMANNO_FEEDURI);
this._ans.setAnnotationString(newURI, LMANNO_FEEDURI, feedURIString, 0,
this._ans.EXPIRE_NEVER);
// Update the annotation that maps the folder URI to the livemark site URI
var siteURIString;
try {
siteURIString = this._ans.getAnnotationString(oldURI, LMANNO_SITEURI);
}
catch (ex) {
// will throw if no annotation
}
if (siteURIString) {
this._ans.removeAnnotation(oldURI, LMANNO_SITEURI);
this._ans.setAnnotationString(newURI, LMANNO_SITEURI, siteURIString, 0,
this._ans.EXPIRE_NEVER);
}
},
function LS_onContainerMoved(container, newFolder, newIndex) { },
childrenReadOnly: true,
@ -561,9 +498,8 @@ LivemarkLoadListener.prototype = {
function LS_insertLivemarkChild(folderId, uri, title) {
var id = this._bms.insertItem(folderId, uri, this._bms.DEFAULT_INDEX);
this._bms.setItemTitle(id, title);
var placeURI = this._bms.getItemURI(id);
this._ans.setAnnotationString(placeURI, LMANNO_BMANNO, uri.spec, 0,
this._ans.EXPIRE_NEVER);
this._ans.setItemAnnotationString(id, LMANNO_BMANNO, uri.spec, 0,
this._ans.EXPIRE_NEVER);
},
/**
@ -633,9 +569,9 @@ LivemarkLoadListener.prototype = {
_setResourceTTL: function LLL__setResourceTTL(seconds) {
var exptime = Date.now() + seconds;
this._ans.setAnnotationInt64(this._livemark.feedURI,
LMANNO_EXPIRATION, exptime, 0,
Ci.nsIAnnotationService.EXPIRE_NEVER);
this._ans.setPageAnnotationInt64(this._livemark.feedURI,
LMANNO_EXPIRATION, exptime, 0,
Ci.nsIAnnotationService.EXPIRE_NEVER);
},
/**

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

@ -89,8 +89,10 @@ nsNavBookmarks::~nsNavBookmarks()
sInstance = nsnull;
}
NS_IMPL_ISUPPORTS2(nsNavBookmarks,
nsINavBookmarksService, nsINavHistoryObserver)
NS_IMPL_ISUPPORTS3(nsNavBookmarks,
nsINavBookmarksService,
nsINavHistoryObserver,
nsIAnnotationObserver)
nsresult
nsNavBookmarks::Init()
@ -263,10 +265,14 @@ nsNavBookmarks::Init()
rv = transaction.Commit();
NS_ENSURE_SUCCESS(rv, rv);
nsAnnotationService* annosvc = nsAnnotationService::GetAnnotationService();
NS_ENSURE_TRUE(annosvc, NS_ERROR_OUT_OF_MEMORY);
// allows us to notify on title changes. MUST BE LAST so it is impossible
// to fail after this call, or the history service will have a reference to
// us and we won't go away.
history->AddObserver(this, PR_FALSE);
annosvc->AddObserver(this);
// DO NOT PUT STUFF HERE that can fail. See observer comment above.
@ -865,11 +871,9 @@ nsNavBookmarks::SetToolbarFolder(PRInt64 aFolderId)
mToolbarFolder = aFolderId;
// notify observers
nsCOMPtr<nsIURI> folderURI;
rv = GetFolderURI(aFolderId, getter_AddRefs(folderURI));
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
OnItemChanged(mToolbarFolder, folderURI, NS_LITERAL_CSTRING("became_toolbar_folder"),
EmptyString()));
OnItemChanged(mToolbarFolder, NS_LITERAL_CSTRING("became_toolbar_folder"),
PR_FALSE, EmptyCString()));
return NS_OK;
}
@ -926,7 +930,7 @@ nsNavBookmarks::InsertItem(PRInt64 aFolder, nsIURI *aItem, PRInt32 aIndex, PRInt
AddBookmarkToHash(childID, 0);
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
OnItemAdded(rowId, aItem, aFolder, index))
OnItemAdded(rowId, aFolder, index))
return NS_OK;
}
@ -937,11 +941,16 @@ nsNavBookmarks::RemoveItem(PRInt64 aItemId)
mozIStorageConnection *dbConn = DBConn();
mozStorageTransaction transaction(dbConn, PR_FALSE);
nsresult rv;
PRInt32 childIndex;
PRInt64 placeId, folderId;
nsCOMPtr<nsIURI> uri;
nsCAutoString buffer, spec;
nsCAutoString buffer;
// First, remove item annotations
nsAnnotationService* annosvc = nsAnnotationService::GetAnnotationService();
NS_ENSURE_TRUE(annosvc, NS_ERROR_OUT_OF_MEMORY);
nsresult rv = annosvc->RemoveItemAnnotations(aItemId);
NS_ENSURE_SUCCESS(rv, rv);
{ // scoping to ensure the statement gets reset
mozStorageStatementScoper scope(mDBGetItemProperties);
mDBGetItemProperties->BindInt64Parameter(0, aItemId);
@ -956,10 +965,6 @@ nsNavBookmarks::RemoveItem(PRInt64 aItemId)
childIndex = mDBGetItemProperties->AsInt32(kGetItemPropertiesIndex_Position);
placeId = mDBGetItemProperties->AsInt64(kGetItemPropertiesIndex_PlaceID);
folderId = mDBGetItemProperties->AsInt64(kGetItemPropertiesIndex_Parent);
rv = mDBGetItemProperties->GetUTF8String(kGetItemPropertiesIndex_URI, spec);
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewURI(getter_AddRefs(uri), spec);
NS_ENSURE_SUCCESS(rv, rv);
}
buffer.AssignLiteral("DELETE FROM moz_bookmarks WHERE id = ");
@ -980,7 +985,7 @@ nsNavBookmarks::RemoveItem(PRInt64 aItemId)
NS_ENSURE_SUCCESS(rv, rv);
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
OnItemRemoved(aItemId, uri, folderId, childIndex))
OnItemRemoved(aItemId, folderId, childIndex))
return NS_OK;
}
@ -1241,7 +1246,12 @@ nsNavBookmarks::GetParentAndIndexOfFolder(PRInt64 aFolder, PRInt64* aParent,
NS_IMETHODIMP
nsNavBookmarks::RemoveFolder(PRInt64 aFolder)
{
nsresult rv;
// First, remove item annotations
nsAnnotationService* annosvc = nsAnnotationService::GetAnnotationService();
NS_ENSURE_TRUE(annosvc, NS_ERROR_OUT_OF_MEMORY);
nsresult rv = annosvc->RemoveItemAnnotations(aFolder);
NS_ENSURE_SUCCESS(rv, rv);
PRInt64 parent;
PRInt32 index;
nsCAutoString folderType;
@ -1334,9 +1344,8 @@ nsNavBookmarks::RemoveFolderChildren(PRInt64 aFolder)
{
mozStorageTransaction transaction(DBConn(), PR_FALSE);
nsTArray<PRInt32> separatorChildren; // separator indices
nsTArray<PRInt64> folderChildren;
nsTArray<PRInt64> itemChildren;
nsTArray<PRInt64> itemChildren; // bookmarks / separators
nsresult rv;
{
mozStorageStatementScoper scope(mDBGetChildren);
@ -1353,26 +1362,15 @@ nsNavBookmarks::RemoveFolderChildren(PRInt64 aFolder)
if (type == TYPE_FOLDER) {
// folder
folderChildren.AppendElement(
mDBGetChildren->AsInt64(nsNavHistory::kGetInfoIndex_BookmarkItemId));
} else if (type == TYPE_SEPARATOR) {
// separator
// XXXDietrich - could merge this and item, fetch both by id?
separatorChildren.AppendElement(mDBGetChildren->AsInt32(kGetChildrenIndex_Position));
mDBGetChildren->AsInt64(nsNavHistory::kGetInfoIndex_ItemId));
} else {
// item
itemChildren.AppendElement(mDBGetChildren->AsInt64(nsNavHistory::kGetInfoIndex_BookmarkItemId));
// bookmarks / separators
itemChildren.AppendElement(mDBGetChildren->AsInt64(nsNavHistory::kGetInfoIndex_ItemId));
}
}
}
// Remove separators. The list of separators will already be sorted since
// we order by position, so by enumerating it backwards, we avoid having to
// deal with shifting indices.
PRUint32 i;
for (i = separatorChildren.Length() - 1; i != PRInt32(-1); --i) {
rv = RemoveChildAt(aFolder, separatorChildren[i]);
NS_ENSURE_SUCCESS(rv, rv);
}
// remove folders
for (i = 0; i < folderChildren.Length(); ++i) {
@ -1592,25 +1590,9 @@ nsNavBookmarks::SetItemTitle(PRInt64 aItemId, const nsAString &aTitle)
rv = transaction.Commit();
NS_ENSURE_SUCCESS(rv, rv);
// get URI
nsCOMPtr<nsIURI> uri;
nsCAutoString spec;
PRBool results;
{
mozStorageStatementScoper scope(mDBGetItemProperties);
rv = mDBGetItemProperties->BindInt64Parameter(0, aItemId);
NS_ENSURE_SUCCESS(rv, rv);
rv = mDBGetItemProperties->ExecuteStep(&results);
NS_ENSURE_SUCCESS(rv, rv);
mDBGetItemProperties->GetUTF8String(kGetItemPropertiesIndex_URI, spec);
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewURI(getter_AddRefs(uri), spec);
NS_ENSURE_SUCCESS(rv, rv);
}
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
OnItemChanged(aItemId, uri, NS_LITERAL_CSTRING("title"),
aTitle));
OnItemChanged(aItemId, NS_LITERAL_CSTRING("title"),
PR_FALSE, NS_ConvertUTF16toUTF8(aTitle)));
return NS_OK;
}
@ -1850,7 +1832,7 @@ nsNavBookmarks::QueryFolderChildren(PRInt64 aFolderId,
index ++;
PRBool isFolder = mDBGetChildren->AsInt32(kGetChildrenIndex_Type) == TYPE_FOLDER;
PRInt64 id = mDBGetChildren->AsInt64(nsNavHistory::kGetInfoIndex_BookmarkItemId);
PRInt64 id = mDBGetChildren->AsInt64(nsNavHistory::kGetInfoIndex_ItemId);
nsCOMPtr<nsNavHistoryResultNode> node;
if (isFolder) {
@ -1873,10 +1855,10 @@ nsNavBookmarks::QueryFolderChildren(PRInt64 aFolderId,
node = new nsNavHistorySeparatorResultNode();
NS_ENSURE_TRUE(node, NS_ERROR_OUT_OF_MEMORY);
// add the bookmark identifier (RowToResult does so for bookmark items in
// add the item identifier (RowToResult does so for bookmark items in
// the next else block);
node->mBookmarkId =
mDBGetChildren->AsInt64(nsNavHistory::kGetInfoIndex_BookmarkItemId);
node->mItemId =
mDBGetChildren->AsInt64(nsNavHistory::kGetInfoIndex_ItemId);
} else {
rv = History()->RowToResult(mDBGetChildren, options,
getter_AddRefs(node));
@ -1994,6 +1976,8 @@ nsNavBookmarks::GetBookmarkedURIFor(nsIURI* aURI, nsIURI** _retval)
NS_IMETHODIMP
nsNavBookmarks::ChangeBookmarkURI(PRInt64 aBookmarkId, nsIURI *aNewURI)
{
NS_ENSURE_ARG(aNewURI);
mozIStorageConnection *dbConn = DBConn();
mozStorageTransaction transaction(dbConn, PR_FALSE);
@ -2015,13 +1999,13 @@ nsNavBookmarks::ChangeBookmarkURI(PRInt64 aBookmarkId, nsIURI *aNewURI)
rv = transaction.Commit();
NS_ENSURE_SUCCESS(rv, rv);
nsCAutoString spec;
rv = aNewURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
// Pass the new URI to OnItemChanged.
// Observers can fetch the changed value from the URI.
// XXXDietrich - would be more explicit, yet redundant
// to pass the string spec as the changed value.
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
OnItemChanged(aBookmarkId, aNewURI, NS_LITERAL_CSTRING("uri"),
EmptyString()))
OnItemChanged(aBookmarkId, NS_LITERAL_CSTRING("uri"), PR_FALSE, spec))
return NS_OK;
}
@ -2330,7 +2314,7 @@ nsNavBookmarks::OnVisit(nsIURI *aURI, PRInt64 aVisitID, PRTime aTime,
if (bookmarks.Length()) {
for (PRUint32 i = 0; i < bookmarks.Length(); i++)
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
OnItemVisited(bookmarks[i], aURI, aVisitID, aTime))
OnItemVisited(bookmarks[i], aVisitID, aTime))
}
}
return NS_OK;
@ -2352,8 +2336,8 @@ nsNavBookmarks::OnDeleteURI(nsIURI *aURI)
if (bookmarks.Length()) {
for (PRUint32 i = 0; i < bookmarks.Length(); i ++)
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
OnItemChanged(bookmarks[i], aURI, NS_LITERAL_CSTRING("cleartime"),
EmptyString()))
OnItemChanged(bookmarks[i], NS_LITERAL_CSTRING("cleartime"),
PR_FALSE, EmptyCString()))
}
}
return NS_OK;
@ -2394,8 +2378,8 @@ nsNavBookmarks::OnPageChanged(nsIURI *aURI, PRUint32 aWhat,
if (bookmarks.Length()) {
for (PRUint32 i = 0; i < bookmarks.Length(); i ++)
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
OnItemChanged(bookmarks[i], aURI, NS_LITERAL_CSTRING("favicon"),
aValue));
OnItemChanged(bookmarks[i], NS_LITERAL_CSTRING("favicon"),
PR_FALSE, NS_ConvertUTF16toUTF8(aValue)));
}
}
}
@ -2409,3 +2393,34 @@ nsNavBookmarks::OnPageExpired(nsIURI* aURI, PRTime aVisitTime,
// pages that are bookmarks shouldn't expire, so we don't need to handle it
return NS_OK;
}
// nsIAnnotationObserver
NS_IMETHODIMP
nsNavBookmarks::OnPageAnnotationSet(nsIURI* aPage, const nsACString& aName)
{
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::OnItemAnnotationSet(PRInt64 aItemId, const nsACString& aName)
{
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
OnItemChanged(aItemId, aName, PR_TRUE, EmptyCString()));
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::OnPageAnnotationRemoved(nsIURI* aPage, const nsACString& aName)
{
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::OnItemAnnotationRemoved(PRInt64 aItemId, const nsACString& aName)
{
ENUMERATE_WEAKARRAY(mObservers, nsINavBookmarkObserver,
OnItemChanged(aItemId, aName, PR_TRUE, EmptyCString()));
return NS_OK;
}

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

@ -40,6 +40,7 @@
#define nsNavBookmarks_h_
#include "nsINavBookmarksService.h"
#include "nsIAnnotationService.h"
#include "nsIStringBundle.h"
#include "nsITransaction.h"
#include "nsNavHistory.h"
@ -49,12 +50,14 @@
class nsIOutputStream;
class nsNavBookmarks : public nsINavBookmarksService,
public nsINavHistoryObserver
public nsINavHistoryObserver,
public nsIAnnotationObserver
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSINAVBOOKMARKSSERVICE
NS_DECL_NSINAVHISTORYOBSERVER
NS_DECL_NSIANNOTATIONOBSERVER
nsNavBookmarks();
nsresult Init();

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

@ -207,7 +207,7 @@ const PRInt32 nsNavHistory::kGetInfoIndex_VisitCount = 4;
const PRInt32 nsNavHistory::kGetInfoIndex_VisitDate = 5;
const PRInt32 nsNavHistory::kGetInfoIndex_FaviconURL = 6;
const PRInt32 nsNavHistory::kGetInfoIndex_SessionId = 7;
const PRInt32 nsNavHistory::kGetInfoIndex_BookmarkItemId = 8;
const PRInt32 nsNavHistory::kGetInfoIndex_ItemId = 8;
const PRInt32 nsNavHistory::kAutoCompleteIndex_URL = 0;
const PRInt32 nsNavHistory::kAutoCompleteIndex_Title = 1;
@ -3933,9 +3933,9 @@ nsNavHistory::RowToResult(mozIStorageValueArray* aRow,
return NS_ERROR_OUT_OF_MEMORY;
PRBool isNull;
if (NS_SUCCEEDED(aRow->GetIsNull(kGetInfoIndex_BookmarkItemId, &isNull)) &&
if (NS_SUCCEEDED(aRow->GetIsNull(kGetInfoIndex_ItemId, &isNull)) &&
!isNull) {
(*aResult)->mBookmarkId = aRow->AsInt64(kGetInfoIndex_BookmarkItemId);
(*aResult)->mItemId = aRow->AsInt64(kGetInfoIndex_ItemId);
}
NS_ADDREF(*aResult);
return NS_OK;

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

@ -220,7 +220,7 @@ public:
static const PRInt32 kGetInfoIndex_Title;
static const PRInt32 kGetInfoIndex_RevHost;
static const PRInt32 kGetInfoIndex_VisitCount;
static const PRInt32 kGetInfoIndex_BookmarkItemId;
static const PRInt32 kGetInfoIndex_ItemId;
// select a history row by URL, with visit date info (extra work)
mozIStorageStatement* DBGetURLPageInfoFull()

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

@ -115,7 +115,7 @@ nsNavHistoryResultNode::nsNavHistoryResultNode(
mTime(aTime),
mFaviconURI(aIconURI),
mBookmarkIndex(-1),
mBookmarkId(-1),
mItemId(-1),
mIndentLevel(-1),
mViewIndex(-1)
{
@ -827,73 +827,120 @@ PRInt32 PR_CALLBACK nsNavHistoryContainerResultNode::SortComparison_AnnotationLe
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bookmarks, 0);
// Get the annotating-uris for both nodes
nsCOMPtr<nsIURI> a_uri;
if (a->mBookmarkId != -1) {
bookmarks->GetItemURI(a->mBookmarkId, getter_AddRefs(a_uri));
PRBool a_itemAnno = PR_FALSE;
PRBool b_itemAnno = PR_FALSE;
// Not used for item annos
nsCOMPtr<nsIURI> a_uri, b_uri;
if (a->mItemId != -1) {
a_itemAnno = PR_TRUE;
} else {
nsCAutoString spec;
if (NS_SUCCEEDED(a->GetUri(spec)))
NS_NewURI(getter_AddRefs(a_uri), spec);
NS_ENSURE_TRUE(a_uri, 0);
}
NS_ENSURE_TRUE(a_uri, 0);
nsCOMPtr<nsIURI> b_uri;
if (b->mBookmarkId != -1) {
bookmarks->GetItemURI(b->mBookmarkId, getter_AddRefs(b_uri));
if (b->mItemId != -1) {
b_itemAnno = PR_TRUE;
} else {
nsCAutoString spec;
if (NS_SUCCEEDED(b->GetUri(spec)))
NS_NewURI(getter_AddRefs(b_uri), spec);
NS_ENSURE_TRUE(b_uri, 0);
}
NS_ENSURE_TRUE(b_uri, 0);
nsAnnotationService* annosvc = nsAnnotationService::GetAnnotationService();
NS_ENSURE_TRUE(annosvc, 0);
PRBool a_hasAnno, b_hasAnno;
NS_ENSURE_SUCCESS(annosvc->HasAnnotation(a_uri, annoName, &a_hasAnno), 0);
NS_ENSURE_SUCCESS(annosvc->HasAnnotation(b_uri, annoName, &b_hasAnno), 0);
if (a_itemAnno) {
NS_ENSURE_SUCCESS(annosvc->ItemHasAnnotation(a->mItemId, annoName,
&a_hasAnno), 0);
} else {
NS_ENSURE_SUCCESS(annosvc->PageHasAnnotation(a_uri, annoName,
&a_hasAnno), 0);
}
if (b_itemAnno) {
NS_ENSURE_SUCCESS(annosvc->ItemHasAnnotation(b->mItemId, annoName,
&b_hasAnno), 0);
} else {
NS_ENSURE_SUCCESS(annosvc->PageHasAnnotation(b_uri, annoName,
&b_hasAnno), 0);
}
PRInt32 value = 0;
if (a_hasAnno && b_hasAnno) {
PRInt32 a_type, b_type;
NS_ENSURE_SUCCESS(annosvc->GetAnnotationType(a_uri, annoName, &a_type), 0);
NS_ENSURE_SUCCESS(annosvc->GetAnnotationType(b_uri, annoName, &b_type), 0);
if (a_hasAnno || b_hasAnno) {
PRUint16 annoType;
if (a_hasAnno) {
if (a_itemAnno) {
NS_ENSURE_SUCCESS(annosvc->GetItemAnnotationType(a->mItemId,
annoName,
&annoType), 0);
} else {
NS_ENSURE_SUCCESS(annosvc->GetPageAnnotationType(a_uri, annoName,
&annoType), 0);
}
}
if (b_hasAnno) {
PRUint16 b_type;
if (b_itemAnno) {
NS_ENSURE_SUCCESS(annosvc->GetItemAnnotationType(b->mItemId,
annoName,
&b_type), 0);
} else {
NS_ENSURE_SUCCESS(annosvc->GetPageAnnotationType(b_uri, annoName,
&b_type), 0);
}
// We better make the API not support this state, really
if (b_type != annoType)
return 0;
}
#define GET_ANNOTATIONS_VALUES(METHOD_ITEM, METHOD_PAGE, A_VAL, B_VAL) \
if (a_hasAnno) { \
if (a_itemAnno) { \
NS_ENSURE_SUCCESS(annosvc->METHOD_ITEM(a->mItemId, annoName, \
A_VAL), 0); \
} else { \
NS_ENSURE_SUCCESS(annosvc->METHOD_PAGE(a_uri, annoName, \
A_VAL), 0); \
} \
} \
if (b_hasAnno) { \
if (b_itemAnno) { \
NS_ENSURE_SUCCESS(annosvc->METHOD_ITEM(b->mItemId, annoName, \
B_VAL), 0); \
} else { \
NS_ENSURE_SUCCESS(annosvc->METHOD_PAGE(b_uri, annoName, \
B_VAL), 0); \
} \
}
// Surprising as it is, we don't support sorting by a binary annotation
if (a_type == b_type &&
a_type != nsIAnnotationService::TYPE_BINARY) {
if (a_type == nsIAnnotationService::TYPE_STRING) {
if (annoType != nsIAnnotationService::TYPE_BINARY) {
if (annoType == nsIAnnotationService::TYPE_STRING) {
nsAutoString a_val, b_val;
NS_ENSURE_SUCCESS(annosvc->GetAnnotationString(a_uri, annoName, a_val),
0);
NS_ENSURE_SUCCESS(annosvc->GetAnnotationString(b_uri, annoName, b_val),
0);
GET_ANNOTATIONS_VALUES(GetItemAnnotationString,
GetPageAnnotationString, a_val, b_val);
value = SortComparison_StringLess(a_val, b_val);
}
else if (a_type == nsIAnnotationService::TYPE_INT32) {
PRInt32 a_val, b_val;
NS_ENSURE_SUCCESS(annosvc->GetAnnotationInt32(a_uri, annoName, &a_val),
0);
NS_ENSURE_SUCCESS(annosvc->GetAnnotationInt32(b_uri, annoName, &b_val),
0);
else if (annoType == nsIAnnotationService::TYPE_INT32) {
PRInt32 a_val = 0, b_val = 0;
GET_ANNOTATIONS_VALUES(GetItemAnnotationInt32,
GetPageAnnotationInt32, &a_val, &b_val);
value = (a < b) ? -1 : (a > b) ? 1 : 0;
}
else if (a_type == nsIAnnotationService::TYPE_INT64) {
PRInt64 a_val, b_val;
NS_ENSURE_SUCCESS(annosvc->GetAnnotationInt64(a_uri, annoName, &a_val),
0);
NS_ENSURE_SUCCESS(annosvc->GetAnnotationInt64(b_uri, annoName, &b_val),
0);
else if (annoType == nsIAnnotationService::TYPE_INT64) {
PRInt64 a_val = 0, b_val = 0;
GET_ANNOTATIONS_VALUES(GetItemAnnotationInt64,
GetPageAnnotationInt64, &a_val, &b_val);
value = (a < b) ? -1 : (a > b) ? 1 : 0;
}
else if (a_type == nsIAnnotationService::TYPE_DOUBLE) {
double a_val, b_val;
NS_ENSURE_SUCCESS(annosvc->GetAnnotationDouble(a_uri, annoName, &a_val),
0);
NS_ENSURE_SUCCESS(annosvc->GetAnnotationDouble(b_uri, annoName, &b_val),
0);
else if (annoType == nsIAnnotationService::TYPE_DOUBLE) {
double a_val = 0, b_val = 0;
GET_ANNOTATIONS_VALUES(GetItemAnnotationDouble,
GetPageAnnotationDouble, &a_val, &b_val);
value = (a < b) ? -1 : (a > b) ? 1 : 0;
}
}
@ -968,7 +1015,7 @@ nsNavHistoryContainerResultNode::FindChildFolder(PRInt64 aFolderId,
for (PRInt32 i = 0; i < mChildren.Count(); i ++) {
if (mChildren[i]->IsFolder()) {
nsNavHistoryFolderResultNode* folder = mChildren[i]->GetAsFolder();
if (folder->mFolderId == aFolderId) {
if (folder->mItemId == aFolderId) {
*aNodeIndex = i;
return folder;
}
@ -2403,7 +2450,7 @@ nsNavHistoryQueryResultNode::OnPageExpired(nsIURI* aURI, PRTime aVisitTime,
// the bookmark system.
NS_IMETHODIMP
nsNavHistoryQueryResultNode::OnItemAdded(PRInt64 aBookmarkId, nsIURI* aBookmark, PRInt64 aFolder,
nsNavHistoryQueryResultNode::OnItemAdded(PRInt64 aItemId, PRInt64 aFolder,
PRInt32 aIndex)
{
if (mLiveUpdate == QUERYUPDATE_COMPLEX_WITH_BOOKMARKS)
@ -2411,7 +2458,7 @@ nsNavHistoryQueryResultNode::OnItemAdded(PRInt64 aBookmarkId, nsIURI* aBookmark,
return NS_OK;
}
NS_IMETHODIMP
nsNavHistoryQueryResultNode::OnItemRemoved(PRInt64 aBookmarkId, nsIURI* aBookmark, PRInt64 aFolder,
nsNavHistoryQueryResultNode::OnItemRemoved(PRInt64 aItemId, PRInt64 aFolder,
PRInt32 aIndex)
{
if (mLiveUpdate == QUERYUPDATE_COMPLEX_WITH_BOOKMARKS)
@ -2419,15 +2466,16 @@ nsNavHistoryQueryResultNode::OnItemRemoved(PRInt64 aBookmarkId, nsIURI* aBookmar
return NS_OK;
}
NS_IMETHODIMP
nsNavHistoryQueryResultNode::OnItemChanged(PRInt64 aBookmarkId, nsIURI* aBookmark,
const nsACString& aProperty,
const nsAString& aValue)
nsNavHistoryQueryResultNode::OnItemChanged(PRInt64 aItemId,
const nsACString& aProperty,
PRBool aIsAnnotationProperty,
const nsACString& aValue)
{
NS_NOTREACHED("Everything observers should not get OnItemChanged, but should get the corresponding history notifications instead");
return NS_OK;
}
NS_IMETHODIMP
nsNavHistoryQueryResultNode::OnItemVisited(PRInt64 aBookmarkId, nsIURI* aBookmark,
nsNavHistoryQueryResultNode::OnItemVisited(PRInt64 aItemId,
PRInt64 aVisitId, PRTime aTime)
{
NS_NOTREACHED("Everything observers should not get OnItemVisited, but should get OnVisit instead");
@ -2524,9 +2572,10 @@ nsNavHistoryFolderResultNode::nsNavHistoryFolderResultNode(
nsNavHistoryResultNode::RESULT_TYPE_FOLDER,
PR_FALSE, aRemoteContainerType),
mContentsValid(PR_FALSE),
mOptions(aOptions),
mFolderId(aFolderId)
mOptions(aOptions)
{
mItemId = aFolderId;
// Get the favicon, if any, for this folder. Errors aren't too important
// here, so just give up if anything bad happens.
//
@ -2648,7 +2697,7 @@ nsNavHistoryFolderResultNode::GetChildrenReadOnly(PRBool *aChildrenReadOnly)
{
nsNavBookmarks* bookmarks = nsNavBookmarks::GetBookmarksService();
NS_ENSURE_TRUE(bookmarks, NS_ERROR_UNEXPECTED);
return bookmarks->GetFolderReadonly(mFolderId, aChildrenReadOnly);
return bookmarks->GetFolderReadonly(mItemId, aChildrenReadOnly);
}
@ -2695,7 +2744,7 @@ nsNavHistoryFolderResultNode::GetQueries(PRUint32* queryCount,
NS_ENSURE_SUCCESS(rv, rv);
// query just has the folder ID set and nothing else
rv = query->SetFolders(&mFolderId, 1);
rv = query->SetFolders(&mItemId, 1);
NS_ENSURE_SUCCESS(rv, rv);
// make array of our 1 query
@ -2742,7 +2791,7 @@ nsNavHistoryFolderResultNode::FillChildren()
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
// actually get the folder children from the bookmark service
nsresult rv = bookmarks->QueryFolderChildren(mFolderId, mOptions, &mChildren);
nsresult rv = bookmarks->QueryFolderChildren(mItemId, mOptions, &mChildren);
NS_ENSURE_SUCCESS(rv, rv);
// PERFORMANCE: it may be better to also fill any child folders at this point
@ -2767,7 +2816,7 @@ nsNavHistoryFolderResultNode::FillChildren()
// register with the result for updates
nsNavHistoryResult* result = GetResult();
NS_ENSURE_TRUE(result, NS_ERROR_FAILURE);
result->AddBookmarkObserver(this, mFolderId);
result->AddBookmarkObserver(this, mItemId);
mContentsValid = PR_TRUE;
return NS_OK;
@ -2788,7 +2837,7 @@ nsNavHistoryFolderResultNode::ClearChildren(PRBool unregister)
if (unregister && mContentsValid) {
nsNavHistoryResult* result = GetResult();
if (result)
result->RemoveBookmarkObserver(this, mFolderId);
result->RemoveBookmarkObserver(this, mItemId);
}
mContentsValid = PR_FALSE;
}
@ -2882,11 +2931,11 @@ nsNavHistoryFolderResultNode::ReindexRange(PRInt32 aStartIndex,
// found. Does not addref the node!
nsNavHistoryResultNode*
nsNavHistoryFolderResultNode::FindChildURIById(PRInt64 aBookmarkId,
nsNavHistoryFolderResultNode::FindChildURIById(PRInt64 aItemId,
PRUint32* aNodeIndex)
{
for (PRInt32 i = 0; i < mChildren.Count(); i ++) {
if (mChildren[i]->mBookmarkId == aBookmarkId) {
if (mChildren[i]->mItemId == aItemId) {
*aNodeIndex = i;
return mChildren[i];
}
@ -2916,10 +2965,10 @@ nsNavHistoryFolderResultNode::OnEndUpdateBatch()
// nsNavHistoryFolderResultNode::OnItemAdded (nsINavBookmarkObserver)
NS_IMETHODIMP
nsNavHistoryFolderResultNode::OnItemAdded(PRInt64 aBookmarkId, nsIURI* aBookmark,
nsNavHistoryFolderResultNode::OnItemAdded(PRInt64 aItemId,
PRInt64 aFolder, PRInt32 aIndex)
{
NS_ASSERTION(aFolder == mFolderId, "Got wrong bookmark update");
NS_ASSERTION(aFolder == mItemId, "Got wrong bookmark update");
if (mOptions->ExcludeItems()) {
// don't update items when we aren't displaying them, but we still need
// to adjust bookmark indices to account for the insertion
@ -2946,10 +2995,10 @@ nsNavHistoryFolderResultNode::OnItemAdded(PRInt64 aBookmarkId, nsIURI* aBookmark
NS_ENSURE_TRUE(history, NS_ERROR_OUT_OF_MEMORY);
nsNavHistoryResultNode* node;
nsresult rv = history->BookmarkIdToResultNode(aBookmarkId, mOptions, &node);
nsresult rv = history->BookmarkIdToResultNode(aItemId, mOptions, &node);
NS_ENSURE_SUCCESS(rv, rv);
node->mBookmarkIndex = aIndex;
node->mBookmarkId = aBookmarkId;
node->mItemId = aItemId;
if (GetSortType() == nsINavHistoryQueryOptions::SORT_BY_NONE) {
// insert at natural bookmarks position
@ -2963,10 +3012,10 @@ nsNavHistoryFolderResultNode::OnItemAdded(PRInt64 aBookmarkId, nsIURI* aBookmark
// nsNavHistoryFolderResultNode::OnItemRemoved (nsINavBookmarkObserver)
NS_IMETHODIMP
nsNavHistoryFolderResultNode::OnItemRemoved(PRInt64 aBookmarkId, nsIURI* aBookmark,
nsNavHistoryFolderResultNode::OnItemRemoved(PRInt64 aItemId,
PRInt64 aFolder, PRInt32 aIndex)
{
NS_ASSERTION(aFolder == mFolderId, "Got wrong bookmark update");
NS_ASSERTION(aFolder == mItemId, "Got wrong bookmark update");
if (mOptions->ExcludeItems()) {
// don't update items when we aren't displaying them, but we do need to
// adjust everybody's bookmark indices to account for the removal
@ -2983,7 +3032,7 @@ nsNavHistoryFolderResultNode::OnItemRemoved(PRInt64 aBookmarkId, nsIURI* aBookma
// sorting could be different, or the bookmark services indices and ours might
// be out of sync somehow.
PRUint32 nodeIndex;
nsNavHistoryResultNode* node = FindChildURIById(aBookmarkId, &nodeIndex);
nsNavHistoryResultNode* node = FindChildURIById(aItemId, &nodeIndex);
if (! node)
return NS_ERROR_FAILURE; // can't find it
@ -2994,9 +3043,10 @@ nsNavHistoryFolderResultNode::OnItemRemoved(PRInt64 aBookmarkId, nsIURI* aBookma
// nsNavHistoryFolderResultNode::OnItemChanged (nsINavBookmarkObserver)
NS_IMETHODIMP
nsNavHistoryFolderResultNode::OnItemChanged(PRInt64 aBookmarkId, nsIURI* aBookmark,
nsNavHistoryFolderResultNode::OnItemChanged(PRInt64 aItemId,
const nsACString& aProperty,
const nsAString& aValue)
PRBool aIsAnnotationProperty,
const nsACString& aValue)
{
if (mOptions->ExcludeItems())
return NS_OK; // don't update items when we aren't displaying them
@ -3004,26 +3054,23 @@ nsNavHistoryFolderResultNode::OnItemChanged(PRInt64 aBookmarkId, nsIURI* aBookma
return NS_OK;
PRUint32 nodeIndex;
nsNavHistoryResultNode* node = FindChildURIById(aBookmarkId, &nodeIndex);
nsNavHistoryResultNode* node = FindChildURIById(aItemId, &nodeIndex);
if (!node)
return NS_ERROR_FAILURE;
if (aProperty.EqualsLiteral("title")) {
node->mTitle = NS_ConvertUTF16toUTF8(aValue);
node->mTitle = aValue;
}
else if (aProperty.EqualsLiteral("uri")) {
nsCAutoString spec;
nsresult rv = aBookmark->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
node->mURI = spec;
node->mURI = aValue;
}
else if (aProperty.EqualsLiteral("favicon")) {
node->mFaviconURI = NS_ConvertUTF16toUTF8(aValue);
node->mFaviconURI = aValue;
}
else if (aProperty.EqualsLiteral("cleartime")) {
node->mTime = 0;
}
else {
else if (!aIsAnnotationProperty){
NS_NOTREACHED("Unknown bookmark property changing.");
}
@ -3056,7 +3103,7 @@ nsNavHistoryFolderResultNode::OnItemChanged(PRInt64 aBookmarkId, nsIURI* aBookma
// Update visit count and last visit time and refresh.
NS_IMETHODIMP
nsNavHistoryFolderResultNode::OnItemVisited(PRInt64 aBookmarkId, nsIURI* aBookmark,
nsNavHistoryFolderResultNode::OnItemVisited(PRInt64 aItemId,
PRInt64 aVisitId, PRTime aTime)
{
if (mOptions->ExcludeItems())
@ -3065,7 +3112,7 @@ nsNavHistoryFolderResultNode::OnItemVisited(PRInt64 aBookmarkId, nsIURI* aBookma
return NS_OK;
PRUint32 nodeIndex;
nsNavHistoryResultNode* node = FindChildURIById(aBookmarkId, &nodeIndex);
nsNavHistoryResultNode* node = FindChildURIById(aItemId, &nodeIndex);
if (! node)
return NS_ERROR_FAILURE;
@ -3117,7 +3164,7 @@ NS_IMETHODIMP
nsNavHistoryFolderResultNode::OnFolderAdded(PRInt64 aFolder, PRInt64 aParent,
PRInt32 aIndex)
{
NS_ASSERTION(aParent == mFolderId, "Got wrong bookmark update");
NS_ASSERTION(aParent == mItemId, "Got wrong bookmark update");
if (! StartIncrementalUpdate())
return NS_OK; // folder was completely refreshed for us
@ -3150,10 +3197,10 @@ nsNavHistoryFolderResultNode::OnFolderRemoved(PRInt64 aFolder, PRInt64 aParent,
// We only care about notifications when a child changes. When the deleted
// folder is us, our parent should also be registered and will remove us from
// its list.
if (mFolderId == aFolder)
if (mItemId == aFolder)
return NS_OK;
NS_ASSERTION(aParent == mFolderId, "Got wrong bookmark update");
NS_ASSERTION(aParent == mItemId, "Got wrong bookmark update");
if (! StartIncrementalUpdate())
return NS_OK; // we are completely refreshed
@ -3177,7 +3224,7 @@ nsNavHistoryFolderResultNode::OnFolderMoved(PRInt64 aFolder, PRInt64 aOldParent,
PRInt32 aOldIndex, PRInt64 aNewParent,
PRInt32 aNewIndex)
{
NS_ASSERTION(aOldParent == mFolderId || aNewParent == mFolderId,
NS_ASSERTION(aOldParent == mItemId || aNewParent == mItemId,
"Got a bookmark message that doesn't belong to us");
if (! StartIncrementalUpdate())
return NS_OK; // entire container was refreshed for us
@ -3218,9 +3265,9 @@ nsNavHistoryFolderResultNode::OnFolderMoved(PRInt64 aFolder, PRInt64 aOldParent,
} else {
// moving between two different folders, just do a remove and an add
if (aOldParent == mFolderId)
if (aOldParent == mItemId)
OnFolderRemoved(aFolder, aOldParent, aOldIndex);
if (aNewParent == mFolderId)
if (aNewParent == mItemId)
OnFolderAdded(aFolder, aNewParent, aNewIndex);
}
return NS_OK;
@ -3247,7 +3294,7 @@ nsNavHistoryFolderResultNode::OnFolderChanged(PRInt64 aFolder,
NS_ENSURE_TRUE(bookmarks, NS_ERROR_OUT_OF_MEMORY);
nsAutoString title;
bookmarks->GetFolderTitle(mFolderId, title);
bookmarks->GetFolderTitle(mItemId, title);
mTitle = NS_ConvertUTF16toUTF8(title);
PRInt32 sortType = GetSortType();
@ -3288,7 +3335,7 @@ nsNavHistoryFolderResultNode::OnFolderChanged(PRInt64 aFolder,
NS_IMETHODIMP
nsNavHistoryFolderResultNode::OnSeparatorAdded(PRInt64 aParent, PRInt32 aIndex)
{
NS_ASSERTION(aParent == mFolderId, "Got wrong bookmark update");
NS_ASSERTION(aParent == mItemId, "Got wrong bookmark update");
if (mOptions->ExcludeItems()) {
// don't update items when we aren't displaying them, except we need to
// update the indices
@ -3317,7 +3364,7 @@ NS_IMETHODIMP
nsNavHistoryFolderResultNode::OnSeparatorRemoved(PRInt64 aParent,
PRInt32 aIndex)
{
NS_ASSERTION(aParent == mFolderId, "Got wrong bookmark update");
NS_ASSERTION(aParent == mItemId, "Got wrong bookmark update");
if (mOptions->ExcludeItems()) {
// don't update items when we aren't displaying them, except we need to
// update everybody's indices
@ -3716,14 +3763,13 @@ nsNavHistoryResult::OnEndUpdateBatch()
// nsNavHistoryResult::OnItemAdded (nsINavBookmarkObserver)
NS_IMETHODIMP
nsNavHistoryResult::OnItemAdded(PRInt64 aBookmarkId,
nsIURI *aBookmark,
nsNavHistoryResult::OnItemAdded(PRInt64 aItemId,
PRInt64 aFolder,
PRInt32 aIndex)
{
ENUMERATE_BOOKMARK_OBSERVERS_FOR_FOLDER(aFolder,
OnItemAdded(aBookmarkId, aBookmark, aFolder, aIndex));
ENUMERATE_HISTORY_OBSERVERS(OnItemAdded(aBookmarkId, aBookmark, aFolder, aIndex));
OnItemAdded(aItemId, aFolder, aIndex));
ENUMERATE_HISTORY_OBSERVERS(OnItemAdded(aItemId, aFolder, aIndex));
return NS_OK;
}
@ -3731,12 +3777,12 @@ nsNavHistoryResult::OnItemAdded(PRInt64 aBookmarkId,
// nsNavHistoryResult::OnItemRemoved (nsINavBookmarkObserver)
NS_IMETHODIMP
nsNavHistoryResult::OnItemRemoved(PRInt64 aBookmarkId, nsIURI *aBookmark,
nsNavHistoryResult::OnItemRemoved(PRInt64 aItemId,
PRInt64 aFolder, PRInt32 aIndex)
{
ENUMERATE_BOOKMARK_OBSERVERS_FOR_FOLDER(aFolder,
OnItemRemoved(aBookmarkId, aBookmark, aFolder, aIndex));
ENUMERATE_HISTORY_OBSERVERS(OnItemRemoved(aBookmarkId, aBookmark, aFolder, aIndex));
OnItemRemoved(aItemId, aFolder, aIndex));
ENUMERATE_HISTORY_OBSERVERS(OnItemRemoved(aItemId, aFolder, aIndex));
return NS_OK;
}
@ -3744,9 +3790,10 @@ nsNavHistoryResult::OnItemRemoved(PRInt64 aBookmarkId, nsIURI *aBookmark,
// nsNavHistoryResult::OnItemChanged (nsINavBookmarkObserver)
NS_IMETHODIMP
nsNavHistoryResult::OnItemChanged(PRInt64 aBookmarkId, nsIURI *aBookmark,
nsNavHistoryResult::OnItemChanged(PRInt64 aItemId,
const nsACString &aProperty,
const nsAString &aValue)
PRBool aIsAnnotationProperty,
const nsACString &aValue)
{
nsresult rv;
nsNavBookmarks* bookmarkService = nsNavBookmarks::GetBookmarksService();
@ -3754,10 +3801,10 @@ nsNavHistoryResult::OnItemChanged(PRInt64 aBookmarkId, nsIURI *aBookmark,
// find the folder to notify about this item
PRInt64 folderId;
rv = bookmarkService->GetFolderIdForItem(aBookmarkId, &folderId);
rv = bookmarkService->GetFolderIdForItem(aItemId, &folderId);
NS_ENSURE_SUCCESS(rv, rv);
ENUMERATE_BOOKMARK_OBSERVERS_FOR_FOLDER(folderId,
OnItemChanged(aBookmarkId, aBookmark, aProperty, aValue));
OnItemChanged(aItemId, aProperty, aIsAnnotationProperty, aValue));
// Note: we do NOT call history observers in this case. This notification is
// the same as other history notification, except that here we know the item
@ -3770,8 +3817,8 @@ nsNavHistoryResult::OnItemChanged(PRInt64 aBookmarkId, nsIURI *aBookmark,
// nsNavHistoryResult::OnItemVisited (nsINavBookmarkObserver)
NS_IMETHODIMP
nsNavHistoryResult::OnItemVisited(PRInt64 aBookmarkId, nsIURI* aBookmark,
PRInt64 aVisitId, PRTime aVisitTime)
nsNavHistoryResult::OnItemVisited(PRInt64 aItemId, PRInt64 aVisitId,
PRTime aVisitTime)
{
nsresult rv;
nsNavBookmarks* bookmarkService = nsNavBookmarks::GetBookmarksService();
@ -3779,10 +3826,10 @@ nsNavHistoryResult::OnItemVisited(PRInt64 aBookmarkId, nsIURI* aBookmark,
// find the folder to notify about this item
PRInt64 folderId;
rv = bookmarkService->GetFolderIdForItem(aBookmarkId, &folderId);
rv = bookmarkService->GetFolderIdForItem(aItemId, &folderId);
NS_ENSURE_SUCCESS(rv, rv);
ENUMERATE_BOOKMARK_OBSERVERS_FOR_FOLDER(folderId,
OnItemVisited(aBookmarkId, aBookmark, aVisitId, aVisitTime));
OnItemVisited(aItemId, aVisitId, aVisitTime));
// Note: we do NOT call history observers in this case. This notification is
// the same as OnVisit, except that here we know the item is a bookmark.

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

@ -224,8 +224,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsNavHistoryResult, NS_NAVHISTORYRESULT_IID)
{ mViewIndex = aViewIndex; return NS_OK; } \
NS_IMETHOD GetBookmarkIndex(PRInt32* aIndex) \
{ *aIndex = mBookmarkIndex; return NS_OK; } \
NS_IMETHOD GetBookmarkId(PRInt64* aId) \
{ *aId= mBookmarkId; return NS_OK; }
NS_IMETHOD GetItemId(PRInt64* aId) \
{ *aId= mItemId; return NS_OK; }
// This is used by the base classes instead of
// NS_FORWARD_NSINAVHISTORYRESULTNODE(nsNavHistoryResultNode) because they
@ -364,7 +364,7 @@ public:
PRInt64 mTime;
nsCString mFaviconURI;
PRInt32 mBookmarkIndex;
PRInt64 mBookmarkId;
PRInt64 mItemId;
// The indent level of this node. The root node will have a value of -1. The
// root's children will have a value of 0, and so on.
@ -707,7 +707,7 @@ public:
NS_DECL_NSINAVHISTORYQUERYRESULTNODE
NS_IMETHOD GetFolderId(PRInt64* aFolderId)
{ *aFolderId = mFolderId; return NS_OK; }
{ *aFolderId = mItemId; return NS_OK; }
virtual nsresult OpenContainer();
@ -725,7 +725,6 @@ public:
PRBool mContentsValid;
nsCOMPtr<nsNavHistoryQueryOptions> mOptions;
PRInt64 mFolderId;
nsresult FillChildren();
void ClearChildren(PRBool aUnregister);
@ -734,7 +733,7 @@ public:
PRBool StartIncrementalUpdate();
void ReindexRange(PRInt32 aStartIndex, PRInt32 aEndIndex, PRInt32 aDelta);
nsNavHistoryResultNode* FindChildURIById(PRInt64 aBookmarkId,
nsNavHistoryResultNode* FindChildURIById(PRInt64 aItemId,
PRUint32* aNodeIndex);
};

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

@ -51,6 +51,13 @@ try {
do_throw("Could not get history service\n");
}
// Get annotation service
try {
var annosvc= Cc["@mozilla.org/browser/annotation-service;1"].getService(Ci.nsIAnnotationService);
} catch(ex) {
do_throw("Could not get annotation service\n");
}
// create and add bookmarks observer
var observer = {
onBeginUpdateBatch: function() {
@ -59,27 +66,25 @@ var observer = {
onEndUpdateBatch: function() {
this._endUpdateBatch = true;
},
onItemAdded: function(id, uri, folder, index) {
this._itemAdded = uri;
onItemAdded: function(id, folder, index) {
this._itemAddedId = id;
this._itemAddedFolder = folder;
this._itemAddedIndex = index;
},
onItemRemoved: function(id, uri, folder, index) {
this._itemRemoved = uri;
onItemRemoved: function(id, folder, index) {
this._itemRemovedId = id;
this._itemRemovedFolder = folder;
this._itemRemovedIndex = index;
},
onItemChanged: function(id, uri, property, value) {
onItemChanged: function(id, property, isAnnotationProperty, value) {
this._itemChangedId = id;
this._itemChanged = uri;
this._itemChangedProperty = property;
this._itemChanged_isAnnotationProperty = isAnnotationProperty;
this._itemChangedValue = value;
},
onItemVisited: function(uri, visitID, time) {
this._itemVisited = uri;
this._itemVisitedID = visitID;
onItemVisited: function(id, visitID, time) {
this._itemVisitedId = id;
this._itemVisitedVistId = visitID;
this._itemVisitedTime = time;
},
onFolderAdded: function(folder, parent, index) {
@ -151,14 +156,13 @@ function run_test() {
// insert a bookmark
var newId = bmsvc.insertItem(testRoot, uri("http://google.com/"), bmsvc.DEFAULT_INDEX);
do_check_eq(observer._itemAddedId, newId);
do_check_eq(observer._itemAdded.spec, "http://google.com/");
do_check_eq(observer._itemAddedFolder, testRoot);
do_check_eq(observer._itemAddedIndex, testStartIndex);
do_check_eq(bmsvc.getBookmarkURI(newId).spec, "http://google.com/");
// set bookmark title
bmsvc.setItemTitle(newId, "Google");
do_check_eq(observer._itemChangedId, newId);
do_check_eq(observer._itemChanged.spec, "http://google.com/");
do_check_eq(observer._itemChangedProperty, "title");
do_check_eq(observer._itemChangedValue, "Google");
@ -196,38 +200,32 @@ function run_test() {
// add item into subfolder, specifying index
var newId2 = bmsvc.insertItem(workFolder, uri("http://developer.mozilla.org/"), 0);
do_check_eq(observer._itemAddedId, newId2);
do_check_eq(observer._itemAdded.spec, "http://developer.mozilla.org/");
do_check_eq(observer._itemAddedFolder, workFolder);
do_check_eq(observer._itemAddedIndex, 0);
// change item
bmsvc.setItemTitle(newId2, "DevMo");
do_check_eq(observer._itemChanged.spec, "http://developer.mozilla.org/");
do_check_eq(observer._itemChangedProperty, "title");
// insert item into subfolder
var newId3 = bmsvc.insertItem(workFolder, uri("http://msdn.microsoft.com/"), bmsvc.DEFAULT_INDEX);
do_check_eq(observer._itemAddedId, newId3);
do_check_eq(observer._itemAdded.spec, "http://msdn.microsoft.com/");
do_check_eq(observer._itemAddedFolder, workFolder);
do_check_eq(observer._itemAddedIndex, 1);
// change item
bmsvc.setItemTitle(newId3, "MSDN");
do_check_eq(observer._itemChanged.spec, "http://msdn.microsoft.com/");
do_check_eq(observer._itemChangedProperty, "title");
// remove item
bmsvc.removeItem(newId2);
do_check_eq(observer._itemRemovedId, newId2);
do_check_eq(observer._itemRemoved.spec, "http://developer.mozilla.org/");
do_check_eq(observer._itemRemovedFolder, workFolder);
do_check_eq(observer._itemRemovedIndex, 0);
// insert item into subfolder
var newId4 = bmsvc.insertItem(workFolder, uri("http://developer.mozilla.org/"), bmsvc.DEFAULT_INDEX);
do_check_eq(observer._itemAddedId, newId4);
do_check_eq(observer._itemAdded.spec, "http://developer.mozilla.org/");
do_check_eq(observer._itemAddedFolder, workFolder);
do_check_eq(observer._itemAddedIndex, 1);
@ -240,24 +238,21 @@ function run_test() {
// insert item
var newId5 = bmsvc.insertItem(homeFolder, uri("http://espn.com/"), bmsvc.DEFAULT_INDEX);
do_check_eq(observer._itemAddedId, newId5);
do_check_eq(observer._itemAdded.spec, "http://espn.com/");
do_check_eq(observer._itemAddedFolder, homeFolder);
do_check_eq(observer._itemAddedIndex, 0);
// change item
bmsvc.setItemTitle(newId5, "ESPN");
do_check_eq(observer._itemChanged.spec, "http://espn.com/");
do_check_eq(observer._itemChangedId, newId5);
do_check_eq(observer._itemChangedProperty, "title");
// insert query item
var newId6 = bmsvc.insertItem(testRoot, uri("place:domain=google.com&group=1"), bmsvc.DEFAULT_INDEX);
do_check_eq(observer._itemAdded.spec, "place:domain=google.com&group=1");
do_check_eq(observer._itemAddedFolder, testRoot);
do_check_eq(observer._itemAddedIndex, 3);
// change item
bmsvc.setItemTitle(newId6, "Google Sites");
do_check_eq(observer._itemChanged.spec, "place:domain=google.com&group=1");
do_check_eq(observer._itemChangedProperty, "title");
// move folder, appending, to different folder
@ -396,9 +391,9 @@ function run_test() {
for (var i=0; i < cc; ++i) {
var node = rootNode.getChild(i);
if (node.type == node.RESULT_TYPE_FOLDER)
do_check_eq(node.bookmarkId, -1);
do_check_eq(node.itemId, -1);
else
do_check_true(node.bookmarkId > 0);
do_check_true(node.itemId > 0);
}
rootNode.containerOpen = false;
}
@ -441,9 +436,8 @@ function run_test() {
var newId10 = bmsvc.insertItem(testRoot, uri("http://foo10.com/"), bmsvc.DEFAULT_INDEX);
bmsvc.changeBookmarkURI(newId10, uri("http://foo11.com/"));
do_check_eq(observer._itemChangedId, newId10);
do_check_eq(observer._itemChanged.spec, "http://foo11.com/");
do_check_eq(observer._itemChangedProperty, "uri");
do_check_eq(observer._itemChangedValue, "");
do_check_eq(observer._itemChangedValue, "http://foo11.com/");
// test getBookmarkURI
var newId11 = bmsvc.insertItem(testRoot, uri("http://foo11.com/"), bmsvc.DEFAULT_INDEX);
@ -467,7 +461,6 @@ function run_test() {
bmsvc.toolbarFolder = newToolbarFolderId;
do_check_eq(bmsvc.toolbarFolder, newToolbarFolderId);
do_check_eq(observer._itemChangedId, newToolbarFolderId);
do_check_eq(observer._itemChanged.spec, bmsvc.getFolderURI(newToolbarFolderId).spec);
do_check_eq(observer._itemChangedProperty, "became_toolbar_folder");
do_check_eq(observer._itemChangedValue, "");
@ -477,17 +470,23 @@ function run_test() {
// see bug #369887 for more details
var newId13 = bmsvc.insertItem(testRoot, uri("http://foobarcheese.com/"), bmsvc.DEFAULT_INDEX);
do_check_eq(observer._itemAddedId, newId13);
do_check_eq(observer._itemAdded.spec, "http://foobarcheese.com/");
do_check_eq(observer._itemAddedFolder, testRoot);
do_check_eq(observer._itemAddedIndex, 13);
// set bookmark title
bmsvc.setItemTitle(newId13, "ZZZXXXYYY");
do_check_eq(observer._itemChangedId, newId13);
do_check_eq(observer._itemChanged.spec, "http://foobarcheese.com/");
do_check_eq(observer._itemChangedProperty, "title");
do_check_eq(observer._itemChangedValue, "ZZZXXXYYY");
// check if setting an item annotation triggers onItemChanged
observer._itemChangedId = -1;
annosvc.setItemAnnotationString(newId3, "test-annotation", "foo", 0, 0);
do_check_eq(observer._itemChangedId, newId3);
do_check_eq(observer._itemChangedProperty, "test-annotation");
do_check_true(observer._itemChanged_isAnnotationProperty);
do_check_eq(observer._itemChangedValue, "");
// test search on bookmark title ZZZXXXYYY
try {
var options = histsvc.getNewQueryOptions();
@ -503,13 +502,18 @@ function run_test() {
do_check_eq(cc, 1);
var node = rootNode.getChild(0);
do_check_eq(node.title, "ZZZXXXYYY");
do_check_true(node.bookmarkId > 0);
do_check_true(node.itemId > 0);
rootNode.containerOpen = false;
}
catch(ex) {
do_throw("bookmarks query: " + ex);
}
// ensure that removing an item removes its annotations
do_check_true(annosvc.itemHasAnnotation(newId3, "test-annotation"));
bmsvc.removeItem(newId3);
do_check_false(annosvc.itemHasAnnotation(newId3, "test-annotation"));
// bug 378820
var uri1 = uri("http://foo.tld/a");
bmsvc.insertItem(testRoot, uri1, bmsvc.DEFAULT_INDEX);

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

@ -62,7 +62,7 @@ var observer =
onEndUpdateBatch: function(){},
onItemAdded: function(bookmarkId, bookmark, folder, index) {},
onItemRemoved: function(bookmarkId, bookmark, folder, index){},
onItemChanged: function(bookmarkId, bookmark, property, value){
onItemChanged: function(bookmarkId, property, isAnnotationProperty, value){
runTest();
bmsvc.removeObserver(this);
},
@ -93,7 +93,7 @@ function runTest() {
for (var i=0; i < cc; ++i) {
var node = rootNode.getChild(i);
// test that bm1 does not have new title
if (node.bookmarkId == bm1)
if (node.itemId == bm1)
ok(node.title != newTitle,
"Changing a bookmark's title did not affect the title of other bookmarks with the same URI");
}

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

@ -49,16 +49,16 @@ var observer =
// nsINavBookmarkObserve
onBeginUpdateBatch: function(){},
onEndUpdateBatch: function(){},
onItemAdded: function(bookmarkId, bookmark, folder, index) {
if (bookmark.spec == "http://example.org/2003/12/13/atom03") {
onItemAdded: function(itemId, folder, index) {
if (bmsvc.getBookmarkURI(itemId).spec == "http://example.org/2003/12/13/atom03") {
is(folder, gLivemarkId, "Livemark added to correct folder");
this._lastBookmarkId = bookmarkId;
this._lastBookmarkId = itemId;
bmsvc.removeObserver(this);
}
},
onItemRemoved: function(bookmarkId, bookmark, folder, index){},
onItemChanged: function(bookmarkId, bookmark, property, value){},
onItemVisited: function(bookmarkId, bookmark, aVisitID, time){},
onItemRemoved: function(itemId, folder, index){},
onItemChanged: function(itemId, property, isAnnotationProperty, value){},
onItemVisited: function(itemId, aVisitID, time){},
onFolderAdded: function(folder, parent, index){},
onFolderRemoved: function(folder, parent, index){},
onFolderMoved: function(folder, oldParent, oldIndex, newParent, newIndex){},
@ -67,18 +67,20 @@ var observer =
onSeparatorRemoved: function(parent, index){},
// nsIAnnotationObserver
onAnnotationSet: function(uri, name) {
if (name == "livemark/bookmarkFeedURI") {
onItemAnnotationSet: function(aItemId, aAnnotationName) {
if (aAnnotationName == "livemark/bookmarkFeedURI") {
ok("_lastBookmarkId" in this,
"Unexpected livemark/bookmarkFeedURI annotation set");
var placeURI = bmsvc.getItemURI(this._lastBookmarkId);
ok(placeURI.equals(uri),
"livemark/bookmarkFeedURI annotation set on the wrong URI");
ok(this._lastBookmarkId == aItemId,
"livemark/bookmarkFeedURI annotation set on the wrong item");
annosvc.removeObserver(this);
SimpleTest.finish();
}
},
onAnnotationRemoved: function(uri, name) { }
onItemAnnotationRemoved: function(aItemId, aAnnotationName) { },
onPageAnnotationSet: function(uri, name) { },
onPageAnnotationRemoved: function(uri, name) { }
};
var root = bmsvc.bookmarksRoot;

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

@ -22,6 +22,7 @@
* Contributor(s):
* Darin Fisher <darin@meer.net>
* Dietrich Ayala <dietrich@mozilla.com>
* Asaf Romano <mano@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -42,42 +43,123 @@ try {
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].getService(Ci.nsINavHistoryService);
} catch(ex) {
do_throw("Could not get history service\n");
}
}
// Get bookmark service
try {
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
} catch(ex) {
do_throw("Could not get nav-bookmarks-service\n");
}
// Get annotation service
try {
var annosvc= Cc["@mozilla.org/browser/annotation-service;1"].getService(Ci.nsIAnnotationService);
} catch(ex) {
do_throw("Could not get annotation service\n");
}
}
var annoObserver = {
PAGE_lastSet_URI: "",
PAGE_lastSet_AnnoName: "",
onPageAnnotationSet: function(aURI, aName) {
this.PAGE_lastSet_URI = aURI.spec;
this.PAGE_lastSet_AnnoName = aName;
},
ITEM_lastSet_Id: -1,
ITEM_lastSet_AnnoName: "",
onItemAnnotationSet: function(aItemId, aName) {
this.ITEM_lastSet_Id = aItemId;
this.ITEM_lastSet_AnnoName = aName;
},
PAGE_lastRemoved_URI: "",
PAGE_lastRemoved_AnnoName: "",
onPageAnnotationRemoved: function(aURI, aName) {
this.PAGE_lastRemoved_URI = aURI.spec;
this.PAGE_lastRemoved_AnnoName = aName;
},
ITEM_lastRemoved_Id: -1,
ITEM_lastRemoved_AnnoName: "",
onItemAnnotationRemoved: function(aItemId, aName) {
this.ITEM_lastRemoved_Id = aItemId;
this.ITEM_lastRemoved_AnnoName = aName;
}
};
// main
function run_test() {
// test URI
var testURI = uri("http://mozilla.com/");
var testItemId = bmsvc.insertItem(bmsvc.bookmarksRoot, testURI, -1);
var testAnnoName = "moz-test-places/annotations";
var testAnnoVal = "test";
annosvc.addObserver(annoObserver);
// create new string annotation
try {
annosvc.setAnnotationString(testURI, testAnnoName, testAnnoVal, 0, 0);
annosvc.setPageAnnotationString(testURI, testAnnoName, testAnnoVal, 0, 0);
} catch(ex) {
do_throw("unable to add annotation");
do_throw("unable to add page-annotation");
}
do_check_eq(annoObserver.PAGE_lastSet_URI, testURI.spec);
do_check_eq(annoObserver.PAGE_lastSet_AnnoName, testAnnoName);
// get string annotation
var storedAnnoVal = annosvc.getAnnotationString(testURI, testAnnoName);
do_check_true(annosvc.pageHasAnnotation(testURI, testAnnoName));
var storedAnnoVal = annosvc.getPageAnnotationString(testURI, testAnnoName);
do_check_eq(testAnnoVal, storedAnnoVal);
// string item-annotation
try {
annosvc.setItemAnnotationString(testItemId, testAnnoName, testAnnoVal, 0, 0);
} catch(ex) {
do_throw("unable to add item annotation");
}
do_check_eq(annoObserver.ITEM_lastSet_Id, testItemId);
do_check_eq(annoObserver.ITEM_lastSet_AnnoName, testAnnoName);
// test getPagesWithAnnotation
var uri2 = uri("http://www.tests.tld");
annosvc.setPageAnnotationString(uri2, testAnnoName, testAnnoVal, 0, 0);
var pages = annosvc.getPagesWithAnnotation(testAnnoName, { });
do_check_eq(pages.length, 2);
// Don't rely on the order
do_check_false(pages[0].equals(pages[1]));
do_check_true(pages[0].equals(testURI) || pages[1].equals(testURI));
do_check_true(pages[0].equals(uri2) || pages[1].equals(uri2));
// test getItemsWithAnnotation
var testItemId2 = bmsvc.insertItem(bmsvc.bookmarksRoot, uri2, -1);
annosvc.setItemAnnotationString(testItemId2, testAnnoName, testAnnoVal, 0, 0);
var items = annosvc.getItemsWithAnnotation(testAnnoName, { });
do_check_eq(items.length, 2);
// Don't rely on the order
do_check_true(items[0] != items[1]);
do_check_true(items[0] == testItemId || items[1] == testItemId);
do_check_true(items[0] == testItemId2 || items[1] == testItemId2);
// get annotation that doesn't exist
try {
annosvc.getAnnotationString(testURI, "blah");
do_throw("fetching annotation that doesn't exist, should've thrown");
annosvc.getPageAnnotationString(testURI, "blah");
do_throw("fetching page-annotation that doesn't exist, should've thrown");
} catch(ex) {}
try {
annosvc.getItemAnnotationString(testURI, "blah");
do_throw("fetching item-annotation that doesn't exist, should've thrown");
} catch(ex) {}
// get annotation info
var flags = {}, exp = {}, mimeType = {}, storageType = {};
annosvc.getAnnotationInfo(testURI, testAnnoName, flags, exp, mimeType, storageType);
annosvc.getPageAnnotationInfo(testURI, testAnnoName, flags, exp, mimeType, storageType);
do_check_eq(flags.value, 0);
do_check_eq(exp.value, 0);
do_check_eq(mimeType.value, null);
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_STRING);
annosvc.getItemAnnotationInfo(testItemId, testAnnoName, flags, exp, mimeType, storageType);
do_check_eq(flags.value, 0);
do_check_eq(exp.value, 0);
do_check_eq(mimeType.value, null);
@ -88,6 +170,11 @@ function run_test() {
do_check_eq(annoNames.length, 1);
do_check_eq(annoNames[0], "moz-test-places/annotations");
// get annotation names for an item
var annoNames = annosvc.getItemAnnotationNames(testItemId, {});
do_check_eq(annoNames.length, 1);
do_check_eq(annoNames[0], "moz-test-places/annotations");
/* copy annotations to another uri
var newURI = uri("http://mozilla.org");
var oldAnnoNames = annosvc.getPageAnnotationNames(testURI, {});
@ -99,84 +186,143 @@ function run_test() {
// test int32 anno type
var int32Key = testAnnoName + "/types/Int32";
var int32Val = 23;
annosvc.setAnnotationInt32(testURI, int32Key, int32Val, 0, 0);
annosvc.setPageAnnotationInt32(testURI, int32Key, int32Val, 0, 0);
do_check_true(annosvc.pageHasAnnotation(testURI, int32Key));
var flags = {}, exp = {}, mimeType = {}, storageType = {};
annosvc.getAnnotationInfo(testURI, int32Key, flags, exp, mimeType, storageType);
annosvc.getPageAnnotationInfo(testURI, int32Key, flags, exp, mimeType,
storageType);
do_check_eq(flags.value, 0);
do_check_eq(exp.value, 0);
do_check_eq(mimeType.value, null);
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_INT32);
var storedVal = annosvc.getAnnotationInt32(testURI, int32Key);
do_check_eq(int32Val, storedVal);
do_check_eq(typeof storedVal, "number");
var storedVal = annosvc.getPageAnnotationInt32(testURI, int32Key);
do_check_true(int32Val === storedVal);
annosvc.setItemAnnotationInt32(testItemId, int32Key, int32Val, 0, 0);
do_check_true(annosvc.itemHasAnnotation(testItemId, int32Key));
annosvc.getItemAnnotationInfo(testItemId, int32Key, flags, exp, mimeType,
storageType);
do_check_eq(flags.value, 0);
do_check_eq(exp.value, 0);
do_check_eq(mimeType.value, null);
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_INT32);
storedVal = annosvc.getItemAnnotationInt32(testItemId, int32Key);
do_check_true(int32Val === storedVal);
// test int64 anno type
var int64Key = testAnnoName + "/types/Int64";
var int64Val = 4294967296;
annosvc.setAnnotationInt64(testURI, int64Key, int64Val, 0, 0);
var flags = {}, exp = {}, mimeType = {}, storageType = {};
annosvc.getAnnotationInfo(testURI, int64Key, flags, exp, mimeType, storageType);
annosvc.setPageAnnotationInt64(testURI, int64Key, int64Val, 0, 0);
annosvc.getPageAnnotationInfo(testURI, int64Key, flags, exp, mimeType, storageType);
do_check_eq(flags.value, 0);
do_check_eq(exp.value, 0);
do_check_eq(mimeType.value, null);
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_INT64);
var storedVal = annosvc.getAnnotationInt64(testURI, int64Key);
do_check_eq(int64Val, storedVal);
do_check_eq(typeof storedVal, "number");
storedVal = annosvc.getPageAnnotationInt64(testURI, int64Key);
do_check_true(int64Val === storedVal);
annosvc.setItemAnnotationInt64(testItemId, int64Key, int64Val, 0, 0);
do_check_true(annosvc.itemHasAnnotation(testItemId, int64Key));
annosvc.getItemAnnotationInfo(testItemId, int64Key, flags, exp, mimeType,
storageType);
do_check_eq(flags.value, 0);
do_check_eq(exp.value, 0);
do_check_eq(mimeType.value, null);
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_INT64);
storedVal = annosvc.getItemAnnotationInt64(testItemId, int64Key);
do_check_true(int64Val === storedVal);
// test double anno type
var doubleKey = testAnnoName + "/types/Double";
var doubleVal = 0.000002342;
annosvc.setAnnotationDouble(testURI, doubleKey, doubleVal, 0, 0);
var flags = {}, exp = {}, mimeType = {}, storageType = {};
annosvc.getAnnotationInfo(testURI, doubleKey, flags, exp, mimeType, storageType);
annosvc.setPageAnnotationDouble(testURI, doubleKey, doubleVal, 0, 0);
annosvc.getPageAnnotationInfo(testURI, doubleKey, flags, exp, mimeType, storageType);
do_check_eq(flags.value, 0);
do_check_eq(exp.value, 0);
do_check_eq(mimeType.value, null);
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_DOUBLE);
var storedVal = annosvc.getAnnotationDouble(testURI, doubleKey);
do_check_eq(doubleVal, storedVal);
do_check_true(Math.round(storedVal) != storedVal);
storedVal = annosvc.getPageAnnotationDouble(testURI, doubleKey);
do_check_true(doubleVal === storedVal);
annosvc.setItemAnnotationDouble(testItemId, doubleKey, doubleVal, 0, 0);
do_check_true(annosvc.itemHasAnnotation(testItemId, doubleKey));
annosvc.getItemAnnotationInfo(testItemId, doubleKey, flags, exp, mimeType,
storageType);
do_check_eq(flags.value, 0);
do_check_eq(exp.value, 0);
do_check_eq(mimeType.value, null);
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_DOUBLE);
storedVal = annosvc.getItemAnnotationDouble(testItemId, doubleKey);
do_check_true(doubleVal === storedVal);
// test binary anno type
var binaryKey = testAnnoName + "/types/Binary";
var binaryVal = Array.prototype.map.call("splarg", function(x) { return x.charCodeAt(0); });
annosvc.setAnnotationBinary(testURI, binaryKey, binaryVal, binaryVal.length, "text/plain", 0, 0);
var flags = {}, exp = {}, mimeType = {}, storageType = {};
annosvc.getAnnotationInfo(testURI, binaryKey, flags, exp, mimeType, storageType);
annosvc.setPageAnnotationBinary(testURI, binaryKey, binaryVal, binaryVal.length, "text/plain", 0, 0);
annosvc.getPageAnnotationInfo(testURI, binaryKey, flags, exp, mimeType, storageType);
do_check_eq(flags.value, 0);
do_check_eq(exp.value, 0);
do_check_eq(mimeType.value, "text/plain");
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_BINARY);
var data = {}, length = {}, mimeType = {};
annosvc.getAnnotationBinary(testURI, binaryKey, data, length, mimeType);
var data = {}, length = {};
annosvc.getPageAnnotationBinary(testURI, binaryKey, data, length, mimeType);
do_check_eq(binaryVal.toString(), data.value.toString());
do_check_eq(typeof data.value, "object");
annosvc.setItemAnnotationBinary(testItemId, binaryKey, binaryVal,
binaryVal.length, "text/plain", 0, 0);
annosvc.getItemAnnotationInfo(testItemId, binaryKey, flags, exp, mimeType,
storageType);
do_check_eq(flags.value, 0);
do_check_eq(exp.value, 0);
do_check_eq(mimeType.value, "text/plain");
do_check_eq(storageType.value, Ci.nsIAnnotationService.TYPE_BINARY);
annosvc.getItemAnnotationBinary(testItemId, binaryKey, data, length,
mimeType);
do_check_eq(binaryVal.toString(), data.value.toString());
do_check_eq(typeof data.value, "object");
// test that accessors throw for wrong types
try {
annosvc.getAnnotationString(testURI, int32Key);
do_throw("annotation string accessor didn't throw for a wrong type!");
annosvc.getPageAnnotationString(testURI, int32Key);
do_throw("page-annotation string accessor didn't throw for a wrong type!");
annosvc.getItemAnnotationString(testItemId, int32Key);
do_throw("item-annotation string accessor didn't throw for a wrong type!");
} catch(ex) {}
try {
annosvc.getAnnotationInt32(testURI, int64Key);
do_throw("annotation int32 accessor didn't throw for a wrong type!");
annosvc.getPageAnnotationInt32(testURI, int64Key);
do_throw("page-annotation int32 accessor didn't throw for a wrong type!");
annosvc.getItemAnnotationInt32(testItemId, int64Key);
do_throw("item-annotation int32 accessor didn't throw for a wrong type!");
} catch(ex) {}
try {
annosvc.getAnnotationInt64(testURI, int32Key);
do_throw("annotation int64 accessor didn't throw for a wrong type!");
annosvc.getPageAnnotationInt64(testURI, int32Key);
do_throw("page-annotation int64 accessor didn't throw for a wrong type!");
annosvc.getItemAnnotationInt64(testItemId, int32Key);
do_throw("item-annotation int64 accessor didn't throw for a wrong type!");
} catch(ex) {}
try {
annosvc.getAnnotationDouble(testURI, int32Key);
do_throw("annotation double accessor didn't throw for a wrong type!");
annosvc.getPageAnnotationDouble(testURI, int32Key);
do_throw("page-annotation double accessor didn't throw for a wrong type!");
annosvc.getItemAnnotationDouble(testItemId, int32Key);
do_throw("item-annotation double accessor didn't throw for a wrong type!");
} catch(ex) {}
try {
var data = {}, length = {}, mimeType = {};
annosvc.getAnnotationBinary(testURI, int32Key, data, length, mimeType);
do_throw("annotation binary accessor didn't throw for a wrong type!");
annosvc.getPageAnnotationBinary(testURI, int32Key, data, length, mimeType);
do_throw("page-annotation binary accessor didn't throw for a wrong type!");
annosvc.getItemAnnotationBinary(testItemId, int32Key, data, length,
mimeType);
do_throw("item-annotation binary accessor didn't throw for a wrong type!");
} catch(ex) {}
// test annotation removal
annosvc.removePageAnnotation(testURI, int32Key);
annosvc.removeItemAnnotation(testItemId, int32Key);
do_check_eq(annoObserver.PAGE_lastRemoved_URI, testURI.spec);
do_check_eq(annoObserver.PAGE_lastRemoved_AnnoName, int32Key);
do_check_eq(annoObserver.ITEM_lastRemoved_Id, testItemId);
do_check_eq(annoObserver.ITEM_lastRemoved_AnnoName, int32Key);
annosvc.removeObserver(annoObserver);
}

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

@ -138,8 +138,8 @@ function run_test() {
// test annotation-based queries
var annos = Cc["@mozilla.org/browser/annotation-service;1"].
getService(Ci.nsIAnnotationService);
annos.setAnnotationInt32(uri("http://mozilla.com/"), "testAnno", 0, 0,
Ci.nsIAnnotationService.EXPIRE_NEVER);
annos.setPageAnnotationInt32(uri("http://mozilla.com/"), "testAnno", 0, 0,
Ci.nsIAnnotationService.EXPIRE_NEVER);
query.annotation = "testAnno";
result = histsvc.executeQuery(query, options);
result.root.containerOpen = true;

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

@ -100,9 +100,9 @@ function run_test() {
const NHQO = Ci.nsINavHistoryQueryOptions;
function checkOrder(a, b, c) {
do_check_eq(root.getChild(0).bookmarkId, a);
do_check_eq(root.getChild(1).bookmarkId, b);
do_check_eq(root.getChild(2).bookmarkId, c);
do_check_eq(root.getChild(0).itemId, a);
do_check_eq(root.getChild(1).itemId, b);
do_check_eq(root.getChild(2).itemId, c);
}
// natural order
@ -128,20 +128,17 @@ function run_test() {
// XXXtodo: test history sortings (visit count, visit date)
// XXXtodo: test different item types once folderId and bookmarkId are merged.
// XXXtodo: test sortingAnnotation functionality with non-bookmark nodes
annosvc.setAnnotationString(bmsvc.getItemURI(id1), "testAnno", "a", 0, 0);
annosvc.setAnnotationString(bmsvc.getItemURI(id3), "testAnno", "b", 0, 0);
annosvc.setItemAnnotationString(id1, "testAnno", "a", 0, 0);
annosvc.setItemAnnotationString(id3, "testAnno", "b", 0, 0);
result.sortingAnnotation = "testAnno";
result.sortingMode = NHQO.SORT_BY_ANNOTATION_DESCENDING;
// id1 precedes id2 per title-descending fallback
checkOrder(id3, id1, id2);
// different annotation types, we fall back to the title sorting route
annosvc.setAnnotationInt32(bmsvc.getItemURI(id3), "testAnno", 10, 0, 0);
// XXXtodo: test live update for sortingAnnotation (not yet implemented);
// manually force sort for now...
result.sortingMode = result.sortingMode;
checkOrder(id1, id2, id3);
// test live update
annosvc.setItemAnnotationString(id1, "testAnno", "c", 0, 0);
checkOrder(id1, id3, id2);
}