diff --git a/docs/api.md b/docs/api.md index 186d72e896..c7f0ef5984 100644 --- a/docs/api.md +++ b/docs/api.md @@ -122,7 +122,6 @@ - [page.mainFrame()](#pagemainframe) - [page.metrics()](#pagemetrics) - [page.mouse](#pagemouse) - - [page.pdf([options])](#pagepdfoptions) - [page.queryObjects(prototypeHandle)](#pagequeryobjectsprototypehandle) - [page.reload([options])](#pagereloadoptions) - [page.screenshot([options])](#pagescreenshotoptions) @@ -1659,74 +1658,6 @@ Page is guaranteed to have a main frame which persists during navigations. - returns: <[Mouse]> -#### page.pdf([options]) -- `options` <[Object]> Options object which might have the following properties: - - `path` <[string]> The file path to save the PDF to. If `path` is a relative path, then it is resolved relative to [current working directory](https://nodejs.org/api/process.html#process_process_cwd). If no path is provided, the PDF won't be saved to the disk. - - `scale` <[number]> Scale of the webpage rendering. Defaults to `1`. Scale amount must be between 0.1 and 2. - - `displayHeaderFooter` <[boolean]> Display header and footer. Defaults to `false`. - - `headerTemplate` <[string]> 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 - - `totalPages` total pages in the document - - `footerTemplate` <[string]> HTML template for the print footer. Should use the same format as the `headerTemplate`. - - `printBackground` <[boolean]> Print background graphics. Defaults to `false`. - - `landscape` <[boolean]> Paper orientation. Defaults to `false`. - - `pageRanges` <[string]> Paper ranges to print, e.g., '1-5, 8, 11-13'. Defaults to the empty string, which means print all pages. - - `format` <[string]> Paper format. If set, takes priority over `width` or `height` options. Defaults to 'Letter'. - - `width` <[string]|[number]> Paper width, accepts values labeled with units. - - `height` <[string]|[number]> Paper height, accepts values labeled with units. - - `margin` <[Object]> Paper margins, defaults to none. - - `top` <[string]|[number]> Top margin, accepts values labeled with units. - - `right` <[string]|[number]> Right margin, accepts values labeled with units. - - `bottom` <[string]|[number]> Bottom margin, accepts values labeled with units. - - `left` <[string]|[number]> Left margin, accepts values labeled with units. - - `preferCSSPageSize` <[boolean]> Give any CSS `@page` size declared in the page priority over what is declared in `width` and `height` or `format` options. Defaults to `false`, which will scale the content to fit the paper size. -- returns: <[Promise]<[Buffer]>> Promise which resolves with PDF buffer. - -> **NOTE** Generating a pdf is currently only supported in Chrome headless. - -`page.pdf()` generates a pdf of the page with `print` css media. To generate a pdf with `screen` media, call [page.emulateMedia('screen')](#pageemulatemediamediatype) before calling `page.pdf()`: - -> **NOTE** By default, `page.pdf()` generates a pdf with modified colors for printing. Use the [`-webkit-print-color-adjust`](https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-print-color-adjust) property to force rendering of exact colors. - -```js -// Generates a PDF with 'screen' media type. -await page.emulateMedia('screen'); -await page.pdf({path: 'page.pdf'}); -``` - -The `width`, `height`, and `margin` options accept values labeled with units. Unlabeled values are treated as pixels. - -A few examples: -- `page.pdf({width: 100})` - prints with width set to 100 pixels -- `page.pdf({width: '100px'})` - prints with width set to 100 pixels -- `page.pdf({width: '10cm'})` - prints with width set to 10 centimeters. - -All possible units are: -- `px` - pixel -- `in` - inch -- `cm` - centimeter -- `mm` - millimeter - -The `format` options are: -- `Letter`: 8.5in x 11in -- `Legal`: 8.5in x 14in -- `Tabloid`: 11in x 17in -- `Ledger`: 17in x 11in -- `A0`: 33.1in x 46.8in -- `A1`: 23.4in x 33.1in -- `A2`: 16.54in x 23.4in -- `A3`: 11.7in x 16.54in -- `A4`: 8.27in x 11.7in -- `A5`: 5.83in x 8.27in -- `A6`: 4.13in x 5.83in - -> **NOTE** `headerTemplate` and `footerTemplate` markup have the following limitations: -> 1. Script tags inside templates are not evaluated. -> 2. Page styles are not visible inside templates. - #### page.queryObjects(prototypeHandle) - `prototypeHandle` <[JSHandle]> A handle to the object prototype. - returns: <[Promise]<[JSHandle]>> Promise which resolves to a handle to an array of objects with this prototype. diff --git a/src/chromium/Page.ts b/src/chromium/Page.ts index 13a85ba543..ae6a1ae7e5 100644 --- a/src/chromium/Page.ts +++ b/src/chromium/Page.ts @@ -28,7 +28,7 @@ import { Events } from '../Events'; import { Frame } from './Frame'; import { FrameManager, FrameManagerEvents } from './FrameManager'; import { assert, debugError, helper } from '../helper'; -import { readProtocolStream, releaseObject, getExceptionMessage, valueFromRemoteObject } from './protocolHelper'; +import { releaseObject, getExceptionMessage, valueFromRemoteObject } from './protocolHelper'; import { Keyboard, Mouse, Touchscreen } from './Input'; import { createJSHandle, ElementHandle, JSHandle, ClickOptions, PointerActionOptions, MultiClickOptions } from './JSHandle'; import { Response, NetworkManagerEvents } from './NetworkManager'; @@ -736,57 +736,6 @@ export class Page extends EventEmitter { } } - async pdf(options: PDFOptions = {}): Promise { - const { - scale = 1, - displayHeaderFooter = false, - headerTemplate = '', - footerTemplate = '', - printBackground = false, - landscape = false, - pageRanges = '', - preferCSSPageSize = false, - margin = {}, - path = null - } = options; - - let paperWidth = 8.5; - let paperHeight = 11; - if (options.format) { - const format = PagePaperFormats[options.format.toLowerCase()]; - assert(format, 'Unknown paper format: ' + options.format); - paperWidth = format.width; - paperHeight = format.height; - } else { - paperWidth = convertPrintParameterToInches(options.width) || paperWidth; - paperHeight = convertPrintParameterToInches(options.height) || paperHeight; - } - - const marginTop = convertPrintParameterToInches(margin.top) || 0; - const marginLeft = convertPrintParameterToInches(margin.left) || 0; - const marginBottom = convertPrintParameterToInches(margin.bottom) || 0; - const marginRight = convertPrintParameterToInches(margin.right) || 0; - - const result = await this._client.send('Page.printToPDF', { - transferMode: 'ReturnAsStream', - landscape, - displayHeaderFooter, - headerTemplate, - footerTemplate, - printBackground, - scale, - paperWidth, - paperHeight, - marginTop, - marginBottom, - marginLeft, - marginRight, - pageRanges, - preferCSSPageSize - }); - return await readProtocolStream(this._client, result.stream, path); - } - async title(): Promise { return this.mainFrame().title(); } @@ -866,22 +815,6 @@ export class Page extends EventEmitter { } } -type PDFOptions = { - scale?: number, - displayHeaderFooter?: boolean, - headerTemplate?: string, - footerTemplate?: string, - printBackground?: boolean, - landscape?: boolean, - pageRanges?: string, - format?: string, - width?: string|number, - height?: string|number, - preferCSSPageSize?: boolean, - margin?: {top?: string|number, bottom?: string|number, left?: string|number, right?: string|number}, - path?: string, -} - type Metrics = { Timestamp?: number, Documents?: number, @@ -929,55 +862,6 @@ const supportedMetrics: Set = new Set([ 'JSHeapTotalSize', ]); -const PagePaperFormats = { - letter: {width: 8.5, height: 11}, - legal: {width: 8.5, height: 14}, - tabloid: {width: 11, height: 17}, - ledger: {width: 17, height: 11}, - a0: {width: 33.1, height: 46.8 }, - a1: {width: 23.4, height: 33.1 }, - a2: {width: 16.54, height: 23.4 }, - a3: {width: 11.7, height: 16.54 }, - a4: {width: 8.27, height: 11.7 }, - a5: {width: 5.83, height: 8.27 }, - a6: {width: 4.13, height: 5.83 }, -}; - -const unitToPixels = { - 'px': 1, - 'in': 96, - 'cm': 37.8, - 'mm': 3.78 -}; - -function convertPrintParameterToInches(parameter: (string | number | undefined)): (number | undefined) { - if (typeof parameter === 'undefined') - return undefined; - let pixels: number; - if (helper.isNumber(parameter)) { - // Treat numbers as pixel values to be aligned with phantom's paperSize. - pixels = parameter as number; - } else if (helper.isString(parameter)) { - const text: string = parameter as string; - let unit = text.substring(text.length - 2).toLowerCase(); - let valueText = ''; - if (unitToPixels.hasOwnProperty(unit)) { - valueText = text.substring(0, text.length - 2); - } else { - // In case of unknown unit try to parse the whole parameter as number of pixels. - // This is consistent with phantom's paperSize behavior. - unit = 'px'; - valueText = text; - } - const value = Number(valueText); - assert(!isNaN(value), 'Failed to parse parameter value: ' + text); - pixels = value * unitToPixels[unit]; - } else { - throw new Error('page.pdf() Cannot handle parameter type: ' + (typeof parameter)); - } - return pixels / 96; -} - type NetworkCookie = { name: string, value: string, diff --git a/src/webkit/Page.ts b/src/webkit/Page.ts index 002d3c5839..76cfe18d63 100644 --- a/src/webkit/Page.ts +++ b/src/webkit/Page.ts @@ -471,21 +471,6 @@ export class Page extends EventEmitter { } } -type PDFOptions = { - scale?: number, - displayHeaderFooter?: boolean, - headerTemplate?: string, - footerTemplate?: string, - printBackground?: boolean, - landscape?: boolean, - pageRanges?: string, - format?: string, - width?: string|number, - height?: string|number, - preferCSSPageSize?: boolean, - margin?: {top?: string|number, bottom?: string|number, left?: string|number, right?: string|number}, - path?: string, -} type Metrics = { Timestamp?: number, diff --git a/test/page.spec.js b/test/page.spec.js index ec9de5a6d9..9245747af9 100644 --- a/test/page.spec.js +++ b/test/page.spec.js @@ -1048,16 +1048,6 @@ module.exports.addTests = function({testRunner, expect, headless, playwright, FF }); }); - // Printing to pdf is currently only supported in headless - describe.skip(FFOX || WEBKIT || !headless)('Page.pdf', function() { - it('should be able to save file', async({page, server}) => { - const outputFile = __dirname + '/assets/output.pdf'; - await page.pdf({path: outputFile}); - expect(fs.readFileSync(outputFile).byteLength).toBeGreaterThan(0); - fs.unlinkSync(outputFile); - }); - }); - describe('Page.title', function() { it('should return the page title', async({page, server}) => { await page.goto(server.PREFIX + '/title.html');