commit af682319d9bccd38c7ad6f5e5f3899cc4a5737b3
parent b8f7d25d5c1379ddbd584850f99532505b6f9f3a
Author: Nick Grato <ngrato@gmail.com>
Date: Wed, 3 Dec 2025 01:07:58 +0000
Bug 1992302 - load assistant in a right sidebar in ai windows r=desktop-theme-reviewers,ai-frontend-reviewers,Gijs,hjones,yjamora,jsudiaman
Loading our current WIP smart assist component into the right sidebar, Adding some mock functionality just to be able to open the side bar. This additional code in smart assist will not stay.
Differential Revision: https://phabricator.services.mozilla.com/D273686
Diffstat:
8 files changed, 143 insertions(+), 19 deletions(-)
diff --git a/browser/base/content/browser-box.inc.xhtml b/browser/base/content/browser-box.inc.xhtml
@@ -28,4 +28,9 @@
<tabbox id="tabbrowser-tabbox" flex="1" tabcontainer="tabbrowser-tabs">
<tabpanels id="tabbrowser-tabpanels" flex="1" selectedIndex="0"/>
</tabbox>
+ <splitter id="ai-window-splitter" class="chromeclass-extrachrome sidebar-splitter" resizebefore="none" resizeafter="sibling" hidden="true"/>
+ <vbox id="ai-window-box" hidden="true" class="chromeclass-extrachrome ai-window-right-sidebar">
+ <stack class="ai-window-browser-stack" flex="1">
+ </stack>
+ </vbox>
</hbox>
diff --git a/browser/base/content/test/sidebar/browser_sidebar_move.js b/browser/base/content/test/sidebar/browser_sidebar_move.js
@@ -9,14 +9,18 @@ const EXPECTED_START_ORDINALS = [
["sidebar-box", 3],
["sidebar-splitter", 4],
["tabbrowser-tabbox", 5],
+ ["ai-window-splitter", 6],
+ ["ai-window-box", 7],
];
const EXPECTED_END_ORDINALS = [
- ["sidebar-main", 5],
- ["sidebar-launcher-splitter", 4],
- ["sidebar-box", 3],
- ["sidebar-splitter", 2],
- ["tabbrowser-tabbox", 1],
+ ["sidebar-main", 7],
+ ["sidebar-launcher-splitter", 6],
+ ["sidebar-box", 5],
+ ["sidebar-splitter", 4],
+ ["tabbrowser-tabbox", 3],
+ ["ai-window-splitter", 2],
+ ["ai-window-box", 1],
];
function getBrowserChildrenWithOrdinals() {
diff --git a/browser/components/genai/content/smart-assist.mjs b/browser/components/genai/content/smart-assist.mjs
@@ -247,6 +247,87 @@ export class SmartAssist extends MozLitElement {
);
}
+ /**
+ * Helper method to get the chrome document
+ *
+ * @returns {Document} The top-level chrome window's document
+ */
+
+ _getChromeDocument() {
+ return window.browsingContext.topChromeWindow.document;
+ }
+
+ /**
+ * Helper method to find an element in the chrome document
+ *
+ * @param {string} id - The element ID to find
+ * @returns {Element|null} The found element or null
+ */
+
+ _getChromeElement(id) {
+ return this._getChromeDocument().getElementById(id);
+ }
+
+ /**
+ * Helper method to get or create the AI window browser element
+ *
+ * @param {Document} chromeDoc - The chrome document
+ * @param {Element} box - The AI window box element
+ * @returns {Element} The AI window browser element
+ */
+
+ _getOrCreateBrowser(chromeDoc, box) {
+ // Find existing browser, or create it the first time we open the sidebar.
+ let browser = chromeDoc.getElementById("ai-window-browser");
+
+ if (!browser) {
+ const stack =
+ box.querySelector(".ai-window-browser-stack") ||
+ chromeDoc.createXULElement("stack");
+
+ stack.className = "ai-window-browser-stack";
+ stack.setAttribute("flex", "1");
+ box.appendChild(stack);
+
+ browser = chromeDoc.createXULElement("browser");
+ browser.setAttribute("id", "ai-window-browser");
+ browser.setAttribute("flex", "1");
+ browser.setAttribute("disablehistory", "true");
+ browser.setAttribute("disablefullscreen", "true");
+ browser.setAttribute("tooltip", "aHTMLTooltip");
+
+ browser.setAttribute(
+ "src",
+ "chrome://browser/content/genai/smartAssist.html"
+ );
+
+ stack.appendChild(browser);
+ }
+ }
+
+ _toggleAIWindowSidebar() {
+ const chromeDoc = this._getChromeDocument();
+ const box = chromeDoc.getElementById("ai-window-box");
+ const splitter = chromeDoc.getElementById("ai-window-splitter");
+
+ if (!box || !splitter) {
+ return;
+ }
+
+ this._getOrCreateBrowser(chromeDoc, box);
+
+ // Toggle visibility
+ const opening = box.hidden;
+
+ box.hidden = !opening;
+ splitter.hidden = !opening;
+
+ // Make sure parent container is also visible
+ if (box.parentElement && box.parentElement.hidden) {
+ box.parentElement.hidden = false;
+ }
+ }
+
render() {
const iconSrc = this.showLog
? "chrome://global/skin/icons/arrow-down.svg"
@@ -360,6 +441,22 @@ export class SmartAssist extends MozLitElement {
</div>`
: ""
}
+
+ ${
+ this.mode === "tab"
+ ? html`
+ <div class="footer">
+ <moz-button
+ type="primary"
+ size="small"
+ @click=${this._toggleAIWindowSidebar}
+ >
+ Open AI Window Sidebar
+ </moz-button>
+ </div>
+ `
+ : ""
+ }
</div>
</div>
`;
diff --git a/browser/components/sidebar/browser-sidebar.js b/browser/components/sidebar/browser-sidebar.js
@@ -794,23 +794,12 @@ var SidebarController = {
// First reset all ordinals to match DOM ordering.
let contentArea = document.getElementById("tabbrowser-tabbox");
let browser = document.getElementById("browser");
- [...browser.children].forEach((node, i) => {
- node.style.order = i + 1;
+ [...browser.children].forEach((node, i, children) => {
+ node.style.order = this._positionStart ? i + 1 : children.length - i;
});
let sidebarContainer = document.getElementById("sidebar-main");
let sidebarMain = document.querySelector("sidebar-main");
- if (!this._positionStart) {
- // DOM ordering is: sidebar-main | launcher-splitter | sidebar-box | splitter | tabbrowser-tabbox
- // Want to display as: tabbrowser-tabbox | splitter | sidebar-box | launcher-splitter | sidebar-main
- // First switch order of sidebar-main and tabbrowser-tabbox
- let mainOrdinal = this.sidebarContainer.style.order;
- this.sidebarContainer.style.order = contentArea.style.order;
- contentArea.style.order = mainOrdinal;
- // Then swap launcher-splitter and splitter
- let splitterOrdinal = this._splitter.style.order;
- this._splitter.style.order = this._launcherSplitter.style.order;
- this._launcherSplitter.style.order = splitterOrdinal;
- }
+
// Indicate we've switched ordering to the box
this._box.toggleAttribute("sidebar-positionend", !this._positionStart);
sidebarMain.toggleAttribute("sidebar-positionend", !this._positionStart);
diff --git a/browser/themes/shared/aiWindowSidebar.css b/browser/themes/shared/aiWindowSidebar.css
@@ -0,0 +1,24 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+:root {
+ --ai-window-sidebar-width-default: 412px;
+}
+
+.ai-window-right-sidebar {
+ width: var(--ai-window-sidebar-width-default);
+}
+
+/* Splitter styling to match the left sidebar */
+#ai-window-splitter {
+ width: var(--splitter-width);
+ border: 0;
+ background-color: transparent;
+ position: relative;
+ z-index: var(--browser-area-z-index-sidebar-splitter);
+}
+
+#ai-window-splitter:hover {
+ background-color: var(--toolbarbutton-hover-background);
+}
diff --git a/browser/themes/shared/browser-shared.css b/browser/themes/shared/browser-shared.css
@@ -24,6 +24,7 @@
@import url("chrome://browser/skin/places/editBookmarkPanel.css");
@import url("chrome://browser/skin/searchbar.css");
@import url("chrome://browser/skin/sidebar.css");
+@import url("chrome://browser/skin/aiWindowSidebar.css");
@import url("chrome://browser/skin/customizableui/customizeMode.css");
@import url("chrome://browser/skin/UITour.css");
@import url("chrome://browser/skin/formautofill-notification.css");
diff --git a/browser/themes/shared/jar.inc.mn b/browser/themes/shared/jar.inc.mn
@@ -15,6 +15,7 @@
skin/classic/browser/tab-list-tree.css (../shared/tab-list-tree.css)
skin/classic/browser/addon-notification.css (../shared/addon-notification.css)
skin/classic/browser/autocomplete.css (../shared/autocomplete.css)
+ skin/classic/browser/aiWindowSidebar.css (../shared/aiWindowSidebar.css)
skin/classic/browser/blockedSite.css (../shared/blockedSite.css)
skin/classic/browser/browser-colors.css (../shared/browser-colors.css)
skin/classic/browser/browser-shared.css (../shared/browser-shared.css)
diff --git a/stylelint-rollouts.config.js b/stylelint-rollouts.config.js
@@ -36,6 +36,7 @@ module.exports = [
"browser/extensions/newtab/content-src/components/DiscoveryStreamComponents/TopicSelection/_TopicSelection.scss",
"browser/themes/linux/browser.css",
"browser/themes/shared/addons/unified-extensions.css",
+ "browser/themes/shared/aiWindowSidebar.css",
"browser/themes/shared/customizableui/customizeMode.css",
"browser/themes/shared/customizableui/panelUI-shared.css",
"browser/themes/shared/identity-block/identity-block.css",
@@ -1050,6 +1051,7 @@ module.exports = [
"browser/themes/osx/downloads/allDownloadsView.css",
"browser/themes/shared/UITour.css",
"browser/themes/shared/addons/unified-extensions.css",
+ "browser/themes/shared/aiWindowSidebar.css",
"browser/themes/shared/autocomplete.css",
"browser/themes/shared/blockedSite.css",
"browser/themes/shared/browser-shared.css",
@@ -1726,6 +1728,7 @@ module.exports = [
"browser/themes/shared/addon-notification.css",
"browser/themes/shared/addons/extension-controlled.css",
"browser/themes/shared/addons/unified-extensions.css",
+ "browser/themes/shared/aiWindowSidebar.css",
"browser/themes/shared/autocomplete.css",
"browser/themes/shared/blockedSite.css",
"browser/themes/shared/browser-shared.css",