various fixes
This commit is contained in:
@@ -24,6 +24,8 @@ browser.runtime.onMessage.addListener((msg, sender) => {
|
||||
return saveNote(msg);
|
||||
case 'upload_attachment':
|
||||
return uploadAttachment(msg);
|
||||
case 'capture_full_page':
|
||||
return captureFullPage(msg);
|
||||
default:
|
||||
return Promise.reject(new Error('Unknown message kind'));
|
||||
}
|
||||
@@ -93,6 +95,60 @@ async function uploadAttachment(msg) {
|
||||
return res.json();
|
||||
}
|
||||
|
||||
const MAX_SLICES = 60;
|
||||
|
||||
function sleep(ms) {
|
||||
return new Promise(function (resolve) { setTimeout(resolve, ms); });
|
||||
}
|
||||
|
||||
function loadImage(dataUrl) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const img = new Image();
|
||||
img.onload = function () { resolve(img); };
|
||||
img.onerror = function () { reject(new Error('Could not decode screenshot slice')); };
|
||||
img.src = dataUrl;
|
||||
});
|
||||
}
|
||||
|
||||
async function captureFullPage(msg) {
|
||||
const tabId = msg.tabId;
|
||||
const windowId = msg.windowId;
|
||||
if (tabId == null) throw new Error('No active tab');
|
||||
|
||||
const dims = await browser.tabs.sendMessage(tabId, { kind: 'get_viewport' });
|
||||
const vw = dims.viewportWidth || 1;
|
||||
const vh = dims.viewportHeight || 1;
|
||||
const ph = dims.pageHeight || vh;
|
||||
const dpr = dims.devicePixelRatio || 1;
|
||||
|
||||
const sliceCount = Math.min(MAX_SLICES, Math.ceil(ph / vh));
|
||||
if (Math.ceil(ph / vh) > MAX_SLICES) {
|
||||
throw new Error('Page too tall to capture (' + Math.ceil(ph / vh) + ' viewports)');
|
||||
}
|
||||
|
||||
const parts = [];
|
||||
for (let i = 0; i < sliceCount; i++) {
|
||||
const y = Math.max(0, Math.min(i * vh, ph - vh));
|
||||
await browser.tabs.sendMessage(tabId, { kind: 'scroll_to', y: y });
|
||||
await sleep(250);
|
||||
const dataUrl = await browser.tabs.captureVisibleTab(windowId, { format: 'png' });
|
||||
parts.push({ dataUrl: dataUrl, y: y });
|
||||
}
|
||||
|
||||
await browser.tabs.sendMessage(tabId, { kind: 'scroll_to', y: dims.scrollY || 0 }).catch(() => {});
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.width = Math.round(vw * dpr);
|
||||
canvas.height = Math.round(ph * dpr);
|
||||
const ctx = canvas.getContext('2d');
|
||||
for (const p of parts) {
|
||||
const img = await loadImage(p.dataUrl);
|
||||
ctx.drawImage(img, 0, Math.round(p.y * dpr));
|
||||
}
|
||||
|
||||
return { dataUrl: canvas.toDataURL('image/png') };
|
||||
}
|
||||
|
||||
function dataUrlToBlob(dataUrl) {
|
||||
const [meta, b64] = dataUrl.split(',');
|
||||
const mime = (meta.match(/data:(.*?);/) || [])[1] || 'image/png';
|
||||
|
||||
Reference in New Issue
Block a user