Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

/* 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 navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
var overflowList = document.getElementById(
navbar.getAttribute("default-overflowtarget")
);
const kTestBtn1 = "test-addWidgetToArea-overflow";
const kTestBtn2 = "test-removeWidgetFromArea-overflow";
const kTestBtn3 = "test-createWidget-overflow";
const kTestBtn4 = "test-createWidget-overflow-first-item";
const kTestBtn5 = "test-addWidgetToArea-overflow-first-item";
const kSidebarBtn = "sidebar-button";
const kLibraryButton = "library-button";
const kDownloadsBtn = "downloads-button";
const kSearchBox = "search-container";
var originalWindowWidth;
// Adding a widget should add it next to the widget it's being inserted next to.
add_task(async function subsequent_widget() {
originalWindowWidth = window.outerWidth;
createDummyXULButton(kTestBtn1, "Test");
ok(
!navbar.hasAttribute("overflowing"),
"Should start subsequent_widget with a non-overflowing toolbar."
);
ok(
CustomizableUI.inDefaultState,
"Should start subsequent_widget in default state."
);
CustomizableUI.addWidgetToArea(kSidebarBtn, "nav-bar");
await waitForElementShown(document.getElementById(kSidebarBtn));
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await TestUtils.waitForCondition(() => {
return (
navbar.hasAttribute("overflowing") &&
document.getElementById(kSidebarBtn).getAttribute("overflowedItem") ==
"true"
);
});
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
ok(
!navbar.querySelector("#" + kSidebarBtn),
"Sidebar button should no longer be in the navbar"
);
let sidebarBtnNode = overflowList.querySelector("#" + kSidebarBtn);
ok(sidebarBtnNode, "Sidebar button should be overflowing");
ok(
sidebarBtnNode && sidebarBtnNode.getAttribute("overflowedItem") == "true",
"Sidebar button should have overflowedItem attribute"
);
let placementOfSidebarButton = CustomizableUI.getWidgetIdsInArea(
navbar.id
).indexOf(kSidebarBtn);
CustomizableUI.addWidgetToArea(
kTestBtn1,
navbar.id,
placementOfSidebarButton
);
ok(
!navbar.querySelector("#" + kTestBtn1),
"New button should not be in the navbar"
);
let newButtonNode = overflowList.querySelector("#" + kTestBtn1);
ok(newButtonNode, "New button should be overflowing");
ok(
newButtonNode && newButtonNode.getAttribute("overflowedItem") == "true",
"New button should have overflowedItem attribute"
);
let nextEl = newButtonNode && newButtonNode.nextElementSibling;
is(
nextEl && nextEl.id,
kSidebarBtn,
"Test button should be next to sidebar button."
);
window.resizeTo(originalWindowWidth, window.outerHeight);
await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
ok(
!navbar.hasAttribute("overflowing"),
"Should not have an overflowing toolbar."
);
ok(
navbar.querySelector("#" + kSidebarBtn),
"Sidebar button should be in the navbar"
);
ok(
sidebarBtnNode && sidebarBtnNode.getAttribute("overflowedItem") != "true",
"Sidebar button should no longer have overflowedItem attribute"
);
ok(
!overflowList.querySelector("#" + kSidebarBtn),
"Sidebar button should no longer be overflowing"
);
ok(
navbar.querySelector("#" + kTestBtn1),
"Test button should be in the navbar"
);
ok(
!overflowList.querySelector("#" + kTestBtn1),
"Test button should no longer be overflowing"
);
ok(
newButtonNode && newButtonNode.getAttribute("overflowedItem") != "true",
"New button should no longer have overflowedItem attribute"
);
let el = document.getElementById(kTestBtn1);
if (el) {
CustomizableUI.removeWidgetFromArea(kTestBtn1);
el.remove();
}
CustomizableUI.removeWidgetFromArea(kSidebarBtn);
window.resizeTo(originalWindowWidth, window.outerHeight);
await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
});
// Removing a widget should remove it from the overflow list if that is where it is, and update it accordingly.
add_task(async function remove_widget() {
createDummyXULButton(kTestBtn2, "Test");
ok(
!navbar.hasAttribute("overflowing"),
"Should start remove_widget with a non-overflowing toolbar."
);
ok(
CustomizableUI.inDefaultState,
"Should start remove_widget in default state."
);
CustomizableUI.addWidgetToArea(kTestBtn2, navbar.id);
ok(
!navbar.hasAttribute("overflowing"),
"Should still have a non-overflowing toolbar."
);
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await TestUtils.waitForCondition(() => navbar.hasAttribute("overflowing"));
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
ok(
!navbar.querySelector("#" + kTestBtn2),
"Test button should not be in the navbar"
);
ok(
overflowList.querySelector("#" + kTestBtn2),
"Test button should be overflowing"
);
CustomizableUI.removeWidgetFromArea(kTestBtn2);
ok(
!overflowList.querySelector("#" + kTestBtn2),
"Test button should not be overflowing."
);
ok(
!navbar.querySelector("#" + kTestBtn2),
"Test button should not be in the navbar"
);
ok(
gNavToolbox.palette.querySelector("#" + kTestBtn2),
"Test button should be in the palette"
);
window.resizeTo(originalWindowWidth, window.outerHeight);
await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
ok(
!navbar.hasAttribute("overflowing"),
"Should not have an overflowing toolbar."
);
let el = document.getElementById(kTestBtn2);
if (el) {
CustomizableUI.removeWidgetFromArea(kTestBtn2);
el.remove();
}
window.resizeTo(originalWindowWidth, window.outerHeight);
await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
});
// Constructing a widget while overflown should set the right class on it.
add_task(async function construct_widget() {
originalWindowWidth = window.outerWidth;
ok(
!navbar.hasAttribute("overflowing"),
"Should start construct_widget with a non-overflowing toolbar."
);
ok(
CustomizableUI.inDefaultState,
"Should start construct_widget in default state."
);
CustomizableUI.addWidgetToArea(kSidebarBtn, "nav-bar");
await waitForElementShown(document.getElementById(kSidebarBtn));
window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
await TestUtils.waitForCondition(() => {
return (
navbar.hasAttribute("overflowing") &&
document.getElementById(kSidebarBtn).getAttribute("overflowedItem") ==
"true"
);
});
ok(navbar.hasAttribute("overflowing"), "Should have an overflowing toolbar.");
ok(
!navbar.querySelector("#" + kSidebarBtn),
"Sidebar button should no longer be in the navbar"
);
let sidebarBtnNode = overflowList.querySelector("#" + kSidebarBtn);
ok(sidebarBtnNode, "Sidebar button should be overflowing");
ok(
sidebarBtnNode && sidebarBtnNode.getAttribute("overflowedItem") == "true",
"Sidebar button should have overflowedItem class"
);
let testBtnSpec = {
id: kTestBtn3,
label: "Overflowable widget test",
defaultArea: "nav-bar",
};
CustomizableUI.createWidget(testBtnSpec);
let testNode = overflowList.querySelector("#" + kTestBtn3);
ok(testNode, "Test button should be overflowing");
ok(
testNode && testNode.getAttribute("overflowedItem") == "true",
"Test button should have overflowedItem class"
);
CustomizableUI.destroyWidget(kTestBtn3);
testNode = document.getElementById(kTestBtn3);
ok(!testNode, "Test button should be gone");
CustomizableUI.createWidget(testBtnSpec);
testNode = overflowList.querySelector("#" + kTestBtn3);
ok(testNode, "Test button should be overflowing");
ok(
testNode && testNode.getAttribute("overflowedItem") == "true",
"Test button should have overflowedItem class"
);
CustomizableUI.removeWidgetFromArea(kTestBtn3);
testNode = document.getElementById(kTestBtn3);
ok(!testNode, "Test button should be gone");
CustomizableUI.destroyWidget(kTestBtn3);
CustomizableUI.removeWidgetFromArea(kSidebarBtn);
window.resizeTo(originalWindowWidth, window.outerHeight);
await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
});
add_task(async function insertBeforeFirstItemInOverflow() {
originalWindowWidth = window.outerWidth;
ok(
!navbar.hasAttribute("overflowing"),
"Should start insertBeforeFirstItemInOverflow with a non-overflowing toolbar."
);
ok(
CustomizableUI.inDefaultState,
"Should start insertBeforeFirstItemInOverflow in default state."
);
CustomizableUI.addWidgetToArea(
kLibraryButton,
"nav-bar",
CustomizableUI.getWidgetIdsInArea("nav-bar").indexOf(
"save-to-pocket-button"
)
);
let libraryButton = document.getElementById(kLibraryButton);
await waitForElementShown(libraryButton);
// Ensure nothing flexes to make the resize predictable:
navbar
.querySelectorAll("toolbarspring")
.forEach(s => CustomizableUI.removeWidgetFromArea(s.id));
let urlbar = document.getElementById("urlbar-container");
urlbar.style.minWidth = urlbar.getBoundingClientRect().width + "px";
// Negative number to make the window smaller by the difference between the left side of
// the item next to the library button and left side of the hamburger one.
// The width of the overflow button that needs to appear will then be enough to
// also hide the library button.
let resizeWidthToMakeLibraryLast =
libraryButton.nextElementSibling.getBoundingClientRect().left -
PanelUI.menuButton.parentNode.getBoundingClientRect().left +
10; // Leave some margin for the margins between buttons etc.;
info(
"Resizing to " +
resizeWidthToMakeLibraryLast +
" , waiting for library to overflow."
);
window.resizeBy(resizeWidthToMakeLibraryLast, 0);
await TestUtils.waitForCondition(() => {
return (
libraryButton.getAttribute("overflowedItem") == "true" &&
!libraryButton.previousElementSibling
);
});
let testBtnSpec = { id: kTestBtn4, label: "Overflowable widget test" };
let placementOfLibraryButton = CustomizableUI.getWidgetIdsInArea(
navbar.id
).indexOf(kLibraryButton);
CustomizableUI.createWidget(testBtnSpec);
CustomizableUI.addWidgetToArea(
kTestBtn4,
"nav-bar",
placementOfLibraryButton
);
let testNode = overflowList.querySelector("#" + kTestBtn4);
ok(testNode, "Test button should be overflowing");
ok(
testNode && testNode.getAttribute("overflowedItem") == "true",
"Test button should have overflowedItem class"
);
CustomizableUI.destroyWidget(kTestBtn4);
testNode = document.getElementById(kTestBtn4);
ok(!testNode, "Test button should be gone");
createDummyXULButton(kTestBtn5, "Test");
CustomizableUI.addWidgetToArea(
kTestBtn5,
"nav-bar",
placementOfLibraryButton
);
testNode = overflowList.querySelector("#" + kTestBtn5);
ok(testNode, "Test button should be overflowing");
ok(
testNode && testNode.getAttribute("overflowedItem") == "true",
"Test button should have overflowedItem class"
);
CustomizableUI.removeWidgetFromArea(kTestBtn5);
testNode && testNode.remove();
urlbar.style.removeProperty("min-width");
CustomizableUI.removeWidgetFromArea(kLibraryButton);
window.resizeTo(originalWindowWidth, window.outerHeight);
await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
await resetCustomization();
});
registerCleanupFunction(async function asyncCleanup() {
document.getElementById("urlbar-container").style.removeProperty("min-width");
window.resizeTo(originalWindowWidth, window.outerHeight);
await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
await resetCustomization();
});