commit 954449162966ffb0853b159c8bf5f1b5410b3344
parent d2894a5af8a8a56011b5740bab1e99a4aa84235d
Author: Atila Butkovits <abutkovits@mozilla.com>
Date: Mon, 5 Jan 2026 19:44:18 +0200
Revert "Bug 2007135 - Create Sidebar service to control sidebar state from other location in the window r=ai-frontend-reviewers,Gijs" for causing build bustages.
This reverts commit 39cd7bea2aea4afcef9b6a53b0aaad5853cb5fe9.
Diffstat:
5 files changed, 100 insertions(+), 289 deletions(-)
diff --git a/browser/components/aiwindow/ui/modules/AIWIndowUI.sys.mjs b/browser/components/aiwindow/ui/modules/AIWIndowUI.sys.mjs
@@ -1,145 +0,0 @@
-/**
- * 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/.
- */
-
-const AIWINDOW_SIDEBAR_URL =
- "chrome://browser/content/aiwindow/aiWindow.html#mode=sidebar";
-
-export const AIWindowUI = {
- BOX_ID: "ai-window-box",
- SPLITTER_ID: "ai-window-splitter",
- BROWSER_ID: "ai-window-browser",
- STACK_CLASS: "ai-window-browser-stack",
-
- /**
- * @param {Window} win
- * @returns {{ chromeDoc: Document, box: Element, splitter: Element } | null}
- */
- _getSidebarElements(win) {
- if (!win) {
- return null;
- }
- const chromeDoc = win.document;
- const box = chromeDoc.getElementById(this.BOX_ID);
- const splitter = chromeDoc.getElementById(this.SPLITTER_ID);
-
- if (!box || !splitter) {
- return null;
- }
- return { chromeDoc, box, splitter };
- },
-
- /**
- * Ensure the aiwindow <browser> exists under the sidebar box.
- *
- * @param {Document} chromeDoc
- * @param {Element} box
- * @returns {XULElement} browser
- */
- ensureBrowserIsAppended(chromeDoc, box) {
- const existingBrowser = chromeDoc.getElementById(this.BROWSER_ID);
- if (existingBrowser) {
- // Already exists
- return existingBrowser;
- }
-
- const stack = box.querySelector(`.${this.STACK_CLASS}`);
-
- if (!stack.isConnected) {
- stack.className = this.STACK_CLASS;
- stack.setAttribute("flex", "1");
- box.appendChild(stack);
- }
-
- const browser = chromeDoc.createXULElement("browser");
- browser.id = this.BROWSER_ID;
- browser.setAttribute("transparent", "true");
- browser.setAttribute("flex", "1");
- browser.setAttribute("disablehistory", "true");
- browser.setAttribute("disablefullscreen", "true");
- browser.setAttribute("tooltip", "aHTMLTooltip");
- browser.setAttribute("src", AIWINDOW_SIDEBAR_URL);
- stack.appendChild(browser);
- return browser;
- },
-
- /**
- * @param {Window} win
- * @returns {boolean} whether the sidebar is open (visible)
- */
- isSidebarOpen(win) {
- const nodes = this._getSidebarElements(win);
- if (!nodes) {
- return false;
- }
- // The sidebar is considered open if the box is visible
- return !nodes.box.hidden;
- },
-
- /**
- * Open the AI Window sidebar
- *
- * @param {Window} win
- */
- openSidebar(win) {
- const nodes = this._getSidebarElements(win);
-
- if (!nodes) {
- return;
- }
-
- const { chromeDoc, box, splitter } = nodes;
-
- this.ensureBrowserIsAppended(chromeDoc, box);
-
- box.hidden = false;
- splitter.hidden = false;
- box.parentElement.hidden = false;
- },
-
- /**
- * Close the AI Window sidebar.
- *
- * @param {Window} win
- */
- closeSidebar(win) {
- const nodes = this._getSidebarElements(win);
- if (!nodes) {
- return;
- }
- const { box, splitter } = nodes;
-
- box.hidden = true;
- splitter.hidden = true;
- },
-
- /**
- * Toggle the AI Window sidebar
- *
- * @param {Window} win
- * @returns {boolean} true if now open, false if now closed
- */
- toggleSidebar(win) {
- const nodes = this._getSidebarElements(win);
- if (!nodes) {
- return false;
- }
- const { chromeDoc, box, splitter } = nodes;
-
- const opening = box.hidden;
- if (opening) {
- this.ensureBrowserIsAppended(chromeDoc, box);
- }
-
- box.hidden = !opening;
- splitter.hidden = !opening;
-
- if (opening && box.parentElement?.hidden) {
- box.parentElement.hidden = false;
- }
-
- return opening;
- },
-};
diff --git a/browser/components/aiwindow/ui/moz.build b/browser/components/aiwindow/ui/moz.build
@@ -14,7 +14,6 @@ MOZ_SRC_FILES += [
"modules/AIWindow.sys.mjs",
"modules/AIWindowAccountAuth.sys.mjs",
"modules/AIWindowMenu.sys.mjs",
- "modules/AIWindowUI.sys.mjs",
"modules/ChatConstants.sys.mjs",
"modules/ChatConversation.sys.mjs",
"modules/ChatEnums.sys.mjs",
diff --git a/browser/components/aiwindow/ui/test/browser/browser.toml b/browser/components/aiwindow/ui/test/browser/browser.toml
@@ -15,8 +15,6 @@ support-files = [
["browser_aiwindow_transparency.js"]
-["browser_aiwindowui.js"]
-
["browser_open_aiwindow.js"]
["browser_sidebar_aiwindow.js"]
diff --git a/browser/components/aiwindow/ui/test/browser/browser_aiwindowui.js b/browser/components/aiwindow/ui/test/browser/browser_aiwindowui.js
@@ -1,138 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
- * http://creativecommons.org/publicdomain/zero/1.0/ */
-
-"use strict";
-
-const { AIWindowUI } = ChromeUtils.importESModule(
- "moz-src:///browser/components/aiwindow/ui/modules/AIWindowUI.sys.mjs"
-);
-
-add_task(async function test_aiwindowui_constants() {
- is(AIWindowUI.BOX_ID, "ai-window-box", "BOX_ID constant is correct");
- is(
- AIWindowUI.SPLITTER_ID,
- "ai-window-splitter",
- "SPLITTER_ID constant is correct"
- );
- is(
- AIWindowUI.BROWSER_ID,
- "ai-window-browser",
- "BROWSER_ID constant is correct"
- );
- is(
- AIWindowUI.STACK_CLASS,
- "ai-window-browser-stack",
- "STACK_CLASS constant is correct"
- );
-});
-
-add_task(async function test_aiwindowui_sidebar_operations() {
- const box = document.getElementById(AIWindowUI.BOX_ID);
- const splitter = document.getElementById(AIWindowUI.SPLITTER_ID);
-
- if (!box || !splitter) {
- todo(
- false,
- "AI Window elements not present in this window - skipping DOM tests"
- );
- return;
- }
-
- const initialBoxHidden = box.hidden;
- const initialSplitterHidden = splitter.hidden;
-
- try {
- // Test opening
- AIWindowUI.openSidebar(window);
- is(box.hidden, false, "Box should be visible after opening");
- is(splitter.hidden, false, "Splitter should be visible after opening");
- is(
- AIWindowUI.isSidebarOpen(window),
- true,
- "isSidebarOpen should return true after opening"
- );
-
- // Test closing
- AIWindowUI.closeSidebar(window);
- is(box.hidden, true, "Box should be hidden after closing");
- is(splitter.hidden, true, "Splitter should be hidden after closing");
- is(
- AIWindowUI.isSidebarOpen(window),
- false,
- "isSidebarOpen should return false after closing"
- );
-
- // Test toggling from closed to open
- const toggleResult1 = AIWindowUI.toggleSidebar(window);
- is(toggleResult1, true, "Toggle should return true when opening");
- is(box.hidden, false, "Box should be visible after toggling open");
- is(
- splitter.hidden,
- false,
- "Splitter should be visible after toggling open"
- );
- is(
- AIWindowUI.isSidebarOpen(window),
- true,
- "isSidebarOpen should return true after toggling open"
- );
-
- // Test toggling from open to closed
- const toggleResult2 = AIWindowUI.toggleSidebar(window);
- is(toggleResult2, false, "Toggle should return false when closing");
- is(box.hidden, true, "Box should be hidden after toggling closed");
- is(
- splitter.hidden,
- true,
- "Splitter should be hidden after toggling closed"
- );
- is(
- AIWindowUI.isSidebarOpen(window),
- false,
- "isSidebarOpen should return false after toggling closed"
- );
- } finally {
- // Restore initial state
- box.hidden = initialBoxHidden;
- splitter.hidden = initialSplitterHidden;
- }
-});
-
-add_task(async function test_aiwindowui_ensureBrowserIsAppended() {
- const box = document.getElementById(AIWindowUI.BOX_ID);
-
- if (!box) {
- todo(
- false,
- "AI Window box element not present - skipping browser creation test"
- );
- return;
- }
-
- // Remove any existing browser to start clean
- let existingBrowser = document.getElementById(AIWindowUI.BROWSER_ID);
- if (existingBrowser) {
- existingBrowser.remove();
- }
-
- try {
- const browser1 = AIWindowUI.ensureBrowserIsAppended(document, box);
- ok(browser1, "Should create and return a browser element");
- is(browser1.id, AIWindowUI.BROWSER_ID, "Browser should have correct ID");
- ok(browser1.isConnected, "Browser should be connected to DOM");
-
- // Call again - should return the same browser
- const browser2 = AIWindowUI.ensureBrowserIsAppended(document, box);
- is(
- browser1,
- browser2,
- "Should return the same browser instance when called again"
- );
- } finally {
- // Clean up the created browser
- let createdBrowser = document.getElementById(AIWindowUI.BROWSER_ID);
- if (createdBrowser) {
- createdBrowser.remove();
- }
- }
-});
diff --git a/browser/components/genai/content/smart-assist.mjs b/browser/components/genai/content/smart-assist.mjs
@@ -16,8 +16,6 @@ ChromeUtils.defineESModuleGetters(lazy, {
PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.sys.mjs",
SpecialMessageActions:
"resource://messaging-system/lib/SpecialMessageActions.sys.mjs",
- AIWindowUI:
- "moz-src:///browser/components/aiwindow/ui/modules/AIWindowUI.sys.mjs",
});
const FULL_PAGE_URL = "chrome://browser/content/genai/smartAssistPage.html";
@@ -249,8 +247,107 @@ 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) {
+ let stack = box.querySelector(".ai-window-browser-stack");
+ if (!stack) {
+ stack = chromeDoc.createXULElement("stack");
+ stack.className = "ai-window-browser-stack";
+ stack.setAttribute("flex", "1");
+ box.appendChild(stack);
+ }
+
+ let browser = stack.querySelector("#ai-window-browser");
+ if (!browser) {
+ 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/aiwindow/aiWindow.html"
+ );
+
+ stack.appendChild(browser);
+ }
+ return stack;
+ }
+
+ /**
+ * Helper method to get or create the smartbar element
+ *
+ * @param {Document} chromeDoc - The chrome document
+ * @param {Element} container - The container element
+ */
+ _getOrCreateSmartbar(chromeDoc, container) {
+ // Find existing Smartbar, or create it the first time we open the sidebar.
+ let smartbar = chromeDoc.getElementById("ai-window-smartbar");
+
+ if (!smartbar) {
+ smartbar = chromeDoc.createElement("moz-smartbar");
+ smartbar.id = "ai-window-smartbar";
+ smartbar.setAttribute("sap-name", "smartbar");
+ smartbar.setAttribute("pageproxystate", "invalid");
+ smartbar.setAttribute("popover", "manual");
+ smartbar.classList.add("smartbar", "urlbar");
+ container.append(smartbar);
+ }
+ return smartbar;
+ }
+
_toggleAIWindowSidebar() {
- lazy.AIWindowUI.toggleSidebar(window.browsingContext.topChromeWindow);
+ const chromeDoc = this._getChromeDocument();
+ const box = chromeDoc.getElementById("ai-window-box");
+ const splitter = chromeDoc.getElementById("ai-window-splitter");
+
+ if (!box || !splitter) {
+ return;
+ }
+
+ const stack = this._getOrCreateBrowser(chromeDoc, box);
+ this._getOrCreateSmartbar(chromeDoc, stack);
+
+ // 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() {