Bug 1250203 - Re-populate recent bookmarks when a bookmark has been deleted. r=mak
☠☠ backed out by 355e9b83a662 ☠ ☠
authorDão Gottwald <dao@mozilla.com>
Fri, 15 Apr 2016 16:50:20 +0200
changeset 317221 fec92924befbea7a0ee52c4cedd531a67b61f2fb
parent 317220 0260dd297a25b97b11dfa208c3d556cb7b62542c
child 317222 52e570214af308e604b413645136f340ad412711
push id9480
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 17:12:58 +0000
treeherdermozilla-aurora@0d6a91c76a9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs1250203
milestone48.0a1
Bug 1250203 - Re-populate recent bookmarks when a bookmark has been deleted. r=mak
browser/base/content/browser-places.js
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -1358,60 +1358,90 @@ var BookmarkingUI = {
         entry: "subviewbutton",
         footer: "panel-subview-footer"
       },
       insertionPoint: ".panel-subview-footer"
     });
   },
 
   _updateRecentBookmarks: function(aHeaderItem, extraCSSClass = "") {
-    const kMaxResults = 5;
+    let repopulate = function () {
+      const kMaxResults = 5;
+
+      let options = PlacesUtils.history.getNewQueryOptions();
+      options.excludeQueries = true;
+      options.queryType = options.QUERY_TYPE_BOOKMARKS;
+      options.sortingMode = options.SORT_BY_DATEADDED_DESCENDING;
+      options.maxResults = kMaxResults;
+      let query = PlacesUtils.history.getNewQuery();
 
-    let options = PlacesUtils.history.getNewQueryOptions();
-    options.excludeQueries = true;
-    options.queryType = options.QUERY_TYPE_BOOKMARKS;
-    options.sortingMode = options.SORT_BY_DATEADDED_DESCENDING;
-    options.maxResults = kMaxResults;
-    let query = PlacesUtils.history.getNewQuery();
+      while (aHeaderItem.nextSibling &&
+             aHeaderItem.nextSibling.localName == "menuitem") {
+        aHeaderItem.nextSibling.remove();
+      }
+
+      let onItemCommand = function (aEvent) {
+        let item = aEvent.target;
+        openUILink(item.getAttribute("targetURI"), aEvent);
+        CustomizableUI.hidePanelForNode(item);
+      };
 
-    while (aHeaderItem.nextSibling &&
-           aHeaderItem.nextSibling.localName == "menuitem") {
-      aHeaderItem.nextSibling.remove();
-    }
+      let fragment = document.createDocumentFragment();
+      let root = PlacesUtils.history.executeQuery(query, options).root;
+      root.containerOpen = true;
+      for (let i = 0; i < root.childCount; i++) {
+        let node = root.getChild(i);
+        let uri = node.uri;
+        let title = node.title;
+        let icon = node.icon;
 
-    let onItemCommand = function (aEvent) {
-      let item = aEvent.target;
-      openUILink(item.getAttribute("targetURI"), aEvent);
-      CustomizableUI.hidePanelForNode(item);
+        let item =
+          document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
+                                   "menuitem");
+        item.setAttribute("label", title || uri);
+        item.setAttribute("targetURI", uri);
+        item.setAttribute("class", "menuitem-iconic menuitem-with-favicon bookmark-item " +
+                                   extraCSSClass);
+        item.addEventListener("command", onItemCommand);
+        if (icon) {
+          item.setAttribute("image", icon);
+        }
+        fragment.appendChild(item);
+      }
+      root.containerOpen = false;
+      aHeaderItem.parentNode.insertBefore(fragment, aHeaderItem.nextSibling);
     };
 
-    let fragment = document.createDocumentFragment();
-    let root = PlacesUtils.history.executeQuery(query, options).root;
-    root.containerOpen = true;
-    for (let i = 0; i < root.childCount; i++) {
-      let node = root.getChild(i);
-      let uri = node.uri;
-      let title = node.title;
-      let icon = node.icon;
+    repopulate();
 
-      let item =
-        document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
-                                 "menuitem");
-      item.setAttribute("label", title || uri);
-      item.setAttribute("targetURI", uri);
-      item.setAttribute("class", "menuitem-iconic menuitem-with-favicon bookmark-item " +
-                                 extraCSSClass);
-      item.addEventListener("command", onItemCommand);
-      if (icon) {
-        item.setAttribute("image", icon);
+    // Update the menu when a bookmark is being removed.
+    // The native menubar on Mac doesn't support live update, so this won't
+    // work there.
+    let observer = {
+      onItemAdded() {},
+      onBeginUpdateBatch() {},
+      onEndUpdateBatch() {},
+      onItemRemoved() {
+        repopulate();
+      },
+      onItemChanged() {},
+      onItemVisited() {},
+      onItemMoved() {}
+    };
+    PlacesUtils.bookmarks.addObserver(observer, false);
+
+    let popup = aHeaderItem.parentNode;
+    let removeObserver = function (event) {
+      if (event && event.target != popup) {
+        return;
       }
-      fragment.appendChild(item);
-    }
-    root.containerOpen = false;
-    aHeaderItem.parentNode.insertBefore(fragment, aHeaderItem.nextSibling);
+      PlacesUtils.bookmarks.removeObserver(observer);
+      popup.removeEventListener("popuphidden", removeObserver);
+    };
+    popup.addEventListener("popuphidden", removeObserver);
   },
 
   /**
    * Handles star styling based on page proxy state changes.
    */
   onPageProxyStateChanged: function BUI_onPageProxyStateChanged(aState) {
     if (!this._shouldUpdateStarState() || !this.star) {
       return;