tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 9b4e659207dba24b3f9d34be451d3892b04d36f7
parent 49b7caee0c4ebc2a63194628ea1af66fffbe32ec
Author: Nick Grato <ngrato@gmail.com>
Date:   Thu,  4 Dec 2025 18:38:24 +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:
Mbrowser/base/content/browser-box.inc.xhtml | 5+++++
Mbrowser/base/content/test/sidebar/browser_sidebar_move.js | 14+++++++++-----
Mbrowser/components/genai/content/smart-assist.mjs | 97+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mbrowser/components/sidebar/browser-sidebar.js | 17+++--------------
Mbrowser/components/sidebar/tests/browser/browser_customize_sidebar.js | 4++--
Mbrowser/components/sidebar/tests/browser/browser_sidebar_position.js | 8++++----
Abrowser/themes/shared/aiWindowSidebar.css | 24++++++++++++++++++++++++
Mbrowser/themes/shared/browser-shared.css | 1+
Mbrowser/themes/shared/jar.inc.mn | 1+
Mstylelint-rollouts.config.js | 3+++
10 files changed, 149 insertions(+), 25 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/components/sidebar/tests/browser/browser_customize_sidebar.js b/browser/components/sidebar/tests/browser/browser_customize_sidebar.js @@ -202,8 +202,8 @@ add_task(async function test_customize_position_setting() { ok(newPanel.positionInput.checked, "Position setting persists."); is( newSidebarBox.style.order, - "3", - "Sidebar box should have an order of 3 when on the right" + "5", + "Sidebar box should have an order of 5 when on the right" ); await BrowserTestUtils.closeWindow(newWin); diff --git a/browser/components/sidebar/tests/browser/browser_sidebar_position.js b/browser/components/sidebar/tests/browser/browser_sidebar_position.js @@ -31,8 +31,8 @@ add_task(async function test_sidebar_position_end() { ok(sidebar, "Sidebar is shown."); await sidebar.updateComplete; - is(sidebar.style.order, "5", "Sidebar is shown at the end"); - is(sidebarBox.style.order, "3", "Sidebar is shown at the end"); + is(sidebar.style.order, "7", "Sidebar is shown at the end"); + is(sidebarBox.style.order, "5", "Sidebar is shown at the end"); await BrowserTestUtils.closeWindow(win); }); @@ -45,8 +45,8 @@ add_task(async function test_sidebar_position_end_new_window() { ok(sidebar, "Sidebar is shown."); await sidebar.updateComplete; - is(sidebar.style.order, "5", "Sidebar is shown at the end"); - is(sidebarBox.style.order, "3", "Sidebar is shown at the end"); + is(sidebar.style.order, "7", "Sidebar is shown at the end"); + is(sidebarBox.style.order, "5", "Sidebar is shown at the end"); await BrowserTestUtils.closeWindow(win); }); 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",