feat: add more options to printToPDF (#21906)

This commit is contained in:
Shelley Vohr 2020-01-28 20:47:24 +00:00 committed by GitHub
parent 1b4eb0b679
commit 548b290ea7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 171 additions and 53 deletions

View file

@ -65,32 +65,34 @@ const PDFPageSizes = {
// Default printing setting
const defaultPrintingSetting = {
pageRage: [],
// Customizable.
pageRange: [],
mediaSize: {},
landscape: false,
color: 2,
headerFooterEnabled: false,
marginsType: 0,
isFirstRequest: false,
previewUIID: 0,
previewModifiable: true,
printToPDF: true,
scaleFactor: 100,
shouldPrintBackgrounds: false,
shouldPrintSelectionOnly: false,
// Non-customizable.
printWithCloudPrint: false,
printWithPrivet: false,
printWithExtension: false,
pagesPerSheet: 1,
isFirstRequest: false,
previewUIID: 0,
previewModifiable: true,
printToPDF: true,
deviceName: 'Save as PDF',
generateDraftData: true,
fitToPageEnabled: false,
scaleFactor: 100,
dpiHorizontal: 72,
dpiVertical: 72,
rasterizePDF: false,
duplex: 0,
copies: 1,
collate: true,
shouldPrintBackgrounds: false,
shouldPrintSelectionOnly: false
// 2 = color - see ColorModel in //printing/print_job_constants.h
color: 2,
collate: true
}
// JavaScript implementations of WebContents.
@ -206,60 +208,135 @@ WebContents.prototype.executeJavaScriptInIsolatedWorld = async function (code, h
// Translate the options of printToPDF.
WebContents.prototype.printToPDF = function (options) {
const printingSetting = {
const printSettings = {
...defaultPrintingSetting,
requestID: getNextId()
}
if (options.landscape) {
printingSetting.landscape = options.landscape
}
if (options.fitToPageEnabled) {
printingSetting.fitToPageEnabled = options.fitToPageEnabled
}
if (options.scaleFactor) {
printingSetting.scaleFactor = options.scaleFactor
}
if (options.marginsType) {
printingSetting.marginsType = options.marginsType
}
if (options.printSelectionOnly) {
printingSetting.shouldPrintSelectionOnly = options.printSelectionOnly
}
if (options.printBackground) {
printingSetting.shouldPrintBackgrounds = options.printBackground
if (options.landscape !== undefined) {
if (typeof options.landscape !== 'boolean') {
const error = new Error('landscape must be a Boolean')
return Promise.reject(error)
}
printSettings.landscape = options.landscape
}
if (options.pageSize) {
if (options.scaleFactor !== undefined) {
if (typeof options.scaleFactor !== 'number') {
const error = new Error('scaleFactor must be a Number')
return Promise.reject(error)
}
printSettings.scaleFactor = options.scaleFactor
}
if (options.marginsType !== undefined) {
if (typeof options.marginsType !== 'number') {
const error = new Error('marginsType must be a Number')
return Promise.reject(error)
}
printSettings.marginsType = options.marginsType
}
if (options.printSelectionOnly !== undefined) {
if (typeof options.printSelectionOnly !== 'boolean') {
const error = new Error('printSelectionOnly must be a Boolean')
return Promise.reject(error)
}
printSettings.shouldPrintSelectionOnly = options.printSelectionOnly
}
if (options.printBackground !== undefined) {
if (typeof options.printBackground !== 'boolean') {
const error = new Error('printBackground must be a Boolean')
return Promise.reject(error)
}
printSettings.shouldPrintBackgrounds = options.printBackground
}
if (options.pageRanges !== undefined) {
const pageRanges = options.pageRanges
if (!pageRanges.hasOwnProperty('from') || !pageRanges.hasOwnProperty('to')) {
const error = new Error(`pageRanges must be an Object with 'from' and 'to' properties`)
return Promise.reject(error)
}
if (typeof pageRanges.from !== 'number') {
const error = new Error('pageRanges.from must be a Number')
return Promise.reject(error)
}
if (typeof pageRanges.to !== 'number') {
const error = new Error('pageRanges.to must be a Number')
return Promise.reject(error)
}
// Chromium uses 1-based page ranges, so increment each by 1.
printSettings.pageRange = [{
from: pageRanges.from + 1,
to: pageRanges.to + 1
}]
}
if (options.headerFooter !== undefined) {
const headerFooter = options.headerFooter
printSettings.headerFooterEnabled = true
if (typeof headerFooter === 'object') {
if (!headerFooter.url || !headerFooter.title) {
const error = new Error('url and title properties are required for headerFooter')
return Promise.reject(error)
}
if (typeof headerFooter.title !== 'string') {
const error = new Error('headerFooter.title must be a String')
return Promise.reject(error)
}
printSettings.title = headerFooter.title
if (typeof headerFooter.url !== 'string') {
const error = new Error('headerFooter.url must be a String')
return Promise.reject(error)
}
printSettings.url = headerFooter.url
} else {
const error = new Error('headerFooter must be an Object')
return Promise.reject(error)
}
}
// Optionally set size for PDF.
if (options.pageSize !== undefined) {
const pageSize = options.pageSize
if (typeof pageSize === 'object') {
if (!pageSize.height || !pageSize.width) {
return Promise.reject(new Error('Must define height and width for pageSize'))
const error = new Error('height and width properties are required for pageSize')
return Promise.reject(error)
}
// Dimensions in Microns
// 1 meter = 10^6 microns
printingSetting.mediaSize = {
printSettings.mediaSize = {
name: 'CUSTOM',
custom_display_name: 'Custom',
height_microns: Math.ceil(pageSize.height),
width_microns: Math.ceil(pageSize.width)
}
} else if (PDFPageSizes[pageSize]) {
printingSetting.mediaSize = PDFPageSizes[pageSize]
printSettings.mediaSize = PDFPageSizes[pageSize]
} else {
return Promise.reject(new Error(`Does not support pageSize with ${pageSize}`))
const error = new Error(`Unsupported pageSize: ${pageSize}`)
return Promise.reject(error)
}
} else {
printingSetting.mediaSize = PDFPageSizes['A4']
printSettings.mediaSize = PDFPageSizes['A4']
}
// Chromium expects this in a 0-100 range number, not as float
printingSetting.scaleFactor = Math.ceil(printingSetting.scaleFactor) % 100
printSettings.scaleFactor = Math.ceil(printSettings.scaleFactor) % 100
// PrinterType enum from //printing/print_job_constants.h
printingSetting.printerType = 2
printSettings.printerType = 2
if (features.isPrintingEnabled()) {
return this._printToPDF(printingSetting)
return this._printToPDF(printSettings)
} else {
return Promise.reject(new Error('Printing feature is disabled'))
const error = new Error('Printing feature is disabled')
return Promise.reject(error)
}
}