Bug 1439315 - 2 - Move command utils to PlacesUIUtils. r=standard8 draft
authorMarco Bonardo <mbonardo@mozilla.com>
Wed, 28 Feb 2018 12:27:21 +0100
changeset 761870 7dacee00aecf5cfb00a6977a88ecea5334958022
parent 761869 9e3e6f58742a0900fdd73e6c5ed5089f7d01da63
child 761871 e215b0a8890b3dc2169d82fbf63ba2fba4e65b4f
push id101023
push usermak77@bonardo.net
push dateThu, 01 Mar 2018 15:34:13 +0000
reviewersstandard8
bugs1439315
milestone60.0a1
Bug 1439315 - 2 - Move command utils to PlacesUIUtils. r=standard8 MozReview-Commit-ID: 6hN9LxVQunX
browser/components/places/PlacesUIUtils.jsm
browser/components/places/content/controller.js
browser/components/places/content/placesOverlay.xul
browser/components/places/tests/browser/browser_check_correct_controllers.js
--- a/browser/components/places/PlacesUIUtils.jsm
+++ b/browser/components/places/PlacesUIUtils.jsm
@@ -400,16 +400,87 @@ var PlacesUIUtils = {
 
       node = node.parentNode;
     }
 
     return null;
   },
 
   /**
+   * Returns the active PlacesController for a given command.
+   *
+   * @param win The window containing the affected view
+   * @param command The command
+   * @return a PlacesController
+   */
+  getControllerForCommand(win, command) {
+    // A context menu may be built for non-focusable views.  Thus, we first try
+    // to look for a view associated with document.popupNode
+    let popupNode;
+    try {
+      popupNode = win.document.popupNode;
+    } catch (e) {
+      // The document went away (bug 797307).
+      return null;
+    }
+    if (popupNode) {
+      let view = this.getViewForNode(popupNode);
+      if (view && view._contextMenuShown)
+        return view.controllers.getControllerForCommand(command);
+    }
+
+    // When we're not building a context menu, only focusable views
+    // are possible.  Thus, we can safely use the command dispatcher.
+    let controller = win.top.document.commandDispatcher
+                        .getControllerForCommand(command);
+    return controller || null;
+  },
+
+  /**
+   * Update all the Places commands for the given window.
+   *
+   * @param win The window to update.
+   */
+  updateCommands(win) {
+    // Get the controller for one of the places commands.
+    let controller = this.getControllerForCommand(win, "placesCmd_open");
+    for (let command of [
+      "placesCmd_open",
+      "placesCmd_open:window",
+      "placesCmd_open:privatewindow",
+      "placesCmd_open:tab",
+      "placesCmd_new:folder",
+      "placesCmd_new:bookmark",
+      "placesCmd_new:separator",
+      "placesCmd_show:info",
+      "placesCmd_reload",
+      "placesCmd_sortBy:name",
+      "placesCmd_cut",
+      "placesCmd_copy",
+      "placesCmd_paste",
+      "placesCmd_delete",
+    ]) {
+      win.goSetCommandEnabled(command,
+                              controller && controller.isCommandEnabled(command));
+    }
+  },
+
+  /**
+   * Executes the given command on the currently active controller.
+   *
+   * @param win The window containing the affected view
+   * @param command The command to execute
+   */
+  doCommand(win, command) {
+    let controller = this.getControllerForCommand(win, command);
+    if (controller && controller.isCommandEnabled(command))
+      controller.doCommand(command);
+  },
+
+  /**
    * By calling this before visiting an URL, the visit will be associated to a
    * TRANSITION_TYPED transition (if there is no a referrer).
    * This is used when visiting pages from the history menu, history sidebar,
    * url bar, url autocomplete results, and history searches from the places
    * organizer.  If this is not called visits will be marked as
    * TRANSITION_LINK.
    */
   markPageAsTyped: function PUIU_markPageAsTyped(aURL) {
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -1505,72 +1505,16 @@ var PlacesControllerDragHelper = {
   }
 };
 
 
 XPCOMUtils.defineLazyServiceGetter(PlacesControllerDragHelper, "dragService",
                                    "@mozilla.org/widget/dragservice;1",
                                    "nsIDragService");
 
