Backed out changeset b92093717dcd (bug 1803392) for wp failures on block-page-break-inside-avoid-1-print.html.

This commit is contained in:
Marian-Vasile Laza 2023-02-16 18:20:19 +02:00
parent 79d36cc9bc
commit 8c0dd89bbe
3 changed files with 101 additions and 50 deletions

View File

@ -12,7 +12,6 @@ ChromeUtils.defineESModuleGetters(lazy, {
DialogHandler:
"chrome://remote/content/cdp/domains/parent/page/DialogHandler.sys.mjs",
PollPromise: "chrome://remote/content/shared/Sync.sys.mjs",
print: "chrome://remote/content/shared/PDF.sys.mjs",
streamRegistry: "chrome://remote/content/cdp/domains/parent/IO.sys.mjs",
Stream: "chrome://remote/content/cdp/StreamRegistry.sys.mjs",
TabManager: "chrome://remote/content/shared/TabManager.sys.mjs",
@ -587,6 +586,9 @@ export class Page extends Domain {
throw new TypeError("paperWidth is zero or negative");
}
let path;
let stream;
const psService = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
Ci.nsIPrintSettingsService
);
@ -598,6 +600,37 @@ export class Page extends Domain {
printSettings.printerName = "";
printSettings.printSilent = true;
if (transferMode === PDF_TRANSFER_MODES.stream) {
// If we are returning a stream, we write the PDF to disk so that we don't
// keep (potentially very large) PDFs in memory. We can then stream them
// to the client via the returned Stream.
//
// NOTE: This is a potentially premature optimization -- it might be fine
// to keep these PDFs in memory, but we don't have specifics on how CDP is
// used in the field so it is possible that leaving the PDFs in memory
// could cause a regression.
path = await IOUtils.createUniqueFile(
PathUtils.tempDir,
"remote-agent.pdf"
);
printSettings.outputDestination =
Ci.nsIPrintSettings.kOutputDestinationFile;
printSettings.toFileName = path;
} else {
// If we are returning the data immediately, there is no sense writing it
// to disk only to read it later.
const UINT32_MAX = 0xffffffff;
stream = Cc["@mozilla.org/storagestream;1"].createInstance(
Ci.nsIStorageStream
);
stream.init(4096, UINT32_MAX);
printSettings.outputDestination =
Ci.nsIPrintSettings.kOutputDestinationStream;
printSettings.outputStream = stream.getOutputStream(0);
}
printSettings.paperSizeUnit = Ci.nsIPrintSettings.kPaperSizeInches;
printSettings.paperWidth = paperWidth;
printSettings.paperHeight = paperHeight;
@ -625,35 +658,26 @@ export class Page extends Domain {
printSettings.orientation = Ci.nsIPrintSettings.kLandscapeOrientation;
}
const retval = { data: null, stream: null };
const { linkedBrowser } = this.session.target.tab;
if (transferMode === PDF_TRANSFER_MODES.stream) {
// If we are returning a stream, we write the PDF to disk so that we don't
// keep (potentially very large) PDFs in memory. We can then stream them
// to the client via the returned Stream.
//
// NOTE: This is a potentially premature optimization -- it might be fine
// to keep these PDFs in memory, but we don't have specifics on how CDP is
// used in the field so it is possible that leaving the PDFs in memory
// could cause a regression.
const path = await IOUtils.createUniqueFile(
PathUtils.tempDir,
"remote-agent.pdf"
);
printSettings.outputDestination =
Ci.nsIPrintSettings.kOutputDestinationFile;
printSettings.toFileName = path;
await linkedBrowser.browsingContext.print(printSettings);
await linkedBrowser.browsingContext.print(printSettings);
const retval = { data: null, stream: null };
if (transferMode == PDF_TRANSFER_MODES.stream) {
retval.stream = lazy.streamRegistry.add(new lazy.Stream(path));
} else {
retval.data = await lazy.print.printToEncodedString(
linkedBrowser,
printSettings
const inputStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
Ci.nsIBinaryInputStream
);
inputStream.setInputStream(stream.newInputStream(0));
const available = inputStream.available();
const bytes = inputStream.readBytes(available);
retval.data = btoa(bytes);
stream.close();
}
return retval;

View File

@ -3082,14 +3082,31 @@ GeckoDriver.prototype.print = async function(cmd) {
lazy.assert.array(settings.pageRanges);
const linkedBrowser = this.curBrowser.tab.linkedBrowser;
const printSettings = await lazy.print.getPrintSettings(settings);
const encodedString = await lazy.print.printToEncodedString(
linkedBrowser,
printSettings
);
const filePath = await lazy.print.printToFile(linkedBrowser, settings);
// return all data as a base64 encoded string
let bytes;
try {
bytes = await IOUtils.read(filePath);
} finally {
await IOUtils.remove(filePath);
}
// Each UCS2 character has an upper byte of 0 and a lower byte matching
// the binary data. Splitting the file into chunks to avoid hitting the
// internal argument length limit.
const chunks = [];
// This is the largest power of 2 smaller than MAX_ARGS_LENGTH defined in Spidermonkey
const argLengthLimit = 262144;
for (let offset = 0; offset < bytes.length; offset += argLengthLimit) {
const chunkData = bytes.subarray(offset, offset + argLengthLimit);
chunks.push(String.fromCharCode.apply(null, chunkData));
}
return {
value: encodedString,
value: btoa(chunks.join("")),
};
};

View File

@ -7,6 +7,9 @@ import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs";
const lazy = {};
ChromeUtils.defineESModuleGetters(lazy, {
clearInterval: "resource://gre/modules/Timer.sys.mjs",
setInterval: "resource://gre/modules/Timer.sys.mjs",
assert: "chrome://remote/content/shared/webdriver/Assert.sys.mjs",
Log: "chrome://remote/content/shared/Log.sys.mjs",
});
@ -49,7 +52,7 @@ print.addDefaultSettings = function(settings) {
};
};
print.getPrintSettings = function(settings) {
function getPrintSettings(settings, filePath) {
const psService = Cc["@mozilla.org/gfx/printsettings-service;1"].getService(
Ci.nsIPrintSettingsService
);
@ -61,6 +64,8 @@ print.getPrintSettings = function(settings) {
printSettings.outputFormat = Ci.nsIPrintSettings.kOutputFormatPDF;
printSettings.printerName = "marionette";
printSettings.printSilent = true;
printSettings.outputDestination = Ci.nsIPrintSettings.kOutputDestinationFile;
printSettings.toFileName = filePath;
// Setting the paperSizeUnit to kPaperSizeMillimeters doesn't work on mac
printSettings.paperSizeUnit = Ci.nsIPrintSettings.kPaperSizeInches;
@ -99,7 +104,7 @@ print.getPrintSettings = function(settings) {
}
return printSettings;
};
}
/**
* Convert array of strings of the form ["1-3", "2-4", "7", "9-"] to an flat array of
@ -184,29 +189,34 @@ function parseRanges(ranges) {
return rv;
}
print.printToEncodedString = async function(browser, printSettings) {
// Create a stream to write to.
const stream = Cc["@mozilla.org/storagestream;1"].createInstance(
Ci.nsIStorageStream
print.printToFile = async function(browser, settings) {
// Create a unique filename for the temporary PDF file
const filePath = await IOUtils.createUniqueFile(
PathUtils.tempDir,
"marionette.pdf",
0o600
);
stream.init(4096, 0xffffffff);
printSettings.outputDestination =
Ci.nsIPrintSettings.kOutputDestinationStream;
printSettings.outputStream = stream.getOutputStream(0);
let printSettings = getPrintSettings(settings, filePath);
await browser.browsingContext.print(printSettings);
const inputStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(
Ci.nsIBinaryInputStream
);
// Bug 1603739 - With e10s enabled the promise returned by print() resolves
// too early, which means the file hasn't been completely written.
await new Promise(resolve => {
const DELAY_CHECK_FILE_COMPLETELY_WRITTEN = 100;
inputStream.setInputStream(stream.newInputStream(0));
let lastSize = 0;
const timerId = lazy.setInterval(async () => {
const fileInfo = await IOUtils.stat(filePath);
if (lastSize > 0 && fileInfo.size == lastSize) {
lazy.clearInterval(timerId);
resolve();
}
lastSize = fileInfo.size;
}, DELAY_CHECK_FILE_COMPLETELY_WRITTEN);
});
const available = inputStream.available();
const bytes = inputStream.readBytes(available);
stream.close();
return btoa(bytes);
lazy.logger.debug(`PDF output written to ${filePath}`);
return filePath;
};