image-exporter 1.2.2 → 1.3.0
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 +32 -3
- package/dist/capture/capture-element.d.ts +2 -1
- package/dist/capture/capture-element.d.ts.map +1 -1
- package/dist/capture/capture.dom.test.d.ts +2 -0
- package/dist/capture/capture.dom.test.d.ts.map +1 -0
- package/dist/capture/copy-to-clipboard.d.ts +13 -0
- package/dist/capture/copy-to-clipboard.d.ts.map +1 -0
- package/dist/capture/copy-to-clipboard.dom.test.d.ts +2 -0
- package/dist/capture/copy-to-clipboard.dom.test.d.ts.map +1 -0
- package/dist/capture/cors-cleanup.dom.test.d.ts +2 -0
- package/dist/capture/cors-cleanup.dom.test.d.ts.map +1 -0
- package/dist/capture/data-url-to-blob.d.ts +9 -0
- package/dist/capture/data-url-to-blob.d.ts.map +1 -0
- package/dist/capture/data-url-to-blob.node.test.d.ts +2 -0
- package/dist/capture/data-url-to-blob.node.test.d.ts.map +1 -0
- package/dist/capture/dedup-consistency.node.test.d.ts +2 -0
- package/dist/capture/dedup-consistency.node.test.d.ts.map +1 -0
- package/dist/capture/determine-total-elements.d.ts +7 -3
- package/dist/capture/determine-total-elements.d.ts.map +1 -1
- package/dist/capture/determine-total-elements.dom.test.d.ts +2 -0
- package/dist/capture/determine-total-elements.dom.test.d.ts.map +1 -0
- package/dist/capture/download-images.d.ts +8 -0
- package/dist/capture/download-images.d.ts.map +1 -1
- package/dist/capture/get-image-options.dom.test.d.ts +2 -0
- package/dist/capture/get-image-options.dom.test.d.ts.map +1 -0
- package/dist/capture/handle-filenames.d.ts +5 -6
- package/dist/capture/handle-filenames.d.ts.map +1 -1
- package/dist/capture/index.d.ts.map +1 -1
- package/dist/capture/make-unique.d.ts +14 -0
- package/dist/capture/make-unique.d.ts.map +1 -0
- package/dist/capture/make-unique.node.test.d.ts +2 -0
- package/dist/capture/make-unique.node.test.d.ts.map +1 -0
- package/dist/index.browser.js +16 -16
- package/dist/index.browser.js.map +20 -17
- package/dist/index.cjs +198 -125
- package/dist/index.cjs.map +20 -17
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +198 -125
- package/dist/index.js.map +20 -17
- package/dist/logger.d.ts +5 -5
- package/dist/logger.d.ts.map +1 -1
- package/dist/types.d.ts +81 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +27 -3
package/dist/index.cjs
CHANGED
|
@@ -4,39 +4,60 @@ var __defProp = Object.defineProperty;
|
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
7
12
|
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
8
20
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
21
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
22
|
for (let key of __getOwnPropNames(mod))
|
|
11
23
|
if (!__hasOwnProp.call(to, key))
|
|
12
24
|
__defProp(to, key, {
|
|
13
|
-
get: (
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
14
26
|
enumerable: true
|
|
15
27
|
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
16
30
|
return to;
|
|
17
31
|
};
|
|
18
|
-
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
19
32
|
var __toCommonJS = (from) => {
|
|
20
|
-
var entry = __moduleCache.get(from), desc;
|
|
33
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
21
34
|
if (entry)
|
|
22
35
|
return entry;
|
|
23
36
|
entry = __defProp({}, "__esModule", { value: true });
|
|
24
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
37
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
38
|
+
for (var key of __getOwnPropNames(from))
|
|
39
|
+
if (!__hasOwnProp.call(entry, key))
|
|
40
|
+
__defProp(entry, key, {
|
|
41
|
+
get: __accessProp.bind(from, key),
|
|
42
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
43
|
+
});
|
|
44
|
+
}
|
|
29
45
|
__moduleCache.set(from, entry);
|
|
30
46
|
return entry;
|
|
31
47
|
};
|
|
48
|
+
var __moduleCache;
|
|
32
49
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
50
|
+
var __returnValue = (v) => v;
|
|
51
|
+
function __exportSetter(name, newValue) {
|
|
52
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
53
|
+
}
|
|
33
54
|
var __export = (target, all) => {
|
|
34
55
|
for (var name in all)
|
|
35
56
|
__defProp(target, name, {
|
|
36
57
|
get: all[name],
|
|
37
58
|
enumerable: true,
|
|
38
59
|
configurable: true,
|
|
39
|
-
set: (
|
|
60
|
+
set: __exportSetter.bind(all, name)
|
|
40
61
|
});
|
|
41
62
|
};
|
|
42
63
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -53,7 +74,7 @@ __export(exports_buffer, {
|
|
|
53
74
|
default: () => buffer_default,
|
|
54
75
|
constants: () => constants,
|
|
55
76
|
btoa: () => btoa,
|
|
56
|
-
atob: () =>
|
|
77
|
+
atob: () => atob2,
|
|
57
78
|
INSPECT_MAX_BYTES: () => INSPECT_MAX_BYTES,
|
|
58
79
|
File: () => File,
|
|
59
80
|
Buffer: () => Buffer2,
|
|
@@ -726,7 +747,7 @@ function notimpl(name) {
|
|
|
726
747
|
throw Error(name + " is not implemented for node:buffer browser polyfill");
|
|
727
748
|
};
|
|
728
749
|
}
|
|
729
|
-
var lookup, revLookup, code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", i, len, customInspectSymbol, INSPECT_MAX_BYTES = 50, kMaxLength = 2147483647, kStringMaxLength = 536870888, btoa,
|
|
750
|
+
var lookup, revLookup, code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", i, len, customInspectSymbol, INSPECT_MAX_BYTES = 50, kMaxLength = 2147483647, kStringMaxLength = 536870888, btoa, atob2, File, Blob2, constants, ERR_BUFFER_OUT_OF_BOUNDS, ERR_INVALID_ARG_TYPE, ERR_OUT_OF_RANGE, MAX_ARGUMENTS_LENGTH = 4096, INVALID_BASE64_RE, hexSliceLookupTable, resolveObjectURL, isUtf8, isAscii = (str) => {
|
|
730
751
|
for (let char of str)
|
|
731
752
|
if (char.charCodeAt(0) > 127)
|
|
732
753
|
return false;
|
|
@@ -741,7 +762,7 @@ var init_buffer = __esm(() => {
|
|
|
741
762
|
revLookup[95] = 63;
|
|
742
763
|
customInspectSymbol = typeof Symbol === "function" && typeof Symbol.for === "function" ? Symbol.for("nodejs.util.inspect.custom") : null;
|
|
743
764
|
btoa = globalThis.btoa;
|
|
744
|
-
|
|
765
|
+
atob2 = globalThis.atob;
|
|
745
766
|
File = globalThis.File;
|
|
746
767
|
Blob2 = globalThis.Blob;
|
|
747
768
|
constants = { MAX_LENGTH: kMaxLength, MAX_STRING_LENGTH: kStringMaxLength };
|
|
@@ -12537,7 +12558,7 @@ var require_zipEntries = __commonJS((exports2, module2) => {
|
|
|
12537
12558
|
if (this.centralDirRecords !== this.files.length) {
|
|
12538
12559
|
if (this.centralDirRecords !== 0 && this.files.length === 0) {
|
|
12539
12560
|
throw new Error("Corrupted zip or bug: expected " + this.centralDirRecords + " records in central dir, got " + this.files.length);
|
|
12540
|
-
}
|
|
12561
|
+
}
|
|
12541
12562
|
}
|
|
12542
12563
|
},
|
|
12543
12564
|
readEndOfCentral: function() {
|
|
@@ -12714,42 +12735,43 @@ var require_lib = __commonJS((exports2, module2) => {
|
|
|
12714
12735
|
var exports_src = {};
|
|
12715
12736
|
__export(exports_src, {
|
|
12716
12737
|
downloadImages: () => downloadImages,
|
|
12738
|
+
copyImageToClipboard: () => copyImageToClipboard,
|
|
12717
12739
|
capture: () => capture
|
|
12718
12740
|
});
|
|
12719
12741
|
module.exports = __toCommonJS(exports_src);
|
|
12720
12742
|
|
|
12743
|
+
// src/capture/make-unique.ts
|
|
12744
|
+
function makeUnique(fileName, seen) {
|
|
12745
|
+
if (!seen.has(fileName)) {
|
|
12746
|
+
seen.add(fileName);
|
|
12747
|
+
return fileName;
|
|
12748
|
+
}
|
|
12749
|
+
const lastDot = fileName.lastIndexOf(".");
|
|
12750
|
+
const base = lastDot !== -1 ? fileName.slice(0, lastDot) : fileName;
|
|
12751
|
+
const extension = lastDot !== -1 ? fileName.slice(lastDot) : "";
|
|
12752
|
+
const match = base.match(/-(\d+)$/);
|
|
12753
|
+
let stem = base;
|
|
12754
|
+
let counter = 2;
|
|
12755
|
+
if (match) {
|
|
12756
|
+
stem = base.slice(0, -match[0].length);
|
|
12757
|
+
counter = parseInt(match[1], 10) + 1;
|
|
12758
|
+
}
|
|
12759
|
+
let candidate = `${stem}-${counter}${extension}`;
|
|
12760
|
+
while (seen.has(candidate)) {
|
|
12761
|
+
counter++;
|
|
12762
|
+
candidate = `${stem}-${counter}${extension}`;
|
|
12763
|
+
}
|
|
12764
|
+
seen.add(candidate);
|
|
12765
|
+
return candidate;
|
|
12766
|
+
}
|
|
12767
|
+
|
|
12721
12768
|
// src/capture/handle-filenames.ts
|
|
12722
|
-
function handleFileNames(imageOptions,
|
|
12769
|
+
function handleFileNames(imageOptions, seen) {
|
|
12723
12770
|
let proposedFilename = imageOptions.label;
|
|
12724
12771
|
if (imageOptions.includeScaleInLabel)
|
|
12725
12772
|
proposedFilename += `_@${imageOptions.scale}x`;
|
|
12726
|
-
|
|
12727
|
-
proposedFilename
|
|
12728
|
-
if (!filenames.includes(proposedFilename)) {
|
|
12729
|
-
filenames.push(proposedFilename);
|
|
12730
|
-
return proposedFilename;
|
|
12731
|
-
}
|
|
12732
|
-
const numberPattern = /-(\d+)$/;
|
|
12733
|
-
const match = proposedFilename.match(numberPattern);
|
|
12734
|
-
if (match) {
|
|
12735
|
-
const baseFilename = proposedFilename.replace(numberPattern, "");
|
|
12736
|
-
let counter = parseInt(match[1], 10);
|
|
12737
|
-
while (filenames.includes(`${baseFilename}-${counter}${extension}`)) {
|
|
12738
|
-
counter++;
|
|
12739
|
-
}
|
|
12740
|
-
const newFilename = `${baseFilename}-${counter}${extension}`;
|
|
12741
|
-
filenames.push(newFilename);
|
|
12742
|
-
return newFilename;
|
|
12743
|
-
} else {
|
|
12744
|
-
const baseFilename = proposedFilename.replace(extension, "");
|
|
12745
|
-
let counter = 2;
|
|
12746
|
-
while (filenames.includes(`${baseFilename}-${counter}${extension}`)) {
|
|
12747
|
-
counter++;
|
|
12748
|
-
}
|
|
12749
|
-
const newFilename = `${baseFilename}-${counter}${extension}`;
|
|
12750
|
-
filenames.push(newFilename);
|
|
12751
|
-
return newFilename;
|
|
12752
|
-
}
|
|
12773
|
+
proposedFilename += `.${imageOptions.format}`;
|
|
12774
|
+
return makeUnique(proposedFilename, seen);
|
|
12753
12775
|
}
|
|
12754
12776
|
|
|
12755
12777
|
// node_modules/modern-screenshot/dist/index.mjs
|
|
@@ -14251,18 +14273,20 @@ async function domToWebp(node, options) {
|
|
|
14251
14273
|
}
|
|
14252
14274
|
|
|
14253
14275
|
// src/capture/capture-element.ts
|
|
14254
|
-
async function captureElement(element, imageOptions,
|
|
14276
|
+
async function captureElement(element, imageOptions, seen, screenshotOptions) {
|
|
14277
|
+
let cleanUpBackground = false;
|
|
14255
14278
|
try {
|
|
14256
14279
|
let dataURL = "";
|
|
14257
|
-
|
|
14280
|
+
const userFilter = screenshotOptions?.filter;
|
|
14281
|
+
const htmlToImageOptions = {
|
|
14282
|
+
...screenshotOptions,
|
|
14258
14283
|
quality: imageOptions.quality,
|
|
14259
14284
|
scale: imageOptions.scale,
|
|
14260
|
-
filter
|
|
14285
|
+
filter: (node) => filter(node) && (userFilter ? userFilter(node) : true)
|
|
14261
14286
|
};
|
|
14262
14287
|
const styles = getComputedStyle(element);
|
|
14263
14288
|
const backgroundColor = styles.backgroundColor;
|
|
14264
14289
|
const backgroundImage = styles.backgroundImage;
|
|
14265
|
-
let cleanUpBackground = false;
|
|
14266
14290
|
if (backgroundColor === "rgba(0, 0, 0, 0)" && backgroundImage === "none" && imageOptions.format === "jpg") {
|
|
14267
14291
|
element.style.backgroundColor = "#FFFFFF";
|
|
14268
14292
|
cleanUpBackground = true;
|
|
@@ -14281,17 +14305,17 @@ async function captureElement(element, imageOptions, filenames) {
|
|
|
14281
14305
|
dataURL = await domToWebp(element, htmlToImageOptions);
|
|
14282
14306
|
break;
|
|
14283
14307
|
}
|
|
14284
|
-
if (cleanUpBackground) {
|
|
14285
|
-
element.style.backgroundColor = "";
|
|
14286
|
-
element.style.backgroundImage = "";
|
|
14287
|
-
}
|
|
14288
14308
|
return {
|
|
14289
14309
|
dataURL,
|
|
14290
|
-
fileName: handleFileNames(imageOptions,
|
|
14310
|
+
fileName: handleFileNames(imageOptions, seen)
|
|
14291
14311
|
};
|
|
14292
14312
|
} catch (error) {
|
|
14293
|
-
|
|
14294
|
-
|
|
14313
|
+
throw new Error(`ImageExporter: failed to capture element as ${imageOptions.format}`, { cause: error });
|
|
14314
|
+
} finally {
|
|
14315
|
+
if (cleanUpBackground) {
|
|
14316
|
+
element.style.backgroundColor = "";
|
|
14317
|
+
element.style.backgroundImage = "";
|
|
14318
|
+
}
|
|
14295
14319
|
}
|
|
14296
14320
|
}
|
|
14297
14321
|
var filter = (node) => {
|
|
@@ -14328,7 +14352,7 @@ async function downloadImages(images, userConfig = defaultConfig) {
|
|
|
14328
14352
|
const uniqueImages = ensureUniqueFileNames(images);
|
|
14329
14353
|
if (uniqueImages.length === 1) {
|
|
14330
14354
|
const image = uniqueImages[0];
|
|
14331
|
-
triggerDownload(image.dataURL, image.fileName);
|
|
14355
|
+
triggerDownload(image.blob ?? image.dataURL, image.fileName);
|
|
14332
14356
|
} else if (uniqueImages.length > 1) {
|
|
14333
14357
|
const imagesBlob = await zipUpImages(uniqueImages);
|
|
14334
14358
|
if (imagesBlob)
|
|
@@ -14352,8 +14376,12 @@ async function zipUpImages(images) {
|
|
|
14352
14376
|
const zip = new import_jszip.default;
|
|
14353
14377
|
try {
|
|
14354
14378
|
images.forEach((image) => {
|
|
14355
|
-
|
|
14356
|
-
|
|
14379
|
+
if (image.blob) {
|
|
14380
|
+
zip.file(image.fileName, image.blob);
|
|
14381
|
+
} else {
|
|
14382
|
+
const content = image.dataURL.split(",")[1];
|
|
14383
|
+
zip.file(image.fileName, content, { base64: true });
|
|
14384
|
+
}
|
|
14357
14385
|
});
|
|
14358
14386
|
} catch (error) {
|
|
14359
14387
|
console.error("Image Exporter - Error adding images to ZIP:", error);
|
|
@@ -14378,27 +14406,15 @@ function parseLabel(config) {
|
|
|
14378
14406
|
}
|
|
14379
14407
|
}
|
|
14380
14408
|
function ensureUniqueFileNames(images) {
|
|
14381
|
-
const
|
|
14409
|
+
const seen = new Set;
|
|
14382
14410
|
return images.map((image) => {
|
|
14383
|
-
const
|
|
14384
|
-
|
|
14385
|
-
const baseName = lastDotIndex !== -1 ? fileName.substring(0, lastDotIndex) : fileName;
|
|
14386
|
-
const extension = lastDotIndex !== -1 ? fileName.substring(lastDotIndex) : "";
|
|
14387
|
-
if (!fileNameMap.has(fileName)) {
|
|
14388
|
-
fileNameMap.set(fileName, 1);
|
|
14389
|
-
return image;
|
|
14390
|
-
}
|
|
14391
|
-
const count = fileNameMap.get(fileName) + 1;
|
|
14392
|
-
fileNameMap.set(fileName, count);
|
|
14393
|
-
const newFileName = `${baseName}-${count}${extension}`;
|
|
14394
|
-
return {
|
|
14395
|
-
...image,
|
|
14396
|
-
fileName: newFileName
|
|
14397
|
-
};
|
|
14411
|
+
const fileName = makeUnique(image.fileName, seen);
|
|
14412
|
+
return fileName === image.fileName ? image : { ...image, fileName };
|
|
14398
14413
|
});
|
|
14399
14414
|
}
|
|
14400
14415
|
|
|
14401
14416
|
// src/logger.ts
|
|
14417
|
+
var hasWindow = typeof window !== "undefined";
|
|
14402
14418
|
var log = {
|
|
14403
14419
|
info: (...messages) => logAction(messages, "info"),
|
|
14404
14420
|
error: (...messages) => logAction(messages, "error"),
|
|
@@ -14434,16 +14450,18 @@ async function logAction(messages, type = "info") {
|
|
|
14434
14450
|
console.groupEnd();
|
|
14435
14451
|
break;
|
|
14436
14452
|
}
|
|
14437
|
-
if (windowLogging)
|
|
14453
|
+
if (windowLogging && hasWindow)
|
|
14438
14454
|
window.imageExporterLogs.push({ message: combinedMessage, type });
|
|
14439
14455
|
}
|
|
14440
14456
|
async function logProgress(progress, total) {
|
|
14441
|
-
if (windowLogging) {
|
|
14457
|
+
if (windowLogging && hasWindow) {
|
|
14442
14458
|
window.imageExporterProgress.push([progress, total]);
|
|
14443
14459
|
}
|
|
14444
14460
|
}
|
|
14445
|
-
|
|
14446
|
-
window.
|
|
14461
|
+
if (hasWindow) {
|
|
14462
|
+
window.imageExporterLogs = [];
|
|
14463
|
+
window.imageExporterProgress = [];
|
|
14464
|
+
}
|
|
14447
14465
|
|
|
14448
14466
|
// src/cors-proxy/is-valid-url.ts
|
|
14449
14467
|
function isValidUrl(string) {
|
|
@@ -14456,7 +14474,7 @@ function isValidUrl(string) {
|
|
|
14456
14474
|
return false;
|
|
14457
14475
|
}
|
|
14458
14476
|
return true;
|
|
14459
|
-
} catch
|
|
14477
|
+
} catch {
|
|
14460
14478
|
return false;
|
|
14461
14479
|
}
|
|
14462
14480
|
}
|
|
@@ -14465,7 +14483,7 @@ function isValidUrl(string) {
|
|
|
14465
14483
|
async function proxyCSS(config) {
|
|
14466
14484
|
const stylesheetElements = document.querySelectorAll('link[rel="stylesheet"]');
|
|
14467
14485
|
log.verbose("stylesheet elements to proxy", stylesheetElements.length);
|
|
14468
|
-
for (
|
|
14486
|
+
for (const stylesheetElement of stylesheetElements) {
|
|
14469
14487
|
const stylesheetURL = stylesheetElement.getAttribute("href");
|
|
14470
14488
|
if (!stylesheetURL)
|
|
14471
14489
|
continue;
|
|
@@ -14479,7 +14497,7 @@ async function proxyCSS(config) {
|
|
|
14479
14497
|
const proxiedURL = config.corsProxyBaseUrl + encodeURIComponent(stylesheetURL);
|
|
14480
14498
|
try {
|
|
14481
14499
|
const response = await fetch(proxiedURL);
|
|
14482
|
-
|
|
14500
|
+
const cssContent = await response.text();
|
|
14483
14501
|
const styleElement = document.createElement("style");
|
|
14484
14502
|
styleElement.textContent = cssContent;
|
|
14485
14503
|
styleElement.setAttribute("original-link-element", encodeURIComponent(stylesheetElement.outerHTML));
|
|
@@ -14535,7 +14553,7 @@ async function cleanUpCorsProxy() {
|
|
|
14535
14553
|
}
|
|
14536
14554
|
async function restoreCSS() {
|
|
14537
14555
|
const styleElements = document.querySelectorAll("style[original-link-element]");
|
|
14538
|
-
for (
|
|
14556
|
+
for (const styleElement of styleElements) {
|
|
14539
14557
|
const originalLinkElementHTML = decodeURIComponent(styleElement.getAttribute("original-link-element"));
|
|
14540
14558
|
const tempContainer = document.createElement("div");
|
|
14541
14559
|
tempContainer.innerHTML = originalLinkElementHTML;
|
|
@@ -14546,7 +14564,7 @@ async function restoreCSS() {
|
|
|
14546
14564
|
}
|
|
14547
14565
|
async function restoreImages() {
|
|
14548
14566
|
const imageElements = document.querySelectorAll("img[original-src]");
|
|
14549
|
-
for (
|
|
14567
|
+
for (const imageElement of imageElements) {
|
|
14550
14568
|
const originalSrc = imageElement.getAttribute("original-src");
|
|
14551
14569
|
imageElement.src = originalSrc;
|
|
14552
14570
|
imageElement.removeAttribute("original-src");
|
|
@@ -14560,6 +14578,23 @@ var corsProxy = {
|
|
|
14560
14578
|
cleanUp: cleanUpCorsProxy
|
|
14561
14579
|
};
|
|
14562
14580
|
|
|
14581
|
+
// src/capture/data-url-to-blob.ts
|
|
14582
|
+
function dataUrlToBlob(dataURL) {
|
|
14583
|
+
const commaIndex = dataURL.indexOf(",");
|
|
14584
|
+
const meta = dataURL.slice(0, commaIndex);
|
|
14585
|
+
const data = dataURL.slice(commaIndex + 1);
|
|
14586
|
+
const mimeMatch = meta.match(/^data:([^;]+)/);
|
|
14587
|
+
const mime = mimeMatch ? mimeMatch[1] : "";
|
|
14588
|
+
if (meta.includes(";base64")) {
|
|
14589
|
+
const binary = atob(data);
|
|
14590
|
+
const bytes = new Uint8Array(binary.length);
|
|
14591
|
+
for (let i2 = 0;i2 < binary.length; i2++)
|
|
14592
|
+
bytes[i2] = binary.charCodeAt(i2);
|
|
14593
|
+
return new Blob([bytes], { type: mime });
|
|
14594
|
+
}
|
|
14595
|
+
return new Blob([decodeURIComponent(data)], { type: mime });
|
|
14596
|
+
}
|
|
14597
|
+
|
|
14563
14598
|
// src/capture/get-image-options.ts
|
|
14564
14599
|
async function getImageOptions(element, config) {
|
|
14565
14600
|
return {
|
|
@@ -14601,7 +14636,7 @@ async function getImageOptions(element, config) {
|
|
|
14601
14636
|
throw new Error(`ImageExporter: provided format is not valid.
|
|
14602
14637
|
Provided: ${format}
|
|
14603
14638
|
Element: ${element}
|
|
14604
|
-
Accepted values: jpg, png, svg,
|
|
14639
|
+
Accepted values: jpg, png, svg, webp
|
|
14605
14640
|
Defaulting to: ${config.format}`);
|
|
14606
14641
|
}
|
|
14607
14642
|
} catch (error) {
|
|
@@ -14692,32 +14727,35 @@ function isVisible(element) {
|
|
|
14692
14727
|
}
|
|
14693
14728
|
|
|
14694
14729
|
// src/capture/determine-total-elements.ts
|
|
14695
|
-
async function determineTotalElements(elements) {
|
|
14730
|
+
async function determineTotalElements(elements, config) {
|
|
14696
14731
|
try {
|
|
14697
14732
|
let totalElements = 0;
|
|
14698
|
-
for (const element of elements) {
|
|
14699
|
-
|
|
14700
|
-
if (!scaleAsString)
|
|
14701
|
-
continue;
|
|
14702
|
-
if (scaleAsString.includes(",")) {
|
|
14703
|
-
const scales = scaleAsString.trim().split(",").map((scale) => parseFloat(scale));
|
|
14704
|
-
if (scales.some((scale) => isNaN(scale)))
|
|
14705
|
-
continue;
|
|
14706
|
-
totalElements += scales.length;
|
|
14707
|
-
} else {
|
|
14708
|
-
const scaleAsNumber = parseFloat(scaleAsString.trim());
|
|
14709
|
-
if (isNaN(scaleAsNumber)) {
|
|
14710
|
-
continue;
|
|
14711
|
-
} else {
|
|
14712
|
-
totalElements++;
|
|
14713
|
-
}
|
|
14714
|
-
}
|
|
14733
|
+
for (const element of Array.from(elements)) {
|
|
14734
|
+
totalElements += countScalesForElement(element, config);
|
|
14715
14735
|
}
|
|
14716
14736
|
return totalElements;
|
|
14717
|
-
} catch
|
|
14737
|
+
} catch {
|
|
14718
14738
|
return 1;
|
|
14719
14739
|
}
|
|
14720
14740
|
}
|
|
14741
|
+
function countScalesForElement(element, config) {
|
|
14742
|
+
const scaleAsString = element.dataset.scale;
|
|
14743
|
+
if (!scaleAsString)
|
|
14744
|
+
return countConfigScale(config);
|
|
14745
|
+
if (scaleAsString.includes(",")) {
|
|
14746
|
+
const scales = scaleAsString.trim().split(",").map((scale) => parseFloat(scale));
|
|
14747
|
+
if (scales.some((scale) => isNaN(scale)))
|
|
14748
|
+
return countConfigScale(config);
|
|
14749
|
+
return scales.length;
|
|
14750
|
+
}
|
|
14751
|
+
const scaleAsNumber = parseFloat(scaleAsString.trim());
|
|
14752
|
+
if (isNaN(scaleAsNumber))
|
|
14753
|
+
return countConfigScale(config);
|
|
14754
|
+
return 1;
|
|
14755
|
+
}
|
|
14756
|
+
function countConfigScale(config) {
|
|
14757
|
+
return Array.isArray(config.scale) ? config.scale.length : 1;
|
|
14758
|
+
}
|
|
14721
14759
|
|
|
14722
14760
|
// src/capture/index.ts
|
|
14723
14761
|
var windowLogging = true;
|
|
@@ -14733,50 +14771,85 @@ async function capture(elements, userConfig = defaultConfig) {
|
|
|
14733
14771
|
elements = [elements];
|
|
14734
14772
|
const originalLength = elements.length;
|
|
14735
14773
|
elements = removeHiddenElements(elements);
|
|
14736
|
-
const totalElements = await determineTotalElements(elements);
|
|
14774
|
+
const totalElements = await determineTotalElements(elements, config);
|
|
14737
14775
|
if (originalLength !== elements.length)
|
|
14738
14776
|
log.verbose("Skipping capture of hidden elements: ", originalLength - elements.length);
|
|
14739
14777
|
log.verbose("Element to capture", elements.length);
|
|
14740
14778
|
if (userConfig.corsProxyBaseUrl)
|
|
14741
14779
|
await corsProxy.run(config, elements);
|
|
14742
|
-
|
|
14743
|
-
|
|
14780
|
+
const images = [];
|
|
14781
|
+
const seen = new Set;
|
|
14744
14782
|
let imageNumber = 1;
|
|
14745
|
-
|
|
14746
|
-
|
|
14747
|
-
|
|
14748
|
-
|
|
14749
|
-
|
|
14750
|
-
|
|
14751
|
-
|
|
14752
|
-
|
|
14753
|
-
|
|
14754
|
-
|
|
14755
|
-
|
|
14756
|
-
|
|
14757
|
-
|
|
14758
|
-
|
|
14759
|
-
|
|
14760
|
-
|
|
14761
|
-
|
|
14762
|
-
|
|
14763
|
-
|
|
14783
|
+
const tryCapture = async (element, options) => {
|
|
14784
|
+
try {
|
|
14785
|
+
const image = await captureElement(element, options, seen, config.screenshotOptions);
|
|
14786
|
+
images.push(applyOutput(image, config.output));
|
|
14787
|
+
} catch (error) {
|
|
14788
|
+
log.error(error);
|
|
14789
|
+
} finally {
|
|
14790
|
+
const completed = imageNumber++;
|
|
14791
|
+
log.progress(completed, totalElements);
|
|
14792
|
+
config.onProgress?.(completed, totalElements);
|
|
14793
|
+
}
|
|
14794
|
+
};
|
|
14795
|
+
captureLoop:
|
|
14796
|
+
for (const element of elements) {
|
|
14797
|
+
if (config.signal?.aborted)
|
|
14798
|
+
break;
|
|
14799
|
+
const imageOptions = await getImageOptions(element, config);
|
|
14800
|
+
log.verbose("Image options", imageOptions);
|
|
14801
|
+
if (imageOptions.scale instanceof Array) {
|
|
14802
|
+
log.verbose("Multi-scale capture");
|
|
14803
|
+
imageOptions.includeScaleInLabel = true;
|
|
14804
|
+
for (const scale of imageOptions.scale) {
|
|
14805
|
+
if (config.signal?.aborted)
|
|
14806
|
+
break captureLoop;
|
|
14807
|
+
await tryCapture(element, {
|
|
14808
|
+
...imageOptions,
|
|
14809
|
+
scale
|
|
14810
|
+
});
|
|
14811
|
+
}
|
|
14812
|
+
} else if (typeof imageOptions.scale === "number") {
|
|
14813
|
+
log.verbose("Single-scale capture");
|
|
14814
|
+
await tryCapture(element, imageOptions);
|
|
14815
|
+
}
|
|
14816
|
+
}
|
|
14817
|
+
if (config.signal?.aborted) {
|
|
14818
|
+
log.verbose("Capture aborted; returning", images.length, "image(s)");
|
|
14819
|
+
return images;
|
|
14820
|
+
}
|
|
14821
|
+
if (config.downloadImages)
|
|
14764
14822
|
await downloadImages(images, config);
|
|
14765
|
-
if (userConfig.corsProxyBaseUrl)
|
|
14766
|
-
await corsProxy.cleanUp();
|
|
14767
14823
|
return images;
|
|
14768
14824
|
} catch (error) {
|
|
14769
14825
|
log.error(error);
|
|
14770
14826
|
return null;
|
|
14771
14827
|
} finally {
|
|
14828
|
+
if (userConfig.corsProxyBaseUrl)
|
|
14829
|
+
await corsProxy.cleanUp();
|
|
14772
14830
|
log.group.close();
|
|
14773
14831
|
}
|
|
14774
14832
|
}
|
|
14833
|
+
function applyOutput(image, output) {
|
|
14834
|
+
if (!output || output === "dataurl")
|
|
14835
|
+
return image;
|
|
14836
|
+
const blob = dataUrlToBlob(image.dataURL);
|
|
14837
|
+
if (output === "blob")
|
|
14838
|
+
return { ...image, dataURL: "", blob };
|
|
14839
|
+
return { ...image, blob };
|
|
14840
|
+
}
|
|
14841
|
+
|
|
14842
|
+
// src/capture/copy-to-clipboard.ts
|
|
14843
|
+
async function copyImageToClipboard(image) {
|
|
14844
|
+
const blob = image.blob ?? dataUrlToBlob(image.dataURL);
|
|
14845
|
+
await navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]);
|
|
14846
|
+
}
|
|
14775
14847
|
|
|
14776
14848
|
// src/index.ts
|
|
14777
14849
|
if (typeof window !== "undefined") {
|
|
14778
14850
|
window.imageExporter = capture;
|
|
14779
14851
|
window.imageExporterDownload = downloadImages;
|
|
14852
|
+
window.imageExporterCopyToClipboard = copyImageToClipboard;
|
|
14780
14853
|
}
|
|
14781
14854
|
|
|
14782
|
-
//# debugId=
|
|
14855
|
+
//# debugId=E8C5F97C6B31AA5264756E2164756E21
|