Bug 1131491 - Remove old synchronous Place's transactions. r?mak draft
authorMark Banner <standard8@mozilla.com>
Mon, 22 Jan 2018 15:41:12 +0000
changeset 723438 170ad5b602421218d9906f4a51cbbc9362015a9a
parent 723437 e4261f4f8300ae09444d3bd1c15eaa6e6d0d405b
child 746857 8db61b35d85bf1f8d1cd5b723cd816855552e580
push id96427
push userbmo:standard8@mozilla.com
push dateTue, 23 Jan 2018 08:57:46 +0000
reviewersmak
bugs1131491
milestone60.0a1
Bug 1131491 - Remove old synchronous Place's transactions. r?mak MozReview-Commit-ID: FNCijeajgeh
services/sync/tests/unit/test_bookmark_tracker.js
toolkit/components/places/PlacesUtils.jsm
toolkit/components/places/tests/legacy/test_placesTxn.js
toolkit/components/places/tests/legacy/xpcshell.ini
tools/lint/eslint/modules.json
--- a/services/sync/tests/unit/test_bookmark_tracker.js
+++ b/services/sync/tests/unit/test_bookmark_tracker.js
@@ -1289,78 +1289,16 @@ add_task(async function test_async_onIte
     await verifyTrackedItems(["menu"]);
     Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE * 3);
   } finally {
     _("Clean up.");
     await cleanup();
   }
 });
 
