feat: promisify webContents.printToPDF() (#16795)

This commit is contained in:
Milan Burda 2019-02-11 20:20:04 +01:00 committed by John Kleinschmidt
parent 3effa6f20c
commit 36ce3e9546
12 changed files with 161 additions and 57 deletions

View file

@ -1499,11 +1499,12 @@ std::vector<printing::PrinterBasicInfo> WebContents::GetPrinterList() {
return printers; return printers;
} }
void WebContents::PrintToPDF( v8::Local<v8::Promise> WebContents::PrintToPDF(
const base::DictionaryValue& settings, const base::DictionaryValue& settings) {
const PrintPreviewMessageHandler::PrintToPDFCallback& callback) { scoped_refptr<util::Promise> promise = new util::Promise(isolate());
PrintPreviewMessageHandler::FromWebContents(web_contents()) PrintPreviewMessageHandler::FromWebContents(web_contents())
->PrintToPDF(settings, callback); ->PrintToPDF(settings, promise);
return promise->GetHandle();
} }
#endif #endif

View file

@ -174,9 +174,7 @@ class WebContents : public mate::TrackableObject<WebContents>,
void Print(mate::Arguments* args); void Print(mate::Arguments* args);
std::vector<printing::PrinterBasicInfo> GetPrinterList(); std::vector<printing::PrinterBasicInfo> GetPrinterList();
// Print current page as PDF. // Print current page as PDF.
void PrintToPDF( v8::Local<v8::Promise> PrintToPDF(const base::DictionaryValue& settings);
const base::DictionaryValue& settings,
const PrintPreviewMessageHandler::PrintToPDFCallback& callback);
#endif #endif
// DevTools workspace api. // DevTools workspace api.

View file

