Bug 910022 - Allow styling of <option> elements color & background color on windows r=jaws
Allows styling of color/background color for options in select dropdowns. Bug still exists with this patch where the selected item of non-styled dropdowns retains the "custombgcolor" attribute.
MozReview-Commit-ID: 2TBawBpvQMR
--- a/toolkit/modules/SelectContentHelper.jsm
+++ b/toolkit/modules/SelectContentHelper.jsm
@@ -231,16 +231,18 @@ function buildOptionListForChildren(node
tagName: tagName,
textContent: textContent,
disabled: child.disabled,
display: cs.display,
// We need to do this for every option element as each one can have
// an individual style set for direction
textDirection: cs.direction,
tooltip: child.title,
+ color: cs.color,
+ backgroundColor: cs.backgroundColor,
// XXX this uses a highlight color when this is the selected element.
// We need to suppress such highlighting in the content process to get
// the option's correct unhighlighted color here.
// We also need to detect default color vs. custom so that a standard
// color does not override color: menutext in the parent.
// backgroundColor: computedStyle.backgroundColor,
// color: computedStyle.color,
children: tagName == 'OPTGROUP' ? buildOptionListForChildren(child) : []
--- a/toolkit/modules/SelectParentHelper.jsm
+++ b/toolkit/modules/SelectParentHelper.jsm
@@ -16,26 +16,28 @@ const MAX_ROWS = 20;
// Interval between autoscrolls
const AUTOSCROLL_INTERVAL = 25;
var currentBrowser = null;
var currentMenulist = null;
var currentZoom = 1;
var closedWithEnter = false;
+var bgColor = "";
this.SelectParentHelper = {
draggedOverPopup: false,
scrollTimer: 0,
populate: function(menulist, items, selectedIndex, zoom) {
// Clear the current contents of the popup
menulist.menupopup.textContent = "";
currentZoom = zoom;
currentMenulist = menulist;
+ bgColor = "";
populateChildren(menulist, items, selectedIndex, zoom);
},
open: function(browser, menulist, rect, isOpenedViaTouch) {
menulist.hidden = false;
currentBrowser = browser;
closedWithEnter = false;
this._registerListeners(browser, menulist.menupopup);
@@ -92,16 +94,20 @@ this.SelectParentHelper = {
switch (event.type) {
case "mouseup":
this.clearScrollTimer();
currentMenulist.menupopup.removeEventListener("mousemove", this);
currentBrowser.messageManager.sendAsyncMessage("Forms:MouseUp", {});
break;
case "mouseover":
+ //This removes the highlighting of the selected element if the select dropdown is styled
+ if (AppConstants.platform == "win" && bgColor != "") {
+ currentMenulist.selectedItem.style.backgroundColor = bgColor;
+ }
currentBrowser.messageManager.sendAsyncMessage("Forms:MouseOver", {});
break;
case "mouseout":
currentBrowser.messageManager.sendAsyncMessage("Forms:MouseOut", {});
break;
case "mousemove":
@@ -209,17 +215,17 @@ this.SelectParentHelper = {
browser.messageManager.removeMessageListener("Forms:UpdateDropDown", this);
},
};
function populateChildren(menulist, options, selectedIndex, zoom,
parentElement = null, isGroupDisabled = false, adjustedTextSize = -1) {
let element = menulist.menupopup;
-
+
// -1 just means we haven't calculated it yet. When we recurse through this function
// we will pass in adjustedTextSize to save on recalculations.
if (adjustedTextSize == -1) {
let win = element.ownerDocument.defaultView;
// Grab the computed text size and multiply it by the remote browser's fullZoom to ensure
// the popup's text size is matched with the content's. We can't just apply a CSS transform
// here as the popup's preferred size is calculated pre-transform.
@@ -232,16 +238,29 @@ function populateChildren(menulist, opti
let item = element.ownerDocument.createElement(isOptGroup ? "menucaption" : "menuitem");
item.setAttribute("label", option.textContent);
item.style.direction = option.textDirection;
item.style.fontSize = adjustedTextSize;
item.hidden = option.display == "none" || (parentElement && parentElement.hidden);
item.setAttribute("tooltiptext", option.tooltip);
+ //For Web Developer Styling of options
+ if (AppConstants.platform == "win" && option.backgroundColor != "" && option.backgroundColor != "transparent") {
+ item.style.backgroundColor = option.backgroundColor;
+ bgColor = option.backgroundColor;
+ item.setAttribute("custombgcolor", "true");
+ } else {
+ item.removeAttribute("custombgcolor");
+ }
+
+ if (AppConstants.platform == "win" && option.color != "" && option.color != "transparent") {
+ item.style.color = option.color;
+ }
+
element.appendChild(item);
// A disabled optgroup disables all of its child options.
let isDisabled = isGroupDisabled || option.disabled;
if (isDisabled) {
item.setAttribute("disabled", "true");
}
--- a/toolkit/themes/windows/global/menu.css
+++ b/toolkit/themes/windows/global/menu.css
@@ -207,16 +207,21 @@ menulist > menupopup > menu {
}
menulist > menupopup > menuitem[_moz-menuactive="true"],
menulist > menupopup > menu[_moz-menuactive="true"] {
background-color: highlight;
color: highlighttext;
}
+menulist > menupopup > menuitem[_moz-menuactive="true"][custombgcolor="true"],
+menulist > menupopup > menu[_moz-menuactive="true"] {
+ filter: invert(100%);
+}
+
menulist > menupopup > menuitem > .menu-iconic-left,
menulist > menupopup > menucaption > .menu-iconic-left,
menulist > menupopup > menu > .menu-iconic-left {
display: none;
}
menulist > menupopup > menuitem > label,
menulist > menupopup > menucaption > label,