dragonfly_chrome_headless 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (228) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +12 -0
  4. data/Gemfile +4 -0
  5. data/README.md +53 -0
  6. data/Rakefile +10 -0
  7. data/bin/console +14 -0
  8. data/bin/setup +8 -0
  9. data/dragonfly_chrome_headless.gemspec +27 -0
  10. data/lib/dragonfly_chrome_headless.rb +9 -0
  11. data/lib/dragonfly_chrome_headless/plugin.rb +17 -0
  12. data/lib/dragonfly_chrome_headless/processors/rasterize.rb +33 -0
  13. data/lib/dragonfly_chrome_headless/version.rb +3 -0
  14. data/node_modules/.bin/chrome-remote-interface +1 -0
  15. data/node_modules/.bin/mkdirp +1 -0
  16. data/node_modules/.bin/rimraf +1 -0
  17. data/node_modules/@types/core-js/LICENSE +21 -0
  18. data/node_modules/@types/core-js/README.md +16 -0
  19. data/node_modules/@types/core-js/index.d.ts +2452 -0
  20. data/node_modules/@types/core-js/package.json +85 -0
  21. data/node_modules/@types/mkdirp/README.md +18 -0
  22. data/node_modules/@types/mkdirp/index.d.ts +14 -0
  23. data/node_modules/@types/mkdirp/package.json +77 -0
  24. data/node_modules/@types/mkdirp/types-metadata.json +25 -0
  25. data/node_modules/@types/node/README.md +16 -0
  26. data/node_modules/@types/node/index.d.ts +4132 -0
  27. data/node_modules/@types/node/package.json +84 -0
  28. data/node_modules/balanced-match/.npmignore +5 -0
  29. data/node_modules/balanced-match/LICENSE.md +21 -0
  30. data/node_modules/balanced-match/README.md +91 -0
  31. data/node_modules/balanced-match/index.js +59 -0
  32. data/node_modules/balanced-match/package.json +112 -0
  33. data/node_modules/brace-expansion/README.md +123 -0
  34. data/node_modules/brace-expansion/index.js +201 -0
  35. data/node_modules/brace-expansion/package.json +114 -0
  36. data/node_modules/chrome-launcher/.clang-format +6 -0
  37. data/node_modules/chrome-launcher/.npmignore +11 -0
  38. data/node_modules/chrome-launcher/README.md +123 -0
  39. data/node_modules/chrome-launcher/ask.js +32 -0
  40. data/node_modules/chrome-launcher/ask.ts +35 -0
  41. data/node_modules/chrome-launcher/chrome-finder.js +157 -0
  42. data/node_modules/chrome-launcher/chrome-finder.ts +186 -0
  43. data/node_modules/chrome-launcher/chrome-launcher.js +245 -0
  44. data/node_modules/chrome-launcher/chrome-launcher.ts +312 -0
  45. data/node_modules/chrome-launcher/compiled-check.js +14 -0
  46. data/node_modules/chrome-launcher/flags.js +27 -0
  47. data/node_modules/chrome-launcher/flags.ts +26 -0
  48. data/node_modules/chrome-launcher/index.js +7 -0
  49. data/node_modules/chrome-launcher/index.ts +1 -0
  50. data/node_modules/chrome-launcher/manual-chrome-launcher.js +30 -0
  51. data/node_modules/chrome-launcher/package.json +116 -0
  52. data/node_modules/chrome-launcher/random-port.js +24 -0
  53. data/node_modules/chrome-launcher/random-port.ts +23 -0
  54. data/node_modules/chrome-launcher/tsconfig.json +19 -0
  55. data/node_modules/chrome-launcher/utils.js +52 -0
  56. data/node_modules/chrome-launcher/utils.ts +44 -0
  57. data/node_modules/chrome-launcher/yarn.lock +1486 -0
  58. data/node_modules/chrome-remote-interface/LICENSE +18 -0
  59. data/node_modules/chrome-remote-interface/README.md +849 -0
  60. data/node_modules/chrome-remote-interface/bin/client.js +337 -0
  61. data/node_modules/chrome-remote-interface/chrome-remote-interface.js +11 -0
  62. data/node_modules/chrome-remote-interface/index.js +39 -0
  63. data/node_modules/chrome-remote-interface/lib/api.js +84 -0
  64. data/node_modules/chrome-remote-interface/lib/chrome.js +307 -0
  65. data/node_modules/chrome-remote-interface/lib/defaults.js +4 -0
  66. data/node_modules/chrome-remote-interface/lib/devtools.js +245 -0
  67. data/node_modules/chrome-remote-interface/lib/external-request.js +28 -0
  68. data/node_modules/chrome-remote-interface/lib/protocol.json +13780 -0
  69. data/node_modules/chrome-remote-interface/lib/websocket-wrapper.js +32 -0
  70. data/node_modules/chrome-remote-interface/package.json +128 -0
  71. data/node_modules/chrome-remote-interface/webpack.config.js +55 -0
  72. data/node_modules/commander/Readme.md +195 -0
  73. data/node_modules/commander/index.js +851 -0
  74. data/node_modules/commander/package.json +92 -0
  75. data/node_modules/concat-map/.travis.yml +4 -0
  76. data/node_modules/concat-map/LICENSE +18 -0
  77. data/node_modules/concat-map/README.markdown +62 -0
  78. data/node_modules/concat-map/example/map.js +6 -0
  79. data/node_modules/concat-map/index.js +13 -0
  80. data/node_modules/concat-map/package.json +117 -0
  81. data/node_modules/concat-map/test/map.js +39 -0
  82. data/node_modules/debug/.coveralls.yml +1 -0
  83. data/node_modules/debug/.eslintrc +11 -0
  84. data/node_modules/debug/.npmignore +9 -0
  85. data/node_modules/debug/.travis.yml +14 -0
  86. data/node_modules/debug/CHANGELOG.md +357 -0
  87. data/node_modules/debug/LICENSE +19 -0
  88. data/node_modules/debug/Makefile +50 -0
  89. data/node_modules/debug/Readme.md +312 -0
  90. data/node_modules/debug/component.json +19 -0
  91. data/node_modules/debug/karma.conf.js +70 -0
  92. data/node_modules/debug/node.js +1 -0
  93. data/node_modules/debug/package.json +124 -0
  94. data/node_modules/debug/src/browser.js +185 -0
  95. data/node_modules/debug/src/debug.js +202 -0
  96. data/node_modules/debug/src/index.js +10 -0
  97. data/node_modules/debug/src/node.js +246 -0
  98. data/node_modules/fs.realpath/LICENSE +43 -0
  99. data/node_modules/fs.realpath/README.md +33 -0
  100. data/node_modules/fs.realpath/index.js +66 -0
  101. data/node_modules/fs.realpath/old.js +303 -0
  102. data/node_modules/fs.realpath/package.json +94 -0
  103. data/node_modules/glob/LICENSE +15 -0
  104. data/node_modules/glob/README.md +368 -0
  105. data/node_modules/glob/changelog.md +67 -0
  106. data/node_modules/glob/common.js +240 -0
  107. data/node_modules/glob/glob.js +790 -0
  108. data/node_modules/glob/package.json +112 -0
  109. data/node_modules/glob/sync.js +486 -0
  110. data/node_modules/html-pdf-chrome/.npmignore +9 -0
  111. data/node_modules/html-pdf-chrome/LICENSE +21 -0
  112. data/node_modules/html-pdf-chrome/README.md +165 -0
  113. data/node_modules/html-pdf-chrome/lib/src/ChromePrintOptions.d.ts +87 -0
  114. data/node_modules/html-pdf-chrome/lib/src/ChromePrintOptions.js +4 -0
  115. data/node_modules/html-pdf-chrome/lib/src/ChromePrintOptions.js.map +1 -0
  116. data/node_modules/html-pdf-chrome/lib/src/CompletionTrigger.d.ts +120 -0
  117. data/node_modules/html-pdf-chrome/lib/src/CompletionTrigger.js +206 -0
  118. data/node_modules/html-pdf-chrome/lib/src/CompletionTrigger.js.map +1 -0
  119. data/node_modules/html-pdf-chrome/lib/src/CreateResult.d.ts +70 -0
  120. data/node_modules/html-pdf-chrome/lib/src/CreateResult.js +98 -0
  121. data/node_modules/html-pdf-chrome/lib/src/CreateResult.js.map +1 -0
  122. data/node_modules/html-pdf-chrome/lib/src/index.d.ts +72 -0
  123. data/node_modules/html-pdf-chrome/lib/src/index.js +123 -0
  124. data/node_modules/html-pdf-chrome/lib/src/index.js.map +1 -0
  125. data/node_modules/html-pdf-chrome/package.json +133 -0
  126. data/node_modules/html-pdf-chrome/src/ChromePrintOptions.ts +99 -0
  127. data/node_modules/html-pdf-chrome/src/CompletionTrigger.ts +201 -0
  128. data/node_modules/html-pdf-chrome/src/CreateResult.ts +100 -0
  129. data/node_modules/html-pdf-chrome/src/index.ts +179 -0
  130. data/node_modules/inflight/LICENSE +15 -0
  131. data/node_modules/inflight/README.md +37 -0
  132. data/node_modules/inflight/inflight.js +54 -0
  133. data/node_modules/inflight/package.json +105 -0
  134. data/node_modules/inherits/LICENSE +16 -0
  135. data/node_modules/inherits/README.md +42 -0
  136. data/node_modules/inherits/inherits.js +7 -0
  137. data/node_modules/inherits/inherits_browser.js +23 -0
  138. data/node_modules/inherits/package.json +97 -0
  139. data/node_modules/lighthouse-logger/README.md +4 -0
  140. data/node_modules/lighthouse-logger/index.js +212 -0
  141. data/node_modules/lighthouse-logger/package.json +69 -0
  142. data/node_modules/lighthouse-logger/yarn.lock +13 -0
  143. data/node_modules/minimatch/LICENSE +15 -0
  144. data/node_modules/minimatch/README.md +209 -0
  145. data/node_modules/minimatch/minimatch.js +923 -0
  146. data/node_modules/minimatch/package.json +99 -0
  147. data/node_modules/minimist/.travis.yml +4 -0
  148. data/node_modules/minimist/LICENSE +18 -0
  149. data/node_modules/minimist/example/parse.js +2 -0
  150. data/node_modules/minimist/index.js +187 -0
  151. data/node_modules/minimist/package.json +101 -0
  152. data/node_modules/minimist/readme.markdown +73 -0
  153. data/node_modules/minimist/test/dash.js +24 -0
  154. data/node_modules/minimist/test/default_bool.js +20 -0
  155. data/node_modules/minimist/test/dotted.js +16 -0
  156. data/node_modules/minimist/test/long.js +31 -0
  157. data/node_modules/minimist/test/parse.js +318 -0
  158. data/node_modules/minimist/test/parse_modified.js +9 -0
  159. data/node_modules/minimist/test/short.js +67 -0
  160. data/node_modules/minimist/test/whitespace.js +8 -0
  161. data/node_modules/mkdirp/.travis.yml +8 -0
  162. data/node_modules/mkdirp/LICENSE +21 -0
  163. data/node_modules/mkdirp/bin/cmd.js +33 -0
  164. data/node_modules/mkdirp/bin/usage.txt +12 -0
  165. data/node_modules/mkdirp/examples/pow.js +6 -0
  166. data/node_modules/mkdirp/index.js +98 -0
  167. data/node_modules/mkdirp/package.json +93 -0
  168. data/node_modules/mkdirp/readme.markdown +100 -0
  169. data/node_modules/mkdirp/test/chmod.js +41 -0
  170. data/node_modules/mkdirp/test/clobber.js +38 -0
  171. data/node_modules/mkdirp/test/mkdirp.js +28 -0
  172. data/node_modules/mkdirp/test/opts_fs.js +29 -0
  173. data/node_modules/mkdirp/test/opts_fs_sync.js +27 -0
  174. data/node_modules/mkdirp/test/perm.js +32 -0
  175. data/node_modules/mkdirp/test/perm_sync.js +36 -0
  176. data/node_modules/mkdirp/test/race.js +37 -0
  177. data/node_modules/mkdirp/test/rel.js +32 -0
  178. data/node_modules/mkdirp/test/return.js +25 -0
  179. data/node_modules/mkdirp/test/return_sync.js +24 -0
  180. data/node_modules/mkdirp/test/root.js +19 -0
  181. data/node_modules/mkdirp/test/sync.js +32 -0
  182. data/node_modules/mkdirp/test/umask.js +28 -0
  183. data/node_modules/mkdirp/test/umask_sync.js +32 -0
  184. data/node_modules/ms/README.md +51 -0
  185. data/node_modules/ms/index.js +152 -0
  186. data/node_modules/ms/license.md +21 -0
  187. data/node_modules/ms/package.json +109 -0
  188. data/node_modules/once/LICENSE +15 -0
  189. data/node_modules/once/README.md +79 -0
  190. data/node_modules/once/once.js +42 -0
  191. data/node_modules/once/package.json +101 -0
  192. data/node_modules/path-is-absolute/index.js +20 -0
  193. data/node_modules/path-is-absolute/license +21 -0
  194. data/node_modules/path-is-absolute/package.json +111 -0
  195. data/node_modules/path-is-absolute/readme.md +59 -0
  196. data/node_modules/rimraf/LICENSE +15 -0
  197. data/node_modules/rimraf/README.md +101 -0
  198. data/node_modules/rimraf/bin.js +50 -0
  199. data/node_modules/rimraf/package.json +99 -0
  200. data/node_modules/rimraf/rimraf.js +363 -0
  201. data/node_modules/ultron/LICENSE +22 -0
  202. data/node_modules/ultron/index.js +138 -0
  203. data/node_modules/ultron/package.json +112 -0
  204. data/node_modules/wrappy/LICENSE +15 -0
  205. data/node_modules/wrappy/README.md +36 -0
  206. data/node_modules/wrappy/package.json +97 -0
  207. data/node_modules/wrappy/wrappy.js +33 -0
  208. data/node_modules/ws/LICENSE +21 -0
  209. data/node_modules/ws/README.md +259 -0
  210. data/node_modules/ws/SECURITY.md +33 -0
  211. data/node_modules/ws/index.js +15 -0
  212. data/node_modules/ws/lib/BufferUtil.fallback.js +56 -0
  213. data/node_modules/ws/lib/BufferUtil.js +15 -0
  214. data/node_modules/ws/lib/ErrorCodes.js +28 -0
  215. data/node_modules/ws/lib/EventTarget.js +158 -0
  216. data/node_modules/ws/lib/Extensions.js +69 -0
  217. data/node_modules/ws/lib/PerMessageDeflate.js +339 -0
  218. data/node_modules/ws/lib/Receiver.js +520 -0
  219. data/node_modules/ws/lib/Sender.js +438 -0
  220. data/node_modules/ws/lib/Validation.fallback.js +9 -0
  221. data/node_modules/ws/lib/Validation.js +17 -0
  222. data/node_modules/ws/lib/WebSocket.js +705 -0
  223. data/node_modules/ws/lib/WebSocketServer.js +336 -0
  224. data/node_modules/ws/package.json +122 -0
  225. data/package.json +26 -0
  226. data/samples/sample.html +13 -0
  227. data/script/rasterize.js +18 -0
  228. 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
+ }