Bug 1458426 - Disable custom theming for selected menuitems when document_color_use is set to Always or when High Contrast Mode is enabled. r?dao draft
authorJared Wein <jwein@mozilla.com>
Wed, 30 May 2018 12:15:42 -0400
changeset 801787 5789f4ba4a7b48178884c4c7b6600f0e02ef353c
parent 801403 5866d6685849311f057e7e229b9ace63a2641c29
push id111739
push userbmo:jaws@mozilla.com
push dateWed, 30 May 2018 19:14:37 +0000
reviewersdao
bugs1458426
milestone62.0a1
Bug 1458426 - Disable custom theming for selected menuitems when document_color_use is set to Always or when High Contrast Mode is enabled. r?dao This is a simple patch that we could uplift if desired as it will just disable a couple CSS rules in this situation. I have tested this with document_color_use=2 and separately with High Contrast mode enabled on Windows. MozReview-Commit-ID: 7UJVhIskRMD
browser/components/preferences/in-content/main.js
browser/components/preferences/in-content/subdialogs.js
toolkit/themes/shared/in-content/common.inc.css
--- a/browser/components/preferences/in-content/main.js
+++ b/browser/components/preferences/in-content/main.js
@@ -146,16 +146,19 @@ Preferences.addAll([
   { id: "browser.ctrlTab.previews", type: "bool" },
 
   // Fonts
   { id: "font.language.group", type: "wstring" },
 
   // Languages
   { id: "browser.translation.detectLanguage", type: "bool" },
 
+  // Colors
+  { id: "browser.display.document_color_use", type: "int" },
+
   // General tab
 
   /* Accessibility
    * accessibility.browsewithcaret
      - true enables keyboard navigation and selection within web pages using a
        visible caret, false uses normal keyboard navigation with no caret
    * accessibility.typeaheadfind
      - when set to true, typing outside text areas and input boxes will
@@ -401,16 +404,21 @@ var gMainPane = {
       gMainPane.updateHardwareAcceleration.bind(gMainPane));
     setEventListener("connectionSettings", "command",
       gMainPane.showConnections);
     setEventListener("browserContainersCheckbox", "command",
       gMainPane.checkBrowserContainers);
     setEventListener("browserContainersSettings", "command",
       gMainPane.showContainerSettings);
 
+    // Colors
+    Preferences.get("browser.display.document_color_use").on("change",
+      gMainPane.updatePreferencesColorUse);
+    gMainPane.updatePreferencesColorUse();
+
     // Initializes the fonts dropdowns displayed in this pane.
     this._rebuildFonts();
 
     this.updateOnScreenKeyboardVisibility();
 
     // Show translation preferences if we may:
     const prefName = "browser.translation.ui.show";
     if (Services.prefs.getBoolPref(prefName)) {
@@ -754,16 +762,38 @@ var gMainPane = {
       checkbox.removeAttribute("disabled");
       newValue = startupPref.value === this.STARTUP_PREF_RESTORE_SESSION;
     }
     if (checkbox.checked !== newValue) {
       checkbox.checked = newValue;
     }
   },
 
+  /**
+   * Update the theming of the preferences based on if the document_color_use
+   * pref is set. This is needed to compensate for some styles being ignored (bug 1458426).
+   */
+  updatePreferencesColorUse() {
+    const documentColorUsePref = Preferences.get("browser.display.document_color_use");
+    let highContrastMode = false;
+    if (documentColorUsePref.value != 2) {
+      // Check if the machine is running in High Contrast mode. Gecko sets
+      // background-image to 'none' when in High Contrast mode.
+      let dummyElement = document.createElement("div");
+      dummyElement.style.backgroundImage = "url('#')";
+      let dummyElementCS = getComputedStyle(dummyElement);
+      highContrastMode = dummyElementCS.backgroundImage == "none";
+    }
+    if (documentColorUsePref.value == 2 || highContrastMode) {
+      document.documentElement.setAttribute("document_color_use", "true");
+    } else {
+      document.documentElement.removeAttribute("document_color_use");
+    }
+  },
+
   onBrowserRestoreSessionChange(event) {
     const value = event.target.checked;
     const startupPref = Preferences.get("browser.startup.page");
     let newValue;
 
     if (value) {
       // We need to restore the blank homepage setting in our other pref
       if (startupPref.value === this.STARTUP_PREF_BLANK) {
--- a/browser/components/preferences/in-content/subdialogs.js
+++ b/browser/components/preferences/in-content/subdialogs.js
@@ -212,17 +212,26 @@ SubDialog.prototype = {
       return;
     }
 
     for (let styleSheetURL of this._injectedStyleSheets) {
       this.injectXMLStylesheet(styleSheetURL);
     }
 
     // Provide the ability for the dialog to know that it is being loaded "in-content".
-    this._frame.contentDocument.documentElement.setAttribute("subdialog", "true");
+    let subdialogRoot = this._frame.contentDocument.documentElement;
+    subdialogRoot.setAttribute("subdialog", "true");
+
+    // Forward the document_color_use attribute to the subdialog
+    let root = document.documentElement;
+    if (root.hasAttribute("document_color_use")) {
+      subdialogRoot.setAttribute("document_color_use", "true");
+    } else {
+      subdialogRoot.removeAttribute("document_color_use");
+    }
 
     this._frame.contentWindow.addEventListener("dialogclosing", this);
 
     let oldResizeBy = this._frame.contentWindow.resizeBy;
     this._frame.contentWindow.resizeBy = (resizeByWidth, resizeByHeight) => {
       // Only handle resizeByHeight currently.
       let frameHeight = this._frame.clientHeight;
       let boxMinHeight = parseFloat(getComputedStyle(this._box).minHeight, 10);
--- a/toolkit/themes/shared/in-content/common.inc.css
+++ b/toolkit/themes/shared/in-content/common.inc.css
@@ -413,28 +413,28 @@ xul|button[type="menu"] > xul|menupopup 
   font-size: 1em;
   color: var(--in-content-text-color);
   padding-top: 0.2em;
   padding-bottom: 0.2em;
   padding-inline-start: 10px;
   padding-inline-end: 30px;
 }
 
-xul|menulist > xul|menupopup > xul|menu:not([disabled="true"])[_moz-menuactive="true"],
-xul|menulist > xul|menupopup > xul|menuitem:not([disabled="true"])[_moz-menuactive="true"],
-xul|button[type="menu"] > xul|menupopup > xul|menu:not([disabled="true"])[_moz-menuactive="true"],
-xul|button[type="menu"] > xul|menupopup > xul|menuitem:not([disabled="true"])[_moz-menuactive="true"] {
+:root:not([document_color_use]) xul|menulist > xul|menupopup > xul|menu:not([disabled="true"])[_moz-menuactive="true"],
+:root:not([document_color_use]) xul|menulist > xul|menupopup > xul|menuitem:not([disabled="true"])[_moz-menuactive="true"],
+:root:not([document_color_use]) xul|button[type="menu"] > xul|menupopup > xul|menu:not([disabled="true"])[_moz-menuactive="true"],
+:root:not([document_color_use]) xul|button[type="menu"] > xul|menupopup > xul|menuitem:not([disabled="true"])[_moz-menuactive="true"] {
   color: var(--in-content-text-color);
   background-color: var(--in-content-item-hover);
 }
 
-xul|menulist > xul|menupopup > xul|menu:not([disabled="true"])[selected="true"],
-xul|menulist > xul|menupopup > xul|menuitem:not([disabled="true"])[selected="true"],
-xul|button[type="menu"] > xul|menupopup > xul|menu:not([disabled="true"])[selected="true"],
-xul|button[type="menu"] > xul|menupopup > xul|menuitem:not([disabled="true"])[selected="true"] {
+:root:not([document_color_use]) xul|menulist > xul|menupopup > xul|menu:not([disabled="true"])[selected="true"],
+:root:not([document_color_use]) xul|menulist > xul|menupopup > xul|menuitem:not([disabled="true"])[selected="true"],
+:root:not([document_color_use]) xul|button[type="menu"] > xul|menupopup > xul|menu:not([disabled="true"])[selected="true"],
+:root:not([document_color_use]) xul|button[type="menu"] > xul|menupopup > xul|menuitem:not([disabled="true"])[selected="true"] {
   color: var(--in-content-selected-text);
   background-color: var(--in-content-item-selected);
 }
 
 xul|menulist > xul|menupopup > xul|menu[disabled="true"],
 xul|menulist > xul|menupopup > xul|menuitem[disabled="true"],
 xul|button[type="menu"] > xul|menupopup > xul|menu[disabled="true"],
 xul|button[type="menu"] > xul|menupopup > xul|menuitem[disabled="true"] {