Bug 1477671 - Stop allowing creation of new live bookmarks from the backend. r=standard8
authorMarco Bonardo <mbonardo@mozilla.com>
Sat, 06 Oct 2018 10:32:13 +0100
changeset 496384 6ea457f6ca9d48bf51ffd0ccec57305d2e191882
parent 496383 2cd0292930415010d25248c5fdc75d221598853d
child 496385 224c0fc59fc12565320b507bfdb7b8f80a07d12d
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersstandard8
bugs1477671
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1477671 - Stop allowing creation of new live bookmarks from the backend. r=standard8 Differential Revision: https://phabricator.services.mozilla.com/D7083
browser/base/content/browser-places.js
browser/components/places/content/bookmarkProperties.js
browser/components/places/content/controller.js
browser/components/places/tests/browser/browser.ini
browser/components/places/tests/browser/browser_bookmarkProperties_addLivemark.js
browser/locales/en-US/chrome/browser/places/bookmarkProperties.properties
toolkit/components/places/BookmarkHTMLUtils.jsm
toolkit/components/places/Bookmarks.jsm
toolkit/components/places/Database.cpp
toolkit/components/places/PlacesTransactions.jsm
toolkit/components/places/PlacesUtils.jsm
toolkit/components/places/mozIAsyncLivemarks.idl
toolkit/components/places/nsLivemarkService.js
toolkit/components/places/tests/chrome/chrome.ini
toolkit/components/places/tests/chrome/test_303567.xul
toolkit/components/places/tests/chrome/test_341972a.xul
toolkit/components/places/tests/chrome/test_341972b.xul
toolkit/components/places/tests/chrome/test_342484.xul
toolkit/components/places/tests/chrome/test_381357.xul
toolkit/components/places/tests/chrome/test_reloadLivemarks.xul
toolkit/components/places/tests/queries/head_queries.js
toolkit/components/places/tests/unit/livemark.xml
toolkit/components/places/tests/unit/test_384370.js
toolkit/components/places/tests/unit/test_async_transactions.js
toolkit/components/places/tests/unit/test_bookmarks_html.js
toolkit/components/places/tests/unit/test_bookmarks_html_corrupt.js
toolkit/components/places/tests/unit/test_bookmarks_json.js
toolkit/components/places/tests/unit/xpcshell.ini
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -503,43 +503,16 @@ var PlacesCommandHook = {
       bookmarkDialogInfo.title = URIList[0].title;
       bookmarkDialogInfo.uri = URIList[0].uri;
     }
 
     PlacesUIUtils.showBookmarkDialog(bookmarkDialogInfo, window);
   },
 
   /**
-   * Adds a Live Bookmark to a feed associated with the current page.
-   * @param     url
-   *            The nsIURI of the page the feed was attached to
-   * @title     title
-   *            The title of the feed. Optional.
-   */
-  async addLiveBookmark(url, feedTitle) {
-    let toolbarIP = new PlacesInsertionPoint({
-      parentId: PlacesUtils.toolbarFolderId,
-      parentGuid: PlacesUtils.bookmarks.toolbarGuid,
-    });
-
-    let feedURI = makeURI(url);
-    let title = feedTitle || gBrowser.contentTitle;
-
-    PlacesUIUtils.showBookmarkDialog({ action: "add",
-                                       type: "livemark",
-                                       feedURI,
-                                       siteURI: gBrowser.currentURI,
-                                       title,
-                                       defaultInsertionPoint: toolbarIP,
-                                       hiddenRows: [ "feedLocation",
-                                                     "siteLocation" ],
-                                     }, window);
-  },
-
-  /**
    * Opens the Places Organizer.
    * @param {String} item The item to select in the organizer window,
    *                      options are (case sensitive):
    *                      BookmarksMenu, BookmarksToolbar, UnfiledBookmarks,
    *                      AllBookmarks, History, Downloads.
    */
   showPlacesOrganizer(item) {
     var organizer = Services.wm.getMostRecentWindow("Places:Organizer");
--- a/browser/components/places/content/bookmarkProperties.js
+++ b/browser/components/places/content/bookmarkProperties.js
@@ -8,39 +8,38 @@
  * as window.arguments[0]. The object must have the following fields set:
  *   @ action (String). Possible values:
  *     - "add" - for adding a new item.
  *       @ type (String). Possible values:
  *         - "bookmark"
  *         - "folder"
  *           @ URIList (Array of nsIURI objects) - optional, list of uris to
  *             be bookmarked under the new folder.
- *         - "livemark"
  *       @ uri (nsIURI object) - optional, the default uri for the new item.
  *         The property is not used for the "folder with items" type.
  *       @ title (String) - optional, the default title for the new item.
  *       @ defaultInsertionPoint (InsertionPoint JS object) - optional, the
  *         default insertion point for the new item.
  *       @ keyword (String) - optional, the default keyword for the new item.
  *       @ postData (String) - optional, POST data to accompany the keyword.
  *       @ charSet (String) - optional, character-set to accompany the keyword.
  *      Notes:
- *        1) If |uri| is set for a bookmark/livemark item and |title| isn't,
+ *        1) If |uri| is set for a bookmark and |title| isn't,
  *           the dialog will query the history tables for the title associated
  *           with the given uri. If the dialog is set to adding a folder with
  *           bookmark items under it (see URIList), a default static title is
  *           used ("[Folder Name]").
  *        2) The index field of the default insertion point is ignored if
  *           the folder picker is shown.
  *     - "edit" - for editing a bookmark item or a folder.
  *       @ type (String). Possible values:
  *         - "bookmark"
  *           @ node (an nsINavHistoryResultNode object) - a node representing
  *             the bookmark.
- *         - "folder" (also applies to livemarks)
+ *         - "folder"
  *           @ node (an nsINavHistoryResultNode object) - a node representing
  *             the folder.
  *   @ hiddenRows (Strings array) - optional, list of rows to be hidden
  *     regardless of the item edited or added by the dialog.
  *     Possible values:
  *     - "title"
  *     - "location"
  *     - "keyword"
@@ -67,17 +66,16 @@ XPCOMUtils.defineLazyScriptGetter(this, 
                                   "chrome://browser/content/places/treeView.js");
 XPCOMUtils.defineLazyScriptGetter(this, ["PlacesInsertionPoint", "PlacesController",
                                          "PlacesControllerDragHelper"],
                                   "chrome://browser/content/places/controller.js");
 /* End Shared Places Import */
 
 const BOOKMARK_ITEM = 0;
 const BOOKMARK_FOLDER = 1;
