Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: printToPDF should be headless #33654

Merged
merged 30 commits into from May 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e5ef623
refactor: use headless approach to printToPdf
codebytere Apr 6, 2022
e0482e6
fix: actually resolve pdf data
codebytere Apr 6, 2022
9f74948
fix: reject properly when PDFgeneration fails
codebytere Apr 6, 2022
081d304
refactor: subclass PrintViewManager
codebytere Apr 7, 2022
852e3b0
fix: pdf generation & some settings
codebytere Apr 7, 2022
bc22863
chore: remove unused includes
codebytere Apr 7, 2022
cb9a6d1
chore: nevermind, we're gonna subclass PrintViewManagerBase
codebytere Apr 8, 2022
34ad458
chore: add back mojo bad message calls
codebytere Apr 8, 2022
5589442
refactor: use proper print job constants
codebytere Apr 8, 2022
cee5984
fix: don't run invalid mojom::PrintParamsPtr
codebytere Apr 8, 2022
4467b56
fix: call PrintViewManagerBase' RenderFrameDeleted
codebytere Apr 8, 2022
fd4022f
fix: broken window.print()
codebytere Apr 9, 2022
310a5b0
refactor: snap to Page.printToPDF settings
codebytere Apr 10, 2022
484a338
fix: remove pdf job from vector on completion
codebytere Apr 10, 2022
90dd7a7
fix: don't create composite client
codebytere Apr 10, 2022
ec60693
fix: don't drop support for pageSize
codebytere Apr 10, 2022
4e8100f
fix: use printing::CompletionCallback again
codebytere Apr 10, 2022
53ba1eb
chore: remove patch redundancy
codebytere Apr 10, 2022
483dcb6
test: fix printToPDF parameter types spec
codebytere Apr 11, 2022
69101f9
fix: add back ignore_invalid_page_ranges
codebytere Apr 11, 2022
a492a6e
chore: fix pageRanges param
codebytere Apr 11, 2022
ab7648b
docs: clarify headerTemplate
codebytere May 9, 2022
bf9552d
chore: handle rebase changes
codebytere May 17, 2022
4c29849
3579838: Add failure reason to PrintManagerHost::PrintingFailed()
codebytere May 17, 2022
e64be1b
3583139: Remove support for ignore_invalid_page_ranges when printing PDF
codebytere May 17, 2022
e1473ce
3581548: Pass page ranges rather than list of pages to print in Print…
codebytere May 17, 2022
e4ea2d8
3586363: Introduce PrintRenderFrame.PrintWithParams() for batch print…
codebytere May 17, 2022
a88c111
3583239: Pass max uint value for end of open page range
codebytere May 17, 2022
db2be74
chore: fixup lint
codebytere May 18, 2022
b99e2d7
chore: update patches
patchup[bot] May 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 0 additions & 2 deletions BUILD.gn
Expand Up @@ -667,8 +667,6 @@ source_set("electron_lib") {

if (enable_basic_printing) {
sources += [
"shell/browser/printing/print_preview_message_handler.cc",
"shell/browser/printing/print_preview_message_handler.h",
"shell/browser/printing/print_view_manager_electron.cc",
"shell/browser/printing/print_view_manager_electron.h",
"shell/renderer/printing/print_render_frame_helper_delegate.cc",
Expand Down
2 changes: 2 additions & 0 deletions chromium_src/BUILD.gn
Expand Up @@ -216,6 +216,8 @@ static_library("chrome") {
"//chrome/browser/printing/printer_query.h",
"//chrome/browser/printing/printing_service.cc",
"//chrome/browser/printing/printing_service.h",
"//components/printing/browser/print_to_pdf/pdf_print_utils.cc",
"//components/printing/browser/print_to_pdf/pdf_print_utils.h",
]

if (enable_oop_printing) {
Expand Down
53 changes: 20 additions & 33 deletions docs/api/web-contents.md
Expand Up @@ -1428,7 +1428,7 @@ Returns `Promise<PrinterInfo[]>` - Resolves with a [`PrinterInfo[]`](structures/
* `header` string (optional) - string to be printed as page header.
* `footer` string (optional) - string to be printed as page footer.
* `pageSize` string | Size (optional) - Specify page size of the printed document. 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`.
* `callback` Function (optional)
* `success` boolean - Indicates success of the print call.
* `failureReason` string - Error description called back if the print fails.
Expand Down Expand Up @@ -1459,43 +1459,28 @@ win.webContents.print(options, (success, errorType) => {
#### `contents.printToPDF(options)`

* `options` Object
* `headerFooter` Record<string, string> (optional) - the header and footer for the PDF.
* `title` string - The title for the PDF header.
* `url` string - the url for the PDF footer.
* `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.
* `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 - Index of the first page to print (0-based).
* `to` number - Index of the last page to print (inclusive) (0-based).
* `pageSize` string | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
`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.
* `landscape` boolean (optional) - Paper orientation.`true` for landscape, `false` for portrait. Defaults to false.
* `displayHeaderFooter` boolean (optional) - Whether to display header and footer. Defaults to false.
* `printBackground` boolean (optional) - Whether to print background graphics. Defaults to false.
* `scale` number(optional) - Scale of the webpage rendering. Defaults to 1.
* `pageSize` string | Size (optional) - Specify page size of the generated PDF. Can be `A0`, `A1`, `A2`, `A3`,
`A4`, `A5`, `A6`, `Legal`, `Letter`, `Tabloid`, `Ledger`, or an Object containing `height` and `width` in inches. Defaults to `Letter`.
* `margins` Object (optional)
* `top` number (optional) - Top margin in inches. Defaults to 1cm (~0.4 inches).
* `bottom` number (optional) - Bottom margin in inches. Defaults to 1cm (~0.4 inches).
* `left` number (optional) - Left margin in inches. Defaults to 1cm (~0.4 inches).
* `right` number (optional) - Right margin in inches. Defaults to 1cm (~0.4 inches).
* `pageRanges` string (optional) - Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages.
* `headerTemplate` string (optional) - HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them: `date` (formatted print date), `title` (document title), `url` (document location), `pageNumber` (current page number) and `totalPages` (total pages in the document). For example, `<span class=title></span>` would generate span containing the title.
* `footerTemplate` string (optional) - HTML template for the print footer. Should use the same format as the `headerTemplate`.
* `preferCSSPageSize` boolean (optional) - Whether or not to prefer page size as defined by css. Defaults to false, in which case the content will be scaled to fit the paper size.

Returns `Promise<Buffer>` - Resolves with the generated PDF data.

Prints window's web page as PDF with Chromium's preview printing custom
settings.
Prints the window's web page as PDF.

The `landscape` will be ignored if `@page` CSS at-rule is used in the web page.

By default, an empty `options` will be regarded as:

```javascript
{
marginsType: 0,
printBackground: false,
printSelectionOnly: false,
landscape: false,
pageSize: 'A4',
scaleFactor: 100
}
```

Use `page-break-before: always;` CSS style to force to print to a new page.

An example of `webContents.printToPDF`:

```javascript
Expand All @@ -1504,7 +1489,7 @@ const fs = require('fs')
const path = require('path')
const os = require('os')

const win = new BrowserWindow({ width: 800, height: 600 })
const win = new BrowserWindow()
win.loadURL('http://github.com')

win.webContents.on('did-finish-load', () => {
Expand All @@ -1521,6 +1506,8 @@ win.webContents.on('did-finish-load', () => {
})
```

See [Page.printToPdf](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF) for more information.

#### `contents.addWorkSpace(path)`

* `path` string
Expand Down
30 changes: 15 additions & 15 deletions docs/api/webview-tag.md
Expand Up @@ -565,21 +565,21 @@ Prints `webview`'s web page. Same as `webContents.print([options])`.
### `<webview>.printToPDF(options)`

* `options` Object
* `headerFooter` Record<string, string> (optional) - the header and footer for the PDF.
* `title` string - The title for the PDF header.
* `url` string - the url for the PDF footer.
* `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. On macOS, only the first range is honored.
* `from` number - Index of the first page to print (0-based).
* `to` number - Index of the last page to print (inclusive) (0-based).
* `pageSize` string | Size (optional) - Specify page size of the generated PDF. Can be `A3`,
`A4`, `A5`, `Legal`, `Letter`, `Tabloid` or an Object containing `height`
* `printBackground` boolean (optional) - Whether to print CSS backgrounds.
* `printSelectionOnly` boolean (optional) - Whether to print selection only.
* `landscape` boolean (optional) - Paper orientation.`true` for landscape, `false` for portrait. Defaults to false.
* `displayHeaderFooter` boolean (optional) - Whether to display header and footer. Defaults to false.
* `printBackground` boolean (optional) - Whether to print background graphics. Defaults to false.
* `scale` number(optional) - Scale of the webpage rendering. Defaults to 1.
* `pageSize` string | Size (optional) - Specify page size of the generated PDF. Can be `A0`, `A1`, `A2`, `A3`,
`A4`, `A5`, `A6`, `Legal`, `Letter`, `Tabloid`, `Ledger`, or an Object containing `height` and `width` in inches. Defaults to `Letter`.
* `margins` Object (optional)
* `top` number (optional) - Top margin in inches. Defaults to 1cm (~0.4 inches).
* `bottom` number (optional) - Bottom margin in inches. Defaults to 1cm (~0.4 inches).
* `left` number (optional) - Left margin in inches. Defaults to 1cm (~0.4 inches).
* `right` number (optional) - Right margin in inches. Defaults to 1cm (~0.4 inches).
* `pageRanges` string (optional) - Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages.
* `headerTemplate` string (optional) - HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them: `date` (formatted print date), `title` (document title), `url` (document location), `pageNumber` (current page number) and `totalPages` (total pages in the document). For example, `<span class=title></span>` would generate span containing the title.
* `footerTemplate` string (optional) - HTML template for the print footer. Should use the same format as the `headerTemplate`.
* `preferCSSPageSize` boolean (optional) - Whether or not to prefer page size as defined by css. Defaults to false, in which case the content will be scaled to fit the paper size.

Returns `Promise<Uint8Array>` - Resolves with the generated PDF data.

Expand Down
55 changes: 55 additions & 0 deletions docs/breaking-changes.md
Expand Up @@ -14,6 +14,61 @@ This document uses the following convention to categorize breaking changes:

## Planned Breaking API Changes (20.0)

### API Changed: `webContents.printToPDF()`

`webContents.printToPDF()` has been modified to conform to [`Page.printToPDF`](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-printToPDF) in the Chrome DevTools Protocol. This has been changes in order to
address changes upstream that made our previous implementation untenable and rife with bugs.

**Arguments Changed**

* `pageRanges`

**Arguments Removed**

* `printSelectionOnly`
* `marginsType`
* `headerFooter`
* `scaleFactor`

**Arguments Added**

* `headerTemplate`
* `footerTemplate`
* `displayHeaderFooter`
* `margins`
* `scale`
* `preferCSSPageSize`

```js
// Main process
const { webContents } = require('electron')

webContents.printToPDF({
landscape: true,
displayHeaderFooter: true,
printBackground: true,
scale: 2,
pageSize: 'Ledger',
margins: {
top: 2,
bottom: 2,
left: 2,
right: 2
},
pageRanges: '1-5, 8, 11-13',
headerTemplate: '<h1>Title</h1>',
footerTemplate: '<div><span class="pageNumber"></span></div>',
preferCSSPageSize: true
}).then(data => {
fs.writeFile(pdfPath, data, (error) => {
if (error) throw error
console.log(`Wrote PDF successfully to ${pdfPath}`)
})
}).catch(error => {
console.log(`Failed to write PDF to ${pdfPath}: `, error)
})
```

### Default Changed: renderers without `nodeIntegration: true` are sandboxed by default

Previously, renderers that specified a preload script defaulted to being
Expand Down