Bug 1699430 - allow window-modal dialogs to overlap the URL bar and tabstrip if the window is not tall enough, r=Mardak

There are a few disparate changes in this commit that combine to fix the bug.
In no particular order:
 - set a min-height on windows with toolbars. This extends the minimum
   content size from toolbarless windows to ones with toolbars, on the
   assumption that the overhead from the toolbar and tabs is always
   going to be at least 25px, even in compact mode (it's significantly
   more at the moment). This is also conveniently *just* enough for
   dialogs with a title, body and checkbox, at the default OS font size,
   to be usable (though the bottom can still get a little cut-off).
 - stop assuming there's 30px frame overhead on top of the size of the
   browser in which the dialog is displayed in SubDialog.jsm. This is
   perhaps true in prefs where we display a titlebar outside of the
   browser, but we don't do this for content/tab/window-modal dialogs
   shown in browser.xhtml so the code shouldn't assume. Without this,
   when the window starts off not being tall enough to fit, we were
   losing an additional 30px for no reason.
 - instead of subtracting the 1em padding on the <dialog> that the
   default styling provides (https://searchfox.org/mozilla-central/rev/2f109387cc6886859d3f985ed9aca352fff653b8/layout/style/res/html.css#815 ) just reset it to 0 and stop subtracting it.
 - remove the CSS rule for tab and window-modal dialogs that depends on
   `--doc-height-px`. It is never set, because it is only set for the
   `limitheight` sizeto value in SubDialog.jsm, and the only
   consumer that sets that is at
   https://searchfox.org/mozilla-central/rev/2f109387cc6886859d3f985ed9aca352fff653b8/browser/base/content/browser.js#8988
   for content dialogs.
 - set the margin-top for the window-modal-dialog element from CSS
   instead of from the gDialogBox code in browser.css (now without the 1em
   subtraction, see above).
 - expose the height of the dialog to the parent of the dialog overlay
   from SubDialog.jsm as --inner-height
 - use CSS to ensure the dialog is off-set to be just below chrome
   when its size allows this, and otherwise move it up until it
   fits. There's a code comment explaining this.

Differential Revision: https://phabricator.services.mozilla.com/D114292
This commit is contained in:
Gijs Kruitbosch 2021-05-07 11:49:39 +00:00
Родитель e9d26ebb23
Коммит 4d264245a1
3 изменённых файлов: 27 добавлений и 12 удалений

Просмотреть файл

@ -25,6 +25,7 @@ body {
:root:not([chromehidden~="toolbar"]) {
min-width: 450px;
min-height: 120px;
}
:root[customizing] {
@ -1616,20 +1617,30 @@ toolbar[keyNav=true]:not([collapsed=true], [customizing=true]) toolbartabstop {
grid-auto-rows: min(90%, var(--doc-height-px));
}
#window-modal-dialog > .dialogOverlay > .dialogBox,
.tab-prompt-dialog > .dialogOverlay > .dialogBox:not([sizeto=available]) {
/* For content-prompts, we size the item using the grid-auto-rows.
* For tab and window prompts, where we fully control the content,
* we use the document height directly. */
min-height: var(--doc-height-px);
}
:not(.content-prompt-dialog) > .dialogOverlay > .dialogBox {
/* Make dialogs overlap with upper chrome UI. */
margin-top: -5px;
}
#window-modal-dialog {
overflow: visible;
padding: 0;
--chrome-offset: 20px; /* gets overridden from JS, but pick some default... */
margin-top: max(
/* Do not go below 8px, corresponding to the negative margin above plus
* a tiny bit of space, as otherwise the top of the dialog would be
* adjacent to or clipped by the top of the window. */
8px,
/* Otherwise, use the chrome height,
* or the height of the parent window minus the height of the dialog,
* whichever is smaller. */
min(
var(--chrome-offset),
calc(100vh - var(--inner-height))
)
);
}
.dialogFrame {
margin: 0;
-moz-box-flex: 1;

Просмотреть файл

@ -9472,8 +9472,7 @@ var gDialogBox = {
gBrowser.selectedBrowser
).top;
let parentElement = document.getElementById("window-modal-dialog");
// The dialog has 1em padding; compensate for that:
parentElement.style.marginTop = `calc(${offset}px - 1em)`;
parentElement.style.setProperty("--chrome-offset", offset + "px");
parentElement.style.removeProperty("visibility");
parentElement.style.removeProperty("width");
parentElement.style.removeProperty("height");

Просмотреть файл

@ -245,6 +245,7 @@ SubDialog.prototype = {
this._box.removeAttribute("height");
this._box.style.removeProperty("min-height");
this._box.style.removeProperty("min-width");
this._overlay.parentNode.style.removeProperty("--inner-height");
let onClosed = () => {
this._openedURL = null;
@ -552,7 +553,10 @@ SubDialog.prototype = {
// Now check if the frame height we calculated is possible at this window size,
// accounting for titlebar, padding/border and some spacing.
let maxHeight = this._window.innerHeight - frameSizeDifference - 30;
let maxHeight =
this._window.innerHeight -
frameSizeDifference -
(this._titleBar ? 30 : 0);
// Do this with a frame height in pixels...
let comparisonFrameHeight;
if (frameHeight.endsWith("em")) {
@ -594,6 +598,7 @@ SubDialog.prototype = {
}
this._frame.style.height = frameHeight;
this._overlay.parentNode.style.setProperty("--inner-height", frameHeight);
this._box.style.minHeight =
"calc(" +
(boxVerticalBorder + titleBarHeight + frameVerticalMargin) +