fix: always callback error with invalid print settings (#24476)
This commit is contained in:
parent
5737fda154
commit
6c4017ff45
4 changed files with 65 additions and 14 deletions
|
@ -1311,6 +1311,8 @@ Returns [`PrinterInfo[]`](structures/printer-info.md)
|
|||
* `success` Boolean - Indicates success of the print call.
|
||||
* `failureReason` String - Error description called back if the print fails.
|
||||
|
||||
When a custom `pageSize` is passed, Chromium attempts to validate platform specific minumum values for `width_microns` and `height_microns`. Width and height must both be minimum 353 microns but may be higher on some operating systems.
|
||||
|
||||
Prints window's web page. When `silent` is set to `true`, Electron will pick
|
||||
the system's default printer if `deviceName` is empty and the default settings for printing.
|
||||
|
||||
|
@ -1334,13 +1336,12 @@ win.webContents.print(options, (success, errorType) => {
|
|||
* `landscape` Boolean (optional) - `true` for landscape, `false` for portrait.
|
||||
* `marginsType` Integer (optional) - Specifies the type of margins to use. Uses 0 for
|
||||
default margin, 1 for no margin, and 2 for minimum margin.
|
||||
and `width` in microns.
|
||||
* `scaleFactor` Number (optional) - The scale factor of the web page. Can range from 0 to 100.
|
||||
* `pageRanges` Record<string, number> (optional) - The page range to print.
|
||||
* `from` Number - the first page to print.
|
||||
* `to` Number - the last page to print (inclusive).
|
||||
* `pageSize` String | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`
|
||||
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height` and `width` in microns.
|
||||
* `printBackground` Boolean (optional) - Whether to print CSS backgrounds.
|
||||
* `printSelectionOnly` Boolean (optional) - Whether to print selection only.
|
||||
|
||||
|
|
|
@ -72,6 +72,19 @@ const PDFPageSizes: Record<string, MediaSize> = {
|
|||
}
|
||||
};
|
||||
|
||||
// The minimum micron size Chromium accepts is that where:
|
||||
// Per printing/units.h:
|
||||
// * kMicronsPerInch - Length of an inch in 0.001mm unit.
|
||||
// * kPointsPerInch - Length of an inch in CSS's 1pt unit.
|
||||
//
|
||||
// Formula: (kPointsPerInch / kMicronsPerInch) * size >= 1
|
||||
//
|
||||
// Practically, this means microns need to be > 352 microns.
|
||||
// We therefore need to verify this or it will silently fail.
|
||||
const isValidCustomPageSize = (width: number, height: number) => {
|
||||
return [width, height].every(x => x > 352);
|
||||
};
|
||||
|
||||
// Default printing setting
|
||||
const defaultPrintingSetting = {
|
||||
// Customizable.
|
||||
|
@ -315,13 +328,20 @@ WebContents.prototype.printToPDF = function (options) {
|
|||
const error = new Error('height and width properties are required for pageSize');
|
||||
return Promise.reject(error);
|
||||
}
|
||||
// Dimensions in Microns
|
||||
// 1 meter = 10^6 microns
|
||||
|
||||
// Dimensions in Microns - 1 meter = 10^6 microns
|
||||
const height = Math.ceil(pageSize.height);
|
||||
const width = Math.ceil(pageSize.width);
|
||||
if (!isValidCustomPageSize(width, height)) {
|
||||
const error = new Error('height and width properties must be minimum 352 microns.');
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
printSettings.mediaSize = {
|
||||
name: 'CUSTOM',
|
||||
custom_display_name: 'Custom',
|
||||
height_microns: Math.ceil(pageSize.height),
|
||||
width_microns: Math.ceil(pageSize.width)
|
||||
height_microns: height,
|
||||
width_microns: width
|
||||
};
|
||||
} else if (Object.prototype.hasOwnProperty.call(PDFPageSizes, pageSize)) {
|
||||
printSettings.mediaSize = PDFPageSizes[pageSize];
|
||||
|
@ -356,12 +376,19 @@ WebContents.prototype.print = function (options = {}, callback) {
|
|||
if (!pageSize.height || !pageSize.width) {
|
||||
throw new Error('height and width properties are required for pageSize');
|
||||
}
|
||||
|
||||
// Dimensions in Microns - 1 meter = 10^6 microns
|
||||
const height = Math.ceil(pageSize.height);
|
||||
const width = Math.ceil(pageSize.width);
|
||||
if (!isValidCustomPageSize(width, height)) {
|
||||
throw new Error('height and width properties must be minimum 352 microns.');
|
||||
}
|
||||
|
||||
(options as any).mediaSize = {
|
||||
name: 'CUSTOM',
|
||||
custom_display_name: 'Custom',
|
||||
height_microns: Math.ceil(pageSize.height),
|
||||
width_microns: Math.ceil(pageSize.width)
|
||||
height_microns: height,
|
||||
width_microns: width
|
||||
};
|
||||
} else if (PDFPageSizes[pageSize]) {
|
||||
(options as any).mediaSize = PDFPageSizes[pageSize];
|
||||
|
|
|
@ -90,7 +90,7 @@ index adb208ba3589e32536527219aaf4e89e3ee3311a..301f6416898445eed814d67901254ef8
|
|||
}
|
||||
|
||||
diff --git a/chrome/browser/printing/print_view_manager_base.cc b/chrome/browser/printing/print_view_manager_base.cc
|
||||
index 8a743d0dd74b087059ff812019ae568a22c5fa01..20c43be03706617a276d210190897dc473bbd0da 100644
|
||||
index 8a743d0dd74b087059ff812019ae568a22c5fa01..551dbc7b0bfdbf4ca549278bb3dfc4e3abb5cf0f 100644
|
||||
--- a/chrome/browser/printing/print_view_manager_base.cc
|
||||
+++ b/chrome/browser/printing/print_view_manager_base.cc
|
||||
@@ -27,10 +27,7 @@
|
||||
|
@ -194,7 +194,19 @@ index 8a743d0dd74b087059ff812019ae568a22c5fa01..20c43be03706617a276d210190897dc4
|
|||
#endif
|
||||
|
||||
ReleasePrinterQuery();
|
||||
@@ -463,9 +476,13 @@ void PrintViewManagerBase::OnNotifyPrintJobEvent(
|
||||
@@ -382,6 +395,11 @@ void PrintViewManagerBase::OnScriptedPrint(
|
||||
}
|
||||
|
||||
void PrintViewManagerBase::OnShowInvalidPrinterSettingsError() {
|
||||
+ if (!callback_.is_null()) {
|
||||
+ std::string cb_str = "Invalid printer settings";
|
||||
+ std::move(callback_).Run(printing_succeeded_, cb_str);
|
||||
+ }
|
||||
+
|
||||
base::ThreadTaskRunnerHandle::Get()->PostTask(
|
||||
FROM_HERE, base::BindOnce(&ShowWarningMessageBox,
|
||||
l10n_util::GetStringUTF16(
|
||||
@@ -463,9 +481,13 @@ void PrintViewManagerBase::OnNotifyPrintJobEvent(
|
||||
content::NotificationService::NoDetails());
|
||||
break;
|
||||
}
|
||||
|
@ -210,7 +222,7 @@ index 8a743d0dd74b087059ff812019ae568a22c5fa01..20c43be03706617a276d210190897dc4
|
|||
NOTREACHED();
|
||||
break;
|
||||
}
|
||||
@@ -560,8 +577,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
@@ -560,8 +582,10 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
DCHECK(!quit_inner_loop_);
|
||||
DCHECK(query);
|
||||
|
||||
|
@ -223,7 +235,7 @@ index 8a743d0dd74b087059ff812019ae568a22c5fa01..20c43be03706617a276d210190897dc4
|
|||
|
||||
// We can't print if there is no renderer.
|
||||
if (!web_contents()->GetRenderViewHost() ||
|
||||
@@ -582,8 +601,6 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
@@ -582,8 +606,6 @@ bool PrintViewManagerBase::CreateNewPrintJob(
|
||||
print_job_->SetSource(source, /*source_id=*/"");
|
||||
#endif
|
||||
|
||||
|
@ -232,7 +244,7 @@ index 8a743d0dd74b087059ff812019ae568a22c5fa01..20c43be03706617a276d210190897dc4
|
|||
printing_succeeded_ = false;
|
||||
return true;
|
||||
}
|
||||
@@ -632,14 +649,22 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
@@ -632,14 +654,22 @@ void PrintViewManagerBase::ReleasePrintJob() {
|
||||
content::RenderFrameHost* rfh = printing_rfh_;
|
||||
printing_rfh_ = nullptr;
|
||||
|
||||
|
@ -257,7 +269,7 @@ index 8a743d0dd74b087059ff812019ae568a22c5fa01..20c43be03706617a276d210190897dc4
|
|||
// Don't close the worker thread.
|
||||
print_job_ = nullptr;
|
||||
}
|
||||
@@ -675,7 +700,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
@@ -675,7 +705,7 @@ bool PrintViewManagerBase::RunInnerMessageLoop() {
|
||||
}
|
||||
|
||||
bool PrintViewManagerBase::OpportunisticallyCreatePrintJob(int cookie) {
|
||||
|
|
|
@ -141,6 +141,17 @@ describe('webContents module', () => {
|
|||
}).to.throw('Unsupported pageSize: i-am-a-bad-pagesize');
|
||||
});
|
||||
|
||||
it('throws when an invalid custom pageSize is passed', () => {
|
||||
expect(() => {
|
||||
w.webContents.print({
|
||||
pageSize: {
|
||||
width: 100,
|
||||
height: 200
|
||||
}
|
||||
});
|
||||
}).to.throw('height and width properties must be minimum 352 microns.');
|
||||
});
|
||||
|
||||
it('does not crash with custom margins', () => {
|
||||
expect(() => {
|
||||
w.webContents.print({
|
||||
|
|
Loading…
Reference in a new issue