|
@@ -113,44 +113,60 @@ function onTabRemoved(tabId) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
async function captureTab(tabId, options) {
|
|
async function captureTab(tabId, options) {
|
|
|
- const { width, height } = options;
|
|
|
|
|
- const canvas = new OffscreenCanvas(width, height);
|
|
|
|
|
- const context = canvas.getContext("2d");
|
|
|
|
|
|
|
+ const { width, height, scale = 1 } = options;
|
|
|
|
|
+ const canvasWidth = Math.floor(width * scale);
|
|
|
|
|
+ const canvasHeight = Math.floor(height * scale);
|
|
|
const image = new Image();
|
|
const image = new Image();
|
|
|
- let y = 0, scrollYStep, activeTabId;
|
|
|
|
|
|
|
+ let y = 0, canvas, canvasY = 0, scrollYStep, activeTabId;
|
|
|
if (browser.tabs.captureTab) {
|
|
if (browser.tabs.captureTab) {
|
|
|
scrollYStep = 4 * 1024;
|
|
scrollYStep = 4 * 1024;
|
|
|
} else {
|
|
} else {
|
|
|
scrollYStep = options.innerHeight;
|
|
scrollYStep = options.innerHeight;
|
|
|
activeTabId = (await browser.tabs.query({ active: true, currentWindow: true }))[0].id;
|
|
activeTabId = (await browser.tabs.query({ active: true, currentWindow: true }))[0].id;
|
|
|
- await browser.tabs.sendMessage(tabId, { method: "content.beginScrollTo" });
|
|
|
|
|
}
|
|
}
|
|
|
- while (y < height) {
|
|
|
|
|
- let imageSrc;
|
|
|
|
|
- if (browser.tabs.captureTab) {
|
|
|
|
|
- imageSrc = await browser.tabs.captureTab(tabId, {
|
|
|
|
|
- format: "png",
|
|
|
|
|
- rect: { x: 0, y, width, height: Math.min(height - y, scrollYStep) }
|
|
|
|
|
|
|
+ const canvasScrollStep = Math.floor(scrollYStep * scale);
|
|
|
|
|
+ await browser.tabs.sendMessage(tabId, { method: "content.beginScrollTo" });
|
|
|
|
|
+ try {
|
|
|
|
|
+ canvas = new OffscreenCanvas(canvasWidth, canvasHeight);
|
|
|
|
|
+ const context = canvas.getContext("2d");
|
|
|
|
|
+ while (y < height) {
|
|
|
|
|
+ let imageSrc;
|
|
|
|
|
+ if (browser.tabs.captureTab) {
|
|
|
|
|
+ imageSrc = await browser.tabs.captureTab(tabId, {
|
|
|
|
|
+ format: "png",
|
|
|
|
|
+ rect: { x: 0, y, width, height: Math.min(height - y, scrollYStep) }
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ await browser.tabs.sendMessage(tabId, { method: "content.scrollTo", y });
|
|
|
|
|
+ await browser.tabs.update(tabId, { active: true });
|
|
|
|
|
+ imageSrc = await browser.tabs.captureVisibleTab(null, {
|
|
|
|
|
+ format: "png"
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ await new Promise((resolve, reject) => {
|
|
|
|
|
+ image.onload = resolve;
|
|
|
|
|
+ image.onerror = event => reject(new Error(event.detail));
|
|
|
|
|
+ image.src = imageSrc;
|
|
|
});
|
|
});
|
|
|
|
|
+ const imageHeight = Math.min(canvasHeight - canvasY, canvasScrollStep);
|
|
|
|
|
+ context.drawImage(image, 0, canvasY, canvasWidth, imageHeight);
|
|
|
|
|
+ y += scrollYStep;
|
|
|
|
|
+ canvasY += canvasScrollStep;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!browser.tabs.captureTab) {
|
|
|
|
|
+ await browser.tabs.update(activeTabId, { active: true });
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ if (scale > .1) {
|
|
|
|
|
+ options.scale = scale * .75;
|
|
|
|
|
+ return captureTab(tabId, options);
|
|
|
} else {
|
|
} else {
|
|
|
- await browser.tabs.sendMessage(tabId, { method: "content.scrollTo", y });
|
|
|
|
|
- await browser.tabs.update(tabId, { active: true });
|
|
|
|
|
- imageSrc = await browser.tabs.captureVisibleTab(null, {
|
|
|
|
|
- format: "png"
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ throw error;
|
|
|
}
|
|
}
|
|
|
- await new Promise((resolve, reject) => {
|
|
|
|
|
- image.onload = resolve;
|
|
|
|
|
- image.onerror = event => reject(new Error(event.detail));
|
|
|
|
|
- image.src = imageSrc;
|
|
|
|
|
- });
|
|
|
|
|
- context.drawImage(image, 0, y, width, Math.min(height - y, scrollYStep));
|
|
|
|
|
- y += scrollYStep;
|
|
|
|
|
- }
|
|
|
|
|
- if (!browser.tabs.captureTab) {
|
|
|
|
|
- await browser.tabs.update(activeTabId, { active: true });
|
|
|
|
|
|
|
+ } finally {
|
|
|
await browser.tabs.sendMessage(tabId, { method: "content.endScrollTo" });
|
|
await browser.tabs.sendMessage(tabId, { method: "content.endScrollTo" });
|
|
|
}
|
|
}
|
|
|
- const blob = await canvas.convertToBlob({ type: "image/png" });
|
|
|
|
|
- return URL.createObjectURL(blob);
|
|
|
|
|
|
|
+ if (canvas) {
|
|
|
|
|
+ return URL.createObjectURL(await canvas.convertToBlob({ type: "image/png" }));
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|