Bug 1674135 - Don't destroy frames from hideDialog() as we rely on printing hidden frames. r=Gijs

Using `visibility` preserves frames of the content inside the dialog,
which we rely on to print the preview `<browser>` element.

This was working before bug 1662336 mostly by chance, because we were
doing an extra clone and that happened to mostly not rely on the cloned
document being rendered.

I'd rather fix it in the front-end (by not trying to print a
`display: none` <browser>) than going back to do a separate clone,
because that can get expensive (specially with fission).

It's not super-clear to me how to best test the "print from system
dialog" case, but ideas certainly welcome.

Differential Revision: https://phabricator.services.mozilla.com/D95501
This commit is contained in:
Emilio Cobos Álvarez 2020-11-02 19:23:23 +00:00
Родитель fe2014a3ab
Коммит 0ebbb751e6
3 изменённых файлов: 19 добавлений и 4 удалений

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

@ -1450,6 +1450,12 @@ toolbar[keyNav=true]:not([collapsed=true]):not([customizing=true]) toolbartabsto
z-index: 2;
}
.dialogStack.temporarilyHidden {
/* For some printing use cases we need to visually hide the dialog before
* actually closing it / make it disappear from the frame tree. */
visibility: hidden;
}
.dialogOverlay {
visibility: hidden;
}

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

@ -140,6 +140,10 @@ class PrintHelper {
assertDialogHidden() {
is(this._dialogs.length, 1, "There is one print dialog");
ok(BrowserTestUtils.is_hidden(this.dialog._box), "The dialog is hidden");
ok(
this.dialog._box.getBoundingClientRect().width > 0,
"The dialog should still have boxes"
);
}
async assertPrintToFile(file, testFn) {

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

@ -377,7 +377,8 @@ SubDialog.prototype = {
// XXX: Hack to make focus during the dialog's load functions work. Make the element visible
// sooner in DOMContentLoaded but mostly invisible instead of changing visibility just before
// the dialog's load event.
this._overlay.style.visibility = "visible";
// Note that this needs to inherit so that hideDialog() works as expected.
this._overlay.style.visibility = "inherit";
this._overlay.style.opacity = "0.01";
// Ensure the document gets an a11y role of dialog.
@ -450,7 +451,7 @@ SubDialog.prototype = {
detail: { dialog: this },
})
);
this._overlay.style.visibility = "visible";
this._overlay.style.visibility = "inherit";
this._overlay.style.opacity = ""; // XXX: focus hack continued from _onContentLoaded
if (this._box.getAttribute("resizable") == "true") {
@ -885,6 +886,7 @@ class SubDialogManager {
if (!this._dialogs.length) {
// When opening the first dialog, show the dialog stack.
this._dialogStack.hidden = false;
this._dialogStack.classList.remove("temporarilyHidden");
this._topLevelPrevActiveElement = doc.activeElement;
// Mark the top dialog according to the array insertion order.
@ -924,12 +926,14 @@ class SubDialogManager {
}
/**
* Hides the dialog stack for a specific browser.
* Hides the dialog stack for a specific browser, without actually destroying
* frames for stuff within it.
*
* @param aBrowser - The browser associated with the tab dialog.
*/
hideDialog(aBrowser) {
aBrowser.removeAttribute("tabDialogShowing");
this._dialogStack.hidden = true;
this._dialogStack.classList.add("temporarilyHidden");
}
/**
@ -1004,6 +1008,7 @@ class SubDialogManager {
this._topDialog._overlay.setAttribute("topmost", true);
this._topDialog._addDialogEventListeners(false);
this._dialogStack.hidden = false;
this._dialogStack.classList.remove("temporarilyHidden");
} else {
// We have closed the last dialog, do cleanup.
this._topLevelPrevActiveElement.focus();