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:
Mark Banner 2018-01-22 13:36:41 +00:00
Родитель 3bdb37e019
Коммит 412e825e77
14 изменённых файлов: 63 добавлений и 1313 удалений

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

@ -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