@ -89,7 +89,7 @@ void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
const PrintHostMsg_DidPrintContent_Params& content = params.content; const PrintHostMsg_DidPrintContent_Params& content = params.content;
if (!content.metafile_data_region.IsValid() || if (!content.metafile_data_region.IsValid() ||
params.expected_pages_count <= 0) { params.expected_pages_count <= 0) {
RunPrintToPDFCallback(ids.request_id, nullptr); RejectPromise(ids.request_id);
return; return;
} }
@ -102,10 +102,9 @@ void PrintPreviewMessageHandler::OnMetafileReadyForPrinting(
base::BindOnce(&PrintPreviewMessageHandler::OnCompositePdfDocumentDone, base::BindOnce(&PrintPreviewMessageHandler::OnCompositePdfDocumentDone,
weak_ptr_factory_.GetWeakPtr(), ids)); weak_ptr_factory_.GetWeakPtr(), ids));
} else { } else {
RunPrintToPDFCallback( ResolvePromise(ids.request_id,
ids.request_id, base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(
base::RefCountedSharedMemoryMapping::CreateFromWholeRegion( content.metafile_data_region));
content.metafile_data_region));
} }
} }
@ -117,11 +116,11 @@ void PrintPreviewMessageHandler::OnCompositePdfDocumentDone(
if (status != printing::mojom::PdfCompositor::Status::SUCCESS) { if (status != printing::mojom::PdfCompositor::Status::SUCCESS) {
DLOG(ERROR) << "Compositing pdf failed with error " << status; DLOG(ERROR) << "Compositing pdf failed with error " << status;
RunPrintToPDFCallback(ids.request_id, nullptr); RejectPromise(ids.request_id);
return; return;
} }
RunPrintToPDFCallback( ResolvePromise(
ids.request_id, ids.request_id,
base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(region)); base::RefCountedSharedMemoryMapping::CreateFromWholeRegion(region));
} }
@ -131,7 +130,7 @@ void PrintPreviewMessageHandler::OnPrintPreviewFailed(
const PrintHostMsg_PreviewIds& ids) { const PrintHostMsg_PreviewIds& ids) {
StopWorker(document_cookie); StopWorker(document_cookie);
RunPrintToPDFCallback(ids.request_id, nullptr); RejectPromise(ids.request_id);
} }
void PrintPreviewMessageHandler::OnPrintPreviewCancelled( void PrintPreviewMessageHandler::OnPrintPreviewCancelled(
@ -139,15 +138,15 @@ void PrintPreviewMessageHandler::OnPrintPreviewCancelled(
const PrintHostMsg_PreviewIds& ids) { const PrintHostMsg_PreviewIds& ids) {
StopWorker(document_cookie); StopWorker(document_cookie);
RunPrintToPDFCallback(ids.request_id, nullptr); RejectPromise(ids.request_id);
} }
void PrintPreviewMessageHandler::PrintToPDF( void PrintPreviewMessageHandler::PrintToPDF(
const base::DictionaryValue& options, const base::DictionaryValue& options,
const PrintToPDFCallback& callback) { scoped_refptr<atom::util::Promise> promise) {
int request_id; int request_id;
options.GetInteger(printing::kPreviewRequestID, &request_id); options.GetInteger(printing::kPreviewRequestID, &request_id);
print_to_pdf_callback_map_[request_id] = callback; promise_map_[request_id] = std::move(promise);
auto* focused_frame = web_contents()->GetFocusedFrame(); auto* focused_frame = web_contents()->GetFocusedFrame();
auto* rfh = focused_frame && focused_frame->HasSelection() auto* rfh = focused_frame && focused_frame->HasSelection()
@ -156,28 +155,44 @@ void PrintPreviewMessageHandler::PrintToPDF(
rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), options)); rfh->Send(new PrintMsg_PrintPreview(rfh->GetRoutingID(), options));
} }
void PrintPreviewMessageHandler::RunPrintToPDFCallback( scoped_refptr<atom::util::Promise> PrintPreviewMessageHandler::GetPromise(
int request_id) {
auto it = promise_map_.find(request_id);
DCHECK(it != promise_map_.end());
auto promise = it->second;
promise_map_.erase(it);
return promise;
}
void PrintPreviewMessageHandler::ResolvePromise(
int request_id, int request_id,
scoped_refptr<base::RefCountedMemory> data_bytes) { scoped_refptr<base::RefCountedMemory> data_bytes) {
DCHECK_CURRENTLY_ON(BrowserThread::UI); DCHECK_CURRENTLY_ON(BrowserThread::UI);
v8::Isolate* isolate = v8::Isolate::GetCurrent(); auto promise = GetPromise(request_id);
v8::Locker locker(isolate);
v8::Isolate* isolate = promise->isolate();
mate::Locker locker(isolate);
v8::HandleScope handle_scope(isolate); v8::HandleScope handle_scope(isolate);
if (data_bytes && data_bytes->size()) { v8::Context::Scope context_scope(
v8::Local<v8::Value> buffer = v8::Local<v8::Context>::New(isolate, promise->GetContext()));
node::Buffer::Copy(isolate,
reinterpret_cast<const char*>(data_bytes->front()), v8::Local<v8::Value> buffer =
data_bytes->size()) node::Buffer::Copy(isolate,
.ToLocalChecked(); reinterpret_cast<const char*>(data_bytes->front()),
print_to_pdf_callback_map_[request_id].Run(v8::Null(isolate), buffer); data_bytes->size())
} else { .ToLocalChecked();
v8::Local<v8::String> error_message =
v8::String::NewFromUtf8(isolate, "Failed to generate PDF"); promise->Resolve(buffer);
print_to_pdf_callback_map_[request_id].Run( }
v8::Exception::Error(error_message), v8::Null(isolate));
} void PrintPreviewMessageHandler::RejectPromise(int request_id) {
print_to_pdf_callback_map_.erase(request_id); DCHECK_CURRENTLY_ON(BrowserThread::UI);
auto promise = GetPromise(request_id);
promise->RejectWithErrorMessage("Failed to generate PDF");
} }
} // namespace atom } // namespace atom

