Bug 980130 - [Australis] bookmarks button breaks after reset in Australis customize mode, r=jaws, a=sledru.
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Tue, 11 Mar 2014 20:12:49 -0400
changeset 183273 7040d27132bc2bfe279a93f789861e4265d2fe07
parent 183272 45cbc102a4145ea2c52b685938d42d35ff2049aa
child 183274 0d08a9e56086fbd731af92db1b8f1adc63659e44
push id3343
push userffxbld
push dateMon, 17 Mar 2014 21:55:32 +0000
treeherdermozilla-beta@2f7d3415f79f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjaws, sledru
bugs980130
milestone29.0a2
Bug 980130 - [Australis] bookmarks button breaks after reset in Australis customize mode, r=jaws, a=sledru.
browser/base/content/browser-places.js
browser/components/customizableui/src/CustomizableUI.jsm
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -965,34 +965,35 @@ let PlacesToolbarHelper = {
 ////////////////////////////////////////////////////////////////////////////////
 //// BookmarkingUI
 
 /**
  * Handles the bookmarks menu-button in the toolbar.
  */
 
 let BookmarkingUI = {
+  BOOKMARK_BUTTON_ID: "bookmarks-menu-button",
   get button() {
     delete this.button;
-    let widgetGroup = CustomizableUI.getWidget("bookmarks-menu-button");
+    let widgetGroup = CustomizableUI.getWidget(this.BOOKMARK_BUTTON_ID);
     return this.button = widgetGroup.forWindow(window).node;
   },
 
   /* Can't make this a self-deleting getter because it's anonymous content
    * and might lose/regain bindings at some point. */
   get star() {
     return document.getAnonymousElementByAttribute(this.button, "anonid",
                                                    "button");
   },
 
   get anchor() {
     if (!this._shouldUpdateStarState()) {
       return null;
     }
-    let widget = CustomizableUI.getWidget("bookmarks-menu-button")
+    let widget = CustomizableUI.getWidget(this.BOOKMARK_BUTTON_ID)
                                .forWindow(window);
     if (widget.overflowed)
       return widget.anchor;
 
     let star = this.star;
     return star ? document.getAnonymousElementByAttribute(star, "class",
                                                           "toolbarbutton-icon")
                 : null;
@@ -1066,17 +1067,17 @@ let BookmarkingUI = {
     // decides to open the popup even though the dropmarker is invisible.
     if (this._currentAreaType == CustomizableUI.TYPE_MENU_PANEL) {
       this._showSubview();
       event.preventDefault();
       event.stopPropagation();
       return;
     }
 
-    let widget = CustomizableUI.getWidget("bookmarks-menu-button")
+    let widget = CustomizableUI.getWidget(this.BOOKMARK_BUTTON_ID)
                                .forWindow(window);
     if (widget.overflowed) {
       // Don't open a popup in the overflow popup, rather just open the Library.
       event.preventDefault();
       widget.node.removeAttribute("closemenu");
       PlacesCommandHook.showPlacesOrganizer("BookmarksMenu");
       return;
     }
@@ -1128,17 +1129,17 @@ let BookmarkingUI = {
     else {
       this.star.removeAttribute("disabled");
       this._updateStar();
     }
     this._updateToolbarStyle();
   },
 
   _updateCustomizationState: function BUI__updateCustomizationState() {
-    let placement = CustomizableUI.getPlacementOfWidget("bookmarks-menu-button");
+    let placement = CustomizableUI.getPlacementOfWidget(this.BOOKMARK_BUTTON_ID);
     this._currentAreaType = placement && CustomizableUI.getAreaType(placement.area);
   },
 
   _updateToolbarStyle: function BUI__updateToolbarStyle() {
     let onPersonalToolbar = false;
     if (this._currentAreaType == CustomizableUI.TYPE_TOOLBAR) {
       let personalToolbar = document.getElementById("PersonalToolbar");
       onPersonalToolbar = this.button.parentNode == personalToolbar ||
@@ -1162,48 +1163,55 @@ let BookmarkingUI = {
   onCustomizeStart: function BUI_customizeStart(aWindow) {
     if (aWindow == window) {
       this._uninitView();
       this._isCustomizing = true;
     }
   },
 
   onWidgetAdded: function BUI_widgetAdded(aWidgetId) {
-    if (aWidgetId != "bookmarks-menu-button") {
-      return;
+    if (aWidgetId == this.BOOKMARK_BUTTON_ID) {
+      this._onWidgetWasMoved();
+    }
+  },
+
+  onWidgetRemoved: function BUI_widgetRemoved(aWidgetId) {
+    if (aWidgetId == this.BOOKMARK_BUTTON_ID) {
+      this._onWidgetWasMoved();
     }
+  },
 
+  onWidgetReset: function BUI_widgetReset(aNode, aContainer) {
+    if (aNode == this.button) {
+      this._onWidgetWasMoved();
+    }
+  },
+
+  onWidgetUndoMove: function BUI_undoWidgetUndoMove(aNode, aContainer) {
+    if (aNode == this.button) {
+      this._onWidgetWasMoved();
+    }
+  },
+
+  _onWidgetWasMoved: function BUI_widgetWasMoved() {
     let usedToUpdateStarState = this._shouldUpdateStarState();
     this._updateCustomizationState();
     if (!usedToUpdateStarState && this._shouldUpdateStarState()) {
       this.updateStarState();
     } else if (usedToUpdateStarState && !this._shouldUpdateStarState()) {
       this._updateStar();
     }
     // If we're moved outside of customize mode, we need to uninit
     // our view so it gets reconstructed.
     if (!this._isCustomizing) {
       this._uninitView();
     }
     this._updateToolbarStyle();
   },
 
-  onWidgetRemoved: function BUI_widgetRemoved(aWidgetId) {
-    if (aWidgetId != "bookmarks-menu-button") {
-      return;
-    }
-    // If we're moved outside of customize mode, we need to uninit
-    // our view so it gets reconstructed.
-    if (!this._isCustomizing) {
-      this._uninitView();
-    }
-    this._updateCustomizationState();
-    this._updateToolbarStyle();
-  },
-
   onCustomizeEnd: function BUI_customizeEnd(aWindow) {
     if (aWindow == window) {
       this._isCustomizing = false;
       this.onToolbarVisibilityChange();
       this._updateToolbarStyle();
     }
   },
 
@@ -1356,17 +1364,17 @@ let BookmarkingUI = {
       this.notifier.style.transform = '';
     }, 1000);
   },
 
   _showSubview: function() {
     let view = document.getElementById("PanelUI-bookmarks");
     view.addEventListener("ViewShowing", this);
     view.addEventListener("ViewHiding", this);
-    let anchor = document.getElementById("bookmarks-menu-button");
+    let anchor = document.getElementById(this.BOOKMARK_BUTTON_ID);
     anchor.setAttribute("closemenu", "none");
     PanelUI.showSubView("PanelUI-bookmarks", anchor,
                         CustomizableUI.AREA_PANEL);
   },
 
   onCommand: function BUI_onCommand(aEvent) {
     if (aEvent.target != aEvent.currentTarget) {
       return;
@@ -1374,17 +1382,17 @@ let BookmarkingUI = {
 
     // Handle special case when the button is in the panel.
     let isBookmarked = this._itemIds.length > 0;
 
     if (this._currentAreaType == CustomizableUI.TYPE_MENU_PANEL) {
       this._showSubview();
       return;
     }
-    let widget = CustomizableUI.getWidget("bookmarks-menu-button")
+    let widget = CustomizableUI.getWidget(this.BOOKMARK_BUTTON_ID)
                                .forWindow(window);
     if (widget.overflowed) {
       // Allow to close the panel if the page is already bookmarked, cause
       // we are going to open the edit bookmark panel.
       if (isBookmarked)
         widget.node.removeAttribute("closemenu");
       else
         widget.node.setAttribute("closemenu", "none");
@@ -1512,33 +1520,33 @@ let BookmarkingUI = {
   },
   get _starButtonOverflowedStarredLabel() {
     delete this._starButtonOverflowedStarredLabel;
     return this._starButtonOverflowedStarredLabel =
       gNavigatorBundle.getString("starButtonOverflowedStarred.label");
   },
   onWidgetOverflow: function(aNode, aContainer) {
     let win = aNode.ownerDocument.defaultView;
-    if (aNode.id != "bookmarks-menu-button" || win != window)
+    if (aNode.id != this.BOOKMARK_BUTTON_ID || win != window)
       return;
 
     let currentLabel = aNode.getAttribute("label");
     if (!this._starButtonLabel)
       this._starButtonLabel = currentLabel;
 
     if (currentLabel == this._starButtonLabel) {
       let desiredLabel = this._itemIds.length > 0 ? this._starButtonOverflowedStarredLabel
                                                  : this._starButtonOverflowedLabel;
       aNode.setAttribute("label", desiredLabel);
     }
   },
 
   onWidgetUnderflow: function(aNode, aContainer) {
     let win = aNode.ownerDocument.defaultView;
-    if (aNode.id != "bookmarks-menu-button" || win != window)
+    if (aNode.id != this.BOOKMARK_BUTTON_ID || win != window)
       return;
 
     // The view gets broken by being removed and reinserted. Uninit
     // here so popupshowing will generate a new one:
     this._uninitView();
 
     if (aNode.getAttribute("label") != this._starButtonLabel)
       aNode.setAttribute("label", this._starButtonLabel);
--- a/browser/components/customizableui/src/CustomizableUI.jsm
+++ b/browser/components/customizableui/src/CustomizableUI.jsm
@@ -107,16 +107,17 @@ let gDirtyAreaCache = new Set();
  */
 let gPendingBuildAreas = new Map();
 
 let gSavedState = null;
 let gRestoring = false;
 let gDirty = false;
 let gInBatchStack = 0;
 let gResetting = false;
+let gUndoResetting = false;
 
 /**
  * gBuildAreas maps area IDs to actual area nodes within browser windows.
  */
 let gBuildAreas = new Map();
 
 /**
  * gBuildWindows is a map of windows that have registered build areas, mapped
@@ -517,16 +518,18 @@ let CustomizableUIInternal = {
           } else {
             node.removeAttribute("wrap");
           }
         }
 
         this.insertWidgetBefore(node, currentNode, container, aArea);
         if (gResetting) {
           this.notifyListeners("onWidgetReset", node, container);
+        } else if (gUndoResetting) {
+          this.notifyListeners("onWidgetUndoMove", node, container);
         }
       }
 
       if (currentNode) {
         let palette = aAreaNode.toolbox ? aAreaNode.toolbox.palette : null;
         let limit = currentNode.previousSibling;
         let node = container.lastChild;
         while (node && node != limit) {
@@ -2164,16 +2167,18 @@ let CustomizableUIInternal = {
   /**
    * Undoes a previous reset, restoring the state of the UI to the state prior to the reset.
    */
   undoReset: function() {
     if (gUIStateBeforeReset.uiCustomizationState == null ||
         gUIStateBeforeReset.drawInTitlebar == null) {
       return;
     }
+    gUndoResetting = true;
+
     let uiCustomizationState = gUIStateBeforeReset.uiCustomizationState;
     let drawInTitlebar = gUIStateBeforeReset.drawInTitlebar;
 
     // Need to clear the previous state before setting the prefs
     // because pref observers may check if there is a previous UI state.
     this._clearPreviousUIState();
 
     Services.prefs.setCharPref(kPrefCustomizationState, uiCustomizationState);
@@ -2183,16 +2188,18 @@ let CustomizableUIInternal = {
     // and we don't need to do anything else here:
     if (gSavedState) {
       for (let areaId of Object.keys(gSavedState.placements)) {
         let placements = gSavedState.placements[areaId];
         gPlacements.set(areaId, placements);
       }
       this._rebuildRegisteredAreas();
     }
+
+    gUndoResetting = false;
   },
 
   _clearPreviousUIState: function() {
     Object.getOwnPropertyNames(gUIStateBeforeReset).forEach((prop) => {
       gUIStateBeforeReset[prop] = null;
     });
   },
 
@@ -2456,16 +2463,21 @@ this.CustomizableUI = {
    *     Like onWidgetBeforeDOMChange, but fired after the change to the DOM
    *     node of the widget.
    *
    *   - onWidgetReset(aNode, aContainer)
    *     Fired after a reset to default placements moves a widget's node to a
    *     different location. aNode is the widget's node, aContainer is the
    *     area it was moved into (NB: it might already have been there and been
    *     moved to a different position!)
+   *   - onWidgetUndoMove(aNode, aContainer)
+   *     Fired after undoing a reset to default placements moves a widget's
+   *     node to a different location. aNode is the widget's node, aContainer
+   *     is the area it was moved into (NB: it might already have been there
+   *     and been moved to a different position!)
    *   - onAreaReset(aArea, aContainer)
    *     Fired after a reset to default placements is complete on an area's
    *     DOM node. Note that this is fired for each DOM node. aArea is the area
    *     that was reset, aContainer the DOM node that was reset.
    *
    *   - onWidgetCreated(aWidgetId)
    *     Fired when a widget with id aWidgetId has been created, but before it
    *     is added to any placements or any DOM nodes have been constructed.