-add_task(async function test_onItemMoved_setItemIndex() {
-  _("Items with updated indices should be tracked");
-
-  try {
-    await stopTracking();
-
-    let folder_id = PlacesUtils.bookmarks.createFolder(
-      PlacesUtils.bookmarks.bookmarksMenuFolder,
-      "Test folder",
-      PlacesUtils.bookmarks.DEFAULT_INDEX);
-    let folder_guid = await engine._store.GUIDForId(folder_id);
-    _(`Folder GUID: ${folder_guid}`);
-
-    let tb_id = PlacesUtils.bookmarks.insertBookmark(
-      folder_id,
-      CommonUtils.makeURI("http://getthunderbird.com"),
-      PlacesUtils.bookmarks.DEFAULT_INDEX,
-      "Thunderbird");
-    let tb_guid = await engine._store.GUIDForId(tb_id);
-    _(`Thunderbird GUID: ${tb_guid}`);
-
-    let fx_id = PlacesUtils.bookmarks.insertBookmark(
-      folder_id,
-      CommonUtils.makeURI("http://getfirefox.com"),
-      PlacesUtils.bookmarks.DEFAULT_INDEX,
-      "Firefox");
-    let fx_guid = await engine._store.GUIDForId(fx_id);
-    _(`Firefox GUID: ${fx_guid}`);
-
-    let moz_id = PlacesUtils.bookmarks.insertBookmark(
-      PlacesUtils.bookmarks.bookmarksMenuFolder,
-      CommonUtils.makeURI("https://mozilla.org"),
-      PlacesUtils.bookmarks.DEFAULT_INDEX,
-      "Mozilla"
-    );
-    let moz_guid = await engine._store.GUIDForId(moz_id);
-    _(`Mozilla GUID: ${moz_guid}`);
-
-    await startTracking();
-
-    // PlacesSortFolderByNameTransaction exercises
-    // PlacesUtils.bookmarks.setItemIndex.
-    let txn = new PlacesSortFolderByNameTransaction(folder_id);
-
-    // We're reordering items within the same folder, so only the folder
-    // should be tracked.
-    _("Execute the sort folder transaction");
-    txn.doTransaction();
-    await verifyTrackedItems([folder_guid]);
-    Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
-    await resetTracker();
-
-    _("Undo the sort folder transaction");
-    txn.undoTransaction();
-    await verifyTrackedItems([folder_guid]);
-    Assert.equal(tracker.score, SCORE_INCREMENT_XLARGE);
-  } finally {
-    _("Clean up.");
-    await cleanup();
-  }
-});
-
 add_task(async function test_onItemDeleted_removeFolderTransaction() {
   _("Folders removed in a transaction should be tracked");
 
   try {
     await stopTracking();
 
     _("Create a folder with two children");
     let folder_id = PlacesUtils.bookmarks.createFolder(
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -1,34 +1,14 @@
 /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-this.EXPORTED_SYMBOLS = [
-  "PlacesUtils",
-  "PlacesAggregatedTransaction",
-  "PlacesCreateFolderTransaction",
-  "PlacesCreateBookmarkTransaction",
-  "PlacesCreateSeparatorTransaction",
-  "PlacesCreateLivemarkTransaction",
-  "PlacesMoveItemTransaction",
-  "PlacesRemoveItemTransaction",
-  "PlacesEditItemTitleTransaction",
-  "PlacesEditBookmarkURITransaction",
-  "PlacesSetItemAnnotationTransaction",
-  "PlacesSetPageAnnotationTransaction",
-  "PlacesEditBookmarkKeywordTransaction",
-  "PlacesEditBookmarkPostDataTransaction",
-  "PlacesEditItemDateAddedTransaction",
-  "PlacesEditItemLastModifiedTransaction",
-  "PlacesSortFolderByNameTransaction",
-  "PlacesTagURITransaction",
-  "PlacesUntagURITransaction"
-];
+this.EXPORTED_SYMBOLS = ["PlacesUtils"];
 
 const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
 
 Cu.importGlobalProperties(["URL"]);
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/AppConstants.jsm");
 
@@ -38,21 +18,16 @@ XPCOMUtils.defineLazyModuleGetters(this,
   OS: "resource://gre/modules/osfile.jsm",
   Sqlite: "resource://gre/modules/Sqlite.jsm",
   Bookmarks: "resource://gre/modules/Bookmarks.jsm",
   History: "resource://gre/modules/History.jsm",
   AsyncShutdown: "resource://gre/modules/AsyncShutdown.jsm",
   PlacesSyncUtils: "resource://gre/modules/PlacesSyncUtils.jsm",
 });
 
-// The minimum amount of transactions before starting a batch. Usually we do
-// do incremental updates, a batch will cause views to completely
-// refresh instead.
-const MIN_TRANSACTIONS_FOR_BATCH = 5;
-
 // On Mac OSX, the transferable system converts "\r\n" to "\n\n", where
 // we really just want "\n". On other platforms, the transferable system
 // converts "\r\n" to "\n".
 const NEWLINE = AppConstants.platform == "macosx" ? "\n" : "\r\n";
 
 // Timers resolution is not always good, it can have a 16ms precision on Win.
 const TIMERS_RESOLUTION_SKEW_MS = 16;
 
@@ -598,20 +573,17 @@ this.PlacesUtils = {
       throw new Error(`${name}: The following properties were expected: ${[...required].join(", ")}`);
     return normalizedInput;
   },
 
   BOOKMARK_VALIDATORS,
   SYNC_BOOKMARK_VALIDATORS,
   SYNC_CHANGE_RECORD_VALIDATORS,
 
-  QueryInterface: XPCOMUtils.generateQI([
-    Ci.nsIObserver,
-    Ci.nsITransactionListener
-  ]),
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
 
   _shutdownFunctions: [],
   registerShutdownFunction: function PU_registerShutdownFunction(aFunc) {
     // If this is the first registered function, add the shutdown observer.
     if (this._shutdownFunctions.length == 0) {
       Services.obs.addObserver(this, this.TOPIC_SHUTDOWN);
     }
     this._shutdownFunctions.push(aFunc);
@@ -627,57 +599,16 @@ this.PlacesUtils = {
         }
         break;
     }
   },
 
   onPageAnnotationSet() {},
   onPageAnnotationRemoved() {},
 
-
-  // nsITransactionListener
-
-  didDo: function PU_didDo(aManager, aTransaction, aDoResult) {
-    updateCommandsOnActiveWindow();
-  },
-
-  didUndo: function PU_didUndo(aManager, aTransaction, aUndoResult) {
-    updateCommandsOnActiveWindow();
-  },
-
-  didRedo: function PU_didRedo(aManager, aTransaction, aRedoResult) {
-    updateCommandsOnActiveWindow();
-  },
-
-  didBeginBatch: function PU_didBeginBatch(aManager, aResult) {
-    // A no-op transaction is pushed to the stack, in order to make safe and
-    // easy to implement "Undo" an unknown number of transactions (including 0),
-    // "above" beginBatch and endBatch. Otherwise,implementing Undo that way
-    // head to dataloss: for example, if no changes were done in the
-    // edit-item panel, the last transaction on the undo stack would be the
-    // initial createItem transaction, or even worse, the batched editing of
-    // some other item.
-    // DO NOT MOVE this to the window scope, that would leak (bug 490068)!
-    this.transactionManager.doTransaction({ doTransaction() {},
-                                            undoTransaction() {},
-                                            redoTransaction() {},
-                                            isTransient: false,
-                                            merge() { return false; }
-                                          });
-  },
-
-  willDo: function PU_willDo() {},
-  willUndo: function PU_willUndo() {},
-  willRedo: function PU_willRedo() {},
-  willBeginBatch: function PU_willBeginBatch() {},
-  willEndBatch: function PU_willEndBatch() {},
-  didEndBatch: function PU_didEndBatch() {},
-  willMerge: function PU_willMerge() {},
-  didMerge: function PU_didMerge() {},
-
   /**
    * Determines whether or not a ResultNode is a host container.
    * @param   aNode
    *          A result node
    * @returns true if the node is a host container, false otherwise
    */
   nodeIsHost: function PU_nodeIsHost(aNode) {
     return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY &&
@@ -1991,48 +1922,16 @@ XPCOMUtils.defineLazyServiceGetter(Place
                                    "@mozilla.org/browser/livemark-service;2",
                                    "mozIAsyncLivemarks");
 
 XPCOMUtils.defineLazyGetter(PlacesUtils, "keywords", () => {
   gKeywordsCachePromise.catch(Cu.reportError);
   return Keywords;
 });
 
-XPCOMUtils.defineLazyGetter(PlacesUtils, "transactionManager", function() {
-  let tm = Cc["@mozilla.org/transactionmanager;1"].
-           createInstance(Ci.nsITransactionManager);
-  tm.AddListener(PlacesUtils);
-  this.registerShutdownFunction(function() {
-    // Clear all references to local transactions in the transaction manager,
-    // this prevents from leaking it.
-    this.transactionManager.RemoveListener(this);
-    this.transactionManager.clear();
-  });
-
-  // Bug 750269
-  // The transaction manager keeps strong references to transactions, and by
-  // that, also to the global for each transaction.  A transaction, however,
-  // could be either the transaction itself (for which the global is this
-  // module) or some js-proxy in another global, usually a window.  The later
-  // would leak because the transaction lifetime (in the manager's stacks)
-  // is independent of the global from which doTransaction was called.
-  // To avoid such a leak, we hide the native doTransaction from callers,
-  // and let each doTransaction call go through this module.
-  // Doing so ensures that, as long as the transaction is any of the
-  // PlacesXXXTransaction objects declared in this module, the object
-  // referenced by the transaction manager has the module itself as global.
-  return Object.create(tm, {
-    "doTransaction": {
-      value(aTransaction) {
-        tm.doTransaction(aTransaction);
-      }
-    }
-  });
-});
-
 XPCOMUtils.defineLazyGetter(this, "bundle", function() {
   const PLACES_STRING_BUNDLE_URI = "chrome://places/locale/places.properties";
   return Services.strings.createBundle(PLACES_STRING_BUNDLE_URI);
 });
 
 // This is just used as a reasonably-random value for copy & paste / drag operations.
 XPCOMUtils.defineLazyGetter(PlacesUtils, "instanceId", () => {
   return PlacesUtils.history.makeGuid();
@@ -2591,1237 +2490,16 @@ var GuidHelper = {
       PlacesUtils.bookmarks.addObserver(this.observer);
       PlacesUtils.registerShutdownFunction(() => {
         PlacesUtils.bookmarks.removeObserver(this.observer);
       });
     }
   }
 };
 
-// Transactions handlers.
-
-/**
- * Updates commands in the undo group of the active window commands.
- * Inactive windows commands will be updated on focus.
- */
-function updateCommandsOnActiveWindow() {
-  let win = Services.focus.activeWindow;
-  if (win && win instanceof Ci.nsIDOMWindow) {
-    // Updating "undo" will cause a group update including "redo".
-    win.updateCommands("undo");
-  }
-}
-
-
-/**
- * Used to cache bookmark information in transactions.
- *
- * @note To avoid leaks any non-primitive property should be copied.
- * @note Used internally, DO NOT EXPORT.
- */
-function TransactionItemCache() {
-}
-
-TransactionItemCache.prototype = {
-  set id(v) {
-    this._id = (parseInt(v) > 0 ? v : null);
-  },
-  get id() {
-    return this._id || -1;
-  },
-  set parentId(v) {
-    this._parentId = (parseInt(v) > 0 ? v : null);
-  },
-  get parentId() {
-    return this._parentId || -1;
-  },
-  keyword: null,
-  title: null,
-  dateAdded: null,
-  lastModified: null,
-  postData: null,
-  itemType: null,
-  set uri(v) {
-    this._uri = (v instanceof Ci.nsIURI ? v.clone() : null);
-  },
-  get uri() {
-    return this._uri || null;
-  },
-  set feedURI(v) {
-    this._feedURI = (v instanceof Ci.nsIURI ? v.clone() : null);
-  },
-  get feedURI() {
-    return this._feedURI || null;
-  },
-  set siteURI(v) {
-    this._siteURI = (v instanceof Ci.nsIURI ? v.clone() : null);
-  },
-  get siteURI() {
-    return this._siteURI || null;
-  },
-  set index(v) {
-    this._index = (parseInt(v) >= 0 ? v : null);
-  },
-  // Index can be 0.
-  get index() {
-    return this._index != null ? this._index : PlacesUtils.bookmarks.DEFAULT_INDEX;
-  },
-  set annotations(v) {
-    this._annotations = Array.isArray(v) ? Cu.cloneInto(v, {}) : null;
-  },
-  get annotations() {
-    return this._annotations || null;
-  },
-  set tags(v) {
-    this._tags = (v && Array.isArray(v) ? Array.prototype.slice.call(v) : null);
-  },
-  get tags() {
-    return this._tags || null;
-  },
-};
-
-
-/**
- * Base transaction implementation.
- *
- * @note used internally, DO NOT EXPORT.
- */
-function BaseTransaction() {
-}
-
-BaseTransaction.prototype = {
-  name: null,
-  set childTransactions(v) {
-    this._childTransactions = (Array.isArray(v) ? Array.prototype.slice.call(v) : null);
-  },
-  get childTransactions() {
-    return this._childTransactions || null;
-  },
-  doTransaction: function BTXN_doTransaction() {},
-  redoTransaction: function BTXN_redoTransaction() {
-    return this.doTransaction();
-  },
-  undoTransaction: function BTXN_undoTransaction() {},
-  merge: function BTXN_merge() {
-    return false;
-  },
-  get isTransient() {
-    return false;
-  },
-  QueryInterface: XPCOMUtils.generateQI([
-    Ci.nsITransaction
-  ]),
-};
-
-
-/**
- * Transaction for performing several Places Transactions in a single batch.
- *
- * @param aName
- *        title of the aggregate transactions
- * @param aTransactions
- *        an array of transactions to perform
- *
- * @return nsITransaction object
- */
-this.PlacesAggregatedTransaction =
- function PlacesAggregatedTransaction(aName, aTransactions) {
-  // Copy the transactions array to decouple it from its prototype, which
-  // otherwise keeps alive its associated global object.
-  this.childTransactions = aTransactions;
-  this.name = aName;
-  this.item = new TransactionItemCache();
-
-  // Check child transactions number.  We will batch if we have more than
-  // MIN_TRANSACTIONS_FOR_BATCH total number of transactions.
-  let countTransactions = function(aTransactions, aTxnCount) {
-    for (let i = 0;
-         i < aTransactions.length && aTxnCount < MIN_TRANSACTIONS_FOR_BATCH;
-         ++i, ++aTxnCount) {
-      let txn = aTransactions[i];
-      if (txn.childTransactions && txn.childTransactions.length > 0)
-        aTxnCount = countTransactions(txn.childTransactions, aTxnCount);
-    }
-    return aTxnCount;
-  };
-
-  let txnCount = countTransactions(this.childTransactions, 0);
-  this._useBatch = txnCount >= MIN_TRANSACTIONS_FOR_BATCH;
-};
-
-PlacesAggregatedTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function ATXN_doTransaction() {
-    this._isUndo = false;
-    if (this._useBatch)
-      PlacesUtils.bookmarks.runInBatchMode(this, null);
-    else
-      this.runBatched(false);
-  },
-
-  undoTransaction: function ATXN_undoTransaction() {
-    this._isUndo = true;
-    if (this._useBatch)
-      PlacesUtils.bookmarks.runInBatchMode(this, null);
-    else
-      this.runBatched(true);
-  },
-
-  runBatched: function ATXN_runBatched() {
-    // Use a copy of the transactions array, so we won't reverse the original
-    // one on undoing.
-    let transactions = this.childTransactions.slice(0);
-    if (this._isUndo)
-      transactions.reverse();
-    for (let i = 0; i < transactions.length; ++i) {
-      let txn = transactions[i];
-      if (this.item.parentId != -1)
-        txn.item.parentId = this.item.parentId;
-      if (this._isUndo)
-        txn.undoTransaction();
-      else
-        txn.doTransaction();
-    }
-  }
-};
-
-
-/**
- * Transaction for creating a new folder.
- *
- * @param aTitle
- *        the title for the new folder
- * @param aParentId
- *        the id of the parent folder in which the new folder should be added
- * @param [optional] aIndex
- *        the index of the item in aParentId
- * @param [optional] aAnnotations
- *        array of annotations to set for the new folder
- * @param [optional] aChildTransactions
- *        array of transactions for items to be created in the new folder
- *
- * @return nsITransaction object
- */
-this.PlacesCreateFolderTransaction =
- function PlacesCreateFolderTransaction(aTitle, aParentId, aIndex, aAnnotations,
-                                        aChildTransactions) {
-  this.item = new TransactionItemCache();
-  this.item.title = aTitle;
-  this.item.parentId = aParentId;
-  this.item.index = aIndex;
-  this.item.annotations = aAnnotations;
-  this.childTransactions = aChildTransactions;
-};
-
-PlacesCreateFolderTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function CFTXN_doTransaction() {
-    this.item.id = PlacesUtils.bookmarks.createFolder(this.item.parentId,
-                                                      this.item.title,
-                                                      this.item.index);
-    if (this.item.annotations && this.item.annotations.length > 0)
-      PlacesUtils.setAnnotationsForItem(this.item.id, this.item.annotations);
-
-    if (this.childTransactions && this.childTransactions.length > 0) {
-      // Set the new parent id into child transactions.
-      for (let i = 0; i < this.childTransactions.length; ++i) {
-        this.childTransactions[i].item.parentId = this.item.id;
-      }
-
-      let txn = new PlacesAggregatedTransaction("Create folder childTxn",
-                                                this.childTransactions);
-      txn.doTransaction();
-    }
-  },
-
-  undoTransaction: function CFTXN_undoTransaction() {
-    if (this.childTransactions && this.childTransactions.length > 0) {
-      let txn = new PlacesAggregatedTransaction("Create folder childTxn",
-                                                this.childTransactions);
-      txn.undoTransaction();
-    }
-
-    // Remove item only after all child transactions have been reverted.
-    PlacesUtils.bookmarks.removeItem(this.item.id);
-  }
-};
-
-
-/**
- * Transaction for creating a new bookmark.
- *
- * @param aURI
- *        the nsIURI of the new bookmark
- * @param aParentId
- *        the id of the folder in which the bookmark should be added.
- * @param [optional] aIndex
- *        the index of the item in aParentId
- * @param [optional] aTitle
- *        the title of the new bookmark
- * @param [optional] aKeyword
- *        the keyword for the new bookmark
- * @param [optional] aAnnotations
- *        array of annotations to set for the new bookmark
- * @param [optional] aChildTransactions
- *        child transactions to commit after creating the bookmark. Prefer
- *        using any of the arguments above if possible. In general, a child
- *        transations should be used only if the change it does has to be
- *        reverted manually when removing the bookmark item.
- *        a child transaction must support setting its bookmark-item
- *        identifier via an "id" js setter.
- * @param [optional] aPostData
- *        keyword's POST data, if available.
- *
- * @return nsITransaction object
- */
-this.PlacesCreateBookmarkTransaction =
- function PlacesCreateBookmarkTransaction(aURI, aParentId, aIndex, aTitle,
-                                          aKeyword, aAnnotations,
-                                          aChildTransactions, aPostData) {
-  this.item = new TransactionItemCache();
-  this.item.uri = aURI;
-  this.item.parentId = aParentId;
-  this.item.index = aIndex;
-  this.item.title = aTitle;
-  this.item.keyword = aKeyword;
-  this.item.postData = aPostData;
-  this.item.annotations = aAnnotations;
-  this.childTransactions = aChildTransactions;
-};
-
-PlacesCreateBookmarkTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function CITXN_doTransaction() {
-    this.item.id = PlacesUtils.bookmarks.insertBookmark(this.item.parentId,
-                                                        this.item.uri,
-                                                        this.item.index,
-                                                        this.item.title);
-    if (this.item.keyword) {
-      PlacesUtils.bookmarks.setKeywordForBookmark(this.item.id,
-                                                  this.item.keyword);
-      if (this.item.postData) {
-        PlacesUtils.setPostDataForBookmark(this.item.id,
-                                           this.item.postData);
-      }
-    }
-    if (this.item.annotations && this.item.annotations.length > 0)
-      PlacesUtils.setAnnotationsForItem(this.item.id, this.item.annotations);
-
-    if (this.childTransactions && this.childTransactions.length > 0) {
-      // Set the new item id into child transactions.
-      for (let i = 0; i < this.childTransactions.length; ++i) {
-        this.childTransactions[i].item.id = this.item.id;
-      }
-      let txn = new PlacesAggregatedTransaction("Create item childTxn",
-                                                this.childTransactions);
-      txn.doTransaction();
-    }
-  },
-
-  undoTransaction: function CITXN_undoTransaction() {
-    if (this.childTransactions && this.childTransactions.length > 0) {
-      // Undo transactions should always be done in reverse order.
-      let txn = new PlacesAggregatedTransaction("Create item childTxn",
-                                                this.childTransactions);
-      txn.undoTransaction();
-    }
-
-    // Remove item only after all child transactions have been reverted.
-    PlacesUtils.bookmarks.removeItem(this.item.id);
-  }
-};
-
-
-/**
- * Transaction for creating a new separator.
- *
- * @param aParentId
- *        the id of the folder in which the separator should be added
- * @param [optional] aIndex
- *        the index of the item in aParentId
- *
- * @return nsITransaction object
- */
-this.PlacesCreateSeparatorTransaction =
- function PlacesCreateSeparatorTransaction(aParentId, aIndex) {
-  this.item = new TransactionItemCache();
-  this.item.parentId = aParentId;
-  this.item.index = aIndex;
-};
-
-PlacesCreateSeparatorTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function CSTXN_doTransaction() {
-    this.item.id =
-      PlacesUtils.bookmarks.insertSeparator(this.item.parentId, this.item.index);
-  },
-
-  undoTransaction: function CSTXN_undoTransaction() {
-    PlacesUtils.bookmarks.removeItem(this.item.id);
-  }
-};
-
-
-/**
- * Transaction for creating a new livemark item.
- *
- * @see mozIAsyncLivemarks for documentation regarding the arguments.
- *
- * @param aFeedURI
- *        nsIURI of the feed
- * @param [optional] aSiteURI
- *        nsIURI of the page serving the feed
- * @param aTitle
- *        title for the livemark
- * @param aParentId
- *        the id of the folder in which the livemark should be added
- * @param [optional]  aIndex
- *        the index of the livemark in aParentId
- * @param [optional] aAnnotations
- *        array of annotations to set for the new livemark.
- *
- * @return nsITransaction object
- */
-this.PlacesCreateLivemarkTransaction =
- function PlacesCreateLivemarkTransaction(aFeedURI, aSiteURI, aTitle, aParentId,
-                                          aIndex, aAnnotations) {
-  this.item = new TransactionItemCache();
-  this.item.feedURI = aFeedURI;
-  this.item.siteURI = aSiteURI;
-  this.item.title = aTitle;
-  this.item.parentId = aParentId;
-  this.item.index = aIndex;
-  this.item.annotations = aAnnotations;
-};
-
-PlacesCreateLivemarkTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function CLTXN_doTransaction() {
-    this._promise = PlacesUtils.livemarks.addLivemark(
-      { title: this.item.title,
-        feedURI: this.item.feedURI,
-        parentId: this.item.parentId,
-        index: this.item.index,
-        siteURI: this.item.siteURI
-      }).then(aLivemark => {
-        this.item.id = aLivemark.id;
-        if (this.item.annotations && this.item.annotations.length > 0) {
-          PlacesUtils.setAnnotationsForItem(this.item.id,
-                                            this.item.annotations);
-        }
-      }, Cu.reportError);
-  },
-
-  undoTransaction: function CLTXN_undoTransaction() {
-    // The getLivemark callback may fail, but it is used just to serialize,
-    // so it doesn't matter.
-    this._promise = PlacesUtils.livemarks.getLivemark({ id: this.item.id })
-      .catch(() => {}).then(() => {
-        PlacesUtils.bookmarks.removeItem(this.item.id);
-      });
-  }
-};
-
-
-/**
- * Transaction for removing a livemark item.
- *
- * @param aLivemarkId
- *        the identifier of the folder for the livemark.
- *
- * @return nsITransaction object
- * @note used internally by PlacesRemoveItemTransaction, DO NOT EXPORT.
- */
-function PlacesRemoveLivemarkTransaction(aLivemarkId) {
-  this.item = new TransactionItemCache();
-  this.item.id = aLivemarkId;
-  this.item.title = PlacesUtils.bookmarks.getItemTitle(this.item.id);
-  this.item.parentId = PlacesUtils.bookmarks.getFolderIdForItem(this.item.id);
-
-  let annos = PlacesUtils.getAnnotationsForItem(this.item.id);
-  // Exclude livemark service annotations, those will be recreated automatically
-  let annosToExclude = [PlacesUtils.LMANNO_FEEDURI,
-                        PlacesUtils.LMANNO_SITEURI];
-  this.item.annotations = annos.filter(function(aValue, aIndex, aArray) {
-      return !annosToExclude.includes(aValue.name);
-    });
-  this.item.dateAdded = PlacesUtils.bookmarks.getItemDateAdded(this.item.id);
-  this.item.lastModified =
-    PlacesUtils.bookmarks.getItemLastModified(this.item.id);
-}
-
-PlacesRemoveLivemarkTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function RLTXN_doTransaction() {
-    PlacesUtils.livemarks.getLivemark({ id: this.item.id })
-      .then(aLivemark => {
-        this.item.feedURI = aLivemark.feedURI;
-        this.item.siteURI = aLivemark.siteURI;
-        PlacesUtils.bookmarks.removeItem(this.item.id);
-      }, Cu.reportError);
-  },
-
-  undoTransaction: function RLTXN_undoTransaction() {
-    // Undo work must be serialized, otherwise won't be able to know the
-    // feedURI and siteURI of the livemark.
-    // The getLivemark callback is expected to receive a failure status but it
-    // is used just to serialize, so doesn't matter.
-    PlacesUtils.livemarks.getLivemark({ id: this.item.id })
-      .catch(() => {
-        PlacesUtils.livemarks.addLivemark({ parentId: this.item.parentId,
-                                            title: this.item.title,
-                                            siteURI: this.item.siteURI,
-                                            feedURI: this.item.feedURI,
-                                            index: this.item.index,
-                                            lastModified: this.item.lastModified
-                                          }).then(
-          aLivemark => {
-            let itemId = aLivemark.id;
-            PlacesUtils.bookmarks.setItemDateAdded(itemId, this.item.dateAdded);
-            PlacesUtils.setAnnotationsForItem(itemId, this.item.annotations);
-          }, Cu.reportError);
-      });
-  }
-};
-
-
-/**
- * Transaction for moving an Item.
- *
- * @param aItemId
- *        the id of the item to move
- * @param aNewParentId
- *        id of the new parent to move to
- * @param aNewIndex
- *        index of the new position to move to
- *
- * @return nsITransaction object
- */
-this.PlacesMoveItemTransaction =
- function PlacesMoveItemTransaction(aItemId, aNewParentId, aNewIndex) {
-  this.item = new TransactionItemCache();
-  this.item.id = aItemId;
-  this.item.parentId = PlacesUtils.bookmarks.getFolderIdForItem(this.item.id);
-  this.new = new TransactionItemCache();
-  this.new.parentId = aNewParentId;
-  this.new.index = aNewIndex;
-};
-
-PlacesMoveItemTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function MITXN_doTransaction() {
-    this.item.index = PlacesUtils.bookmarks.getItemIndex(this.item.id);
-    PlacesUtils.bookmarks.moveItem(this.item.id,
-                                   this.new.parentId, this.new.index);
-    this._undoIndex = PlacesUtils.bookmarks.getItemIndex(this.item.id);
-  },
-
-  undoTransaction: function MITXN_undoTransaction() {
-    // moving down in the same parent takes in count removal of the item
-    // so to revert positions we must move to oldIndex + 1
-    if (this.new.parentId == this.item.parentId &&
-        this.item.index > this._undoIndex) {
-      PlacesUtils.bookmarks.moveItem(this.item.id, this.item.parentId,
-                                     this.item.index + 1);
-    } else {
-      PlacesUtils.bookmarks.moveItem(this.item.id, this.item.parentId,
-                                     this.item.index);
-    }
-  }
-};
-
-
-/**
- * Transaction for removing an Item
- *
- * @param aItemId
- *        id of the item to remove
- *
- * @return nsITransaction object
- */
-this.PlacesRemoveItemTransaction =
- function PlacesRemoveItemTransaction(aItemId) {
-  if (PlacesUtils.isRootItem(aItemId))
-    throw Cr.NS_ERROR_INVALID_ARG;
-
-  // if the item lives within a tag container, use the tagging transactions
-  let parent = PlacesUtils.bookmarks.getFolderIdForItem(aItemId);
-  let grandparent = PlacesUtils.bookmarks.getFolderIdForItem(parent);
-  if (grandparent == PlacesUtils.tagsFolderId) {
-    let uri = PlacesUtils.bookmarks.getBookmarkURI(aItemId);
-    return new PlacesUntagURITransaction(uri, [parent]);
-  }
-
-  // if the item is a livemark container we will not save its children.
-  if (PlacesUtils.annotations.itemHasAnnotation(aItemId,
-                                                PlacesUtils.LMANNO_FEEDURI))
-    return new PlacesRemoveLivemarkTransaction(aItemId);
-
-  this.item = new TransactionItemCache();
-  this.item.id = aItemId;
-  this.item.itemType = PlacesUtils.bookmarks.getItemType(this.item.id);
-  if (this.item.itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
-    this.childTransactions = this._getFolderContentsTransactions();
-    // Remove this folder itself.
-    let txn = PlacesUtils.bookmarks.getRemoveFolderTransaction(this.item.id);
-    this.childTransactions.push(txn);
-  } else if (this.item.itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK) {
-    this.item.uri = PlacesUtils.bookmarks.getBookmarkURI(this.item.id);
-    this.item.keyword =
-      PlacesUtils.bookmarks.getKeywordForBookmark(this.item.id);
-    if (this.item.keyword)
-      this.item.postData = PlacesUtils.getPostDataForBookmark(this.item.id);
-  }
-
-  if (this.item.itemType != Ci.nsINavBookmarksService.TYPE_SEPARATOR)
-    this.item.title = PlacesUtils.bookmarks.getItemTitle(this.item.id);
-
-  this.item.parentId = PlacesUtils.bookmarks.getFolderIdForItem(this.item.id);
-  this.item.annotations = PlacesUtils.getAnnotationsForItem(this.item.id);
-  this.item.dateAdded = PlacesUtils.bookmarks.getItemDateAdded(this.item.id);
-  this.item.lastModified =
-    PlacesUtils.bookmarks.getItemLastModified(this.item.id);
-};
-
-PlacesRemoveItemTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function RITXN_doTransaction() {
-    this.item.index = PlacesUtils.bookmarks.getItemIndex(this.item.id);
-
-    if (this.item.itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
-      let txn = new PlacesAggregatedTransaction("Remove item childTxn",
-                                                this.childTransactions);
-      txn.doTransaction();
-    } else {
-      // Before removing the bookmark, save its tags.
-      let tags = this.item.uri ?
-        PlacesUtils.tagging.getTagsForURI(this.item.uri) : null;
-
-      PlacesUtils.bookmarks.removeItem(this.item.id);
-
-      // If this was the last bookmark (excluding tag-items) for this url,
-      // persist the tags.
-      if (tags && PlacesUtils.getMostRecentBookmarkForURI(this.item.uri) == -1) {
-        this.item.tags = tags;
-      }
-    }
-  },
-
-  undoTransaction: function RITXN_undoTransaction() {
-    if (this.item.itemType == Ci.nsINavBookmarksService.TYPE_BOOKMARK) {
-      this.item.id = PlacesUtils.bookmarks.insertBookmark(this.item.parentId,
-                                                          this.item.uri,
-                                                          this.item.index,
-                                                          this.item.title);
-      if (this.item.tags && this.item.tags.length > 0)
-        PlacesUtils.tagging.tagURI(this.item.uri, this.item.tags);
-      if (this.item.keyword) {
-        PlacesUtils.bookmarks.setKeywordForBookmark(this.item.id,
-                                                    this.item.keyword);
-        if (this.item.postData) {
-          PlacesUtils.bookmarks.setPostDataForBookmark(this.item.id);
-        }
-      }
-    } else if (this.item.itemType == Ci.nsINavBookmarksService.TYPE_FOLDER) {
-      let txn = new PlacesAggregatedTransaction("Remove item childTxn",
-                                                this.childTransactions);
-      txn.undoTransaction();
-    } else { // TYPE_SEPARATOR
-      this.item.id = PlacesUtils.bookmarks.insertSeparator(this.item.parentId,
-                                                            this.item.index);
-    }
-
-    if (this.item.annotations && this.item.annotations.length > 0)
-      PlacesUtils.setAnnotationsForItem(this.item.id, this.item.annotations);
-
-    PlacesUtils.bookmarks.setItemDateAdded(this.item.id, this.item.dateAdded);
-    PlacesUtils.bookmarks.setItemLastModified(this.item.id,
-                                              this.item.lastModified);
-  },
-
-  /**
-  * Returns a flat, ordered list of transactions for a depth-first recreation
-  * of items within this folder.
-  */
-  _getFolderContentsTransactions:
-  function RITXN__getFolderContentsTransactions() {
-    let transactions = [];
-    let contents =
-      PlacesUtils.getFolderContents(this.item.id, false, false).root;
-    for (let i = 0; i < contents.childCount; ++i) {
-      let txn = new PlacesRemoveItemTransaction(contents.getChild(i).itemId);
-      transactions.push(txn);
-    }
-    contents.containerOpen = false;
-    // Reverse transactions to preserve parent-child relationship.
-    return transactions.reverse();
-  }
-};
-
-
-/**
- * Transaction for editting a bookmark's title.
- *
- * @param aItemId
- *        id of the item to edit
- * @param aNewTitle
- *        new title for the item to edit
- *
- * @return nsITransaction object
- */
-this.PlacesEditItemTitleTransaction =
- function PlacesEditItemTitleTransaction(aItemId, aNewTitle) {
-  this.item = new TransactionItemCache();
-  this.item.id = aItemId;
-  this.new = new TransactionItemCache();
-  this.new.title = aNewTitle;
-};
-
-PlacesEditItemTitleTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function EITTXN_doTransaction() {
-    this.item.title = PlacesUtils.bookmarks.getItemTitle(this.item.id);
-    PlacesUtils.bookmarks.setItemTitle(this.item.id, this.new.title);
-  },
-
-  undoTransaction: function EITTXN_undoTransaction() {
-    PlacesUtils.bookmarks.setItemTitle(this.item.id, this.item.title);
-  }
-};
-
-
-/**
- * Transaction for editing a bookmark's uri.
- *
- * @param aItemId
- *        id of the bookmark to edit
- * @param aNewURI
- *        new uri for the bookmark
- *
- * @return nsITransaction object
- */
-this.PlacesEditBookmarkURITransaction =
- function PlacesEditBookmarkURITransaction(aItemId, aNewURI) {
-  this.item = new TransactionItemCache();
-  this.item.id = aItemId;
-  this.new = new TransactionItemCache();
-  this.new.uri = aNewURI;
-};
-
-PlacesEditBookmarkURITransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function EBUTXN_doTransaction() {
-    this.item.uri = PlacesUtils.bookmarks.getBookmarkURI(this.item.id);
-    PlacesUtils.bookmarks.changeBookmarkURI(this.item.id, this.new.uri);
-    // move tags from old URI to new URI
-    this.item.tags = PlacesUtils.tagging.getTagsForURI(this.item.uri);
-    if (this.item.tags.length > 0) {
-      // only untag the old URI if this is the only bookmark
-      if (PlacesUtils.getBookmarksForURI(this.item.uri, {}).length == 0)
-        PlacesUtils.tagging.untagURI(this.item.uri, this.item.tags);
-      PlacesUtils.tagging.tagURI(this.new.uri, this.item.tags);
-    }
-  },
-
-  undoTransaction: function EBUTXN_undoTransaction() {
-    PlacesUtils.bookmarks.changeBookmarkURI(this.item.id, this.item.uri);
-    // move tags from new URI to old URI
-    if (this.item.tags.length > 0) {
-      // only untag the new URI if this is the only bookmark
-      if (PlacesUtils.getBookmarksForURI(this.new.uri, {}).length == 0)
-        PlacesUtils.tagging.untagURI(this.new.uri, this.item.tags);
-      PlacesUtils.tagging.tagURI(this.item.uri, this.item.tags);
-    }
-  }
-};
-
-
-/**
- * Transaction for setting/unsetting an item annotation
- *
- * @param aItemId
- *        id of the item where to set annotation
- * @param aAnnotationObject
- *        Object representing an annotation, containing the following
- *        properties: name, flags, expires, value.
- *        If value is null the annotation will be removed
- *
- * @return nsITransaction object
- */
-this.PlacesSetItemAnnotationTransaction =
- function PlacesSetItemAnnotationTransaction(aItemId, aAnnotationObject) {
-  this.item = new TransactionItemCache();
-  this.item.id = aItemId;
-  this.new = new TransactionItemCache();
-  this.new.annotations = [aAnnotationObject];
-};
-
-PlacesSetItemAnnotationTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function SIATXN_doTransaction() {
-    let annoName = this.new.annotations[0].name;
-    if (PlacesUtils.annotations.itemHasAnnotation(this.item.id, annoName)) {
-      // fill the old anno if it is set
-      let flags = {}, expires = {}, type = {};
-      PlacesUtils.annotations.getItemAnnotationInfo(this.item.id, annoName, flags,
-                                                    expires, type);
-      let value = PlacesUtils.annotations.getItemAnnotation(this.item.id,
-                                                            annoName);
-      this.item.annotations = [{ name: annoName,
-                                type: type.value,
-                                flags: flags.value,
-                                value,
-                                expires: expires.value }];
-    } else {
-      // create an empty old anno
-      this.item.annotations = [{ name: annoName,
-                                flags: 0,
-                                value: null,
-                                expires: Ci.nsIAnnotationService.EXPIRE_NEVER }];
-    }
-
-    PlacesUtils.setAnnotationsForItem(this.item.id, this.new.annotations);
-  },
-
-  undoTransaction: function SIATXN_undoTransaction() {
-    PlacesUtils.setAnnotationsForItem(this.item.id, this.item.annotations);
-  }
-};
-
-
-/**
- * Transaction for setting/unsetting a page annotation
- *
- * @param aURI
- *        URI of the page where to set annotation
- * @param aAnnotationObject
- *        Object representing an annotation, containing the following
- *        properties: name, flags, expires, value.
- *        If value is null the annotation will be removed
- *
- * @return nsITransaction object
- */
-this.PlacesSetPageAnnotationTransaction =
- function PlacesSetPageAnnotationTransaction(aURI, aAnnotationObject) {
-  this.item = new TransactionItemCache();
-  this.item.uri = aURI;
-  this.new = new TransactionItemCache();
-  this.new.annotations = [aAnnotationObject];
-};
-
-PlacesSetPageAnnotationTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function SPATXN_doTransaction() {
-    let annoName = this.new.annotations[0].name;
-    if (PlacesUtils.annotations.pageHasAnnotation(this.item.uri, annoName)) {
-      // fill the old anno if it is set
-      let flags = {}, expires = {}, type = {};
-      PlacesUtils.annotations.getPageAnnotationInfo(this.item.uri, annoName, flags,
-                                                    expires, type);
-      let value = PlacesUtils.annotations.getPageAnnotation(this.item.uri,
-                                                            annoName);
-      this.item.annotations = [{ name: annoName,
-                                flags: flags.value,
-                                value,
-                                expires: expires.value }];
-    } else {
-      // create an empty old anno
-      this.item.annotations = [{ name: annoName,
-                                type: Ci.nsIAnnotationService.TYPE_STRING,
-                                flags: 0,
-                                value: null,
-                                expires: Ci.nsIAnnotationService.EXPIRE_NEVER }];
-    }
-
-    PlacesUtils.setAnnotationsForURI(this.item.uri, this.new.annotations);
-  },
-
-  undoTransaction: function SPATXN_undoTransaction() {
-    PlacesUtils.setAnnotationsForURI(this.item.uri, this.item.annotations);
-  }
-};
-
-
-/**
- * Transaction for editing a bookmark's keyword.
- *
- * @param aItemId
- *        id of the bookmark to edit
- * @param aNewKeyword
- *        new keyword for the bookmark
- * @param aNewPostData [optional]
- *        new keyword's POST data, if available
- * @param aOldKeyword [optional]
- *        old keyword of the bookmark
- *
- * @return nsITransaction object
- */
-this.PlacesEditBookmarkKeywordTransaction =
-  function PlacesEditBookmarkKeywordTransaction(aItemId, aNewKeyword,
-                                                aNewPostData, aOldKeyword) {
-  this.item = new TransactionItemCache();
-  this.item.id = aItemId;
-  this.item.keyword = aOldKeyword;
-  this.item.href = (PlacesUtils.bookmarks.getBookmarkURI(aItemId)).spec;
-  this.new = new TransactionItemCache();
-  this.new.keyword = aNewKeyword;
-  this.new.postData = aNewPostData;
-};
-
-PlacesEditBookmarkKeywordTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function EBKTXN_doTransaction() {
-    let done = false;
-    (async () => {
-      if (this.item.keyword) {
-        let oldEntry = await PlacesUtils.keywords.fetch(this.item.keyword);
-        this.item.postData = oldEntry.postData;
-        await PlacesUtils.keywords.remove(this.item.keyword);
-      }
-
-      if (this.new.keyword) {
-        await PlacesUtils.keywords.insert({
-          url: this.item.href,
-          keyword: this.new.keyword,
-          postData: this.new.postData || this.item.postData
-        });
-      }
-    })().catch(Cu.reportError)
-                 .then(() => done = true);
-    // TODO: Until we can move to PlacesTransactions.jsm, we must spin the
-    // events loop :(
-    Services.tm.spinEventLoopUntil(() => done);
-  },
-
-  undoTransaction: function EBKTXN_undoTransaction() {
-
-    let done = false;
-    (async () => {
-      if (this.new.keyword) {
-        await PlacesUtils.keywords.remove(this.new.keyword);
-      }
-
-      if (this.item.keyword) {
-        await PlacesUtils.keywords.insert({
-          url: this.item.href,
-          keyword: this.item.keyword,
-          postData: this.item.postData
-        });
-      }
-    })().catch(Cu.reportError)
-                 .then(() => done = true);
-    // TODO: Until we can move to PlacesTransactions.jsm, we must spin the
-    // events loop :(
-    Services.tm.spinEventLoopUntil(() => {
-      return done;
-    });
-  }
-};
-
-
-/**
- * Transaction for editing the post data associated with a bookmark.
- *
- * @param aItemId
- *        id of the bookmark to edit
- * @param aPostData
- *        post data
- *
- * @return nsITransaction object
- */
-this.PlacesEditBookmarkPostDataTransaction =
- function PlacesEditBookmarkPostDataTransaction(aItemId, aPostData) {
-  this.item = new TransactionItemCache();
-  this.item.id = aItemId;
-  this.new = new TransactionItemCache();
-  this.new.postData = aPostData;
-};
-
-PlacesEditBookmarkPostDataTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction() {
-    // Setting null postData is not supported by the current schema.
-    if (this.new.postData) {
-      this.item.postData = PlacesUtils.getPostDataForBookmark(this.item.id);
-      PlacesUtils.setPostDataForBookmark(this.item.id, this.new.postData);
-    }
-  },
-
-  undoTransaction() {
-    // Setting null postData is not supported by the current schema.
-    if (this.item.postData) {
-      PlacesUtils.setPostDataForBookmark(this.item.id, this.item.postData);
-    }
-  }
-};
-
-
-/**
- * Transaction for editing an item's date added property.
- *
- * @param aItemId
- *        id of the item to edit
- * @param aNewDateAdded
- *        new date added for the item
- *
- * @return nsITransaction object
- */
-this.PlacesEditItemDateAddedTransaction =
- function PlacesEditItemDateAddedTransaction(aItemId, aNewDateAdded) {
-  this.item = new TransactionItemCache();
-  this.item.id = aItemId;
-  this.new = new TransactionItemCache();
-  this.new.dateAdded = aNewDateAdded;
-};
-
-PlacesEditItemDateAddedTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function EIDATXN_doTransaction() {
-    // Child transactions have the id set as parentId.
-    if (this.item.id == -1 && this.item.parentId != -1)
-      this.item.id = this.item.parentId;
-    this.item.dateAdded =
-      PlacesUtils.bookmarks.getItemDateAdded(this.item.id);
-    PlacesUtils.bookmarks.setItemDateAdded(this.item.id, this.new.dateAdded);
-  },
-
-  undoTransaction: function EIDATXN_undoTransaction() {
-    PlacesUtils.bookmarks.setItemDateAdded(this.item.id, this.item.dateAdded);
-  }
-};
-
-
-/**
- * Transaction for editing an item's last modified time.
- *
- * @param aItemId
- *        id of the item to edit
- * @param aNewLastModified
- *        new last modified date for the item
- *
- * @return nsITransaction object
- */
-this.PlacesEditItemLastModifiedTransaction =
- function PlacesEditItemLastModifiedTransaction(aItemId, aNewLastModified) {
-  this.item = new TransactionItemCache();
-  this.item.id = aItemId;
-  this.new = new TransactionItemCache();
-  this.new.lastModified = aNewLastModified;
-};
-
-PlacesEditItemLastModifiedTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction:
-  function EILMTXN_doTransaction() {
-    // Child transactions have the id set as parentId.
-    if (this.item.id == -1 && this.item.parentId != -1)
-      this.item.id = this.item.parentId;
-    this.item.lastModified =
-      PlacesUtils.bookmarks.getItemLastModified(this.item.id);
-    PlacesUtils.bookmarks.setItemLastModified(this.item.id,
-                                              this.new.lastModified);
-  },
-
-  undoTransaction:
-  function EILMTXN_undoTransaction() {
-    PlacesUtils.bookmarks.setItemLastModified(this.item.id,
-                                              this.item.lastModified);
-  }
-};
-
-
-/**
- * Transaction for sorting a folder by name
- *
- * @param aFolderId
- *        id of the folder to sort
- *
- * @return nsITransaction object
- */
-this.PlacesSortFolderByNameTransaction =
- function PlacesSortFolderByNameTransaction(aFolderId) {
-  this.item = new TransactionItemCache();
-  this.item.id = aFolderId;
-};
-
-PlacesSortFolderByNameTransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function SFBNTXN_doTransaction() {
-    this._oldOrder = [];
-
-    let contents =
-      PlacesUtils.getFolderContents(this.item.id, false, false).root;
-    let count = contents.childCount;
-
-    // sort between separators
-    let newOrder = [];
-    let preSep = []; // temporary array for sorting each group of items
-    let sortingMethod =
-      function(a, b) {
-        if (PlacesUtils.nodeIsContainer(a) && !PlacesUtils.nodeIsContainer(b))
-          return -1;
-        if (!PlacesUtils.nodeIsContainer(a) && PlacesUtils.nodeIsContainer(b))
-          return 1;
-        return a.title.localeCompare(b.title);
-      };
-
-    for (let i = 0; i < count; ++i) {
-      let item = contents.getChild(i);
-      this._oldOrder[item.itemId] = i;
-      if (PlacesUtils.nodeIsSeparator(item)) {
-        if (preSep.length > 0) {
-          preSep.sort(sortingMethod);
-          newOrder = newOrder.concat(preSep);
-          preSep.splice(0, preSep.length);
-        }
-        newOrder.push(item);
-      } else
-        preSep.push(item);
-    }
-    contents.containerOpen = false;
-
-    if (preSep.length > 0) {
-      preSep.sort(sortingMethod);
-      newOrder = newOrder.concat(preSep);
-    }
-
-    // set the nex indexes
-    let callback = {
-      runBatched() {
-        for (let i = 0; i < newOrder.length; ++i) {
-          PlacesUtils.bookmarks.setItemIndex(newOrder[i].itemId, i);
-        }
-      }
-    };
-    PlacesUtils.bookmarks.runInBatchMode(callback, null);
-  },
-
-  undoTransaction: function SFBNTXN_undoTransaction() {
-    let callback = {
-      _self: this,
-      runBatched() {
-        for (let item in this._self._oldOrder)
-          PlacesUtils.bookmarks.setItemIndex(item, this._self._oldOrder[item]);
-      }
-    };
-    PlacesUtils.bookmarks.runInBatchMode(callback, null);
-  }
-};
-
-
-/**
- * Transaction for tagging a URL with the given set of tags. Current tags set
- * for the URL persist. It's the caller's job to check whether or not aURI
- * was already tagged by any of the tags in aTags, undoing this tags
- * transaction removes them all from aURL!
- *
- * @param aURI
- *        the URL to tag.
- * @param aTags
- *        Array of tags to set for the given URL.
- */
-this.PlacesTagURITransaction =
- function PlacesTagURITransaction(aURI, aTags) {
-  this.item = new TransactionItemCache();
-  this.item.uri = aURI;
-  this.item.tags = aTags;
-};
-
-PlacesTagURITransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function TUTXN_doTransaction() {
-    if (PlacesUtils.getMostRecentBookmarkForURI(this.item.uri) == -1) {
-      // There is no bookmark for this uri, but we only allow to tag bookmarks.
-      // Force an unfiled bookmark first.
-      this.item.id =
-        PlacesUtils.bookmarks
-                   .insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
-                                   this.item.uri,
-                                   PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                   PlacesUtils.history.getPageTitle(this.item.uri));
-    }
-    PlacesUtils.tagging.tagURI(this.item.uri, this.item.tags);
-  },
-
-  undoTransaction: function TUTXN_undoTransaction() {
-    if (this.item.id != -1) {
-      PlacesUtils.bookmarks.removeItem(this.item.id);
-      this.item.id = -1;
-    }
-    PlacesUtils.tagging.untagURI(this.item.uri, this.item.tags);
-  }
-};
-
-
-/**
- * Transaction for removing tags from a URL. It's the caller's job to check
- * whether or not aURI isn't tagged by any of the tags in aTags, undoing this
- * tags transaction adds them all to aURL!
- *
- * @param aURI
- *        the URL to un-tag.
- * @param aTags
- *        Array of tags to unset. pass null to remove all tags from the given
- *        url.
- */
-this.PlacesUntagURITransaction =
- function PlacesUntagURITransaction(aURI, aTags) {
-  this.item = new TransactionItemCache();
-  this.item.uri = aURI;
-  if (aTags) {
-    // Within this transaction, we cannot rely on tags given by itemId
-    // since the tag containers may be gone after we call untagURI.
-    // Thus, we convert each tag given by its itemId to name.
-    let tags = [];
-    for (let i = 0; i < aTags.length; ++i) {
-      if (typeof(aTags[i]) == "number")
-        tags.push(PlacesUtils.bookmarks.getItemTitle(aTags[i]));
-      else
-        tags.push(aTags[i]);
-    }
-    this.item.tags = tags;
-  }
-};
-
-PlacesUntagURITransaction.prototype = {
-  __proto__: BaseTransaction.prototype,
-
-  doTransaction: function UTUTXN_doTransaction() {
-    // Filter tags existing on the bookmark, otherwise on undo we may try to
-    // set nonexistent tags.
-    let tags = PlacesUtils.tagging.getTagsForURI(this.item.uri);
-    this.item.tags = this.item.tags.filter(function(aTag) {
-      return tags.includes(aTag);
-    });
-    PlacesUtils.tagging.untagURI(this.item.uri, this.item.tags);
-  },
-
-  undoTransaction: function UTUTXN_undoTransaction() {
-    PlacesUtils.tagging.tagURI(this.item.uri, this.item.tags);
-  }
-};
-
 /**
  * Executes a boolean validate function, throwing if it returns false.
  *
  * @param boolValidateFn
  *        A boolean validate function.
  * @return the input value.
  * @throws if input doesn't pass the validate function.
  */
