t issues. let selectBackgroundSet = selectStyle["background-color"] != uaStyle["background-color"] || selectStyle.color != uaStyle.color; if (custom) { if (selectStyle["text-shadow"] != "none") { sheet.insertRule( `#ContentSelectDropdown > menupopup > :is(menuitem, menucaption)[_moz-menuactive="true"] { text-shadow: none; }`, 0 ); } for (let property of SUPPORTED_SELECT_PROPERTIES) { let shouldSkip = (function () { if (property == "direction") { // Handled elsewhere. return true; } if (!selectStyle[property]) { return true; } if (property == "background-color") { // This also depends on whether "color" is set. return !selectBackgroundSet; } return selectStyle[property] == uaStyle[property]; })(); if (shouldSkip) { continue; } let value = selectStyle[property]; if (property == "scrollbar-width") { // This needs to actually apply to the relevant scrollbox, because // scrollbar-width doesn't inherit. property = "--content-select-scrollbar-width"; } if (property == "color") { property = "--panel-color"; } menupopup.style.setProperty(property, value); } // Some webpages set the element. * * It attempts to intelligently add per-item CSS rules if the single * item values differ from the parent menu values and attempting to avoid * ending up with the same color of text and background. * * @param {Element} menulist * @param {Array} options * @param {Array} uniqueOptionStyles * @param {number} selectedIndex * @param {Element} parentElement * @param {boolean} isGroupDisabled * @param {boolean} addSearch * @param {number} nthChildIndex * @returns {number} */ populateChildren( menulist, custom, options, uniqueOptionStyles, selectedIndex, parentElement = null, isGroupDisabled = false, addSearch = true, nthChildIndex = 1 ) { let element = menulist.menupopup; let ariaOwns = ""; for (let option of options) { let isOptGroup = option.isOptGroup; let isHR = option.isHR; let xulElement = "menuitem"; if (isOptGroup) { xulElement = "menucaption"; } if (isHR) { xulElement = "menuseparator"; } let item = element.ownerDocument.createXULElement(xulElement); item.hidden = option.display == "none" || (parentElement && parentElement.hidden); if (parentElement) { // In the menupopup, the optgroup is a sibling of its contained options. // For accessibility, we want to preserve the hierarchy such that the // options are inside the optgroup. We do this using aria-owns on the // parent. item.id = "ContentSelectDropdownOption" + nthChildIndex; item.setAttribute("aria-level", "2"); ariaOwns += item.id + " "; } element.appendChild(item); nthChildIndex++; if (isHR) { item.style.color = (custom && option.color) || ""; // Continue early as HRs do not have other attributes. continue; } item.className = `ContentSelectDropdown-item-${option.styleIndex}`; if (isOptGroup) { item.setAttribute("role", "group"); } item.setAttribute("label", option.textContent); // 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); if (uniqueOptionStyles[option.styleIndex].customStyling) { item.setAttribute("customoptionstyling", "true"); } else { item.removeAttribute("customoptionstyling"); } // A disabled optgroup disables all of its child options. let isDisabled = isGroupDisabled || option.disabled; if (isDisabled) { item.setAttribute("disabled", "true"); } if (isOptGroup) { nthChildIndex = this.populateChildren( menulist, custom, option.children, uniqueOptionStyles, selectedIndex, item, isDisabled, false, nthChildIndex ); } else { if (option.index == selectedIndex) { // We expect the parent element of the popup to be a that // has the popuponly attribute set to "true". This is necessary in order // for a to act like a proper dropdown, as // the does things like remember state and set the // _moz-menuactive attribute on the selected . menulist.selectedItem = item; // It's hack time. In the event that we've re-populated the menulist due // to a mutation in the