gecko/browser/components/customizableui/test/browser_984455_bookmarks_items_reparenting.js

268 lines
9.4 KiB
JavaScript

/* 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/. */
"use strict";
let gNavBar = document.getElementById(CustomizableUI.AREA_NAVBAR);
let gOverflowList = document.getElementById(gNavBar.getAttribute("overflowtarget"));
const kBookmarksButton = "bookmarks-menu-button";
const kBookmarksItems = "personal-bookmarks";
const kOriginalWindowWidth = window.outerWidth;
const kSmallWidth = 400;
/**
* Helper function that opens the bookmarks menu, and returns a Promise that
* resolves as soon as the menu is ready for interaction.
*/
function bookmarksMenuPanelShown() {
let deferred = Promise.defer();
let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
let onTransitionEnd = (e) => {
if (e.target == bookmarksMenuPopup) {
bookmarksMenuPopup.removeEventListener("transitionend", onTransitionEnd);
deferred.resolve();
}
}
bookmarksMenuPopup.addEventListener("transitionend", onTransitionEnd);
return deferred.promise;
}
/**
* Checks that the placesContext menu is correctly attached to the
* controller of some view. Returns a Promise that resolves as soon
* as the context menu is closed.
*
* @param aItemWithContextMenu the item that we need to synthesize hte
* right click on in order to open the context menu.
*/
function checkPlacesContextMenu(aItemWithContextMenu) {
return Task.spawn(function* () {
let contextMenu = document.getElementById("placesContext");
let newBookmarkItem = document.getElementById("placesContext_new:bookmark");
info("Waiting for context menu on " + aItemWithContextMenu.id);
let shownPromise = popupShown(contextMenu);
EventUtils.synthesizeMouseAtCenter(aItemWithContextMenu,
{type: "contextmenu", button: 2});
yield shownPromise;
ok(!newBookmarkItem.hasAttribute("disabled"),
"New bookmark item shouldn't be disabled");
info("Closing context menu");
yield closePopup(contextMenu);
});
}
/**
* Opens the bookmarks menu panel, and then opens each of the "special"
* submenus in that list. Then it checks that those submenu's context menus
* are properly hooked up to a controller.
*/
function checkSpecialContextMenus() {
return Task.spawn(function* () {
let contextMenu = document.getElementById("placesContext");
let bookmarksMenuButton = document.getElementById(kBookmarksButton);
let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
const kSpecialItemIDs = {
"BMB_bookmarksToolbar": "BMB_bookmarksToolbarPopup",
"BMB_unsortedBookmarks": "BMB_unsortedBookmarksPopup",
};
// Open the bookmarks menu button context menus and ensure that
// they have the proper views attached.
let shownPromise = bookmarksMenuPanelShown();
let dropmarker = document.getAnonymousElementByAttribute(bookmarksMenuButton,
"anonid", "dropmarker");
EventUtils.synthesizeMouseAtCenter(dropmarker, {});
info("Waiting for bookmarks menu popup to show after clicking dropmarker.")
yield shownPromise;
for (let menuID in kSpecialItemIDs) {
let menuItem = document.getElementById(menuID);
let menuPopup = document.getElementById(kSpecialItemIDs[menuID]);
info("Waiting to open menu for " + menuID);
let shownPromise = popupShown(menuPopup);
menuPopup.openPopup(menuItem, null, 0, 0, false, false, null);
yield shownPromise;
yield checkPlacesContextMenu(menuPopup);
info("Closing menu for " + menuID);
yield closePopup(menuPopup);
}
info("Closing bookmarks menu");
yield closePopup(bookmarksMenuPopup);
});
}
/**
* Closes a focused popup by simulating pressing the Escape key,
* and returns a Promise that resolves as soon as the popup is closed.
*
* @param aPopup the popup node to close.
*/
function closePopup(aPopup) {
let hiddenPromise = popupHidden(aPopup);
EventUtils.synthesizeKey("VK_ESCAPE", {});
return hiddenPromise;
}
/**
* Helper function that checks that the context menu of the
* bookmark toolbar items chevron popup is correctly hooked up
* to the controller of a view.
*/
function checkBookmarksItemsChevronContextMenu() {
return Task.spawn(function*() {
let chevronPopup = document.getElementById("PlacesChevronPopup");
let shownPromise = popupShown(chevronPopup);
let chevron = document.getElementById("PlacesChevron");
EventUtils.synthesizeMouseAtCenter(chevron, {});
info("Waiting for bookmark toolbar item chevron popup to show");
yield shownPromise;
yield waitForCondition(() => {
for (let child of chevronPopup.children) {
if (child.style.visibility != "hidden")
return true;
}
});
yield checkPlacesContextMenu(chevronPopup);
info("Waiting for bookmark toolbar item chevron popup to close");
yield closePopup(chevronPopup);
});
}
/**
* Forces the window to a width that causes the nav-bar to overflow
* its contents. Returns a Promise that resolves as soon as the
* overflowable nav-bar is showing its chevron.
*/
function overflowEverything() {
info("Waiting for overflow");
window.resizeTo(kSmallWidth, window.outerHeight);
return waitForCondition(() => gNavBar.hasAttribute("overflowing"));
}
/**
* Returns the window to its original size from the start of the test,
* and returns a Promise that resolves when the nav-bar is no longer
* overflowing.
*/
function stopOverflowing() {
info("Waiting until we stop overflowing");
window.resizeTo(kOriginalWindowWidth, window.outerHeight);
return waitForCondition(() => !gNavBar.hasAttribute("overflowing"));
}
/**
* Checks that an item with ID aID is overflowing in the nav-bar.
*
* @param aID the ID of the node to check for overflowingness.
*/
function checkOverflowing(aID) {
ok(!gNavBar.querySelector("#" + aID),
"Item with ID " + aID + " should no longer be in the gNavBar");
let item = gOverflowList.querySelector("#" + aID);
ok(item, "Item with ID " + aID + " should be overflowing");
is(item.getAttribute("overflowedItem"), "true",
"Item with ID " + aID + " should have overflowedItem attribute");
}
/**
* Checks that an item with ID aID is not overflowing in the nav-bar.
*
* @param aID the ID of hte node to check for non-overflowingness.
*/
function checkNotOverflowing(aID) {
ok(!gOverflowList.querySelector("#" + aID),
"Item with ID " + aID + " should no longer be overflowing");
let item = gNavBar.querySelector("#" + aID);
ok(item, "Item with ID " + aID + " should be in the nav bar");
ok(!item.hasAttribute("overflowedItem"),
"Item with ID " + aID + " should not have overflowedItem attribute");
}
/**
* Test that overflowing the bookmarks menu button doesn't break the
* context menus for the Unsorted and Bookmarks Toolbar menu items.
*/
add_task(function* testOverflowingBookmarksButtonContextMenu() {
ok(!gNavBar.hasAttribute("overflowing"), "Should start with a non-overflowing toolbar.");
ok(CustomizableUI.inDefaultState, "Should start in default state.");
// Open the Unsorted and Bookmarks Toolbar context menus and ensure
// that they have views attached.
yield checkSpecialContextMenus();
yield overflowEverything();
checkOverflowing(kBookmarksButton);
yield stopOverflowing();
checkNotOverflowing(kBookmarksButton);
yield checkSpecialContextMenus();
});
/**
* Test that the bookmarks toolbar items context menu still works if moved
* to the menu from the overflow panel, and then back to the toolbar.
*/
add_task(function* testOverflowingBookmarksItemsContextMenu() {
info("Ensuring panel is ready.");
yield PanelUI.ensureReady();
let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
gCustomizeMode.addToToolbar(bookmarksToolbarItems);
yield checkPlacesContextMenu(bookmarksToolbarItems);
yield overflowEverything();
checkOverflowing(kBookmarksItems)
gCustomizeMode.addToPanel(bookmarksToolbarItems);
yield stopOverflowing();
gCustomizeMode.addToToolbar(bookmarksToolbarItems);
yield checkPlacesContextMenu(bookmarksToolbarItems);
});
/**
* Test that overflowing the bookmarks toolbar items doesn't cause the
* context menu in the bookmarks toolbar items chevron to stop working.
*/
add_task(function* testOverflowingBookmarksItemsChevronContextMenu() {
// If it's not already there, let's move the bookmarks toolbar items to
// the nav-bar.
let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
gCustomizeMode.addToToolbar(bookmarksToolbarItems);
// We make the PlacesToolbarItems element be super tiny in order to force
// the bookmarks toolbar items into overflowing and making the chevron
// show itself.
let placesToolbarItems = document.getElementById("PlacesToolbarItems");
let placesChevron = document.getElementById("PlacesChevron");
placesToolbarItems.style.maxWidth = "10px";
info("Waiting for chevron to no longer be collapsed");
yield waitForCondition(() => !placesChevron.collapsed);
yield checkBookmarksItemsChevronContextMenu();
yield overflowEverything();
checkOverflowing(kBookmarksItems);
yield stopOverflowing();
checkNotOverflowing(kBookmarksItems);
yield checkBookmarksItemsChevronContextMenu();
placesToolbarItems.style.removeProperty("max-width");
});
add_task(function* asyncCleanup() {
window.resizeTo(kOriginalWindowWidth, window.outerHeight);
yield resetCustomization();
});