dragonfly_chrome_headless 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +12 -0
- data/Gemfile +4 -0
- data/README.md +53 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/dragonfly_chrome_headless.gemspec +27 -0
- data/lib/dragonfly_chrome_headless.rb +9 -0
- data/lib/dragonfly_chrome_headless/plugin.rb +17 -0
- data/lib/dragonfly_chrome_headless/processors/rasterize.rb +33 -0
- data/lib/dragonfly_chrome_headless/version.rb +3 -0
- data/node_modules/.bin/chrome-remote-interface +1 -0
- data/node_modules/.bin/mkdirp +1 -0
- data/node_modules/.bin/rimraf +1 -0
- data/node_modules/@types/core-js/LICENSE +21 -0
- data/node_modules/@types/core-js/README.md +16 -0
- data/node_modules/@types/core-js/index.d.ts +2452 -0
- data/node_modules/@types/core-js/package.json +85 -0
- data/node_modules/@types/mkdirp/README.md +18 -0
- data/node_modules/@types/mkdirp/index.d.ts +14 -0
- data/node_modules/@types/mkdirp/package.json +77 -0
- data/node_modules/@types/mkdirp/types-metadata.json +25 -0
- data/node_modules/@types/node/README.md +16 -0
- data/node_modules/@types/node/index.d.ts +4132 -0
- data/node_modules/@types/node/package.json +84 -0
- data/node_modules/balanced-match/.npmignore +5 -0
- data/node_modules/balanced-match/LICENSE.md +21 -0
- data/node_modules/balanced-match/README.md +91 -0
- data/node_modules/balanced-match/index.js +59 -0
- data/node_modules/balanced-match/package.json +112 -0
- data/node_modules/brace-expansion/README.md +123 -0
- data/node_modules/brace-expansion/index.js +201 -0
- data/node_modules/brace-expansion/package.json +114 -0
- data/node_modules/chrome-launcher/.clang-format +6 -0
- data/node_modules/chrome-launcher/.npmignore +11 -0
- data/node_modules/chrome-launcher/README.md +123 -0
- data/node_modules/chrome-launcher/ask.js +32 -0
- data/node_modules/chrome-launcher/ask.ts +35 -0
- data/node_modules/chrome-launcher/chrome-finder.js +157 -0
- data/node_modules/chrome-launcher/chrome-finder.ts +186 -0
- data/node_modules/chrome-launcher/chrome-launcher.js +245 -0
- data/node_modules/chrome-launcher/chrome-launcher.ts +312 -0
- data/node_modules/chrome-launcher/compiled-check.js +14 -0
- data/node_modules/chrome-launcher/flags.js +27 -0
- data/node_modules/chrome-launcher/flags.ts +26 -0
- data/node_modules/chrome-launcher/index.js +7 -0
- data/node_modules/chrome-launcher/index.ts +1 -0
- data/node_modules/chrome-launcher/manual-chrome-launcher.js +30 -0
- data/node_modules/chrome-launcher/package.json +116 -0
- data/node_modules/chrome-launcher/random-port.js +24 -0
- data/node_modules/chrome-launcher/random-port.ts +23 -0
- data/node_modules/chrome-launcher/tsconfig.json +19 -0
- data/node_modules/chrome-launcher/utils.js +52 -0
- data/node_modules/chrome-launcher/utils.ts +44 -0
- data/node_modules/chrome-launcher/yarn.lock +1486 -0
- data/node_modules/chrome-remote-interface/LICENSE +18 -0
- data/node_modules/chrome-remote-interface/README.md +849 -0
- data/node_modules/chrome-remote-interface/bin/client.js +337 -0
- data/node_modules/chrome-remote-interface/chrome-remote-interface.js +11 -0
- data/node_modules/chrome-remote-interface/index.js +39 -0
- data/node_modules/chrome-remote-interface/lib/api.js +84 -0
- data/node_modules/chrome-remote-interface/lib/chrome.js +307 -0
- data/node_modules/chrome-remote-interface/lib/defaults.js +4 -0
- data/node_modules/chrome-remote-interface/lib/devtools.js +245 -0
- data/node_modules/chrome-remote-interface/lib/external-request.js +28 -0
- data/node_modules/chrome-remote-interface/lib/protocol.json +13780 -0
- data/node_modules/chrome-remote-interface/lib/websocket-wrapper.js +32 -0
- data/node_modules/chrome-remote-interface/package.json +128 -0
- data/node_modules/chrome-remote-interface/webpack.config.js +55 -0
- data/node_modules/commander/Readme.md +195 -0
- data/node_modules/commander/index.js +851 -0
- data/node_modules/commander/package.json +92 -0
- data/node_modules/concat-map/.travis.yml +4 -0
- data/node_modules/concat-map/LICENSE +18 -0
- data/node_modules/concat-map/README.markdown +62 -0
- data/node_modules/concat-map/example/map.js +6 -0
- data/node_modules/concat-map/index.js +13 -0
- data/node_modules/concat-map/package.json +117 -0
- data/node_modules/concat-map/test/map.js +39 -0
- data/node_modules/debug/.coveralls.yml +1 -0
- data/node_modules/debug/.eslintrc +11 -0
- data/node_modules/debug/.npmignore +9 -0
- data/node_modules/debug/.travis.yml +14 -0
- data/node_modules/debug/CHANGELOG.md +357 -0
- data/node_modules/debug/LICENSE +19 -0
- data/node_modules/debug/Makefile +50 -0
- data/node_modules/debug/Readme.md +312 -0
- data/node_modules/debug/component.json +19 -0
- data/node_modules/debug/karma.conf.js +70 -0
- data/node_modules/debug/node.js +1 -0
- data/node_modules/debug/package.json +124 -0
- data/node_modules/debug/src/browser.js +185 -0
- data/node_modules/debug/src/debug.js +202 -0
- data/node_modules/debug/src/index.js +10 -0
- data/node_modules/debug/src/node.js +246 -0
- data/node_modules/fs.realpath/LICENSE +43 -0
- data/node_modules/fs.realpath/README.md +33 -0
- data/node_modules/fs.realpath/index.js +66 -0
- data/node_modules/fs.realpath/old.js +303 -0
- data/node_modules/fs.realpath/package.json +94 -0
- data/node_modules/glob/LICENSE +15 -0
- data/node_modules/glob/README.md +368 -0
- data/node_modules/glob/changelog.md +67 -0
- data/node_modules/glob/common.js +240 -0
- data/node_modules/glob/glob.js +790 -0
- data/node_modules/glob/package.json +112 -0
- data/node_modules/glob/sync.js +486 -0
- data/node_modules/html-pdf-chrome/.npmignore +9 -0
- data/node_modules/html-pdf-chrome/LICENSE +21 -0
- data/node_modules/html-pdf-chrome/README.md +165 -0
- data/node_modules/html-pdf-chrome/lib/src/ChromePrintOptions.d.ts +87 -0
- data/node_modules/html-pdf-chrome/lib/src/ChromePrintOptions.js +4 -0
- data/node_modules/html-pdf-chrome/lib/src/ChromePrintOptions.js.map +1 -0
- data/node_modules/html-pdf-chrome/lib/src/CompletionTrigger.d.ts +120 -0
- data/node_modules/html-pdf-chrome/lib/src/CompletionTrigger.js +206 -0
- data/node_modules/html-pdf-chrome/lib/src/CompletionTrigger.js.map +1 -0
- data/node_modules/html-pdf-chrome/lib/src/CreateResult.d.ts +70 -0
- data/node_modules/html-pdf-chrome/lib/src/CreateResult.js +98 -0
- data/node_modules/html-pdf-chrome/lib/src/CreateResult.js.map +1 -0
- data/node_modules/html-pdf-chrome/lib/src/index.d.ts +72 -0
- data/node_modules/html-pdf-chrome/lib/src/index.js +123 -0
- data/node_modules/html-pdf-chrome/lib/src/index.js.map +1 -0
- data/node_modules/html-pdf-chrome/package.json +133 -0
- data/node_modules/html-pdf-chrome/src/ChromePrintOptions.ts +99 -0
- data/node_modules/html-pdf-chrome/src/CompletionTrigger.ts +201 -0
- data/node_modules/html-pdf-chrome/src/CreateResult.ts +100 -0
- data/node_modules/html-pdf-chrome/src/index.ts +179 -0
- data/node_modules/inflight/LICENSE +15 -0
- data/node_modules/inflight/README.md +37 -0
- data/node_modules/inflight/inflight.js +54 -0
- data/node_modules/inflight/package.json +105 -0
- data/node_modules/inherits/LICENSE +16 -0
- data/node_modules/inherits/README.md +42 -0
- data/node_modules/inherits/inherits.js +7 -0
- data/node_modules/inherits/inherits_browser.js +23 -0
- data/node_modules/inherits/package.json +97 -0
- data/node_modules/lighthouse-logger/README.md +4 -0
- data/node_modules/lighthouse-logger/index.js +212 -0
- data/node_modules/lighthouse-logger/package.json +69 -0
- data/node_modules/lighthouse-logger/yarn.lock +13 -0
- data/node_modules/minimatch/LICENSE +15 -0
- data/node_modules/minimatch/README.md +209 -0
- data/node_modules/minimatch/minimatch.js +923 -0
- data/node_modules/minimatch/package.json +99 -0
- data/node_modules/minimist/.travis.yml +4 -0
- data/node_modules/minimist/LICENSE +18 -0
- data/node_modules/minimist/example/parse.js +2 -0
- data/node_modules/minimist/index.js +187 -0
- data/node_modules/minimist/package.json +101 -0
- data/node_modules/minimist/readme.markdown +73 -0
- data/node_modules/minimist/test/dash.js +24 -0
- data/node_modules/minimist/test/default_bool.js +20 -0
- data/node_modules/minimist/test/dotted.js +16 -0
- data/node_modules/minimist/test/long.js +31 -0
- data/node_modules/minimist/test/parse.js +318 -0
- data/node_modules/minimist/test/parse_modified.js +9 -0
- data/node_modules/minimist/test/short.js +67 -0
- data/node_modules/minimist/test/whitespace.js +8 -0
- data/node_modules/mkdirp/.travis.yml +8 -0
- data/node_modules/mkdirp/LICENSE +21 -0
- data/node_modules/mkdirp/bin/cmd.js +33 -0
- data/node_modules/mkdirp/bin/usage.txt +12 -0
- data/node_modules/mkdirp/examples/pow.js +6 -0
- data/node_modules/mkdirp/index.js +98 -0
- data/node_modules/mkdirp/package.json +93 -0
- data/node_modules/mkdirp/readme.markdown +100 -0
- data/node_modules/mkdirp/test/chmod.js +41 -0
- data/node_modules/mkdirp/test/clobber.js +38 -0
- data/node_modules/mkdirp/test/mkdirp.js +28 -0
- data/node_modules/mkdirp/test/opts_fs.js +29 -0
- data/node_modules/mkdirp/test/opts_fs_sync.js +27 -0
- data/node_modules/mkdirp/test/perm.js +32 -0
- data/node_modules/mkdirp/test/perm_sync.js +36 -0
- data/node_modules/mkdirp/test/race.js +37 -0
- data/node_modules/mkdirp/test/rel.js +32 -0
- data/node_modules/mkdirp/test/return.js +25 -0
- data/node_modules/mkdirp/test/return_sync.js +24 -0
- data/node_modules/mkdirp/test/root.js +19 -0
- data/node_modules/mkdirp/test/sync.js +32 -0
- data/node_modules/mkdirp/test/umask.js +28 -0
- data/node_modules/mkdirp/test/umask_sync.js +32 -0
- data/node_modules/ms/README.md +51 -0
- data/node_modules/ms/index.js +152 -0
- data/node_modules/ms/license.md +21 -0
- data/node_modules/ms/package.json +109 -0
- data/node_modules/once/LICENSE +15 -0
- data/node_modules/once/README.md +79 -0
- data/node_modules/once/once.js +42 -0
- data/node_modules/once/package.json +101 -0
- data/node_modules/path-is-absolute/index.js +20 -0
- data/node_modules/path-is-absolute/license +21 -0
- data/node_modules/path-is-absolute/package.json +111 -0
- data/node_modules/path-is-absolute/readme.md +59 -0
- data/node_modules/rimraf/LICENSE +15 -0
- data/node_modules/rimraf/README.md +101 -0
- data/node_modules/rimraf/bin.js +50 -0
- data/node_modules/rimraf/package.json +99 -0
- data/node_modules/rimraf/rimraf.js +363 -0
- data/node_modules/ultron/LICENSE +22 -0
- data/node_modules/ultron/index.js +138 -0
- data/node_modules/ultron/package.json +112 -0
- data/node_modules/wrappy/LICENSE +15 -0
- data/node_modules/wrappy/README.md +36 -0
- data/node_modules/wrappy/package.json +97 -0
- data/node_modules/wrappy/wrappy.js +33 -0
- data/node_modules/ws/LICENSE +21 -0
- data/node_modules/ws/README.md +259 -0
- data/node_modules/ws/SECURITY.md +33 -0
- data/node_modules/ws/index.js +15 -0
- data/node_modules/ws/lib/BufferUtil.fallback.js +56 -0
- data/node_modules/ws/lib/BufferUtil.js +15 -0
- data/node_modules/ws/lib/ErrorCodes.js +28 -0
- data/node_modules/ws/lib/EventTarget.js +158 -0
- data/node_modules/ws/lib/Extensions.js +69 -0
- data/node_modules/ws/lib/PerMessageDeflate.js +339 -0
- data/node_modules/ws/lib/Receiver.js +520 -0
- data/node_modules/ws/lib/Sender.js +438 -0
- data/node_modules/ws/lib/Validation.fallback.js +9 -0
- data/node_modules/ws/lib/Validation.js +17 -0
- data/node_modules/ws/lib/WebSocket.js +705 -0
- data/node_modules/ws/lib/WebSocketServer.js +336 -0
- data/node_modules/ws/package.json +122 -0
- data/package.json +26 -0
- data/samples/sample.html +13 -0
- data/script/rasterize.js +18 -0
- metadata +325 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Chrome Page.printToPDF options.
|
|
5
|
+
* Note: these require Chrome >= 60.
|
|
6
|
+
*
|
|
7
|
+
* @export
|
|
8
|
+
* @interface ChromePrintOptions
|
|
9
|
+
*/
|
|
10
|
+
export interface ChromePrintOptions {
|
|
11
|
+
/**
|
|
12
|
+
* Paper orientation. Defaults to false.
|
|
13
|
+
*
|
|
14
|
+
* @type {boolean}
|
|
15
|
+
* @memberof ChromePrintOptions
|
|
16
|
+
*/
|
|
17
|
+
landscape?: boolean;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Display header and footer. Defaults to false.
|
|
21
|
+
*
|
|
22
|
+
* @type {boolean}
|
|
23
|
+
* @memberof ChromePrintOptions
|
|
24
|
+
*/
|
|
25
|
+
displayHeaderFooter?: boolean;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Print background graphics. Defaults to false.
|
|
29
|
+
*
|
|
30
|
+
* @type {boolean}
|
|
31
|
+
* @memberof ChromePrintOptions
|
|
32
|
+
*/
|
|
33
|
+
printBackground?: boolean;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Scale of the webpage rendering. Defaults to 1.
|
|
37
|
+
*
|
|
38
|
+
* @type {number}
|
|
39
|
+
* @memberof ChromePrintOptions
|
|
40
|
+
*/
|
|
41
|
+
scale?: number;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Paper width in inches. Defaults to 8.5 inches.
|
|
45
|
+
*
|
|
46
|
+
* @type {number}
|
|
47
|
+
* @memberof ChromePrintOptions
|
|
48
|
+
*/
|
|
49
|
+
paperWidth?: number;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Paper height in inches. Defaults to 11 inches.
|
|
53
|
+
*
|
|
54
|
+
* @type {number}
|
|
55
|
+
* @memberof ChromePrintOptions
|
|
56
|
+
*/
|
|
57
|
+
paperHeight?: number;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Top margin in inches. Defaults to 1cm (~0.4 inches).
|
|
61
|
+
*
|
|
62
|
+
* @type {number}
|
|
63
|
+
* @memberof ChromePrintOptions
|
|
64
|
+
*/
|
|
65
|
+
marginTop?: number;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Bottom margin in inches. Defaults to 1cm (~0.4 inches).
|
|
69
|
+
*
|
|
70
|
+
* @type {number}
|
|
71
|
+
* @memberof ChromePrintOptions
|
|
72
|
+
*/
|
|
73
|
+
marginBottom?: number;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Left margin in inches. Defaults to 1cm (~0.4 inches).
|
|
77
|
+
*
|
|
78
|
+
* @type {number}
|
|
79
|
+
* @memberof ChromePrintOptions
|
|
80
|
+
*/
|
|
81
|
+
marginLeft?: number;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Right margin in inches. Defaults to 1cm (~0.4 inches).
|
|
85
|
+
*
|
|
86
|
+
* @type {number}
|
|
87
|
+
* @memberof ChromePrintOptions
|
|
88
|
+
*/
|
|
89
|
+
marginRight?: number;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Paper ranges to print, e.g., '1-5, 8, 11-13'.
|
|
93
|
+
* Defaults to the empty string, which means print all pages.
|
|
94
|
+
*
|
|
95
|
+
* @type {string}
|
|
96
|
+
* @memberof ChromePrintOptions
|
|
97
|
+
*/
|
|
98
|
+
pageRanges?: string;
|
|
99
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Defines a trigger that signifies page render completion.
|
|
5
|
+
*
|
|
6
|
+
* @export
|
|
7
|
+
* @abstract
|
|
8
|
+
* @class CompletionTrigger
|
|
9
|
+
*/
|
|
10
|
+
export abstract class CompletionTrigger {
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates an instance of CompletionTrigger.
|
|
14
|
+
* @param {number} [timeout=1000] milliseconds until timing out.
|
|
15
|
+
* @param {string} [timeoutMessage='CompletionTrigger timed out.'] The timeout message.
|
|
16
|
+
* @memberof CompletionTrigger
|
|
17
|
+
*/
|
|
18
|
+
constructor(
|
|
19
|
+
protected timeout = 1000,
|
|
20
|
+
protected timeoutMessage = 'CompletionTrigger timed out.',
|
|
21
|
+
) {}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Abstracts away the trigger logic.
|
|
25
|
+
*
|
|
26
|
+
* @abstract
|
|
27
|
+
* @param {*} client the Chrome connection information.
|
|
28
|
+
* @returns {Promise<any>} resolves if triggered, rejects on error or timeout.
|
|
29
|
+
* @memberof CompletionTrigger
|
|
30
|
+
*/
|
|
31
|
+
public abstract async wait(client: any): Promise<any>;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Waits for a specified amount of time.
|
|
36
|
+
*
|
|
37
|
+
* @export
|
|
38
|
+
* @class Timer
|
|
39
|
+
* @extends {CompletionTrigger}
|
|
40
|
+
*/
|
|
41
|
+
export class Timer extends CompletionTrigger {
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Creates an instance of the Timer CompletionTrigger.
|
|
45
|
+
* @param {number} timeout ms to wait until timing out.
|
|
46
|
+
* @memberof Timer
|
|
47
|
+
*/
|
|
48
|
+
constructor(timeout: number) {
|
|
49
|
+
super(timeout);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public async wait(client: any): Promise<any> {
|
|
53
|
+
return new Promise((resolve) => {
|
|
54
|
+
setTimeout(resolve, this.timeout);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Waits for an Event to fire.
|
|
61
|
+
*
|
|
62
|
+
* @export
|
|
63
|
+
* @class Event
|
|
64
|
+
* @extends {CompletionTrigger}
|
|
65
|
+
*/
|
|
66
|
+
export class Event extends CompletionTrigger {
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Creates an instance of the Event CompletionTrigger.
|
|
70
|
+
* @param {string} event the name of the event to listen for.
|
|
71
|
+
* @param {string} [cssSelector] the CSS selector of the element to listen on.
|
|
72
|
+
* Defaults to body.
|
|
73
|
+
* @param {number} [timeout] ms to wait until timing out.
|
|
74
|
+
* @memberof Event
|
|
75
|
+
*/
|
|
76
|
+
constructor(protected event: string, protected cssSelector?: string, timeout?: number) {
|
|
77
|
+
super(timeout);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
public async wait(client: any): Promise<any> {
|
|
81
|
+
const {Runtime} = client;
|
|
82
|
+
const selector = this.cssSelector ? `querySelector('${this.cssSelector}')` : 'body';
|
|
83
|
+
return Runtime.evaluate({
|
|
84
|
+
awaitPromise: true,
|
|
85
|
+
expression: `
|
|
86
|
+
new Promise((resolve, reject) => {
|
|
87
|
+
document.${selector}.addEventListener('${this.event}', resolve, { once: true });
|
|
88
|
+
setTimeout(() => reject('${this.timeoutMessage}'), ${this.timeout});
|
|
89
|
+
})`,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Waits for a callback to be called.
|
|
96
|
+
*
|
|
97
|
+
* @export
|
|
98
|
+
* @class Callback
|
|
99
|
+
* @extends {CompletionTrigger}
|
|
100
|
+
*/
|
|
101
|
+
export class Callback extends CompletionTrigger {
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Creates an instance of the Callback CompletionTrigger.
|
|
105
|
+
* @param {string} [callbackName] the name of the callback to listen for.
|
|
106
|
+
* Defaults to htmlPdfCb.
|
|
107
|
+
* @param {number} [timeout] ms to wait until timing out.
|
|
108
|
+
* @memberof Callback
|
|
109
|
+
*/
|
|
110
|
+
constructor(protected callbackName?: string, timeout?: number) {
|
|
111
|
+
super(timeout);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public async wait(client: any): Promise<any> {
|
|
115
|
+
const {Runtime} = client;
|
|
116
|
+
const cbName = this.callbackName || 'htmlPdfCb';
|
|
117
|
+
return Runtime.evaluate({
|
|
118
|
+
awaitPromise: true,
|
|
119
|
+
expression: `
|
|
120
|
+
new Promise((resolve, reject) => {
|
|
121
|
+
${cbName} = resolve;
|
|
122
|
+
setTimeout(() => reject('${this.timeoutMessage}'), ${this.timeout});
|
|
123
|
+
})`,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Waits for a DOM element to appear.
|
|
130
|
+
*
|
|
131
|
+
* @export
|
|
132
|
+
* @class Element
|
|
133
|
+
* @extends {CompletionTrigger}
|
|
134
|
+
*/
|
|
135
|
+
export class Element extends CompletionTrigger {
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Creates an instance of the Element CompletionTrigger.
|
|
139
|
+
* @param {string} cssSelector the element to listen for.
|
|
140
|
+
* @param {number} [timeout] ms to wait until timing out.
|
|
141
|
+
* @memberof Element
|
|
142
|
+
*/
|
|
143
|
+
constructor(protected cssSelector: string, timeout?: number) {
|
|
144
|
+
super(timeout);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
public async wait(client: any): Promise<any> {
|
|
148
|
+
const {Runtime} = client;
|
|
149
|
+
return Runtime.evaluate({
|
|
150
|
+
awaitPromise: true,
|
|
151
|
+
expression: `
|
|
152
|
+
new Promise((resolve, reject) => {
|
|
153
|
+
new MutationObserver((mutations, observer) => {
|
|
154
|
+
mutations.forEach((mutation) => {
|
|
155
|
+
if ([...mutation.addedNodes].find((node) => node.matches('${this.cssSelector}'))) {
|
|
156
|
+
observer.disconnect();
|
|
157
|
+
resolve();
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
}).observe(document.body, { childList: true });
|
|
161
|
+
setTimeout(() => reject('${this.timeoutMessage}'), ${this.timeout});
|
|
162
|
+
})`,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Waits for a variable to be true.
|
|
169
|
+
*
|
|
170
|
+
* @export
|
|
171
|
+
* @class Variable
|
|
172
|
+
* @extends {CompletionTrigger}
|
|
173
|
+
*/
|
|
174
|
+
export class Variable extends CompletionTrigger {
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Creates an instance of the Variable CompletionTrigger.
|
|
178
|
+
* @param {string} [variableName] the variable to listen on.
|
|
179
|
+
* Defaults to htmlPdfDone.
|
|
180
|
+
* @param {number} [timeout] ms to wait until timing out.
|
|
181
|
+
* @memberof Variable
|
|
182
|
+
*/
|
|
183
|
+
constructor(protected variableName?: string, timeout?: number) {
|
|
184
|
+
super(timeout);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
public async wait(client: any): Promise<any> {
|
|
188
|
+
const {Runtime} = client;
|
|
189
|
+
const varName = this.variableName || 'htmlPdfDone';
|
|
190
|
+
return Runtime.evaluate({
|
|
191
|
+
awaitPromise: true,
|
|
192
|
+
expression: `
|
|
193
|
+
new Promise((resolve, reject) => {
|
|
194
|
+
Object.defineProperty(window, '${varName}', {
|
|
195
|
+
set: (val) => { if (val === true) resolve(); }
|
|
196
|
+
});
|
|
197
|
+
setTimeout(() => reject('${this.timeoutMessage}'), ${this.timeout});
|
|
198
|
+
})`,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import { Readable, Stream } from 'stream';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Allows exporting of PDF data to multiple formats.
|
|
8
|
+
*
|
|
9
|
+
* @export
|
|
10
|
+
* @class CreateResult
|
|
11
|
+
*/
|
|
12
|
+
export class CreateResult {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Writes the given data Buffer to the specified file location.
|
|
16
|
+
*
|
|
17
|
+
* @private
|
|
18
|
+
* @static
|
|
19
|
+
* @param {string} filename the file name to write to.
|
|
20
|
+
* @param {Buffer} data the data to write.
|
|
21
|
+
* @returns {Promise<void>}
|
|
22
|
+
*
|
|
23
|
+
* @memberof CreateResult
|
|
24
|
+
*/
|
|
25
|
+
private static async writeFile(filename: string, data: Buffer): Promise<void> {
|
|
26
|
+
return new Promise<void>((resolve, reject) => {
|
|
27
|
+
fs.writeFile(filename, data, (err) => {
|
|
28
|
+
err ? reject(err) : resolve();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Base64-encoded PDF data.
|
|
35
|
+
*
|
|
36
|
+
* @private
|
|
37
|
+
* @type {string}
|
|
38
|
+
* @memberof CreateResult
|
|
39
|
+
*/
|
|
40
|
+
private data: string;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Creates an instance of CreateResult.
|
|
44
|
+
* @param {string} data base64 PDF data
|
|
45
|
+
*
|
|
46
|
+
* @memberof CreateResult
|
|
47
|
+
*/
|
|
48
|
+
public constructor(data: string) {
|
|
49
|
+
this.data = data;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Get the base64 PDF data.
|
|
54
|
+
*
|
|
55
|
+
* @returns {string} base64 PDF data.
|
|
56
|
+
*
|
|
57
|
+
* @memberof CreateResult
|
|
58
|
+
*/
|
|
59
|
+
public toBase64(): string {
|
|
60
|
+
return this.data;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get a Buffer of the PDF data.
|
|
65
|
+
*
|
|
66
|
+
* @returns {Buffer} PDF data.
|
|
67
|
+
*
|
|
68
|
+
* @memberof CreateResult
|
|
69
|
+
*/
|
|
70
|
+
public toBuffer(): Buffer {
|
|
71
|
+
return Buffer.from(this.data, 'base64');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get a Stream of the PDF data.
|
|
76
|
+
*
|
|
77
|
+
* @returns {Stream} Stream of PDF data.
|
|
78
|
+
*
|
|
79
|
+
* @memberof CreateResult
|
|
80
|
+
*/
|
|
81
|
+
public toStream(): Stream {
|
|
82
|
+
const stream = new Readable();
|
|
83
|
+
stream.push(this.data, 'base64');
|
|
84
|
+
stream.push(null);
|
|
85
|
+
return stream;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Saves the PDF to a file.
|
|
90
|
+
*
|
|
91
|
+
* @param {string} filename the filename.
|
|
92
|
+
* @returns {Promise<void>} resolves upon successful create.
|
|
93
|
+
*
|
|
94
|
+
* @memberof CreateResult
|
|
95
|
+
*/
|
|
96
|
+
public async toFile(filename: string): Promise<void> {
|
|
97
|
+
await CreateResult.writeFile(filename, this.toBuffer());
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
import { launch, LaunchedChrome } from 'chrome-launcher';
|
|
4
|
+
import * as CDP from 'chrome-remote-interface';
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import { Readable, Stream } from 'stream';
|
|
7
|
+
|
|
8
|
+
import { ChromePrintOptions } from './ChromePrintOptions';
|
|
9
|
+
import * as CompletionTrigger from './CompletionTrigger';
|
|
10
|
+
import { CreateResult } from './CreateResult';
|
|
11
|
+
|
|
12
|
+
export { CompletionTrigger, CreateResult };
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* PDF generation options.
|
|
16
|
+
*
|
|
17
|
+
* @export
|
|
18
|
+
* @interface CreateOptions
|
|
19
|
+
*/
|
|
20
|
+
export interface CreateOptions {
|
|
21
|
+
/**
|
|
22
|
+
* The host to connect to Chrome at.
|
|
23
|
+
* If set, it attempts to connect to Chrome.
|
|
24
|
+
* If this and port are not set, it spawns
|
|
25
|
+
* Chrome for the duration of the PDF generation.
|
|
26
|
+
*
|
|
27
|
+
* @type {string}
|
|
28
|
+
* @memberof CreateOptions
|
|
29
|
+
*/
|
|
30
|
+
host?: string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The port to connect to Chrome with.
|
|
34
|
+
* If set, it attempts to connect to Chrome.
|
|
35
|
+
* If this and host are not set, it spawns
|
|
36
|
+
* Chrome for the duration of the PDF generation.
|
|
37
|
+
*
|
|
38
|
+
* @type {number}
|
|
39
|
+
* @memberof CreateOptions
|
|
40
|
+
*/
|
|
41
|
+
port?: number;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The explicit path of the intended Chrome binary.
|
|
45
|
+
*
|
|
46
|
+
* @type {string}
|
|
47
|
+
* @memberof CreateOptions
|
|
48
|
+
*/
|
|
49
|
+
chromePath?: string;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The options to pass to Chrome's Page.printToPDF.
|
|
53
|
+
* Note: these require Chrome >= 60.
|
|
54
|
+
*
|
|
55
|
+
* @type {ChromePrintOptions}
|
|
56
|
+
* @memberof CreateOptions
|
|
57
|
+
*/
|
|
58
|
+
printOptions?: ChromePrintOptions;
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* An optional CompletionTrigger to wait for before
|
|
62
|
+
* printing the rendered page to a PDF.
|
|
63
|
+
*
|
|
64
|
+
* @type {CompletionTrigger.CompletionTrigger}
|
|
65
|
+
* @memberof CreateOptions
|
|
66
|
+
*/
|
|
67
|
+
completionTrigger?: CompletionTrigger.CompletionTrigger;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The time in milliseconds to wait until timing out.
|
|
71
|
+
*/
|
|
72
|
+
timeout?: number;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* A private flag to signify the operation has been canceled.
|
|
76
|
+
*/
|
|
77
|
+
_canceled?: boolean;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Generates a PDF from the given HTML string, launching Chrome as necessary.
|
|
82
|
+
*
|
|
83
|
+
* @export
|
|
84
|
+
* @param {string} html the HTML string.
|
|
85
|
+
* @param {Options} [options] the generation options.
|
|
86
|
+
* @returns {Promise<CreateResult>} the generated PDF data.
|
|
87
|
+
*/
|
|
88
|
+
export async function create(html: string, options?: CreateOptions): Promise<CreateResult> {
|
|
89
|
+
const myOptions = Object.assign({}, options);
|
|
90
|
+
let chrome: LaunchedChrome;
|
|
91
|
+
|
|
92
|
+
myOptions._canceled = false;
|
|
93
|
+
if (myOptions.timeout >= 0) {
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
myOptions._canceled = true;
|
|
96
|
+
}, myOptions.timeout);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
await throwIfCanceled(myOptions);
|
|
100
|
+
if (!myOptions.host && !myOptions.port) {
|
|
101
|
+
await throwIfCanceled(myOptions);
|
|
102
|
+
chrome = await launchChrome(myOptions);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
return await generate(html, myOptions);
|
|
107
|
+
} finally {
|
|
108
|
+
if (chrome) {
|
|
109
|
+
await chrome.kill();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Connects to Chrome and generates a PDF from HTML or a URL.
|
|
116
|
+
*
|
|
117
|
+
* @param {string} html the HTML string or URL.
|
|
118
|
+
* @param {CreateOptions} options the generation options.
|
|
119
|
+
* @returns {Promise<CreateResult>} the generated PDF data.
|
|
120
|
+
*/
|
|
121
|
+
async function generate(html: string, options: CreateOptions): Promise<CreateResult> {
|
|
122
|
+
await throwIfCanceled(options);
|
|
123
|
+
const client = await CDP(options);
|
|
124
|
+
try {
|
|
125
|
+
const {Page} = client;
|
|
126
|
+
await Page.enable(); // Enable Page events
|
|
127
|
+
const url = /^(https?|file|data):/i.test(html) ? html : `data:text/html,${html}`;
|
|
128
|
+
await throwIfCanceled(options);
|
|
129
|
+
await Page.navigate({url});
|
|
130
|
+
await throwIfCanceled(options);
|
|
131
|
+
await Page.loadEventFired();
|
|
132
|
+
if (options.completionTrigger) {
|
|
133
|
+
await throwIfCanceled(options);
|
|
134
|
+
const waitResult = await options.completionTrigger.wait(client);
|
|
135
|
+
if (waitResult && waitResult.exceptionDetails) {
|
|
136
|
+
await throwIfCanceled(options);
|
|
137
|
+
throw new Error(waitResult.result.value);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
await throwIfCanceled(options);
|
|
141
|
+
// https://chromedevtools.github.io/debugger-protocol-viewer/tot/Page/#method-printToPDF
|
|
142
|
+
const pdf = await Page.printToPDF(options.printOptions);
|
|
143
|
+
await throwIfCanceled(options);
|
|
144
|
+
return new CreateResult(pdf.data);
|
|
145
|
+
} finally {
|
|
146
|
+
client.close();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Throws an exception if the operation has been canceled.
|
|
152
|
+
*
|
|
153
|
+
* @param {CreateOptions} options the options which track cancellation.
|
|
154
|
+
* @returns {Promise<void>} reject if cancelled, resolve if not.
|
|
155
|
+
*/
|
|
156
|
+
async function throwIfCanceled(options: CreateOptions): Promise<void> {
|
|
157
|
+
if (options._canceled) {
|
|
158
|
+
throw new Error('HtmlPdf.create() timed out.');
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Launches Chrome with the specified options.
|
|
164
|
+
*
|
|
165
|
+
* @param {CreateOptions} options the options for Chrome.
|
|
166
|
+
* @returns {Promise<LaunchedChrome>} The launched Chrome instance.
|
|
167
|
+
*/
|
|
168
|
+
async function launchChrome(options: CreateOptions): Promise<LaunchedChrome> {
|
|
169
|
+
const chrome = await launch({
|
|
170
|
+
port: options.port,
|
|
171
|
+
chromePath: options.chromePath,
|
|
172
|
+
chromeFlags: [
|
|
173
|
+
'--disable-gpu',
|
|
174
|
+
'--headless',
|
|
175
|
+
],
|
|
176
|
+
});
|
|
177
|
+
options.port = chrome.port;
|
|
178
|
+
return chrome;
|
|
179
|
+
}
|