зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1131491 - Remove browser.places.useAsyncTransactions preference - async transactions are now the only version. r=mak
MozReview-Commit-ID: 9EKNvA8Q9jo --HG-- extra : rebase_source : 289082be4a1f086620bf0fe3008c2eacbdc6a9fa
This commit is contained in:
Родитель
3bdb37e019
Коммит
412e825e77
|
@ -915,9 +915,6 @@ pref("browser.sessionstore.max_write_failures", 5);
|
|||
// allow META refresh by default
|
||||
pref("accessibility.blockautorefresh", false);
|
||||
|
||||
// Whether useAsyncTransactions is enabled or not.
|
||||
pref("browser.places.useAsyncTransactions", true);
|
||||
|
||||
// Whether history is enabled or not.
|
||||
pref("places.history.enabled", true);
|
||||
|
||||
|
|
|
@ -11,8 +11,6 @@ XPCOMUtils.defineLazyScriptGetter(this, ["PlacesToolbar", "PlacesMenu",
|
|||
|
||||
var StarUI = {
|
||||
_itemGuids: null,
|
||||
// TODO (bug 1131491): _itemIdsMap is only used for the old transactions manager.
|
||||
_itemIdsMap: null,
|
||||
_batching: false,
|
||||
_isNewBookmark: false,
|
||||
_isComposing: false,
|
||||
|
@ -96,10 +94,8 @@ var StarUI = {
|
|||
this._restoreCommandsState();
|
||||
let removeBookmarksOnPopupHidden = this._removeBookmarksOnPopupHidden;
|
||||
this._removeBookmarksOnPopupHidden = false;
|
||||
let idsForRemoval = this._itemIdsMap;
|
||||
let guidsForRemoval = this._itemGuids;
|
||||
this._itemGuids = null;
|
||||
this._itemIdsMap = null;
|
||||
|
||||
if (this._batching) {
|
||||
this.endBatch();
|
||||
|
@ -107,25 +103,11 @@ var StarUI = {
|
|||
|
||||
if (removeBookmarksOnPopupHidden && guidsForRemoval) {
|
||||
if (this._isNewBookmark) {
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
PlacesUtils.transactionManager.undoTransaction();
|
||||
break;
|
||||
}
|
||||
PlacesTransactions.undo().catch(Cu.reportError);
|
||||
break;
|
||||
}
|
||||
// Remove all bookmarks for the bookmark's url, this also removes
|
||||
// the tags for the url.
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
if (idsForRemoval) {
|
||||
for (let itemId of idsForRemoval.values()) {
|
||||
let txn = new PlacesRemoveItemTransaction(itemId);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
PlacesTransactions.Remove(guidsForRemoval)
|
||||
.transact().catch(Cu.reportError);
|
||||
} else if (this._isNewBookmark) {
|
||||
|
@ -230,7 +212,6 @@ var StarUI = {
|
|||
}
|
||||
|
||||
this._isNewBookmark = aIsNewBookmark;
|
||||
this._itemIdsMap = null;
|
||||
this._itemGuids = null;
|
||||
// TODO (bug 1131491): Deprecate this once async transactions are enabled
|
||||
// and the legacy transactions code is gone.
|
||||
|
@ -291,9 +272,6 @@ var StarUI = {
|
|||
await PlacesUtils.bookmarks.fetch({url: aUrl},
|
||||
bookmark => this._itemGuids.push(bookmark.guid));
|
||||
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
this._itemIdsMap = await PlacesUtils.promiseManyItemIds(this._itemGuids);
|
||||
}
|
||||
let forms = gNavigatorBundle.getString("editBookmark.removeBookmarks.label");
|
||||
let bookmarksCount = this._itemGuids.length;
|
||||
let label = PluralForm.get(bookmarksCount, forms)
|
||||
|
@ -365,14 +343,10 @@ var StarUI = {
|
|||
beginBatch() {
|
||||
if (this._batching)
|
||||
return;
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
this._batchBlockingDeferred = PromiseUtils.defer();
|
||||
PlacesTransactions.batch(async () => {
|
||||
await this._batchBlockingDeferred.promise;
|
||||
});
|
||||
} else {
|
||||
PlacesUtils.transactionManager.beginBatch(null);
|
||||
}
|
||||
this._batchBlockingDeferred = PromiseUtils.defer();
|
||||
PlacesTransactions.batch(async () => {
|
||||
await this._batchBlockingDeferred.promise;
|
||||
});
|
||||
this._batching = true;
|
||||
},
|
||||
|
||||
|
@ -380,12 +354,8 @@ var StarUI = {
|
|||
if (!this._batching)
|
||||
return;
|
||||
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
this._batchBlockingDeferred.resolve();
|
||||
this._batchBlockingDeferred = null;
|
||||
} else {
|
||||
PlacesUtils.transactionManager.endBatch(false);
|
||||
}
|
||||
this._batchBlockingDeferred.resolve();
|
||||
this._batchBlockingDeferred = null;
|
||||
this._batching = false;
|
||||
}
|
||||
};
|
||||
|
@ -413,75 +383,6 @@ var PlacesCommandHook = {
|
|||
* getting the current page's title
|
||||
*/
|
||||
async bookmarkPage(aBrowser, aShowEditUI, aUrl = null, aTitle = null) {
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
await this._bookmarkPagePT(aBrowser, aShowEditUI, aUrl, aTitle);
|
||||
return;
|
||||
}
|
||||
|
||||
// If aUrl is provided, we want to bookmark that url rather than the
|
||||
// the current page
|
||||
var uri = aUrl ? Services.io.newURI(aUrl) : aBrowser.currentURI;
|
||||
var itemId = PlacesUtils.getMostRecentBookmarkForURI(uri);
|
||||
let isNewBookmark = itemId == -1;
|
||||
if (isNewBookmark) {
|
||||
// Bug 1148838 - Make this code work for full page plugins.
|
||||
var title;
|
||||
var description;
|
||||
var charset;
|
||||
|
||||
let docInfo = aUrl ? {} : await this._getPageDetails(aBrowser);
|
||||
|
||||
try {
|
||||
title = aTitle ||
|
||||
(docInfo.isErrorPage ? PlacesUtils.history.getPageTitle(uri)
|
||||
: aBrowser.contentTitle) ||
|
||||
uri.displaySpec;
|
||||
description = docInfo.description;
|
||||
charset = aUrl ? null : aBrowser.characterSet;
|
||||
} catch (e) { }
|
||||
|
||||
if (aShowEditUI) {
|
||||
// If we bookmark the page here but open right into a cancelable
|
||||
// state (i.e. new bookmark in Library), start batching here so
|
||||
// all of the actions can be undone in a single undo step.
|
||||
StarUI.beginBatch();
|
||||
}
|
||||
|
||||
var descAnno = { name: PlacesUIUtils.DESCRIPTION_ANNO, value: description };
|
||||
var txn = new PlacesCreateBookmarkTransaction(uri,
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
title, null, [descAnno]);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
itemId = txn.item.id;
|
||||
// Set the character-set.
|
||||
if (charset && !PrivateBrowsingUtils.isBrowserPrivate(aBrowser))
|
||||
PlacesUtils.setCharsetForURI(uri, charset);
|
||||
}
|
||||
|
||||
// Revert the contents of the location bar
|
||||
gURLBar.handleRevert();
|
||||
|
||||
// If it was not requested to open directly in "edit" mode, we are done.
|
||||
if (!aShowEditUI)
|
||||
return;
|
||||
|
||||
let anchor = BookmarkingUI.anchor;
|
||||
if (anchor) {
|
||||
await StarUI.showEditBookmarkPopup(itemId, anchor,
|
||||
"bottomcenter topright", isNewBookmark,
|
||||
uri);
|
||||
return;
|
||||
}
|
||||
|
||||
// Fall back to showing the panel over the content area.
|
||||
await StarUI.showEditBookmarkPopup(itemId, aBrowser, "overlap",
|
||||
isNewBookmark, uri);
|
||||
},
|
||||
|
||||
// TODO: Replace bookmarkPage code with this function once legacy
|
||||
// transactions are removed.
|
||||
async _bookmarkPagePT(aBrowser, aShowEditUI, aUrl, aTitle) {
|
||||
// If aUrl is provided, we want to bookmark that url rather than the
|
||||
// the current page
|
||||
let url = aUrl ? new URL(aUrl) : new URL(aBrowser.currentURI.spec);
|
||||
|
|
|
@ -11,11 +11,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
|||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/Timer.jsm");
|
||||
|
||||
// PlacesUtils exposes multiple symbols, so we can't use defineLazyModuleGetter
|
||||
// until we remove legacy transactions (Bug 1131491).
|
||||
Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
PlacesUtils: "resource://gre/modules/PlacesUtils.jsm",
|
||||
PluralForm: "resource://gre/modules/PluralForm.jsm",
|
||||
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm",
|
||||
RecentWindow: "resource:///modules/RecentWindow.jsm",
|
||||
|
@ -269,251 +266,6 @@ this.PlacesUIUtils = {
|
|||
},
|
||||
|
||||
/**
|
||||
* Get a transaction for copying a uri item (either a bookmark or a history
|
||||
* entry) from one container to another.
|
||||
*
|
||||
* @param aData
|
||||
* JSON object of dropped or pasted item properties
|
||||
* @param aContainer
|
||||
* The container being copied into
|
||||
* @param aIndex
|
||||
* The index within the container the item is copied to
|
||||
* @return A nsITransaction object that performs the copy.
|
||||
*
|
||||
* @note Since a copy creates a completely new item, only some internal
|
||||
* annotations are synced from the old one.
|
||||
* @see this._copyableAnnotations for the list of copyable annotations.
|
||||
*/
|
||||
_getURIItemCopyTransaction:
|
||||
function PUIU__getURIItemCopyTransaction(aData, aContainer, aIndex) {
|
||||
let transactions = [];
|
||||
if (aData.dateAdded) {
|
||||
transactions.push(
|
||||
new PlacesEditItemDateAddedTransaction(null, aData.dateAdded)
|
||||
);
|
||||
}
|
||||
if (aData.lastModified) {
|
||||
transactions.push(
|
||||
new PlacesEditItemLastModifiedTransaction(null, aData.lastModified)
|
||||
);
|
||||
}
|
||||
|
||||
let annos = [];
|
||||
if (aData.annos) {
|
||||
annos = aData.annos.filter(function(aAnno) {
|
||||
return this._copyableAnnotations.includes(aAnno.name);
|
||||
}, this);
|
||||
}
|
||||
|
||||
// There's no need to copy the keyword since it's bound to the bookmark url.
|
||||
return new PlacesCreateBookmarkTransaction(PlacesUtils._uri(aData.uri),
|
||||
aContainer, aIndex, aData.title,
|
||||
null, annos, transactions);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a transaction for copying (recursively nesting to include children)
|
||||
* a folder (or container) and its contents from one folder to another.
|
||||
*
|
||||
* @param aData
|
||||
* Unwrapped dropped folder data - Obj containing folder and children
|
||||
* @param aContainer
|
||||
* The container we are copying into
|
||||
* @param aIndex
|
||||
* The index in the destination container to insert the new items
|
||||
* @return A nsITransaction object that will perform the copy.
|
||||
*
|
||||
* @note Since a copy creates a completely new item, only some internal
|
||||
* annotations are synced from the old one.
|
||||
* @see this._copyableAnnotations for the list of copyable annotations.
|
||||
*/
|
||||
_getFolderCopyTransaction(aData, aContainer, aIndex) {
|
||||
function getChildItemsTransactions(aRoot) {
|
||||
let transactions = [];
|
||||
let index = aIndex;
|
||||
for (let i = 0; i < aRoot.childCount; ++i) {
|
||||
let child = aRoot.getChild(i);
|
||||
// Temporary hacks until we switch to PlacesTransactions.jsm.
|
||||
let isLivemark =
|
||||
PlacesUtils.annotations.itemHasAnnotation(child.itemId,
|
||||
PlacesUtils.LMANNO_FEEDURI);
|
||||
let [node] = PlacesUtils.unwrapNodes(
|
||||
PlacesUtils.wrapNode(child, PlacesUtils.TYPE_X_MOZ_PLACE, isLivemark),
|
||||
PlacesUtils.TYPE_X_MOZ_PLACE
|
||||
);
|
||||
|
||||
// Make sure that items are given the correct index, this will be
|
||||
// passed by the transaction manager to the backend for the insertion.
|
||||
// Insertion behaves differently for DEFAULT_INDEX (append).
|
||||
if (aIndex != PlacesUtils.bookmarks.DEFAULT_INDEX) {
|
||||
index = i;
|
||||
}
|
||||
|
||||
if (node.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER) {
|
||||
if (node.livemark && node.annos) {
|
||||
transactions.push(
|
||||
PlacesUIUtils._getLivemarkCopyTransaction(node, aContainer, index)
|
||||
);
|
||||
} else {
|
||||
transactions.push(
|
||||
PlacesUIUtils._getFolderCopyTransaction(node, aContainer, index)
|
||||
);
|
||||
}
|
||||
} else if (node.type == PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR) {
|
||||
transactions.push(new PlacesCreateSeparatorTransaction(-1, index));
|
||||
} else if (node.type == PlacesUtils.TYPE_X_MOZ_PLACE) {
|
||||
transactions.push(
|
||||
PlacesUIUtils._getURIItemCopyTransaction(node, -1, index)
|
||||
);
|
||||
} else {
|
||||
throw new Error("Unexpected item under a bookmarks folder");
|
||||
}
|
||||
}
|
||||
return transactions;
|
||||
}
|
||||
|
||||
if (aContainer == PlacesUtils.tagsFolderId) { // Copying into a tag folder.
|
||||
let transactions = [];
|
||||
if (!aData.livemark && aData.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER) {
|
||||
let {root} = PlacesUtils.getFolderContents(aData.id, false, false);
|
||||
let urls = PlacesUtils.getURLsForContainerNode(root);
|
||||
root.containerOpen = false;
|
||||
for (let { uri } of urls) {
|
||||
transactions.push(
|
||||
new PlacesTagURITransaction(Services.io.newURI(uri), [aData.title])
|
||||
);
|
||||
}
|
||||
}
|
||||
return new PlacesAggregatedTransaction("addTags", transactions);
|
||||
}
|
||||
|
||||
if (aData.livemark && aData.annos) { // Copying a livemark.
|
||||
return this._getLivemarkCopyTransaction(aData, aContainer, aIndex);
|
||||
}
|
||||
|
||||
let {root} = PlacesUtils.getFolderContents(aData.id, false, false);
|
||||
let transactions = getChildItemsTransactions(root);
|
||||
root.containerOpen = false;
|
||||
|
||||
if (aData.dateAdded) {
|
||||
transactions.push(
|
||||
new PlacesEditItemDateAddedTransaction(null, aData.dateAdded)
|
||||
);
|
||||
}
|
||||
if (aData.lastModified) {
|
||||
transactions.push(
|
||||
new PlacesEditItemLastModifiedTransaction(null, aData.lastModified)
|
||||
);
|
||||
}
|
||||
|
||||
let annos = [];
|
||||
if (aData.annos) {
|
||||
annos = aData.annos.filter(function(aAnno) {
|
||||
return this._copyableAnnotations.includes(aAnno.name);
|
||||
}, this);
|
||||
}
|
||||
|
||||
return new PlacesCreateFolderTransaction(aData.title, aContainer, aIndex,
|
||||
annos, transactions);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets a transaction for copying a live bookmark item from one container to
|
||||
* another.
|
||||
*
|
||||
* @param aData
|
||||
* Unwrapped live bookmarkmark data
|
||||
* @param aContainer
|
||||
* The container we are copying into
|
||||
* @param aIndex
|
||||
* The index in the destination container to insert the new items
|
||||
* @return A nsITransaction object that will perform the copy.
|
||||
*
|
||||
* @note Since a copy creates a completely new item, only some internal
|
||||
* annotations are synced from the old one.
|
||||
* @see this._copyableAnnotations for the list of copyable annotations.
|
||||
*/
|
||||
_getLivemarkCopyTransaction:
|
||||
function PUIU__getLivemarkCopyTransaction(aData, aContainer, aIndex) {
|
||||
if (!aData.livemark || !aData.annos) {
|
||||
throw new Error("node is not a livemark");
|
||||
}
|
||||
|
||||
let feedURI, siteURI;
|
||||
let annos = [];
|
||||
if (aData.annos) {
|
||||
annos = aData.annos.filter(function(aAnno) {
|
||||
if (aAnno.name == PlacesUtils.LMANNO_FEEDURI) {
|
||||
feedURI = PlacesUtils._uri(aAnno.value);
|
||||
} else if (aAnno.name == PlacesUtils.LMANNO_SITEURI) {
|
||||
siteURI = PlacesUtils._uri(aAnno.value);
|
||||
}
|
||||
return this._copyableAnnotations.includes(aAnno.name);
|
||||
}, this);
|
||||
}
|
||||
|
||||
return new PlacesCreateLivemarkTransaction(feedURI, siteURI, aData.title,
|
||||
aContainer, aIndex, annos);
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructs a Transaction for the drop or paste of a blob of data into
|
||||
* a container.
|
||||
* @param data
|
||||
* The unwrapped data blob of dropped or pasted data.
|
||||
* @param type
|
||||
* The content type of the data
|
||||
* @param container
|
||||
* The container the data was dropped or pasted into
|
||||
* @param index
|
||||
* The index within the container the item was dropped or pasted at
|
||||
* @param copy
|
||||
* The drag action was copy, so don't move folders or links.
|
||||
* @return An object implementing nsITransaction that can perform
|
||||
* the move/insert.
|
||||
*/
|
||||
makeTransaction:
|
||||
function PUIU_makeTransaction(data, type, container, index, copy) {
|
||||
switch (data.type) {
|
||||
case PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER:
|
||||
if (copy) {
|
||||
return this._getFolderCopyTransaction(data, container, index);
|
||||
}
|
||||
|
||||
// Otherwise move the item.
|
||||
return new PlacesMoveItemTransaction(data.id, container, index);
|
||||
case PlacesUtils.TYPE_X_MOZ_PLACE:
|
||||
if (copy || data.id == -1) { // Id is -1 if the place is not bookmarked.
|
||||
return this._getURIItemCopyTransaction(data, container, index);
|
||||
}
|
||||
|
||||
// Otherwise move the item.
|
||||
return new PlacesMoveItemTransaction(data.id, container, index);
|
||||
case PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR:
|
||||
if (copy) {
|
||||
// There is no data in a separator, so copying it just amounts to
|
||||
// inserting a new separator.
|
||||
return new PlacesCreateSeparatorTransaction(container, index);
|
||||
}
|
||||
|
||||
// Otherwise move the item.
|
||||
return new PlacesMoveItemTransaction(data.id, container, index);
|
||||
default:
|
||||
if (type == PlacesUtils.TYPE_X_MOZ_URL ||
|
||||
type == PlacesUtils.TYPE_UNICODE ||
|
||||
type == TAB_DROP_TYPE) {
|
||||
let title = type != PlacesUtils.TYPE_UNICODE ? data.title
|
||||
: data.uri;
|
||||
return new PlacesCreateBookmarkTransaction(PlacesUtils._uri(data.uri),
|
||||
container, index, title);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* ********* PlacesTransactions version of the function defined above ********
|
||||
*
|
||||
* Constructs a Places Transaction for the drop or paste of a blob of data
|
||||
* into a container.
|
||||
*
|
||||
|
@ -596,26 +348,22 @@ this.PlacesUIUtils = {
|
|||
let topUndoEntry;
|
||||
let batchBlockingDeferred;
|
||||
|
||||
if (this.useAsyncTransactions) {
|
||||
// Set the transaction manager into batching mode.
|
||||
topUndoEntry = PlacesTransactions.topUndoEntry;
|
||||
batchBlockingDeferred = PromiseUtils.defer();
|
||||
PlacesTransactions.batch(async () => {
|
||||
await batchBlockingDeferred.promise;
|
||||
});
|
||||
}
|
||||
// Set the transaction manager into batching mode.
|
||||
topUndoEntry = PlacesTransactions.topUndoEntry;
|
||||
batchBlockingDeferred = PromiseUtils.defer();
|
||||
PlacesTransactions.batch(async () => {
|
||||
await batchBlockingDeferred.promise;
|
||||
});
|
||||
|
||||
aParentWindow.openDialog(dialogURL, "", features, aInfo);
|
||||
|
||||
let performed = ("performed" in aInfo && aInfo.performed);
|
||||
|
||||
if (this.useAsyncTransactions) {
|
||||
batchBlockingDeferred.resolve();
|
||||
batchBlockingDeferred.resolve();
|
||||
|
||||
if (!performed &&
|
||||
topUndoEntry != PlacesTransactions.topUndoEntry) {
|
||||
PlacesTransactions.undo().catch(Components.utils.reportError);
|
||||
}
|
||||
if (!performed &&
|
||||
topUndoEntry != PlacesTransactions.topUndoEntry) {
|
||||
PlacesTransactions.undo().catch(Components.utils.reportError);
|
||||
}
|
||||
|
||||
return performed;
|
||||
|
@ -1530,8 +1278,6 @@ XPCOMUtils.defineLazyGetter(PlacesUIUtils, "ellipsis", function() {
|
|||
Ci.nsIPrefLocalizedString).data;
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(PlacesUIUtils, "useAsyncTransactions",
|
||||
"browser.places.useAsyncTransactions", false);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(PlacesUIUtils, "loadBookmarksInBackground",
|
||||
PREF_LOAD_BOOKMARKS_IN_BACKGROUND, false);
|
||||
XPCOMUtils.defineLazyPreferenceGetter(PlacesUIUtils, "loadBookmarksInTabs",
|
||||
|
|
|
@ -99,7 +99,6 @@ var BookmarkPropertiesPanel = {
|
|||
|
||||
_defaultInsertionPoint: null,
|
||||
_hiddenRows: [],
|
||||
_batching: false,
|
||||
|
||||
/**
|
||||
* This method returns the correct label for the dialog's "accept"
|
||||
|
@ -304,8 +303,6 @@ var BookmarkPropertiesPanel = {
|
|||
// the dialog is resized.
|
||||
window.addEventListener("resize", this);
|
||||
|
||||
this._beginBatch();
|
||||
|
||||
switch (this._action) {
|
||||
case ACTION_EDIT:
|
||||
gEditItemOverlay.initPanel({ node: this._node,
|
||||
|
@ -372,29 +369,6 @@ var BookmarkPropertiesPanel = {
|
|||
}
|
||||
},
|
||||
|
||||
// Hack for implementing batched-Undo around the editBookmarkOverlay
|
||||
// instant-apply code. For all the details see the comment above beginBatch
|
||||
// in browser-places.js
|
||||
_batchBlockingDeferred: null,
|
||||
_beginBatch() {
|
||||
if (this._batching)
|
||||
return;
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
PlacesUtils.transactionManager.beginBatch(null);
|
||||
}
|
||||
this._batching = true;
|
||||
},
|
||||
|
||||
_endBatch() {
|
||||
if (!this._batching)
|
||||
return;
|
||||
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
PlacesUtils.transactionManager.endBatch(false);
|
||||
}
|
||||
this._batching = false;
|
||||
},
|
||||
|
||||
// nsISupports
|
||||
QueryInterface: function BPP_QueryInterface(aIID) {
|
||||
if (aIID.equals(Ci.nsIDOMEventListener) ||
|
||||
|
@ -424,22 +398,16 @@ var BookmarkPropertiesPanel = {
|
|||
onDialogAccept() {
|
||||
// We must blur current focused element to save its changes correctly
|
||||
document.commandDispatcher.focusedElement.blur();
|
||||
// The order here is important! We have to uninit the panel first, otherwise
|
||||
// late changes could force it to commit more transactions.
|
||||
// We have to uninit the panel first, otherwise late changes could force it
|
||||
// to commit more transactions.
|
||||
gEditItemOverlay.uninitPanel(true);
|
||||
this._endBatch();
|
||||
window.arguments[0].performed = true;
|
||||
},
|
||||
|
||||
onDialogCancel() {
|
||||
// The order here is important! We have to uninit the panel first, otherwise
|
||||
// changes done as part of Undo may change the panel contents and by
|
||||
// that force it to commit more transactions.
|
||||
// We have to uninit the panel first, otherwise late changes could force it
|
||||
// to commit more transactions.
|
||||
gEditItemOverlay.uninitPanel(true);
|
||||
this._endBatch();
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
PlacesUtils.transactionManager.undoTransaction();
|
||||
}
|
||||
window.arguments[0].performed = false;
|
||||
},
|
||||
|
||||
|
@ -493,132 +461,7 @@ var BookmarkPropertiesPanel = {
|
|||
];
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a transaction for creating a new bookmark item representing the
|
||||
* various fields and opening arguments of the dialog.
|
||||
*/
|
||||
_getCreateNewBookmarkTransaction:
|
||||
function BPP__getCreateNewBookmarkTransaction(aContainer, aIndex) {
|
||||
var annotations = [];
|
||||
var childTransactions = [];
|
||||
|
||||
if (this._description) {
|
||||
let annoObj = { name: PlacesUIUtils.DESCRIPTION_ANNO,
|
||||
type: Ci.nsIAnnotationService.TYPE_STRING,
|
||||
flags: 0,
|
||||
value: this._description,
|
||||
expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
|
||||
let editItemTxn = new PlacesSetItemAnnotationTransaction(-1, annoObj);
|
||||
childTransactions.push(editItemTxn);
|
||||
}
|
||||
|
||||
if (this._loadInSidebar) {
|
||||
let annoObj = { name: PlacesUIUtils.LOAD_IN_SIDEBAR_ANNO,
|
||||
value: true };
|
||||
let setLoadTxn = new PlacesSetItemAnnotationTransaction(-1, annoObj);
|
||||
childTransactions.push(setLoadTxn);
|
||||
}
|
||||
|
||||
// XXX TODO: this should be in a transaction!
|
||||
if (this._charSet && !PrivateBrowsingUtils.isWindowPrivate(window))
|
||||
PlacesUtils.setCharsetForURI(this._uri, this._charSet);
|
||||
|
||||
let createTxn = new PlacesCreateBookmarkTransaction(this._uri,
|
||||
aContainer,
|
||||
aIndex,
|
||||
this._title,
|
||||
this._keyword,
|
||||
annotations,
|
||||
childTransactions,
|
||||
this._postData);
|
||||
|
||||
return new PlacesAggregatedTransaction(this._getDialogTitle(),
|
||||
[createTxn]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a childItems-transactions array representing the URIList with
|
||||
* which the dialog has been opened.
|
||||
*/
|
||||
_getTransactionsForURIList: function BPP__getTransactionsForURIList() {
|
||||
var transactions = [];
|
||||
for (let uri of this._URIs) {
|
||||
let createTxn =
|
||||
new PlacesCreateBookmarkTransaction(uri.uri, -1,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
uri.title);
|
||||
transactions.push(createTxn);
|
||||
}
|
||||
return transactions;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a transaction for creating a new folder item representing the
|
||||
* various fields and opening arguments of the dialog.
|
||||
*/
|
||||
_getCreateNewFolderTransaction:
|
||||
function BPP__getCreateNewFolderTransaction(aContainer, aIndex) {
|
||||
var annotations = [];
|
||||
var childItemsTransactions;
|
||||
if (this._URIs.length)
|
||||
childItemsTransactions = this._getTransactionsForURIList();
|
||||
|
||||
if (this._description)
|
||||
annotations.push(this._getDescriptionAnnotation(this._description));
|
||||
|
||||
return new PlacesCreateFolderTransaction(this._title, aContainer,
|
||||
aIndex, annotations,
|
||||
childItemsTransactions);
|
||||
},
|
||||
|
||||
async _createNewItem() {
|
||||
let [container, index] = await this._getInsertionPointDetails();
|
||||
let txn;
|
||||
switch (this._itemType) {
|
||||
case BOOKMARK_FOLDER:
|
||||
txn = this._getCreateNewFolderTransaction(container, index);
|
||||
break;
|
||||
case LIVEMARK_CONTAINER:
|
||||
txn = new PlacesCreateLivemarkTransaction(this._feedURI, this._siteURI,
|
||||
this._title, container, index);
|
||||
break;
|
||||
default: // BOOKMARK_ITEM
|
||||
txn = this._getCreateNewBookmarkTransaction(container, index);
|
||||
}
|
||||
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
// This is a temporary hack until we use PlacesTransactions.jsm
|
||||
if (txn._promise) {
|
||||
await txn._promise;
|
||||
}
|
||||
|
||||
let folderGuid = await PlacesUtils.promiseItemGuid(container);
|
||||
let bm = await PlacesUtils.bookmarks.fetch({
|
||||
parentGuid: folderGuid,
|
||||
index
|
||||
});
|
||||
this._itemId = await PlacesUtils.promiseItemId(bm.guid);
|
||||
|
||||
return Object.freeze({
|
||||
itemId: this._itemId,
|
||||
bookmarkGuid: bm.guid,
|
||||
title: this._title,
|
||||
uri: this._uri ? this._uri.spec : "",
|
||||
type: this._itemType == BOOKMARK_ITEM ?
|
||||
Ci.nsINavHistoryResultNode.RESULT_TYPE_URI :
|
||||
Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER,
|
||||
parent: {
|
||||
itemId: container,
|
||||
bookmarkGuid: await PlacesUtils.promiseItemGuid(container),
|
||||
type: Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async _promiseNewItem() {
|
||||
if (!PlacesUIUtils.useAsyncTransactions)
|
||||
return this._createNewItem();
|
||||
|
||||
let [containerId, index, parentGuid] = await this._getInsertionPointDetails();
|
||||
let annotations = [];
|
||||
if (this._description) {
|
||||
|
|
|
@ -120,14 +120,8 @@ PlacesController.prototype = {
|
|||
isCommandEnabled: function PC_isCommandEnabled(aCommand) {
|
||||
switch (aCommand) {
|
||||
case "cmd_undo":
|
||||
if (!PlacesUIUtils.useAsyncTransactions)
|
||||
return PlacesUtils.transactionManager.numberOfUndoItems > 0;
|
||||
|
||||
return PlacesTransactions.topUndoEntry != null;
|
||||
case "cmd_redo":
|
||||
if (!PlacesUIUtils.useAsyncTransactions)
|
||||
return PlacesUtils.transactionManager.numberOfRedoItems > 0;
|
||||
|
||||
return PlacesTransactions.topRedoEntry != null;
|
||||
case "cmd_cut":
|
||||
case "placesCmd_cut":
|
||||
|
@ -201,17 +195,9 @@ PlacesController.prototype = {
|
|||
doCommand: function PC_doCommand(aCommand) {
|
||||
switch (aCommand) {
|
||||
case "cmd_undo":
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
PlacesUtils.transactionManager.undoTransaction();
|
||||
return;
|
||||
}
|
||||
PlacesTransactions.undo().catch(Components.utils.reportError);
|
||||
break;
|
||||
case "cmd_redo":
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
PlacesUtils.transactionManager.redoTransaction();
|
||||
return;
|
||||
}
|
||||
PlacesTransactions.redo().catch(Components.utils.reportError);
|
||||
break;
|
||||
case "cmd_cut":
|
||||
|
@ -747,16 +733,6 @@ PlacesController.prototype = {
|
|||
throw Cr.NS_ERROR_NOT_AVAILABLE;
|
||||
|
||||
let index = await ip.getIndex();
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
let txn = new PlacesCreateSeparatorTransaction(ip.itemId, index);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
// Select the new item.
|
||||
let insertedNodeId = PlacesUtils.bookmarks
|
||||
.getIdForItemAt(ip.itemId, index);
|
||||
this._view.selectItems([insertedNodeId], false);
|
||||
return;
|
||||
}
|
||||
|
||||
let txn = PlacesTransactions.NewSeparator({ parentGuid: ip.guid, index });
|
||||
let guid = await txn.transact();
|
||||
// Select the new item.
|
||||
|
@ -767,13 +743,7 @@ PlacesController.prototype = {
|
|||
* Sort the selected folder by name
|
||||
*/
|
||||
async sortFolderByName() {
|
||||
let itemId = PlacesUtils.getConcreteItemId(this._view.selectedNode);
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
var txn = new PlacesSortFolderByNameTransaction(itemId);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
return;
|
||||
}
|
||||
let guid = await PlacesUtils.promiseItemGuid(itemId);
|
||||
let guid = PlacesUtils.getConcreteItemGuid(this._view.selectedNode);
|
||||
await PlacesTransactions.SortByName(guid).transact();
|
||||
},
|
||||
|
||||
|
@ -842,19 +812,14 @@ PlacesController.prototype = {
|
|||
if (PlacesUtils.nodeIsTagQuery(node.parent)) {
|
||||
// This is a uri node inside a tag container. It needs a special
|
||||
// untag transaction.
|
||||
var tagItemId = PlacesUtils.getConcreteItemId(node.parent);
|
||||
var uri = NetUtil.newURI(node.uri);
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
let tag = node.parent.title;
|
||||
if (!tag) {
|
||||
let tagGuid = await PlacesUtils.promiseItemGuid(tagItemId);
|
||||
tag = (await PlacesUtils.bookmarks.fetch(tagGuid)).title;
|
||||
}
|
||||
transactions.push(PlacesTransactions.Untag({ urls: [uri], tag }));
|
||||
} else {
|
||||
let txn = new PlacesUntagURITransaction(uri, [tagItemId]);
|
||||
transactions.push(txn);
|
||||
let tag = node.parent.title;
|
||||
if (!tag) {
|
||||
// TODO: Bug 1432405 Try using getConcreteItemGuid.
|
||||
let tagItemId = PlacesUtils.getConcreteItemId(node.parent);
|
||||
let tagGuid = await PlacesUtils.promiseItemGuid(tagItemId);
|
||||
tag = (await PlacesUtils.bookmarks.fetch(tagGuid)).title;
|
||||
}
|
||||
transactions.push(PlacesTransactions.Untag({ urls: [node.uri], tag }));
|
||||
} else if (PlacesUtils.nodeIsTagQuery(node) && node.parent &&
|
||||
PlacesUtils.nodeIsQuery(node.parent) &&
|
||||
PlacesUtils.asQuery(node.parent).queryOptions.resultType ==
|
||||
|
@ -865,14 +830,7 @@ PlacesController.prototype = {
|
|||
// must only remove the query node.
|
||||
let tag = node.title;
|
||||
let URIs = PlacesUtils.tagging.getURIsForTag(tag);
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
transactions.push(PlacesTransactions.Untag({ tag, urls: URIs }));
|
||||
} else {
|
||||
for (var j = 0; j < URIs.length; j++) {
|
||||
let txn = new PlacesUntagURITransaction(URIs[j], [tag]);
|
||||
transactions.push(txn);
|
||||
}
|
||||
}
|
||||
transactions.push(PlacesTransactions.Untag({ tag, urls: URIs }));
|
||||
} else if (PlacesUtils.nodeIsURI(node) &&
|
||||
PlacesUtils.nodeIsQuery(node.parent) &&
|
||||
PlacesUtils.asQuery(node.parent).queryOptions.queryType ==
|
||||
|
@ -896,12 +854,7 @@ PlacesController.prototype = {
|
|||
// to skip nodes that are children of an already removed folder.
|
||||
removedFolders.push(node);
|
||||
}
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
bmGuidsToRemove.push(node.bookmarkGuid);
|
||||
} else {
|
||||
let txn = new PlacesRemoveItemTransaction(node.itemId);
|
||||
transactions.push(txn);
|
||||
}
|
||||
bmGuidsToRemove.push(node.bookmarkGuid);
|
||||
}
|
||||
}
|
||||
if (bmGuidsToRemove.length) {
|
||||
|
@ -926,14 +879,9 @@ PlacesController.prototype = {
|
|||
}
|
||||
|
||||
if (transactions.length > 0) {
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
await PlacesUIUtils.batchUpdatesForNode(this._view.result, totalItems, async () => {
|
||||
await PlacesTransactions.batch(transactions);
|
||||
});
|
||||
} else {
|
||||
var txn = new PlacesAggregatedTransaction(txnName, transactions);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
}
|
||||
await PlacesUIUtils.batchUpdatesForNode(this._view.result, totalItems, async () => {
|
||||
await PlacesTransactions.batch(transactions);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1000,17 +948,11 @@ PlacesController.prototype = {
|
|||
var root = this._view.result.root;
|
||||
|
||||
if (PlacesUtils.nodeIsFolder(root)) {
|
||||
if (PlacesUIUtils.useAsyncTransactions)
|
||||
await this._removeRowsFromBookmarks(aTxnName);
|
||||
else
|
||||
this._removeRowsFromBookmarks(aTxnName);
|
||||
await this._removeRowsFromBookmarks(aTxnName);
|
||||
} else if (PlacesUtils.nodeIsQuery(root)) {
|
||||
var queryType = PlacesUtils.asQuery(root).queryOptions.queryType;
|
||||
if (queryType == Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS) {
|
||||
if (PlacesUIUtils.useAsyncTransactions)
|
||||
await this._removeRowsFromBookmarks(aTxnName);
|
||||
else
|
||||
this._removeRowsFromBookmarks(aTxnName);
|
||||
await this._removeRowsFromBookmarks(aTxnName);
|
||||
} else if (queryType == Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY) {
|
||||
this._removeRowsFromHistory();
|
||||
} else {
|
||||
|
@ -1261,50 +1203,8 @@ PlacesController.prototype = {
|
|||
return;
|
||||
}
|
||||
|
||||
let itemsToSelect = [];
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
let doCopy = action == "copy";
|
||||
itemsToSelect = await handleTransferItems(items, ip, doCopy, this._view);
|
||||
} else {
|
||||
let transactions = [];
|
||||
let insertionIndex = await ip.getIndex();
|
||||
for (let index = insertionIndex, i = 0; i < items.length; ++i) {
|
||||
if (ip.isTag) {
|
||||
// Pasting into a tag container means tagging the item, regardless of
|
||||
// the requested action.
|
||||
let tagTxn = new PlacesTagURITransaction(NetUtil.newURI(items[i].uri),
|
||||
[ip.itemId]);
|
||||
transactions.push(tagTxn);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Adjust index to make sure items are pasted in the correct position.
|
||||
// If index is DEFAULT_INDEX, items are just appended.
|
||||
if (index != PlacesUtils.bookmarks.DEFAULT_INDEX)
|
||||
index += i;
|
||||
|
||||
// If this is not a copy, check for safety that we can move the source,
|
||||
// otherwise report an error and fallback to a copy.
|
||||
if (action != "copy" && !PlacesControllerDragHelper.canMoveUnwrappedNode(items[i])) {
|
||||
Components.utils.reportError("Tried to move an unmovable Places " +
|
||||
"node, reverting to a copy operation.");
|
||||
action = "copy";
|
||||
}
|
||||
transactions.push(
|
||||
PlacesUIUtils.makeTransaction(items[i], type, ip.itemId,
|
||||
index, action == "copy")
|
||||
);
|
||||
}
|
||||
|
||||
let aggregatedTxn = new PlacesAggregatedTransaction("Paste", transactions);
|
||||
PlacesUtils.transactionManager.doTransaction(aggregatedTxn);
|
||||
|
||||
for (let i = 0; i < transactions.length; ++i) {
|
||||
itemsToSelect.push(
|
||||
PlacesUtils.bookmarks.getIdForItemAt(ip.itemId, insertionIndex + i)
|
||||
);
|
||||
}
|
||||
}
|
||||
let doCopy = action == "copy";
|
||||
let itemsToSelect = await handleTransferItems(items, ip, doCopy, this._view);
|
||||
|
||||
// Cut/past operations are not repeatable, so clear the clipboard.
|
||||
if (action == "cut") {
|
||||
|
@ -1543,9 +1443,7 @@ var PlacesControllerDragHelper = {
|
|||
async onDrop(insertionPoint, dt, view) {
|
||||
let doCopy = ["copy", "link"].includes(dt.dropEffect);
|
||||
|
||||
let transactions = [];
|
||||
let dropCount = dt.mozItemCount;
|
||||
let parentGuid = insertionPoint.guid;
|
||||
|
||||
// Following flavors may contain duplicated data.
|
||||
let duplicable = new Map();
|
||||
|
@ -1571,97 +1469,27 @@ var PlacesControllerDragHelper = {
|
|||
dtItems.push({flavor, data});
|
||||
}
|
||||
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
let nodes = [];
|
||||
// TODO: When sync transactions are removed, merge the for loop here into the
|
||||
// one above.
|
||||
for (let {flavor, data} of dtItems) {
|
||||
if (flavor != TAB_DROP_TYPE) {
|
||||
nodes = [...nodes, ...PlacesUtils.unwrapNodes(data, flavor)];
|
||||
} else if (data instanceof XULElement && data.localName == "tab" &&
|
||||
data.ownerGlobal.isChromeWindow) {
|
||||
let uri = data.linkedBrowser.currentURI;
|
||||
let spec = uri ? uri.spec : "about:blank";
|
||||
nodes.push({
|
||||
uri: spec,
|
||||
title: data.label,
|
||||
type: PlacesUtils.TYPE_X_MOZ_URL
|
||||
});
|
||||
} else {
|
||||
throw new Error("bogus data was passed as a tab");
|
||||
}
|
||||
}
|
||||
|
||||
await handleTransferItems(nodes, insertionPoint, doCopy, view);
|
||||
} else {
|
||||
for (let {flavor, data} of dtItems) {
|
||||
let nodes;
|
||||
if (flavor != TAB_DROP_TYPE) {
|
||||
nodes = PlacesUtils.unwrapNodes(data, flavor);
|
||||
} else if (data instanceof XULElement && data.localName == "tab" &&
|
||||
data.ownerGlobal.isChromeWindow) {
|
||||
let uri = data.linkedBrowser.currentURI;
|
||||
let spec = uri ? uri.spec : "about:blank";
|
||||
nodes = [{ uri: spec,
|
||||
title: data.label,
|
||||
type: PlacesUtils.TYPE_X_MOZ_URL}];
|
||||
} else {
|
||||
throw new Error("bogus data was passed as a tab");
|
||||
}
|
||||
|
||||
let movedCount = 0;
|
||||
for (let unwrapped of nodes) {
|
||||
let index = await insertionPoint.getIndex();
|
||||
|
||||
if (index != -1 && unwrapped.itemGuid) {
|
||||
// Note: we use the parent from the existing bookmark as the sidebar
|
||||
// gives us an unwrapped.parent that is actually a query and not the real
|
||||
// parent.
|
||||
let existingBookmark = await PlacesUtils.bookmarks.fetch(unwrapped.itemGuid);
|
||||
|
||||
// If we're dropping on the same folder, then we may need to adjust
|
||||
// the index to insert at the correct place.
|
||||
if (existingBookmark && parentGuid == existingBookmark.parentGuid) {
|
||||
// Sync Transactions. Adjust insertion index to prevent reversal
|
||||
// of dragged items. When you drag multiple elts upward: need to
|
||||
// increment index or each successive elt will be inserted at the
|
||||
// same index, each above the previous.
|
||||
if (index < existingBookmark.index) { // eslint-disable-line no-lonely-if
|
||||
index += movedCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If dragging over a tag container we should tag the item.
|
||||
// eslint-disable-next-line no-lonely-if
|
||||
if (insertionPoint.isTag) {
|
||||
let uri = NetUtil.newURI(unwrapped.uri);
|
||||
let tagItemId = insertionPoint.itemId;
|
||||
transactions.push(new PlacesTagURITransaction(uri, [tagItemId]));
|
||||
} else {
|
||||
// If this is not a copy, check for safety that we can move the
|
||||
// source, otherwise report an error and fallback to a copy.
|
||||
if (!doCopy && !PlacesControllerDragHelper.canMoveUnwrappedNode(unwrapped)) {
|
||||
Components.utils.reportError("Tried to move an unmovable Places " +
|
||||
"node, reverting to a copy operation.");
|
||||
doCopy = true;
|
||||
}
|
||||
transactions.push(PlacesUIUtils.makeTransaction(unwrapped,
|
||||
flavor, insertionPoint.itemId,
|
||||
index, doCopy));
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we actually have something to add, if we don't it probably wasn't
|
||||
// valid, or it was moving to the same location, so just ignore it.
|
||||
if (!transactions.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let txn = new PlacesAggregatedTransaction("DropItems", transactions);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
let nodes = [];
|
||||
// TODO: Bug 1432407. When sync transactions are removed, merge the for loop
|
||||
// here into the one above.
|
||||
for (let {flavor, data} of dtItems) {
|
||||
if (flavor != TAB_DROP_TYPE) {
|
||||
nodes = [...nodes, ...PlacesUtils.unwrapNodes(data, flavor)];
|
||||
} else if (data instanceof XULElement && data.localName == "tab" &&
|
||||
data.ownerGlobal.isChromeWindow) {
|
||||
let uri = data.linkedBrowser.currentURI;
|
||||
let spec = uri ? uri.spec : "about:blank";
|
||||
nodes.push({
|
||||
uri: spec,
|
||||
title: data.label,
|
||||
type: PlacesUtils.TYPE_X_MOZ_URL
|
||||
});
|
||||
} else {
|
||||
throw new Error("bogus data was passed as a tab");
|
||||
}
|
||||
}
|
||||
|
||||
await handleTransferItems(nodes, insertionPoint, doCopy, view);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -542,20 +542,6 @@ var gEditItemOverlay = {
|
|||
if (removedTags.length + newTags.length == 0)
|
||||
return false;
|
||||
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
let txns = [];
|
||||
for (let uri of aURIs) {
|
||||
if (removedTags.length > 0)
|
||||
txns.push(new PlacesUntagURITransaction(uri, removedTags));
|
||||
if (newTags.length > 0)
|
||||
txns.push(new PlacesTagURITransaction(uri, newTags));
|
||||
}
|
||||
|
||||
PlacesUtils.transactionManager.doTransaction(
|
||||
new PlacesAggregatedTransaction("Update tags", txns));
|
||||
return true;
|
||||
}
|
||||
|
||||
let setTags = async function() {
|
||||
if (removedTags.length > 0) {
|
||||
await PlacesTransactions.Untag({ urls: aURIs, tags: removedTags })
|
||||
|
@ -630,12 +616,6 @@ var gEditItemOverlay = {
|
|||
this._initNamePicker();
|
||||
} else {
|
||||
this._mayUpdateFirstEditField("namePicker");
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
let txn = new PlacesEditItemTitleTransaction(this._paneInfo.itemId,
|
||||
newTitle);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
return;
|
||||
}
|
||||
|
||||
let guid = this._paneInfo.isTag
|
||||
? (await PlacesUtils.promiseItemGuid(this._paneInfo.itemId))
|
||||
|
@ -648,17 +628,10 @@ var gEditItemOverlay = {
|
|||
if (this.readOnly || !this._paneInfo.isItem)
|
||||
return;
|
||||
|
||||
let itemId = this._paneInfo.itemId;
|
||||
let description = this._element("descriptionField").value;
|
||||
if (description != PlacesUIUtils.getItemDescription(this._paneInfo.itemId)) {
|
||||
let annotation =
|
||||
{ name: PlacesUIUtils.DESCRIPTION_ANNO, value: description };
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
let txn = new PlacesSetItemAnnotationTransaction(itemId,
|
||||
annotation);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
return;
|
||||
}
|
||||
let guid = this._paneInfo.itemGuid;
|
||||
PlacesTransactions.Annotate({ guid, annotation })
|
||||
.transact().catch(Components.utils.reportError);
|
||||
|
@ -680,11 +653,6 @@ var gEditItemOverlay = {
|
|||
if (this._paneInfo.uri.equals(newURI))
|
||||
return;
|
||||
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
let txn = new PlacesEditBookmarkURITransaction(this._paneInfo.itemId, newURI);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
return;
|
||||
}
|
||||
let guid = this._paneInfo.itemGuid;
|
||||
PlacesTransactions.EditUrl({ guid, url: newURI })
|
||||
.transact().catch(Components.utils.reportError);
|
||||
|
@ -694,18 +662,9 @@ var gEditItemOverlay = {
|
|||
if (this.readOnly || !this._paneInfo.isBookmark)
|
||||
return;
|
||||
|
||||
let itemId = this._paneInfo.itemId;
|
||||
let oldKeyword = this._keyword;
|
||||
let keyword = this._keyword = this._keywordField.value;
|
||||
let postData = this._paneInfo.postData;
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
let txn = new PlacesEditBookmarkKeywordTransaction(itemId,
|
||||
keyword,
|
||||
postData,
|
||||
oldKeyword);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
return;
|
||||
}
|
||||
let guid = this._paneInfo.itemGuid;
|
||||
PlacesTransactions.EditKeyword({ guid, keyword, postData, oldKeyword })
|
||||
.transact().catch(Components.utils.reportError);
|
||||
|
@ -719,13 +678,6 @@ var gEditItemOverlay = {
|
|||
if (this._loadInSidebarCheckbox.checked)
|
||||
annotation.value = true;
|
||||
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
let itemId = this._paneInfo.itemId;
|
||||
let txn = new PlacesSetItemAnnotationTransaction(itemId,
|
||||
annotation);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
return;
|
||||
}
|
||||
let guid = this._paneInfo.itemGuid;
|
||||
PlacesTransactions.Annotate({ guid, annotation })
|
||||
.transact().catch(Components.utils.reportError);
|
||||
|
@ -813,16 +765,9 @@ var gEditItemOverlay = {
|
|||
let containerId = this._folderMenuList.selectedItem.folderId;
|
||||
if (this._paneInfo.parentId != containerId &&
|
||||
this._paneInfo.itemId != containerId) {
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
let newParentGuid = await PlacesUtils.promiseItemGuid(containerId);
|
||||
let guid = this._paneInfo.itemGuid;
|
||||
await PlacesTransactions.Move({ guid, newParentGuid }).transact();
|
||||
} else {
|
||||
let txn = new PlacesMoveItemTransaction(this._paneInfo.itemId,
|
||||
containerId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
}
|
||||
let newParentGuid = await PlacesUtils.promiseItemGuid(containerId);
|
||||
let guid = this._paneInfo.itemGuid;
|
||||
await PlacesTransactions.Move({ guid, newParentGuid }).transact();
|
||||
|
||||
// Mark the containing folder as recently-used if it isn't in the
|
||||
// static list
|
||||
|
@ -869,30 +814,6 @@ var gEditItemOverlay = {
|
|||
},
|
||||
|
||||
async _markFolderAsRecentlyUsed(aFolderId) {
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
let txns = [];
|
||||
|
||||
// Expire old unused recent folders.
|
||||
let annotation = this._getLastUsedAnnotationObject(false);
|
||||
while (this._recentFolders.length > MAX_FOLDER_ITEM_IN_MENU_LIST) {
|
||||
let folderId = this._recentFolders.pop().folderId;
|
||||
let annoTxn = new PlacesSetItemAnnotationTransaction(folderId,
|
||||
annotation);
|
||||
txns.push(annoTxn);
|
||||
}
|
||||
|
||||
// Mark folder as recently used
|
||||
annotation = this._getLastUsedAnnotationObject(true);
|
||||
let annoTxn = new PlacesSetItemAnnotationTransaction(aFolderId,
|
||||
annotation);
|
||||
txns.push(annoTxn);
|
||||
|
||||
let aggregate =
|
||||
new PlacesAggregatedTransaction("Update last used folders", txns);
|
||||
PlacesUtils.transactionManager.doTransaction(aggregate);
|
||||
return;
|
||||
}
|
||||
|
||||
// Expire old unused recent folders.
|
||||
let guids = [];
|
||||
while (this._recentFolders.length > MAX_FOLDER_ITEM_IN_MENU_LIST) {
|
||||
|
@ -1016,14 +937,9 @@ var gEditItemOverlay = {
|
|||
|
||||
// XXXmano: add a separate "New Folder" string at some point...
|
||||
let title = this._element("newFolderButton").label;
|
||||
if (PlacesUIUtils.useAsyncTransactions) {
|
||||
await PlacesTransactions.NewFolder({ parentGuid: ip.guid, title,
|
||||
index: await ip.getIndex() })
|
||||
.transact().catch(Components.utils.reportError);
|
||||
} else {
|
||||
let txn = new PlacesCreateFolderTransaction(title, ip.itemId, await ip.getIndex());
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
}
|
||||
await PlacesTransactions.NewFolder({ parentGuid: ip.guid, title,
|
||||
index: await ip.getIndex() })
|
||||
.transact().catch(Components.utils.reportError);
|
||||
|
||||
this._folderTree.focus();
|
||||
this._folderTree.selectItems([ip.itemId]);
|
||||
|
|
|
@ -1784,11 +1784,6 @@ PlacesTreeView.prototype = {
|
|||
// We may only get here if the cell is editable.
|
||||
let node = this._rows[aRow];
|
||||
if (node.title != aText) {
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
let txn = new PlacesEditItemTitleTransaction(node.itemId, aText);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
return;
|
||||
}
|
||||
PlacesTransactions.EditTitle({ guid: node.bookmarkGuid, title: aText })
|
||||
.transact().catch(Cu.reportError);
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ skip-if = (os == 'win' && ccov) # Bug 1423667
|
|||
skip-if = (os == 'win' && ccov) # Bug 1423667
|
||||
[browser_controller_onDrop.js]
|
||||
skip-if = (os == 'win' && ccov) # Bug 1423667
|
||||
[browser_copy_folder_tree.js]
|
||||
[browser_copy_query_without_tree.js]
|
||||
skip-if = (os == 'win' && ccov) # Bug 1423667
|
||||
subsuite = clipboard
|
||||
|
|
|
@ -34,11 +34,6 @@ add_task(async function setup() {
|
|||
// Tests for bug 1391393 - Ensures that if the user cancels the bookmark properties
|
||||
// dialog without having done any changes, then no undo is called.
|
||||
add_task(async function test_cancel_with_no_changes() {
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
Assert.ok(true, "Skipping test as async transactions are turned off");
|
||||
return;
|
||||
}
|
||||
|
||||
await withSidebarTree("bookmarks", async (tree) => {
|
||||
tree.selectItems([bookmarks[0].guid]);
|
||||
|
||||
|
@ -75,11 +70,6 @@ add_task(async function test_cancel_with_no_changes() {
|
|||
});
|
||||
|
||||
add_task(async function test_cancel_with_changes() {
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
Assert.ok(true, "Skipping test as async transactions are turned off");
|
||||
return;
|
||||
}
|
||||
|
||||
await withSidebarTree("bookmarks", async (tree) => {
|
||||
tree.selectItems([bookmarks[1].guid]);
|
||||
|
||||
|
|
|
@ -59,11 +59,6 @@ add_task(async function setup() {
|
|||
|
||||
async function run_drag_test(startBookmarkIndex, insertionIndex, newParentGuid,
|
||||
expectedInsertionIndex, expectTransactionCreated = true) {
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
Assert.ok(true, "Skipping test as async transactions are turned off");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!newParentGuid) {
|
||||
newParentGuid = PlacesUtils.bookmarks.unfiledGuid;
|
||||
}
|
||||
|
|
|
@ -39,11 +39,6 @@ add_task(async function setup() {
|
|||
});
|
||||
|
||||
async function run_drag_test(startBookmarkIndex, newParentGuid) {
|
||||
if (!PlacesUIUtils.useAsyncTransactions) {
|
||||
Assert.ok(true, "Skipping test as async transactions are turned off");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!newParentGuid) {
|
||||
newParentGuid = PlacesUtils.bookmarks.unfiledGuid;
|
||||
}
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Deep copy of bookmark data, using the front-end codepath:
|
||||
|
||||
- create test folder A
|
||||
- add a subfolder to folder A, and add items to it
|
||||
- validate folder A (sanity check)
|
||||
- copy folder A, creating new folder B, using the front-end path
|
||||
- validate folder B
|
||||
- undo copy transaction
|
||||
- validate folder B (empty)
|
||||
- redo copy transaction
|
||||
- validate folder B's contents
|
||||
*/
|
||||
|
||||
add_task(async function() {
|
||||
let toolbarId = PlacesUtils.toolbarFolderId;
|
||||
let toolbarNode = PlacesUtils.getFolderContents(toolbarId).root;
|
||||
|
||||
let oldCount = toolbarNode.childCount;
|
||||
let testRoot = await PlacesUtils.bookmarks.insert({
|
||||
parentGuid: PlacesUtils.bookmarks.toolbarGuid,
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
title: "test root"
|
||||
});
|
||||
is(toolbarNode.childCount, oldCount + 1, "confirm test root node is a container, and is empty");
|
||||
|
||||
let testRootNode = toolbarNode.getChild(toolbarNode.childCount - 1);
|
||||
testRootNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
|
||||
testRootNode.containerOpen = true;
|
||||
is(testRootNode.childCount, 0, "confirm test root node is a container, and is empty");
|
||||
|
||||
// create folder A, fill it, validate its contents
|
||||
let folderA = await PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: testRoot.guid,
|
||||
title: "A"
|
||||
});
|
||||
|
||||
await populate(folderA);
|
||||
|
||||
let folderAId = await PlacesUtils.promiseItemId(folderA.guid);
|
||||
let folderANode = PlacesUtils.getFolderContents(folderAId).root;
|
||||
validate(folderANode);
|
||||
is(testRootNode.childCount, 1, "create test folder");
|
||||
|
||||
// copy it, using the front-end helper functions
|
||||
let serializedNode = PlacesUtils.wrapNode(folderANode, PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER);
|
||||
let rawNode = PlacesUtils.unwrapNodes(serializedNode, PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER).shift();
|
||||
// confirm serialization
|
||||
ok(rawNode.type, "confirm json node");
|
||||
folderANode.containerOpen = false;
|
||||
|
||||
let testRootId = await PlacesUtils.promiseItemId(testRoot.guid);
|
||||
let transaction = PlacesUIUtils.makeTransaction(rawNode,
|
||||
PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
|
||||
testRootId,
|
||||
-1,
|
||||
true);
|
||||
ok(transaction, "create transaction");
|
||||
PlacesUtils.transactionManager.doTransaction(transaction);
|
||||
// confirm copy
|
||||
is(testRootNode.childCount, 2, "create test folder via copy");
|
||||
|
||||
// validate the copy
|
||||
let folderBNode = testRootNode.getChild(1);
|
||||
validate(folderBNode);
|
||||
|
||||
// undo the transaction, confirm the removal
|
||||
PlacesUtils.transactionManager.undoTransaction();
|
||||
is(testRootNode.childCount, 1, "confirm undo removed the copied folder");
|
||||
|
||||
// redo the transaction
|
||||
PlacesUtils.transactionManager.redoTransaction();
|
||||
is(testRootNode.childCount, 2, "confirm redo re-copied the folder");
|
||||
folderBNode = testRootNode.getChild(1);
|
||||
validate(folderBNode);
|
||||
|
||||
// Close containers, cleaning up their observers.
|
||||
testRootNode.containerOpen = false;
|
||||
toolbarNode.containerOpen = false;
|
||||
|
||||
// clean up
|
||||
PlacesUtils.transactionManager.undoTransaction();
|
||||
await PlacesUtils.bookmarks.remove(folderA.guid);
|
||||
});
|
||||
|
||||
var populate = async function(parentFolder) {
|
||||
let folder = await PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_FOLDER,
|
||||
parentGuid: parentFolder.guid,
|
||||
title: "test folder"
|
||||
});
|
||||
|
||||
await PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_BOOKMARK,
|
||||
parentGuid: folder.guid,
|
||||
title: "test bookmark",
|
||||
url: "http://foo"
|
||||
});
|
||||
|
||||
await PlacesUtils.bookmarks.insert({
|
||||
type: PlacesUtils.bookmarks.TYPE_SEPARATOR,
|
||||
parentGuid: folder.guid
|
||||
});
|
||||
};
|
||||
|
||||
function validate(aNode) {
|
||||
PlacesUtils.asContainer(aNode);
|
||||
aNode.containerOpen = true;
|
||||
is(aNode.childCount, 1, "confirm child count match");
|
||||
var folderNode = aNode.getChild(0);
|
||||
is(folderNode.title, "test folder", "confirm folder title");
|
||||
PlacesUtils.asContainer(folderNode);
|
||||
folderNode.containerOpen = true;
|
||||
is(folderNode.childCount, 2, "confirm child count match");
|
||||
folderNode.containerOpen = false;
|
||||
aNode.containerOpen = false;
|
||||
}
|
|
@ -1,330 +0,0 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function waitForBookmarkNotification(aNotification, aCallback, aProperty) {
|
||||
PlacesUtils.bookmarks.addObserver({
|
||||
validate(aMethodName, aData) {
|
||||
if (aMethodName == aNotification &&
|
||||
(!aProperty || aProperty == aData.property)) {
|
||||
PlacesUtils.bookmarks.removeObserver(this);
|
||||
aCallback(aData);
|
||||
}
|
||||
},
|
||||
|
||||
// nsINavBookmarkObserver
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavBookmarkObserver]),
|
||||
onBeginUpdateBatch: function onBeginUpdateBatch() {
|
||||
return this.validate("onBeginUpdateBatch", arguments);
|
||||
},
|
||||
onEndUpdateBatch: function onEndUpdateBatch() {
|
||||
return this.validate("onEndUpdateBatch", arguments);
|
||||
},
|
||||
onItemAdded: function onItemAdded(aItemId, aParentId, aIndex, aItemType,
|
||||
aURI, aTitle) {
|
||||
return this.validate("onItemAdded", { id: aItemId,
|
||||
index: aIndex,
|
||||
type: aItemType,
|
||||
url: aURI ? aURI.spec : null,
|
||||
title: aTitle });
|
||||
},
|
||||
onItemRemoved: function onItemRemoved() {
|
||||
return this.validate("onItemRemoved", arguments);
|
||||
},
|
||||
onItemChanged: function onItemChanged(id, property, aIsAnno,
|
||||
aNewValue, aLastModified, type) {
|
||||
return this.validate("onItemChanged",
|
||||
{ id,
|
||||
get index() {
|
||||
return PlacesUtils.bookmarks.getItemIndex(this.id);
|
||||
},
|
||||
type,
|
||||
property,
|
||||
get url() {
|
||||
return type == PlacesUtils.bookmarks.TYPE_BOOKMARK ?
|
||||
PlacesUtils.bookmarks.getBookmarkURI(this.id).spec :
|
||||
null;
|
||||
},
|
||||
get title() {
|
||||
return PlacesUtils.bookmarks.getItemTitle(this.id);
|
||||
},
|
||||
});
|
||||
},
|
||||
onItemVisited: function onItemVisited() {
|
||||
return this.validate("onItemVisited", arguments);
|
||||
},
|
||||
onItemMoved: function onItemMoved(aItemId, aOldParentId, aOldIndex,
|
||||
aNewParentId, aNewIndex, aItemType) {
|
||||
this.validate("onItemMoved", { id: aItemId,
|
||||
index: aNewIndex,
|
||||
type: aItemType });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function wrapNodeByIdAndParent(aItemId, aParentId) {
|
||||
let wrappedNode;
|
||||
let root = PlacesUtils.getFolderContents(aParentId, false, false).root;
|
||||
for (let i = 0; i < root.childCount; ++i) {
|
||||
let node = root.getChild(i);
|
||||
if (node.itemId == aItemId) {
|
||||
let type;
|
||||
if (PlacesUtils.nodeIsContainer(node)) {
|
||||
type = PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER;
|
||||
} else if (PlacesUtils.nodeIsURI(node)) {
|
||||
type = PlacesUtils.TYPE_X_MOZ_PLACE;
|
||||
} else if (PlacesUtils.nodeIsSeparator(node)) {
|
||||
type = PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR;
|
||||
} else {
|
||||
do_throw("Unknown node type");
|
||||
}
|
||||
wrappedNode = PlacesUtils.wrapNode(node, type);
|
||||
}
|
||||
}
|
||||
root.containerOpen = false;
|
||||
return JSON.parse(wrappedNode);
|
||||
}
|
||||
|
||||
add_test(function test_text_paste() {
|
||||
const TEST_URL = "http://places.moz.org/";
|
||||
const TEST_TITLE = "Places bookmark";
|
||||
|
||||
waitForBookmarkNotification("onItemAdded", function(aData) {
|
||||
Assert.equal(aData.title, TEST_TITLE);
|
||||
Assert.equal(aData.url, TEST_URL);
|
||||
Assert.equal(aData.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(aData.index, 0);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
let txn = PlacesUIUtils.makeTransaction(
|
||||
{ title: TEST_TITLE, uri: TEST_URL },
|
||||
PlacesUtils.TYPE_X_MOZ_URL,
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
true // Unused for text.
|
||||
);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
});
|
||||
|
||||
add_test(function test_container() {
|
||||
const TEST_TITLE = "Places folder";
|
||||
|
||||
waitForBookmarkNotification("onItemChanged", function(aChangedData) {
|
||||
Assert.equal(aChangedData.title, TEST_TITLE);
|
||||
Assert.equal(aChangedData.type, PlacesUtils.bookmarks.TYPE_FOLDER);
|
||||
Assert.equal(aChangedData.index, 1);
|
||||
|
||||
waitForBookmarkNotification("onItemAdded", function(aAddedData) {
|
||||
Assert.equal(aAddedData.title, TEST_TITLE);
|
||||
Assert.equal(aAddedData.type, PlacesUtils.bookmarks.TYPE_FOLDER);
|
||||
Assert.equal(aAddedData.index, 2);
|
||||
let id = aAddedData.id;
|
||||
|
||||
waitForBookmarkNotification("onItemMoved", function(aMovedData) {
|
||||
Assert.equal(aMovedData.id, id);
|
||||
Assert.equal(aMovedData.type, PlacesUtils.bookmarks.TYPE_FOLDER);
|
||||
Assert.equal(aMovedData.index, 1);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
let txn = PlacesUIUtils.makeTransaction(
|
||||
wrapNodeByIdAndParent(aAddedData.id, PlacesUtils.unfiledBookmarksFolderId),
|
||||
0, // Unused for real nodes.
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
1, // Move to position 1.
|
||||
false
|
||||
);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
});
|
||||
|
||||
try {
|
||||
let txn = PlacesUIUtils.makeTransaction(
|
||||
wrapNodeByIdAndParent(aChangedData.id, PlacesUtils.unfiledBookmarksFolderId),
|
||||
0, // Unused for real nodes.
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
true
|
||||
);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
} catch (ex) {
|
||||
do_throw(ex);
|
||||
}
|
||||
}, "random-anno");
|
||||
|
||||
let id = PlacesUtils.bookmarks.createFolder(PlacesUtils.unfiledBookmarksFolderId,
|
||||
TEST_TITLE,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.annotations.setItemAnnotation(id, PlacesUIUtils.DESCRIPTION_ANNO,
|
||||
"description", 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
PlacesUtils.annotations.setItemAnnotation(id, "random-anno",
|
||||
"random-value", 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
});
|
||||
|
||||
|
||||
add_test(function test_separator() {
|
||||
waitForBookmarkNotification("onItemChanged", function(aChangedData) {
|
||||
Assert.equal(aChangedData.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
|
||||
Assert.equal(aChangedData.index, 3);
|
||||
|
||||
waitForBookmarkNotification("onItemAdded", function(aAddedData) {
|
||||
Assert.equal(aAddedData.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
|
||||
Assert.equal(aAddedData.index, 4);
|
||||
let id = aAddedData.id;
|
||||
|
||||
waitForBookmarkNotification("onItemMoved", function(aMovedData) {
|
||||
Assert.equal(aMovedData.id, id);
|
||||
Assert.equal(aMovedData.type, PlacesUtils.bookmarks.TYPE_SEPARATOR);
|
||||
Assert.equal(aMovedData.index, 1);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
let txn = PlacesUIUtils.makeTransaction(
|
||||
wrapNodeByIdAndParent(aAddedData.id, PlacesUtils.unfiledBookmarksFolderId),
|
||||
0, // Unused for real nodes.
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
1, // Move to position 1.
|
||||
false
|
||||
);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
});
|
||||
|
||||
try {
|
||||
let txn = PlacesUIUtils.makeTransaction(
|
||||
wrapNodeByIdAndParent(aChangedData.id, PlacesUtils.unfiledBookmarksFolderId),
|
||||
0, // Unused for real nodes.
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
true
|
||||
);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
} catch (ex) {
|
||||
do_throw(ex);
|
||||
}
|
||||
}, "random-anno");
|
||||
|
||||
let id = PlacesUtils.bookmarks.insertSeparator(PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
PlacesUtils.annotations.setItemAnnotation(id, "random-anno",
|
||||
"random-value", 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
});
|
||||
|
||||
add_test(function test_bookmark() {
|
||||
const TEST_URL = "http://places.moz.org/";
|
||||
const TEST_TITLE = "Places bookmark";
|
||||
|
||||
waitForBookmarkNotification("onItemChanged", function(aChangedData) {
|
||||
Assert.equal(aChangedData.title, TEST_TITLE);
|
||||
Assert.equal(aChangedData.url, TEST_URL);
|
||||
Assert.equal(aChangedData.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(aChangedData.index, 5);
|
||||
|
||||
waitForBookmarkNotification("onItemAdded", function(aAddedData) {
|
||||
Assert.equal(aAddedData.title, TEST_TITLE);
|
||||
Assert.equal(aAddedData.url, TEST_URL);
|
||||
Assert.equal(aAddedData.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(aAddedData.index, 6);
|
||||
let id = aAddedData.id;
|
||||
|
||||
waitForBookmarkNotification("onItemMoved", function(aMovedData) {
|
||||
Assert.equal(aMovedData.id, id);
|
||||
Assert.equal(aMovedData.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(aMovedData.index, 1);
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
let txn = PlacesUIUtils.makeTransaction(
|
||||
wrapNodeByIdAndParent(aAddedData.id, PlacesUtils.unfiledBookmarksFolderId),
|
||||
0, // Unused for real nodes.
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
1, // Move to position 1.
|
||||
false
|
||||
);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
});
|
||||
|
||||
try {
|
||||
let txn = PlacesUIUtils.makeTransaction(
|
||||
wrapNodeByIdAndParent(aChangedData.id, PlacesUtils.unfiledBookmarksFolderId),
|
||||
0, // Unused for real nodes.
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
true
|
||||
);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
} catch (ex) {
|
||||
do_throw(ex);
|
||||
}
|
||||
}, "random-anno");
|
||||
|
||||
let id = PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
NetUtil.newURI(TEST_URL),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
TEST_TITLE);
|
||||
PlacesUtils.annotations.setItemAnnotation(id, PlacesUIUtils.DESCRIPTION_ANNO,
|
||||
"description", 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
PlacesUtils.annotations.setItemAnnotation(id, "random-anno",
|
||||
"random-value", 0,
|
||||
PlacesUtils.annotations.EXPIRE_NEVER);
|
||||
});
|
||||
|
||||
add_test(function test_visit() {
|
||||
const TEST_URL = "http://places.moz.org/";
|
||||
const TEST_TITLE = "Places bookmark";
|
||||
|
||||
waitForBookmarkNotification("onItemAdded", function(aAddedData) {
|
||||
Assert.equal(aAddedData.title, TEST_TITLE);
|
||||
Assert.equal(aAddedData.url, TEST_URL);
|
||||
Assert.equal(aAddedData.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(aAddedData.index, 7);
|
||||
|
||||
waitForBookmarkNotification("onItemAdded", function(aAddedData2) {
|
||||
Assert.equal(aAddedData2.title, TEST_TITLE);
|
||||
Assert.equal(aAddedData2.url, TEST_URL);
|
||||
Assert.equal(aAddedData2.type, PlacesUtils.bookmarks.TYPE_BOOKMARK);
|
||||
Assert.equal(aAddedData2.index, 8);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
try {
|
||||
let node = wrapNodeByIdAndParent(aAddedData.id, PlacesUtils.unfiledBookmarksFolderId);
|
||||
// Simulate a not-bookmarked node, will copy it to a new bookmark.
|
||||
node.id = -1;
|
||||
let txn = PlacesUIUtils.makeTransaction(
|
||||
node,
|
||||
0, // Unused for real nodes.
|
||||
PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
true
|
||||
);
|
||||
PlacesUtils.transactionManager.doTransaction(txn);
|
||||
} catch (ex) {
|
||||
do_throw(ex);
|
||||
}
|
||||
});
|
||||
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
NetUtil.newURI(TEST_URL),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
TEST_TITLE);
|
||||
});
|
||||
|
||||
add_test(function check_annotations() {
|
||||
// As last step check how many items for each annotation exist.
|
||||
|
||||
// Copies should retain the description annotation.
|
||||
let descriptions =
|
||||
PlacesUtils.annotations.getItemsWithAnnotation(PlacesUIUtils.DESCRIPTION_ANNO, {});
|
||||
Assert.equal(descriptions.length, 4);
|
||||
|
||||
// Only the original bookmarks should have this annotation.
|
||||
let others = PlacesUtils.annotations.getItemsWithAnnotation("random-anno", {});
|
||||
Assert.equal(others.length, 3);
|
||||
run_next_test();
|
||||
});
|
|
@ -22,5 +22,3 @@ support-files =
|
|||
[test_clearHistory_shutdown.js]
|
||||
[test_leftpane_corruption_handling.js]
|
||||
[test_PUIU_batchUpdatesForNode.js]
|
||||
[test_PUIU_makeTransaction.js]
|
||||
skip-if = (os == 'win' && ccov) # Bug 1423667
|
||||
|
|
Загрузка…
Ссылка в новой задаче