forked from mirrors/gecko-dev
When Unified Extensions is enabled, we want to make it so that any WebExtension browser_actions overflow into the Unified Extensions panel instead of the default overflow panel. Depends on D160292 Differential Revision: https://phabricator.services.mozilla.com/D160293
302 lines
10 KiB
JavaScript
302 lines
10 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";
|
|
|
|
var gNavBar = document.getElementById(CustomizableUI.AREA_NAVBAR);
|
|
var gOverflowList = document.getElementById(
|
|
gNavBar.getAttribute("default-overflowtarget")
|
|
);
|
|
|
|
const kBookmarksButton = "bookmarks-menu-button";
|
|
const kBookmarksItems = "personal-bookmarks";
|
|
const kOriginalWindowWidth = window.outerWidth;
|
|
|
|
/**
|
|
* Helper function that opens the bookmarks menu, and returns a Promise that
|
|
* resolves as soon as the menu is ready for interaction.
|
|
*/
|
|
function bookmarksMenuPanelShown() {
|
|
return new Promise(resolve => {
|
|
let bookmarksMenuPopup = document.getElementById("BMB_bookmarksPopup");
|
|
let onPopupShown = e => {
|
|
if (e.target == bookmarksMenuPopup) {
|
|
bookmarksMenuPopup.removeEventListener("popupshown", onPopupShown);
|
|
resolve();
|
|
}
|
|
};
|
|
bookmarksMenuPopup.addEventListener("popupshown", onPopupShown);
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 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 the
|
|
* right click on in order to open the context menu.
|
|
*/
|
|
function checkPlacesContextMenu(aItemWithContextMenu) {
|
|
return (async 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,
|
|
});
|
|
await shownPromise;
|
|
|
|
ok(
|
|
!newBookmarkItem.hasAttribute("disabled"),
|
|
"New bookmark item shouldn't be disabled"
|
|
);
|
|
|
|
info("Closing context menu");
|
|
let hiddenPromise = popupHidden(contextMenu);
|
|
// Use hidePopup instead of the closePopup helper because macOS native
|
|
// context menus can't be closed by synthesized ESC in automation.
|
|
contextMenu.hidePopup();
|
|
await hiddenPromise;
|
|
})();
|
|
}
|
|
|
|
/**
|
|
* 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 (async function() {
|
|
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();
|
|
|
|
EventUtils.synthesizeMouseAtCenter(bookmarksMenuButton, {});
|
|
info("Waiting for bookmarks menu popup to show after clicking dropmarker.");
|
|
await shownPromise;
|
|
|
|
for (let menuID in kSpecialItemIDs) {
|
|
let menuItem = document.getElementById(menuID);
|
|
let menuPopup = document.getElementById(kSpecialItemIDs[menuID]);
|
|
info("Waiting to open menu for " + menuID);
|
|
shownPromise = popupShown(menuPopup);
|
|
menuPopup.openPopup(menuItem, null, 0, 0, false, false, null);
|
|
await shownPromise;
|
|
|
|
await checkPlacesContextMenu(menuPopup);
|
|
info("Closing menu for " + menuID);
|
|
await closePopup(menuPopup);
|
|
}
|
|
|
|
info("Closing bookmarks menu");
|
|
await 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("KEY_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 (async 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");
|
|
await shownPromise;
|
|
await TestUtils.waitForCondition(() => {
|
|
for (let child of chevronPopup.children) {
|
|
if (child.style.visibility != "hidden") {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
});
|
|
await checkPlacesContextMenu(chevronPopup);
|
|
info("Waiting for bookmark toolbar item chevron popup to close");
|
|
await 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(kForceOverflowWidthPx, window.outerHeight);
|
|
return TestUtils.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 TestUtils.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(async function testOverflowingBookmarksButtonContextMenu() {
|
|
ok(CustomizableUI.inDefaultState, "Should start in default state.");
|
|
// The DevEdition has the DevTools button in the toolbar by default. Remove it
|
|
// to prevent branch-specific available toolbar space.
|
|
CustomizableUI.removeWidgetFromArea("developer-button");
|
|
CustomizableUI.removeWidgetFromArea(
|
|
"library-button",
|
|
CustomizableUI.AREA_NAVBAR
|
|
);
|
|
CustomizableUI.addWidgetToArea(kBookmarksButton, CustomizableUI.AREA_NAVBAR);
|
|
ok(
|
|
!gNavBar.hasAttribute("overflowing"),
|
|
"Should start with a non-overflowing toolbar."
|
|
);
|
|
|
|
// Open the Unsorted and Bookmarks Toolbar context menus and ensure
|
|
// that they have views attached.
|
|
await checkSpecialContextMenus();
|
|
|
|
await overflowEverything();
|
|
checkOverflowing(kBookmarksButton);
|
|
|
|
await stopOverflowing();
|
|
checkNotOverflowing(kBookmarksButton);
|
|
|
|
await 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(async function testOverflowingBookmarksItemsContextMenu() {
|
|
info("Ensuring panel is ready.");
|
|
await PanelUI.ensureReady();
|
|
|
|
let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
|
|
await gCustomizeMode.addToToolbar(bookmarksToolbarItems);
|
|
await TestUtils.waitForCondition(
|
|
() => document.getElementById("PlacesToolbar")._placesView
|
|
);
|
|
await checkPlacesContextMenu(bookmarksToolbarItems);
|
|
|
|
await overflowEverything();
|
|
checkOverflowing(kBookmarksItems);
|
|
|
|
await gCustomizeMode.addToPanel(bookmarksToolbarItems);
|
|
|
|
await stopOverflowing();
|
|
|
|
await gCustomizeMode.addToToolbar(bookmarksToolbarItems);
|
|
await TestUtils.waitForCondition(
|
|
() => document.getElementById("PlacesToolbar")._placesView
|
|
);
|
|
await 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(async function testOverflowingBookmarksItemsChevronContextMenu() {
|
|
// If it's not already there, let's move the bookmarks toolbar items to
|
|
// the nav-bar.
|
|
let bookmarksToolbarItems = document.getElementById(kBookmarksItems);
|
|
await 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");
|
|
await TestUtils.waitForCondition(() => !placesChevron.collapsed);
|
|
|
|
await checkBookmarksItemsChevronContextMenu();
|
|
|
|
await overflowEverything();
|
|
checkOverflowing(kBookmarksItems);
|
|
|
|
await stopOverflowing();
|
|
checkNotOverflowing(kBookmarksItems);
|
|
|
|
await checkBookmarksItemsChevronContextMenu();
|
|
|
|
placesToolbarItems.style.removeProperty("max-width");
|
|
});
|
|
|
|
add_task(async function asyncCleanup() {
|
|
window.resizeTo(kOriginalWindowWidth, window.outerHeight);
|
|
await resetCustomization();
|
|
});
|