View file

@ -7,6 +7,7 @@
#include <map> #include <map>
#include "atom/common/promise_util.h"
#include "base/memory/ref_counted_memory.h" #include "base/memory/ref_counted_memory.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h" #include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h"
@ -28,13 +29,10 @@ class PrintPreviewMessageHandler
: public content::WebContentsObserver, : public content::WebContentsObserver,
public content::WebContentsUserData<PrintPreviewMessageHandler> { public content::WebContentsUserData<PrintPreviewMessageHandler> {
public: public:
using PrintToPDFCallback =
base::Callback<void(v8::Local<v8::Value>, v8::Local<v8::Value>)>;
~PrintPreviewMessageHandler() override; ~PrintPreviewMessageHandler() override;
void PrintToPDF(const base::DictionaryValue& options, void PrintToPDF(const base::DictionaryValue& options,
const PrintToPDFCallback& callback); scoped_refptr<atom::util::Promise> promise);
protected: protected:
// content::WebContentsObserver implementation. // content::WebContentsObserver implementation.
@ -57,11 +55,15 @@ class PrintPreviewMessageHandler
const PrintHostMsg_PreviewIds& ids); const PrintHostMsg_PreviewIds& ids);
void OnPrintPreviewCancelled(int document_cookie, void OnPrintPreviewCancelled(int document_cookie,
const PrintHostMsg_PreviewIds& ids); const PrintHostMsg_PreviewIds& ids);
void RunPrintToPDFCallback(int request_id,
scoped_refptr<base::RefCountedMemory> data_bytes);
using PrintToPDFCallbackMap = std::map<int, PrintToPDFCallback>; scoped_refptr<atom::util::Promise> GetPromise(int request_id);
PrintToPDFCallbackMap print_to_pdf_callback_map_;
void ResolvePromise(int request_id,
scoped_refptr<base::RefCountedMemory> data_bytes);
void RejectPromise(int request_id);
using PromiseMap = std::map<int, scoped_refptr<atom::util::Promise>>;
PromiseMap promise_map_;
base::WeakPtrFactory<PrintPreviewMessageHandler> weak_ptr_factory_; base::WeakPtrFactory<PrintPreviewMessageHandler> weak_ptr_factory_;

View file

