Bug 1339966 - Add a pref to disable content styling for <select> and <option>. r?mconley draft
authorJared Wein <jwein@mozilla.com>
Wed, 15 Feb 2017 18:25:31 -0500
changeset 485267 bcf14a027d02744021288815b72264cc207f108e
parent 485266 bb0b61de0265deb69cbdd156123eb7c964f2e15a
child 545977 0adaf6cb1d6bcd3d17ae4d0f47a9bdea59d36f34
push id45690
push userbmo:jaws@mozilla.com
push dateThu, 16 Feb 2017 14:04:32 +0000
reviewersmconley
bugs1339966
milestone54.0a1
Bug 1339966 - Add a pref to disable content styling for <select> and <option>. r?mconley MozReview-Commit-ID: FMSbuHUKLY
browser/base/content/test/general/browser_selectpopup.js
modules/libpref/init/all.js
toolkit/modules/SelectParentHelper.jsm
--- a/browser/base/content/test/general/browser_selectpopup.js
+++ b/browser/base/content/test/general/browser_selectpopup.js
@@ -302,16 +302,17 @@ function* doSelectTests(contentType, dtd
 
   yield BrowserTestUtils.removeTab(tab);
 }
 
 add_task(function* setup() {
   yield SpecialPowers.pushPrefEnv({
     "set": [
       ["dom.select_popup_in_parent.enabled", true],
+      ["dom.forms.select.customstyling", true]
     ]
   });
 });
 
 add_task(function*() {
   yield doSelectTests("text/html", "");
 });
 
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -112,17 +112,16 @@ pref("offline-apps.quota.warn",        5
 // cache compression turned off for now - see bug #715198
 pref("browser.cache.compression_level", 0);
 
 // Don't show "Open with" option on download dialog if true.
 pref("browser.download.forbid_open_with", false);
 
 // Whether or not testing features are enabled.
 pref("dom.quotaManager.testing", false);
-pref("dom.select_popup_in_parent.enabled", false);
 
 // Whether or not indexedDB is enabled.
 pref("dom.indexedDB.enabled", true);
 // Whether or not indexedDB experimental features are enabled.
 pref("dom.indexedDB.experimental", false);
 // Enable indexedDB logging.
 pref("dom.indexedDB.logging.enabled", true);
 // Detailed output in log messages.
@@ -1188,16 +1187,24 @@ pref("dom.forms.datetime.timepicker", fa
 // Support for new @autocomplete values
 pref("dom.forms.autocomplete.experimental", false);
 
 // Enables requestAutocomplete DOM API on forms.
 pref("dom.forms.requestAutocomplete", false);
 
 // Enable search in <select> dropdowns (more than 40 options)
 pref("dom.forms.selectSearch", false);
+// Allow for webpages to provide custom styling for <select>
+// popups. Disabled on Linux due to bug 1338283.
+#ifdef XP_LINUX
+pref("dom.forms.select.customstyling", false);
+#else
+pref("dom.forms.select.customstyling", true);
+#endif
+pref("dom.select_popup_in_parent.enabled", false);
 
 // Enable Directory API. By default, disabled.
 pref("dom.input.dirpicker", false);
 
 // Enables system messages and activities
 pref("dom.sysmsg.enabled", false);
 
 // Enable pre-installed applications.
--- a/toolkit/modules/SelectParentHelper.jsm
+++ b/toolkit/modules/SelectParentHelper.jsm
@@ -18,46 +18,52 @@ const MAX_ROWS = 20;
 // Minimum elements required to show select search
 const SEARCH_MINIMUM_ELEMENTS = 40;
 
 var currentBrowser = null;
 var currentMenulist = null;
 var currentZoom = 1;
 var closedWithEnter = false;
 var selectRect;
+var customStylingEnabled = Services.prefs.getBoolPref("dom.forms.select.customstyling");
 
 this.SelectParentHelper = {
   populate(menulist, items, selectedIndex, zoom, uaBackgroundColor, uaColor,
            uaSelectBackgroundColor, uaSelectColor, selectBackgroundColor, selectColor) {
     // Clear the current contents of the popup
     menulist.menupopup.textContent = "";
     let stylesheet = menulist.querySelector("#ContentSelectDropdownScopedStylesheet");
     if (stylesheet) {
       stylesheet.remove();
     }
 
     let doc = menulist.ownerDocument;
-    stylesheet = doc.createElementNS("http://www.w3.org/1999/xhtml", "style");
-    stylesheet.setAttribute("id", "ContentSelectDropdownScopedStylesheet");
-    stylesheet.scoped = true;
-    stylesheet.hidden = true;
-    stylesheet = menulist.appendChild(stylesheet);
+    let sheet;
+    if (customStylingEnabled) {
+      stylesheet = doc.createElementNS("http://www.w3.org/1999/xhtml", "style");
+      stylesheet.setAttribute("id", "ContentSelectDropdownScopedStylesheet");
+      stylesheet.scoped = true;
+      stylesheet.hidden = true;
+      stylesheet = menulist.appendChild(stylesheet);
+      sheet = stylesheet.sheet;
+    }
 
-    let sheet = stylesheet.sheet;
     let ruleBody = "";
 
     // Some webpages set the <select> backgroundColor to transparent,
     // but they don't intend to change the popup to transparent.
-    if (selectBackgroundColor != uaSelectBackgroundColor &&
+    if (customStylingEnabled &&
+        selectBackgroundColor != uaSelectBackgroundColor &&
         selectBackgroundColor != "transparent" &&
         selectBackgroundColor != selectColor) {
       ruleBody = `background-color: ${selectBackgroundColor};`;
     }
 
-    if (selectColor != uaSelectColor &&
+    if (customStylingEnabled &&
+        selectColor != uaSelectColor &&
         selectColor != selectBackgroundColor &&
         (selectBackgroundColor != "transparent" ||
          selectColor != uaSelectBackgroundColor)) {
       ruleBody += `color: ${selectColor};`;
     }
 
     if (ruleBody) {
       sheet.insertRule(`menupopup {
@@ -240,23 +246,25 @@ function populateChildren(menulist, opti
     item.style.fontSize = adjustedTextSize;
     item.hidden = option.display == "none" || (parentElement && parentElement.hidden);
     // Keep track of which options are hidden by page content, so we can avoid showing
     // them on search input
     item.hiddenByContent = item.hidden;
     item.setAttribute("tooltiptext", option.tooltip);
 
     let ruleBody = "";
-    if (option.backgroundColor &&
+    if (customStylingEnabled &&
+        option.backgroundColor &&
         option.backgroundColor != "transparent" &&
         option.backgroundColor != uaBackgroundColor) {
       ruleBody = `background-color: ${option.backgroundColor};`;
     }
 
-    if (option.color &&
+    if (customStylingEnabled &&
+        option.color &&
         option.color != uaColor) {
       ruleBody += `color: ${option.color};`;
     }
 
     if (ruleBody) {
       sheet.insertRule(`${item.localName}:nth-child(${nthChildIndex}):not([_moz-menuactive="true"]) {
         ${ruleBody}
       }`, 0);