author | Neil Deakin <neil@mozilla.com> |
Fri, 05 Jun 2015 08:33:28 -0400 | |
changeset 247356 | 9c8afe52c600eea9eeb2633bfbb13c2d5a0efe47 |
parent 247355 | 44986f66ee4b590f1a5d7781828477f06ba400b6 |
child 247357 | 45f0d3729d5fabd69476c1e916d10425867f8c87 |
push id | 60685 |
push user | neil@mozilla.com |
push date | Fri, 05 Jun 2015 12:33:54 +0000 |
treeherder | mozilla-inbound@8c81e97e0604 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | neil, felipe |
bugs | 1047713 |
milestone | 41.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/base/content/browser.css +++ b/browser/base/content/browser.css @@ -1017,24 +1017,19 @@ chatbox:-moz-full-screen-ancestor > .cha /* Combobox dropdown renderer */ #ContentSelectDropdown > menupopup { max-height: 350px; /* The menupopup itself should always be rendered LTR to ensure the scrollbar aligns with * the dropdown arrow on the dropdown widget. If a menuitem is RTL, its style will be set accordingly */ direction: ltr; } -.contentSelectDropdown-optgroup { - font-weight: bold; - /* color: menutext used to overwrite the disabled color */ - color: menutext; -} - -.contentSelectDropdown-ingroup { - -moz-margin-start: 2em; +/* Indent options in optgroups */ +.contentSelectDropdown-ingroup .menu-iconic-text { + -moz-padding-start: 2em; } /* Give this menupopup an arrow panel styling */ #BMB_bookmarksPopup { -moz-appearance: none; -moz-binding: url("chrome://browser/content/places/menu.xml#places-popup-arrow"); background: transparent; border: none;
--- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -375,16 +375,18 @@ skip-if = buildapp == 'mulet' || e10s # skip-if = buildapp == 'mulet' [browser_save_video_frame.js] [browser_scope.js] [browser_searchSuggestionUI.js] skip-if = e10s support-files = searchSuggestionUI.html searchSuggestionUI.js +[browser_selectpopup.js] +run-if = e10s [browser_selectTabAtIndex.js] [browser_ssl_error_reports.js] [browser_star_hsts.js] [browser_subframe_favicons_not_used.js] [browser_syncui.js] skip-if = e10s # Bug 1137087 - browser_tabopen_reflows.js fails if this was previously run with e10s [browser_tabDrop.js] skip-if = buildapp == 'mulet' || e10s
new file mode 100644 --- /dev/null +++ b/browser/base/content/test/general/browser_selectpopup.js @@ -0,0 +1,76 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// This test checks that a <select> with an <optgroup> opens and can be navigated +// in a child process. This is different than single-process as a <menulist> is used +// to implement the dropdown list. + +const PAGECONTENT = + "<html><body onload='document.body.firstChild.focus()'><select>" + + " <optgroup label='First Group'>" + + " <option value=One>One" + + " <option value=Two>Two" + + " </optgroup>" + + " <option value=Three>Three" + + " <optgroup label='Second Group'>" + + " <option value=Four>Four" + + " <option value=Five>Five" + + " </optgroup>" + + "</body></html>"; + +function openSelectPopup(selectPopup) +{ + return new Promise((resolve, reject) => { + selectPopup.addEventListener("popupshown", function popupListener(event) { + selectPopup.removeEventListener("popupshown", popupListener, false) + resolve(); + }, false); + setTimeout(() => EventUtils.synthesizeKey("KEY_ArrowDown", { altKey: true, code: "ArrowDown" }), 1500); + }); +} + +function hideSelectPopup(selectPopup) +{ + return new Promise((resolve, reject) => { + selectPopup.addEventListener("popuphidden", function popupListener(event) { + selectPopup.removeEventListener("popuphidden", popupListener, false) + resolve(); + }, false); + EventUtils.synthesizeKey("KEY_Enter", { code: "Enter" }); + }); +} + +add_task(function*() { + let tab = gBrowser.selectedTab = gBrowser.addTab(); + let browser = gBrowser.getBrowserForTab(tab); + yield promiseTabLoadEvent(tab, "data:text/html," + escape(PAGECONTENT)); + + yield SimpleTest.promiseFocus(browser.contentWindow); + + let menulist = document.getElementById("ContentSelectDropdown"); + let selectPopup = menulist.menupopup; + + yield openSelectPopup(selectPopup); + + is(menulist.selectedIndex, 1, "Initial selection"); + is(selectPopup.firstChild.localName, "menucaption", "optgroup is caption"); + is(selectPopup.firstChild.getAttribute("label"), "First Group", "optgroup label"); + is(selectPopup.childNodes[1].localName, "menuitem", "option is menuitem"); + is(selectPopup.childNodes[1].getAttribute("label"), "One", "option label"); + + EventUtils.synthesizeKey("KEY_ArrowDown", { code: "ArrowDown" }); + is(menulist.menuBoxObject.activeChild, menulist.getItemAtIndex(2), "Select item 2"); + + EventUtils.synthesizeKey("KEY_ArrowDown", { code: "ArrowDown" }); + is(menulist.menuBoxObject.activeChild, menulist.getItemAtIndex(3), "Select item 3"); + + EventUtils.synthesizeKey("KEY_ArrowDown", { code: "ArrowDown" }); + is(menulist.menuBoxObject.activeChild, menulist.getItemAtIndex(5), "Skip optgroup header and select item 4"); + + yield hideSelectPopup(selectPopup); + + is(menulist.selectedIndex, 5, "Item 4 still selected selectedIndex"); + + gBrowser.removeCurrentTab(); +}); +
--- a/toolkit/content/widgets/menu.xml +++ b/toolkit/content/widgets/menu.xml @@ -182,16 +182,22 @@ <content> <xul:label class="menu-text" xbl:inherits="value=label,accesskey,crop" crop="right"/> <xul:hbox class="menu-accel-container" anonid="accel"> <xul:label class="menu-accel" xbl:inherits="value=acceltext"/> </xul:hbox> </content> </binding> + <binding id="menucaption" extends="chrome://global/content/bindings/menu.xml#menu-base"> + <content> + <xul:label class="menu-text" xbl:inherits="value=label,crop" crop="right"/> + </content> + </binding> + <binding id="menu-menubar" extends="chrome://global/content/bindings/menu.xml#menu-base"> <content> <xul:label class="menubar-text" xbl:inherits="value=label,accesskey,crop" crop="right"/> <children includes="menupopup"/> </content> </binding> @@ -222,16 +228,26 @@ <xul:hbox class="menu-iconic-left" align="center" pack="center" xbl:inherits="selected,disabled,checked"> <xul:image class="menu-iconic-icon" xbl:inherits="src=image,validate,src"/> </xul:hbox> <xul:label class="menu-iconic-text" flex="1" xbl:inherits="value=label,accesskey,crop" crop="right"/> </content> </binding> + <binding id="menucaption-inmenulist" extends="chrome://global/content/bindings/menu.xml#menucaption"> + <content> + <xul:hbox class="menu-iconic-left" align="center" pack="center" + xbl:inherits="selected,disabled,checked"> + <xul:image class="menu-iconic-icon" xbl:inherits="src=image,validate,src"/> + </xul:hbox> + <xul:label class="menu-iconic-text" flex="1" xbl:inherits="value=label,crop" crop="right"/> + </content> + </binding> + <binding id="menuitem-iconic-desc-noaccel" extends="chrome://global/content/bindings/menu.xml#menuitem"> <content> <xul:hbox class="menu-iconic-left" align="center" pack="center" xbl:inherits="selected,disabled,checked"> <xul:image class="menu-iconic-icon" xbl:inherits="src=image,validate,src"/> </xul:hbox> <xul:label class="menu-iconic-text" xbl:inherits="value=label,accesskey,crop" crop="right" flex="1"/> <xul:label class="menu-iconic-text menu-description" xbl:inherits="value=description" crop="right" flex="10000"/>
--- a/toolkit/content/xul.css +++ b/toolkit/content/xul.css @@ -377,16 +377,20 @@ menuitem[type="checkbox"], menuitem[type="radio"] { -moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic"); } menuitem.menuitem-non-iconic { -moz-binding: url("chrome://global/content/bindings/menu.xml#menubutton-item"); } +menucaption { + -moz-binding: url("chrome://global/content/bindings/menu.xml#menucaption"); +} + .menu-text { -moz-box-flex: 1; } %ifdef MOZ_WIDGET_GTK /********* detection of system setting to use icons in menus ***********/ @media not all and (-moz-images-in-menus) { .menu-iconic-left { @@ -948,16 +952,20 @@ menulist[editable="true"] { menulist[type="description"] { -moz-binding: url("chrome://global/content/bindings/menulist.xml#menulist-description"); } menulist > menupopup > menuitem { -moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic-noaccel"); } +menulist > menupopup > menucaption { + -moz-binding: url("chrome://global/content/bindings/menu.xml#menucaption-inmenulist"); +} + dropmarker { -moz-binding: url("chrome://global/content/bindings/general.xml#dropmarker"); } /********** splitter **********/ splitter { -moz-binding: url("chrome://global/content/bindings/splitter.xml#splitter");
--- a/toolkit/modules/SelectParentHelper.jsm +++ b/toolkit/modules/SelectParentHelper.jsm @@ -60,42 +60,43 @@ this.SelectParentHelper = { _unregisterListeners: function(popup) { popup.removeEventListener("command", this); popup.removeEventListener("popuphidden", this); }, }; -function populateChildren(menulist, options, selectedIndex, startIndex = 0, isGroup = false) { +function populateChildren(menulist, options, selectedIndex, startIndex = 0, isInGroup = false) { let index = startIndex; let element = menulist.menupopup; for (let option of options) { - let item = element.ownerDocument.createElement("menuitem"); + let isOptGroup = (option.tagName == 'OPTGROUP'); + let item = element.ownerDocument.createElement(isOptGroup ? "menucaption" : "menuitem"); + item.setAttribute("label", option.textContent); item.style.direction = option.textDirection; element.appendChild(item); - if (option.children.length > 0) { - item.classList.add("contentSelectDropdown-optgroup"); - item.setAttribute("disabled", "true"); + if (isOptGroup) { index = populateChildren(menulist, option.children, selectedIndex, index, true); } else { if (index == selectedIndex) { // We expect the parent element of the popup to be a <xul:menulist> that // has the popuponly attribute set to "true". This is necessary in order // for a <xul:menupopup> to act like a proper <html:select> dropdown, as // the <xul:menulist> does things like remember state and set the // _moz-menuactive attribute on the selected <xul:menuitem>. menulist.selectedItem = item; } + item.setAttribute("value", index++); - if (isGroup) { + if (isInGroup) { item.classList.add("contentSelectDropdown-ingroup") } } } return index; }
--- a/toolkit/themes/linux/global/menu.css +++ b/toolkit/themes/linux/global/menu.css @@ -7,16 +7,17 @@ ======================================================================= */ @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* ::::: menu/menuitem ::::: */ menu, menuitem, +menucaption, .splitmenu-menuitem { -moz-appearance: menuitem; -moz-box-align: center; max-width: 42em; color: MenuText; font: menu; list-style-image: none; -moz-image-region: auto; @@ -63,16 +64,17 @@ menubar > menu[open] { } menuitem.spell-suggestion { font-weight:bold; } /* ::::: menu/menuitems in menulist popups ::::: */ menulist > menupopup > menuitem, +menulist > menupopup > menucaption, menulist > menupopup > menu { padding: 1px 5px; max-width: none; font: message-box; } /* ..... internal content .... */ @@ -87,16 +89,22 @@ menulist > menupopup > menu { } .menu-text { /* This is (18 + the size of end-padding on .menu-iconic-left)px */ -moz-margin-start: 21px !important; font-weight: inherit; } +menucaption > .menu-text, +menucaption > .menu-iconic-text { + -moz-margin-start: 0 !important; + font-weight: bold; +} + .menu-description { font-style: italic; color: GrayText; -moz-margin-start: 1ex !important; } .menu-accel, .menu-iconic-accel { @@ -144,16 +152,17 @@ menulist > menupopup > menu { .menubar-text { margin: 0 1px !important; color: inherit; } menulist > menupopup > menuitem > .menu-iconic-left, +menulist > menupopup > menucaption > .menu-iconic-left, menulist > menupopup > menu > .menu-iconic-left { display: none; } /* ::::: checkbox menuitem ::::: */ menuitem[checked="true"] { -moz-appearance: checkmenuitem !important;
--- a/toolkit/themes/osx/global/menu.css +++ b/toolkit/themes/osx/global/menu.css @@ -1,16 +1,17 @@ /* 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/. */ @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); menu, -menuitem { +menuitem, +menucaption { -moz-appearance: menuitem; -moz-box-align: center; color: MenuText; font: -moz-pull-down-menu; list-style-image: none; -moz-image-region: auto; padding: 0 21px 2px; } @@ -31,16 +32,21 @@ menuitem[_moz-menuactive="true"][disable } .menu-text, .menu-iconic-text { font-weight: inherit; color: inherit; } +menucaption > .menu-text, +menucaption > .menu-iconic-text { + font-weight: bold; +} + .menu-description { font-style: italic; color: -moz-mac-menutextdisable; -moz-margin-start: 1ex !important; } .menu-iconic-icon { height: 16px; @@ -122,42 +128,45 @@ menubar > menu[_moz-menuactive="true"][o .menubar-text { margin: 0 1px !important; color: inherit; } /* ::::: menu/menuitems in popups ::::: */ menupopup > menu, -menupopup > menuitem { +menupopup > menuitem, +menupopup > menucaption { max-width: 42em; } menu[_moz-menuactive="true"], menuitem[_moz-menuactive="true"] { color: -moz-mac-menutextselect; background-color: Highlight; } /* ::::: menu/menuitems in menulist popups ::::: */ menulist > menupopup > menuitem, +menulist > menupopup > menucaption, menulist > menupopup > menu { max-width: none; font: inherit; color: -moz-FieldText; } /* ::::: menuitems in editable menulist popups ::::: */ -menulist[editable="true"] > menupopup > menuitem { +menulist[editable="true"] > menupopup > menuitem, +menulist[editable="true"] > menupopup > menucaption { -moz-appearance: none; } -menulist[editable="true"] > menupopup > menuitem > .menu-iconic-left { +menulist[editable="true"] > menupopup > :moz-any(menuitem, menucaption) > .menu-iconic-left display: none; } /* ::::: checked menuitems ::::: */ :not(menulist) > menupopup > menuitem[checked="true"], :not(menulist) > menupopup > menuitem[selected="true"] { -moz-appearance: checkmenuitem;
--- a/toolkit/themes/windows/global/menu.css +++ b/toolkit/themes/windows/global/menu.css @@ -7,16 +7,17 @@ ======================================================================= */ @namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* ::::: menu/menuitem ::::: */ menu, menuitem, +menucaption, .splitmenu-menuitem { -moz-appearance: menuitem; -moz-box-align: center; color: MenuText; font: menu; list-style-image: none; -moz-image-region: auto; } @@ -67,16 +68,22 @@ menuitem.spell-suggestion { .menu-text, .menu-iconic-text { font-weight: inherit; -moz-margin-start: 2px !important; -moz-padding-end: 2px; } +menucaption > .menu-text, +menucaption > .menu-iconic-text { + font-weight: bold; + -moz-padding-start: 0 !important; +} + .menu-description { font-style: italic; color: GrayText; -moz-margin-start: 1ex !important; } .menu-accel, .menu-iconic-accel { @@ -168,30 +175,32 @@ menubar > menu:-moz-window-inactive { .menubar-text { margin: 1px 6px 2px 6px !important; color: inherit; } /* ::::: menu/menuitems in popups ::::: */ menupopup > menu, -menupopup > menuitem { +menupopup > menuitem, +menupopup > menucaption { max-width: 42em; } menu[_moz-menuactive="true"], menuitem[_moz-menuactive="true"], .splitmenu-menuitem[_moz-menuactive="true"] { background-color: -moz-menuhover; color: -moz-menuhovertext; } /* ::::: menu/menuitems in menulist popups ::::: */ menulist > menupopup > menuitem, +menulist > menupopup > menucaption, menulist > menupopup > menu { -moz-appearance: none !important; border: 1px solid transparent; -moz-padding-start: 5px; -moz-padding-end: 5px; max-width: none; font: message-box; color: -moz-FieldText; @@ -199,22 +208,24 @@ menulist > menupopup > menu { menulist > menupopup > menuitem[_moz-menuactive="true"], menulist > menupopup > menu[_moz-menuactive="true"] { background-color: highlight; color: highlighttext; } menulist > menupopup > menuitem > .menu-iconic-left, +menulist > menupopup > menucaption > .menu-iconic-left, menulist > menupopup > menu > .menu-iconic-left { display: none; padding-top: 0px; } menulist > menupopup > menuitem > label, +menulist > menupopup > menucaption > label, menulist > menupopup > menu > label { padding-top: 0px; padding-bottom: 0px; } menulist:-moz-focusring > menupopup > menuitem[_moz-menuactive="true"] { border: 1px dotted #F5DB95; } @@ -223,17 +234,17 @@ menulist > menupopup > menuitem[_moz-men color: GrayText; } menulist > menupopup > menuitem[disabled="true"]:not([_moz-menuactive="true"]):-moz-system-metric(windows-classic) { color: GrayText; text-shadow: none; } -menulist > menupopup > menuitem:not(.menuitem-iconic) > .menu-iconic-text { +menulist > menupopup > :moz-any(menuitem, menucaption):not(.menuitem-iconic) > .menu-iconic-text, margin: 0 !important; } /* ::::: checkbox and radio menuitems ::::: */ menuitem[type="checkbox"], menuitem[checked="true"] { -moz-appearance: checkmenuitem;