@ -28,17 +28,16 @@ When a majority of affected functions are migrated, this flag will be enabled by
- [ses.clearAuthCache(options[, callback])](https://github.com/electron/electron/blob/master/docs/api/session.md#clearAuthCache) - [ses.clearAuthCache(options[, callback])](https://github.com/electron/electron/blob/master/docs/api/session.md#clearAuthCache)
- [contents.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#executeJavaScript) - [contents.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#executeJavaScript)
- [contents.print([options], [callback])](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#print) - [contents.print([options], [callback])](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#print)
- [contents.printToPDF(options, callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#printToPDF)
- [contents.savePage(fullPath, saveType, callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#savePage) - [contents.savePage(fullPath, saveType, callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#savePage)
- [webFrame.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-frame.md#executeJavaScript) - [webFrame.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-frame.md#executeJavaScript)
- [webFrame.executeJavaScriptInIsolatedWorld(worldId, scripts[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-frame.md#executeJavaScriptInIsolatedWorld) - [webFrame.executeJavaScriptInIsolatedWorld(worldId, scripts[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/web-frame.md#executeJavaScriptInIsolatedWorld)
- [webviewTag.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#executeJavaScript) - [webviewTag.executeJavaScript(code[, userGesture, callback])](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#executeJavaScript)
- [webviewTag.printToPDF(options, callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#printToPDF)
### Converted Functions ### Converted Functions
- [app.getFileIcon(path[, options], callback)](https://github.com/electron/electron/blob/master/docs/api/app.md#getFileIcon) - [app.getFileIcon(path[, options], callback)](https://github.com/electron/electron/blob/master/docs/api/app.md#getFileIcon)
- [contents.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#capturePage) - [contents.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#capturePage)
- [contents.printToPDF(options, callback)](https://github.com/electron/electron/blob/master/docs/api/web-contents.md#printToPDF)
- [contentTracing.getCategories(callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#getCategories) - [contentTracing.getCategories(callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#getCategories)
- [contentTracing.startRecording(options, callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#startRecording) - [contentTracing.startRecording(options, callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#startRecording)
- [contentTracing.stopRecording(resultFilePath, callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#stopRecording) - [contentTracing.stopRecording(resultFilePath, callback)](https://github.com/electron/electron/blob/master/docs/api/content-tracing.md#stopRecording)
@ -50,5 +49,6 @@ When a majority of affected functions are migrated, this flag will be enabled by
- [protocol.isProtocolHandled(scheme, callback)](https://github.com/electron/electron/blob/master/docs/api/protocol.md#isProtocolHandled) - [protocol.isProtocolHandled(scheme, callback)](https://github.com/electron/electron/blob/master/docs/api/protocol.md#isProtocolHandled)
- [shell.openExternal(url[, options, callback])](https://github.com/electron/electron/blob/master/docs/api/shell.md#openExternal) - [shell.openExternal(url[, options, callback])](https://github.com/electron/electron/blob/master/docs/api/shell.md#openExternal)
- [webviewTag.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#capturePage) - [webviewTag.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#capturePage)
- [webviewTag.printToPDF(options, callback)](https://github.com/electron/electron/blob/master/docs/api/webview-tag.md#printToPDF)
- [win.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/browser-window.md#capturePage) - [win.capturePage([rect, ]callback)](https://github.com/electron/electron/blob/master/docs/api/browser-window.md#capturePage)
- [desktopCapturer.getSources(options, callback)](https://github.com/electron/electron/blob/master/docs/api/desktop-capturer.md#getSources) - [desktopCapturer.getSources(options, callback)](https://github.com/electron/electron/blob/master/docs/api/desktop-capturer.md#getSources)

View file

@ -1202,6 +1202,25 @@ settings.
The `callback` will be called with `callback(error, data)` on completion. The The `callback` will be called with `callback(error, data)` on completion. The
`data` is a `Buffer` that contains the generated PDF data. `data` is a `Buffer` that contains the generated PDF data.
**[Deprecated Soon](promisification.md)**
#### `contents.printToPDF(options)`
* `options` Object
* `marginsType` Integer (optional) - Specifies the type of margins to use. Uses 0 for
default margin, 1 for no margin, and 2 for minimum margin.
* `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) - `true` for landscape, `false` for portrait.
* Returns `Promise<Buffer>` - Resolves with the generated PDF data.
Prints window's web page as PDF with Chromium's preview printing custom
settings.
The `landscape` will be ignored if `@page` CSS at-rule is used in the web page. 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: By default, an empty `options` will be regarded as:

View file

@ -542,6 +542,24 @@ Prints `webview`'s web page. Same as `webContents.print([options])`.
Prints `webview`'s web page as PDF, Same as `webContents.printToPDF(options, callback)`. Prints `webview`'s web page as PDF, Same as `webContents.printToPDF(options, callback)`.
**[Deprecated Soon](promisification.md)**
### `<webview>.printToPDF(options)`
* `options` Object
* `marginsType` Integer (optional) - Specifies the type of margins to use. Uses 0 for
default margin, 1 for no margin, and 2 for minimum margin.
* `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) - `true` for landscape, `false` for portrait.
* Returns `Promise<Buffer>` - Resolves with the generated PDF data.
Prints `webview`'s web page as PDF, Same as `webContents.printToPDF(options)`.
### `<webview>.capturePage([rect, ]callback)` ### `<webview>.capturePage([rect, ]callback)`
* `rect` [Rectangle](structures/rectangle.md) (optional) - The bounds to capture * `rect` [Rectangle](structures/rectangle.md) (optional) - The bounds to capture

View file

@ -263,7 +263,7 @@ WebContents.prototype.takeHeapSnapshot = function (filePath) {
} }
// Translate the options of printToPDF. // Translate the options of printToPDF.
WebContents.prototype.printToPDF = function (options, callback) { WebContents.prototype.printToPDF = function (options) {
const printingSetting = Object.assign({}, defaultPrintingSetting) const printingSetting = Object.assign({}, defaultPrintingSetting)
if (options.landscape) { if (options.landscape) {
printingSetting.landscape = options.landscape printingSetting.landscape = options.landscape
@ -282,7 +282,7 @@ WebContents.prototype.printToPDF = function (options, callback) {
const pageSize = options.pageSize const pageSize = options.pageSize
if (typeof pageSize === 'object') { if (typeof pageSize === 'object') {
if (!pageSize.height || !pageSize.width) { if (!pageSize.height || !pageSize.width) {
return callback(new Error('Must define height and width for pageSize')) return Promise.reject(new Error('Must define height and width for pageSize'))
} }
// Dimensions in Microns // Dimensions in Microns
// 1 meter = 10^6 microns // 1 meter = 10^6 microns
@ -295,7 +295,7 @@ WebContents.prototype.printToPDF = function (options, callback) {
} else if (PDFPageSizes[pageSize]) { } else if (PDFPageSizes[pageSize]) {
printingSetting.mediaSize = PDFPageSizes[pageSize] printingSetting.mediaSize = PDFPageSizes[pageSize]
} else { } else {
return callback(new Error(`Does not support pageSize with ${pageSize}`)) return Promise.reject(new Error(`Does not support pageSize with ${pageSize}`))
} }
} else { } else {
printingSetting.mediaSize = PDFPageSizes['A4'] printingSetting.mediaSize = PDFPageSizes['A4']
@ -304,9 +304,9 @@ WebContents.prototype.printToPDF = function (options, callback) {
// Chromium expects this in a 0-100 range number, not as float // Chromium expects this in a 0-100 range number, not as float
printingSetting.scaleFactor *= 100 printingSetting.scaleFactor *= 100
if (features.isPrintingEnabled()) { if (features.isPrintingEnabled()) {
this._printToPDF(printingSetting, callback) return this._printToPDF(printingSetting)
} else { } else {
console.error('Error: Printing feature is disabled.') return Promise.reject(new Error('Printing feature is disabled'))
} }
} }
@ -342,6 +342,9 @@ WebContents.prototype.loadFile = function (filePath, options = {}) {
})) }))
} }
WebContents.prototype.capturePage = deprecate.promisify(WebContents.prototype.capturePage)
WebContents.prototype.printToPDF = deprecate.promisify(WebContents.prototype.printToPDF)
const addReplyToEvent = (event) => { const addReplyToEvent = (event) => {
event.reply = (...args) => { event.reply = (...args) => {
event.sender.sendToFrame(event.frameId, ...args) event.sender.sendToFrame(event.frameId, ...args)
@ -385,8 +388,6 @@ WebContents.prototype._init = function () {
// render-view-deleted event, so ignore the listeners warning. // render-view-deleted event, so ignore the listeners warning.
this.setMaxListeners(0) this.setMaxListeners(0)
this.capturePage = deprecate.promisify(this.capturePage)
// Dispatch IPC messages to the ipc module. // Dispatch IPC messages to the ipc module.
this.on('-ipc-message', function (event, internal, channel, args) { this.on('-ipc-message', function (event, internal, channel, args) {
if (internal) { if (internal) {

View file

@ -60,11 +60,11 @@ exports.asyncCallbackMethods = new Set([
'sendInputEvent', 'sendInputEvent',
'setLayoutZoomLevelLimits', 'setLayoutZoomLevelLimits',
'setVisualZoomLevelLimits', 'setVisualZoomLevelLimits',
'print', 'print'
'printToPDF'
]) ])
exports.asyncPromiseMethods = new Set([ exports.asyncPromiseMethods = new Set([
'capturePage', 'capturePage',
'executeJavaScript' 'executeJavaScript',
'printToPDF'
]) ])

View file

@ -1,6 +1,6 @@
'use strict' 'use strict'
const { webFrame } = require('electron') const { webFrame, deprecate } = require('electron')
const v8Util = process.atomBinding('v8_util') const v8Util = process.atomBinding('v8_util')
const ipcRenderer = require('@electron/internal/renderer/ipc-renderer-internal') const ipcRenderer = require('@electron/internal/renderer/ipc-renderer-internal')
@ -287,6 +287,8 @@ const setupMethods = (WebViewElement) => {
for (const method of asyncPromiseMethods) { for (const method of asyncPromiseMethods) {
WebViewElement.prototype[method] = createPromiseHandler(method) WebViewElement.prototype[method] = createPromiseHandler(method)
} }
WebViewElement.prototype.printToPDF = deprecate.promisify(WebViewElement.prototype.printToPDF)
} }
module.exports = { setupAttributes, setupMethods, guestViewInternal, webFrame, WebViewImpl } module.exports = { setupAttributes, setupMethods, guestViewInternal, webFrame, WebViewImpl }

View file

@ -1268,7 +1268,22 @@ describe('webContents module', () => {
} }
}) })
it('can print to PDF', (done) => { it('can print to PDF', async () => {
w.destroy()
w = new BrowserWindow({
show: false,
webPreferences: {
sandbox: true
}
})
await w.loadURL('data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E')
const data = await w.webContents.printToPDF({})
assert.strictEqual(data instanceof Buffer, true)
assert.notStrictEqual(data.length, 0)
})
// TODO(miniak): remove when promisification is complete
it('can print to PDF (callback)', (done) => {
w.destroy() w.destroy()
w = new BrowserWindow({ w = new BrowserWindow({
show: false, show: false,

View file

@ -12,6 +12,7 @@ const { emittedOnce, waitForEvent } = require('./events-helpers')
const { expect } = chai const { expect } = chai
chai.use(dirtyChai) chai.use(dirtyChai)
const features = process.atomBinding('features')
const isCI = remote.getGlobal('isCi') const isCI = remote.getGlobal('isCi')
const nativeModulesEnabled = remote.getGlobal('nativeModulesEnabled') const nativeModulesEnabled = remote.getGlobal('nativeModulesEnabled')
@ -1233,6 +1234,38 @@ describe('<webview> tag', function () {
}) })
}) })
describe('<webview>.printToPDF()', () => {
before(function () {
if (!features.isPrintingEnabled()) {
this.skip()
}
})
it('can print to PDF', async () => {
const src = 'data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E'
await loadWebView(webview, { src })
const data = await webview.printToPDF({})
assert.strictEqual(data instanceof Buffer, true)
assert.notStrictEqual(data.length, 0)
})
// TODO(miniak): remove when promisification is complete
it('can print to PDF (callback)', (done) => {
webview.addEventListener('did-finish-load', () => {
webview.printToPDF({}, function (error, data) {
assert.strictEqual(error, null)
assert.strictEqual(data instanceof Buffer, true)
assert.notStrictEqual(data.length, 0)
done()
})
})
webview.src = 'data:text/html,%3Ch1%3EHello%2C%20World!%3C%2Fh1%3E'
document.body.appendChild(webview)
})
})
// FIXME(deepak1556): Ch69 follow up. // FIXME(deepak1556): Ch69 follow up.
xdescribe('document.visibilityState/hidden', () => { xdescribe('document.visibilityState/hidden', () => {
afterEach(() => { afterEach(() => {