deleted file mode 100644
--- a/toolkit/components/places/tests/legacy/test_placesTxn.js
+++ /dev/null
@@ -1,935 +0,0 @@
-/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
-/* vim:set ts=2 sw=2 sts=2 et: */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-var bmsvc = PlacesUtils.bookmarks;
-var tagssvc = PlacesUtils.tagging;
-var annosvc = PlacesUtils.annotations;
-var txnManager = PlacesUtils.transactionManager;
-const DESCRIPTION_ANNO = "bookmarkProperties/description";
-
-async function promiseKeyword(keyword, href, postData) {
-  while (true) {
-    let entry = await PlacesUtils.keywords.fetch(keyword);
-    if (href == null && !entry)
-      break;
-    if (entry && entry.url.href == href && entry.postData == postData) {
-      break;
-    }
-
-    await new Promise(resolve => do_timeout(100, resolve));
-  }
-}
-
-// create and add bookmarks observer
-var observer = {
-
-  onBeginUpdateBatch() {
-    this._beginUpdateBatch = true;
-  },
-  _beginUpdateBatch: false,
-
-  onEndUpdateBatch() {
-    this._endUpdateBatch = true;
-  },
-  _endUpdateBatch: false,
-
-  onItemAdded(id, folder, index, itemType, uri) {
-    this._itemAddedId = id;
-    this._itemAddedParent = folder;
-    this._itemAddedIndex = index;
-    this._itemAddedType = itemType;
-  },
-  _itemAddedId: null,
-  _itemAddedParent: null,
-  _itemAddedIndex: null,
-  _itemAddedType: null,
-
-  onItemRemoved(id, folder, index, itemType) {
-    this._itemRemovedId = id;
-    this._itemRemovedFolder = folder;
-    this._itemRemovedIndex = index;
-  },
-  _itemRemovedId: null,
-  _itemRemovedFolder: null,
-  _itemRemovedIndex: null,
-
-  onItemChanged(id, property, isAnnotationProperty, newValue,
-                          lastModified, itemType) {
-    // The transaction manager is being rewritten in bug 891303, so just
-    // skip checking this for now.
-    if (property == "tags")
-      return;
-    this._itemChangedId = id;
-    this._itemChangedProperty = property;
-    this._itemChanged_isAnnotationProperty = isAnnotationProperty;
-    this._itemChangedValue = newValue;
-  },
-  _itemChangedId: null,
-  _itemChangedProperty: null,
-  _itemChanged_isAnnotationProperty: null,
-  _itemChangedValue: null,
-
-  onItemVisited(id, visitID, time) {
-    this._itemVisitedId = id;
-    this._itemVisitedVistId = visitID;
-    this._itemVisitedTime = time;
-  },
-  _itemVisitedId: null,
-  _itemVisitedVistId: null,
-  _itemVisitedTime: null,
-
-  onItemMoved(id, oldParent, oldIndex, newParent, newIndex,
-                        itemType) {
-    this._itemMovedId = id;
-    this._itemMovedOldParent = oldParent;
-    this._itemMovedOldIndex = oldIndex;
-    this._itemMovedNewParent = newParent;
-    this._itemMovedNewIndex = newIndex;
-  },
-  _itemMovedId: null,
-  _itemMovedOldParent: null,
-  _itemMovedOldIndex: null,
-  _itemMovedNewParent: null,
-  _itemMovedNewIndex: null,
-
-  QueryInterface(iid) {
-    if (iid.equals(Ci.nsINavBookmarkObserver) ||
-        iid.equals(Ci.nsISupports)) {
-      return this;
-    }
-    throw Cr.NS_ERROR_NO_INTERFACE;
-  }
-};
-
-// index at which items should begin
-var bmStartIndex = 0;
-
-// get bookmarks root id
-var root = PlacesUtils.bookmarksMenuFolderId;
-
-add_task(async function init() {
-  bmsvc.addObserver(observer);
-  registerCleanupFunction(function() {
-    bmsvc.removeObserver(observer);
-  });
-});
-
-add_task(async function test_create_folder_with_description() {
-  const TEST_FOLDERNAME = "Test creating a folder with a description";
-  const TEST_DESCRIPTION = "this is my test description";
-
-  let annos = [{ name: DESCRIPTION_ANNO,
-                 type: annosvc.TYPE_STRING,
-                 flags: 0,
-                 value: TEST_DESCRIPTION,
-                 expires: annosvc.EXPIRE_NEVER }];
-  let txn = new PlacesCreateFolderTransaction(TEST_FOLDERNAME, root, bmStartIndex, annos);
-  txnManager.doTransaction(txn);
-
-  // This checks that calling undoTransaction on an "empty batch" doesn't
-  // undo the previous transaction (getItemTitle will fail)
-  txnManager.beginBatch(null);
-  txnManager.endBatch(false);
-  txnManager.undoTransaction();
-
-  let folderId = observer._itemAddedId;
-  Assert.equal(bmsvc.getItemTitle(folderId), TEST_FOLDERNAME);
-  Assert.equal(observer._itemAddedIndex, bmStartIndex);
-  Assert.equal(observer._itemAddedParent, root);
-  Assert.equal(observer._itemAddedId, folderId);
-  Assert.equal(TEST_DESCRIPTION, annosvc.getItemAnnotation(folderId, DESCRIPTION_ANNO));
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemRemovedId, folderId);
-  Assert.equal(observer._itemRemovedFolder, root);
-  Assert.equal(observer._itemRemovedIndex, bmStartIndex);
-
-  txn.redoTransaction();
-  Assert.equal(observer._itemAddedIndex, bmStartIndex);
-  Assert.equal(observer._itemAddedParent, root);
-  Assert.equal(observer._itemAddedId, folderId);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemRemovedId, folderId);
-  Assert.equal(observer._itemRemovedFolder, root);
-  Assert.equal(observer._itemRemovedIndex, bmStartIndex);
-});
-
-add_task(async function test_create_item() {
-  let testURI = NetUtil.newURI("http://test_create_item.com");
-
-  let txn = new PlacesCreateBookmarkTransaction(testURI, root, bmStartIndex,
-                                                "Test creating an item");
-
-  txnManager.doTransaction(txn);
-  let id = bmsvc.getBookmarkIdsForURI(testURI)[0];
-  Assert.equal(observer._itemAddedId, id);
-  Assert.equal(observer._itemAddedIndex, bmStartIndex);
-  Assert.notEqual(await PlacesUtils.bookmarks.fetch({url: testURI}), null);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemRemovedId, id);
-  Assert.equal(observer._itemRemovedIndex, bmStartIndex);
-  Assert.equal(await PlacesUtils.bookmarks.fetch({url: testURI}), null);
-
-  txn.redoTransaction();
-  Assert.notEqual(await PlacesUtils.bookmarks.fetch({url: testURI}), null);
-  let newId = bmsvc.getBookmarkIdsForURI(testURI)[0];
-  Assert.equal(observer._itemAddedIndex, bmStartIndex);
-  Assert.equal(observer._itemAddedParent, root);
-  Assert.equal(observer._itemAddedId, newId);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemRemovedId, newId);
-  Assert.equal(observer._itemRemovedFolder, root);
-  Assert.equal(observer._itemRemovedIndex, bmStartIndex);
-});
-
-add_task(async function test_create_item_to_folder() {
-  const TEST_FOLDERNAME = "Test creating item to a folder";
-  let testURI = NetUtil.newURI("http://test_create_item_to_folder.com");
-  let folderId = bmsvc.createFolder(root, TEST_FOLDERNAME, bmsvc.DEFAULT_INDEX);
-
-  let txn = new PlacesCreateBookmarkTransaction(testURI, folderId, bmStartIndex,
-                                                "Test creating item");
-  txnManager.doTransaction(txn);
-  let bkmId = bmsvc.getBookmarkIdsForURI(testURI)[0];
-  Assert.equal(observer._itemAddedId, bkmId);
-  Assert.equal(observer._itemAddedIndex, bmStartIndex);
-  Assert.notEqual(await PlacesUtils.bookmarks.fetch({url: testURI}), null);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemRemovedId, bkmId);
-  Assert.equal(observer._itemRemovedIndex, bmStartIndex);
-
-  txn.redoTransaction();
-  let newBkmId = bmsvc.getBookmarkIdsForURI(testURI)[0];
-  Assert.equal(observer._itemAddedIndex, bmStartIndex);
-  Assert.equal(observer._itemAddedParent, folderId);
-  Assert.equal(observer._itemAddedId, newBkmId);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemRemovedId, newBkmId);
-  Assert.equal(observer._itemRemovedFolder, folderId);
-  Assert.equal(observer._itemRemovedIndex, bmStartIndex);
-});
-
-add_task(async function test_move_items_to_folder() {
-  let testFolderId = bmsvc.createFolder(root, "Test move items", bmsvc.DEFAULT_INDEX);
-  let testURI = NetUtil.newURI("http://test_move_items.com");
-  let testBkmId = bmsvc.insertBookmark(testFolderId, testURI, bmsvc.DEFAULT_INDEX, "1: Test move items");
-  bmsvc.insertBookmark(testFolderId, testURI, bmsvc.DEFAULT_INDEX, "2: Test move items");
-
-  // Moving items between the same folder
-  let sameTxn = new PlacesMoveItemTransaction(testBkmId, testFolderId, bmsvc.DEFAULT_INDEX);
-
-  sameTxn.doTransaction();
-  Assert.equal(observer._itemMovedId, testBkmId);
-  Assert.equal(observer._itemMovedOldParent, testFolderId);
-  Assert.equal(observer._itemMovedOldIndex, 0);
-  Assert.equal(observer._itemMovedNewParent, testFolderId);
-  Assert.equal(observer._itemMovedNewIndex, 1);
-
-  sameTxn.undoTransaction();
-  Assert.equal(observer._itemMovedId, testBkmId);
-  Assert.equal(observer._itemMovedOldParent, testFolderId);
-  Assert.equal(observer._itemMovedOldIndex, 1);
-  Assert.equal(observer._itemMovedNewParent, testFolderId);
-  Assert.equal(observer._itemMovedNewIndex, 0);
-
-  sameTxn.redoTransaction();
-  Assert.equal(observer._itemMovedId, testBkmId);
-  Assert.equal(observer._itemMovedOldParent, testFolderId);
-  Assert.equal(observer._itemMovedOldIndex, 0);
-  Assert.equal(observer._itemMovedNewParent, testFolderId);
-  Assert.equal(observer._itemMovedNewIndex, 1);
-
-  sameTxn.undoTransaction();
-  Assert.equal(observer._itemMovedId, testBkmId);
-  Assert.equal(observer._itemMovedOldParent, testFolderId);
-  Assert.equal(observer._itemMovedOldIndex, 1);
-  Assert.equal(observer._itemMovedNewParent, testFolderId);
-  Assert.equal(observer._itemMovedNewIndex, 0);
-
-  // Moving items between different folders
-  let folderId = bmsvc.createFolder(testFolderId,
-                                    "Test move items between different folders",
-                                    bmsvc.DEFAULT_INDEX);
-  let diffTxn = new PlacesMoveItemTransaction(testBkmId, folderId, bmsvc.DEFAULT_INDEX);
-
-  diffTxn.doTransaction();
-  Assert.equal(observer._itemMovedId, testBkmId);
-  Assert.equal(observer._itemMovedOldParent, testFolderId);
-  Assert.equal(observer._itemMovedOldIndex, 0);
-  Assert.equal(observer._itemMovedNewParent, folderId);
-  Assert.equal(observer._itemMovedNewIndex, 0);
-
-  sameTxn.undoTransaction();
-  Assert.equal(observer._itemMovedId, testBkmId);
-  Assert.equal(observer._itemMovedOldParent, folderId);
-  Assert.equal(observer._itemMovedOldIndex, 0);
-  Assert.equal(observer._itemMovedNewParent, testFolderId);
-  Assert.equal(observer._itemMovedNewIndex, 0);
-
-  diffTxn.redoTransaction();
-  Assert.equal(observer._itemMovedId, testBkmId);
-  Assert.equal(observer._itemMovedOldParent, testFolderId);
-  Assert.equal(observer._itemMovedOldIndex, 0);
-  Assert.equal(observer._itemMovedNewParent, folderId);
-  Assert.equal(observer._itemMovedNewIndex, 0);
-
-  sameTxn.undoTransaction();
-  Assert.equal(observer._itemMovedId, testBkmId);
-  Assert.equal(observer._itemMovedOldParent, folderId);
-  Assert.equal(observer._itemMovedOldIndex, 0);
-  Assert.equal(observer._itemMovedNewParent, testFolderId);
-  Assert.equal(observer._itemMovedNewIndex, 0);
-});
-
-add_task(async function test_remove_folder() {
-  let testFolder = bmsvc.createFolder(root, "Test Removing a Folder", bmsvc.DEFAULT_INDEX);
-  let folderId = bmsvc.createFolder(testFolder, "Removed Folder", bmsvc.DEFAULT_INDEX);
-
-  let txn = new PlacesRemoveItemTransaction(folderId);
-
-  txn.doTransaction();
-  Assert.equal(observer._itemRemovedId, folderId);
-  Assert.equal(observer._itemRemovedFolder, testFolder);
-  Assert.equal(observer._itemRemovedIndex, 0);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemAddedId, folderId);
-  Assert.equal(observer._itemAddedParent, testFolder);
-  Assert.equal(observer._itemAddedIndex, 0);
-
-  txn.redoTransaction();
-  Assert.equal(observer._itemRemovedId, folderId);
-  Assert.equal(observer._itemRemovedFolder, testFolder);
-  Assert.equal(observer._itemRemovedIndex, 0);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemAddedId, folderId);
-  Assert.equal(observer._itemAddedParent, testFolder);
-  Assert.equal(observer._itemAddedIndex, 0);
-});
-
-add_task(async function test_remove_item_with_tag() {
-  // Notice in this case the tag persists since other bookmarks have same uri.
-  let testFolder = bmsvc.createFolder(root, "Test removing an item with a tag",
-                                      bmsvc.DEFAULT_INDEX);
-
-  const TAG_NAME = "tag-test_remove_item_with_tag";
-  let testURI = NetUtil.newURI("http://test_remove_item_with_tag.com");
-  let testBkmId = bmsvc.insertBookmark(testFolder, testURI, bmsvc.DEFAULT_INDEX, "test-item1");
-
-  // create bookmark for not removing tag.
-  bmsvc.insertBookmark(testFolder, testURI, bmsvc.DEFAULT_INDEX, "test-item2");
-
-  // set tag
-  tagssvc.tagURI(testURI, [TAG_NAME]);
-
-  let txn = new PlacesRemoveItemTransaction(testBkmId);
-
-  txn.doTransaction();
-  Assert.equal(observer._itemRemovedId, testBkmId);
-  Assert.equal(observer._itemRemovedFolder, testFolder);
-  Assert.equal(observer._itemRemovedIndex, 0);
-  Assert.equal(tagssvc.getTagsForURI(testURI), TAG_NAME);
-
-  txn.undoTransaction();
-  let newbkmk2Id = observer._itemAddedId;
-  Assert.equal(observer._itemAddedParent, testFolder);
-  Assert.equal(observer._itemAddedIndex, 0);
-  Assert.equal(tagssvc.getTagsForURI(testURI)[0], TAG_NAME);
-
-  txn.redoTransaction();
-  Assert.equal(observer._itemRemovedId, newbkmk2Id);
-  Assert.equal(observer._itemRemovedFolder, testFolder);
-  Assert.equal(observer._itemRemovedIndex, 0);
-  Assert.equal(tagssvc.getTagsForURI(testURI)[0], TAG_NAME);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemAddedParent, testFolder);
-  Assert.equal(observer._itemAddedIndex, 0);
-  Assert.equal(tagssvc.getTagsForURI(testURI)[0], TAG_NAME);
-});
-
-add_task(async function test_remove_item_with_keyword() {
-  // Notice in this case the tag persists since other bookmarks have same uri.
-  let testFolder = bmsvc.createFolder(root, "Test removing an item with a keyword",
-                                      bmsvc.DEFAULT_INDEX);
-
-  const KEYWORD = "test: test removing an item with a keyword";
-  let testURI = NetUtil.newURI("http://test_remove_item_with_keyword.com");
-  let testBkmId = bmsvc.insertBookmark(testFolder, testURI, bmsvc.DEFAULT_INDEX, "test-item1");
-
-  // set keyword
-  await PlacesUtils.keywords.insert({ url: testURI.spec, keyword: KEYWORD});
-
-  let txn = new PlacesRemoveItemTransaction(testBkmId);
-
-  txn.doTransaction();
-  Assert.equal(observer._itemRemovedId, testBkmId);
-  Assert.equal(observer._itemRemovedFolder, testFolder);
-  Assert.equal(observer._itemRemovedIndex, 0);
-  await promiseKeyword(KEYWORD, null);
-
-  txn.undoTransaction();
-  let newbkmk2Id = observer._itemAddedId;
-  Assert.equal(observer._itemAddedParent, testFolder);
-  Assert.equal(observer._itemAddedIndex, 0);
-  await promiseKeyword(KEYWORD, testURI.spec);
-
-  txn.redoTransaction();
-  Assert.equal(observer._itemRemovedId, newbkmk2Id);
-  Assert.equal(observer._itemRemovedFolder, testFolder);
-  Assert.equal(observer._itemRemovedIndex, 0);
-  await promiseKeyword(KEYWORD, null);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemAddedParent, testFolder);
-  Assert.equal(observer._itemAddedIndex, 0);
-});
-
-add_task(async function test_creating_separator() {
-  let testFolder = bmsvc.createFolder(root, "Test creating a separator", bmsvc.DEFAULT_INDEX);
-
-  let txn = new PlacesCreateSeparatorTransaction(testFolder, 0);
-  txn.doTransaction();
-
-  let sepId = observer._itemAddedId;
-  Assert.equal(observer._itemAddedIndex, 0);
-  Assert.equal(observer._itemAddedParent, testFolder);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemRemovedId, sepId);
-  Assert.equal(observer._itemRemovedFolder, testFolder);
-  Assert.equal(observer._itemRemovedIndex, 0);
-
-  txn.redoTransaction();
-  let newSepId = observer._itemAddedId;
-  Assert.equal(observer._itemAddedIndex, 0);
-  Assert.equal(observer._itemAddedParent, testFolder);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemRemovedId, newSepId);
-  Assert.equal(observer._itemRemovedFolder, testFolder);
-  Assert.equal(observer._itemRemovedIndex, 0);
-});
-
-add_task(async function test_removing_separator() {
-  let testFolder = bmsvc.createFolder(root, "Test removing a separator", bmsvc.DEFAULT_INDEX);
-
-  let sepId = bmsvc.insertSeparator(testFolder, 0);
-  let txn = new PlacesRemoveItemTransaction(sepId);
-
-  txn.doTransaction();
-  Assert.equal(observer._itemRemovedId, sepId);
-  Assert.equal(observer._itemRemovedFolder, testFolder);
-  Assert.equal(observer._itemRemovedIndex, 0);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemAddedId, sepId); // New separator created
-  Assert.equal(observer._itemAddedParent, testFolder);
-  Assert.equal(observer._itemAddedIndex, 0);
-
-  txn.redoTransaction();
-  Assert.equal(observer._itemRemovedId, sepId);
-  Assert.equal(observer._itemRemovedFolder, testFolder);
-  Assert.equal(observer._itemRemovedIndex, 0);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemAddedId, sepId); // New separator created
-  Assert.equal(observer._itemAddedParent, testFolder);
-  Assert.equal(observer._itemAddedIndex, 0);
-});
-
-add_task(async function test_editing_item_title() {
-  const TITLE = "Test editing item title";
-  const MOD_TITLE = "Mod: Test editing item title";
-  let testURI = NetUtil.newURI("http://www.test_editing_item_title.com");
-  let testBkmId = bmsvc.insertBookmark(root, testURI, bmsvc.DEFAULT_INDEX, TITLE);
-
-  let txn = new PlacesEditItemTitleTransaction(testBkmId, MOD_TITLE);
-
-  txn.doTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "title");
-  Assert.equal(observer._itemChangedValue, MOD_TITLE);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "title");
-  Assert.equal(observer._itemChangedValue, TITLE);
-
-  txn.redoTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "title");
-  Assert.equal(observer._itemChangedValue, MOD_TITLE);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "title");
-  Assert.equal(observer._itemChangedValue, TITLE);
-});
-
-add_task(async function test_editing_item_uri() {
-  const OLD_TEST_URI = NetUtil.newURI("http://old.test_editing_item_uri.com/");
-  const NEW_TEST_URI = NetUtil.newURI("http://new.test_editing_item_uri.com/");
-  let testBkmId = bmsvc.insertBookmark(root, OLD_TEST_URI, bmsvc.DEFAULT_INDEX,
-                                       "Test editing item title");
-  tagssvc.tagURI(OLD_TEST_URI, ["tag"]);
-
-  let txn = new PlacesEditBookmarkURITransaction(testBkmId, NEW_TEST_URI);
-
-  txn.doTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "uri");
-  Assert.equal(observer._itemChangedValue, NEW_TEST_URI.spec);
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(NEW_TEST_URI)), JSON.stringify(["tag"]));
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(OLD_TEST_URI)), JSON.stringify([]));
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "uri");
-  Assert.equal(observer._itemChangedValue, OLD_TEST_URI.spec);
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(OLD_TEST_URI)), JSON.stringify(["tag"]));
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(NEW_TEST_URI)), JSON.stringify([]));
-
-  txn.redoTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "uri");
-  Assert.equal(observer._itemChangedValue, NEW_TEST_URI.spec);
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(NEW_TEST_URI)), JSON.stringify(["tag"]));
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(OLD_TEST_URI)), JSON.stringify([]));
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "uri");
-  Assert.equal(observer._itemChangedValue, OLD_TEST_URI.spec);
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(OLD_TEST_URI)), JSON.stringify(["tag"]));
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(NEW_TEST_URI)), JSON.stringify([]));
-});
-
-add_task(async function test_edit_description_transaction() {
-  let testURI = NetUtil.newURI("http://test_edit_description_transaction.com");
-  let testBkmId = bmsvc.insertBookmark(root, testURI, bmsvc.DEFAULT_INDEX, "Test edit description transaction");
-
-  let anno = {
-    name: DESCRIPTION_ANNO,
-    type: Ci.nsIAnnotationService.TYPE_STRING,
-    flags: 0,
-    value: "Test edit Description",
-    expires: Ci.nsIAnnotationService.EXPIRE_NEVER,
-  };
-  let txn = new PlacesSetItemAnnotationTransaction(testBkmId, anno);
-
-  txn.doTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, DESCRIPTION_ANNO);
-});
-
-add_task(async function test_edit_keyword() {
-  const KEYWORD = "keyword-test_edit_keyword";
-
-  let testURI = NetUtil.newURI("http://test_edit_keyword.com");
-  let testBkmId = bmsvc.insertBookmark(root, testURI, bmsvc.DEFAULT_INDEX, "Test edit keyword");
-
-  let txn = new PlacesEditBookmarkKeywordTransaction(testBkmId, KEYWORD, "postData");
-
-  txn.doTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "keyword");
-  Assert.equal(observer._itemChangedValue, KEYWORD);
-  Assert.equal(PlacesUtils.getPostDataForBookmark(testBkmId), "postData");
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "keyword");
-  Assert.equal(observer._itemChangedValue, "");
-  Assert.equal(PlacesUtils.getPostDataForBookmark(testBkmId), null);
-});
-
-add_task(async function test_edit_specific_keyword() {
-  const KEYWORD = "keyword-test_edit_keyword2";
-
-  let testURI = NetUtil.newURI("http://test_edit_keyword2.com");
-  let testBkmId = bmsvc.insertBookmark(root, testURI, bmsvc.DEFAULT_INDEX, "Test edit keyword");
-  // Add multiple keyword to this uri.
-  await PlacesUtils.keywords.insert({ keyword: "kw1", url: testURI.spec, postData: "postData1" });
-  await PlacesUtils.keywords.insert({keyword: "kw2", url: testURI.spec, postData: "postData2" });
-
-  // Try to change only kw2.
-  let txn = new PlacesEditBookmarkKeywordTransaction(testBkmId, KEYWORD, "postData2", "kw2");
-
-  txn.doTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "keyword");
-  Assert.equal(observer._itemChangedValue, KEYWORD);
-  let entry = await PlacesUtils.keywords.fetch("kw1");
-  Assert.equal(entry.url.href, testURI.spec);
-  Assert.equal(entry.postData, "postData1");
-  await promiseKeyword(KEYWORD, testURI.spec, "postData2");
-  await promiseKeyword("kw2", null);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "keyword");
-  Assert.equal(observer._itemChangedValue, "kw2");
-  Assert.equal(PlacesUtils.getPostDataForBookmark(testBkmId), "postData1");
-  entry = await PlacesUtils.keywords.fetch("kw1");
-  Assert.equal(entry.url.href, testURI.spec);
-  Assert.equal(entry.postData, "postData1");
-  await promiseKeyword("kw2", testURI.spec, "postData2");
-  await promiseKeyword("keyword", null);
-});
-
-add_task(async function test_LoadInSidebar_transaction() {
-  let testURI = NetUtil.newURI("http://test_LoadInSidebar_transaction.com");
-  let testBkmId = bmsvc.insertBookmark(root, testURI, bmsvc.DEFAULT_INDEX, "Test LoadInSidebar transaction");
-
-  const LOAD_IN_SIDEBAR_ANNO = "bookmarkProperties/loadInSidebar";
-  let anno = { name: LOAD_IN_SIDEBAR_ANNO,
-               type: Ci.nsIAnnotationService.TYPE_INT32,
-               flags: 0,
-               value: true,
-               expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
-  let txn = new PlacesSetItemAnnotationTransaction(testBkmId, anno);
-
-  txn.doTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, LOAD_IN_SIDEBAR_ANNO);
-  Assert.equal(observer._itemChanged_isAnnotationProperty, true);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, LOAD_IN_SIDEBAR_ANNO);
-  Assert.equal(observer._itemChanged_isAnnotationProperty, true);
-});
-
-add_task(async function test_generic_item_annotation() {
-  let testURI = NetUtil.newURI("http://test_generic_item_annotation.com");
-  let testBkmId = bmsvc.insertBookmark(root, testURI, bmsvc.DEFAULT_INDEX, "Test generic item annotation");
-
-  let itemAnnoObj = { name: "testAnno/testInt",
-                      type: Ci.nsIAnnotationService.TYPE_INT32,
-                      flags: 0,
-                      value: 123,
-                      expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
-  let txn = new PlacesSetItemAnnotationTransaction(testBkmId, itemAnnoObj);
-
-  txn.doTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "testAnno/testInt");
-  Assert.equal(observer._itemChanged_isAnnotationProperty, true);
-
-  txn.undoTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "testAnno/testInt");
-  Assert.equal(observer._itemChanged_isAnnotationProperty, true);
-
-  txn.redoTransaction();
-  Assert.equal(observer._itemChangedId, testBkmId);
-  Assert.equal(observer._itemChangedProperty, "testAnno/testInt");
-  Assert.equal(observer._itemChanged_isAnnotationProperty, true);
-});
-
-add_task(async function test_editing_item_date_added() {
-  let testURI = NetUtil.newURI("http://test_editing_item_date_added.com");
-  let testBkmId = bmsvc.insertBookmark(root, testURI, bmsvc.DEFAULT_INDEX,
-                                       "Test editing item date added");
-
-  let oldAdded = bmsvc.getItemDateAdded(testBkmId);
-  let newAdded = Date.now() * 1000 + 1000;
-  let txn = new PlacesEditItemDateAddedTransaction(testBkmId, newAdded);
-
-  txn.doTransaction();
-  Assert.equal(newAdded, bmsvc.getItemDateAdded(testBkmId));
-
-  txn.undoTransaction();
-  Assert.equal(oldAdded, bmsvc.getItemDateAdded(testBkmId));
-});
-
-add_task(async function test_edit_item_last_modified() {
-  let testURI = NetUtil.newURI("http://test_edit_item_last_modified.com");
-  let testBkmId = bmsvc.insertBookmark(root, testURI, bmsvc.DEFAULT_INDEX,
-                                       "Test editing item last modified");
-
-  let oldModified = bmsvc.getItemLastModified(testBkmId);
-  let newModified = Date.now() * 1000 + 1000;
-  let txn = new PlacesEditItemLastModifiedTransaction(testBkmId, newModified);
-
-  txn.doTransaction();
-  Assert.equal(newModified, bmsvc.getItemLastModified(testBkmId));
-
-  txn.undoTransaction();
-  Assert.equal(oldModified, bmsvc.getItemLastModified(testBkmId));
-});
-
-add_task(async function test_generic_page_annotation() {
-  const TEST_ANNO = "testAnno/testInt";
-  let testURI = NetUtil.newURI("http://www.mozilla.org/");
-  PlacesTestUtils.addVisits(testURI).then(function() {
-    let pageAnnoObj = { name: TEST_ANNO,
-                        type: Ci.nsIAnnotationService.TYPE_INT32,
-                        flags: 0,
-                        value: 123,
-                        expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
-    let txn = new PlacesSetPageAnnotationTransaction(testURI, pageAnnoObj);
-
-    txn.doTransaction();
-    Assert.ok(annosvc.pageHasAnnotation(testURI, TEST_ANNO));
-
-    txn.undoTransaction();
-    Assert.ok(!annosvc.pageHasAnnotation(testURI, TEST_ANNO));
-
-    txn.redoTransaction();
-    Assert.ok(annosvc.pageHasAnnotation(testURI, TEST_ANNO));
-  });
-});
-
-add_task(async function test_sort_folder_by_name() {
-  let testFolder = bmsvc.createFolder(root, "Test PlacesSortFolderByNameTransaction",
-                                      bmsvc.DEFAULT_INDEX);
-  let testURI = NetUtil.newURI("http://test_sort_folder_by_name.com");
-
-  bmsvc.insertBookmark(testFolder, testURI, bmsvc.DEFAULT_INDEX, "bookmark3");
-  bmsvc.insertBookmark(testFolder, testURI, bmsvc.DEFAULT_INDEX, "bookmark2");
-  bmsvc.insertBookmark(testFolder, testURI, bmsvc.DEFAULT_INDEX, "bookmark1");
-
-  let bkmIds = bmsvc.getBookmarkIdsForURI(testURI);
-  bkmIds.sort();
-
-  let b1 = bkmIds[0];
-  let b2 = bkmIds[1];
-  let b3 = bkmIds[2];
-
-  Assert.equal(0, bmsvc.getItemIndex(b1));
-  Assert.equal(1, bmsvc.getItemIndex(b2));
-  Assert.equal(2, bmsvc.getItemIndex(b3));
-
-  let txn = new PlacesSortFolderByNameTransaction(testFolder);
-
-  txn.doTransaction();
-  Assert.equal(2, bmsvc.getItemIndex(b1));
-  Assert.equal(1, bmsvc.getItemIndex(b2));
-  Assert.equal(0, bmsvc.getItemIndex(b3));
-
-  txn.undoTransaction();
-  Assert.equal(0, bmsvc.getItemIndex(b1));
-  Assert.equal(1, bmsvc.getItemIndex(b2));
-  Assert.equal(2, bmsvc.getItemIndex(b3));
-
-  txn.redoTransaction();
-  Assert.equal(2, bmsvc.getItemIndex(b1));
-  Assert.equal(1, bmsvc.getItemIndex(b2));
-  Assert.equal(0, bmsvc.getItemIndex(b3));
-
-  txn.undoTransaction();
-  Assert.equal(0, bmsvc.getItemIndex(b1));
-  Assert.equal(1, bmsvc.getItemIndex(b2));
-  Assert.equal(2, bmsvc.getItemIndex(b3));
-});
-
-add_task(async function test_tagURI_untagURI() {
-  const TAG_1 = "tag-test_tagURI_untagURI-bar";
-  const TAG_2 = "tag-test_tagURI_untagURI-foo";
-  let tagURI = NetUtil.newURI("http://test_tagURI_untagURI.com");
-
-  // Test tagURI
-  let tagTxn = new PlacesTagURITransaction(tagURI, [TAG_1, TAG_2]);
-
-  tagTxn.doTransaction();
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(tagURI)), JSON.stringify([TAG_1, TAG_2]));
-
-  tagTxn.undoTransaction();
-  Assert.equal(tagssvc.getTagsForURI(tagURI).length, 0);
-
-  tagTxn.redoTransaction();
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(tagURI)), JSON.stringify([TAG_1, TAG_2]));
-
-  // Test untagURI
-  let untagTxn = new PlacesUntagURITransaction(tagURI, [TAG_1]);
-
-  untagTxn.doTransaction();
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(tagURI)), JSON.stringify([TAG_2]));
-
-  untagTxn.undoTransaction();
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(tagURI)), JSON.stringify([TAG_1, TAG_2]));
-
-  untagTxn.redoTransaction();
-  Assert.equal(JSON.stringify(tagssvc.getTagsForURI(tagURI)), JSON.stringify([TAG_2]));
-});
-
-add_task(async function test_aggregate_removeItem_Txn() {
-  let testFolder = bmsvc.createFolder(root, "Test aggregate removeItem transaction", bmsvc.DEFAULT_INDEX);
-
-  const TEST_URL = "http://test_aggregate_removeitem_txn.com/";
-  const FOLDERNAME = "Folder";
-  let testURI = NetUtil.newURI(TEST_URL);
-
-  let bkmk1Id = bmsvc.insertBookmark(testFolder, testURI, 0, "Mozilla");
-  let bkmk2Id = bmsvc.insertSeparator(testFolder, 1);
-  let bkmk3Id = bmsvc.createFolder(testFolder, FOLDERNAME, 2);
-
-  let bkmk3_1Id = bmsvc.insertBookmark(bkmk3Id, testURI, 0, "Mozilla");
-  let bkmk3_2Id = bmsvc.insertSeparator(bkmk3Id, 1);
-  let bkmk3_3Id = bmsvc.createFolder(bkmk3Id, FOLDERNAME, 2);
-
-  let childTxn1 = new PlacesRemoveItemTransaction(bkmk1Id);
-  let childTxn2 = new PlacesRemoveItemTransaction(bkmk2Id);
-  let childTxn3 = new PlacesRemoveItemTransaction(bkmk3Id);
-  let transactions = [childTxn1, childTxn2, childTxn3];
-  let txn = new PlacesAggregatedTransaction("RemoveItems", transactions);
-
-  txn.doTransaction();
-  Assert.equal(bmsvc.getItemIndex(bkmk1Id), -1);
-  Assert.equal(bmsvc.getItemIndex(bkmk2Id), -1);
-  Assert.equal(bmsvc.getItemIndex(bkmk3Id), -1);
-  Assert.equal(bmsvc.getItemIndex(bkmk3_1Id), -1);
-  Assert.equal(bmsvc.getItemIndex(bkmk3_2Id), -1);
-  Assert.equal(bmsvc.getItemIndex(bkmk3_3Id), -1);
-  // Check last removed item id.
-  Assert.equal(observer._itemRemovedId, bkmk3Id);
-
-  txn.undoTransaction();
-  let newBkmk1Id = bmsvc.getIdForItemAt(testFolder, 0);
-  let newBkmk2Id = bmsvc.getIdForItemAt(testFolder, 1);
-  let newBkmk3Id = bmsvc.getIdForItemAt(testFolder, 2);
-  let newBkmk3_1Id = bmsvc.getIdForItemAt(newBkmk3Id, 0);
-  let newBkmk3_2Id = bmsvc.getIdForItemAt(newBkmk3Id, 1);
-  let newBkmk3_3Id = bmsvc.getIdForItemAt(newBkmk3Id, 2);
-  Assert.equal(bmsvc.getItemType(newBkmk1Id), bmsvc.TYPE_BOOKMARK);
-  Assert.equal(bmsvc.getBookmarkURI(newBkmk1Id).spec, TEST_URL);
-  Assert.equal(bmsvc.getItemType(newBkmk2Id), bmsvc.TYPE_SEPARATOR);
-  Assert.equal(bmsvc.getItemType(newBkmk3Id), bmsvc.TYPE_FOLDER);
-  Assert.equal(bmsvc.getItemTitle(newBkmk3Id), FOLDERNAME);
-  Assert.equal(bmsvc.getFolderIdForItem(newBkmk3_1Id), newBkmk3Id);
-  Assert.equal(bmsvc.getItemType(newBkmk3_1Id), bmsvc.TYPE_BOOKMARK);
-  Assert.equal(bmsvc.getBookmarkURI(newBkmk3_1Id).spec, TEST_URL);
-  Assert.equal(bmsvc.getFolderIdForItem(newBkmk3_2Id), newBkmk3Id);
-  Assert.equal(bmsvc.getItemType(newBkmk3_2Id), bmsvc.TYPE_SEPARATOR);
-  Assert.equal(bmsvc.getFolderIdForItem(newBkmk3_3Id), newBkmk3Id);
-  Assert.equal(bmsvc.getItemType(newBkmk3_3Id), bmsvc.TYPE_FOLDER);
-  Assert.equal(bmsvc.getItemTitle(newBkmk3_3Id), FOLDERNAME);
-  // Check last added back item id.
-  // Notice items are restored in reverse order.
-  Assert.equal(observer._itemAddedId, newBkmk1Id);
-
-  txn.redoTransaction();
-  Assert.equal(bmsvc.getItemIndex(newBkmk1Id), -1);
-  Assert.equal(bmsvc.getItemIndex(newBkmk2Id), -1);
-  Assert.equal(bmsvc.getItemIndex(newBkmk3Id), -1);
-  Assert.equal(bmsvc.getItemIndex(newBkmk3_1Id), -1);
-  Assert.equal(bmsvc.getItemIndex(newBkmk3_2Id), -1);
-  Assert.equal(bmsvc.getItemIndex(newBkmk3_3Id), -1);
-  // Check last removed item id.
-  Assert.equal(observer._itemRemovedId, newBkmk3Id);
-
-  txn.undoTransaction();
-  newBkmk1Id = bmsvc.getIdForItemAt(testFolder, 0);
-  newBkmk2Id = bmsvc.getIdForItemAt(testFolder, 1);
-  newBkmk3Id = bmsvc.getIdForItemAt(testFolder, 2);
-  newBkmk3_1Id = bmsvc.getIdForItemAt(newBkmk3Id, 0);
-  newBkmk3_2Id = bmsvc.getIdForItemAt(newBkmk3Id, 1);
-  newBkmk3_3Id = bmsvc.getIdForItemAt(newBkmk3Id, 2);
-  Assert.equal(bmsvc.getItemType(newBkmk1Id), bmsvc.TYPE_BOOKMARK);
-  Assert.equal(bmsvc.getBookmarkURI(newBkmk1Id).spec, TEST_URL);
-  Assert.equal(bmsvc.getItemType(newBkmk2Id), bmsvc.TYPE_SEPARATOR);
-  Assert.equal(bmsvc.getItemType(newBkmk3Id), bmsvc.TYPE_FOLDER);
-  Assert.equal(bmsvc.getItemTitle(newBkmk3Id), FOLDERNAME);
-  Assert.equal(bmsvc.getFolderIdForItem(newBkmk3_1Id), newBkmk3Id);
-  Assert.equal(bmsvc.getItemType(newBkmk3_1Id), bmsvc.TYPE_BOOKMARK);
-  Assert.equal(bmsvc.getBookmarkURI(newBkmk3_1Id).spec, TEST_URL);
-  Assert.equal(bmsvc.getFolderIdForItem(newBkmk3_2Id), newBkmk3Id);
-  Assert.equal(bmsvc.getItemType(newBkmk3_2Id), bmsvc.TYPE_SEPARATOR);
-  Assert.equal(bmsvc.getFolderIdForItem(newBkmk3_3Id), newBkmk3Id);
-  Assert.equal(bmsvc.getItemType(newBkmk3_3Id), bmsvc.TYPE_FOLDER);
-  Assert.equal(bmsvc.getItemTitle(newBkmk3_3Id), FOLDERNAME);
-  // Check last added back item id.
-  // Notice items are restored in reverse order.
-  Assert.equal(observer._itemAddedId, newBkmk1Id);
-});
-
-add_task(async function test_create_item_with_childTxn() {
-  let testFolder = bmsvc.createFolder(root, "Test creating an item with childTxns", bmsvc.DEFAULT_INDEX);
-
-  const BOOKMARK_TITLE = "parent item";
-  let testURI = NetUtil.newURI("http://test_create_item_with_childTxn.com");
-  let childTxns = [];
-  let newDateAdded = Date.now() * 1000 - 20000;
-  let editDateAdddedTxn = new PlacesEditItemDateAddedTransaction(null, newDateAdded);
-  childTxns.push(editDateAdddedTxn);
-
-  let itemChildAnnoObj = { name: "testAnno/testInt",
-                           type: Ci.nsIAnnotationService.TYPE_INT32,
-                           flags: 0,
-                           value: 123,
-                           expires: Ci.nsIAnnotationService.EXPIRE_NEVER };
-  let annoTxn = new PlacesSetItemAnnotationTransaction(null, itemChildAnnoObj);
-  childTxns.push(annoTxn);
-
-  let itemWChildTxn = new PlacesCreateBookmarkTransaction(testURI, testFolder, bmStartIndex,
-                                                          BOOKMARK_TITLE, null, null,
-                                                          childTxns);
-  try {
-    txnManager.doTransaction(itemWChildTxn);
-    let itemId = bmsvc.getBookmarkIdsForURI(testURI)[0];
-    Assert.equal(observer._itemAddedId, itemId);
-    Assert.equal(newDateAdded, bmsvc.getItemDateAdded(itemId));
-    Assert.equal(observer._itemChangedProperty, "testAnno/testInt");
-    Assert.equal(observer._itemChanged_isAnnotationProperty, true);
-    Assert.ok(annosvc.itemHasAnnotation(itemId, itemChildAnnoObj.name));
-    Assert.equal(annosvc.getItemAnnotation(itemId, itemChildAnnoObj.name), itemChildAnnoObj.value);
-
-    itemWChildTxn.undoTransaction();
-    Assert.equal(observer._itemRemovedId, itemId);
-
-    itemWChildTxn.redoTransaction();
-    Assert.notEqual(await PlacesUtils.bookmarks.fetch({url: testURI}), null);
-    let newId = bmsvc.getBookmarkIdsForURI(testURI)[0];
-    Assert.equal(newDateAdded, bmsvc.getItemDateAdded(newId));
-    Assert.equal(observer._itemAddedId, newId);
-    Assert.equal(observer._itemChangedProperty, "testAnno/testInt");
-    Assert.equal(observer._itemChanged_isAnnotationProperty, true);
-    Assert.ok(annosvc.itemHasAnnotation(newId, itemChildAnnoObj.name));
-    Assert.equal(annosvc.getItemAnnotation(newId, itemChildAnnoObj.name), itemChildAnnoObj.value);
-
-    itemWChildTxn.undoTransaction();
-    Assert.equal(observer._itemRemovedId, newId);
-  } catch (ex) {
-    do_throw("Setting a child transaction in a createItem transaction did throw: " + ex);
-  }
-});
-
-add_task(async function test_create_folder_with_child_itemTxn() {
-  let childURI = NetUtil.newURI("http://test_create_folder_with_child_itemTxn.com");
-  let childItemTxn = new PlacesCreateBookmarkTransaction(childURI, root,
-                                                         bmStartIndex, "childItem");
-  let txn = new PlacesCreateFolderTransaction("Test creating a folder with child itemTxns",
-                                              root, bmStartIndex, null, [childItemTxn]);
-  try {
-    txnManager.doTransaction(txn);
-    let childItemId = bmsvc.getBookmarkIdsForURI(childURI)[0];
-    Assert.equal(observer._itemAddedId, childItemId);
-    Assert.equal(observer._itemAddedIndex, 0);
-    Assert.notEqual(await PlacesUtils.bookmarks.fetch({url: childURI}), null);
-
-    txn.undoTransaction();
-    Assert.equal(await PlacesUtils.bookmarks.fetch({url: childURI}), null);
-
-    txn.redoTransaction();
-    let newchildItemId = bmsvc.getBookmarkIdsForURI(childURI)[0];
-    Assert.equal(observer._itemAddedIndex, 0);
-    Assert.equal(observer._itemAddedId, newchildItemId);
-    Assert.notEqual(await PlacesUtils.bookmarks.fetch({url: childURI}), null);
-
-    txn.undoTransaction();
-    Assert.equal(await PlacesUtils.bookmarks.fetch({url: childURI}), null);
-  } catch (ex) {
-    do_throw("Setting a child item transaction in a createFolder transaction did throw: " + ex);
-  }
-});
--- a/toolkit/components/places/tests/legacy/xpcshell.ini
+++ b/toolkit/components/places/tests/legacy/xpcshell.ini
@@ -3,11 +3,10 @@
 
 [DEFAULT]
 head = head_legacy.js
 firefox-appdir = browser
 
 [test_418643_removeFolderChildren.js]
 [test_bookmarks_setNullTitle.js]
 [test_changeBookmarkURI.js]
