Backed out changeset d26e7747cf69 (bug 1800417) for bc failures on browser_unified_extensions_overflowable_toolbar.js. CLOSED TREE

This commit is contained in:
Marian-Vasile Laza 2023-02-13 22:14:44 +02:00
Родитель b7d534ad1c
Коммит e39c51f7fd
6 изменённых файлов: 105 добавлений и 403 удалений

Просмотреть файл

@ -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;
}