Bug 861703 - Constrain the maximum height of the menu panel. r=jaws,feedback=Gijs.

This commit is contained in:
Mike Conley 2013-07-27 14:58:36 -04:00
parent ec3ee297fc
commit e34085c006
12 changed files with 202 additions and 129 deletions

View File

@ -24,6 +24,5 @@
<box class="panel-inner-arrowcontentfooter" hidden="true"/>
</box>
</vbox>
<spacer flex="1"/>
</vbox>
</hbox>

View File

@ -19,7 +19,7 @@
.panel-subviews {
-moz-stack-sizing: ignore;
transform: translateX(0);
overflow-y: hidden;
overflow-y: auto;
}
.panel-subviews[panelopen] {

View File

@ -11,13 +11,15 @@
noautofocus="true">
<panelmultiview id="PanelUI-multiView" mainViewId="PanelUI-mainView">
<panelview id="PanelUI-mainView" contextmenu="customizationPanelContextMenu">
<vbox id="PanelUI-contents" type="grid"/>
<vbox id="PanelUI-contents-scroller">
<vbox id="PanelUI-contents"/>
</vbox>
<vbox id="PanelUI-mainView-spring" flex="1"/>
<vbox id="PanelUI-mainView-spring"/>
<footer class="PanelUI-footer">
<footer id="PanelUI-footer">
<toolbarbutton id="PanelUI-customize-btn" label="&appMenuCustomize.label;" tabindex="0"
oncommand="gCustomizeMode.toggle()" flex="1"/>
oncommand="gCustomizeMode.toggle()"/>
<!-- The parentNode is used so that the footer is presented as the anchor
instead of just the button being the anchor. -->
<toolbarbutton id="PanelUI-help-btn" aria-label="&helpMenu.label;" tabindex="0"

View File

@ -4,6 +4,8 @@
XPCOMUtils.defineLazyModuleGetter(this, "CustomizableUI",
"resource:///modules/CustomizableUI.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Promise",
"resource://gre/modules/Promise.jsm");
/**
* Maintains the state and dispatches events for the main menu panel.
*/
@ -22,7 +24,8 @@ const PanelUI = {
multiView: "PanelUI-multiView",
helpView: "PanelUI-help",
menuButton: "PanelUI-menu-button",
panel: "PanelUI-popup"
panel: "PanelUI-popup",
scroller: "PanelUI-contents-scroller"
};
},
@ -93,29 +96,30 @@ const PanelUI = {
if (this.panel.state == "open") {
this.hide();
} else if (this.panel.state == "closed") {
this.ensureRegistered();
this.panel.hidden = false;
let editControlPlacement = CustomizableUI.getPlacementOfWidget("edit-controls");
if (editControlPlacement && editControlPlacement.area == CustomizableUI.AREA_PANEL) {
updateEditUIVisibility();
}
this.ensureReady().then(function() {
this.panel.hidden = false;
let editControlPlacement = CustomizableUI.getPlacementOfWidget("edit-controls");
if (editControlPlacement && editControlPlacement.area == CustomizableUI.AREA_PANEL) {
updateEditUIVisibility();
}
let anchor;
if (aEvent.type == "command") {
anchor = this.menuButton;
} else {
anchor = aEvent.target;
}
let iconAnchor =
document.getAnonymousElementByAttribute(anchor, "class",
"toolbarbutton-icon");
let anchor;
if (aEvent.type == "command") {
anchor = this.menuButton;
} else {
anchor = aEvent.target;
}
let iconAnchor =
document.getAnonymousElementByAttribute(anchor, "class",
"toolbarbutton-icon");
// Only focus the panel if it's opened using the keyboard, so that
// cut/copy/paste buttons will work for mouse users.
let keyboardOpened = aEvent.sourceEvent &&
aEvent.sourceEvent.target.localName == "key";
this.panel.setAttribute("noautofocus", !keyboardOpened);
this.panel.openPopup(iconAnchor || anchor, "bottomcenter topright");
// Only focus the panel if it's opened using the keyboard, so that
// cut/copy/paste buttons will work for mouse users.
let keyboardOpened = aEvent.sourceEvent &&
aEvent.sourceEvent.target.localName == "key";
this.panel.setAttribute("noautofocus", !keyboardOpened);
this.panel.openPopup(iconAnchor || anchor, "bottomcenter topright");
}.bind(this));
}
},
@ -143,22 +147,45 @@ const PanelUI = {
/**
* Registering the menu panel is done lazily for performance reasons. This
* method is exposed so that CustomizationMode can force registration in the
* event that customization mode is started before the panel has had a chance
* to register itself.
* method is exposed so that CustomizationMode can force panel-readyness in the
* event that customization mode is started before the panel has been opened
* by the user.
*
* @param aCustomizing (optional) set to true if this was called while entering
* customization mode. If that's the case, we trust that customization
* mode will handle calling beginBatchUpdate and endBatchUpdate.
*
* @return a Promise that resolves once the panel is ready to roll.
*/
ensureRegistered: function(aCustomizing=false) {
if (aCustomizing) {
CustomizableUI.registerMenuPanel(this.contents);
} else {
this.beginBatchUpdate();
CustomizableUI.registerMenuPanel(this.contents);
this.endBatchUpdate();
}
ensureReady: function(aCustomizing=false) {
return Task.spawn(function() {
if (!this._scrollWidth) {
// In order to properly center the contents of the panel, while ensuring
// that we have enough space on either side to show a scrollbar, we have to
// do a bit of hackery. In particular, we sample the system scrollbar width,
// and then use that to calculate a new width for the scroller.
this._scrollWidth = (yield this._sampleScrollbarWidth()) + "px";
let cstyle = window.getComputedStyle(this.scroller);
let widthStr = cstyle.width;
// Get the calculated padding on the left and right sides of
// the scroller too. We'll use that in our final calculation so
// that if a scrollbar appears, we don't have the contents right
// up against the edge of the scroller.
let paddingLeft = cstyle.paddingLeft;
let paddingRight = cstyle.paddingRight;
let calcStr = [widthStr, this._scrollWidth,
paddingLeft, paddingRight].join(" + ");
this.scroller.style.width = "calc(" + calcStr + ")";
}
if (aCustomizing) {
CustomizableUI.registerMenuPanel(this.contents);
} else {
this.beginBatchUpdate();
CustomizableUI.registerMenuPanel(this.contents);
this.endBatchUpdate();
}
}.bind(this));
},
/**
@ -317,5 +344,35 @@ const PanelUI = {
_onHelpViewHide: function(aEvent) {
this.removeEventListener("command", PanelUI.onCommandHandler);
},
_sampleScrollbarWidth: function() {
let deferred = Promise.defer();
let hwin = Services.appShell.hiddenDOMWindow;
let hdoc = hwin.document.documentElement;
let iframe = hwin.document.createElementNS("http://www.w3.org/1999/xhtml",
"html:iframe");
iframe.setAttribute("srcdoc", '<body style="overflow-y: scroll"></body>');
hdoc.appendChild(iframe);
let cwindow = iframe.contentWindow;
let utils = cwindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
cwindow.addEventListener("load", function onLoad(aEvent) {
cwindow.removeEventListener("load", onLoad);
let sbWidth = {};
try {
utils.getScrollbarSize(true, sbWidth, {});
} catch(e) {
Components.utils.reportError("Could not sample scrollbar size: " + e +
" -- " + e.stack);
sbWidth.value = 0;
}
deferred.resolve(sbWidth.value);
iframe.remove();
});
return deferred.promise;
}
};

View File

@ -8,36 +8,6 @@
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="toolbarbutton" display="xul:button"
extends="chrome://global/content/bindings/button.xml#button-base">
<resources>
<stylesheet src="chrome://global/skin/toolbarbutton.css"/>
</resources>
<content>
<children includes="observes|template|menupopup|panel|tooltip"/>
<xul:hbox align="center" flex="1">
<xul:image class="toolbarbutton-icon" xbl:inherits="validate,src=image,label"/>
<xul:vbox flex="1">
<xul:label class="toolbarbutton-text" crop="right" flex="1"
xbl:inherits="value=label,accesskey,crop"/>
<xul:hbox pack="end">
<xul:label class="toolbarbutton-acceltext" crop="middle"
xbl:inherits="value=acceltext"/>
</xul:hbox>
</xul:vbox>
</xul:hbox>
</content>
<implementation implements="nsIAccessibleProvider">
<property name="accessibleType" readonly="true">
<getter>
return Components.interfaces.nsIAccessibleProvider.XULToolbarButton;
</getter>
</property>
</implementation>
</binding>
<binding id="panelmultiview">
<resources>
<stylesheet src="chrome://browser/content/customizableui/panelUI.css"/>
@ -129,6 +99,7 @@
<constructor><![CDATA[
this._clickCapturer.addEventListener("click", this);
this._panel.addEventListener("popupshowing", this);
this._panel.addEventListener("popupshown", this);
this._panel.addEventListener("popuphidden", this);
this._subViews.addEventListener("overflow", this);
this._mainViewContainer.addEventListener("overflow", this);
@ -156,6 +127,7 @@
this._mainViewObserver.disconnect();
this._subViewObserver.disconnect();
this._panel.removeEventListener("popupshowing", this);
this._panel.removeEventListener("popupshown", this);
this._panel.removeEventListener("popuphidden", this);
this._subViews.removeEventListener("overflow", this);
this._mainViewContainer.removeEventListener("overflow", this);
@ -305,14 +277,28 @@
this.setAttribute("panelopen", "true");
this._syncContainerWithMainView();
break;
case "popupshown":
this._setMaxHeight();
break;
case "popuphidden":
this.removeAttribute("panelopen");
this._mainView.style.height = "";
this.showMainView();
break;
}
]]></body>
</method>
<method name="_setMaxHeight">
<body><![CDATA[
// Ignore the mutation that'll fire when we set the height of
// the main view.
this.ignoreMutations = true;
this._mainView.style.height =
this.getBoundingClientRect().height + "px";
this.ignoreMutations = false;
]]></body>
</method>
<method name="_syncContainerWithSubView">
<body><![CDATA[
if (!this.ignoreMutations && this.showingSubView) {

View File

@ -132,7 +132,7 @@ CustomizeMode.prototype = {
// is really not going to work. We pass "true" to ensureRegistered to
// indicate that we're handling calling startBatchUpdate and
// endBatchUpdate.
window.PanelUI.ensureRegistered(true);
yield window.PanelUI.ensureReady(true);
this._showPanelCustomizationPlaceholders();

View File

@ -3,6 +3,6 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%filter substitution
%define menuPanelWidth 23em
%define menuPanelWidth 21em
%include ../../shared/customizableui/panelUIOverlay.inc.css

View File

@ -1327,10 +1327,6 @@ toolbarbutton.bookmark-item > menupopup {
/* zoom controls */
#zoom-controls {
-moz-box-align: center;
}
#zoom-out-button {
-moz-margin-end: 0;
}