-[test_placesTxn.js]
 [test_protectRoots.js]
 [test_removeItem.js]
--- a/tools/lint/eslint/modules.json
+++ b/tools/lint/eslint/modules.json
@@ -147,17 +147,17 @@
   "PageMenu.jsm": ["PageMenuParent", "PageMenuChild"],
   "PageThumbs.jsm": ["PageThumbs", "PageThumbsStorage"],
   "Parser.jsm": ["Parser", "ParserHelpers", "SyntaxTreeVisitor"],
   "ParseSymbols.jsm": ["ParseSymbols"],
   "passwords.js": ["PasswordEngine", "LoginRec", "PasswordValidator"],
   "passwords.jsm": ["Password", "DumpPasswords"],
   "PdfJsNetwork.jsm": ["NetworkManager"],
   "PhoneNumberMetaData.jsm": ["PHONE_NUMBER_META_DATA"],
-  "PlacesUtils.jsm": ["PlacesUtils", "PlacesAggregatedTransaction", "PlacesCreateFolderTransaction", "PlacesCreateBookmarkTransaction", "PlacesCreateSeparatorTransaction", "PlacesCreateLivemarkTransaction", "PlacesMoveItemTransaction", "PlacesRemoveItemTransaction", "PlacesEditItemTitleTransaction", "PlacesEditBookmarkURITransaction", "PlacesSetItemAnnotationTransaction", "PlacesSetPageAnnotationTransaction", "PlacesEditBookmarkKeywordTransaction", "PlacesEditBookmarkPostDataTransaction", "PlacesEditItemDateAddedTransaction", "PlacesEditItemLastModifiedTransaction", "PlacesSortFolderByNameTransaction", "PlacesTagURITransaction", "PlacesUntagURITransaction"],
+  "PlacesUtils.jsm": ["PlacesUtils"],
   "PluginProvider.jsm": [],
   "PointerAdapter.jsm": ["PointerRelay", "PointerAdapter"],
   "policies.js": ["ErrorHandler", "SyncScheduler"],
   "prefs.js": ["PrefsEngine", "PrefRec"],
   "prefs.jsm": ["Preference"],
   "ProfileStorage.jsm": ["profileStorage"],
   "PromiseWorker.jsm": ["BasePromiseWorker"],
   "PushCrypto.jsm": ["PushCrypto", "concatArray"],