@wenathlan/extension 1.1.39 → 1.1.41
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/README.md +6 -4
- package/dist/capture.d.ts +161 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +907 -5
- package/dist/index.js.map +4 -4
- package/dist/media.d.ts +96 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/memory.d.ts +40 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/policy.d.ts +31 -1
- package/dist/policy.d.ts.map +1 -1
- package/dist/protocol.d.ts +34 -2
- package/dist/protocol.d.ts.map +1 -1
- package/dist/types.d.ts +294 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/extension/dist/background.js +1786 -51
- package/extension/dist/background.js.map +4 -4
- package/extension/dist/manifest.json +1 -1
- package/extension/dist/pagebridge.js +245 -3
- package/extension/dist/pagebridge.js.map +3 -3
- package/extension/dist/popup.html +1 -1
- package/extension/dist/popup.js +22 -2
- package/extension/dist/popup.js.map +2 -2
- package/extension/dist/sidepanel.html +1 -1
- package/extension/dist/sidepanel.js +390 -2
- package/extension/dist/sidepanel.js.map +3 -3
- package/extension/dist/style.css +4 -0
- package/extension/manifest.json +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"manifest_version": 3,
|
|
3
3
|
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnOEjO8Z0PDgQyfvawGcaO2j+o0GLCFTLNj7TkYC/Avo9l2NenMRq7gp90Nfd7E9MViv/OMcCKSYZ5unv12QPRtv31C+a5UQWDFAOP/cH5mwMd6hsayElrSoW8ta+FwFqmr9dIFkn7cQEU3YhZr4Gcbs+ycUHOxVgDA4NBKB0rQ6e9VW5LvTw0isRYUrqM+M72vKxHk9zUIYYn/LGPvottKBYi2GLr0PHSeC2UE+Shmq7vcFIXj6hDjvD4kLJ5sKoUllEcZ1TPuBcnHUQ9ndKA5iktXDQOIJCUJmi7a0YJ2PGg7fvpYfT9k0ai/qZ+pIoRfoOEwE01bPoDn7NjeYnNQIDAQAB",
|
|
4
4
|
"name": "Devthink",
|
|
5
|
-
"version": "1.1.
|
|
5
|
+
"version": "1.1.41",
|
|
6
6
|
"description": "A consent-first bridge for reviewed browser-agent tasks.",
|
|
7
7
|
"permissions": [
|
|
8
8
|
"activeTab",
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
(() => {
|
|
3
3
|
// policy.ts
|
|
4
|
-
var sensitiveactions = /* @__PURE__ */ new Set(["click", "type", "navigate", "select", "presskey", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "reload", "back", "forward", "writestorage", "setattribute", "removeattribute", "evaluate", "tabcreate", "tabactivate", "tabclose", "tabreload", "windowcreate", "windowclose", "windowresize", "downloadfile", "clickpoint", "shiftclick", "dismissdialog", "enterframe", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "openlink", "openprivate", "reloadcache", "stopnav", "followlink", "spanav", "rewritequery", "setfragment", "navlist", "navprofile", "handleauth", "printpdf", "prefetch", "preconnect", "deeplink", "reopentab", "pausenav", "navrate", "openclipboard", "batchopen", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "restorelayout", "reopenrun", "badgetab", "fillform", "filllabel", "fillplaceholder", "submitform", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcard", "fillcode", "consentpassword", "exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk", "paginateextract", "resumeextract", "batchdownload", "pausedownload", "resumedownload", "interceptmime", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "cleanupartifacts"]);
|
|
4
|
+
var sensitiveactions = /* @__PURE__ */ new Set(["click", "type", "navigate", "select", "presskey", "drag", "drop", "upload", "clear", "check", "uncheck", "toggle", "submit", "reload", "back", "forward", "writestorage", "setattribute", "removeattribute", "evaluate", "tabcreate", "tabactivate", "tabclose", "tabreload", "windowcreate", "windowclose", "windowresize", "downloadfile", "clickpoint", "shiftclick", "dismissdialog", "enterframe", "typetime", "appendtext", "setvalue", "typeedit", "keyhold", "keyrelease", "submitsearch", "selectmulti", "chooseradio", "setslider", "setdate", "setcolor", "openlink", "openprivate", "reloadcache", "stopnav", "followlink", "spanav", "rewritequery", "setfragment", "navlist", "navprofile", "handleauth", "printpdf", "prefetch", "preconnect", "deeplink", "reopentab", "pausenav", "navrate", "openclipboard", "batchopen", "duplicatetab", "closepattern", "pintab", "mutetab", "movetab", "movetabwindow", "grouptabs", "colorgroup", "collapsegroup", "discardtab", "reloadtabs", "zoomin", "zoomout", "switchtab", "maximizewindow", "minimizewindow", "restorewindow", "focuswindow", "scratchwindow", "incognitowindow", "restoretab", "restorelayout", "reopenrun", "badgetab", "fillform", "filllabel", "fillplaceholder", "submitform", "retryform", "runwizard", "selectchain", "picktypeahead", "pickdate", "attachfile", "fillcard", "fillcode", "consentpassword", "exportcsv", "exportjson", "exportexcel", "copytable", "pushsheets", "streamdisk", "paginateextract", "resumeextract", "batchdownload", "pausedownload", "resumedownload", "interceptmime", "readclipboard", "writeclipboard", "copyscreen", "quarantinedownload", "scanvirus", "cleanupartifacts", "recordscreen", "captureaudio", "downloadimages"]);
|
|
5
5
|
var interactionactions = /* @__PURE__ */ new Set(["focus", "scroll", "hover", "clickdeep", "rightclick", "doubleclick", "scrollpage", "scrollby", "scrollend", "scrolltop", "fullscreen", "zoomset", "movepointer", "clicktext", "clickaria", "clickname", "expanddetails", "pierceshadow", "retryaction"]);
|
|
6
|
-
var readactions = /* @__PURE__ */ new Set(["observe", "inspect", "extract", "wait", "waitfor", "waittext", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "readlinks", "readimages", "readmeta", "readforms", "readstorage", "highlight", "tablist", "windowlist", "tabsnapshot", "mapclicks", "verifyvisible", "verifyenabled", "resolvexpath", "a11ytree", "readvisible", "readertree", "detectlists", "detecttables", "readjson", "watchmutate", "waitquiet", "watchbanner", "detectinfinitescroll", "detectvirtual", "detectlazy", "readscrollpos", "readlang", "readoutline", "countpages", "listshadow", "listframes", "classifypage", "fingerprintsection", "diffsnapshots", "readselection", "watchfocus", "detectsticky", "detectscrolllock", "readopengraph", "detectlanguage", "deriveselector", "waitload", "waiturl", "spawait", "detecthttp", "readredirects", "readfinalurl", "trailaudit", "navintent", "checksafe", "querytabs", "watchtab", "findclones", "searchtabs", "listaudio", "snapshotsession", "savelayout", "attachmeta", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "readerrors", "skiphoneypot", "detectlogin", "detecttemplate", "handoffcaptcha", "scrapetable", "importcsv", "looprows", "transformvalues", "deduperows", "mergepages", "stamplerows", "previewgrid", "logprovenance", "verifydownload", "exportnetlog", "namecaptures"]);
|
|
6
|
+
var readactions = /* @__PURE__ */ new Set(["observe", "inspect", "extract", "wait", "waitfor", "waittext", "readattribute", "readstyle", "readgeometry", "readvalue", "readtext", "readhtml", "countelements", "readtable", "readlinks", "readimages", "readmeta", "readforms", "readstorage", "highlight", "tablist", "windowlist", "tabsnapshot", "mapclicks", "verifyvisible", "verifyenabled", "resolvexpath", "a11ytree", "readvisible", "readertree", "detectlists", "detecttables", "readjson", "watchmutate", "waitquiet", "watchbanner", "detectinfinitescroll", "detectvirtual", "detectlazy", "readscrollpos", "readlang", "readoutline", "countpages", "listshadow", "listframes", "classifypage", "fingerprintsection", "diffsnapshots", "readselection", "watchfocus", "detectsticky", "detectscrolllock", "readopengraph", "detectlanguage", "deriveselector", "waitload", "waiturl", "spawait", "detecthttp", "readredirects", "readfinalurl", "trailaudit", "navintent", "checksafe", "querytabs", "watchtab", "findclones", "searchtabs", "listaudio", "snapshotsession", "savelayout", "attachmeta", "detectfields", "generatevalues", "saveprofiles", "asksubmit", "readerrors", "skiphoneypot", "detectlogin", "detecttemplate", "handoffcaptcha", "scrapetable", "importcsv", "looprows", "transformvalues", "deduperows", "mergepages", "stamplerows", "previewgrid", "logprovenance", "verifydownload", "exportnetlog", "namecaptures", "shotview", "shotfullpage", "shotelement", "shotregion", "contactsheet", "capturepdf", "captureframe", "readmedia", "readassets", "probestream", "timelapse", "shotcanvas", "convertimage", "makethumbs"]);
|
|
7
7
|
var allowedactions = /* @__PURE__ */ new Set([...sensitiveactions, ...interactionactions, ...readactions]);
|
|
8
8
|
function parseoptions(step) {
|
|
9
9
|
if (step.options === void 0) return {};
|
|
@@ -3328,6 +3328,248 @@
|
|
|
3328
3328
|
}
|
|
3329
3329
|
return output;
|
|
3330
3330
|
}
|
|
3331
|
-
|
|
3331
|
+
function measurepage() {
|
|
3332
|
+
const root = document.documentElement;
|
|
3333
|
+
return {
|
|
3334
|
+
scrollwidth: Math.max(root.scrollWidth, document.body?.scrollWidth ?? 0),
|
|
3335
|
+
scrollheight: Math.max(root.scrollHeight, document.body?.scrollHeight ?? 0),
|
|
3336
|
+
viewportwidth: window.innerWidth,
|
|
3337
|
+
viewportheight: window.innerHeight,
|
|
3338
|
+
pixelratio: window.devicePixelRatio || 1,
|
|
3339
|
+
scrollx: window.scrollX,
|
|
3340
|
+
scrolly: window.scrollY
|
|
3341
|
+
};
|
|
3342
|
+
}
|
|
3343
|
+
function elementrect(selector) {
|
|
3344
|
+
const target = document.querySelector(selector);
|
|
3345
|
+
if (!target) return { ok: false, summary: "The reviewed capture element is no longer available." };
|
|
3346
|
+
const bounds = target.getBoundingClientRect();
|
|
3347
|
+
if (bounds.width <= 0 || bounds.height <= 0) return { ok: false, summary: "The reviewed capture element is not currently visible." };
|
|
3348
|
+
const viewport = { width: window.innerWidth, height: window.innerHeight };
|
|
3349
|
+
const rect = { x: Math.round(bounds.left + window.scrollX), y: Math.round(bounds.top + window.scrollY), width: Math.round(bounds.width), height: Math.round(bounds.height) };
|
|
3350
|
+
const viewrect = { x: bounds.left, y: bounds.top, width: bounds.width, height: bounds.height };
|
|
3351
|
+
return { ok: true, rect, pixelratio: window.devicePixelRatio || 1, crossesviewport: viewrect.x < 0 || viewrect.y < 0 || viewrect.x + viewrect.width > viewport.width || viewrect.y + viewrect.height > viewport.height, summary: `Measured the capture element at ${rect.width} by ${rect.height} css pixels.` };
|
|
3352
|
+
}
|
|
3353
|
+
var scrollbarstyleid = "devthinkcapturehider";
|
|
3354
|
+
function preparecapture() {
|
|
3355
|
+
if (!document.getElementById(scrollbarstyleid)) {
|
|
3356
|
+
const style = document.createElement("style");
|
|
3357
|
+
style.id = scrollbarstyleid;
|
|
3358
|
+
style.setAttribute("aria-hidden", "true");
|
|
3359
|
+
style.textContent = "html::-webkit-scrollbar,body::-webkit-scrollbar{display:none!important}html{scrollbar-width:none!important}";
|
|
3360
|
+
document.documentElement.append(style);
|
|
3361
|
+
}
|
|
3362
|
+
return { scrollx: window.scrollX, scrolly: window.scrollY };
|
|
3363
|
+
}
|
|
3364
|
+
function scrollcapture(x, y) {
|
|
3365
|
+
window.scrollTo(x, y);
|
|
3366
|
+
return { x: window.scrollX, y: window.scrollY };
|
|
3367
|
+
}
|
|
3368
|
+
function restorecapture(state) {
|
|
3369
|
+
document.getElementById(scrollbarstyleid)?.remove();
|
|
3370
|
+
window.scrollTo(state.scrollx, state.scrolly);
|
|
3371
|
+
}
|
|
3372
|
+
function scrollcontainercapture(selector, top) {
|
|
3373
|
+
const container = document.querySelector(selector);
|
|
3374
|
+
if (!container) return { ok: false, summary: "The reviewed scrollable container is no longer available." };
|
|
3375
|
+
if (!(container instanceof HTMLElement)) return { ok: false, summary: "The reviewed scrollable container cannot scroll." };
|
|
3376
|
+
container.scrollTo({ top, behavior: "auto" });
|
|
3377
|
+
return { ok: true, top: container.scrollTop, height: container.scrollHeight, viewportheight: container.clientHeight, summary: `Scrolled the container to ${container.scrollTop} of ${container.scrollHeight} pixels.` };
|
|
3378
|
+
}
|
|
3379
|
+
function waitsettle(milliseconds) {
|
|
3380
|
+
return new Promise((resolve) => window.setTimeout(resolve, Math.max(0, milliseconds)));
|
|
3381
|
+
}
|
|
3382
|
+
function pdfsegment(top, height) {
|
|
3383
|
+
const blocks = [...document.querySelectorAll("h1,h2,h3,h4,h5,h6,p,li,td,th,blockquote,pre,figcaption,section,article > div")];
|
|
3384
|
+
const lines = [];
|
|
3385
|
+
for (const block of blocks) {
|
|
3386
|
+
const bounds = block.getBoundingClientRect();
|
|
3387
|
+
const blocktop = bounds.top + window.scrollY;
|
|
3388
|
+
const blockbottom = blocktop + bounds.height;
|
|
3389
|
+
if (blockbottom <= top || blocktop >= top + height) continue;
|
|
3390
|
+
const text2 = clean(block.textContent ?? "");
|
|
3391
|
+
if (text2) lines.push(text2);
|
|
3392
|
+
}
|
|
3393
|
+
const text = lines.join("\n");
|
|
3394
|
+
return { ok: true, text, summary: `Collected ${text.length} characters of the report segment at ${Math.round(top)} to ${Math.round(top + height)} pixels.` };
|
|
3395
|
+
}
|
|
3396
|
+
function pdfbreaks(selectors) {
|
|
3397
|
+
const resolved = [];
|
|
3398
|
+
for (const selector of selectors) {
|
|
3399
|
+
const target = document.querySelector(selector);
|
|
3400
|
+
if (!target) continue;
|
|
3401
|
+
resolved.push({ selector, top: Math.round(target.getBoundingClientRect().top + window.scrollY) });
|
|
3402
|
+
}
|
|
3403
|
+
return resolved;
|
|
3404
|
+
}
|
|
3405
|
+
async function videoframe(selector, timestamp, poster) {
|
|
3406
|
+
const target = document.querySelector(selector);
|
|
3407
|
+
if (!(target instanceof HTMLVideoElement)) return { ok: false, summary: "The reviewed frame source is not a video element." };
|
|
3408
|
+
target.pause();
|
|
3409
|
+
if (typeof timestamp === "number" && Number.isFinite(timestamp) && timestamp >= 0 && timestamp <= (target.duration || 0)) {
|
|
3410
|
+
await new Promise((resolve) => {
|
|
3411
|
+
const done = () => resolve();
|
|
3412
|
+
target.addEventListener("seeked", done, { once: true });
|
|
3413
|
+
target.currentTime = timestamp;
|
|
3414
|
+
window.setTimeout(done, 1500);
|
|
3415
|
+
});
|
|
3416
|
+
}
|
|
3417
|
+
const width = target.videoWidth || target.clientWidth || 1;
|
|
3418
|
+
const height = target.videoHeight || target.clientHeight || 1;
|
|
3419
|
+
try {
|
|
3420
|
+
const canvas = document.createElement("canvas");
|
|
3421
|
+
canvas.width = width;
|
|
3422
|
+
canvas.height = height;
|
|
3423
|
+
const context = canvas.getContext("2d");
|
|
3424
|
+
if (!context) return { ok: false, summary: "The frame grab could not create a canvas context." };
|
|
3425
|
+
context.drawImage(target, 0, 0, width, height);
|
|
3426
|
+
const dataurl = canvas.toDataURL("image/png");
|
|
3427
|
+
return { ok: dataurl.length > 100, dataurl, width, height, summary: `Grabbed the video frame at ${target.currentTime.toFixed(2)} seconds of ${width} by ${height} pixels${poster ? " as the poster frame" : ""}.` };
|
|
3428
|
+
} catch {
|
|
3429
|
+
return { ok: false, summary: "The video frame draw was refused; cross origin videos need cors headers before frames can be read." };
|
|
3430
|
+
}
|
|
3431
|
+
}
|
|
3432
|
+
function canvasdata(selector) {
|
|
3433
|
+
const target = document.querySelector(selector);
|
|
3434
|
+
if (!(target instanceof HTMLCanvasElement)) return { ok: false, context: "2d", summary: "The reviewed canvas element is no longer available." };
|
|
3435
|
+
const width = target.width || 1;
|
|
3436
|
+
const height = target.height || 1;
|
|
3437
|
+
const kind = target.getContext("2d") ? "2d" : "webgl";
|
|
3438
|
+
try {
|
|
3439
|
+
let dataurl = "";
|
|
3440
|
+
let preserved = false;
|
|
3441
|
+
if (kind === "2d") {
|
|
3442
|
+
dataurl = target.toDataURL("image/png");
|
|
3443
|
+
} else {
|
|
3444
|
+
dataurl = target.toDataURL("image/png");
|
|
3445
|
+
if (dataurl.length <= 100) {
|
|
3446
|
+
const gl = target.getContext("webgl") ?? target.getContext("experimental-webgl");
|
|
3447
|
+
if (gl) {
|
|
3448
|
+
const pixels = new Uint8Array(width * height * 4);
|
|
3449
|
+
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
|
|
3450
|
+
const canvas = document.createElement("canvas");
|
|
3451
|
+
canvas.width = width;
|
|
3452
|
+
canvas.height = height;
|
|
3453
|
+
const context = canvas.getContext("2d");
|
|
3454
|
+
if (context) {
|
|
3455
|
+
const image = context.createImageData(width, height);
|
|
3456
|
+
for (let row = 0; row < height; row += 1) {
|
|
3457
|
+
const source = (height - 1 - row) * width * 4;
|
|
3458
|
+
const destination = row * width * 4;
|
|
3459
|
+
image.data.set(pixels.subarray(source, source + width * 4), destination);
|
|
3460
|
+
}
|
|
3461
|
+
context.putImageData(image, 0, 0);
|
|
3462
|
+
dataurl = canvas.toDataURL("image/png");
|
|
3463
|
+
preserved = true;
|
|
3464
|
+
}
|
|
3465
|
+
}
|
|
3466
|
+
}
|
|
3467
|
+
}
|
|
3468
|
+
return { ok: dataurl.length > 100, context: kind, dataurl, width, height, preserved, summary: `Read the ${kind} canvas buffer of ${width} by ${height} pixels${kind === "webgl" ? preserved ? " through a preserved readPixels pass" : " through the preserved drawing buffer" : ""}.` };
|
|
3469
|
+
} catch {
|
|
3470
|
+
return { ok: false, context: kind, summary: "The canvas read was refused; tainted canvas content needs cross origin resources with cors headers." };
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3473
|
+
function streamelements(selector) {
|
|
3474
|
+
const root = selector ? document.querySelector(selector) : document;
|
|
3475
|
+
if (!root) return [];
|
|
3476
|
+
const entries = [];
|
|
3477
|
+
for (const element of [...root.querySelectorAll("video, audio")]) {
|
|
3478
|
+
const media = element instanceof HTMLMediaElement ? element : null;
|
|
3479
|
+
if (!media) continue;
|
|
3480
|
+
const stream = media.srcObject;
|
|
3481
|
+
if (!(stream instanceof MediaStream)) continue;
|
|
3482
|
+
entries.push({
|
|
3483
|
+
kind: "webrtc",
|
|
3484
|
+
label: stream.id,
|
|
3485
|
+
live: stream.active,
|
|
3486
|
+
tracks: stream.getTracks().map((track) => ({
|
|
3487
|
+
kind: track.kind,
|
|
3488
|
+
label: track.label,
|
|
3489
|
+
state: track.readyState,
|
|
3490
|
+
...track.kind === "video" ? { width: track.getSettings().width, height: track.getSettings().height, framerate: track.getSettings().frameRate } : {}
|
|
3491
|
+
}))
|
|
3492
|
+
});
|
|
3493
|
+
}
|
|
3494
|
+
return entries;
|
|
3495
|
+
}
|
|
3496
|
+
function mediaelements() {
|
|
3497
|
+
const entries = [];
|
|
3498
|
+
for (const element of [...document.querySelectorAll("video, audio")]) {
|
|
3499
|
+
if (!(element instanceof HTMLMediaElement)) continue;
|
|
3500
|
+
const source = element.querySelector("source");
|
|
3501
|
+
const url = element.currentSrc || element.src || (source instanceof HTMLSourceElement ? source.src : "") || "";
|
|
3502
|
+
if (!url) continue;
|
|
3503
|
+
const type = (source instanceof HTMLSourceElement ? source.type : "") || "";
|
|
3504
|
+
const codecs = type.includes("codecs=") ? type.slice(type.indexOf("codecs=") + "codecs=".length).replace(/["']/g, "") : "";
|
|
3505
|
+
entries.push({
|
|
3506
|
+
url,
|
|
3507
|
+
mime: type.split(";")[0] || "",
|
|
3508
|
+
duration: Number.isFinite(element.duration) ? element.duration : 0,
|
|
3509
|
+
width: element instanceof HTMLVideoElement ? element.videoWidth : 0,
|
|
3510
|
+
height: element instanceof HTMLVideoElement ? element.videoHeight : 0,
|
|
3511
|
+
codecs,
|
|
3512
|
+
tracks: [...element.textTracks].map((track) => track.label || track.kind).filter(Boolean)
|
|
3513
|
+
});
|
|
3514
|
+
}
|
|
3515
|
+
return entries;
|
|
3516
|
+
}
|
|
3517
|
+
async function pageassets() {
|
|
3518
|
+
const entries = [];
|
|
3519
|
+
for (const link of [...document.querySelectorAll("link[rel]")]) {
|
|
3520
|
+
const rel = (link.getAttribute("rel") ?? "").toLowerCase();
|
|
3521
|
+
const href = link.getAttribute("href");
|
|
3522
|
+
if (!href || !(rel.includes("icon") || rel.includes("apple-touch"))) continue;
|
|
3523
|
+
const resolved = new URL(href, location.href).toString();
|
|
3524
|
+
entries.push({ kind: "favicon", url: resolved, bytes: 0, sizes: link.getAttribute("sizes") ?? "any" });
|
|
3525
|
+
}
|
|
3526
|
+
const og = document.querySelector('meta[property="og:image"]');
|
|
3527
|
+
if (og instanceof HTMLMetaElement && og.content) entries.push({ kind: "logo", url: new URL(og.content, location.href).toString(), bytes: 0, sizes: "og" });
|
|
3528
|
+
for (const image of [...document.querySelectorAll("header img, nav img, img[alt*=logo i], img[src*=logo i]")]) {
|
|
3529
|
+
const url = image instanceof HTMLImageElement ? image.currentSrc || image.src : "";
|
|
3530
|
+
if (!url) continue;
|
|
3531
|
+
entries.push({ kind: "logo", url: new URL(url, location.href).toString(), bytes: 0, sizes: image instanceof HTMLImageElement ? `${image.naturalWidth}x${image.naturalHeight}` : "" });
|
|
3532
|
+
}
|
|
3533
|
+
const manifestlink = document.querySelector('link[rel="manifest"]');
|
|
3534
|
+
if (manifestlink instanceof HTMLLinkElement && manifestlink.href) {
|
|
3535
|
+
try {
|
|
3536
|
+
const response = await fetch(manifestlink.href);
|
|
3537
|
+
const manifest = await response.json();
|
|
3538
|
+
for (const icon of manifest.icons ?? []) {
|
|
3539
|
+
if (!icon.src) continue;
|
|
3540
|
+
entries.push({ kind: "favicon", url: new URL(icon.src, location.href).toString(), bytes: 0, sizes: icon.sizes ?? "any" });
|
|
3541
|
+
}
|
|
3542
|
+
} catch {
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
return entries;
|
|
3546
|
+
}
|
|
3547
|
+
function pageimages(selector) {
|
|
3548
|
+
const root = selector ? document.querySelector(selector) : document;
|
|
3549
|
+
if (!root) return [];
|
|
3550
|
+
const transfers = /* @__PURE__ */ new Map();
|
|
3551
|
+
for (const entry of performance.getEntriesByType("resource")) {
|
|
3552
|
+
const resource = entry;
|
|
3553
|
+
if (resource.transferSize > 0) transfers.set(resource.name, resource.transferSize);
|
|
3554
|
+
}
|
|
3555
|
+
const images = [];
|
|
3556
|
+
for (const element of [...root.querySelectorAll("img")]) {
|
|
3557
|
+
if (!(element instanceof HTMLImageElement)) continue;
|
|
3558
|
+
const url = element.currentSrc || element.src;
|
|
3559
|
+
if (!url) continue;
|
|
3560
|
+
const resolved = new URL(url, location.href).toString();
|
|
3561
|
+
const type = element.getAttribute("type") ?? "";
|
|
3562
|
+
images.push({
|
|
3563
|
+
url: resolved,
|
|
3564
|
+
alt: element.alt ?? "",
|
|
3565
|
+
width: element.naturalWidth || element.width,
|
|
3566
|
+
height: element.naturalHeight || element.height,
|
|
3567
|
+
bytes: transfers.get(resolved) ?? 0,
|
|
3568
|
+
mime: type || (element.src.startsWith("data:") ? element.src.slice(5, element.src.indexOf(";")) : "image/*")
|
|
3569
|
+
});
|
|
3570
|
+
}
|
|
3571
|
+
return images;
|
|
3572
|
+
}
|
|
3573
|
+
Object.assign(globalThis, { devthinkbridge: { capturesnapshot, previewtarget, performstep, readdialogs, measurepage, elementrect, preparecapture, scrollcapture, restorecapture, scrollcontainercapture, waitsettle, pdfsegment, pdfbreaks, videoframe, canvasdata, streamelements, mediaelements, pageassets, pageimages } });
|
|
3332
3574
|
})();
|
|
3333
3575
|
//# sourceMappingURL=pagebridge.js.map
|