Bug 1418602 - Allow Theming Sidebars (WIP)
MozReview-Commit-ID: 8OcbExWxTkI
--- a/browser/components/places/content/sidebarUtils.js
+++ b/browser/components/places/content/sidebarUtils.js
@@ -1,13 +1,16 @@
/* 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/. */
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
+const { LightweightThemeConsumer } = ChromeUtils.import("resource://gre/modules/LightweightThemeConsumer.jsm", {});
+new LightweightThemeConsumer(document, window.top);
+
window.top.gUIDensity.update();
var SidebarUtils = {
handleTreeClick: function SU_handleTreeClick(aTree, aEvent, aGutterSelect) {
// right-clicks are not handled here
if (aEvent.button == 2)
return;
--- a/browser/modules/ThemeVariableMap.jsm
+++ b/browser/modules/ThemeVariableMap.jsm
@@ -18,9 +18,14 @@ const ThemeVariableMap = [
["--urlbar-separator-color", "toolbar_field_separator"],
["--tabs-border-color", "toolbar_top_separator", "navigator-toolbox"],
["--lwt-toolbar-vertical-separator", "toolbar_vertical_separator"],
["--toolbox-border-bottom-color", "toolbar_bottom_separator"],
["--lwt-toolbarbutton-icon-fill", "icon_color"],
["--lwt-toolbarbutton-icon-fill-attention", "icon_attention_color"],
["--lwt-toolbarbutton-hover-background", "button_background_hover"],
["--lwt-toolbarbutton-active-background", "button_background_active"],
+ ["--lwt-sidebar-background", "sidebar"],
+ ["--lwt-sidebar-text", "sidebar_text"],
+ ["--lwt-sidebar-border", "sidebar_border"],
+ ["--lwt-sidebar-highlight", "sidebar_highlight"],
+ ["--lwt-sidebar-highlight-text", "sidebar_highlight_text"],
];
new file mode 100644
--- /dev/null
+++ b/browser/themes/shared/places/places.inc.css
@@ -0,0 +1,22 @@
+/* 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/. */
+
+.sidebar,
+#sidebar {
+ background-color: var(--lwt-sidebar-background, transparent);
+ color: color: var(--lwt-sidebar-text, black);
+ border-color: var(--lwt-sidebar-border, transparent);
+}
+
+.sidebar-header,
+#sidebar-header {
+ background-color: var(--lwt-sidebar-background, transparent);
+ color: var(--lwt-sidebar-text, black);
+ border-color: var(--lwt-sidebar-border, transparent);
+}
+
+:root[style*="--lwt-sidebar-highlight"] treechildren::-moz-tree-row(hover) {
+ color: var(--lwt-sidebar-highlight-text);
+ background-color: var(--lwt-sidebar-highlight);
+}
\ No newline at end of file
--- a/browser/themes/shared/places/tree-icons.inc.css
+++ b/browser/themes/shared/places/tree-icons.inc.css
@@ -1,15 +1,15 @@
/* 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/. */
treechildren:-moz-tree-image {
-moz-context-properties: fill, fill-opacity;
- fill: -moz-FieldText;
+ fill: currentColor;
fill-opacity: 0.7;
}
treechildren::-moz-tree-image(title) {
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.svg");
padding-inline-end: 2px;
margin: 0 2px;
width: 16px;
--- a/browser/themes/shared/sidebar.inc.css
+++ b/browser/themes/shared/sidebar.inc.css
@@ -1,14 +1,16 @@
%if 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/. */
%endif
+%include ../shared/places/places.inc.css
+
.sidebar-header,
#sidebar-header {
font-size: 1.333em;
font-weight: lighter;
padding: 8px;
}
%ifndef MOZ_WIDGET_GTK
--- a/browser/themes/windows/browser.css
+++ b/browser/themes/windows/browser.css
@@ -668,21 +668,21 @@ html|*.urlbar-input:-moz-lwtheme::placeh
%include ../shared/sidebar.inc.css
#sidebar-box {
background-color: -moz-Field;
color: -moz-FieldText;
}
#sidebar-header {
- border-bottom: 1px solid ThreeDLightShadow;
+ border-bottom: 1px solid var(--lwt-sidebar-border, ThreeDLightShadow);
}
.sidebar-splitter {
- border-color: ThreeDLightShadow;
+ border-color: var(--lwt-sidebar-border, ThreeDLightShadow);;
}
.browserContainer > findbar {
background-color: -moz-dialog;
color: -moz-DialogText;
text-shadow: none;
}
@@ -717,16 +717,18 @@ html|*.urlbar-input:-moz-lwtheme::placeh
}
/* All tabs menupopup */
.alltabs-item[selected="true"] {
font-weight: bold;
}
+%include ../shared/places/places.inc.css
+
/* Bookmarks toolbar */
#PlacesToolbarDropIndicator {
list-style-image: url(chrome://browser/skin/places/toolbarDropMarker.png);
}
toolbarbutton.bookmark-item[dragover="true"][open="true"] {
-moz-appearance: none;
background: Highlight !important;
--- a/toolkit/components/extensions/ext-theme.js
+++ b/toolkit/components/extensions/ext-theme.js
@@ -157,16 +157,21 @@ class Theme {
case "toolbar_top_separator":
case "toolbar_bottom_separator":
case "toolbar_vertical_separator":
case "button_background_hover":
case "button_background_active":
case "popup":
case "popup_text":
case "popup_border":
+ case "sidebar":
+ case "sidebar_text":
+ case "sidebar_border":
+ case "sidebar_highlight":
+ case "sidebar_highlight_text":
this.lwtStyles[color] = cssColor;
break;
}
}
}
/**
* Helper method for loading images found in the extension's manifest.
--- a/toolkit/components/extensions/schemas/theme.json
+++ b/toolkit/components/extensions/schemas/theme.json
@@ -159,16 +159,36 @@
},
"popup_text": {
"$ref": "ThemeColor",
"optional": true
},
"popup_border": {
"$ref": "ThemeColor",
"optional": true
+ },
+ "sidebar": {
+ "$ref": "ThemeColor",
+ "optional": true
+ },
+ "sidebar_text": {
+ "$ref": "ThemeColor",
+ "optional": true
+ },
+ "sidebar_border": {
+ "$ref": "ThemeColor",
+ "optional": true
+ },
+ "sidebar_highlight": {
+ "$ref": "ThemeColor",
+ "optional": true
+ },
+ "sidebar_highlight_text": {
+ "$ref": "ThemeColor",
+ "optional": true
}
},
"additionalProperties": { "$ref": "UnrecognizedProperty" }
},
"icons": {
"type": "object",
"optional": true,
"properties": {
--- a/toolkit/components/extensions/test/browser/browser.ini
+++ b/toolkit/components/extensions/test/browser/browser.ini
@@ -16,8 +16,9 @@ support-files =
[browser_ext_themes_static_onUpdated.js]
[browser_ext_themes_tab_loading.js]
[browser_ext_themes_tab_text.js]
[browser_ext_themes_toolbar_fields.js]
[browser_ext_themes_toolbars.js]
[browser_ext_themes_toolbarbutton_icons.js]
[browser_ext_themes_toolbarbutton_colors.js]
[browser_ext_themes_arrowpanels.js]
+[browser_ext_themes_sidebars.js]
new file mode 100644
--- /dev/null
+++ b/toolkit/components/extensions/test/browser/browser_ext_themes_sidebars.js
@@ -0,0 +1,62 @@
+"use strict";
+
+// This test checks applied WebExtension themes that attempt to change
+// popup properties
+
+add_task(async function test_popup_styling(browser, accDoc) {
+ const BACKGROUND_COLOR = "#FF0000";
+ const TEXT_COLOR = "#008000";
+ const BORDER_COLOR = "#0000FF";
+ const HIGHLIGHT_COLOR = "#FF00FF";
+ const HIGHLIGHT_TEXT_COLOR = "#00FF00";
+
+ let extension = ExtensionTestUtils.loadExtension({
+ manifest: {
+ "theme": {
+ "images": {
+ "headerURL": "image1.png",
+ },
+ "colors": {
+ "accentcolor": ACCENT_COLOR,
+ "textcolor": TEXT_COLOR,
+ "sidebar": BACKGROUND_COLOR,
+ "sidebar_text": TEXT_COLOR,
+ "sidebar_border": BORDER_COLOR,
+ "sidebar_highlight": HIGHLIGHT_COLOR,
+ "sidebar_highlight_text": HIGHLIGHT_TEXT_COLOR,
+ },
+ },
+ },
+ files: {
+ "image1.png": BACKGROUND,
+ },
+ });
+
+
+ await BrowserTestUtils.withNewTab({gBrowser, url: "https://example.com"}, async function(browser) {
+ await extension.startup();
+ let sidebar = document.getElementById("sidebar");
+ BrowserTestUtils.waitForEvent(sidebar, "load", true);
+ SidebarUI.toggle("viewBookmarksSidebar");
+
+ let sidebarContent = document.getElementById("sidebar");
+ let sidebarComputedStyle = window.getComputedStyle(sidebarContent);
+
+ // Ensure sidebar background color was set properly
+ Assert.equal(
+ sidebarComputedStyle.getPropertyValue("background-color"),
+ `rgb(${hexToRGB(BACKGROUND_COLOR).join(", ")})`,
+ "Popup background color should have been themed"
+ );
+
+ // Ensure sidebar text color was set properly
+ Assert.equal(
+ sidebarComputedStyle.getPropertyValue("color"),
+ `rgb(${hexToRGB(TEXT_COLOR).join(", ")})`,
+ "Popup text color should have been themed"
+ );
+
+ SidebarUI.toggle("viewBookmarksSidebar");
+ await extension.unload();
+ });
+});
--- a/toolkit/modules/LightweightThemeConsumer.jsm
+++ b/toolkit/modules/LightweightThemeConsumer.jsm
@@ -15,21 +15,25 @@ const toolkitVariableMap = [
["--arrowpanel-color", "popup_text"],
["--arrowpanel-border-color", "popup_border"],
];
ChromeUtils.import("resource:///modules/ThemeVariableMap.jsm");
ChromeUtils.defineModuleGetter(this, "LightweightThemeImageOptimizer",
"resource://gre/modules/addons/LightweightThemeImageOptimizer.jsm");
+// this._doc: The document where the theme variables are applied in.
+// this._win: The corresponding browser window used in the theme data.
this.LightweightThemeConsumer =
- function LightweightThemeConsumer(aDocument) {
+ function LightweightThemeConsumer(aDocument, aWindow = null) {
this._doc = aDocument;
- this._win = aDocument.defaultView;
-
+ if (aWindow == null)
+ this._win = aDocument.defaultView;
+ else
+ this._win = aWindow;
let screen = this._win.screen;
this._lastScreenWidth = screen.width;
this._lastScreenHeight = screen.height;
Services.obs.addObserver(this, "lightweight-theme-styling-update");
var temp = {};
ChromeUtils.import("resource://gre/modules/LightweightThemeManager.jsm", temp);
@@ -119,17 +123,17 @@ LightweightThemeConsumer.prototype = {
// We need to clear these either way: either because the theme is being removed,
// or because we are applying a new theme and the data might be bogus CSS,
// so if we don't reset first, it'll keep the old value.
root.style.removeProperty("--lwt-text-color");
root.style.removeProperty("--lwt-accent-color");
let textcolor = aData.textcolor || "black";
_setProperty(root, active, "--lwt-text-color", textcolor);
_setProperty(root, active, "--lwt-accent-color", this._sanitizeCSSColor(aData.accentcolor) || "white");
-
+ // add properties here MASINI
if (active) {
let dummy = this._doc.createElement("dummy");
dummy.style.color = textcolor;
let [r, g, b] = _parseRGB(this._win.getComputedStyle(dummy).color);
let luminance = 0.2125 * r + 0.7154 * g + 0.0721 * b;
root.setAttribute("lwthemetextcolor", luminance <= 110 ? "dark" : "bright");
root.setAttribute("lwtheme", "true");
} else {
@@ -197,16 +201,18 @@ function _setProperty(elem, active, vari
} else {
elem.style.removeProperty(variableName);
}
}
function _setProperties(root, active, vars) {
for (let map of [toolkitVariableMap, ThemeVariableMap]) {
for (let [cssVarName, varsKey, optionalElementID] of map) {
+ if (optionalElementID != null)
+ continue;
let elem = optionalElementID ? root.ownerDocument.getElementById(optionalElementID)
: root;
_setProperty(elem, active, cssVarName, vars[varsKey]);
}
}
}
function _parseRGB(aColorString) {