View File

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%filter substitution
%define menuPanelWidth 26em
%define menuPanelWidth 21em
%include ../../shared/customizableui/panelUIOverlay.inc.css
@ -35,3 +35,8 @@ toolbarpaletteitem[place="palette"] > #zoom-controls > #zoom-out-button {
padding-left: 12px;
padding-right: 12px;
}
.panel-combined-item[customizableui-areatype="menu-panel"] > toolbarbutton,
toolbarbutton[customizableui-areatype="menu-panel"] {
margin: 0;
}

View File

@ -15,12 +15,12 @@
}
#main-window[customizing] .customization-target,
#main-window[customizing] #customization-panelHolder > #PanelUI-mainView > #PanelUI-contents > .panel-customization-placeholder {
#PanelUI-contents > .panel-customization-placeholder {
outline: 1px dashed transparent;
}
#main-window[customizing-movingItem] .customization-target,
#main-window[customizing-movingItem] #customization-panelHolder > #PanelUI-mainView > #PanelUI-contents > .panel-customization-placeholder {
#main-window[customizing-movingItem] .panel-customization-placeholder {
outline-color: #bbb;
}
@ -33,6 +33,35 @@
list-style-image: none;
}
#customization-panelHolder {
overflow-y: hidden;
}
#customization-panelWrapper,
#customization-panelWrapper > .panel-arrowcontent {
-moz-box-flex: 1;
}
#customization-panelHolder > #PanelUI-mainView {
display: flex;
flex-direction: column;
/* Hack alert - by manually setting the preferred height to 0, we convince
#PanelUI-mainView to shrink when the window gets smaller in customization
mode. Not sure why that is - might have to do with our intermingling of
XUL flex, and CSS3 Flexbox. */
height: 0;
}
#customization-panelHolder > #PanelUI-mainView > #PanelUI-contents-scroller {
display: flex;
flex: auto;
flex-direction: column;
}
#customization-panelHolder > #PanelUI-mainView > #PanelUI-mainView-spring {
display: none;
}
#main-window[customizing] .customization-target {
min-width: 100px;
padding-left: 10px;
@ -66,7 +95,7 @@
background-repeat: no-repeat, no-repeat, repeat, repeat, no-repeat;
background-size: auto 12px, 12px 100%, auto, auto, auto;
background-attachment: scroll, scroll, fixed, fixed, scroll;
overflow-y: auto;
}
#customization-panelWrapper > .panel-arrowcontent {

