single-file-cli 2.0.34 → 2.0.36
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.
- package/build.sh +1 -1
- package/deno.json +1 -1
- package/lib/cdp-client.js +68 -10
- package/lib/single-file-bundle.js +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/single-file-launcher.js +3 -3
package/build.sh
CHANGED
package/deno.json
CHANGED
package/lib/cdp-client.js
CHANGED
|
@@ -32,6 +32,9 @@ const NETWORK_STATES = ["InteractiveTime", "networkIdle", "networkAlmostIdle", "
|
|
|
32
32
|
const MINIMIZED_WINDOW_STATE = "minimized";
|
|
33
33
|
const SINGLE_FILE_WORLD_NAME = "singlefile";
|
|
34
34
|
const EMPTY_PAGE_URL = "about:blank";
|
|
35
|
+
const CAPTURE_SCREENSHOT_FUNCTION_NAME = "captureScreenshot";
|
|
36
|
+
const SET_SCREENSHOT_FUNCTION_NAME = "setScreenshot";
|
|
37
|
+
const SET_PAGE_DATA_FUNCTION_NAME = "setPageData";
|
|
35
38
|
|
|
36
39
|
export { initialize, getPageData, closeBrowser };
|
|
37
40
|
|
|
@@ -103,27 +106,45 @@ async function getPageData(options) {
|
|
|
103
106
|
options.browserDebug ? waitForDebuggerReady({ Debugger }) : Promise.resolve()
|
|
104
107
|
]);
|
|
105
108
|
if (options.browserWaitDelay) {
|
|
106
|
-
|
|
109
|
+
await new Promise(resolve => setTimeout(resolve, options.browserWaitDelay));
|
|
107
110
|
}
|
|
111
|
+
await Runtime.addBinding({ name: SET_PAGE_DATA_FUNCTION_NAME, executionContextId: contextId });
|
|
112
|
+
const pageDataPromise = new Promise(resolve => {
|
|
113
|
+
let pageDataResponse = "";
|
|
114
|
+
Runtime.addEventListener("bindingCalled", async ({ params }) => {
|
|
115
|
+
if (params.name === SET_PAGE_DATA_FUNCTION_NAME) {
|
|
116
|
+
const { payload } = params;
|
|
117
|
+
if (payload.length) {
|
|
118
|
+
pageDataResponse += payload;
|
|
119
|
+
} else {
|
|
120
|
+
const result = JSON.parse(pageDataResponse);
|
|
121
|
+
if (result.content instanceof Array) {
|
|
122
|
+
result.content = new Uint8Array(result.content);
|
|
123
|
+
}
|
|
124
|
+
resolve(result);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
});
|
|
108
129
|
if (options.embedScreenshot && options.compressContent) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
130
|
+
await Runtime.addBinding({ name: CAPTURE_SCREENSHOT_FUNCTION_NAME, executionContextId: contextId });
|
|
131
|
+
Runtime.addEventListener("bindingCalled", ({ params }) => {
|
|
132
|
+
if (params.name === CAPTURE_SCREENSHOT_FUNCTION_NAME) {
|
|
133
|
+
onCaptureScreenshot({ Page, Runtime }, contextId);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
112
136
|
}
|
|
113
137
|
const { result } = await Runtime.evaluate({
|
|
114
|
-
expression: `
|
|
138
|
+
expression: `(${getPageDataScriptSource.toString()})(${JSON.stringify(options)},${JSON.stringify([SET_SCREENSHOT_FUNCTION_NAME, SET_PAGE_DATA_FUNCTION_NAME])})`,
|
|
115
139
|
awaitPromise: true,
|
|
116
140
|
returnByValue: true,
|
|
117
141
|
contextId
|
|
118
142
|
});
|
|
119
|
-
const {
|
|
143
|
+
const { subtype, description } = result;
|
|
120
144
|
if (subtype === "error") {
|
|
121
145
|
throw new Error(description);
|
|
122
146
|
}
|
|
123
|
-
|
|
124
|
-
value.content = new Uint8Array(value.content);
|
|
125
|
-
}
|
|
126
|
-
return value;
|
|
147
|
+
return pageDataPromise;
|
|
127
148
|
} catch (error) {
|
|
128
149
|
if (error.code === LOAD_TIMEOUT_ERROR && options.browserWaitUntilFallback && options.browserWaitUntil) {
|
|
129
150
|
const browserWaitUntil = NETWORK_STATES[(NETWORK_STATES.indexOf(options.browserWaitUntil) + 1)];
|
|
@@ -140,6 +161,43 @@ async function getPageData(options) {
|
|
|
140
161
|
}
|
|
141
162
|
}
|
|
142
163
|
|
|
164
|
+
async function onCaptureScreenshot({ Page, Runtime }, contextId) {
|
|
165
|
+
const { data } = await Page.captureScreenshot({ format: "png", captureBeyondViewport: true });
|
|
166
|
+
const dataURI = "data:image/png;base64," + data;
|
|
167
|
+
const screenshotData = Array.from(new Uint8Array(await (await fetch(dataURI)).arrayBuffer()));
|
|
168
|
+
await Runtime.evaluate({
|
|
169
|
+
expression: `globalThis.${SET_SCREENSHOT_FUNCTION_NAME}(${JSON.stringify(screenshotData)})`,
|
|
170
|
+
contextId
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function getPageDataScriptSource(options, [SET_SCREENSHOT_FUNCTION_NAME, SET_PAGE_DATA_FUNCTION_NAME]) {
|
|
175
|
+
if (options.embedScreenshot && options.compressContent) {
|
|
176
|
+
let screenshot = new Promise(resolve => globalThis[SET_SCREENSHOT_FUNCTION_NAME] = resolve);
|
|
177
|
+
let pendingCapture;
|
|
178
|
+
options.onprogress = async event => {
|
|
179
|
+
if (event.type == event.RESOURCES_INITIALIZING && globalThis.captureScreenshot && window == top && !pendingCapture) {
|
|
180
|
+
pendingCapture = true;
|
|
181
|
+
globalThis.captureScreenshot("");
|
|
182
|
+
options.embeddedImage = await screenshot;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
const MAX_CONTENT_SIZE = 32 * 1024 * 1024;
|
|
187
|
+
return singlefile.getPageData(options).then(data => {
|
|
188
|
+
if (data.content instanceof Uint8Array) {
|
|
189
|
+
data.content = Array.from(data.content);
|
|
190
|
+
}
|
|
191
|
+
data = JSON.stringify(data);
|
|
192
|
+
let indexData = 0;
|
|
193
|
+
do {
|
|
194
|
+
globalThis[SET_PAGE_DATA_FUNCTION_NAME](data.slice(indexData, indexData + MAX_CONTENT_SIZE));
|
|
195
|
+
indexData += MAX_CONTENT_SIZE;
|
|
196
|
+
} while (indexData < data.length);
|
|
197
|
+
globalThis[SET_PAGE_DATA_FUNCTION_NAME]("");
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
|
|
143
201
|
async function loadPage({ Page, Runtime }, options) {
|
|
144
202
|
await Runtime.enable();
|
|
145
203
|
await Page.enable();
|