-const LIVEMARK_CONTAINER = 2;
 
 const ACTION_EDIT = 0;
 const ACTION_ADD = 1;
 
 var elementsHeight = new Map();
 
 var BookmarkPropertiesPanel = {
 
@@ -108,37 +106,32 @@ var BookmarkPropertiesPanel = {
    * This method returns the correct label for the dialog's "accept"
    * button based on the variant of the dialog.
    */
   _getAcceptLabel: function BPP__getAcceptLabel() {
     if (this._action == ACTION_ADD) {
       if (this._URIs.length)
         return this._strings.getString("dialogAcceptLabelAddMulti");
 
-      if (this._itemType == LIVEMARK_CONTAINER)
-        return this._strings.getString("dialogAcceptLabelAddLivemark");
-
       if (this._dummyItem)
         return this._strings.getString("dialogAcceptLabelAddItem");
 
       return this._strings.getString("dialogAcceptLabelSaveItem");
     }
     return this._strings.getString("dialogAcceptLabelEdit");
   },
 
   /**
    * This method returns the correct title for the current variant
    * of this dialog.
    */
   _getDialogTitle: function BPP__getDialogTitle() {
     if (this._action == ACTION_ADD) {
       if (this._itemType == BOOKMARK_ITEM)
         return this._strings.getString("dialogTitleAddBookmark");
-      if (this._itemType == LIVEMARK_CONTAINER)
-        return this._strings.getString("dialogTitleAddLivemark");
 
       // add folder
       if (this._itemType != BOOKMARK_FOLDER)
         throw new Error("Unknown item type");
       if (this._URIs.length)
         return this._strings.getString("dialogTitleAddMulti");
 
       return this._strings.getString("dialogTitleAddFolder");
@@ -206,31 +199,16 @@ var BookmarkPropertiesPanel = {
             if ("URIList" in dialogInfo) {
               this._title = this._strings.getString("bookmarkAllTabsDefault");
               this._URIs = dialogInfo.URIList;
             } else
               this._title = this._strings.getString("newFolderDefault");
               this._dummyItem = true;
           }
           break;
-
-        case "livemark":
-          this._itemType = LIVEMARK_CONTAINER;
-          if ("feedURI" in dialogInfo)
-            this._feedURI = dialogInfo.feedURI;
-          if ("siteURI" in dialogInfo)
-            this._siteURI = dialogInfo.siteURI;
-
-          if (!this._title) {
-            if (this._feedURI) {
-              this._title = await PlacesUtils.history.fetch(this._feedURI) ||
-                            this._feedURI.spec;
-            } else
-              this._title = this._strings.getString("newLivemarkDefault");
-          }
       }
     } else { // edit
       this._node = dialogInfo.node;
       this._title = this._node.title;
       if (PlacesUtils.nodeIsFolder(this._node))
         this._itemType = BOOKMARK_FOLDER;
       else if (PlacesUtils.nodeIsURI(this._node))
         this._itemType = BOOKMARK_ITEM;
@@ -468,22 +446,16 @@ var BookmarkPropertiesPanel = {
       if (this._postData)
         info.postData = this._postData;
 
       if (this._charSet) {
         PlacesUIUtils.setCharsetForPage(this._uri, this._charSet, window).catch(Cu.reportError);
       }
 
       itemGuid = await PlacesTransactions.NewBookmark(info).transact();
-    } else if (this._itemType == LIVEMARK_CONTAINER) {
-      info.feedUrl = this._feedURI;
-      if (this._siteURI)
-        info.siteUrl = this._siteURI;
-
-      itemGuid = await PlacesTransactions.NewLivemark(info).transact();
     } else if (this._itemType == BOOKMARK_FOLDER) {
       // NewFolder requires a url rather than uri.
       info.children = this._URIs.map(item => {
         return { url: item.uri, title: item.title };
       });
       itemGuid = await PlacesTransactions.NewFolder(info).transact();
     } else {
       throw new Error(`unexpected value for _itemType:  ${this._itemType}`);
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -682,17 +682,17 @@ PlacesController.prototype = {
     else
       PlacesUIUtils.openURINodesInTabs(nodes, aEvent, this._view);
   },
 
   /**
    * Shows the Add Bookmark UI for the current insertion point.
    *
    * @param aType
-   *        the type of the new item (bookmark/livemark/folder)
+   *        the type of the new item (bookmark/folder)
    */
   async newItem(aType) {
     let ip = this._view.insertionPoint;
     if (!ip)
       throw Cr.NS_ERROR_NOT_AVAILABLE;
 
     let bookmarkGuid =
       PlacesUIUtils.showBookmarkDialog({ action: "add",
--- a/browser/components/places/tests/browser/browser.ini
+++ b/browser/components/places/tests/browser/browser.ini
@@ -27,18 +27,16 @@ support-files =
 skip-if = os != 'mac' # Mac-only functionality
 [browser_bookmarks_change_title.js]
 [browser_bookmarks_sidebar_search.js]
 support-files =
   pageopeningwindow.html
 [browser_bookmarkProperties_addFolderDefaultButton.js]
 [browser_bookmarkProperties_addKeywordForThisSearch.js]
 skip-if = (verify && debug)
-[browser_bookmarkProperties_addLivemark.js]
-skip-if = (verify && debug && (os == 'linux' || os == 'win'))
 [browser_bookmarkProperties_bookmarkAllTabs.js]
 skip-if = (verify && debug && (os == 'win' || os == 'mac'))
 [browser_bookmarkProperties_cancel.js]
 [browser_bookmarkProperties_editFolder.js]
 [browser_bookmarkProperties_editTagContainer.js]
 [browser_bookmarkProperties_no_user_actions.js]
 [browser_bookmarkProperties_newFolder.js]
 [browser_bookmarkProperties_readOnlyRoot.js]
deleted file mode 100644
--- a/browser/components/places/tests/browser/browser_bookmarkProperties_addLivemark.js
+++ /dev/null
@@ -1,38 +0,0 @@
-"use strict";
-
-add_task(async function() {
-  info("Add a live bookmark editing its data");
-
-  await withSidebarTree("bookmarks", async function(tree) {
-    tree.selectItems([PlacesUtils.bookmarks.unfiledGuid]);
-
-    await withBookmarksDialog(
-      true,
-      function openDialog() {
-        PlacesCommandHook.addLiveBookmark("http://livemark.com/",
-                                          "livemark", "description");
-      },
-      async function test(dialogWin) {
-        let promiseTitleChangeNotification = PlacesTestUtils.waitForNotification(
-          "onItemChanged", (unused, prop, isAnno, val) => prop == "title" && val == "modified");
-
-        fillBookmarkTextField("editBMPanel_namePicker", "modified", dialogWin);
-
-        await promiseTitleChangeNotification;
-
-        let bookmark = await PlacesUtils.bookmarks.fetch({
-          parentGuid: PlacesUtils.bookmarks.toolbarGuid,
-          index: PlacesUtils.bookmarks.DEFAULT_INDEX,
-        });
-
-        Assert.equal(bookmark.title, "modified", "folder name has been edited");
-
-        let livemark = await PlacesUtils.livemarks.getLivemark({
-          guid: bookmark.guid,
-        });
-        Assert.equal(livemark.feedURI.spec, "http://livemark.com/", "livemark has the correct url");
-        Assert.equal(livemark.title, "modified", "livemark has the correct title");
-      }
-    );
-  });
-});
--- a/browser/locales/en-US/chrome/browser/places/bookmarkProperties.properties
+++ b/browser/locales/en-US/chrome/browser/places/bookmarkProperties.properties
@@ -1,19 +1,16 @@
 # 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/.
 
 dialogAcceptLabelAddItem=Add
 dialogAcceptLabelSaveItem=Save
-dialogAcceptLabelAddLivemark=Subscribe
 dialogAcceptLabelAddMulti=Add Bookmarks
 dialogAcceptLabelEdit=Save
 dialogTitleAddBookmark=New Bookmark
-dialogTitleAddLivemark=Subscribe with Live Bookmark
 dialogTitleAddFolder=New Folder
 dialogTitleAddMulti=New Bookmarks
 dialogTitleEdit=Properties for ā€œ%Sā€
 
 bookmarkAllTabsDefault=[Folder Name]
 newFolderDefault=New Folder
 newBookmarkDefault=New Bookmark
-newLivemarkDefault=New Live Bookmark
--- a/toolkit/components/places/BookmarkHTMLUtils.jsm
+++ b/toolkit/components/places/BookmarkHTMLUtils.jsm
@@ -16,17 +16,18 @@
  *   For backwards compatibility, if we don't find this, we assume that the
  *   hierarchy is rooted at the bookmarks menu.
  * Heading := any heading other than h1
  *   Old version used this to set attributes on the current container. We only
  *   care about the content of the heading container, which contains the title
  *   of the bookmark container.
  * Bookmark := a
  *   HREF is the destination of the bookmark
- *   FEEDURL is the URI of the RSS feed if this is a livemark.
+ *   FEEDURL is the URI of the RSS feed. This is deprecated and no more
+ *   supported, but some old files may still contain it.
  *   LAST_CHARSET is stored as an annotation so that the next time we go to
  *     that page we remember the user's preference.
  *   ICON will be stored in the favicon service
  *   ICON_URI is new for places bookmarks.html, it refers to the original
  *     URI of the favicon so we don't have to make up favicon URLs.
  *   Text of the <a> container is the name of the bookmark
  *   Ignored: LAST_VISIT, ID (writing out non-RDF IDs can confuse Firefox 2)
  * Bookmark comment := dd
@@ -276,22 +277,16 @@ function Frame(aFolder) {
    * contains the URL of the previous bookmark created. This is used so that
    * when we encounter a <dd>, we know what bookmark to associate the text with.
    * This is cleared whenever we hit a <h3>, so that we know NOT to save this
    * with a bookmark, but to keep it until
    */
   this.previousLink = null;
 
   /**
-   * contains the URL of the previous livemark, so that when the link ends,
-   * and the livemark title is known, we can create it.
-   */
-  this.previousFeed = null;
-
-  /**
    * Contains a reference to the last created bookmark or folder object.
    */
   this.previousItem = null;
 
   /**
    * Contains the date-added and last-modified-date of an imported item.
    * Used to override the values set by insertBookmark, createFolder, etc.
    */
@@ -483,85 +478,57 @@ BookmarkImporter.prototype = {
   /*
    * Handles "<a" tags by creating a new bookmark. The title of the bookmark
    * will be the text content, which will be stuffed in previousText for us
    * and which will be saved by handleLinkEnd
    */
   _handleLinkBegin: function handleLinkBegin(aElt) {
     let frame = this._curFrame;
 
-    frame.previousFeed = null;
     frame.previousItem = null;
     frame.previousText = ""; // Will hold link text, clear it.
 
     // Get the attributes we care about.
     let href = this._safeTrim(aElt.getAttribute("href"));
-    let feedUrl = this._safeTrim(aElt.getAttribute("feedurl"));
     let icon = this._safeTrim(aElt.getAttribute("icon"));
     let iconUri = this._safeTrim(aElt.getAttribute("icon_uri"));
     let lastCharset = this._safeTrim(aElt.getAttribute("last_charset"));
     let keyword = this._safeTrim(aElt.getAttribute("shortcuturl"));
     let postData = this._safeTrim(aElt.getAttribute("post_data"));
     let dateAdded = this._safeTrim(aElt.getAttribute("add_date"));
     let lastModified = this._safeTrim(aElt.getAttribute("last_modified"));
     let tags = this._safeTrim(aElt.getAttribute("tags"));
 
-    // For feeds, get the feed URL.  If it is invalid, mPreviousFeed will be
-    // NULL and we'll create it as a normal bookmark.
-    if (feedUrl) {
-      frame.previousFeed = feedUrl;
-    }
-
     // Ignore <a> tags that have no href.
-    if (href) {
-      // Save the address if it's valid.  Note that we ignore errors if this is a
-      // feed since href is optional for them.
-      try {
-        frame.previousLink = Services.io.newURI(href).spec;
-      } catch (e) {
-        if (!frame.previousFeed) {
-          frame.previousLink = null;
-          return;
-        }
-      }
-    } else {
+    try {
+      frame.previousLink = Services.io.newURI(href).spec;
+    } catch (e) {
       frame.previousLink = null;
-      // The exception is for feeds, where the href is an optional component
-      // indicating the source web site.
-      if (!frame.previousFeed) {
-        return;
-      }
+      return;
     }
 
     let bookmark = {};
 
-    // Only set the url for bookmarks, not for livemarks.
-    if (frame.previousLink && !frame.previousFeed) {
+    // Only set the url for bookmarks.
+    if (frame.previousLink) {
       bookmark.url = frame.previousLink;
     }
 
     if (dateAdded) {
       bookmark.dateAdded = this._convertImportedDateToInternalDate(dateAdded);
     }
     // Save bookmark's last modified date.
     if (lastModified) {
       bookmark.lastModified = this._convertImportedDateToInternalDate(lastModified);
     }
 
     if (!dateAdded && lastModified) {
       bookmark.dateAdded = bookmark.lastModified;
     }
 
-    if (frame.previousFeed) {
-      // This is a livemark, we've done all we need to do here, so finish early.
-      frame.folder.children.push(bookmark);
-      frame.previousItem = bookmark;
-      return;
-    }
-
     if (tags) {
       bookmark.tags = tags.split(",").filter(aTag => aTag.length > 0 &&
         aTag.length <= PlacesUtils.bookmarks.MAX_TAG_LENGTH);
 
       // If we end up with none, then delete the property completely.
       if (!bookmark.tags.length) {
         delete bookmark.tags;
       }
@@ -622,36 +589,16 @@ BookmarkImporter.prototype = {
   /**
    * Saves the title for the given bookmark.
    */
   _handleLinkEnd: function handleLinkEnd() {
     let frame = this._curFrame;
     frame.previousText = frame.previousText.trim();
 
     if (frame.previousItem != null) {
-      if (frame.previousFeed) {
-        if (!frame.previousItem.hasOwnProperty("annos")) {
-          frame.previousItem.annos = [];
-        }
-        frame.previousItem.type = PlacesUtils.bookmarks.TYPE_FOLDER;
-        frame.previousItem.annos.push({
-          "name": PlacesUtils.LMANNO_FEEDURI,
-          "flags": 0,
-          "expires": 4,
-          "value": frame.previousFeed,
-        });
-        if (frame.previousLink) {
-          frame.previousItem.annos.push({
-            "name": PlacesUtils.LMANNO_SITEURI,
-            "flags": 0,
-            "expires": 4,
-            "value": frame.previousLink,
-          });
-        }
-      }
       frame.previousItem.title = frame.previousText;
     }
 
     frame.previousText = "";
   },
 
   _openContainer: function openContainer(aElt) {
     if (aElt.namespaceURI != "http://www.w3.org/1999/xhtml") {
@@ -951,19 +898,17 @@ BookmarkExporter.prototype = {
     else
       this._writeLine(aIndent + "</DL><p>");
   },
 
   async _writeContainerContents(aItem, aIndent) {
     let localIndent = aIndent + EXPORT_INDENT;
 
     for (let child of aItem.children) {
-      if (child.annos && child.annos.some(anno => anno.name == PlacesUtils.LMANNO_FEEDURI)) {
-        this._writeLivemark(child, localIndent);
-      } else if (child.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER) {
+      if (child.type == PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER) {
         await this._writeContainer(child, localIndent);
       } else if (child.type == PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR) {
         this._writeSeparator(child, localIndent);
       } else {
         await this._writeItem(child, localIndent);
       }
     }
   },
@@ -971,27 +916,16 @@ BookmarkExporter.prototype = {
   _writeSeparator(aItem, aIndent) {
     this._write(aIndent + "<HR");
     // We keep exporting separator titles, but don't support them anymore.
     if (aItem.title)
       this._writeAttribute("NAME", escapeHtmlEntities(aItem.title));
     this._write(">");
   },
 
-  _writeLivemark(aItem, aIndent) {
-    this._write(aIndent + "<DT><A");
-    let feedSpec = aItem.annos.find(anno => anno.name == PlacesUtils.LMANNO_FEEDURI).value;
-    this._writeAttribute("FEEDURL", escapeUrl(feedSpec));
-    let siteSpecAnno = aItem.annos.find(anno => anno.name == PlacesUtils.LMANNO_SITEURI);
-    if (siteSpecAnno)
-      this._writeAttribute("HREF", escapeUrl(siteSpecAnno.value));
-    this._writeLine(">" + escapeHtmlEntities(aItem.title) + "</A>");
-    this._writeDescription(aItem, aIndent);
-  },
-
   async _writeItem(aItem, aIndent) {
     try {
       NetUtil.newURI(aItem.uri);
     } catch (ex) {
       // If the item URI is invalid, skip the item instead of failing later.
       return;
     }
 
--- a/toolkit/components/places/Bookmarks.jsm
+++ b/toolkit/components/places/Bookmarks.jsm
@@ -383,17 +383,16 @@ var Bookmarks = Object.freeze({
     }
     if (options && typeof options != "object") {
       throw new Error("Options should be a valid object");
     }
     let fixupOrSkipInvalidEntries = options && !!options.fixupOrSkipInvalidEntries;
 
     // Serialize the tree into an array of items to insert into the db.
     let insertInfos = [];
-    let insertLivemarkInfos = [];
     let urlsThatMightNeedPlaces = [];
 
     // We want to use the same 'last added' time for all the entries
     // we import (so they won't differ by a few ms based on where
     // they are in the tree, and so we don't needlessly construct
     // multiple dates).
     let fallbackLastAdded = new Date();
 
@@ -472,30 +471,16 @@ var Bookmarks = Object.freeze({
           insertInfo.index = null;
         }
         // Store the URL if this is a bookmark, so we can ensure we create an
         // entry in moz_places for it.
         if (insertInfo.type == Bookmarks.TYPE_BOOKMARK) {
           urlsThatMightNeedPlaces.push(insertInfo.url);
         }
 
-        // As we don't track indexes for children of root folders, and we
-        // insert livemarks separately, we create a temporary placeholder in
-        // the bookmarks, and later we'll replace it by the real livemark.
-        if (isLivemark(insertInfo)) {
-          // Make the current insertInfo item a placeholder.
-          let livemarkInfo = Object.assign({}, insertInfo);
-
-          // Delete the annotations that make it a livemark.
-          delete insertInfo.annos;
-
-          // Now save the livemark info for later.
-          insertLivemarkInfos.push(livemarkInfo);
-        }
-
         insertInfos.push(insertInfo);
         // Process any children. We have to use info.children here rather than
         // insertInfo.children because validateBookmarkObject doesn't copy over
         // the children ref, as the default bookmark validators object doesn't
         // know about children.
         if (info.children) {
           // start children of this item off at index 0.
           let childrenLastAdded = appendInsertionInfoForInfoArray(info.children, 0, insertInfo.guid);
@@ -528,35 +513,16 @@ var Bookmarks = Object.freeze({
 
       if (treeParent._parentId == PlacesUtils.tagsFolderId) {
         throw new Error("Can't use insertTree to insert tags.");
       }
 
       await insertBookmarkTree(insertInfos, source, treeParent,
                                urlsThatMightNeedPlaces, lastAddedForParent);
 
-      for (let info of insertLivemarkInfos) {
-        try {
-          await insertLivemarkData(info);
-        } catch (ex) {
-          // This can arguably fail, if some of the livemarks data is invalid.
-          if (fixupOrSkipInvalidEntries) {
-            // The placeholder should have been removed at this point, thus we
-            // can avoid to notify about it.
-            let placeholderIndex = insertInfos.findIndex(item => item.guid == info.guid);
-            if (placeholderIndex != -1) {
-              insertInfos.splice(placeholderIndex, 1);
-            }
-          } else {
-            // Throw if we're not lenient to input mistakes.
-            throw ex;
-          }
-        }
-      }
-
       // Now update the indices of root items in the objects we return.
       // These may be wrong if someone else modified the table between
       // when we fetched the parent and inserted our items, but the actual
       // inserts will have been correct, and we don't want to query the DB
       // again if we don't have to. bug 1347230 covers improving this.
       let rootIndex = treeParent._childCount;
       for (let insertInfo of insertInfos) {
         if (insertInfo.parentGuid == tree.guid) {
@@ -1821,27 +1787,16 @@ function insertBookmark(item, parent) {
       // ...though we don't wait for the calculation.
       updateFrecency(db, [item.url]).catch(Cu.reportError);
     }
 
     return item;
   });
 }
 
-/**
- * Determines if a bookmark is a Livemark depending on how it is annotated.
- *
- * @param {Object} node The bookmark node to check.
- * @returns {Boolean} True if the node is a Livemark, false otherwise.
- */
-function isLivemark(node) {
-  return node.type == Bookmarks.TYPE_FOLDER && node.annos &&
-         node.annos.some(anno => anno.name == PlacesUtils.LMANNO_FEEDURI);
-}
-
 function insertBookmarkTree(items, source, parent, urls, lastAddedForParent) {
   return PlacesUtils.withConnectionWrapper("Bookmarks.jsm: insertBookmarkTree", async function(db) {
     await db.executeTransaction(async function transaction() {
       await maybeInsertManyPlaces(db, urls);
 
       let syncChangeDelta =
         PlacesSyncUtils.bookmarks.determineSyncChangeDelta(source);
       let syncStatus =
@@ -1882,66 +1837,16 @@ function insertBookmarkTree(items, sourc
     // We don't wait for the frecency calculation.
     updateFrecency(db, urls, true).catch(Cu.reportError);
 
     return items;
   });
 }
 
 /**
- * Handles data for a Livemark insert.
- *
- * @param {Object} item Livemark item that need to be added.
- */
-async function insertLivemarkData(item) {
-  // Delete the placeholder but note the index of it, so that we can insert the
-  // livemark item at the right place.
-  let placeholder = await Bookmarks.fetch(item.guid);
-  let index = placeholder.index;
-  await removeBookmarks([item], {source: item.source});
-
-  let feedURI = null;
-  let siteURI = null;
-  item.annos = item.annos.filter(function(aAnno) {
-    switch (aAnno.name) {
-      case PlacesUtils.LMANNO_FEEDURI:
-        feedURI = NetUtil.newURI(aAnno.value);
-        return false;
-      case PlacesUtils.LMANNO_SITEURI:
-        siteURI = NetUtil.newURI(aAnno.value);
-        return false;
-      default:
-        return true;
-    }
-  });
-
-  if (feedURI) {
-    item.feedURI = feedURI;
-    item.siteURI = siteURI;
-    item.index = index;
-
-    if (item.dateAdded) {
-      item.dateAdded = PlacesUtils.toPRTime(item.dateAdded);
-    }
-    if (item.lastModified) {
-      item.lastModified = PlacesUtils.toPRTime(item.lastModified);
-    }
-
-    let livemark = await PlacesUtils.livemarks.addLivemark(item);
-
-    let id = livemark.id;
-    if (item.annos && item.annos.length) {
-      // Note: for annotations, we intentionally skip updating the last modified
-      // value for the bookmark, to avoid a second update of the added bookmark.
-      PlacesUtils.setAnnotationsForItem(id, item.annos, item.source, true);
-    }
-  }
-}
-
-/**
  * Handles special data on a bookmark, e.g. annotations, keywords, tags, charsets,
  * inserting the data into the appropriate place.
  *
  * @param {Integer} itemId The ID of the item within the bookmarks database.
  * @param {Object} item The bookmark item with possible special data to be inserted.
  */
 async function handleBookmarkItemSpecialData(itemId, item) {
   if (item.annos && item.annos.length) {
--- a/toolkit/components/places/Database.cpp
+++ b/toolkit/components/places/Database.cpp
@@ -99,20 +99,16 @@
 #define DATABASE_BUSY_TIMEOUT_MS 100
 
 // Old Sync GUID annotation.
 #define SYNCGUID_ANNO NS_LITERAL_CSTRING("sync/guid")
 
 // Places string bundle, contains internationalized bookmark root names.
 #define PLACES_BUNDLE "chrome://places/locale/places.properties"
 
-// Livemarks annotations.
-#define LMANNO_FEEDURI "livemark/feedURI"
-#define LMANNO_SITEURI "livemark/siteURI"
-
 // This is no longer used & obsolete except for during migration.
 // Note: it may still be found in older places databases.
 #define MOBILE_ROOT_ANNO "mobile/bookmarksRoot"
 
 // This annotation is no longer used & is obsolete, but here for migration.
 #define LAST_USED_ANNO NS_LITERAL_CSTRING("bookmarkPropertiesDialog/folderLastUsed")
 // This is key in the meta table that the LAST_USED_ANNO is migrated to.
 #define LAST_USED_FOLDERS_META_KEY NS_LITERAL_CSTRING("places/bookmarks/edit/lastusedfolder")
--- a/toolkit/components/places/PlacesTransactions.jsm
+++ b/toolkit/components/places/PlacesTransactions.jsm
@@ -83,17 +83,17 @@ var EXPORTED_SYMBOLS = ["PlacesTransacti
  * reveal once the transaction is executed.
  *
  * Executing Transactions (the |transact| method of transactions)
  * --------------------------------------------------------------
  * Once a transaction is created, you must call its |transact| method for it to
  * be executed and take effect.  |transact| is an asynchronous method that takes
  * no arguments, and returns a promise that resolves once the transaction is
  * executed.  Executing one of the transactions for creating items (NewBookmark,
- * NewFolder, NewSeparator or NewLivemark) resolve to the new item's GUID.
+ * NewFolder, NewSeparator) resolve to the new item's GUID.
  * There's no resolution value for other transactions.
  * If a transaction fails to execute, |transact| rejects and the transactions
  * history is not affected.
  *
  * |transact| throws if it's called more than once (successfully or not) on the
  * same transaction object.
  *
  * Batches
@@ -940,33 +940,16 @@ DefineTransaction.defineArrayInputProp("
  *       always ignored.  The index property is ignored for all items but the
  *       root one.
  * @return {Promise}
  * @resolves to the guid of the new item.
  */
 // TODO: Replace most of this with insertTree.
 function createItemsFromBookmarksTree(tree, restoring = false,
                                       excludingAnnotations = []) {
-  function extractLivemarkDetails(annos) {
-    let feedURI = null, siteURI = null;
-    annos = annos.filter(anno => {
-      switch (anno.name) {
-        case PlacesUtils.LMANNO_FEEDURI:
-          feedURI = Services.io.newURI(anno.value);
-          return false;
-        case PlacesUtils.LMANNO_SITEURI:
-          siteURI = Services.io.newURI(anno.value);
-          return false;
-        default:
-          return true;
-      }
-    });
-    return [feedURI, siteURI, annos];
-  }
-
   async function createItem(item,
                             parentGuid,
                             index = PlacesUtils.bookmarks.DEFAULT_INDEX) {
     let guid;
     let info = { parentGuid, index };
     if (restoring) {
       info.guid = item.guid;
       info.dateAdded = PlacesUtils.toDate(item.dateAdded);
@@ -988,43 +971,27 @@ function createItemsFromBookmarksTree(tr
         }
         if ("tags" in item) {
           PlacesUtils.tagging.tagURI(Services.io.newURI(item.uri),
                                      item.tags.split(","));
         }
         break;
       }
       case PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER: {
-        // Either a folder or a livemark
-        let feedURI, siteURI;
-        [feedURI, siteURI, annos] = extractLivemarkDetails(annos);
-        if (!feedURI) {
-          info.type = PlacesUtils.bookmarks.TYPE_FOLDER;
-          if (typeof(item.title) == "string")
-            info.title = item.title;
-          guid = (await PlacesUtils.bookmarks.insert(info)).guid;
-          if ("children" in item) {
-            for (let child of item.children) {
-              await createItem(child, guid);
-            }
+        info.type = PlacesUtils.bookmarks.TYPE_FOLDER;
+        if (typeof(item.title) == "string")
+          info.title = item.title;
+        guid = (await PlacesUtils.bookmarks.insert(info)).guid;
+        if ("children" in item) {
+          for (let child of item.children) {
+            await createItem(child, guid);
           }
-          if (restoring)
-            shouldResetLastModified = true;
-        } else {
-          info.parentId = await PlacesUtils.promiseItemId(parentGuid);
-          info.feedURI = feedURI;
-          info.siteURI = siteURI;
-          if (info.dateAdded)
-            info.dateAdded = PlacesUtils.toPRTime(info.dateAdded);
-          if (info.lastModified)
-            info.lastModified = PlacesUtils.toPRTime(info.lastModified);
-          if (typeof(item.title) == "string")
-            info.title = item.title;
-          guid = (await PlacesUtils.livemarks.addLivemark(info)).guid;
         }
+        if (restoring)
+          shouldResetLastModified = true;
         break;
       }
       case PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR: {
         info.type = PlacesUtils.bookmarks.TYPE_SEPARATOR;
         guid = (await PlacesUtils.bookmarks.insert(info)).guid;
         break;
       }
     }
@@ -1193,59 +1160,16 @@ PT.NewSeparator.prototype = Object.seal(
     info = await PlacesUtils.bookmarks.insert(info);
     this.undo = PlacesUtils.bookmarks.remove.bind(PlacesUtils.bookmarks, info);
     this.redo = PlacesUtils.bookmarks.insert.bind(PlacesUtils.bookmarks, info);
     return info.guid;
   },
 });
 
 /**
- * Transaction for creating a live bookmark (see mozIAsyncLivemarks for the
- * semantics).
- *
- * Required Input Properties: feedUrl, title, parentGuid.
- * Optional Input Properties: siteUrl, index, annotations.
- *
- * When this transaction is executed, it's resolved to the new livemark's
- * GUID.
- */
-PT.NewLivemark = DefineTransaction(["feedUrl", "title", "parentGuid"],
-                                   ["siteUrl", "index", "annotations"]);
-PT.NewLivemark.prototype = Object.seal({
-  async execute({ feedUrl, title, parentGuid, siteUrl, index, annotations }) {
-    let livemarkInfo = { title,
-                         feedURI: Services.io.newURI(feedUrl.href),
-                         siteURI: siteUrl ? Services.io.newURI(siteUrl.href) : null,
-                         index,
-                         parentGuid};
-    let createItem = async function() {
-      let livemark = await PlacesUtils.livemarks.addLivemark(livemarkInfo);
-      if (annotations.length > 0) {
-        PlacesUtils.setAnnotationsForItem(livemark.id, annotations,
-          Ci.nsINavBookmarksService.SOURCE_DEFAULT, true);
-      }
-      return livemark;
-    };
-
-    let livemark = await createItem();
-    livemarkInfo.guid = livemark.guid;
-    livemarkInfo.dateAdded = livemark.dateAdded;
-    livemarkInfo.lastModified = livemark.lastModified;
-
-    this.undo = async function() {
-      await PlacesUtils.livemarks.removeLivemark(livemark);
-    };
-    this.redo = async function() {
-      livemark = await createItem();
-    };
-    return livemark.guid;
-  },
-});
-
-/**
  * Transaction for moving an item.
  *
  * Required Input Properties: guid, newParentGuid.
  * Optional Input Properties  newIndex.
  */
 PT.Move = DefineTransaction(["guids", "newParentGuid"], ["newIndex"]);
 PT.Move.prototype = Object.seal({
   async execute({ guids, newParentGuid, newIndex }) {
--- a/toolkit/components/places/PlacesUtils.jsm
+++ b/toolkit/components/places/PlacesUtils.jsm
@@ -121,29 +121,26 @@ function getAnnotationsForItem(aItemId) 
   return annos;
 }
 
 /**
  * Serializes the given node in JSON format.
  *
  * @param aNode
  *        An nsINavHistoryResultNode
- * @param aIsLivemark
- *        Whether the node represents a livemark.
  */
-function serializeNode(aNode, aIsLivemark) {
+function serializeNode(aNode) {
   let data = {};
 
   data.title = aNode.title;
   // The id is no longer used for copying within the same instance/session of
   // Firefox as of at least 61. However, we keep the id for now to maintain
   // backwards compat of drag and drop with older Firefox versions.
   data.id = aNode.itemId;
   data.itemGuid = aNode.bookmarkGuid;
-  data.livemark = aIsLivemark;
   // Add an instanceId so we can tell which instance of an FF session the data
   // is coming from.
   data.instanceId = PlacesUtils.instanceId;
 
   let guid = aNode.bookmarkGuid;
 
   // Some nodes, e.g. the unfiled/menu/toolbar ones can have a virtual guid, so
   // we ignore any that are a folder shortcut. These will be handled below.
@@ -918,23 +915,19 @@ var PlacesUtils = {
   /**
    * String-wraps a result node according to the rules of the specified
    * content type for copy or move operations.
    *
    * @param   aNode
    *          The Result node to wrap (serialize)
    * @param   aType
    *          The content type to serialize as
-   * @param   [optional] aFeedURI
-   *          Used instead of the node's URI if provided.
-   *          This is useful for wrapping a livemark as TYPE_X_MOZ_URL,
-   *          TYPE_HTML or TYPE_UNICODE.
    * @return  A string serialization of the node
    */
-  wrapNode(aNode, aType, aFeedURI) {
+  wrapNode(aNode, aType) {
     // when wrapping a node, we want all the items, even if the original
     // query options are excluding them.
     // This can happen when copying from the left hand pane of the bookmarks
     // organizer.
     // @return [node, shouldClose]
     function gatherDataFromNode(node, gatherDataFunc) {
       if (PlacesUtils.nodeIsFolder(node) &&
           node.type != Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER_SHORTCUT &&
@@ -955,20 +948,16 @@ var PlacesUtils = {
                              .replace(/>/g, "&gt;")
                              .replace(/</g, "&lt;")
                              .replace(/"/g, "&quot;")
                              .replace(/'/g, "&apos;");
 
       // escape out potential HTML in the title
       let escapedTitle = node.title ? htmlEscape(node.title) : "";
 
-      if (aFeedURI) {
-        return `<A HREF="${aFeedURI}">${escapedTitle}</A>${NEWLINE}`;
-      }
-
       if (PlacesUtils.nodeIsContainer(node)) {
         asContainer(node);
         let wasOpen = node.containerOpen;
         if (!wasOpen)
           node.containerOpen = true;
 
         let childString = "<DL><DT>" + escapedTitle + "</DT>" + NEWLINE;
         let cc = node.childCount;
@@ -985,20 +974,16 @@ var PlacesUtils = {
       if (PlacesUtils.nodeIsURI(node))
         return `<A HREF="${node.uri}">${escapedTitle}</A>${NEWLINE}`;
       if (PlacesUtils.nodeIsSeparator(node))
         return "<HR>" + NEWLINE;
       return "";
     }
 
     function gatherDataText(node) {
-      if (aFeedURI) {
-        return aFeedURI;
-      }
-
       if (PlacesUtils.nodeIsContainer(node)) {
         asContainer(node);
         let wasOpen = node.containerOpen;
         if (!wasOpen)
           node.containerOpen = true;
 
         let childString = node.title + NEWLINE;
         let cc = node.childCount;
@@ -1017,21 +1002,22 @@ var PlacesUtils = {
       return "";
     }
 
     switch (aType) {
       case this.TYPE_X_MOZ_PLACE:
       case this.TYPE_X_MOZ_PLACE_SEPARATOR:
       case this.TYPE_X_MOZ_PLACE_CONTAINER: {
         // Serialize the node to JSON.
-        return serializeNode(aNode, aFeedURI);
+        return serializeNode(aNode);
       }
       case this.TYPE_X_MOZ_URL: {
-        if (aFeedURI || PlacesUtils.nodeIsURI(aNode))
-          return (aFeedURI || aNode.uri) + NEWLINE + aNode.title;
+        if (PlacesUtils.nodeIsURI(aNode)) {
+          return aNode.uri + NEWLINE + aNode.title;
+        }
         if (PlacesUtils.nodeIsContainer(aNode)) {
           return PlacesUtils.getURLsForContainerNode(aNode)
             .map(item => item.uri + "\n" + item.title)
             .join("\n");
         }
         return "";
       }
       case this.TYPE_HTML: {
--- a/toolkit/components/places/mozIAsyncLivemarks.idl
+++ b/toolkit/components/places/mozIAsyncLivemarks.idl
@@ -10,29 +10,16 @@ interface mozILivemarkInfo;
 interface mozILivemark;
 
 interface nsINavHistoryResultObserver;
 
 [scriptable, uuid(672387b7-a75d-4e8f-9b49-5c1dcbfff46b)]
 interface mozIAsyncLivemarks : nsISupports
 {
   /**
-   * Creates a new livemark
-   *
-   * @param aLivemarkInfo
-   *        mozILivemarkInfo object containing at least title, parentId,
-   *        index and feedURI of the livemark to create.
-   *
-   * @return {Promise}
-   * @throws NS_ERROR_INVALID_ARG if the supplied information is insufficient
-   *         for the creation.
-   */
-  jsval addLivemark(in jsval aLivemarkInfo);
-
-  /**
    * Removes an existing livemark.
    *
    * @param aLivemarkInfo
    *        mozILivemarkInfo object containing either an id or a guid of the
    *        livemark to remove.
    *
    * @return {Promise}
    * @throws NS_ERROR_INVALID_ARG if the id/guid is invalid.
--- a/toolkit/components/places/nsLivemarkService.js
+++ b/toolkit/components/places/nsLivemarkService.js
@@ -156,88 +156,16 @@ LivemarkService.prototype = {
         // No need to restart the reload timer on shutdown.
         keepReloading: false,
       }).catch(Cu.reportError);
     }
   },
 
   // mozIAsyncLivemarks
 
-  addLivemark(aLivemarkInfo) {
-    if (!aLivemarkInfo) {
-      throw new Components.Exception("Invalid arguments", Cr.NS_ERROR_INVALID_ARG);
-    }
-    let hasParentId = "parentId" in aLivemarkInfo;
-    let hasParentGuid = "parentGuid" in aLivemarkInfo;
-    let hasIndex = "index" in aLivemarkInfo;
-    // Must provide at least non-null parent guid/id, index and feedURI.
-    if ((!hasParentId && !hasParentGuid) ||
-        (hasParentId && aLivemarkInfo.parentId < 1) ||
-        (hasParentGuid && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.parentGuid)) ||
-        (hasIndex && aLivemarkInfo.index < Ci.nsINavBookmarksService.DEFAULT_INDEX) ||
-        !(aLivemarkInfo.feedURI instanceof Ci.nsIURI) ||
-        (aLivemarkInfo.siteURI && !(aLivemarkInfo.siteURI instanceof Ci.nsIURI)) ||
-        (aLivemarkInfo.guid && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.guid))) {
-      throw new Components.Exception("Invalid arguments", Cr.NS_ERROR_INVALID_ARG);
-    }
-
-    return this._withLivemarksMap(async livemarksMap => {
-      if (!aLivemarkInfo.parentGuid)
-        aLivemarkInfo.parentGuid = await PlacesUtils.promiseItemGuid(aLivemarkInfo.parentId);
-
-      // Disallow adding a livemark inside another livemark.
-      if (livemarksMap.has(aLivemarkInfo.parentGuid)) {
-        throw new Components.Exception("Cannot create a livemark inside a livemark", Cr.NS_ERROR_INVALID_ARG);
-      }
-
-      // Create a new livemark.
-      let folder = await PlacesUtils.bookmarks.insert({
-        type: PlacesUtils.bookmarks.TYPE_FOLDER,
-        parentGuid: aLivemarkInfo.parentGuid,
-        title: aLivemarkInfo.title,
-        index: aLivemarkInfo.index,
-        guid: aLivemarkInfo.guid,
-        dateAdded: toDate(aLivemarkInfo.dateAdded) || toDate(aLivemarkInfo.lastModified),
-        source: aLivemarkInfo.source,
-      });
-
-      // Set feed and site URI annotations.
-      let id = await PlacesUtils.promiseItemId(folder.guid);
-
-      // Create the internal Livemark object.
-      let livemark = new Livemark({ id,
-                                    title:        folder.title,
-                                    parentGuid:   folder.parentGuid,
-                                    parentId:     await PlacesUtils.promiseItemId(folder.parentGuid),
-                                    index:        folder.index,
-                                    feedURI:      aLivemarkInfo.feedURI,
-                                    siteURI:      aLivemarkInfo.siteURI,
-                                    guid:         folder.guid,
-                                    dateAdded:    toPRTime(folder.dateAdded),
-                                    lastModified: toPRTime(folder.lastModified),
-                                  });
-
-      livemark.writeFeedURI(aLivemarkInfo.feedURI, aLivemarkInfo.source);
-      if (aLivemarkInfo.siteURI) {
-        livemark.writeSiteURI(aLivemarkInfo.siteURI, aLivemarkInfo.source);
-      }
-
-      if (aLivemarkInfo.lastModified) {
-        await PlacesUtils.bookmarks.update({ guid: folder.guid,
-                                             lastModified: toDate(aLivemarkInfo.lastModified),
-                                             source: aLivemarkInfo.source });
-        livemark.lastModified = aLivemarkInfo.lastModified;
-      }
-
-      livemarksMap.set(folder.guid, livemark);
-
-      return livemark;
-    });
-  },
-
   removeLivemark(aLivemarkInfo) {
     if (!aLivemarkInfo) {
       throw new Components.Exception("Invalid arguments", Cr.NS_ERROR_INVALID_ARG);
     }
     // Accept either a guid or an id.
     let hasGuid = "guid" in aLivemarkInfo;
     let hasId = "id" in aLivemarkInfo;
     if ((hasGuid && !/^[a-zA-Z0-9\-_]{12}$/.test(aLivemarkInfo.guid)) ||
@@ -493,25 +421,16 @@ Livemark.prototype = {
   set status(val) {
     if (this._status != val) {
       this._status = val;
       this._invalidateRegisteredContainers();
     }
     return this._status;
   },
 
-  writeFeedURI(aFeedURI, aSource) {
-    PlacesUtils.annotations
-               .setItemAnnotation(this.id, PlacesUtils.LMANNO_FEEDURI,
-                                  aFeedURI.spec,
-                                  0, PlacesUtils.annotations.EXPIRE_NEVER,
-                                  aSource, true);
-    this.feedURI = aFeedURI;
-  },
-
   writeSiteURI(aSiteURI, aSource) {
     if (!aSiteURI) {
       PlacesUtils.annotations.removeItemAnnotation(this.id,
                                                    PlacesUtils.LMANNO_SITEURI,
                                                    aSource);
       this.siteURI = null;
       return;
     }
--- a/toolkit/components/places/tests/chrome/chrome.ini
+++ b/toolkit/components/places/tests/chrome/chrome.ini
@@ -1,14 +1,7 @@
 [DEFAULT]
 support-files = head.js
 
-[test_303567.xul]
-[test_341972a.xul]
-[test_341972b.xul]
-[test_342484.xul]
 [test_371798.xul]
-[test_381357.xul]
 [test_favicon_annotations.xul]
-[test_reloadLivemarks.xul]
-skip-if = verify
 [test_browser_disableglobalhistory.xul]
 support-files = browser_disableglobalhistory.xul
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_303567.xul
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Add Bad Livemarks"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-// Test that for feeds with items that have no link:
-//   * the link-less items are present in the database.
-//   * the feed's site URI is substituted for each item's link.
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-const LIVEMARKS = [
-  { feedURI: NetUtil.newURI("http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/link-less-items.rss"),
-    siteURI: NetUtil.newURI("http://mochi.test:8888/"),
-    urls: [
-      "http://feed-item-link.com/",
-      "http://feed-link.com/",
-      "http://feed-item-link.com/",
-    ],
-    message: "Ensure link-less livemark item picked up site uri.",
-  },
-  { feedURI: NetUtil.newURI("http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/link-less-items-no-site-uri.rss"),
-    siteURI: null,
-    urls: [
-      "http://feed-item-link.com/",
-      "http://feed-item-link.com/",
-    ],
-    message: "Ensure livemark item links did not inherit site uri."
-  },  
-];
-
-function runTest()
-{
-  let loadCount = 0;
-
-  function testLivemark(aLivemarkData) {
-    PlacesUtils.livemarks.addLivemark(
-      { title: "foo"
-      , parentGuid: PlacesUtils.bookmarks.toolbarGuid
-      , feedURI: aLivemarkData.feedURI
-      , siteURI: aLivemarkData.siteURI
-      })
-      .then(function (aLivemark) {
-        is (aLivemark.feedURI.spec, aLivemarkData.feedURI.spec,
-            "Get correct feedURI");
-        if (aLivemarkData.siteURI) {
-          is (aLivemark.siteURI.spec, aLivemarkData.siteURI.spec,
-              "Get correct siteURI");
-        }
-        else {
-          is (aLivemark.siteURI, null, "Get correct siteURI");
-        }
-
-        waitForLivemarkLoad(aLivemark, function (aLivemark) {
-          let nodes = aLivemark.getNodesForContainer({});
-          is(nodes.length, aLivemarkData.urls.length,
-             "Ensure all the livemark items were created.");
-          aLivemarkData.urls.forEach(function (aUrl, aIndex) {
-            let node = nodes[aIndex];
-            is(node.uri, aUrl, aLivemarkData.message);
-          });
-
-          PlacesUtils.livemarks.removeLivemark(aLivemark).then(() => {
-            if (++loadCount == LIVEMARKS.length)
-              SimpleTest.finish();
-          });
-        });
-      }, function () {
-        is(true, false, "Should not fail adding a livemark");
-      }
-    );
-  }
-
-  LIVEMARKS.forEach(testLivemark);
-}
-
-function waitForLivemarkLoad(aLivemark, aCallback) {
-  // Don't need a real node here.
-  let node = {};
-  let resultObserver = {
-    nodeInserted: function() {},
-    nodeRemoved: function() {},
-    nodeAnnotationChanged: function() {},
-    nodeTitleChanged: function() {},
-    nodeHistoryDetailsChanged: function() {},
-    nodeMoved: function() {},
-    ontainerStateChanged: function () {},
-    sortingChanged: function() {},
-    batching: function() {},
-    invalidateContainer: function(node) {
-      isnot(aLivemark.status, Ci.mozILivemark.STATUS_FAILED,
-            "Loading livemark should success");
-      if (aLivemark.status == Ci.mozILivemark.STATUS_READY) {
-        aLivemark.unregisterForUpdates(node, resultObserver);
-        aCallback(aLivemark);
-      }
-    }
-  };
-  aLivemark.registerForUpdates(node, resultObserver);
-  aLivemark.reload();
-}
-
-]]>
-</script>
-</window>
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_341972a.xul
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Update Livemark SiteURI"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-/*
- Test updating livemark siteURI to the value from the feed
- */
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-function runTest() {
-  const FEEDSPEC = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/sample_feed.atom";
-  const INITIALSITESPEC = "http://mochi.test:8888/";
-  const FEEDSITESPEC = "http://example.org/"; 
-
-  PlacesUtils.livemarks.addLivemark(
-    { title: "foo"
-    , parentGuid: PlacesUtils.bookmarks.toolbarGuid
-    , feedURI: NetUtil.newURI(FEEDSPEC)
-    , siteURI: NetUtil.newURI(INITIALSITESPEC)
-    })
-    .then(function (aLivemark) {
-      is(aLivemark.siteURI.spec, INITIALSITESPEC,
-         "Has correct initial livemark site URI");
-
-      waitForLivemarkLoad(aLivemark, function (aLivemark) {
-        is(aLivemark.siteURI.spec, FEEDSITESPEC,
-           "livemark site URI set to value in feed");
-
-        PlacesUtils.livemarks.removeLivemark(aLivemark).then(() => {
-          SimpleTest.finish();
-        });
-      });
-    }, function () {
-      is(true, false, "Should not fail adding a livemark");
-    }
-  );
-}
-
-function waitForLivemarkLoad(aLivemark, aCallback) {
-  // Don't need a real node here.
-  let node = {};
-  let resultObserver = {
-    nodeInserted: function() {},
-    nodeRemoved: function() {},
-    nodeAnnotationChanged: function() {},
-    nodeTitleChanged: function() {},
-    nodeHistoryDetailsChanged: function() {},
-    nodeMoved: function() {},
-    ontainerStateChanged: function () {},
-    sortingChanged: function() {},
-    batching: function() {},
-    invalidateContainer: function(node) {
-      isnot(aLivemark.status, Ci.mozILivemark.STATUS_FAILED,
-            "Loading livemark should success");
-      if (aLivemark.status == Ci.mozILivemark.STATUS_READY) {
-        aLivemark.unregisterForUpdates(node, resultObserver);
-        aCallback(aLivemark);
-      }
-    }
-  };
-  aLivemark.registerForUpdates(node, resultObserver);
-  aLivemark.reload();
-}
-
-]]>
-</script>
-
-</window>
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_341972b.xul
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Update Livemark SiteURI, null to start"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-/*
- Test updating livemark siteURI to the value from the feed, when it's null
- */
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-function runTest() {
-  const FEEDSPEC = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/sample_feed.atom";
-  const FEEDSITESPEC = "http://example.org/"; 
-
-  PlacesUtils.livemarks.addLivemark(
-    { title: "foo"
-    , parentGuid: PlacesUtils.bookmarks.toolbarGuid
-    , feedURI: NetUtil.newURI(FEEDSPEC)
-    })
-    .then(function (aLivemark) {
-      is(aLivemark.siteURI, null, "Has null livemark site URI");
-
-      waitForLivemarkLoad(aLivemark, function (aLivemark) {
-        is(aLivemark.siteURI.spec, FEEDSITESPEC,
-           "livemark site URI set to value in feed");
-
-        PlacesUtils.livemarks.removeLivemark(aLivemark).then(() => {
-          SimpleTest.finish();
-        });
-      });
-    }, function () {
-      is(true, false, "Should not fail adding a livemark");
-    }
-  );
-}
-
-function waitForLivemarkLoad(aLivemark, aCallback) {
-  // Don't need a real node here.
-  let node = {};
-  let resultObserver = {
-    nodeInserted: function() {},
-    nodeRemoved: function() {},
-    nodeAnnotationChanged: function() {},
-    nodeTitleChanged: function() {},
-    nodeHistoryDetailsChanged: function() {},
-    nodeMoved: function() {},
-    ontainerStateChanged: function () {},
-    sortingChanged: function() {},
-    batching: function() {},
-    invalidateContainer: function(node) {
-      isnot(aLivemark.status, Ci.mozILivemark.STATUS_FAILED,
-            "Loading livemark should success");
-      if (aLivemark.status == Ci.mozILivemark.STATUS_READY) {
-        aLivemark.unregisterForUpdates(node, resultObserver);
-        aCallback(aLivemark);
-      }
-    }
-  };
-  aLivemark.registerForUpdates(node, resultObserver);
-  aLivemark.reload();
-}
-
-]]>
-</script>
-
-</window>
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_342484.xul
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Add Bad Livemarks"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-/*
- Test loading feeds with items that aren't allowed
- */
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-function runTest() {
-  const FEEDSPEC = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/bad_links.atom";
-  const GOOD_URLS = ["http://example.org/first", "http://example.org/last"];
-
-  PlacesUtils.livemarks.addLivemark(
-    { title: "foo"
-    , parentGuid: PlacesUtils.bookmarks.toolbarGuid
-    , feedURI: NetUtil.newURI(FEEDSPEC)
-    , siteURI: NetUtil.newURI("http:/mochi.test/")
-    })
-    .then(function (aLivemark) {
-      waitForLivemarkLoad(aLivemark, function (aLivemark) {
-        let nodes = aLivemark.getNodesForContainer({});
-
-        is(nodes.length, 2, "Created the two good livemark items");
-        for (let i = 0; i < nodes.length; ++i) {
-          let node = nodes[i];
-          ok(GOOD_URLS.includes(node.uri), "livemark item created with bad uri " + node.uri);
-        }
-
-        PlacesUtils.livemarks.removeLivemark(aLivemark).then(() => {
-          SimpleTest.finish();
-        });
-      });
-    }, function () {
-      is(true, false, "Should not fail adding a livemark");
-    }
-  );
-}
-
-function waitForLivemarkLoad(aLivemark, aCallback) {
-  // Don't need a real node here.
-  let node = {};
-  let resultObserver = {
-    nodeInserted: function() {},
-    nodeRemoved: function() {},
-    nodeAnnotationChanged: function() {},
-    nodeTitleChanged: function() {},
-    nodeHistoryDetailsChanged: function() {},
-    nodeMoved: function() {},
-    ontainerStateChanged: function () {},
-    sortingChanged: function() {},
-    batching: function() {},
-    invalidateContainer: function(node) {
-      isnot(aLivemark.status, Ci.mozILivemark.STATUS_FAILED,
-            "Loading livemark should success");
-      if (aLivemark.status == Ci.mozILivemark.STATUS_READY) {
-        aLivemark.unregisterForUpdates(node, resultObserver);
-        aCallback(aLivemark);
-      }
-    }
-  };
-  aLivemark.registerForUpdates(node, resultObserver);
-  aLivemark.reload();
-}
-
-]]>
-</script>
-
-</window>
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_381357.xul
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Add Livemarks from RSS feed served as text/html"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-/*
- Test loading feeds with text/html 
- */
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-function runTest() {
-  const FEEDSPEC = "http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/rss_as_html.rss";
-
-  PlacesUtils.livemarks.addLivemark(
-    { title: "foo"
-    , parentGuid: PlacesUtils.bookmarks.toolbarGuid
-    , feedURI: NetUtil.newURI(FEEDSPEC)
-    , siteURI: NetUtil.newURI("http:/mochi.test/")
-    })
-    .then(function (aLivemark) {
-      waitForLivemarkLoad(aLivemark, function (aLivemark) {
-        let nodes = aLivemark.getNodesForContainer({});
-
-        is(nodes[0].title, "The First Title",
-           "livemark site URI set to value in feed");
-
-        PlacesUtils.livemarks.removeLivemark(aLivemark).then(() => {
-          SimpleTest.finish();
-        });
-      });
-    }, function () {
-      is(true, false, "Should not fail adding a livemark");
-      SimpleTest.finish();
-    }
-  );
-}
-
-function waitForLivemarkLoad(aLivemark, aCallback) {
-  // Don't need a real node here.
-  let node = {};
-  let resultObserver = {
-    nodeInserted: function() {},
-    nodeRemoved: function() {},
-    nodeAnnotationChanged: function() {},
-    nodeTitleChanged: function() {},
-    nodeHistoryDetailsChanged: function() {},
-    nodeMoved: function() {},
-    ontainerStateChanged: function () {},
-    sortingChanged: function() {},
-    batching: function() {},
-    invalidateContainer: function(node) {
-      isnot(aLivemark.status, Ci.mozILivemark.STATUS_FAILED,
-            "Loading livemark should success");
-      if (aLivemark.status == Ci.mozILivemark.STATUS_READY) {
-        aLivemark.unregisterForUpdates(node, resultObserver);
-        aCallback(aLivemark);
-      }
-    }
-  };
-  aLivemark.registerForUpdates(node, resultObserver);
-  aLivemark.reload();
-}
-
-]]>
-</script>
-
-</window>
deleted file mode 100644
--- a/toolkit/components/places/tests/chrome/test_reloadLivemarks.xul
+++ /dev/null
@@ -1,151 +0,0 @@
-<?xml version="1.0"?>
-<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
-<?xml-stylesheet
-  href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
-<window title="Reload Livemarks"
-  xmlns:html="http://www.w3.org/1999/xhtml"
-  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
-  onload="runTest()" onunload="cleanup()">
-  <script type="application/javascript"
-   src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
-
-  <body xmlns="http://www.w3.org/1999/xhtml" />
-
-<script type="application/javascript">
-<![CDATA[
-// Test that for concurrent reload of livemarks.
-
-SimpleTest.waitForExplicitFinish();
-
-ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
-ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
-ChromeUtils.import("resource://gre/modules/PlacesUtils.jsm");
-
-let gLivemarks = [
-  { id: -1,
-    title: "foo",
-    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
-    feedURI: NetUtil.newURI("http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/link-less-items.rss")
-  },
-  { id: -1,
-    title: "bar",
-    parentGuid: PlacesUtils.bookmarks.toolbarGuid,
-    feedURI: NetUtil.newURI("http://mochi.test:8888/tests/toolkit/components/places/tests/chrome/link-less-items-no-site-uri.rss")
-  },
-];
-
-function runTest()
-{
-  addLivemarks(function () {
-    reloadLivemarks(false, function () {
-      reloadLivemarks(true, function () {
-        removeLivemarks(SimpleTest.finish);
-      });
-    });
-    // Ensure this normal reload doesn't overwrite the forced one.
-    PlacesUtils.livemarks.reloadLivemarks();
-  });
-}
-
-function addLivemarks(aCallback) {
-  info("Adding livemarks");
-  let count = gLivemarks.length;
-  gLivemarks.forEach(function(aLivemarkData) {
-    PlacesUtils.livemarks.addLivemark(aLivemarkData)
-      .then(function (aLivemark) {
-        ok(aLivemark.feedURI.equals(aLivemarkData.feedURI), "Livemark added");
-        aLivemarkData.id = aLivemark.id;
-        if (--count == 0) {
-          aCallback();
-        }
-      },
-      function () {
-        is(true, false, "Should not fail adding a livemark.");
-        aCallback();
-      });
-  });
-}
-
-function reloadLivemarks(aForceUpdate, aCallback) {
-  info("Reloading livemarks with forceUpdate: " + aForceUpdate);
-  let count = gLivemarks.length;
-  gLivemarks.forEach(function(aLivemarkData) {
-    PlacesUtils.livemarks.getLivemark(aLivemarkData)
-      .then(aLivemark => {
-        ok(aLivemark.feedURI.equals(aLivemarkData.feedURI), "Livemark found");
-        aLivemarkData._observer = new resultObserver(aLivemark, function() {
-          if (++count == gLivemarks.length) {
-            aCallback();
-          }
-        });
-        if (--count == 0) {
-          PlacesUtils.livemarks.reloadLivemarks(aForceUpdate);
-        }
-      },
-      function() {
-        is(true, false, "Should not fail getting a livemark.");
-        aCallback();
-      }
-    );
-  });
-}
-
-function removeLivemarks(aCallback) {
-  info("Removing livemarks");
-  let count = gLivemarks.length;
-  gLivemarks.forEach(function(aLivemarkData) {
-    PlacesUtils.livemarks.removeLivemark(aLivemarkData).then(
-      function (aLivemark) {
-        if (--count == 0) {
-          aCallback();
-        }
-      },
-      function() {
-        is(true, false, "Should not fail adding a livemark.");
-        aCallback();
-      }
-    );
-  });
-}
-
-function resultObserver(aLivemark, aCallback) {
-  this._node = {};
-  this._livemark = aLivemark;
-  this._callback = aCallback;
-  this._livemark.registerForUpdates(this._node, this);
-}
-resultObserver.prototype = {
-  nodeInserted: function() {},
-  nodeRemoved: function() {},
-  nodeAnnotationChanged: function() {},
-  nodeTitleChanged: function() {},
-  nodeHistoryDetailsChanged: function() {},
-  nodeMoved: function() {},
-  ontainerStateChanged: function () {},
-  sortingChanged: function() {},
-  batching: function() {},
-  invalidateContainer: function(aContainer) {
-    // Wait for load finish.
-    if (this._livemark.status == Ci.mozILivemark.STATUS_LOADING)
-      return;
-
-    this._terminate();
-    this._callback();
-  },
-  _terminate: function () {
-    if (!this._terminated) {
-      this._livemark.unregisterForUpdates(this._node);
-      this._terminated = true;
-    }
-  }
-};
-
-function cleanup() {
-  gLivemarks.forEach(function(aLivemarkData) {
-    if (aLivemarkData._observer)
-      aLivemarkData._observer._terminate();
-  });
-}
-]]>
-</script>
-</window>
--- a/toolkit/components/places/tests/queries/head_queries.js
+++ b/toolkit/components/places/tests/queries/head_queries.js
@@ -122,25 +122,16 @@ async function task_populateDB(aArray) {
         await PlacesUtils.bookmarks.insert({
           parentGuid: qdata.parentGuid,
           type: PlacesUtils.bookmarks.TYPE_FOLDER,
           title: qdata.title,
           index: qdata.index,
         });
       }
 
-      if (qdata.isLivemark) {
-        await PlacesUtils.livemarks.addLivemark({ title: qdata.title,
-                                                  parentId: (await PlacesUtils.promiseItemId(qdata.parentGuid)),
-                                                  index: qdata.index,
-                                                  feedURI: uri(qdata.feedURI),
-                                                  siteURI: uri(qdata.uri),
-                                                });
-      }
-
       if (qdata.isBookmark) {
         let data = {
           parentGuid: qdata.parentGuid,
           index: qdata.index,
           title: qdata.title,
           url: qdata.uri,
         };
 
@@ -206,17 +197,16 @@ function queryData(obj) {
   this.removeAnnotation = !!obj.removeAnnotation;
   this.annoName = obj.annoName ? obj.annoName : "";
   this.annoVal = obj.annoVal ? obj.annoVal : "";
   this.isItemAnnotation = obj.isItemAnnotation ? obj.isItemAnnotation : false;
   this.itemId = obj.itemId ? obj.itemId : 0;
   this.annoMimeType = obj.annoMimeType ? obj.annoMimeType : "";
   this.isTag = obj.isTag ? obj.isTag : false;
   this.tagArray = obj.tagArray ? obj.tagArray : null;
-  this.isLivemark = obj.isLivemark ? obj.isLivemark : false;
   this.parentGuid = obj.parentGuid || PlacesUtils.bookmarks.unfiledGuid;
   this.feedURI = obj.feedURI ? obj.feedURI : "";
   this.index = obj.index ? obj.index : PlacesUtils.bookmarks.DEFAULT_INDEX;
   this.isFolder = obj.isFolder ? obj.isFolder : false;
   this.contractId = obj.contractId ? obj.contractId : "";
   this.lastModified = obj.lastModified ? obj.lastModified : null;
   this.dateAdded = obj.dateAdded ? obj.dateAdded : null;
   this.keyword = obj.keyword ? obj.keyword : "";
deleted file mode 100644
--- a/toolkit/components/places/tests/unit/livemark.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
-  <title>Livemark Feed</title>
-  <link href="https://example.com/"/>
-  <updated>2016-08-09T19:51:45.147Z</updated>
-  <author>
-    <name>John Doe</name>
-  </author>
-  <id>urn:uuid:e7947414-6ee0-4009-ae75-8b0ad3c6894b</id>
-  <entry>
-    <title>Some awesome article</title>
-    <link href="https://example.com/some-article"/>
-    <id>urn:uuid:d72ce019-0a56-4a0b-ac03-f66117d78141</id>
-    <updated>2016-08-09T19:57:22.178Z</updated>
-    <summary>My great article summary.</summary>
-  </entry>
-</feed>
--- a/toolkit/components/places/tests/unit/test_384370.js
+++ b/toolkit/components/places/tests/unit/test_384370.js
@@ -110,41 +110,33 @@ async function testMenuBookmarks() {
 
   folderNode.containerOpen = false;
   root.containerOpen = false;
 }
 
 async function testToolbarBookmarks() {
   let root = PlacesUtils.getFolderContents(PlacesUtils.bookmarks.toolbarGuid).root;
 
-  // child count (add 3 for pre-existing items)
-  Assert.equal(root.childCount, bookmarkData.length + 3);
+  // child count (add 2 for pre-existing items, one of the feeds is skipped
+  // because it doesn't have href)
+  Assert.equal(root.childCount, bookmarkData.length + 2);
 
-  let livemarkNode = root.getChild(1);
-  Assert.equal("Latest Headlines", livemarkNode.title);
-
-  let livemark = await PlacesUtils.livemarks.getLivemark({ id: livemarkNode.itemId });
+  // Livemarks are no more supported but may still exist in old html files.
+  let legacyLivemarkNode = root.getChild(1);
+  Assert.equal("Latest Headlines", legacyLivemarkNode.title);
   Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
-               livemark.siteURI.spec);
-  Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
-               livemark.feedURI.spec);
-
-  livemarkNode = root.getChild(2);
-  Assert.equal("Latest Headlines No Site", livemarkNode.title);
-
-  livemark = await PlacesUtils.livemarks.getLivemark({ id: livemarkNode.itemId });
-  Assert.equal(null, livemark.siteURI);
-  Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
-               livemark.feedURI.spec);
+               legacyLivemarkNode.uri);
+  Assert.equal(legacyLivemarkNode.type,
+               Ci.nsINavHistoryResultNode.RESULT_TYPE_URI);
 
   // test added bookmark data
-  let bookmarkNode = root.getChild(3);
+  let bookmarkNode = root.getChild(2);
   Assert.equal(bookmarkNode.uri, bookmarkData[0].uri.spec);
   Assert.equal(bookmarkNode.title, bookmarkData[0].title);
-  bookmarkNode = root.getChild(4);
+  bookmarkNode = root.getChild(3);
   Assert.equal(bookmarkNode.uri, bookmarkData[1].uri.spec);
   Assert.equal(bookmarkNode.title, bookmarkData[1].title);
 
   root.containerOpen = false;
 }
 
 function testUnfiledBookmarks() {
   let root = PlacesUtils.getFolderContents(PlacesUtils.bookmarks.unfiledGuid).root;
--- a/toolkit/components/places/tests/unit/test_async_transactions.js
+++ b/toolkit/components/places/tests/unit/test_async_transactions.js
@@ -282,26 +282,16 @@ function createTestFolderInfo(title = "T
                               children = undefined) {
   let info = { parentGuid, title };
   if (children) {
     info.children = children;
   }
   return info;
 }
 
-function isLivemarkTree(aTree) {
-  return !!aTree.annos &&
-         aTree.annos.some( a => a.name == PlacesUtils.LMANNO_FEEDURI );
-}
-
-async function ensureLivemarkCreatedByAddLivemark(aLivemarkGuid) {
-  // This throws otherwise.
-  await PlacesUtils.livemarks.getLivemark({ guid: aLivemarkGuid });
-}
-
 function removeAllDatesInTree(tree) {
   if ("lastModified" in tree) {
     delete tree.lastModified;
   }
   if ("dateAdded" in tree) {
     delete tree.dateAdded;
   }
 
@@ -329,18 +319,16 @@ async function ensureEqualBookmarksTrees
     if (aIgnoreAllDates) {
       removeAllDatesInTree(aOriginal);
       removeAllDatesInTree(aNew);
     } else if (!aOriginal.lastModified) {
       // Ignore lastModified for newly created items, for performance reasons.
       aNew.lastModified = aOriginal.lastModified;
     }
     Assert.deepEqual(aOriginal, aNew);
-    if (isLivemarkTree(aNew))
-      await ensureLivemarkCreatedByAddLivemark(aNew.guid);
     return;
   }
 
   for (let property of Object.keys(aOriginal)) {
     if (property == "children") {
       Assert.equal(aOriginal.children.length, aNew.children.length);
       for (let i = 0; i < aOriginal.children.length; i++) {
         await ensureEqualBookmarksTrees(aOriginal.children[i],
@@ -361,19 +349,16 @@ async function ensureEqualBookmarksTrees
         Assert.ok(!aNew.lastModified);
       else
         Assert.ok(is_time_ordered(aOriginal.lastModified, aNew.lastModified));
     } else if (aCheckParentAndPosition ||
              (property != "parentGuid" && property != "index")) {
       Assert.deepEqual(aOriginal[property], aNew[property]);
     }
   }
-
-  if (isLivemarkTree(aNew))
-    await ensureLivemarkCreatedByAddLivemark(aNew.guid);
 }
 
 async function ensureBookmarksTreeRestoredCorrectly(...aOriginalBookmarksTrees) {
   for (let originalTree of aOriginalBookmarksTrees) {
     let restoredTree =
       await PlacesUtils.promiseBookmarksTree(originalTree.guid);
     await ensureEqualBookmarksTrees(originalTree, restoredTree);
   }
@@ -1110,60 +1095,16 @@ add_task(async function test_creating_an
   observer.reset();
   await PT.undo();
   ensureUndoState(undoEntries, 1);
   ensureItemsRemoved(folder_info, separator_info);
   await PT.clearTransactionsHistory();
   ensureUndoState();
 });
 
-add_task(async function test_add_and_remove_livemark() {
-  let createLivemarkTxn = PT.NewLivemark(
-    { feedUrl: "http://test.remove.livemark",
-      parentGuid: PlacesUtils.bookmarks.unfiledGuid,
-      title: "Test Remove Livemark" });
-  let guid = await createLivemarkTxn.transact();
-  let originalInfo = await PlacesUtils.promiseBookmarksTree(guid);
-  Assert.ok(originalInfo);
-  await ensureLivemarkCreatedByAddLivemark(guid);
-
-  let removeTxn = PT.Remove(guid);
-  await removeTxn.transact();
-  await ensureNonExistent(guid);
-
-  async function undo() {
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 0);
-    await PT.undo();
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 1);
-    await ensureBookmarksTreeRestoredCorrectly(originalInfo);
-    await PT.undo();
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 2);
-    await ensureNonExistent(guid);
-  }
-  async function redo() {
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 2);
-    await PT.redo();
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 1);
-    await ensureBookmarksTreeRestoredCorrectly(originalInfo);
-    await PT.redo();
-    ensureUndoState([[removeTxn], [createLivemarkTxn]], 0);
-    await ensureNonExistent(guid);
-  }
-
-  await undo();
-  await redo();
-  await undo();
-  await redo();
-
-  // Cleanup
-  await undo();
-  observer.reset();
-  await PT.clearTransactionsHistory();
-});
-
 add_task(async function test_edit_title() {
   let bm_info = {
     parentGuid: PlacesUtils.bookmarks.unfiledGuid,
     url: "http://test_create_item.com",
     title: "Original Title",
   };
 
   function ensureTitleChange(aCurrentTitle) {
@@ -1599,65 +1540,16 @@ add_task(async function test_sort_folder
   // Cleanup
   observer.reset();
   await PT.undo();
   ensureOrder(originalOrder);
   await PT.undo();
   ensureItemsRemoved(...originalOrder, folder_info);
 });
 
-add_task(async function test_livemark_txns() {
-  let livemark_info =
-    { feedUrl: "http://test.feed.uri/",
-      parentGuid: PlacesUtils.bookmarks.unfiledGuid,
-      title: "Test Livemark" };
-  function ensureLivemarkAdded() {
-    ensureItemsAdded({ guid:       livemark_info.guid,
-                       title:      livemark_info.title,
-                       parentGuid: livemark_info.parentGuid,
-                       itemType:   PlacesUtils.bookmarks.TYPE_FOLDER });
-    let annos = [{ name:  PlacesUtils.LMANNO_FEEDURI,
-                   value: livemark_info.feedUrl }];
-    if ("siteUrl" in livemark_info) {
-      annos.push({ name: PlacesUtils.LMANNO_SITEURI,
-                   value: livemark_info.siteUrl });
-    }
-    ensureAnnotationsSet(livemark_info.guid, annos);
-  }
-  function ensureLivemarkRemoved() {
-    ensureItemsRemoved({ guid:       livemark_info.guid,
-                         parentGuid: livemark_info.parentGuid });
-  }
-
-  async function _testDoUndoRedoUndo() {
-    observer.reset();
-    livemark_info.guid = await PT.NewLivemark(livemark_info).transact();
-    ensureLivemarkAdded();
-
-    observer.reset();
-    await PT.undo();
-    ensureLivemarkRemoved();
-
-    observer.reset();
-    await PT.redo();
-    ensureLivemarkAdded();
-
-    await PT.undo();
-    ensureLivemarkRemoved();
-  }
-
-  await _testDoUndoRedoUndo();
-  livemark_info.siteUrl = "http://feed.site.uri/";
-  await _testDoUndoRedoUndo();
-
-  // Cleanup
-  observer.reset();
-  await PT.clearTransactionsHistory();
-});
-
 add_task(async function test_copy() {
   async function duplicate_and_test(aOriginalGuid) {
     let txn = PT.Copy({
       guid: aOriginalGuid, newParentGuid: PlacesUtils.bookmarks.unfiledGuid,
     });
     let duplicateGuid = await txn.transact();
     let originalInfo = await PlacesUtils.promiseBookmarksTree(aOriginalGuid);
     let duplicateInfo = await PlacesUtils.promiseBookmarksTree(duplicateGuid);
@@ -1697,22 +1589,19 @@ add_task(async function test_copy() {
   // Test duplicating leafs (bookmark, separator, empty folder)
   PT.NewBookmark({ url: "http://test.item.duplicate",
                    parentGuid: PlacesUtils.bookmarks.unfiledGuid,
                    annos: [{ name: "Anno", value: "AnnoValue"}] });
   let sepTxn = PT.NewSeparator({
     parentGuid: PlacesUtils.bookmarks.unfiledGuid,
     index: 1,
   });
-  let livemarkTxn = PT.NewLivemark(
-    { feedUrl: "http://test.feed.uri",
-      parentGuid: PlacesUtils.bookmarks.unfiledGuid,
-      title: "Test Livemark", index: 1 });
+
   let emptyFolderTxn = PT.NewFolder(createTestFolderInfo());
-  for (let txn of [livemarkTxn, sepTxn, emptyFolderTxn]) {
+  for (let txn of [sepTxn, emptyFolderTxn]) {
     let guid = await txn.transact();
     await duplicate_and_test(guid);
   }
 
   // Test duplicating a folder having some contents.
   let filledFolderGuid = await PT.batch(async function() {
     let folderGuid = await PT.NewFolder(createTestFolderInfo()).transact();
     let nestedFolderGuid =
--- a/toolkit/components/places/tests/unit/test_bookmarks_html.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_html.js
@@ -49,18 +49,20 @@ var test_bookmarks = {
     { title: "Getting Started",
       url: "http://en-us.www.mozilla.com/en-US/firefox/central/",
       icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==",
     },
     { title: "Latest Headlines",
       url: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
       feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
     },
+    // This will be ignored, because it has no url.
     { title: "Latest Headlines No Site",
       feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
+      ignore: true,
     },
   ],
   unfiled: [
     { title: "Example.tld",
       url: "http://example.tld/",
     },
   ],
 };
@@ -255,30 +257,28 @@ add_task(async function test_import_onto
 });
 
 async function testImportedBookmarks() {
   for (let group in test_bookmarks) {
     info("[testImportedBookmarks()] Checking group '" + group + "'");
 
     let root = PlacesUtils.getFolderContents(PlacesUtils.bookmarks[`${group}Guid`]).root;
 
-    let items = test_bookmarks[group];
+    let items = test_bookmarks[group].filter(b => !b.ignore);
     Assert.equal(root.childCount, items.length);
 
     for (let key in items) {
       await checkItem(items[key], root.getChild(key));
     }
 
     root.containerOpen = false;
   }
 }
 
 function checkItem(aExpected, aNode) {
-  let id = aNode.itemId;
-
   return (async function() {
     let bookmark = await PlacesUtils.bookmarks.fetch(aNode.bookmarkGuid);
 
     for (let prop in aExpected) {
       switch (prop) {
         case "type":
           Assert.equal(aNode.type, aExpected.type);
           break;
@@ -289,18 +289,17 @@ function checkItem(aExpected, aNode) {
           Assert.equal(PlacesUtils.toPRTime(bookmark.dateAdded),
                        aExpected.dateAdded);
           break;
         case "lastModified":
           Assert.equal(PlacesUtils.toPRTime(bookmark.lastModified),
                        aExpected.lastModified);
           break;
         case "url":
-          if (!("feedUrl" in aExpected))
-            Assert.equal(aNode.uri, aExpected.url);
+          Assert.equal(aNode.uri, aExpected.url);
           break;
         case "icon":
           let {data} = await getFaviconDataForPage(aExpected.url);
           let base64Icon = "data:image/png;base64," +
                            base64EncodeString(String.fromCharCode.apply(String, data));
           Assert.ok(base64Icon == aExpected.icon);
           break;
         case "keyword": {
@@ -313,21 +312,17 @@ function checkItem(aExpected, aNode) {
           Assert.equal(entry.postData, aExpected.postData);
           break;
         }
         case "charset":
           let pageInfo = await PlacesUtils.history.fetch(aNode.uri, {includeAnnotations: true});
           Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), aExpected.charset);
           break;
         case "feedUrl":
-          let livemark = await PlacesUtils.livemarks.getLivemark({ id });
-          if (aExpected.url) {
-            Assert.equal(livemark.siteURI.spec, aExpected.url);
-          }
-          Assert.equal(livemark.feedURI.spec, aExpected.feedUrl);
+          // No more supported.
           break;
         case "children":
           let folder = aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
           Assert.equal(folder.hasChildren, aExpected.children.length > 0);
           folder.containerOpen = true;
           Assert.equal(folder.childCount, aExpected.children.length);
 
           for (let index = 0; index < aExpected.children.length; index++) {
--- a/toolkit/components/places/tests/unit/test_bookmarks_html_corrupt.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_html_corrupt.js
@@ -84,33 +84,16 @@ var database_check = async function() {
   // clean up
   folderNode.containerOpen = false;
   root.containerOpen = false;
 
   // BOOKMARKS TOOLBAR
   root = PlacesUtils.getFolderContents(PlacesUtils.bookmarks.toolbarGuid).root;
   Assert.equal(root.childCount, 3);
 
-  // For now some promises are resolved later, so we can't guarantee an order.
-  let foundLivemark = false;
-  for (let i = 0; i < root.childCount; ++i) {
-    let node = root.getChild(i);
-    if (node.title == "Latest Headlines") {
-      foundLivemark = true;
-      Assert.equal("Latest Headlines", node.title);
-
-      let livemark = await PlacesUtils.livemarks.getLivemark({ guid: node.bookmarkGuid });
-      Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
-                   livemark.siteURI.spec);
-      Assert.equal("http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
-                   livemark.feedURI.spec);
-    }
-  }
-  Assert.ok(foundLivemark);
-
   // cleanup
   root.containerOpen = false;
 
   // UNFILED BOOKMARKS
   root = PlacesUtils.getFolderContents(PlacesUtils.bookmarks.unfiledGuid).root;
   Assert.equal(root.childCount, 1);
   root.containerOpen = false;
 
--- a/toolkit/components/places/tests/unit/test_bookmarks_json.js
+++ b/toolkit/components/places/tests/unit/test_bookmarks_json.js
@@ -60,18 +60,21 @@ var test_bookmarks = {
   toolbar: [
     { guid: "OCyeUO5uu9FB",
       title: "Getting Started",
       url: "http://en-us.www.mozilla.com/en-US/firefox/central/",
       icon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==",
     },
     { guid: "OCyeUO5uu9FR",
       title: "Latest Headlines",
-      url: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/livebookmarks/",
-      feedUrl: "http://en-us.fxfeeds.mozilla.com/en-US/firefox/headlines.xml",
+      // This used to be a livemark, but we don't import them anymore, instead
+      // it will be imported as an empty folder, because the json format stores
+      // it like that: an empty folder with a couple annotations. Since
+      // annotations will go away, there won't be a clean way to import it as a
+      // bookmark instead.
       // Note: date gets truncated to milliseconds, whereas the value in bookmarks.json
       // has full microseconds.
       dateAdded: 1361551979451000,
       lastModified: 1361551979457000,
     },
   ],
   unfiled: [
     { guid: "OCyeUO5uu9FW",
@@ -165,17 +168,16 @@ async function testImportedBookmarks() {
       await checkItem(items[key], root.getChild(key));
     }
 
     root.containerOpen = false;
   }
 }
 
 async function checkItem(aExpected, aNode) {
-  let id = aNode.itemId;
   let bookmark = await PlacesUtils.bookmarks.fetch(aNode.bookmarkGuid);
 
   for (let prop in aExpected) {
     switch (prop) {
       case "type":
         Assert.equal(aNode.type, aExpected.type);
         break;
       case "title":
@@ -185,18 +187,17 @@ async function checkItem(aExpected, aNod
         Assert.equal(PlacesUtils.toPRTime(bookmark.dateAdded),
                      aExpected.dateAdded);
         break;
       case "lastModified":
         Assert.equal(PlacesUtils.toPRTime(bookmark.lastModified),
                      aExpected.lastModified);
         break;
       case "url":
-        if (!("feedUrl" in aExpected))
-          Assert.equal(aNode.uri, aExpected.url);
+        Assert.equal(aNode.uri, aExpected.url);
         break;
       case "icon":
         let {data} = await getFaviconDataForPage(aExpected.url);
         let base64Icon = "data:image/png;base64," +
                          base64EncodeString(String.fromCharCode.apply(String, data));
         Assert.equal(base64Icon, aExpected.icon);
         break;
       case "keyword": {
@@ -211,21 +212,16 @@ async function checkItem(aExpected, aNod
         let entry = await PlacesUtils.keywords.fetch({ url: aNode.uri });
         Assert.equal(entry.postData, aExpected.postData);
         break;
       }
       case "charset":
         let pageInfo = await PlacesUtils.history.fetch(aNode.uri, {includeAnnotations: true});
         Assert.equal(pageInfo.annotations.get(PlacesUtils.CHARSET_ANNO), aExpected.charset);
         break;
-      case "feedUrl":
-        let livemark = await PlacesUtils.livemarks.getLivemark({ id });
-        Assert.equal(livemark.siteURI.spec, aExpected.url);
-        Assert.equal(livemark.feedURI.spec, aExpected.feedUrl);
-        break;
       case "children":
         let folder = aNode.QueryInterface(Ci.nsINavHistoryContainerResultNode);
         Assert.equal(folder.hasChildren, aExpected.children.length > 0);
         folder.containerOpen = true;
         Assert.equal(folder.childCount, aExpected.children.length);
 
         for (let index = 0; index < aExpected.children.length; index++) {
           await checkItem(aExpected.children[index], folder.getChild(index));
--- a/toolkit/components/places/tests/unit/xpcshell.ini
+++ b/toolkit/components/places/tests/unit/xpcshell.ini
@@ -2,17 +2,16 @@
 head = head_bookmarks.js
 firefox-appdir = browser
 support-files =
   bookmarks.corrupt.html
   bookmarks.json
   bookmarks_corrupt.json
   bookmarks.preplaces.html
   bookmarks_html_singleframe.html
-  livemark.xml
   mobile_bookmarks_folder_import.json
   mobile_bookmarks_folder_merge.json
   mobile_bookmarks_multiple_folders.json
   mobile_bookmarks_root_import.json
   mobile_bookmarks_root_merge.json
   places.sparse.sqlite
 
 [test_000_frecency.js]
@@ -75,17 +74,16 @@ skip-if = appname == "thunderbird"
 [test_keywords.js]
 [test_lastModified.js]
 [test_markpageas.js]
 [test_metadata.js]
 [test_missing_builtin_folders.js]
 support-files = missingBuiltIn.sqlite
 [test_missing_root_folder.js]
 support-files = noRoot.sqlite
-[test_mozIAsyncLivemarks.js]
 [test_multi_word_tags.js]
 [test_nsINavHistoryViewer.js]
 [test_null_interfaces.js]
 [test_onItemChanged_tags.js]
 [test_origins.js]
 [test_origins_parsing.js]
 [test_pageGuid_bookmarkGuid.js]
 [test_frecency_observers.js]