Bug 909102 - Fix middle-clicking on a folder in the left panel of the Library (to open all items within the folder). r=mak
☠☠ backed out by 7b8d033f7717 ☠ ☠
authorMark Banner <standard8@mozilla.com>
Thu, 02 Mar 2017 11:34:43 +0000
changeset 345806 55d9a513c90e37af3d2fe22de2f01c1797f97b35
parent 345805 909cf4b977736e76e35339f41aa4a529db0795ca
child 345807 2ae0da5b22c63f1d1fea0c6d97262d99fe854ad8
push id38300
push usermbanner@mozilla.com
push dateFri, 03 Mar 2017 16:57:53 +0000
treeherderautoland@55d9a513c90e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmak
bugs909102
milestone54.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 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,187 @@
+/* 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();
+
+    // Middle click on first node in the content tree of the Library.
+    gLibrary.focus();
+    waitForFocus(function() {
+      mouseEventOnCell(gLibrary.PlacesOrganizer._places, 6, 0, { button: 0, clickCount: 2 },
+      gLibrary.PlacesOrganizer._places.ownerGlobal);
+      mouseEventOnCell(gLibrary.PlacesOrganizer._places, 7, 0, { button: 1 });
+    }, gLibrary);
+  } else {
+    // No more tests.
+
+    // 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);
+}