View File

@ -13,14 +13,19 @@
transform: translateX(@menuPanelWidth@);
}
#PanelUI-contents[type="list"] > toolbarbutton {
-moz-binding: url("chrome://browser/content/panelUI.xml#toolbarbutton");
}
.panel-viewstack:not([viewtype="main"]) > .panel-mainview > #PanelUI-mainView {
-moz-box-flex: 1;
}
#PanelUI-mainView-spring {
flex: auto;
}
#PanelUI-mainView {
display: flex;
flex-direction: column;
}
.panel-viewstack[viewtype="main"] > .panel-mainview > #PanelUI-mainView > #PanelUI-mainView-spring {
display: none;
}
@ -48,6 +53,11 @@
box-shadow: none;
}
#PanelUI-contents,
.panel-mainview:not([panelid="PanelUI-popup"]) {
padding: .5em 0;
}
#PanelUI-contents > toolbarpaletteitem > toolbaritem > toolbarbutton > .toolbarbutton-text,
#PanelUI-contents > toolbaritem > toolbarbutton > .toolbarbutton-text,
#PanelUI-contents > toolbarpaletteitem > toolbarbutton > .toolbarbutton-text,
@ -55,39 +65,16 @@
font-size: 10px;
}
#PanelUI-contents #wrapper-edit-controls,
#PanelUI-contents #wrapper-zoom-controls {
margin-left: -1em;
margin-right: -1em;
width: calc(100% + 2em);
}
#PanelUI-contents #edit-controls,
#PanelUI-contents #zoom-controls {
padding: 1em 0 0;
}
#PanelUI-contents #edit-controls,
#PanelUI-contents #zoom-controls {
-moz-margin-start: -1em;
-moz-box-align: stretch;
width: calc(100% + 2em);
}
#PanelUI-contents #wrapper-edit-controls #edit-controls,
#PanelUI-contents #wrapper-zoom-controls #zoom-controls {
-moz-margin-start: 0;
}
#PanelUI-contents #edit-controls,
#PanelUI-contents #zoom-controls,
#PanelUI-contents,
.panel-mainview:not([panelid="PanelUI-popup"]) {
max-width: @menuPanelWidth@;
padding: .5em 1em;
}
#PanelUI-contents[type="list"] toolbarbutton > .toolbarbutton-text,
panelview:not([mainview]) .toolbarbutton-text,
#customizationui-widget-panel toolbarbutton > .toolbarbutton-text {
text-align: start;
@ -95,22 +82,20 @@ panelview:not([mainview]) .toolbarbutton-text,
display: -moz-box;
}
#PanelUI-contents[type="list"] toolbarbutton .toolbarbutton-acceltext {
font-size: calc(5em / 6);
color: GrayText;
margin-left: 0;
margin-right: 0;
}
#PanelUI-contents[type="list"] toolbarbutton .toolbarbutton-icon {
min-width: 2em;
max-width: 2em;
min-height: 2em;
max-height: 2em;
}
#PanelUI-contents[type="grid"] {
#PanelUI-contents {
display: block;
flex: auto;
margin-left: auto;
margin-right: auto;
max-width: @menuPanelWidth@;
}
#PanelUI-contents-scroller {
overflow-y: auto;
overflow-x: hidden;
width: @menuPanelWidth@;
padding-left: 5px;
padding-right: 5px;
}
#PanelUI-contents #edit-controls toolbarbutton > .toolbarbutton-icon,
@ -118,7 +103,7 @@ panelview:not([mainview]) .toolbarbutton-text,
-moz-margin-end: 0;
}
#PanelUI-contents[type="grid"] toolbarbutton,
#PanelUI-contents toolbarbutton,
toolbarpaletteitem[place="panel"] > toolbarbutton,
toolbarpaletteitem[place="palette"] > toolbarbutton,
.panel-customization-placeholder {
@ -154,12 +139,22 @@ toolbarpaletteitem[place="palette"] > toolbarbutton,
min-width: 1em;
}
.panel-combined-item[customizableui-areatype="menu-panel"] {
-moz-box-align: stretch;
padding: .5em 0 .5em;
}
.panel-combined-button[disabled] > .toolbarbutton-icon {
opacity: .5;
}
#PanelUI-contents[type="grid"] toolbarbutton > .toolbarbutton-icon,
#customization-palette toolbarbutton > .toolbarbutton-icon {
.panel-customization-placeholder-child > .toolbarbutton-icon,
toolbarbutton[customizableui-areatype="menu-panel"] > .toolbarbutton-icon,
toolbaritem[customizableui-areatype="menu-panel"] > toolbarbutton > .toolbarbutton-icon,
toolbarpaletteitem[place="palette"] > toolbarbutton > .toolbarbutton-icon,
toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton > .toolbarbutton-icon,
toolbarpaletteitem[place="panel"] > toolbarbutton > .toolbarbutton-icon,
toolbarpaletteitem[place="panel"] > toolbaritem > toolbarbutton > .toolbarbutton-icon {
min-width: calc(8em / 3);
min-height: calc(8em / 3);
margin: calc(5em / 12);
@ -185,11 +180,13 @@ toolbarpaletteitem[place="palette"] > toolbarbutton,
display: none;
}
.PanelUI-footer {
#PanelUI-footer {
display: flex;
background-color: rgba(0, 0, 0, 0.05);
border-top: 1px solid rgba(0,0,0,.1);
padding: 0;
margin: 0;
min-height: 4em;
}
#PanelUI-help-btn,
@ -209,6 +206,7 @@ toolbarpaletteitem[place="palette"] > toolbarbutton,
list-style-image: url(chrome://global/skin/icons/question-16.png);
}
#PanelUI-customize-btn {
flex: auto;
-moz-border-end: 1px solid transparent;
list-style-image: url(chrome://browser/skin/menuPanel-small.png);
-moz-image-region: rect(0, 16px, 16px, 0);
@ -304,8 +302,8 @@ panelview toolbarseparator {
height: 16px;
}
.PanelUI-footer.panel-multiview-anchor,
.PanelUI-footer.panel-multiview-anchor > #PanelUI-help-btn,
#PanelUI-footer.panel-multiview-anchor,
#PanelUI-footer.panel-multiview-anchor > #PanelUI-help-btn,
toolbarbutton.panel-multiview-anchor {
background-color: Highlight;
background-image: linear-gradient(rgba(255,255,255,0.3), rgba(255,255,255,0));
@ -313,7 +311,7 @@ toolbarbutton.panel-multiview-anchor {
color: HighlightText;
}
#PanelUI-contents[type="grid"] #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarker,
#PanelUI-contents #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarker,
#customization-palette #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarker {
display: none;
}

View File

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
%filter substitution
%define menuPanelWidth 23em
%define menuPanelWidth 21em
%include ../../shared/customizableui/panelUIOverlay.inc.css
@ -11,6 +11,7 @@
padding-left: 12px;
padding-right: 12px;
}
#PanelUI-contents #zoom-in-btn {
padding-left: 12px;
padding-right: 12px;