Bug 909102 - Fix middle-clicking on a folder in the left panel of the Library (to open all items within the folder). r?mak draft
authorMark Banner <standard8@mozilla.com>
Thu, 02 Mar 2017 11:34:43 +0000
changeset 494060 8c6eea87f2073ac57db8f430e7418e8e1b415af8
parent 493227 77d5a39a4677ed8e32a7ed46561c962d807fa7b1
child 547996 6783b873f628653fa983bbb3dd26fd65774ecd1a
push id47919
push userbmo:standard8@mozilla.com
push dateMon, 06 Mar 2017 14:35:05 +0000
reviewersmak
bugs909102
milestone54.0a1
Bug 909102 - Fix middle-clicking on a folder in the left panel of the Library (to open all items within the folder). r?mak MozReview-Commit-ID: 75Z8wOynfQh
browser/components/places/content/places.js
browser/components/places/tests/browser/browser.ini
browser/components/places/tests/browser/browser_library_left_pane_middleclick.js
--- a/browser/components/places/content/places.js
+++ b/browser/components/places/content/places.js
@@ -304,17 +304,17 @@ var PlacesOrganizer = {
 
     let node = this._places.selectedNode;
     if (node) {
       let middleClick = aEvent.button == 1 && aEvent.detail == 1;
       if (middleClick && PlacesUtils.nodeIsContainer(node)) {
         // The command execution function will take care of seeing if the
         // selection is a folder or a different container type, and will
         // load its contents in tabs.
-        PlacesUIUtils.openContainerNodeInTabs(selectedNode, aEvent, this._places);
+        PlacesUIUtils.openContainerNodeInTabs(node, aEvent, this._places);
       }
     }
   },
 
   /**
    * Handle focus changes on the places list and the current content view.
    */
   updateDetailsPane: function PO_updateDetailsPane() {
--- a/browser/components/places/tests/browser/browser.ini
+++ b/browser/components/places/tests/browser/browser.ini
@@ -34,16 +34,17 @@ support-files =
 [browser_drag_bookmarks_on_toolbar.js]
 [browser_forgetthissite_single.js]
 [browser_history_sidebar_search.js]
 [browser_library_batch_delete.js]
 [browser_library_commands.js]
 [browser_library_downloads.js]
 [browser_library_infoBox.js]
 [browser_library_left_pane_fixnames.js]
+[browser_library_left_pane_middleclick.js]
 [browser_library_left_pane_select_hierarchy.js]
 [browser_library_middleclick.js]
 [browser_library_open_leak.js]
 [browser_library_openFlatContainer.js]
 [browser_library_panel_leak.js]
 [browser_library_search.js]
 [browser_library_views_liveupdate.js]
 [browser_markPageAsFollowedLink.js]
new file mode 100644
--- /dev/null
+++ b/browser/components/places/tests/browser/browser_library_left_pane_middleclick.js
@@ -0,0 +1,196 @@
+/* vim:set ts=2 sw=2 sts=2 et: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ /**
+ * Tests middle-clicking items in the Library.
+ */
+
+const ENABLE_HISTORY_PREF = "places.history.enabled";
+
+var gLibrary = null;
+var gTests = [];
+var gCurrentTest = null;
+
+// Listener for TabOpen and tabs progress.
+var gTabsListener = {
+  _loadedURIs: [],
+  _openTabsCount: 0,
+
+  handleEvent(aEvent) {
+    if (aEvent.type != "TabOpen")
+      return;
+
+    if (++this._openTabsCount == gCurrentTest.URIs.length) {
+      is(gBrowser.tabs.length, gCurrentTest.URIs.length + 1,
+         "We have opened " + gCurrentTest.URIs.length + " new tab(s)");
+    }
+
+    var tab = aEvent.target;
+    is(tab.ownerGlobal, window,
+       "Tab has been opened in current browser window");
+  },
+
+  onLocationChange(aBrowser, aWebProgress, aRequest, aLocationURI,
+                             aFlags) {
+    var spec = aLocationURI.spec;
+    ok(true, spec);
+    // When a new tab is opened, location is first set to "about:blank", so
+    // we can ignore those calls.
+    // Ignore multiple notifications for the same URI too.
+    if (spec == "about:blank" || this._loadedURIs.includes(spec))
+      return;
+
+    ok(gCurrentTest.URIs.includes(spec),
+       "Opened URI found in list: " + spec);
+
+    if (gCurrentTest.URIs.includes(spec))
+      this._loadedURIs.push(spec);
+
+    if (this._loadedURIs.length == gCurrentTest.URIs.length) {
+      // We have correctly opened all URIs.
+
+      // Reset arrays.
+      this._loadedURIs.length = 0;
+
+      this._openTabsCount = 0;
+
+      executeSoon(function() {
+        // Close all tabs.
+        while (gBrowser.tabs.length > 1)
+          gBrowser.removeCurrentTab();
+
+        // Test finished.  This will move to the next one.
+        waitForFocus(gCurrentTest.finish, gBrowser.ownerGlobal);
+      });
+    }
+  }
+}
+
+// ------------------------------------------------------------------------------
+// Open a folder in tabs.
+
+gTests.push({
+  desc: "Open a folder in tabs.",
+  URIs: ["about:buildconfig", "about:"],
+  _folderId: -1,
+
+  setup() {
+    var bs = PlacesUtils.bookmarks;
+    // Create a new folder.
+    var folderId = bs.createFolder(bs.unfiledBookmarksFolder,
+                                   "Folder",
+                                   bs.DEFAULT_INDEX);
+    this._folderId = folderId;
+
+    // Add bookmarks in folder.
+    this.URIs.forEach(function(aURI) {
+      bs.insertBookmark(folderId,
+                        PlacesUtils._uri(aURI),
+                        bs.DEFAULT_INDEX,
+                        "Title");
+    });
+
+    // Select unsorted bookmarks root in the left pane.
+    gLibrary.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
+    isnot(gLibrary.PlacesOrganizer._places.selectedNode, null,
+          "We correctly have selection in the Library left pane");
+    // Get our bookmark in the right pane.
+    var folderNode = gLibrary.ContentTree.view.view.nodeForTreeIndex(0);
+    is(folderNode.title, "Folder", "Found folder in the right pane");
+  },
+
+  finish() {
+    setTimeout(runNextTest, 0);
+  },
+
+  cleanup() {
+    PlacesUtils.bookmarks.removeItem(this._folderId);
+  }
+});
+
+// ------------------------------------------------------------------------------
+
+function test() {
+  waitForExplicitFinish();
+
+  // Sanity checks.
+  ok(PlacesUtils, "PlacesUtils in context");
+  ok(PlacesUIUtils, "PlacesUIUtils in context");
+
+  // Add tabs listeners.
+  gBrowser.tabContainer.addEventListener("TabOpen", gTabsListener);
+  gBrowser.addTabsProgressListener(gTabsListener);
+
+  // Temporary disable history, so we won't record pages navigation.
+  gPrefService.setBoolPref(ENABLE_HISTORY_PREF, false);
+
+  // Open Library window.
+  openLibrary(function(library) {
+    gLibrary = library;
+    // Kick off tests.
+    runNextTest();
+  });
+}
+
+function runNextTest() {
+  // Cleanup from previous test.
+  if (gCurrentTest)
+    gCurrentTest.cleanup();
+
+  if (gTests.length > 0) {
+    // Goto next test.
+    gCurrentTest = gTests.shift();
+    info("Start of test: " + gCurrentTest.desc);
+    // Test setup will set Library so that the bookmark to be opened is the
+    // first node in the content (right pane) tree.
+    gCurrentTest.setup();
+
+    gLibrary.focus();
+    waitForFocus(function() {
+      // Open the "Other Bookmarks" folder.
+      gLibrary.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
+      gLibrary.PlacesOrganizer._places.selectedNode.containerOpen = true;
+      // Now middle-click on the bookmark contained with it.
+      let bookmarkedNode = gLibrary.PlacesOrganizer._places.selectedNode.getChild(0);
+      mouseEventOnCell(gLibrary.PlacesOrganizer._places,
+        gLibrary.PlacesOrganizer._places.view.treeIndexForNode(bookmarkedNode),
+        0,
+        { button: 1 });
+    }, gLibrary);
+  } else {
+    // No more tests.
+
+    // We must close "Other Bookmarks" ready for other tests.
+    gLibrary.PlacesOrganizer.selectLeftPaneQuery("UnfiledBookmarks");
+    gLibrary.PlacesOrganizer._places.selectedNode.containerOpen = false;
+
+    // Close Library window.
+    gLibrary.close();
+
+    // Remove tabs listeners.
+    gBrowser.tabContainer.removeEventListener("TabOpen", gTabsListener);
+    gBrowser.removeTabsProgressListener(gTabsListener);
+
+    // Restore history.
+    try {
+      gPrefService.clearUserPref(ENABLE_HISTORY_PREF);
+    } catch (ex) {}
+
+    finish();
+  }
+}
+
+function mouseEventOnCell(aTree, aRowIndex, aColumnIndex, aEventDetails) {
+  var selection = aTree.view.selection;
+  selection.select(aRowIndex);
+  aTree.treeBoxObject.ensureRowIsVisible(aRowIndex);
+  var column = aTree.columns[aColumnIndex];
+
+  // get cell coordinates
+  var rect = aTree.treeBoxObject.getCoordsForCellItem(aRowIndex, column, "text");
+
+  EventUtils.synthesizeMouse(aTree.body, rect.x, rect.y,
+                             aEventDetails, gLibrary);
+}