-function goUpdatePlacesCommands() {
-  // Get the controller for one of the places commands.
-  var placesController = doGetPlacesControllerForCommand("placesCmd_open");
-  function updatePlacesCommand(aCommand) {
-    goSetCommandEnabled(aCommand, placesController &&
-                                  placesController.isCommandEnabled(aCommand));
-  }
-
-  updatePlacesCommand("placesCmd_open");
-  updatePlacesCommand("placesCmd_open:window");
-  updatePlacesCommand("placesCmd_open:privatewindow");
-  updatePlacesCommand("placesCmd_open:tab");
-  updatePlacesCommand("placesCmd_new:folder");
-  updatePlacesCommand("placesCmd_new:bookmark");
-  updatePlacesCommand("placesCmd_new:separator");
-  updatePlacesCommand("placesCmd_show:info");
-  updatePlacesCommand("placesCmd_reload");
-  updatePlacesCommand("placesCmd_sortBy:name");
-  updatePlacesCommand("placesCmd_cut");
-  updatePlacesCommand("placesCmd_copy");
-  updatePlacesCommand("placesCmd_paste");
-  updatePlacesCommand("placesCmd_delete");
-}
-
-function doGetPlacesControllerForCommand(aCommand) {
-  // A context menu may be built for non-focusable views.  Thus, we first try
-  // to look for a view associated with document.popupNode
-  let popupNode;
-  try {
-    popupNode = document.popupNode;
-  } catch (e) {
-    // The document went away (bug 797307).
-    return null;
-  }
-  if (popupNode) {
-    let view = PlacesUIUtils.getViewForNode(popupNode);
-    if (view && view._contextMenuShown)
-      return view.controllers.getControllerForCommand(aCommand);
-  }
-
-  // When we're not building a context menu, only focusable views
-  // are possible.  Thus, we can safely use the command dispatcher.
-  let controller = top.document.commandDispatcher
-                      .getControllerForCommand(aCommand);
-  if (controller)
-    return controller;
-
-  return null;
-}
-
-function goDoPlacesCommand(aCommand) {
-  let controller = doGetPlacesControllerForCommand(aCommand);
-  if (controller && controller.isCommandEnabled(aCommand))
-    controller.doCommand(aCommand);
-}
-
 /**
  * This gets the most appropriate item for using for batching. In the case of multiple
  * views being related, the method returns the most expensive result to batch.
  * For example, if it detects the left-hand library pane, then it will look for
  * and return the reference to the right-hand pane.
  *
  * @param {Object} viewOrElement The item to check.
  * @return {Object} Will return the best result node to batch, or null
--- a/browser/components/places/content/placesOverlay.xul
+++ b/browser/components/places/content/placesOverlay.xul
@@ -38,55 +38,55 @@
       <label id="bhtTitleText" class="tooltip-label" />
       <label id="bhtUrlText" crop="center" class="tooltip-label uri-element" />
     </vbox>
   </tooltip>
 
   <commandset id="placesCommands"
               commandupdater="true"
               events="focus,sort,places"
-              oncommandupdate="goUpdatePlacesCommands();">
+              oncommandupdate="PlacesUIUtils.updateCommands(window);">
     <command id="placesCmd_open"
-             oncommand="goDoPlacesCommand('placesCmd_open');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_open');"/>
     <command id="placesCmd_open:window"
-             oncommand="goDoPlacesCommand('placesCmd_open:window');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_open:window');"/>
     <command id="placesCmd_open:privatewindow"
-             oncommand="goDoPlacesCommand('placesCmd_open:privatewindow');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_open:privatewindow');"/>
     <command id="placesCmd_open:tab"
-             oncommand="goDoPlacesCommand('placesCmd_open:tab');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_open:tab');"/>
 
     <command id="placesCmd_new:bookmark"
-             oncommand="goDoPlacesCommand('placesCmd_new:bookmark');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_new:bookmark');"/>
     <command id="placesCmd_new:folder"
-             oncommand="goDoPlacesCommand('placesCmd_new:folder');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_new:folder');"/>
     <command id="placesCmd_new:separator"
-             oncommand="goDoPlacesCommand('placesCmd_new:separator');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_new:separator');"/>
     <command id="placesCmd_show:info"
-             oncommand="goDoPlacesCommand('placesCmd_show:info');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_show:info');"/>
     <command id="placesCmd_rename"
-             oncommand="goDoPlacesCommand('placesCmd_show:info');"
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_show:info');"
              observes="placesCmd_show:info"/>
     <command id="placesCmd_reload"
-             oncommand="goDoPlacesCommand('placesCmd_reload');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_reload');"/>
     <command id="placesCmd_sortBy:name"
-             oncommand="goDoPlacesCommand('placesCmd_sortBy:name');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_sortBy:name');"/>
     <command id="placesCmd_deleteDataHost"
-             oncommand="goDoPlacesCommand('placesCmd_deleteDataHost');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_deleteDataHost');"/>
     <command id="placesCmd_createBookmark"
-             oncommand="goDoPlacesCommand('placesCmd_createBookmark');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_createBookmark');"/>
 
     <!-- Special versions of cut/copy/paste/delete which check for an open context menu. -->
     <command id="placesCmd_cut"
-             oncommand="goDoPlacesCommand('placesCmd_cut');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_cut');"/>
     <command id="placesCmd_copy"
-             oncommand="goDoPlacesCommand('placesCmd_copy');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_copy');"/>
     <command id="placesCmd_paste"
-             oncommand="goDoPlacesCommand('placesCmd_paste');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_paste');"/>
     <command id="placesCmd_delete"
-             oncommand="goDoPlacesCommand('placesCmd_delete');"/>
+             oncommand="PlacesUIUtils.doCommand(window, 'placesCmd_delete');"/>
   </commandset>
 
   <menupopup id="placesContext"
              onpopupshowing="this._view = PlacesUIUtils.getViewForNode(document.popupNode);
                              if (!PlacesUIUtils.openInTabClosesMenu) {
                                document.getElementById ('placesContext_open:newtab')
                                .setAttribute('closemenu', 'single');
                              }
--- a/browser/components/places/tests/browser/browser_check_correct_controllers.js
+++ b/browser/components/places/tests/browser/browser_check_correct_controllers.js
@@ -29,38 +29,38 @@ add_task(async function test() {
   registerCleanupFunction(() => {
     SidebarUI.hide();
   });
 
   // Focus the tree and check if its controller is returned.
   let tree = sidebar.contentDocument.getElementById("bookmarks-view");
   tree.focus();
 
-  let controller = doGetPlacesControllerForCommand("placesCmd_copy");
+  let controller = PlacesUIUtils.getControllerForCommand(window, "placesCmd_copy");
   let treeController = tree.controllers
                            .getControllerForCommand("placesCmd_copy");
   ok(controller == treeController, "tree controller was returned");
 
   // Open the context menu for a toolbar item, and check if the toolbar's
   // controller is returned.
   let toolbarItems = document.getElementById("PlacesToolbarItems");
   EventUtils.synthesizeMouse(toolbarItems.childNodes[0],
                              4, 4, { type: "contextmenu", button: 2 },
                              window);
-  controller = doGetPlacesControllerForCommand("placesCmd_copy");
+  controller = PlacesUIUtils.getControllerForCommand(window, "placesCmd_copy");
   let toolbarController = document.getElementById("PlacesToolbar")
                                   .controllers
                                   .getControllerForCommand("placesCmd_copy");
   ok(controller == toolbarController, "the toolbar controller was returned");
 
   document.getElementById("placesContext").hidePopup();
 
   // Now that the context menu is closed, try to get the tree controller again.
   tree.focus();
-  controller = doGetPlacesControllerForCommand("placesCmd_copy");
+  controller = PlacesUIUtils.getControllerForCommand(window, "placesCmd_copy");
   ok(controller == treeController, "tree controller was returned");
 
   if (wasCollapsed) {
     await promiseSetToolbarVisibility(toolbar, false);
   }
 });
 
 function promiseLoadedSidebar(cmd) {