async function* makeFullPageScreenshots({ windowId, tabId, timeout = 500 }) {
const { result: windowInfo } = await api.custom.injectScript(
{ tabId },
{
args: [{ timeout }],
func: async function ({ timeout = 0 } = {}) {
await untilLoaded();
const div = document.createElement("div");
Object.assign(div.style, {
backgroundColor: "rgba(255,255,255,0)",
zIndex: 100000,
position: "fixed",
top: 0,
left: 0,
right: 0,
bottom: 0
});
const body = document.body;
body.appendChild(div);
// Await for the content loading before measuring the document size
await new Promise((resolve) => {
timeout
? setTimeout(resolve, timeout)
: requestAnimationFrame(resolve);
});
// Get the page parameters to return
const { x, y, top, right, bottom, left, width, height } =
body.getBoundingClientRect();
const { innerHeight, innerWidth } = window;
const info = {
x,
y,
top,
right,
bottom,
left,
width,
height,
window: {
innerHeight: window.innerHeight,
innerWidth: window.innerWidth
},
body: {
clientWidth: body.clientWidth,
clientHeight: body.clientHeight,
scrollHeight: body.scrollHeight,
scrollWidth: body.scrollWidth
}
};
return info;
async function untilLoaded() {
return new Promise((resolve, reject) => {
if (document.readyState === "complete") {
resolve();
} else {
document.addEventListener("DOMContentLoaded", function onLoad() {
resolve();
document.removeEventListener("DOMContentLoaded", onLoad);
});
}
});
}
}.toString()
}
);
console.log("* [windowInfo]", windowInfo);
const scrollHeight = windowInfo.body.scrollHeight;
const windowHeight = windowInfo.window.innerHeight;
const bodyWidth = windowInfo.body.clientWidth;
for (
let pos = 0, prevPos = 0;
pos < scrollHeight;
prevPos = pos, pos += windowHeight
) {
if (pos > 0) {
await scrollTo({ tabId }, pos);
}
// We have to wait at least 500ms because the default
// MAX_CAPTURE_VISIBLE_TAB_CALLS_PER_SECOND value is 2
// (2 screenshots per second)
await Promises.delay(500);
const imgUrl = await api.tabs.captureVisibleTab(windowId, {
format: "png"
});
const top = windowHeight - Math.min(scrollHeight - pos, windowHeight);
const bottom = windowHeight;
const left = 0;
const right = bodyWidth;
yield {
imgUrl,
top,
right,
bottom,
left
};
}
async function scrollTo(target, pos) {
return await api.custom.injectScript(target, {
args: [pos],
func: async function (pos) {
window.scrollTo(0, pos);
}.toString()
});
}
}