зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset d26e7747cf69 (bug 1800417) for bc failures on browser_unified_extensions_overflowable_toolbar.js. CLOSED TREE
This commit is contained in:
Родитель
b7d534ad1c
Коммит
e39c51f7fd
|
@ -1258,21 +1258,16 @@ var gUnifiedExtensions = {
|
|||
lazy.ExtensionPermissions.addListener(this.permListener);
|
||||
|
||||
gNavToolbox.addEventListener("customizationstarting", this);
|
||||
CustomizableUI.addListener(this);
|
||||
|
||||
this._initialized = true;
|
||||
},
|
||||
|
||||
uninit() {
|
||||
if (!this._initialized) {
|
||||
return;
|
||||
if (this.permListener) {
|
||||
lazy.ExtensionPermissions.removeListener(this.permListener);
|
||||
this.permListener = null;
|
||||
}
|
||||
|
||||
lazy.ExtensionPermissions.removeListener(this.permListener);
|
||||
this.permListener = null;
|
||||
|
||||
gNavToolbox.removeEventListener("customizationstarting", this);
|
||||
CustomizableUI.removeListener(this);
|
||||
},
|
||||
|
||||
onLocationChange(browser, webProgress, _request, _uri, flags) {
|
||||
|
@ -1627,74 +1622,4 @@ var gUnifiedExtensions = {
|
|||
|
||||
this.updateAttention();
|
||||
},
|
||||
|
||||
onWidgetAdded(aWidgetId, aArea, aPosition) {
|
||||
// When we pin a widget to the toolbar from a narrow window, the widget
|
||||
// will be overflowed directly. In this case, we do not want to change the
|
||||
// class name since it is going to be changed by `onWidgetOverflow()`
|
||||
// below.
|
||||
if (CustomizableUI.getWidget(aWidgetId)?.forWindow(window)?.overflowed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const inPanel =
|
||||
CustomizableUI.getAreaType(aArea) !== CustomizableUI.TYPE_TOOLBAR;
|
||||
|
||||
this._updateWidgetClassName(aWidgetId, inPanel);
|
||||
},
|
||||
|
||||
onWidgetOverflow(aNode, aContainer) {
|
||||
// We register a CUI listener for each window so we make sure that we
|
||||
// handle the event for the right window here.
|
||||
if (window !== aNode.ownerGlobal) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._updateWidgetClassName(aNode.getAttribute("widget-id"), true);
|
||||
},
|
||||
|
||||
onWidgetUnderflow(aNode, aContainer) {
|
||||
// We register a CUI listener for each window so we make sure that we
|
||||
// handle the event for the right window here.
|
||||
if (window !== aNode.ownerGlobal) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._updateWidgetClassName(aNode.getAttribute("widget-id"), false);
|
||||
},
|
||||
|
||||
onAreaNodeRegistered(aArea, aContainer) {
|
||||
// We register a CUI listener for each window so we make sure that we
|
||||
// handle the event for the right window here.
|
||||
if (window !== aContainer.ownerGlobal) {
|
||||
return;
|
||||
}
|
||||
|
||||
const inPanel =
|
||||
CustomizableUI.getAreaType(aArea) !== CustomizableUI.TYPE_TOOLBAR;
|
||||
|
||||
for (const widgetId of CustomizableUI.getWidgetIdsInArea(aArea)) {
|
||||
this._updateWidgetClassName(widgetId, inPanel);
|
||||
}
|
||||
},
|
||||
|
||||
// This internal method is used to change some CSS classnames on the action
|
||||
// button of an extension (CUI) widget. When the widget is placed in the
|
||||
// panel, the action button should have the `.subviewbutton` class and not
|
||||
// the `.toolbarbutton-1` one. When NOT placed in the panel, it is the other
|
||||
// way around.
|
||||
_updateWidgetClassName(aWidgetId, inPanel) {
|
||||
if (!CustomizableUI.isWebExtensionWidget(aWidgetId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const node = CustomizableUI.getWidget(aWidgetId)?.forWindow(window)?.node;
|
||||
if (node) {
|
||||
const actionButton = node.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
actionButton.classList.toggle("subviewbutton", inPanel);
|
||||
actionButton.classList.toggle("toolbarbutton-1", !inPanel);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -219,7 +219,11 @@ this.browserAction = class extends ExtensionAPIPersistent {
|
|||
// Ensure the extension context menuitems are available by setting this
|
||||
// on all button children and the item.
|
||||
button.setAttribute("data-extensionid", extension.id);
|
||||
button.classList.add("unified-extensions-item-action-button");
|
||||
button.classList.add(
|
||||
"toolbarbutton-1",
|
||||
"unified-extensions-item-action-button",
|
||||
"subviewbutton"
|
||||
);
|
||||
|
||||
let contents = document.createXULElement("vbox");
|
||||
contents.classList.add("unified-extensions-item-contents");
|
||||
|
|
|
@ -1329,48 +1329,3 @@ add_task(async function test_temporary_access() {
|
|||
}
|
||||
);
|
||||
});
|
||||
|
||||
add_task(async function test_action_button_css_class_with_new_window() {
|
||||
const [extension] = createExtensions([
|
||||
{
|
||||
name: "an extension placed in the extensions panel",
|
||||
browser_action: {
|
||||
default_area: "menupanel",
|
||||
},
|
||||
},
|
||||
]);
|
||||
await extension.startup();
|
||||
|
||||
let aSecondWindow = await BrowserTestUtils.openNewBrowserWindow();
|
||||
await ensureMaximizedWindow(aSecondWindow);
|
||||
|
||||
// Open and close the extensions panel in the newly created window to build
|
||||
// the extensions panel and add the extension widget(s) to it.
|
||||
await openExtensionsPanel(aSecondWindow);
|
||||
await closeExtensionsPanel(aSecondWindow);
|
||||
|
||||
for (const { title, win } of [
|
||||
{ title: "current window", win: window },
|
||||
{ title: "second window", win: aSecondWindow },
|
||||
]) {
|
||||
const node = CustomizableUI.getWidget(
|
||||
AppUiTestInternals.getBrowserActionWidgetId(extension.id)
|
||||
).forWindow(win).node;
|
||||
|
||||
let actionButton = node.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
ok(
|
||||
actionButton.classList.contains("subviewbutton"),
|
||||
`${title} - expected .subviewbutton CSS class on the action button`
|
||||
);
|
||||
ok(
|
||||
!actionButton.classList.contains("toolbarbutton-1"),
|
||||
`${title} - expected no .toolbarbutton-1 CSS class on the action button`
|
||||
);
|
||||
}
|
||||
|
||||
await BrowserTestUtils.closeWindow(aSecondWindow);
|
||||
|
||||
await extension.unload();
|
||||
});
|
||||
|
|
|
@ -19,5 +19,4 @@ add_task(async function test_hide_panel_when_customizing() {
|
|||
CustomizableUI.dispatchToolboxEvent("customizationstarting", {});
|
||||
await panelHidden;
|
||||
Assert.equal(panel.state, "closed");
|
||||
CustomizableUI.dispatchToolboxEvent("aftercustomization", {});
|
||||
});
|
||||
|
|
|
@ -312,24 +312,14 @@ async function withWindowOverflowed(
|
|||
}
|
||||
}
|
||||
|
||||
async function verifyExtensionWidget(widget) {
|
||||
async function verifyExtensionWidget(win, widget) {
|
||||
Assert.ok(widget, "expected widget");
|
||||
|
||||
let actionButton = widget.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
let actionButton = widget.firstElementChild;
|
||||
Assert.ok(
|
||||
actionButton.classList.contains("unified-extensions-item-action-button"),
|
||||
"expected action class on the button"
|
||||
);
|
||||
ok(
|
||||
actionButton.classList.contains("subviewbutton"),
|
||||
"expected the .subviewbutton CSS class on the action button in the panel"
|
||||
);
|
||||
ok(
|
||||
!actionButton.classList.contains("toolbarbutton-1"),
|
||||
"expected no .toolbarbutton-1 CSS class on the action button in the panel"
|
||||
);
|
||||
|
||||
let menuButton = widget.lastElementChild;
|
||||
Assert.ok(
|
||||
|
@ -384,17 +374,17 @@ async function verifyExtensionWidget(widget) {
|
|||
);
|
||||
|
||||
Assert.equal(
|
||||
document.l10n.getAttributes(menuButton).id,
|
||||
win.document.l10n.getAttributes(menuButton).id,
|
||||
"unified-extensions-item-open-menu",
|
||||
"expected l10n id attribute for the extension"
|
||||
);
|
||||
Assert.deepEqual(
|
||||
Object.keys(document.l10n.getAttributes(menuButton).args),
|
||||
Object.keys(win.document.l10n.getAttributes(menuButton).args),
|
||||
["extensionName"],
|
||||
"expected l10n args attribute for the extension"
|
||||
);
|
||||
Assert.ok(
|
||||
document.l10n
|
||||
win.document.l10n
|
||||
.getAttributes(menuButton)
|
||||
.args.extensionName.startsWith("Extension "),
|
||||
"expected l10n args attribute to start with the correct name"
|
||||
|
@ -411,9 +401,10 @@ async function verifyExtensionWidget(widget) {
|
|||
* panel.
|
||||
*/
|
||||
add_task(async function test_overflowable_toolbar() {
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
let movedNode;
|
||||
|
||||
await withWindowOverflowed(window, {
|
||||
await withWindowOverflowed(win, {
|
||||
whenOverflowed: async (defaultList, unifiedExtensionList, extensionIDs) => {
|
||||
// Ensure that there are 5 items in the Unified Extensions overflow
|
||||
// list, and the default widgets should all be in the default overflow
|
||||
|
@ -438,13 +429,13 @@ add_task(async function test_overflowable_toolbar() {
|
|||
extensionIDs.includes(child.dataset.extensionid),
|
||||
`Unified Extensions overflow list should have ${child.dataset.extensionid}`
|
||||
);
|
||||
await verifyExtensionWidget(child);
|
||||
await verifyExtensionWidget(win, child, true);
|
||||
}
|
||||
|
||||
let extensionWidgetID = AppUiTestInternals.getBrowserActionWidgetId(
|
||||
extensionIDs.at(-1)
|
||||
);
|
||||
movedNode = CustomizableUI.getWidget(extensionWidgetID).forWindow(window)
|
||||
movedNode = CustomizableUI.getWidget(extensionWidgetID).forWindow(win)
|
||||
.node;
|
||||
Assert.equal(movedNode.getAttribute("cui-areatype"), "toolbar");
|
||||
|
||||
|
@ -469,10 +460,14 @@ add_task(async function test_overflowable_toolbar() {
|
|||
CustomizableUI.addWidgetToArea(movedNode.id, CustomizableUI.AREA_NAVBAR);
|
||||
},
|
||||
});
|
||||
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
|
||||
add_task(async function test_context_menu() {
|
||||
await withWindowOverflowed(window, {
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
|
||||
await withWindowOverflowed(win, {
|
||||
whenOverflowed: async (defaultList, unifiedExtensionList, extensionIDs) => {
|
||||
Assert.ok(
|
||||
unifiedExtensionList.children.length,
|
||||
|
@ -480,7 +475,7 @@ add_task(async function test_context_menu() {
|
|||
);
|
||||
|
||||
// Open the extension panel.
|
||||
await openExtensionsPanel();
|
||||
await openExtensionsPanel(win);
|
||||
|
||||
// Let's verify the context menus for the following extensions:
|
||||
//
|
||||
|
@ -492,7 +487,8 @@ add_task(async function test_context_menu() {
|
|||
const firstExtensionWidget = unifiedExtensionList.children[0];
|
||||
Assert.ok(firstExtensionWidget, "expected extension widget");
|
||||
let contextMenu = await openUnifiedExtensionsContextMenu(
|
||||
firstExtensionWidget.dataset.extensionid
|
||||
firstExtensionWidget.dataset.extensionid,
|
||||
win
|
||||
);
|
||||
Assert.ok(contextMenu, "expected a context menu");
|
||||
let visibleItems = getVisibleMenuItems(contextMenu);
|
||||
|
@ -519,13 +515,14 @@ add_task(async function test_context_menu() {
|
|||
"expected separator after last menu item created by the extension"
|
||||
);
|
||||
|
||||
await closeChromeContextMenu(contextMenu.id, null);
|
||||
await closeChromeContextMenu(contextMenu.id, null, win);
|
||||
|
||||
info("extension with browser action and a menu with submenu");
|
||||
const secondExtensionWidget = unifiedExtensionList.children[1];
|
||||
Assert.ok(secondExtensionWidget, "expected extension widget");
|
||||
contextMenu = await openUnifiedExtensionsContextMenu(
|
||||
secondExtensionWidget.dataset.extensionid
|
||||
secondExtensionWidget.dataset.extensionid,
|
||||
win
|
||||
);
|
||||
visibleItems = getVisibleMenuItems(contextMenu);
|
||||
is(visibleItems.length, 7, "expected 7 menu items");
|
||||
|
@ -539,7 +536,7 @@ add_task(async function test_context_menu() {
|
|||
// The number of items in the (main) context menu should remain the same.
|
||||
visibleItems = getVisibleMenuItems(contextMenu);
|
||||
is(visibleItems.length, 7, "expected 7 menu items");
|
||||
await closeChromeContextMenu(contextMenu.id, null);
|
||||
await closeChromeContextMenu(contextMenu.id, null, win);
|
||||
|
||||
info("extension with no browser action and no menu");
|
||||
// There is no context menu created by this extension, so there should
|
||||
|
@ -548,22 +545,27 @@ add_task(async function test_context_menu() {
|
|||
const thirdExtensionWidget = unifiedExtensionList.children[2];
|
||||
Assert.ok(thirdExtensionWidget, "expected extension widget");
|
||||
contextMenu = await openUnifiedExtensionsContextMenu(
|
||||
thirdExtensionWidget.dataset.extensionid
|
||||
thirdExtensionWidget.dataset.extensionid,
|
||||
win
|
||||
);
|
||||
Assert.ok(contextMenu, "expected a context menu");
|
||||
visibleItems = getVisibleMenuItems(contextMenu);
|
||||
is(visibleItems.length, 5, "expected 5 menu items");
|
||||
|
||||
await closeChromeContextMenu(contextMenu.id, null);
|
||||
await closeChromeContextMenu(contextMenu.id, null, win);
|
||||
|
||||
// We can close the unified extensions panel now.
|
||||
await closeExtensionsPanel();
|
||||
await closeExtensionsPanel(win);
|
||||
},
|
||||
});
|
||||
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
|
||||
add_task(async function test_message_deck() {
|
||||
await withWindowOverflowed(window, {
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
|
||||
await withWindowOverflowed(win, {
|
||||
whenOverflowed: async (defaultList, unifiedExtensionList, extensionIDs) => {
|
||||
Assert.ok(
|
||||
unifiedExtensionList.children.length,
|
||||
|
@ -579,14 +581,15 @@ add_task(async function test_message_deck() {
|
|||
|
||||
// Navigate to a page where `activeTab` is useful.
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "https://example.com/" },
|
||||
{ gBrowser: win.gBrowser, url: "https://example.com/" },
|
||||
async () => {
|
||||
// Open the extension panel.
|
||||
await openExtensionsPanel();
|
||||
await openExtensionsPanel(win);
|
||||
|
||||
info("verify message when focusing the action button");
|
||||
const item = getUnifiedExtensionsItem(
|
||||
firstExtensionWidget.dataset.extensionid
|
||||
firstExtensionWidget.dataset.extensionid,
|
||||
win
|
||||
);
|
||||
Assert.ok(item, "expected an item for the extension");
|
||||
|
||||
|
@ -606,7 +609,7 @@ add_task(async function test_message_deck() {
|
|||
Assert.ok(messageDeck, "expected message deck");
|
||||
is(
|
||||
messageDeck.selectedIndex,
|
||||
gUnifiedExtensions.MESSAGE_DECK_INDEX_DEFAULT,
|
||||
win.gUnifiedExtensions.MESSAGE_DECK_INDEX_DEFAULT,
|
||||
"expected selected message in the deck to be the default message"
|
||||
);
|
||||
|
||||
|
@ -614,7 +617,7 @@ add_task(async function test_message_deck() {
|
|||
".unified-extensions-item-message-default"
|
||||
);
|
||||
Assert.deepEqual(
|
||||
document.l10n.getAttributes(defaultMessage),
|
||||
win.document.l10n.getAttributes(defaultMessage),
|
||||
{ id: "origin-controls-state-when-clicked", args: null },
|
||||
"expected correct l10n attributes for the default message"
|
||||
);
|
||||
|
@ -627,7 +630,7 @@ add_task(async function test_message_deck() {
|
|||
".unified-extensions-item-message-hover"
|
||||
);
|
||||
Assert.deepEqual(
|
||||
document.l10n.getAttributes(hoverMessage),
|
||||
win.document.l10n.getAttributes(hoverMessage),
|
||||
{ id: "origin-controls-state-hover-run-visit-only", args: null },
|
||||
"expected correct l10n attributes for the hover message"
|
||||
);
|
||||
|
@ -640,7 +643,7 @@ add_task(async function test_message_deck() {
|
|||
".unified-extensions-item-message-hover-menu-button"
|
||||
);
|
||||
Assert.deepEqual(
|
||||
document.l10n.getAttributes(hoverMenuButtonMessage),
|
||||
win.document.l10n.getAttributes(hoverMenuButtonMessage),
|
||||
{ id: "unified-extensions-item-message-manage", args: null },
|
||||
"expected correct l10n attributes for the message when hovering the menu button"
|
||||
);
|
||||
|
@ -651,42 +654,42 @@ add_task(async function test_message_deck() {
|
|||
|
||||
// 1. Focus the action button of the first extension in the panel.
|
||||
let focused = BrowserTestUtils.waitForEvent(actionButton, "focus");
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
await focused;
|
||||
is(
|
||||
actionButton,
|
||||
document.activeElement,
|
||||
win.document.activeElement,
|
||||
"expected action button of the first extension item to be focused"
|
||||
);
|
||||
is(
|
||||
messageDeck.selectedIndex,
|
||||
gUnifiedExtensions.MESSAGE_DECK_INDEX_HOVER,
|
||||
win.gUnifiedExtensions.MESSAGE_DECK_INDEX_HOVER,
|
||||
"expected selected message in the deck to be the hover message"
|
||||
);
|
||||
|
||||
// 2. Focus the menu button, causing the action button to lose focus.
|
||||
focused = BrowserTestUtils.waitForEvent(menuButton, "focus");
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
EventUtils.synthesizeKey("VK_TAB", {}, win);
|
||||
await focused;
|
||||
is(
|
||||
menuButton,
|
||||
document.activeElement,
|
||||
win.document.activeElement,
|
||||
"expected menu button of the first extension item to be focused"
|
||||
);
|
||||
is(
|
||||
messageDeck.selectedIndex,
|
||||
gUnifiedExtensions.MESSAGE_DECK_INDEX_MENU_HOVER,
|
||||
win.gUnifiedExtensions.MESSAGE_DECK_INDEX_MENU_HOVER,
|
||||
"expected selected message in the deck to be the message when focusing the menu button"
|
||||
);
|
||||
|
||||
await closeExtensionsPanel();
|
||||
await closeExtensionsPanel(win);
|
||||
|
||||
info("verify message when hovering the action button");
|
||||
await openExtensionsPanel();
|
||||
await openExtensionsPanel(win);
|
||||
|
||||
is(
|
||||
messageDeck.selectedIndex,
|
||||
gUnifiedExtensions.MESSAGE_DECK_INDEX_DEFAULT,
|
||||
win.gUnifiedExtensions.MESSAGE_DECK_INDEX_DEFAULT,
|
||||
"expected selected message in the deck to be the default message"
|
||||
);
|
||||
|
||||
|
@ -695,32 +698,40 @@ add_task(async function test_message_deck() {
|
|||
actionButton,
|
||||
"mouseover"
|
||||
);
|
||||
EventUtils.synthesizeMouseAtCenter(actionButton, {
|
||||
type: "mouseover",
|
||||
});
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
actionButton,
|
||||
{ type: "mouseover" },
|
||||
win
|
||||
);
|
||||
await hovered;
|
||||
is(
|
||||
messageDeck.selectedIndex,
|
||||
gUnifiedExtensions.MESSAGE_DECK_INDEX_HOVER,
|
||||
win.gUnifiedExtensions.MESSAGE_DECK_INDEX_HOVER,
|
||||
"expected selected message in the deck to be the hover message"
|
||||
);
|
||||
|
||||
// 2. Hover the menu button, causing the action button to no longer
|
||||
// be hovered.
|
||||
hovered = BrowserTestUtils.waitForEvent(menuButton, "mouseover");
|
||||
EventUtils.synthesizeMouseAtCenter(menuButton, { type: "mouseover" });
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
menuButton,
|
||||
{ type: "mouseover" },
|
||||
win
|
||||
);
|
||||
await hovered;
|
||||
is(
|
||||
messageDeck.selectedIndex,
|
||||
gUnifiedExtensions.MESSAGE_DECK_INDEX_MENU_HOVER,
|
||||
win.gUnifiedExtensions.MESSAGE_DECK_INDEX_MENU_HOVER,
|
||||
"expected selected message in the deck to be the message when hovering the menu button"
|
||||
);
|
||||
|
||||
await closeExtensionsPanel();
|
||||
await closeExtensionsPanel(win);
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -729,11 +740,11 @@ add_task(async function test_message_deck() {
|
|||
* button is put into the addons panel overflow list.
|
||||
*/
|
||||
add_task(async function test_pinning_to_toolbar_when_overflowed() {
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
let movedNode;
|
||||
let extensionWidgetID;
|
||||
let actionButton;
|
||||
|
||||
await withWindowOverflowed(window, {
|
||||
await withWindowOverflowed(win, {
|
||||
beforeOverflowed: async extensionIDs => {
|
||||
// Before we overflow the toolbar, let's move the last item to the addons
|
||||
// panel.
|
||||
|
@ -741,45 +752,15 @@ add_task(async function test_pinning_to_toolbar_when_overflowed() {
|
|||
extensionIDs.at(-1)
|
||||
);
|
||||
|
||||
movedNode = CustomizableUI.getWidget(extensionWidgetID).forWindow(window)
|
||||
movedNode = CustomizableUI.getWidget(extensionWidgetID).forWindow(win)
|
||||
.node;
|
||||
|
||||
actionButton = movedNode.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
ok(
|
||||
actionButton.classList.contains("toolbarbutton-1"),
|
||||
"expected .toolbarbutton-1 CSS class on the action button in the navbar"
|
||||
);
|
||||
ok(
|
||||
!actionButton.classList.contains("subviewbutton"),
|
||||
"expected no .subviewbutton CSS class on the action button in the navbar"
|
||||
);
|
||||
|
||||
CustomizableUI.addWidgetToArea(
|
||||
extensionWidgetID,
|
||||
CustomizableUI.AREA_ADDONS
|
||||
);
|
||||
|
||||
ok(
|
||||
actionButton.classList.contains("subviewbutton"),
|
||||
"expected .subviewbutton CSS class on the action button in the panel"
|
||||
);
|
||||
ok(
|
||||
!actionButton.classList.contains("toolbarbutton-1"),
|
||||
"expected no .toolbarbutton-1 CSS class on the action button in the panel"
|
||||
);
|
||||
},
|
||||
whenOverflowed: async (defaultList, unifiedExtensionList, extensionIDs) => {
|
||||
ok(
|
||||
actionButton.classList.contains("subviewbutton"),
|
||||
"expected .subviewbutton CSS class on the action button in the panel"
|
||||
);
|
||||
ok(
|
||||
!actionButton.classList.contains("toolbarbutton-1"),
|
||||
"expected no .toolbarbutton-1 CSS class on the action button in the panel"
|
||||
);
|
||||
|
||||
// Now that the window is overflowed, let's move the widget in the addons
|
||||
// panel back to the navbar. This should cause the widget to overflow back
|
||||
// into the addons panel.
|
||||
|
@ -795,17 +776,10 @@ add_task(async function test_pinning_to_toolbar_when_overflowed() {
|
|||
unifiedExtensionList,
|
||||
"Should have overflowed the extension button to the right list."
|
||||
);
|
||||
|
||||
ok(
|
||||
actionButton.classList.contains("subviewbutton"),
|
||||
"expected no .subviewbutton CSS class on the action button in the panel"
|
||||
);
|
||||
ok(
|
||||
!actionButton.classList.contains("toolbarbutton-1"),
|
||||
"expected .toolbarbutton-1 CSS class on the action button in the panel"
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
await BrowserTestUtils.closeWindow(win);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -815,10 +789,11 @@ add_task(async function test_pinning_to_toolbar_when_overflowed() {
|
|||
* extension into the dedicated addons area of the panel, and that the item
|
||||
* then does not underflow.
|
||||
*/
|
||||
add_task(async function test_unpin_overflowed_widget() {
|
||||
add_task(async function test_() {
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
let extensionID;
|
||||
|
||||
await withWindowOverflowed(window, {
|
||||
await withWindowOverflowed(win, {
|
||||
whenOverflowed: async (defaultList, unifiedExtensionList, extensionIDs) => {
|
||||
const firstExtensionWidget = unifiedExtensionList.children[0];
|
||||
Assert.ok(firstExtensionWidget, "expected an extension widget");
|
||||
|
@ -826,7 +801,7 @@ add_task(async function test_unpin_overflowed_widget() {
|
|||
|
||||
let movedNode = CustomizableUI.getWidget(
|
||||
firstExtensionWidget.id
|
||||
).forWindow(window).node;
|
||||
).forWindow(win).node;
|
||||
Assert.equal(
|
||||
movedNode.getAttribute("cui-areatype"),
|
||||
"toolbar",
|
||||
|
@ -836,23 +811,15 @@ add_task(async function test_unpin_overflowed_widget() {
|
|||
movedNode.hasAttribute("overflowedItem"),
|
||||
"expected extension widget to be overflowed"
|
||||
);
|
||||
let actionButton = movedNode.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
ok(
|
||||
actionButton.classList.contains("subviewbutton"),
|
||||
"expected the .subviewbutton CSS class on the action button in the panel"
|
||||
);
|
||||
ok(
|
||||
!actionButton.classList.contains("toolbarbutton-1"),
|
||||
"expected no .toolbarbutton-1 CSS class on the action button in the panel"
|
||||
);
|
||||
|
||||
// Open the panel, then the context menu of the extension widget, verify
|
||||
// the 'Pin to Toolbar' menu item, then click on this menu item to
|
||||
// uncheck it (i.e. unpin the extension).
|
||||
await openExtensionsPanel();
|
||||
const contextMenu = await openUnifiedExtensionsContextMenu(extensionID);
|
||||
await openExtensionsPanel(win);
|
||||
const contextMenu = await openUnifiedExtensionsContextMenu(
|
||||
extensionID,
|
||||
win
|
||||
);
|
||||
Assert.ok(contextMenu, "expected a context menu");
|
||||
|
||||
const pinToToolbar = contextMenu.querySelector(
|
||||
|
@ -872,7 +839,7 @@ add_task(async function test_unpin_overflowed_widget() {
|
|||
// Uncheck "Pin to Toolbar" menu item. Clicking a menu item in the
|
||||
// context menu closes the unified extensions panel automatically.
|
||||
const hidden = BrowserTestUtils.waitForEvent(
|
||||
gUnifiedExtensions.panel,
|
||||
win.gUnifiedExtensions.panel,
|
||||
"popuphidden",
|
||||
true
|
||||
);
|
||||
|
@ -896,162 +863,15 @@ add_task(async function test_unpin_overflowed_widget() {
|
|||
);
|
||||
},
|
||||
afterUnderflowed: async () => {
|
||||
await openExtensionsPanel();
|
||||
await openExtensionsPanel(win);
|
||||
|
||||
const item = getUnifiedExtensionsItem(extensionID);
|
||||
const item = getUnifiedExtensionsItem(extensionID, win);
|
||||
Assert.ok(
|
||||
item,
|
||||
"expected extension widget to be listed in the unified extensions panel"
|
||||
);
|
||||
let actionButton = item.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
ok(
|
||||
actionButton.classList.contains("subviewbutton"),
|
||||
"expected the .subviewbutton CSS class on the action button in the panel"
|
||||
);
|
||||
ok(
|
||||
!actionButton.classList.contains("toolbarbutton-1"),
|
||||
"expected no .toolbarbutton-1 CSS class on the action button in the panel"
|
||||
);
|
||||
|
||||
await closeExtensionsPanel();
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_overflow_with_a_second_window() {
|
||||
// Open a second window that will stay maximized. We want to be sure that
|
||||
// overflowing a widget in one window isn't going to affect the other window
|
||||
// since we have an instance (of a CUI widget) per window.
|
||||
let win = await BrowserTestUtils.openNewBrowserWindow();
|
||||
await ensureMaximizedWindow(win);
|
||||
|
||||
let extensionWidgetID;
|
||||
let aNode;
|
||||
let aNodeInSecondWindow;
|
||||
|
||||
await withWindowOverflowed(window, {
|
||||
beforeOverflowed: async extensionIDs => {
|
||||
extensionWidgetID = AppUiTestInternals.getBrowserActionWidgetId(
|
||||
extensionIDs.at(-1)
|
||||
);
|
||||
|
||||
// This is the DOM node for the current window that is overflowed.
|
||||
aNode = CustomizableUI.getWidget(extensionWidgetID).forWindow(window)
|
||||
.node;
|
||||
Assert.ok(
|
||||
!aNode.hasAttribute("overflowedItem"),
|
||||
"expected extension widget to NOT be overflowed"
|
||||
);
|
||||
|
||||
let actionButton = aNode.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
ok(
|
||||
actionButton.classList.contains("toolbarbutton-1"),
|
||||
"expected .toolbarbutton-1 CSS class on the action button"
|
||||
);
|
||||
ok(
|
||||
!actionButton.classList.contains("subviewbutton"),
|
||||
"expected no .subviewbutton CSS class on the action button"
|
||||
);
|
||||
|
||||
// This is the DOM node of the same CUI widget but in the maximized
|
||||
// window opened before.
|
||||
aNodeInSecondWindow = CustomizableUI.getWidget(
|
||||
extensionWidgetID
|
||||
).forWindow(win).node;
|
||||
|
||||
let actionButtonInSecondWindow = aNodeInSecondWindow.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
ok(
|
||||
actionButtonInSecondWindow.classList.contains("toolbarbutton-1"),
|
||||
"expected .toolbarbutton-1 CSS class on the action button in the second window"
|
||||
);
|
||||
ok(
|
||||
!actionButtonInSecondWindow.classList.contains("subviewbutton"),
|
||||
"expected no .subviewbutton CSS class on the action button in the second window"
|
||||
);
|
||||
},
|
||||
whenOverflowed: async (defaultList, unifiedExtensionList, extensionIDs) => {
|
||||
// The DOM node should have been overflowed.
|
||||
Assert.ok(
|
||||
aNode.hasAttribute("overflowedItem"),
|
||||
"expected extension widget to be overflowed"
|
||||
);
|
||||
Assert.equal(
|
||||
aNode.getAttribute("widget-id"),
|
||||
extensionWidgetID,
|
||||
"expected the CUI widget ID to be set on the DOM node"
|
||||
);
|
||||
|
||||
// When the node is overflowed, we swap the CSS class on the action
|
||||
// button since the node is now placed in the extensions panel.
|
||||
let actionButton = aNode.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
ok(
|
||||
actionButton.classList.contains("subviewbutton"),
|
||||
"expected the .subviewbutton CSS class on the action button"
|
||||
);
|
||||
ok(
|
||||
!actionButton.classList.contains("toolbarbutton-1"),
|
||||
"expected no .toolbarbutton-1 CSS class on the action button"
|
||||
);
|
||||
|
||||
// The DOM node in the other window should not have been overflowed.
|
||||
Assert.ok(
|
||||
!aNodeInSecondWindow.hasAttribute("overflowedItem"),
|
||||
"expected extension widget to NOT be overflowed in the other window"
|
||||
);
|
||||
Assert.equal(
|
||||
aNodeInSecondWindow.getAttribute("widget-id"),
|
||||
extensionWidgetID,
|
||||
"expected the CUI widget ID to be set on the DOM node"
|
||||
);
|
||||
|
||||
// We expect no CSS class changes for the node in the other window.
|
||||
let actionButtonInSecondWindow = aNodeInSecondWindow.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
ok(
|
||||
actionButtonInSecondWindow.classList.contains("toolbarbutton-1"),
|
||||
"expected .toolbarbutton-1 CSS class on the action button in the second window"
|
||||
);
|
||||
ok(
|
||||
!actionButtonInSecondWindow.classList.contains("subviewbutton"),
|
||||
"expected no .subviewbutton CSS class on the action button in the second window"
|
||||
);
|
||||
},
|
||||
afterUnderflowed: async () => {
|
||||
// After underflow, we expect the CSS class on the action button of the
|
||||
// DOM node of the current window to be updated.
|
||||
let actionButton = aNode.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
ok(
|
||||
actionButton.classList.contains("toolbarbutton-1"),
|
||||
"expected .toolbarbutton-1 CSS class on the action button in the panel"
|
||||
);
|
||||
ok(
|
||||
!actionButton.classList.contains("subviewbutton"),
|
||||
"expected no .subviewbutton CSS class on the action button in the panel"
|
||||
);
|
||||
|
||||
// The DOM node of the other window should not be changed.
|
||||
let actionButtonInSecondWindow = aNodeInSecondWindow.querySelector(
|
||||
".unified-extensions-item-action-button"
|
||||
);
|
||||
ok(
|
||||
actionButtonInSecondWindow.classList.contains("toolbarbutton-1"),
|
||||
"expected .toolbarbutton-1 CSS class on the action button in the second window"
|
||||
);
|
||||
ok(
|
||||
!actionButtonInSecondWindow.classList.contains("subviewbutton"),
|
||||
"expected no .subviewbutton CSS class on the action button in the second window"
|
||||
);
|
||||
await closeExtensionsPanel(win);
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -38,11 +38,11 @@ unified-extensions-item {
|
|||
|
||||
/* On the main unified extensions button, we draw the attention on the icon element. */
|
||||
#unified-extensions-button[attention] > .toolbarbutton-icon,
|
||||
/* For extension widgets placed in a toolbar, we use the stack element
|
||||
* (containing the icon) of the action button to draw the attention dot.
|
||||
/* For extension widgets placed in a toolbar, we use the stack element (containing the icon)
|
||||
* of the action button to draw the attention dot.
|
||||
* Otherwise (in the extensions panel), we use the action button itself. */
|
||||
.unified-extensions-item[attention] > .unified-extensions-item-action-button.toolbarbutton-1 > .toolbarbutton-badge-stack,
|
||||
.unified-extensions-item[attention] > .unified-extensions-item-action-button.subviewbutton {
|
||||
toolbar .unified-extensions-item[attention] > .unified-extensions-item-action-button > .toolbarbutton-badge-stack,
|
||||
#unified-extensions-panel .unified-extensions-item[attention] > .unified-extensions-item-action-button {
|
||||
background-image: radial-gradient(circle, var(--uei-button-attention-dot-color), var(--uei-button-attention-dot-color) 2px, transparent 2px);
|
||||
background-size: var(--uei-attention-dot-size) var(--uei-attention-dot-size);
|
||||
background-repeat: no-repeat;
|
||||
|
@ -50,17 +50,17 @@ unified-extensions-item {
|
|||
|
||||
/* Adjust attention dots position in the toolbar. */
|
||||
#unified-extensions-button[attention] > .toolbarbutton-icon,
|
||||
.unified-extensions-item[attention] > .unified-extensions-item-action-button.toolbarbutton-1 > .toolbarbutton-badge-stack {
|
||||
toolbar .unified-extensions-item[attention] > .unified-extensions-item-action-button > .toolbarbutton-badge-stack {
|
||||
background-position: center bottom calc(var(--toolbarbutton-inner-padding) / 2 - var(--uei-attention-dot-size) / 2);
|
||||
}
|
||||
|
||||
/* Adjust attention dots position in the unified extensions panel. */
|
||||
.unified-extensions-item[attention] > .unified-extensions-item-action-button.subviewbutton {
|
||||
#unified-extensions-panel .unified-extensions-item[attention] > .unified-extensions-item-action-button {
|
||||
background-position: left var(--uei-dot-horizontal-position-in-panel) bottom var(--uei-dot-vertical-position-in-panel);
|
||||
}
|
||||
|
||||
/* Adjust attention dots position in the unified extensions panel for RTL. */
|
||||
.unified-extensions-item[attention] > .unified-extensions-item-action-button.subviewbutton:-moz-locale-dir(rtl) {
|
||||
#unified-extensions-panel .unified-extensions-item[attention] > .unified-extensions-item-action-button:-moz-locale-dir(rtl) {
|
||||
background-position-x: right var(--uei-dot-horizontal-position-in-panel);
|
||||
}
|
||||
|
||||
|
@ -80,19 +80,19 @@ unified-extensions-item {
|
|||
color: var(--panel-description-color);
|
||||
}
|
||||
|
||||
.unified-extensions-item-action-button[disabled] > .unified-extensions-item-icon {
|
||||
.unified-extensions-item-action-button[disabled] .unified-extensions-item-icon {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.unified-extensions-item-icon,
|
||||
.unified-extensions-item .webextension-browser-action.subviewbutton > .toolbarbutton-badge-stack > .toolbarbutton-icon {
|
||||
#unified-extensions-panel .unified-extensions-item .webextension-browser-action > .toolbarbutton-badge-stack > .toolbarbutton-icon {
|
||||
height: var(--uei-icon-size);
|
||||
width: var(--uei-icon-size);
|
||||
}
|
||||
|
||||
/* The first selector is for the custom elements icon, which appears only in the UEP. */
|
||||
.unified-extensions-item-icon,
|
||||
.unified-extensions-item .webextension-browser-action.subviewbutton > .toolbarbutton-badge-stack {
|
||||
#unified-extensions-panel .unified-extensions-item .webextension-browser-action > .toolbarbutton-badge-stack {
|
||||
margin-inline-end: 6px;
|
||||
}
|
||||
|
||||
|
@ -130,12 +130,12 @@ unified-extensions-item {
|
|||
|
||||
/* --- browser action CUI widget styles --- */
|
||||
|
||||
/* Hide the menu button and the unified extensions content when the extension
|
||||
* item is placed on the toolbar. */
|
||||
.unified-extensions-item[cui-areatype="toolbar"]:not([overflowedItem="true"]) :is(
|
||||
.unified-extensions-item-menu-button,
|
||||
.unified-extensions-item-contents
|
||||
) {
|
||||
toolbar toolbaritem.unified-extensions-item .unified-extensions-item-menu-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide unified extensions content by default. */
|
||||
toolbar .unified-extensions-item .unified-extensions-item-contents {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -148,8 +148,7 @@ toolbaritem.unified-extensions-item .unified-extensions-item-menu-button.subview
|
|||
|
||||
/* --- browser action CUI widget styles in the extensions panel --- */
|
||||
|
||||
/* Align CUI widgets with the custom elements in the unified extensions panel,
|
||||
* especially when the widgets overflow in the panel. */
|
||||
/* Align CUI widgets with the custom elements in the unified extensions panel. */
|
||||
#unified-extensions-panel toolbaritem.unified-extensions-item {
|
||||
max-width: max-content;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче