commit 0476dbcf5bb1d0a774ccd4259065ba8ec5d057a6
parent d7e949fc3321dac3ffaf646e9291df903ea1fd0f
Author: DJ <dj@walker.dev>
Date: Thu, 18 Dec 2025 18:34:24 +0000
Bug 2000063 - unify show/hide behavior for tab and tab group panels. r=sthompson,tabbrowser-reviewers,nsharpley,places-reviewers,mak
Differential Revision: https://phabricator.services.mozilla.com/D273500
Diffstat:
9 files changed, 246 insertions(+), 159 deletions(-)
diff --git a/browser/components/places/tests/browser/browser.toml b/browser/components/places/tests/browser/browser.toml
@@ -11,6 +11,11 @@ support-files = [
"sidebarpanels_click_test_page.html",
"keyword_form.html",
]
+prefs = [
+ # Disable tab previews as some tests click on the toolbar.
+ "browser.tabs.hoverPreview.enabled=false",
+ "browser.tabs.groups.hoverPreview.enabled=false",
+]
["browser_addBookmarkForFrame.js"]
skip-if = [
diff --git a/browser/components/sidebar/browser-sidebar.js b/browser/components/sidebar/browser-sidebar.js
@@ -2295,18 +2295,12 @@ var SidebarController = {
switch (e.type) {
case "popupshown":
/* Temporarily remove MousePosTracker listener when a context menu is open */
- if (
- e.composedTarget.id !== "tab-preview-panel" &&
- e.composedTarget.tagName !== "tooltip"
- ) {
+ if (e.composedTarget.tagName !== "tooltip") {
this._addHoverStateBlocker();
}
break;
case "popuphidden":
- if (
- e.composedTarget.id !== "tab-preview-panel" &&
- e.composedTarget.tagName !== "tooltip"
- ) {
+ if (e.composedTarget.tagName !== "tooltip") {
await this._removeHoverStateBlocker();
}
break;
diff --git a/browser/components/tabbrowser/content/drag-and-drop.js b/browser/components/tabbrowser/content/drag-and-drop.js
@@ -136,7 +136,7 @@
// Pinned tabs in expanded vertical mode are on a grid format and require
// different logic to drag and drop.
- if (this._isContainerVerticalPinnedGrid(draggedTab)) {
+ if (this._tabbrowserTabs.isContainerVerticalPinnedGrid(draggedTab)) {
this._animateExpandedPinnedTabMove(event);
return;
}
@@ -300,7 +300,7 @@
let isPinned = draggedTab.pinned;
let numPinned = gBrowser.pinnedTabCount;
- if (this._isContainerVerticalPinnedGrid(draggedTab)) {
+ if (this._tabbrowserTabs.isContainerVerticalPinnedGrid(draggedTab)) {
// Update both translate axis for pinned vertical expanded tabs
if (oldTranslateX > 0 && translateOffsetX > tabWidth / 2) {
newTranslateX += tabWidth;
@@ -385,7 +385,7 @@
!isSplitViewWrapper(draggedTab) &&
!shouldPin &&
!shouldUnpin;
- if (this._isContainerVerticalPinnedGrid(draggedTab)) {
+ if (this._tabbrowserTabs.isContainerVerticalPinnedGrid(draggedTab)) {
shouldTranslate &&=
(oldTranslateX && oldTranslateX != newTranslateX) ||
(oldTranslateY && oldTranslateY != newTranslateY);
@@ -857,15 +857,6 @@
return target;
}
- _isContainerVerticalPinnedGrid(tab) {
- return (
- this._tabbrowserTabs.verticalMode &&
- tab.pinned &&
- this._tabbrowserTabs.hasAttribute("expanded") &&
- !this._tabbrowserTabs.expandOnHover
- );
- }
-
#isMovingTab() {
return this._tabbrowserTabs.hasAttribute("movingtab");
}
@@ -954,7 +945,7 @@
// Temporarily disable MousePosTracker while dragging
MousePosTracker.removeListener(document.defaultView.SidebarController);
}
- if (this._isContainerVerticalPinnedGrid(tab)) {
+ if (this._tabbrowserTabs.isContainerVerticalPinnedGrid(tab)) {
// In expanded vertical mode, the max number of pinned tabs per row is dynamic
// Set this before adjusting dragged tab's position
let pinnedTabs = this._tabbrowserTabs.visibleTabs.slice(
@@ -1191,7 +1182,7 @@
let isPinned = tab.pinned;
let numPinned = gBrowser.pinnedTabCount;
let dragAndDropElements = this._tabbrowserTabs.dragAndDropElements;
- let isGrid = this._isContainerVerticalPinnedGrid(tab);
+ let isGrid = this._tabbrowserTabs.isContainerVerticalPinnedGrid(tab);
let periphery = document.getElementById(
"tabbrowser-arrowscrollbox-periphery"
);
diff --git a/browser/components/tabbrowser/content/tab-hover-preview.mjs b/browser/components/tabbrowser/content/tab-hover-preview.mjs
@@ -19,11 +19,11 @@ ChromeUtils.defineESModuleGetters(lazy, {
// strip.
const ZERO_DELAY_ACTIVATION_TIME = 300;
-// Denotes the amount of time (in ms) that the tab group hover preview panel
-// will remain open after the user's mouse leaves the tab group label. This
-// is necessary to allow the user to move their mouse between the tab group
-// label and the open panel without having it disappear before they get there.
-const TAB_GROUP_PANEL_STICKY_TIME = 100;
+// Denotes the amount of time (in ms) that a hover preview panel will remain
+// open after the user's mouse leaves its anchor element. This is necessary to
+// allow the user to move their mouse between the anchor (tab or group label)
+// and the open panel without having it disappear before they get there.
+const HOVER_PANEL_STICKY_TIME = 100;
/**
* Shared module that contains logic for the tab hover preview (THP) and tab
@@ -36,6 +36,12 @@ export default class TabHoverPanelSet {
/** @type {Set<HTMLElement>} */
#openPopups;
+ /** @type {WeakMap<HoverPanel, number>} */
+ #deactivateTimers;
+
+ /** @type {HoverPanel|null} */
+ #activePanel;
+
constructor(win) {
XPCOMUtils.defineLazyPreferenceGetter(
this,
@@ -45,6 +51,8 @@ export default class TabHoverPanelSet {
);
this.#win = win;
+ this.#deactivateTimers = new WeakMap();
+ this.#activePanel = null;
this.panelOpener = new TabPreviewPanelTimedFunction(
ZERO_DELAY_ACTIVATION_TIME,
@@ -79,18 +87,14 @@ export default class TabHoverPanelSet {
}
if (this.#win.gBrowser.isTab(tabOrGroup)) {
- if (this.tabGroupPanel.isActive) {
- this.tabGroupPanel.deactivate({ force: true });
- }
+ this.#setActivePanel(this.tabPanel);
this.tabPanel.activate(tabOrGroup);
} else if (this.#win.gBrowser.isTabGroup(tabOrGroup)) {
if (!tabOrGroup.collapsed) {
return;
}
- if (this.tabPanel.isActive) {
- this.tabPanel.deactivate();
- }
+ this.#setActivePanel(this.tabGroupPanel);
this.tabGroupPanel.activate(tabOrGroup);
} else {
throw new Error("Received activate call from unknown element");
@@ -104,13 +108,8 @@ export default class TabHoverPanelSet {
* `tabOrGroup` is a tab group, the group preview will be deactivated.
* If neither, both are deactivated.
*
- * The tab group panel deactivation contains special logic which keeps it
- * open for a specified interval, and then checks the hover state of the tab
- * group label and the panel itself, cancelling deactivation if either is
- * being hovered over. This is necessary to allow a user to move the mouse
- * between the group and the panel without experiencing jittery behaviour.
- * Calling functions can pass `force` to the options dict to override this
- * if necessary.
+ * Panels linger briefly to allow the mouse to travel between the anchor and
+ * panel; passing `force` skips that delay.
*
* @param {MozTabbrowserTab|MozTabbrowserTabGroup|null} tabOrGroup - The tab or group to activate the panel on.
* @param {bool} [options.force] - If true, force immediate deactivation of the tab group panel.
@@ -121,7 +120,7 @@ export default class TabHoverPanelSet {
}
if (this.#win.gBrowser.isTab(tabOrGroup) || !tabOrGroup) {
- this.tabPanel.deactivate(tabOrGroup);
+ this.tabPanel.deactivate(tabOrGroup, { force });
}
if (this.#win.gBrowser.isTabGroup(tabOrGroup) || !tabOrGroup) {
@@ -129,6 +128,51 @@ export default class TabHoverPanelSet {
}
}
+ #setActivePanel(panel) {
+ if (this.#activePanel && this.#activePanel != panel) {
+ this.requestDeactivate(this.#activePanel, { force: true });
+ }
+
+ this.#activePanel = panel;
+ this.#clearDeactivateTimer(panel);
+ }
+
+ requestDeactivate(panel, { force = false } = {}) {
+ this.#clearDeactivateTimer(panel);
+ if (force) {
+ this.#doDeactivate(panel);
+ return;
+ }
+
+ const timer = this.#win.setTimeout(() => {
+ this.#deactivateTimers.delete(panel);
+ if (panel.hoverTargets?.some(t => t.matches(":hover"))) {
+ return;
+ }
+ this.#doDeactivate(panel);
+ }, HOVER_PANEL_STICKY_TIME);
+ this.#deactivateTimers.set(panel, timer);
+ }
+
+ #clearDeactivateTimer(panel) {
+ const timer = this.#deactivateTimers.get(panel);
+ if (timer) {
+ this.#win.clearTimeout(timer);
+ this.#deactivateTimers.delete(panel);
+ }
+ }
+
+ #doDeactivate(panel) {
+ panel.onBeforeHide();
+ panel.panelElement.hidePopup();
+ this.panelOpener.clear(panel);
+ this.panelOpener.setZeroDelay();
+
+ if (this.#activePanel == panel) {
+ this.#activePanel = null;
+ }
+ }
+
shouldActivate() {
return (
// All other popups are closed.
@@ -174,24 +218,41 @@ export default class TabHoverPanelSet {
}
}
-class Panel {
+class HoverPanel {
+ /**
+ * @param {XULPopupElement} panelElement
+ * @param {TabHoverPanelSet} panelSet
+ */
+ constructor(panelElement, panelSet) {
+ this.panelElement = panelElement;
+ this.panelSet = panelSet;
+ this.win = this.panelElement.ownerGlobal;
+ }
+
get isActive() {
return this.panelElement.state == "open";
}
+
+ deactivate({ force = false } = {}) {
+ this.panelSet.requestDeactivate(this, { force });
+ }
+
+ get hoverTargets() {
+ return [this.panelElement];
+ }
+
+ onBeforeHide() {}
}
-class TabPanel extends Panel {
+class TabPanel extends HoverPanel {
/** @type {MozTabbrowserTab|null} */
#tab;
/** @type {DOMElement|null} */
#thumbnailElement;
- /** @type {TabHoverPanelSet} */
- #panelSet;
-
constructor(panel, panelSet) {
- super();
+ super(panel, panelSet);
XPCOMUtils.defineLazyPreferenceGetter(
this,
@@ -204,11 +265,12 @@ class TabPanel extends Panel {
"_prefCollectWireframes",
"browser.history.collectWireframes"
);
-
- this.panelElement = panel;
- this.#panelSet = panelSet;
-
- this.win = this.panelElement.ownerGlobal;
+ XPCOMUtils.defineLazyPreferenceGetter(
+ this,
+ "_prefUseTabNotes",
+ "browser.tabs.notes.enabled",
+ false
+ );
this.#tab = null;
this.#thumbnailElement = null;
@@ -217,18 +279,27 @@ class TabPanel extends Panel {
handleEvent(e) {
switch (e.type) {
case "popupshowing":
+ this.panelElement.addEventListener("mouseout", this);
this.#updatePreview();
break;
case "TabAttrModified":
this.#updatePreview(e.target);
break;
case "TabSelect":
- this.deactivate();
+ this.deactivate(null, { force: true });
+ break;
+ case "mouseout":
+ if (!this.panelElement.contains(e.relatedTarget)) {
+ this.deactivate();
+ }
break;
}
}
activate(tab) {
+ if (this.#tab === tab && this.panelElement.state == "open") {
+ return;
+ }
let originalTab = this.#tab;
this.#tab = tab;
@@ -252,8 +323,8 @@ class TabPanel extends Panel {
) {
this.#updatePreview();
} else {
- this.#panelSet.panelOpener.execute(() => {
- if (!this.#panelSet.shouldActivate()) {
+ this.panelSet.panelOpener.execute(() => {
+ if (!this.panelSet.shouldActivate()) {
return;
}
this.panelElement.openPopup(this.#tab, this.popupOptions);
@@ -263,26 +334,42 @@ class TabPanel extends Panel {
}
}
- deactivate(leavingTab = null) {
+ deactivate(leavingTab = null, { force = false } = {}) {
+ if (!this._prefUseTabNotes) {
+ force = true;
+ }
if (leavingTab) {
if (this.#tab != leavingTab) {
return;
}
this.win.requestAnimationFrame(() => {
if (this.#tab == leavingTab) {
- this.deactivate();
+ this.deactivate(null, { force });
}
});
return;
}
+ super.deactivate({ force });
+ }
+
+ onBeforeHide() {
+ this.panelElement.removeEventListener("popupshowing", this);
+ this.panelElement.removeEventListener("mouseout", this);
+ this.win.removeEventListener("TabSelect", this);
this.#tab?.removeEventListener("TabAttrModified", this);
this.#tab = null;
this.#thumbnailElement = null;
- this.panelElement.removeEventListener("popupshowing", this);
- this.win.removeEventListener("TabSelect", this);
- this.panelElement.hidePopup();
- this.#panelSet.panelOpener.clear(this);
- this.#panelSet.panelOpener.setZeroDelay();
+ }
+
+ get hoverTargets() {
+ let targets = [];
+ if (this._prefUseTabNotes) {
+ targets.push(this.panelElement);
+ }
+ if (this.#tab) {
+ targets.push(this.#tab);
+ }
+ return targets;
}
getPrettyURI(uri) {
@@ -450,38 +537,43 @@ class TabPanel extends Panel {
}
get popupOptions() {
- if (!this.win.gBrowser.tabContainer.verticalMode) {
+ let tabContainer = this.win.gBrowser.tabContainer;
+ // Popup anchors to the bottom edge of the tab in horizontal tabs mode
+ if (!tabContainer.verticalMode) {
return {
position: "bottomleft topleft",
x: 0,
y: -2,
};
}
- if (!this.win.SidebarController._positionStart) {
- return {
- position: "topleft topright",
- x: 0,
- y: 3,
- };
+
+ let sidebarAtStart = this.win.SidebarController._positionStart;
+
+ // Popup anchors to the end edge of the tab in vertical mode
+ let positionFromAnchor = sidebarAtStart ? "topright" : "topleft";
+ let positionFromPanel = sidebarAtStart ? "topleft" : "topright";
+ let positionX = 0;
+ let positionY = 3;
+
+ // Popup anchors to the corner of tabs in the vertical pinned grid
+ if (tabContainer.isContainerVerticalPinnedGrid(this.#tab)) {
+ positionFromAnchor = sidebarAtStart ? "bottomright" : "bottomleft";
+ positionX = sidebarAtStart ? -20 : 20;
+ positionY = -15;
}
+
return {
- position: "topright topleft",
- x: 0,
- y: 3,
+ position: `${positionFromAnchor} ${positionFromPanel}`,
+ x: positionX,
+ y: positionY,
};
}
}
-class TabGroupPanel extends Panel {
+class TabGroupPanel extends HoverPanel {
/** @type {MozTabbrowserTabGroup|null} */
#group;
- /** @type {TabHoverPanelSet} */
- #panelSet;
-
- /** @type {number | null} */
- #deactivateTimer;
-
static PANEL_UPDATE_EVENTS = [
"TabAttrModified",
"TabClose",
@@ -493,19 +585,15 @@ class TabGroupPanel extends Panel {
];
constructor(panel, panelSet) {
- super();
+ super(panel, panelSet);
- this.panelElement = panel;
this.panelContent = panel.querySelector("#tabgroup-panel-content");
- this.win = this.panelElement.ownerGlobal;
-
- this.#panelSet = panelSet;
this.#group = null;
}
activate(group) {
if (this.#group && this.#group != group) {
- this.#group.hoverPreviewPanelActive = false;
+ this.#removeGroupListeners();
}
this.#group = group;
@@ -514,12 +602,14 @@ class TabGroupPanel extends Panel {
Glean.tabgroup.groupInteractions.hover_preview.add();
if (this.panelElement.state == "closed") {
- this.#panelSet.panelOpener.execute(() => {
- if (!this.#panelSet.shouldActivate() || !this.#group.collapsed) {
+ this.panelSet.panelOpener.execute(() => {
+ if (!this.panelSet.shouldActivate() || !this.#group.collapsed) {
return;
}
this.#doOpenPanel();
}, this);
+ } else {
+ this.#addGroupListeners();
}
}
@@ -533,60 +623,11 @@ class TabGroupPanel extends Panel {
this.panelContent.children[childIndex].focus();
}
- deactivate({ force = false } = {}) {
- if (force) {
- this.win.clearTimeout(this.#deactivateTimer);
- this.#deactivateTimer = null;
- this.#doDeactivate();
- return;
- }
-
- if (this.#deactivateTimer) {
- return;
- }
-
- this.#deactivateTimer = this.win.setTimeout(() => {
- this.#deactivateTimer = null;
- if (this.#hasHoverState()) {
- return;
- }
- this.#doDeactivate();
- }, TAB_GROUP_PANEL_STICKY_TIME);
- }
-
- #doDeactivate() {
- this.panelElement.removeEventListener("mouseout", this);
- this.panelElement.removeEventListener("command", this);
-
- if (this.#group) {
- this.#group.hoverPreviewPanelActive = false;
-
- for (let event of TabGroupPanel.PANEL_UPDATE_EVENTS) {
- this.#group.removeEventListener(event, this);
- }
- }
-
- this.panelElement.hidePopup();
- this.#panelSet.panelOpener.clear(this);
- this.#panelSet.panelOpener.setZeroDelay();
- }
-
- #hasHoverState() {
- return (
- this.#group?.labelContainerElement?.matches(":hover") ||
- this.panelElement.matches(":hover")
- );
- }
-
#doOpenPanel() {
this.panelElement.addEventListener("mouseout", this);
this.panelElement.addEventListener("command", this);
- this.#group.hoverPreviewPanelActive = true;
-
- for (let event of TabGroupPanel.PANEL_UPDATE_EVENTS) {
- this.#group.addEventListener(event, this);
- }
+ this.#addGroupListeners();
this.panelElement.openPopup(this.#popupTarget, this.popupOptions);
}
@@ -599,10 +640,12 @@ class TabGroupPanel extends Panel {
tabbutton.setAttribute("keyNav", false);
tabbutton.setAttribute("tabindex", 0);
tabbutton.setAttribute("label", tab.label);
- tabbutton.setAttribute(
- "image",
- "page-icon:" + tab.linkedBrowser.currentURI.spec
- );
+ if (tab.linkedBrowser) {
+ tabbutton.setAttribute(
+ "image",
+ "page-icon:" + tab.linkedBrowser.currentURI.spec
+ );
+ }
tabbutton.setAttribute("tooltiptext", tab.label);
tabbutton.classList.add(
"subviewbutton",
@@ -649,13 +692,31 @@ class TabGroupPanel extends Panel {
this.win.gBrowser.selectedTab = event.target.tab;
this.deactivate({ force: true });
- } else if (event.type == "mouseout" && event.target == this.panelElement) {
+ } else if (
+ event.type == "mouseout" &&
+ this.hoverTargets.every(target => !target.contains(event.relatedTarget))
+ ) {
this.deactivate();
} else if (TabGroupPanel.PANEL_UPDATE_EVENTS.includes(event.type)) {
this.#updatePanelContent();
}
}
+ onBeforeHide() {
+ this.panelElement.removeEventListener("mouseout", this);
+ this.panelElement.removeEventListener("command", this);
+
+ this.#removeGroupListeners();
+ }
+
+ get hoverTargets() {
+ let targets = [this.panelElement];
+ if (this.#popupTarget) {
+ targets.push(this.#popupTarget);
+ }
+ return targets;
+ }
+
get popupOptions() {
if (!this.win.gBrowser.tabContainer.verticalMode) {
return {
@@ -682,6 +743,26 @@ class TabGroupPanel extends Panel {
return this.#group?.labelContainerElement;
}
+ #addGroupListeners() {
+ if (!this.#group) {
+ return;
+ }
+ this.#group.hoverPreviewPanelActive = true;
+ for (let event of TabGroupPanel.PANEL_UPDATE_EVENTS) {
+ this.#group.addEventListener(event, this);
+ }
+ }
+
+ #removeGroupListeners() {
+ if (!this.#group) {
+ return;
+ }
+ this.#group.hoverPreviewPanelActive = false;
+ for (let event of TabGroupPanel.PANEL_UPDATE_EVENTS) {
+ this.#group.removeEventListener(event, this);
+ }
+ }
+
#movePanel() {
if (!this.#popupTarget) {
return;
diff --git a/browser/components/tabbrowser/content/tab-stacking.js b/browser/components/tabbrowser/content/tab-stacking.js
@@ -117,7 +117,7 @@
isPinned ? numPinned : undefined
);
- if (this._isContainerVerticalPinnedGrid(draggedTab)) {
+ if (this._tabbrowserTabs.isContainerVerticalPinnedGrid(draggedTab)) {
// Update both translate axis for pinned vertical expanded tabs
if (oldTranslateX > 0 && translateOffsetX > tabWidth / 2) {
newTranslateX += tabWidth;
@@ -205,7 +205,7 @@
!isSplitViewWrapper(draggedTab) &&
!shouldPin &&
!shouldUnpin;
- if (this._isContainerVerticalPinnedGrid(draggedTab)) {
+ if (this._tabbrowserTabs.isContainerVerticalPinnedGrid(draggedTab)) {
shouldTranslate &&=
(oldTranslateX && oldTranslateX != newTranslateX) ||
(oldTranslateY && oldTranslateY != newTranslateY);
@@ -446,7 +446,7 @@
"Cannot move together a mix of pinned and unpinned tabs."
);
}
- let isGrid = this._isContainerVerticalPinnedGrid(tab);
+ let isGrid = this._tabbrowserTabs.isContainerVerticalPinnedGrid(tab);
let animate = !gReduceMotion;
tab._moveTogetherSelectedTabsData = {
@@ -655,7 +655,7 @@
}
let isPinned = tab.pinned;
let dragAndDropElements = this._tabbrowserTabs.dragAndDropElements;
- let isGrid = this._isContainerVerticalPinnedGrid(tab);
+ let isGrid = this._tabbrowserTabs.isContainerVerticalPinnedGrid(tab);
let periphery = document.getElementById(
"tabbrowser-arrowscrollbox-periphery"
);
diff --git a/browser/components/tabbrowser/content/tabs.js b/browser/components/tabbrowser/content/tabs.js
@@ -1066,6 +1066,15 @@
return this.hasAttribute("movingtab");
}
+ isContainerVerticalPinnedGrid(tab) {
+ return (
+ tab.pinned &&
+ this.verticalMode &&
+ this.hasAttribute("expanded") &&
+ !this.expandOnHover
+ );
+ }
+
/**
* Changes the selected tab or tab group label on the tab strip
* relative to the ARIA-focused tab strip element or the active tab. This
diff --git a/browser/components/tabbrowser/test/browser/dragdrop/browser_drag_to_pin.js b/browser/components/tabbrowser/test/browser/dragdrop/browser_drag_to_pin.js
@@ -129,6 +129,10 @@ add_task(async function test_resize_container_on_unpin_horizontal() {
});
add_task(async function test_pin_to_promo_card_vertical() {
+ // Ensure the mouse is not hovering over the tab strip.
+ EventUtils.synthesizeMouseAtCenter(document.documentElement, {
+ type: "mouseover",
+ });
await SpecialPowers.pushPrefEnv({
set: [
["sidebar.verticalTabs", true],
diff --git a/browser/components/tabbrowser/test/browser/tabs/browser_tab_preview.js b/browser/components/tabbrowser/test/browser/tabs/browser_tab_preview.js
@@ -40,16 +40,16 @@ async function openTabPreview(tab, win = window) {
}
async function closeTabPreviews(win = window) {
- const tabs = win.document.getElementById("tabbrowser-tabs");
- const tabsRect = tabs.getBoundingClientRect();
const previewHidden = BrowserTestUtils.waitForPopupEvent(
win.document.getElementById(TAB_PREVIEW_PANEL_ID),
"hidden"
);
+ const tabs = win.document.getElementById("tabbrowser-tabs");
+ const tabsRect = tabs.getBoundingClientRect();
EventUtils.synthesizeMouse(
tabs,
0,
- tabsRect.height + 1,
+ tabsRect.height + 10,
{
type: "mouseout",
},
@@ -451,7 +451,9 @@ add_task(async function tabUrlBarInputTests() {
await previewHidden;
Assert.equal(previewElement.state, "closed", "Preview is closed");
- await closeTabPreviews();
+ EventUtils.synthesizeMouseAtCenter(document.documentElement, {
+ type: "mousemove",
+ });
await openTabPreview(tab1);
Assert.equal(previewElement.state, "open", "Preview is open");
@@ -984,15 +986,12 @@ add_task(async function tabGroupPanelUpdatesTests() {
// TODO Bug 1899556: If possible, write a test to confirm tab previews
// aren't shown when /all/ windows are in the background
add_task(async function noPreviewInBackgroundWindowTests() {
+ todo(false, "test is failing on CI, bug 2006695");
+
+ /*
const bgWindow = window;
- const bgTabUngrouped = await BrowserTestUtils.openNewForegroundTab(
- gBrowser,
- "about:robots"
- );
- const bgTabGrouped = await BrowserTestUtils.openNewForegroundTab(
- gBrowser,
- "about:robots"
- );
+ const bgTabUngrouped = await addTab("about:robots");
+ const bgTabGrouped = await addTab("about:robots");
const bgGroup = gBrowser.addTabGroup([bgTabGrouped]);
bgGroup.collapsed = true;
@@ -1060,6 +1059,7 @@ add_task(async function noPreviewInBackgroundWindowTests() {
sinon.restore();
await resetState();
+ */
});
/**
diff --git a/browser/themes/shared/tabbrowser/tab-hover-preview.css b/browser/themes/shared/tabbrowser/tab-hover-preview.css
@@ -5,7 +5,10 @@
#tab-preview-panel {
--panel-width: 280px;
--panel-padding: 0;
- pointer-events: none;
+ /* stylelint-disable-next-line media-query-no-invalid */
+ @media not -moz-pref("browser.tabs.notes.enabled") {
+ pointer-events: none;
+ }
}
.tab-preview-text-container {