/* 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/. */ "use strict"; /* INCLUDE THIS FILE AS: * * * FOR ANY WEBSITE THAT WOULD NEED TO USE THE ACCENT COLOR, ETC */ { const kZenThemeAccentColorPref = "zen.theme.accent-color"; const kZenThemePanelSeparationPref = "zen.theme.panel-separation"; /** * ZenThemeModifier controls the application of theme data to the browser, * for examplem, it injects the accent color to the document. This is used * because we need a way to apply the accent color without having to worry about * shadow roots not inheriting the accent color. * * note: It must be a firefox builtin page with access to the browser's configuration * and services. */ const ZenThemeModifier = { _inMainBrowserWindow: false, /** * Listen for theming updates from the LightweightThemeChild actor, and * begin listening to changes in preferred color scheme. */ init() { this._inMainBrowserWindow = window.location.href == "chrome://browser/content/browser.xhtml"; this.listenForEvents(); this.updateAllThemeBasics(); this._zenInitBrowserLayout(); }, listenForEvents() { addEventListener("LightweightTheme:Set", this); Services.prefs.addObserver(kZenThemeAccentColorPref, this.handleEvent.bind(this)); if (this._inMainBrowserWindow) { Services.prefs.addObserver(kZenThemePanelSeparationPref, this.handleEvent.bind(this)); } }, handleEvent(event) { // note: even might be undefined, but we shoudnt use it! this.updateAllThemeBasics(); }, /** * Update all theme basics, like the accent color. */ updateAllThemeBasics() { this.updateAccentColor(); this.updateExtraBrowserStyles(); }, /** * Update the accent color. */ updateAccentColor() { const accentColor = Services.prefs.getStringPref(kZenThemeAccentColorPref, "#0b57d0"); document.documentElement.style.setProperty("--zen-primary-color", accentColor); // Notify the page that the accent color has changed, only if a function // handler is defined. if (typeof window.zenPageAccentColorChanged === "function") { window.zenPageAccentColorChanged(accentColor); } }, updateExtraBrowserStyles() { // If we are in the main browser window, we can add some extra styles. if (!this._inMainBrowserWindow) return; const panelSeparation = Services.prefs.getIntPref(kZenThemePanelSeparationPref, 7); document.documentElement.style.setProperty("--zen-appcontent-separator-from-window-single", panelSeparation + "px"); if (panelSeparation <= 0) { document.documentElement.style.setProperty("--zen-appcontent-border-radius", "0px"); } else { document.documentElement.style.setProperty("--zen-appcontent-border-radius", "var(--zen-panel-radius)"); } this._changeSidebarLocation(panelSeparation); }, _changeSidebarLocation(value) { const kElementsToAppend = [ "zen-sidebar-web-panel-wrapper", "sidebar-splitter", "sidebar-box", "navigator-toolbox", ]; const kInlineIndicatorElements = [ "nav-bar", "tabbrowser-tabbox", "appcontent", ...kElementsToAppend, ]; const wrapper = document.getElementById("zen-tabbox-wrapper"); const appWrapepr = document.getElementById("zen-sidebar-box-container"); if (value <= 0) { for (let id of kElementsToAppend) { const elem = document.getElementById(id); if (elem) { wrapper.prepend(elem); } } appWrapepr.setAttribute("hidden", "true"); for (let id of kInlineIndicatorElements) { const elem = document.getElementById(id); if (elem) { elem.setAttribute("inlinedwithsidebar", "true"); } } } else { for (let i = kElementsToAppend.length - 1; i >= 0; i--) { const elem = document.getElementById(kElementsToAppend[i]); if (elem) { appWrapepr.appendChild(elem); } } appWrapepr.removeAttribute("hidden"); for (let id of kInlineIndicatorElements) { const elem = document.getElementById(id); if (elem) { elem.removeAttribute("inlinedwithsidebar"); } } } }, _zenInitBrowserLayout() { if (!this._inMainBrowserWindow) return; const kNavbarItems = [ "nav-bar", "PersonalToolbar", "tab-notification-deck-template" ]; const kSeparatorId = "zen-website-and-native-separator"; const kNewContainerId = "zen-appcontent-navbar-container"; let newContainer = document.getElementById(kNewContainerId); for (let id of kNavbarItems) { const node = document.getElementById(id); console.assert(node, "Could not find node with id: " + id); if (!node) continue; newContainer.appendChild(node); } // Add the separator const separator = document.createElement("span"); separator.id = kSeparatorId; newContainer.appendChild(separator); // move the security button to the right const securityButton = document.getElementById("tracking-protection-icon-container"); document.getElementById("urlbar-input-container").insertBefore(securityButton, document.getElementById("page-action-buttons")); }, }; if (typeof Services !== "undefined") ZenThemeModifier.init(); }