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
--- 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);
+}