--- a/toolkit/components/places/BookmarkHTMLUtils.jsm
+++ b/toolkit/components/places/BookmarkHTMLUtils.jsm
@@ -309,16 +309,20 @@ function Frame(aFrameId) {
* Used to override the values set by insertBookmark, createFolder, etc.
*/
this.previousDateAdded = 0;
this.previousLastModifiedDate = 0;
}
function BookmarkImporter(aInitialImport) {
this._isImportDefaults = aInitialImport;
+ // The bookmark change source, used to determine the sync status and change
+ // counter.
+ this._source = aInitialImport ? PlacesUtils.bookmarks.SOURCE_IMPORT_REPLACE :
+ PlacesUtils.bookmarks.SOURCE_IMPORT;
this._frames = new Array();
this._frames.push(new Frame(PlacesUtils.bookmarksMenuFolderId));
}
BookmarkImporter.prototype = {
_safeTrim: function safeTrim(aStr) {
return aStr ? aStr.trim() : aStr;
@@ -344,17 +348,18 @@ BookmarkImporter.prototype = {
let containerType = frame.lastContainerType;
switch (containerType) {
case Container_Normal:
// append a new folder
containerId =
PlacesUtils.bookmarks.createFolder(frame.containerId,
containerTitle,
- PlacesUtils.bookmarks.DEFAULT_INDEX);
+ PlacesUtils.bookmarks.DEFAULT_INDEX,
+ /* aGuid */ null, this._source);
break;
case Container_Places:
containerId = PlacesUtils.placesRootId;
break;
case Container_Menu:
containerId = PlacesUtils.bookmarksMenuFolderId;
break;
case Container_Unfiled:
@@ -365,24 +370,24 @@ BookmarkImporter.prototype = {
break;
default:
// NOT REACHED
throw new Error("Unreached");
}
if (frame.previousDateAdded > 0) {
try {
- PlacesUtils.bookmarks.setItemDateAdded(containerId, frame.previousDateAdded);
+ PlacesUtils.bookmarks.setItemDateAdded(containerId, frame.previousDateAdded, this._source);
} catch (e) {
}
frame.previousDateAdded = 0;
}
if (frame.previousLastModifiedDate > 0) {
try {
- PlacesUtils.bookmarks.setItemLastModified(containerId, frame.previousLastModifiedDate);
+ PlacesUtils.bookmarks.setItemLastModified(containerId, frame.previousLastModifiedDate, this._source);
} catch (e) {
}
// don't clear last-modified, in case there's a description
}
frame.previousId = containerId;
this._frames.push(new Frame(containerId));
@@ -396,17 +401,19 @@ BookmarkImporter.prototype = {
* We also don't import ADD_DATE or LAST_MODIFIED for separators because
* pre-Places bookmarks did not support them.
*/
_handleSeparator: function handleSeparator(aElt) {
let frame = this._curFrame;
try {
frame.previousId =
PlacesUtils.bookmarks.insertSeparator(frame.containerId,
- PlacesUtils.bookmarks.DEFAULT_INDEX);
+ PlacesUtils.bookmarks.DEFAULT_INDEX,
+ /* aGuid */ null,
+ this._source);
} catch (e) {}
},
/**
* Handles <H1>. We check for the attribute PLACES_ROOT and reset the
* container id if it's found. Otherwise, the default bookmark menu
* root is assumed and imported things will go into the bookmarks menu.
*/
@@ -559,35 +566,37 @@ BookmarkImporter.prototype = {
}
// Create the bookmark. The title is unknown for now, we will set it later.
try {
frame.previousId =
PlacesUtils.bookmarks.insertBookmark(frame.containerId,
frame.previousLink,
PlacesUtils.bookmarks.DEFAULT_INDEX,
- "");
+ /* aTitle */ "",
+ /* aGuid */ null,
+ this._source);
} catch (e) {
return;
}
// Set the date added value, if we have it.
if (dateAdded) {
try {
PlacesUtils.bookmarks.setItemDateAdded(frame.previousId,
- this._convertImportedDateToInternalDate(dateAdded));
+ this._convertImportedDateToInternalDate(dateAdded), this._source);
} catch (e) {
}
}
// Adds tags to the URI, if there are any.
if (tags) {
try {
let tagsArray = tags.split(",");
- PlacesUtils.tagging.tagURI(frame.previousLink, tagsArray);
+ PlacesUtils.tagging.tagURI(frame.previousLink, tagsArray, this._source);
} catch (e) {
}
}
// Save the favicon.
if (icon || iconUri) {
let iconUriObject;
try {
@@ -601,35 +610,37 @@ BookmarkImporter.prototype = {
}
}
}
// Save the keyword.
if (keyword) {
let kwPromise = PlacesUtils.keywords.insert({ keyword,
url: frame.previousLink.spec,
- postData });
+ postData,
+ source: this._source });
this._importPromises.push(kwPromise);
}
// Set load-in-sidebar annotation for the bookmark.
if (webPanel && webPanel.toLowerCase() == "true") {
try {
PlacesUtils.annotations.setItemAnnotation(frame.previousId,
LOAD_IN_SIDEBAR_ANNO,
1,
0,
- PlacesUtils.annotations.EXPIRE_NEVER);
+ PlacesUtils.annotations.EXPIRE_NEVER,
+ this._source);
} catch (e) {
}
}
// Import last charset.
if (lastCharset) {
- let chPromise = PlacesUtils.setCharsetForURI(frame.previousLink, lastCharset);
+ let chPromise = PlacesUtils.setCharsetForURI(frame.previousLink, lastCharset, this._source);
this._importPromises.push(chPromise);
}
},
_handleContainerBegin: function handleContainerBegin() {
this._curFrame.containerNesting++;
},
@@ -643,17 +654,18 @@ BookmarkImporter.prototype = {
if (frame.containerNesting > 0)
frame.containerNesting --;
if (this._frames.length > 1 && frame.containerNesting == 0) {
// we also need to re-set the imported last-modified date here. Otherwise
// the addition of items will override the imported field.
let prevFrame = this._previousFrame;
if (prevFrame.previousLastModifiedDate > 0) {
PlacesUtils.bookmarks.setItemLastModified(frame.containerId,
- prevFrame.previousLastModifiedDate);
+ prevFrame.previousLastModifiedDate,
+ this._source);
}
this._frames.pop();
}
},
/**
* Creates the new frame for this heading now that we know the name of the
* container (tokens since the heading open tag will have been placed in
@@ -675,32 +687,35 @@ BookmarkImporter.prototype = {
// The is a live bookmark. We create it here since in HandleLinkBegin we
// don't know the title.
let lmPromise = PlacesUtils.livemarks.addLivemark({
"title": frame.previousText,
"parentId": frame.containerId,
"index": PlacesUtils.bookmarks.DEFAULT_INDEX,
"feedURI": frame.previousFeed,
"siteURI": frame.previousLink,
+ "source": this._source,
});
this._importPromises.push(lmPromise);
} else if (frame.previousLink) {
// This is a common bookmark.
PlacesUtils.bookmarks.setItemTitle(frame.previousId,
- frame.previousText);
+ frame.previousText,
+ this._source);
}
} catch (e) {
}
// Set last modified date as the last change.
if (frame.previousId > 0 && frame.previousLastModifiedDate > 0) {
try {
PlacesUtils.bookmarks.setItemLastModified(frame.previousId,
- frame.previousLastModifiedDate);
+ frame.previousLastModifiedDate,
+ this._source);
} catch (e) {
}
// Note: don't clear previousLastModifiedDate, because if this item has a
// description, we'll need to set it again.
}
frame.previousText = "";
@@ -753,17 +768,18 @@ BookmarkImporter.prototype = {
: frame.previousId;
try {
if (!PlacesUtils.annotations.itemHasAnnotation(itemId, DESCRIPTION_ANNO)) {
PlacesUtils.annotations.setItemAnnotation(itemId,
DESCRIPTION_ANNO,
frame.previousText,
0,
- PlacesUtils.annotations.EXPIRE_NEVER);
+ PlacesUtils.annotations.EXPIRE_NEVER,
+ this._source);
}
} catch (e) {
}
frame.previousText = "";
// Set last-modified a 2nd time for all items with descriptions
// we need to set last-modified as the *last* step in processing
// any item type in the bookmarks.html file, so that we do
@@ -778,17 +794,18 @@ BookmarkImporter.prototype = {
let lastModified;
if (!frame.previousLink) {
lastModified = this._previousFrame.previousLastModifiedDate;
} else {
lastModified = frame.previousLastModifiedDate;
}
if (itemId > 0 && lastModified > 0) {
- PlacesUtils.bookmarks.setItemLastModified(itemId, lastModified);
+ PlacesUtils.bookmarks.setItemLastModified(itemId, lastModified,
+ this._source);
}
}
frame.inDescription = false;
}
if (aElt.namespaceURI != "http://www.w3.org/1999/xhtml") {
return;
}
@@ -889,19 +906,19 @@ BookmarkImporter.prototype = {
},
runBatched: function runBatched(aDoc) {
if (!aDoc) {
return;
}
if (this._isImportDefaults) {
- PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarksMenuFolderId);
- PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.toolbarFolderId);
- PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
+ PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarksMenuFolderId, this._source);
+ PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.toolbarFolderId, this._source);
+ PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId, this._source);
}
let current = aDoc;
let next;
for (;;) {
switch (current.nodeType) {
case Ci.nsIDOMNode.ELEMENT_NODE:
this._openContainer(current);
--- a/toolkit/components/places/BookmarkJSONUtils.jsm
+++ b/toolkit/components/places/BookmarkJSONUtils.jsm
@@ -171,16 +171,20 @@ this.BookmarkJSONUtils = Object.freeze({
yield OS.File.writeAtomic(aFilePath, jsonString, writeOptions);
return { count: count, hash: hash };
});
}
});
function BookmarkImporter(aReplace) {
this._replace = aReplace;
+ // The bookmark change source, used to determine the sync status and change
+ // counter.
+ this._source = aReplace ? PlacesUtils.bookmarks.SOURCE_IMPORT_REPLACE :
+ PlacesUtils.bookmarks.SOURCE_IMPORT;
}
BookmarkImporter.prototype = {
/**
* Import bookmarks from a url.
*
* @param aSpec
* url of the bookmark data.
*
@@ -283,19 +287,20 @@ BookmarkImporter.prototype = {
childIds.push(childId);
}
}
root.containerOpen = false;
for (let i = 0; i < childIds.length; i++) {
let rootItemId = childIds[i];
if (PlacesUtils.isRootItem(rootItemId)) {
- PlacesUtils.bookmarks.removeFolderChildren(rootItemId);
+ PlacesUtils.bookmarks.removeFolderChildren(rootItemId,
+ this._source);
} else {
- PlacesUtils.bookmarks.removeItem(rootItemId);
+ PlacesUtils.bookmarks.removeItem(rootItemId, this._source);
}
}
}
let searchIds = [];
let folderIdMap = [];
for (let node of batch.nodes) {
@@ -336,17 +341,17 @@ BookmarkImporter.prototype = {
}
}
// Fixup imported place: uris that contain folders
searchIds.forEach(function(aId) {
let oldURI = PlacesUtils.bookmarks.getBookmarkURI(aId);
let uri = fixupQuery(oldURI, folderIdMap);
if (!uri.equals(oldURI)) {
- PlacesUtils.bookmarks.changeBookmarkURI(aId, uri);
+ PlacesUtils.bookmarks.changeBookmarkURI(aId, uri, this._source);
}
});
deferred.resolve();
}.bind(this)
};
PlacesUtils.bookmarks.runInBatchMode(batch, null);
@@ -382,17 +387,17 @@ BookmarkImporter.prototype = {
switch (aData.type) {
case PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER:
if (aContainer == PlacesUtils.tagsFolderId) {
// Node is a tag
if (aData.children) {
aData.children.forEach(function(aChild) {
try {
PlacesUtils.tagging.tagURI(
- NetUtil.newURI(aChild.uri), [aData.title]);
+ NetUtil.newURI(aChild.uri), [aData.title], this._source);
} catch (ex) {
// Invalid tag child, skip it
}
});
return [folderIdMap, searchIds];
}
} else if (aData.annos &&
aData.annos.some(anno => anno.name == PlacesUtils.LMANNO_FEEDURI)) {
@@ -415,29 +420,32 @@ BookmarkImporter.prototype = {
if (feedURI) {
let lmPromise = PlacesUtils.livemarks.addLivemark({
title: aData.title,
feedURI: feedURI,
parentId: aContainer,
index: aIndex,
lastModified: aData.lastModified,
siteURI: siteURI,
- guid: aData.guid
- }).then(function (aLivemark) {
+ guid: aData.guid,
+ source: this._source
+ }).then(aLivemark => {
let id = aLivemark.id;
if (aData.dateAdded)
- PlacesUtils.bookmarks.setItemDateAdded(id, aData.dateAdded);
+ PlacesUtils.bookmarks.setItemDateAdded(id, aData.dateAdded,
+ this._source);
if (aData.annos && aData.annos.length)
- PlacesUtils.setAnnotationsForItem(id, aData.annos);
+ PlacesUtils.setAnnotationsForItem(id, aData.annos,
+ this._source);
});
this._importPromises.push(lmPromise);
}
} else {
id = PlacesUtils.bookmarks.createFolder(
- aContainer, aData.title, aIndex, aData.guid);
+ aContainer, aData.title, aIndex, aData.guid, this._source);
folderIdMap[aData.id] = id;
// Process children
if (aData.children) {
for (let i = 0; i < aData.children.length; i++) {
let child = aData.children[i];
let [folders, searches] =
this.importJSONNode(child, id, i, aContainer);
for (let j = 0; j < folders.length; j++) {
@@ -446,35 +454,36 @@ BookmarkImporter.prototype = {
}
searchIds = searchIds.concat(searches);
}
}
}
break;
case PlacesUtils.TYPE_X_MOZ_PLACE:
id = PlacesUtils.bookmarks.insertBookmark(
- aContainer, NetUtil.newURI(aData.uri), aIndex, aData.title, aData.guid);
+ aContainer, NetUtil.newURI(aData.uri), aIndex, aData.title, aData.guid, this._source);
if (aData.keyword) {
// POST data could be set in 2 ways:
// 1. new backups have a postData property
// 2. old backups have an item annotation
let postDataAnno = aData.annos &&
aData.annos.find(anno => anno.name == PlacesUtils.POST_DATA_ANNO);
let postData = aData.postData || (postDataAnno && postDataAnno.value);
let kwPromise = PlacesUtils.keywords.insert({ keyword: aData.keyword,
url: aData.uri,
- postData });
+ postData,
+ source: this._source });
this._importPromises.push(kwPromise);
}
if (aData.tags) {
let tags = aData.tags.split(",").filter(aTag =>
aTag.length <= Ci.nsITaggingService.MAX_TAG_LENGTH);
if (tags.length) {
try {
- PlacesUtils.tagging.tagURI(NetUtil.newURI(aData.uri), tags);
+ PlacesUtils.tagging.tagURI(NetUtil.newURI(aData.uri), tags, this._source);
} catch (ex) {
// Invalid tag child, skip it.
Cu.reportError(`Unable to set tags "${tags.join(", ")}" for ${aData.uri}: ${ex}`);
}
}
}
if (aData.charset) {
PlacesUtils.annotations.setPageAnnotation(
@@ -505,31 +514,33 @@ BookmarkImporter.prototype = {
PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, null,
Services.scriptSecurityManager.getSystemPrincipal());
} catch (ex) {
Components.utils.reportError("Failed to import favicon URI:" + ex);
}
}
break;
case PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR:
- id = PlacesUtils.bookmarks.insertSeparator(aContainer, aIndex, aData.guid);
+ id = PlacesUtils.bookmarks.insertSeparator(aContainer, aIndex, aData.guid, this._source);
break;
default:
// Unknown node type
}
// Set generic properties, valid for all nodes
if (id != -1 && aContainer != PlacesUtils.tagsFolderId &&
aGrandParentId != PlacesUtils.tagsFolderId) {
if (aData.dateAdded)
- PlacesUtils.bookmarks.setItemDateAdded(id, aData.dateAdded);
+ PlacesUtils.bookmarks.setItemDateAdded(id, aData.dateAdded,
+ this._source);
if (aData.lastModified)
- PlacesUtils.bookmarks.setItemLastModified(id, aData.lastModified);
+ PlacesUtils.bookmarks.setItemLastModified(id, aData.lastModified,
+ this._source);
if (aData.annos && aData.annos.length)
- PlacesUtils.setAnnotationsForItem(id, aData.annos);
+ PlacesUtils.setAnnotationsForItem(id, aData.annos, this._source);
}
return [folderIdMap, searchIds];
}
}
function notifyObservers(topic) {
Services.obs.notifyObservers(null, topic, "json");
--- a/toolkit/components/places/Bookmarks.jsm
+++ b/toolkit/components/places/Bookmarks.jsm
@@ -100,16 +100,18 @@ var Bookmarks = Object.freeze({
/**
* Bookmark change source constants, passed as optional properties and
* forwarded to observers. See nsINavBookmarksService.idl for an explanation.
*/
SOURCES: {
DEFAULT: Ci.nsINavBookmarksService.SOURCE_DEFAULT,
SYNC: Ci.nsINavBookmarksService.SOURCE_SYNC,
+ IMPORT: Ci.nsINavBookmarksService.SOURCE_IMPORT,
+ IMPORT_REPLACE: Ci.nsINavBookmarksService.SOURCE_IMPORT_REPLACE,
},
/**
* Special GUIDs associated with bookmark roots.
* It's guaranteed that the roots will always have these guids.
*/
rootGuid: "root________",
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -1060,29 +1060,29 @@ this.PlacesUtils = {
* Annotate an item 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.
* If the value for an annotation is not set it will be removed.
*/
- setAnnotationsForItem: function PU_setAnnotationsForItem(aItemId, aAnnos) {
+ setAnnotationsForItem: function PU_setAnnotationsForItem(aItemId, aAnnos, aSource) {
var annosvc = this.annotations;
aAnnos.forEach(function(anno) {
if (anno.value === undefined || anno.value === null) {
- annosvc.removeItemAnnotation(aItemId, anno.name);
+ annosvc.removeItemAnnotation(aItemId, anno.name, aSource);
}
else {
let flags = ("flags" in anno) ? anno.flags : 0;
let expires = ("expires" in anno) ?
anno.expires : Ci.nsIAnnotationService.EXPIRE_NEVER;
annosvc.setItemAnnotation(aItemId, anno.name, anno.value, flags,
- expires);
+ expires, aSource);
}
});
},
// Identifier getters for special folders.
// You should use these everywhere PlacesUtils is available to avoid XPCOM
// traversal just to get roots' ids.
get placesRootId() {
@@ -2267,17 +2267,17 @@ var Keywords = {
* @return {Promise}
* @resolves when the removal is complete.
*/
remove(keywordOrEntry) {
if (typeof(keywordOrEntry) == "string")
keywordOrEntry = { keyword: keywordOrEntry };
if (keywordOrEntry === null || typeof(keywordOrEntry) != "object" ||
- typeof keywordOrEntry.keyword != "string")
+ !keywordOrEntry.keyword || typeof keywordOrEntry.keyword != "string")
throw new Error("Invalid keyword");
let { keyword,
source = Ci.nsINavBookmarksService.SOURCE_DEFAULT } = keywordOrEntry;
keyword = keywordOrEntry.keyword.trim().toLowerCase();
return PlacesUtils.withConnectionWrapper("Keywords.remove", Task.async(function*(db) {
let cache = yield gKeywordsCachePromise;
if (!cache.has(keyword))
--- a/toolkit/components/places/nsINavBookmarksService.idl
+++ b/toolkit/components/places/nsINavBookmarksService.idl
@@ -286,21 +286,23 @@ interface nsINavBookmarksService : nsISu
const unsigned short TYPE_BOOKMARK = 1;
const unsigned short TYPE_FOLDER = 2;
const unsigned short TYPE_SEPARATOR = 3;
// Dynamic containers are deprecated and unsupported.
// This const exists just to avoid reusing the value.
const unsigned short TYPE_DYNAMIC_CONTAINER = 4;
// Change source constants. These are used to distinguish changes made by
- // Sync from other Places consumers, though they can be extended to support
- // other callers. Sources are passed as optional parameters to methods used
- // by Sync, and forwarded to observers.
+ // Sync and bookmarks import from other Places consumers, though they can
+ // be extended to support other callers. Sources are passed as optional
+ // parameters to methods used by Sync, and forwarded to observers.
const unsigned short SOURCE_DEFAULT = 0;
const unsigned short SOURCE_SYNC = 1;
+ const unsigned short SOURCE_IMPORT = 2;
+ const unsigned short SOURCE_IMPORT_REPLACE = 3;
/**
* Inserts a child bookmark into the given folder.
*
* @param aParentId
* The id of the parent folder
* @param aURI
* The URI to insert
@@ -421,21 +423,25 @@ interface nsINavBookmarksService : nsISu
* @param aParentId
* The id of the parent folder
* @param aIndex
* The separator's index under folder, or DEFAULT_INDEX to append
* @param [optional] aGuid
* The GUID to be set for the new item. If not set, a new GUID is
* generated. Unless you've a very sound reason, such as an undo
* manager implementation, do not pass this argument.
+ * @param [optional] aSource
+ * The change source, forwarded to all bookmark observers. Defaults
+ * to SOURCE_DEFAULT.
* @return The ID of the new separator.
* @throws if aGuid is malformed.
*/
long long insertSeparator(in long long aParentId, in long aIndex,
- [optional] in ACString aGuid);
+ [optional] in ACString aGuid,
+ [optional] in unsigned short aSource);
/**
* Get the itemId given the containing folder and the index.
* @param aParentId
* The id of the diret parent folder of the item
* @param aIndex
* The index of the item within the parent folder.
* Pass DEFAULT_INDEX for the last item.
@@ -472,18 +478,23 @@ interface nsINavBookmarksService : nsISu
/**
* Set the date added time for an item.
*
* @param aItemId
* the id of the item whose date added time should be updated.
* @param aDateAdded
* the new date added value in microseconds. Note that it is rounded
* down to milliseconds precision.
+ * @param [optional] aSource
+ * The change source, forwarded to all bookmark observers. Defaults
+ * to SOURCE_DEFAULT.
*/
- void setItemDateAdded(in long long aItemId, in PRTime aDateAdded);
+ void setItemDateAdded(in long long aItemId,
+ in PRTime aDateAdded,
+ [optional] in unsigned short aSource);
/**
* Get the date added time for an item.
*
* @param aItemId
* the id of the item whose date added time should be retrieved.
*
* @return the date added value in microseconds.
@@ -493,23 +504,28 @@ interface nsINavBookmarksService : nsISu
/**
* Set the last modified time for an item.
*
* @param aItemId
* the id of the item whose last modified time should be updated.
* @param aLastModified
* the new last modified value in microseconds. Note that it is
* rounded down to milliseconds precision.
+ * @param [optional] aSource
+ * The change source, forwarded to all bookmark observers. Defaults
+ * to SOURCE_DEFAULT.
*
* @note This is the only method that will send an itemChanged notification
* for the property. lastModified will still be updated in
* any other method that changes an item property, but we will send
* the corresponding itemChanged notification instead.
*/
- void setItemLastModified(in long long aItemId, in PRTime aLastModified);
+ void setItemLastModified(in long long aItemId,
+ in PRTime aLastModified,
+ [optional] in unsigned short aSource);
/**
* Get the last modified time for an item.
*
* @param aItemId
* the id of the item whose last modified time should be retrieved.
*
* @return the date added value in microseconds.
@@ -577,17 +593,19 @@ interface nsINavBookmarksService : nsISu
*/
nsIURI getBookmarkedURIFor(in nsIURI aURI);
/**
* Change the bookmarked URI for a bookmark.
* This changes which "place" the bookmark points at,
* which means all annotations, etc are carried along.
*/
- void changeBookmarkURI(in long long aItemId, in nsIURI aNewURI);
+ void changeBookmarkURI(in long long aItemId,
+ in nsIURI aNewURI,
+ [optional] in unsigned short aSource);
/**
* Get the parent folder's id for an item.
*/
long long getFolderIdForItem(in long long aItemId);
/**
* Returns the list of bookmark ids that contain the given URI.
--- a/toolkit/components/places/nsNavBookmarks.cpp
+++ b/toolkit/components/places/nsNavBookmarks.cpp
@@ -763,16 +763,17 @@ nsNavBookmarks::CreateContainerWithID(in
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::InsertSeparator(int64_t aParent,
int32_t aIndex,
const nsACString& aGUID,
+ uint16_t aSource,
int64_t* aNewItemId)
{
NS_ENSURE_ARG_MIN(aParent, 1);
NS_ENSURE_ARG_MIN(aIndex, nsINavBookmarksService::DEFAULT_INDEX);
NS_ENSURE_ARG_POINTER(aNewItemId);
if (!aGUID.IsEmpty() && !IsValidGUID(aGUID))
return NS_ERROR_INVALID_ARG;
@@ -1405,17 +1406,18 @@ nsNavBookmarks::SetItemDateInternal(enum
// note, we are not notifying the observers
// that the item has changed.
return NS_OK;
}
NS_IMETHODIMP
-nsNavBookmarks::SetItemDateAdded(int64_t aItemId, PRTime aDateAdded)
+nsNavBookmarks::SetItemDateAdded(int64_t aItemId, PRTime aDateAdded,
+ uint16_t aSource)
{
NS_ENSURE_ARG_MIN(aItemId, 1);
BookmarkData bookmark;
nsresult rv = FetchItemInfo(aItemId, bookmark);
NS_ENSURE_SUCCESS(rv, rv);
// Round here so that we notify with the right value.
@@ -1432,17 +1434,17 @@ nsNavBookmarks::SetItemDateAdded(int64_t
false,
nsPrintfCString("%lld", bookmark.dateAdded),
bookmark.dateAdded,
bookmark.type,
bookmark.parentId,
bookmark.guid,
bookmark.parentGuid,
EmptyCString(),
- SOURCE_DEFAULT));
+ aSource));
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::GetItemDateAdded(int64_t aItemId, PRTime* _dateAdded)
{
NS_ENSURE_ARG_MIN(aItemId, 1);
@@ -1453,17 +1455,18 @@ nsNavBookmarks::GetItemDateAdded(int64_t
NS_ENSURE_SUCCESS(rv, rv);
*_dateAdded = bookmark.dateAdded;
return NS_OK;
}
NS_IMETHODIMP
-nsNavBookmarks::SetItemLastModified(int64_t aItemId, PRTime aLastModified)
+nsNavBookmarks::SetItemLastModified(int64_t aItemId, PRTime aLastModified,
+ uint16_t aSource)
{
NS_ENSURE_ARG_MIN(aItemId, 1);
BookmarkData bookmark;
nsresult rv = FetchItemInfo(aItemId, bookmark);
NS_ENSURE_SUCCESS(rv, rv);
// Round here so that we notify with the right value.
@@ -1480,17 +1483,17 @@ nsNavBookmarks::SetItemLastModified(int6
false,
nsPrintfCString("%lld", bookmark.lastModified),
bookmark.lastModified,
bookmark.type,
bookmark.parentId,
bookmark.guid,
bookmark.parentGuid,
EmptyCString(),
- SOURCE_DEFAULT));
+ aSource));
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::GetItemLastModified(int64_t aItemId, PRTime* _lastModified)
{
NS_ENSURE_ARG_MIN(aItemId, 1);
@@ -1970,17 +1973,18 @@ nsNavBookmarks::GetBookmarkedURIFor(nsIU
}
// If there is no bookmarked origin, we will just return null.
return NS_OK;
}
NS_IMETHODIMP
-nsNavBookmarks::ChangeBookmarkURI(int64_t aBookmarkId, nsIURI* aNewURI)
+nsNavBookmarks::ChangeBookmarkURI(int64_t aBookmarkId, nsIURI* aNewURI,
+ uint16_t aSource)
{
NS_ENSURE_ARG_MIN(aBookmarkId, 1);
NS_ENSURE_ARG(aNewURI);
BookmarkData bookmark;
nsresult rv = FetchItemInfo(aBookmarkId, bookmark);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_ARG(bookmark.type == TYPE_BOOKMARK);
@@ -2036,17 +2040,17 @@ nsNavBookmarks::ChangeBookmarkURI(int64_
false,
spec,
bookmark.lastModified,
bookmark.type,
bookmark.parentId,
bookmark.guid,
bookmark.parentGuid,
bookmark.url,
- SOURCE_DEFAULT));
+ aSource));
return NS_OK;
}
NS_IMETHODIMP
nsNavBookmarks::GetFolderIdForItem(int64_t aItemId, int64_t* _parentId)
{
NS_ENSURE_ARG_MIN(aItemId, 1);