commit 1d759f5caf7b54b917093b0fe94a3ab8c5117afd
parent 99222628946a255a65b9213309e7ddc8a18d88ce
Author: Jeremy Swinarton <jswinarton@mozilla.com>
Date: Tue, 16 Dec 2025 14:33:01 +0000
Bug 2000064: Add truncated tab note text to tab hover preview r=sthompson,desktop-theme-reviewers,tabbrowser-reviewers,dao
Differential Revision: https://phabricator.services.mozilla.com/D273501
Diffstat:
4 files changed, 73 insertions(+), 3 deletions(-)
diff --git a/browser/base/content/main-popupset.inc.xhtml b/browser/base/content/main-popupset.inc.xhtml
@@ -562,6 +562,7 @@
</html:div>
</html:div>
<html:div class="tab-preview-thumbnail-container"></html:div>
+ <html:div class="tab-note-text-container"></html:div>
</panel>
<panel id="tabgroup-preview-panel"
diff --git a/browser/components/tabbrowser/content/tab-hover-preview.mjs b/browser/components/tabbrowser/content/tab-hover-preview.mjs
@@ -10,6 +10,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
PageWireframes: "resource:///modules/sessionstore/PageWireframes.sys.mjs",
SponsorProtection:
"moz-src:///browser/components/newtab/SponsorProtection.sys.mjs",
+ TabNotes: "moz-src:///browser/components/tabnotes/TabNotes.sys.mjs",
});
// Denotes the amount of time (in ms) that the panel will *not* respect
@@ -408,6 +409,11 @@ class TabPanel extends Panel {
"";
}
+ lazy.TabNotes.get(this.#tab.canonicalUrl).then(note => {
+ this.panelElement.querySelector(".tab-note-text-container").textContent =
+ note?.text || "";
+ });
+
let thumbnailContainer = this.panelElement.querySelector(
".tab-preview-thumbnail-container"
);
diff --git a/browser/components/tabbrowser/test/browser/tabs/browser_tab_preview.js b/browser/components/tabbrowser/test/browser/tabs/browser_tab_preview.js
@@ -23,6 +23,10 @@ const TabHoverPanelSet = ChromeUtils.importESModule(
"chrome://browser/content/tabbrowser/tab-hover-preview.mjs"
).default;
+const { TabNotes } = ChromeUtils.importESModule(
+ "moz-src:///browser/components/tabnotes/TabNotes.sys.mjs"
+);
+
const TAB_PREVIEW_PANEL_ID = "tab-preview-panel";
const TAB_GROUP_PREVIEW_PANEL_ID = "tabgroup-preview-panel";
@@ -548,6 +552,52 @@ add_task(async function tabContentChangeTests() {
await resetState();
});
+/**
+ * Test that if a note is set on a tab, the note appears in the preview panel
+ */
+add_task(async function tabNotesTests() {
+ const previewPanel = document.getElementById(TAB_PREVIEW_PANEL_ID);
+ const noteText = "Hello world";
+
+ const tab = await addTabTo(gBrowser, "https://example.com/");
+
+ await openTabPreview(tab);
+ Assert.equal(
+ previewPanel.querySelector(".tab-note-text-container").innerText,
+ "",
+ "Preview panel contains no tab note"
+ );
+ await closeTabPreviews();
+
+ const tabNoteCreatedObserved = TestUtils.topicObserved("TabNote:Created");
+ TabNotes.set("https://example.com/", noteText);
+ await tabNoteCreatedObserved;
+
+ await openTabPreview(tab);
+
+ Assert.equal(
+ previewPanel.querySelector(".tab-note-text-container").innerText,
+ noteText,
+ "New tab note is visible in preview panel"
+ );
+ await closeTabPreviews();
+
+ const tabNoteRemovedObserved = TestUtils.topicObserved("TabNote:Removed");
+ TabNotes.delete("https://example.com/");
+ await tabNoteRemovedObserved;
+
+ await openTabPreview(tab);
+ Assert.equal(
+ previewPanel.querySelector(".tab-note-text-container").innerText,
+ "",
+ "Preview panel contains no tab note after delete"
+ );
+ await closeTabPreviews();
+
+ BrowserTestUtils.removeTab(tab);
+ await resetState();
+});
+
/*
* Tab group hover preview tests
* -----------------------------
diff --git a/browser/themes/shared/tabbrowser/tab-hover-preview.css b/browser/themes/shared/tabbrowser/tab-hover-preview.css
@@ -14,6 +14,8 @@
.tab-preview-title {
overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
-webkit-line-clamp: 2;
font-weight: var(--heading-font-weight);
}
@@ -32,9 +34,12 @@
}
.tab-preview-thumbnail-container {
- width: 280px;
- height: 140px;
- border-top: 1px solid var(--panel-border-color);
+ width: 264px;
+ border: 1px solid var(--border-color-deemphasized);
+ border-radius: var(--border-radius-medium);
+ margin: 0 auto var(--space-small);
+ overflow: hidden;
+
&.hide-thumbnail {
display: none;
}
@@ -48,6 +53,14 @@
}
}
+.tab-note-text-container:not(:empty) {
+ margin: 0 var(--space-large) var(--space-large);
+ overflow: hidden;
+ display: -webkit-box;
+ -webkit-box-orient: vertical;
+ -webkit-line-clamp: 10;
+}
+
@keyframes tab-hover-preview-fadein {
from {
opacity: 0;