Bug 1693277 - fix sizing of dialogs with various content sizes, r=mtigley

This uses the new sizeTo value supported by SubDialog.jsm to also impact
how we size things inside the dialog. It's a bit complicated because we
need the dialog to support 3 layouts:

1. the window-modal setup (which we're trying not to touch)
2. the non-proton modal setup (which uses grid layout to have one column with
   the image and the username/password fields, where applicable)
3. the proton modal setup (where we don't want the grid layout, as
   the labels for username/password go above their text fields and there's no
   big icon on the left, so there's no point)

Finally, for content modal prompts, we need to effectively determine the size
of the content and whether we need to overflow. We can't just always allow
flexbox to shrink everything, or we end up with overflow even for dialogs
with just 2 lines of text.

So with this patch, we determine the ideal height of the dialog document from
SubDialog.jsm, before setting the `.sizeDetermined` class there, thus allowing
the #infoBody part to overflow. The SubDialog.jsm code will ensure the
embedding browser is large enough to allow not overflowing/scrolling the
content.

In terms of the 3 layouts, we select for "not 1" by using `dialog[subdialog]`
(an attribute set by the SubDialog.jsm code anyway). We then use proton
pref-based @supports queries to pick between layouts (2) and (3).

Differential Revision: https://phabricator.services.mozilla.com/D107111
This commit is contained in:
Gijs Kruitbosch 2021-03-05 00:07:36 +00:00
Родитель d81adf55b0
Коммит 3617dc2de5
4 изменённых файлов: 98 добавлений и 4 удалений

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

@ -10,6 +10,7 @@
display: grid;
grid-template-columns: auto 1fr;
align-items: center;
max-height: 100%;
}
.dialogRow:not([hidden]) {
@ -37,6 +38,35 @@
unicode-bidi: plaintext;
}
.sizeDetermined #infoBody {
overflow-y: auto;
}
.sizeDetermined,
.sizeDetermined::part(content-box) {
display: flex;
flex-direction: column;
min-height: 0;
}
@supports not -moz-bool-pref("browser.proton.enabled") {
.sizeDetermined,
.sizeDetermined .dialogRow,
.sizeDetermined #infoContainer {
max-height: 100%;
}
dialog[subdialog] #infoContainer {
display: flex;
flex-direction: column;
overflow: hidden;
}
}
.sizeDetermined > div {
display: contents;
}
#loginLabel, #password1Label {
text-align: end;
}
@ -45,3 +75,57 @@
#password1Textbox {
text-align: match-parent;
}
@supports -moz-bool-pref("browser.proton.enabled") {
/* use flexbox instead of grid: */
dialog[subdialog],
dialog[subdialog] #dialogGrid,
dialog[subdialog] #infoContainer,
dialog[subdialog] .dialogRow:not([hidden]) {
display: flex;
flex-direction: column;
align-items: stretch;
}
dialog[subdialog] #infoContainer {
max-height: 100%;
/* Needed to ensure text wrapping happens correctly. Without this, when
* text wraps unexpectedly, the overall dialog height is off by the height
* of a line of text. */
max-width: calc(100vw - 32px);
}
.sizeDetermined #infoRow {
min-height: 0;
}
dialog[subdialog] #iconContainer {
display: none;
}
/* Fix padding/spacing */
dialog[subdialog] {
/* All the inner items should have 4px inline margin, leading to 16px spacing
* between the dialog and its contents, and 8px horizontal spacing between items. */
padding: 16px 12px;
}
/* Use an ID selector for the dialog to win on specificity... */
#commonDialog[subdialog] label,
#commonDialog[subdialog] description,
#commonDialog[subdialog] checkbox,
#commonDialog[subdialog] input {
margin: 0 4px;
}
/* Add vertical spaces between rows: */
dialog[subdialog] .dialogRow,
dialog[subdialog] #infoTitle {
margin-block: 0 20px;
}
/* Start-align labels: */
#loginLabel, #password1Label {
text-align: start;
}
}

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

@ -53,7 +53,7 @@
<!-- The <div> was added in bug 1606617 to workaround bug 1614447 -->
<div xmlns="http://www.w3.org/1999/xhtml">
<div id="dialogGrid">
<div class="dialogRow">
<div class="dialogRow" id="infoRow">
<div id="iconContainer">
<xul:image id="infoIcon"/>
</div>

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

@ -497,10 +497,15 @@ SubDialog.prototype = {
let frameSizeDifference =
frameRect.top - boxRect.top + (boxRect.bottom - frameRect.bottom);
let contentPane =
this._frame.contentDocument.querySelector(".contentPane") ||
this._frame.contentDocument.querySelector("dialog");
let sizeTo = this._box.getAttribute("sizeto");
if (["available", "limitheight"].includes(sizeTo)) {
if (sizeTo == "limitheight") {
this._overlay.style.setProperty("--doc-height-px", getDocHeight());
contentPane?.classList.add("sizeDetermined");
} else {
// Inform the CSS of the toolbar height so the bottom padding can be
// correctly calculated.
@ -550,9 +555,7 @@ SubDialog.prototype = {
// element is used to implement the subdialog instead.
frameHeight = maxHeight + "px";
frameMinHeight = maxHeight + "px";
let contentPane =
this._frame.contentDocument.querySelector(".contentPane") ||
this._frame.contentDocument.querySelector("dialog");
if (contentPane) {
// There are also instances where the subdialog is neither implemented
// using a content pane, nor a <dialog> (such as manageAddresses.xhtml)

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

@ -1232,3 +1232,10 @@ xul|*.addons-icon {
.back-button:dir(rtl) {
transform: scaleX(-1);
}
/* Adjust vertical margins for buttons in dialogs. We do this here because
* this sheet gets inserted into the Shadow DOM for the button box in the dialog,
* so can actually affect the button styling that way. */
:host(dialog[subdialog]) .dialog-button-box > button {
margin: 0 4px;
}