From 3617dc2de5a3dfb0eff59b1a54a004a0a160b00e Mon Sep 17 00:00:00 2001 From: Gijs Kruitbosch Date: Fri, 5 Mar 2021 00:07:36 +0000 Subject: [PATCH] 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 --- .../prompts/content/commonDialog.css | 84 +++++++++++++++++++ .../prompts/content/commonDialog.xhtml | 2 +- toolkit/modules/SubDialog.jsm | 9 +- .../themes/shared/in-content/common.inc.css | 7 ++ 4 files changed, 98 insertions(+), 4 deletions(-) diff --git a/toolkit/components/prompts/content/commonDialog.css b/toolkit/components/prompts/content/commonDialog.css index 6d91ba32c44a..7ba04b0b5200 100644 --- a/toolkit/components/prompts/content/commonDialog.css +++ b/toolkit/components/prompts/content/commonDialog.css @@ -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; +} +} diff --git a/toolkit/components/prompts/content/commonDialog.xhtml b/toolkit/components/prompts/content/commonDialog.xhtml index 51441187a0f9..da2fe03c8997 100644 --- a/toolkit/components/prompts/content/commonDialog.xhtml +++ b/toolkit/components/prompts/content/commonDialog.xhtml @@ -53,7 +53,7 @@
-
+
diff --git a/toolkit/modules/SubDialog.jsm b/toolkit/modules/SubDialog.jsm index 97f450d4f9c8..ae0bb7f917f3 100644 --- a/toolkit/modules/SubDialog.jsm +++ b/toolkit/modules/SubDialog.jsm @@ -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 (such as manageAddresses.xhtml) diff --git a/toolkit/themes/shared/in-content/common.inc.css b/toolkit/themes/shared/in-content/common.inc.css index 260bb853cf0e..962eaab793a3 100644 --- a/toolkit/themes/shared/in-content/common.inc.css +++ b/toolkit/themes/shared/in-content/common.inc.css @@ -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; +}