@zumer/snapdom 1.9.10 → 1.9.12-dev.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 +9 -3
- package/dist/snapdom.js +208 -76
- package/dist/snapdom.min.js +4 -4
- package/dist/snapdom.min.mjs +4 -4
- package/dist/snapdom.mjs +192 -61
- package/package.json +1 -1
- package/types/snapdom.d.ts +15 -0
package/dist/snapdom.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
/*
|
|
3
3
|
* snapdom
|
|
4
|
-
* v.1.9.
|
|
4
|
+
* v.1.9.12-dev.0
|
|
5
5
|
* Author Juan Martin Muda
|
|
6
6
|
* License MIT
|
|
7
7
|
**/
|
|
@@ -127,10 +127,25 @@ var snapLogger = createSnapLogger("[snapDOM]", { ttlMs: 3 * 6e4, maxEntries: 10
|
|
|
127
127
|
var _inflight = /* @__PURE__ */ new Map();
|
|
128
128
|
var _errorCache = /* @__PURE__ */ new Map();
|
|
129
129
|
function isSpecialURL(url) {
|
|
130
|
-
return /^data:|^blob:|^about:blank
|
|
130
|
+
return /^data:|^blob:|^about:blank$/i.test(url);
|
|
131
|
+
}
|
|
132
|
+
function isAlreadyProxied(url, useProxy) {
|
|
133
|
+
try {
|
|
134
|
+
const baseHref = typeof location !== "undefined" && location.href ? location.href : "http://localhost/";
|
|
135
|
+
const proxyBaseRaw = useProxy.includes("{url}") ? useProxy.split("{url}")[0] : useProxy;
|
|
136
|
+
const proxyBase = new URL(proxyBaseRaw || ".", baseHref);
|
|
137
|
+
const u = new URL(url, baseHref);
|
|
138
|
+
if (u.origin === proxyBase.origin) return true;
|
|
139
|
+
const sp = u.searchParams;
|
|
140
|
+
if (sp && (sp.has("url") || sp.has("target"))) return true;
|
|
141
|
+
} catch {
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
131
144
|
}
|
|
132
145
|
function shouldProxy(url, useProxy) {
|
|
133
|
-
if (!useProxy
|
|
146
|
+
if (!useProxy) return false;
|
|
147
|
+
if (isSpecialURL(url)) return false;
|
|
148
|
+
if (isAlreadyProxied(url, useProxy)) return false;
|
|
134
149
|
try {
|
|
135
150
|
const base = typeof location !== "undefined" && location.href ? location.href : "http://localhost/";
|
|
136
151
|
const u = new URL(url, base);
|
|
@@ -141,8 +156,19 @@ function shouldProxy(url, useProxy) {
|
|
|
141
156
|
}
|
|
142
157
|
function applyProxy(url, useProxy) {
|
|
143
158
|
if (!useProxy) return url;
|
|
144
|
-
if (useProxy.includes("{url}"))
|
|
145
|
-
|
|
159
|
+
if (useProxy.includes("{url}")) {
|
|
160
|
+
return useProxy.replace("{urlRaw}", safeEncodeURI(url)).replace("{url}", encodeURIComponent(url));
|
|
161
|
+
}
|
|
162
|
+
if (/[?&]url=?$/.test(useProxy)) {
|
|
163
|
+
return `${useProxy}${encodeURIComponent(url)}`;
|
|
164
|
+
}
|
|
165
|
+
if (useProxy.endsWith("?")) {
|
|
166
|
+
return `${useProxy}url=${encodeURIComponent(url)}`;
|
|
167
|
+
}
|
|
168
|
+
if (useProxy.endsWith("/")) {
|
|
169
|
+
return `${useProxy}${safeEncodeURI(url)}`;
|
|
170
|
+
}
|
|
171
|
+
const sep = useProxy.includes("?") ? "&" : "?";
|
|
146
172
|
return `${useProxy}${sep}url=${encodeURIComponent(url)}`;
|
|
147
173
|
}
|
|
148
174
|
function blobToDataURL(blob) {
|
|
@@ -169,6 +195,65 @@ async function snapFetch(url, options = {}) {
|
|
|
169
195
|
const errorTTL = options.errorTTL ?? 8e3;
|
|
170
196
|
const headers = options.headers || {};
|
|
171
197
|
const silent = !!options.silent;
|
|
198
|
+
if (/^data:/i.test(url)) {
|
|
199
|
+
try {
|
|
200
|
+
if (as === "text") {
|
|
201
|
+
return { ok: true, data: String(url), status: 200, url, fromCache: false };
|
|
202
|
+
}
|
|
203
|
+
if (as === "dataURL") {
|
|
204
|
+
return {
|
|
205
|
+
ok: true,
|
|
206
|
+
data: String(url),
|
|
207
|
+
status: 200,
|
|
208
|
+
url,
|
|
209
|
+
fromCache: false,
|
|
210
|
+
mime: String(url).slice(5).split(";")[0] || ""
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const [, meta = "", data = ""] = String(url).match(/^data:([^,]*),(.*)$/) || [];
|
|
214
|
+
const isBase64 = /;base64/i.test(meta);
|
|
215
|
+
const bin = isBase64 ? atob(data) : decodeURIComponent(data);
|
|
216
|
+
const bytes = new Uint8Array([...bin].map((c) => c.charCodeAt(0)));
|
|
217
|
+
const b = new Blob([bytes], { type: (meta || "").split(";")[0] || "" });
|
|
218
|
+
return { ok: true, data: b, status: 200, url, fromCache: false, mime: b.type || "" };
|
|
219
|
+
} catch {
|
|
220
|
+
return { ok: false, data: null, status: 0, url, fromCache: false, reason: "special_url_error" };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (/^blob:/i.test(url)) {
|
|
224
|
+
try {
|
|
225
|
+
const resp = await fetch(url);
|
|
226
|
+
if (!resp.ok) {
|
|
227
|
+
return { ok: false, data: null, status: resp.status, url, fromCache: false, reason: "http_error" };
|
|
228
|
+
}
|
|
229
|
+
const blob = await resp.blob();
|
|
230
|
+
const mime = blob.type || resp.headers.get("content-type") || "";
|
|
231
|
+
if (as === "dataURL") {
|
|
232
|
+
const dataURL = await blobToDataURL(blob);
|
|
233
|
+
return { ok: true, data: dataURL, status: resp.status, url, fromCache: false, mime };
|
|
234
|
+
}
|
|
235
|
+
if (as === "text") {
|
|
236
|
+
const text = await blob.text();
|
|
237
|
+
return { ok: true, data: text, status: resp.status, url, fromCache: false, mime };
|
|
238
|
+
}
|
|
239
|
+
return { ok: true, data: blob, status: resp.status, url, fromCache: false, mime };
|
|
240
|
+
} catch {
|
|
241
|
+
return { ok: false, data: null, status: 0, url, fromCache: false, reason: "network" };
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (/^about:blank$/i.test(url)) {
|
|
245
|
+
if (as === "dataURL") {
|
|
246
|
+
return {
|
|
247
|
+
ok: true,
|
|
248
|
+
data: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==",
|
|
249
|
+
status: 200,
|
|
250
|
+
url,
|
|
251
|
+
fromCache: false,
|
|
252
|
+
mime: "image/png"
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
return { ok: true, data: as === "text" ? "" : new Blob([]), status: 200, url, fromCache: false };
|
|
256
|
+
}
|
|
172
257
|
const key = makeKey(url, { as, timeout, useProxy, errorTTL });
|
|
173
258
|
const e = _errorCache.get(key);
|
|
174
259
|
if (e && e.until > Date.now()) {
|
|
@@ -197,7 +282,7 @@ async function snapFetch(url, options = {}) {
|
|
|
197
282
|
const resp = await fetch(finalURL, { signal: ctrl.signal, credentials: cred, headers });
|
|
198
283
|
if (!resp.ok) {
|
|
199
284
|
const result = { ok: false, data: null, status: resp.status, url: finalURL, fromCache: false, reason: "http_error" };
|
|
200
|
-
_errorCache.set(key, { until: Date.now() + errorTTL, result });
|
|
285
|
+
if (errorTTL > 0) _errorCache.set(key, { until: Date.now() + errorTTL, result });
|
|
201
286
|
if (!silent) {
|
|
202
287
|
const short = `${resp.status} ${resp.statusText || ""}`.trim();
|
|
203
288
|
snapLogger.warnOnce(
|
|
@@ -222,7 +307,9 @@ async function snapFetch(url, options = {}) {
|
|
|
222
307
|
} catch (err) {
|
|
223
308
|
const reason = err && typeof err === "object" && "name" in err && err.name === "AbortError" ? String(err.message || "").includes("timeout") ? "timeout" : "abort" : "network";
|
|
224
309
|
const result = { ok: false, data: null, status: 0, url: finalURL, fromCache: false, reason };
|
|
225
|
-
|
|
310
|
+
if (!/^blob:/i.test(url) && errorTTL > 0) {
|
|
311
|
+
_errorCache.set(key, { until: Date.now() + errorTTL, result });
|
|
312
|
+
}
|
|
226
313
|
if (!silent) {
|
|
227
314
|
const k = `${reason}:${as}:${new URL(url, location?.href ?? "http://localhost/").origin}`;
|
|
228
315
|
const tips = reason === "timeout" ? `Timeout after ${timeout}ms. Consider increasing timeout or using a proxy for ${url}` : reason === "abort" ? `Request aborted while fetching ${as} ${url}` : `Network/CORS issue while fetching ${as} ${url}. A proxy may be required`;
|
|
@@ -670,22 +757,14 @@ function idleCallback(childList, callback, fast) {
|
|
|
670
757
|
return Promise.all(childList.map((child) => {
|
|
671
758
|
return new Promise((resolve) => {
|
|
672
759
|
function deal() {
|
|
673
|
-
idle(
|
|
674
|
-
(
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
deal();
|
|
680
|
-
}
|
|
681
|
-
} else {
|
|
682
|
-
callback(child, resolve);
|
|
683
|
-
}
|
|
684
|
-
},
|
|
685
|
-
{
|
|
686
|
-
fast
|
|
760
|
+
idle((deadline) => {
|
|
761
|
+
const hasIdleBudget = deadline && typeof deadline.timeRemaining === "function" ? deadline.timeRemaining() > 0 : true;
|
|
762
|
+
if (hasIdleBudget) {
|
|
763
|
+
callback(child, resolve);
|
|
764
|
+
} else {
|
|
765
|
+
deal();
|
|
687
766
|
}
|
|
688
|
-
);
|
|
767
|
+
}, { fast });
|
|
689
768
|
}
|
|
690
769
|
deal();
|
|
691
770
|
});
|
|
@@ -906,19 +985,27 @@ async function deepClone(node, sessionCache, options) {
|
|
|
906
985
|
return node.cloneNode(true);
|
|
907
986
|
}
|
|
908
987
|
if (node.getAttribute("data-capture") === "exclude") {
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
988
|
+
if (options.excludeMode === "visuallyHide") {
|
|
989
|
+
const spacer = document.createElement("div");
|
|
990
|
+
const rect = node.getBoundingClientRect();
|
|
991
|
+
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
992
|
+
return spacer;
|
|
993
|
+
} else if (options.excludeMode === "remove") {
|
|
994
|
+
return null;
|
|
995
|
+
}
|
|
913
996
|
}
|
|
914
997
|
if (options.exclude && Array.isArray(options.exclude)) {
|
|
915
998
|
for (const selector of options.exclude) {
|
|
916
999
|
try {
|
|
917
1000
|
if (node.matches?.(selector)) {
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
1001
|
+
if (options.excludeMode === "visuallyHide") {
|
|
1002
|
+
const spacer = document.createElement("div");
|
|
1003
|
+
const rect = node.getBoundingClientRect();
|
|
1004
|
+
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
1005
|
+
return spacer;
|
|
1006
|
+
} else if (options.excludeMode === "remove") {
|
|
1007
|
+
return null;
|
|
1008
|
+
}
|
|
922
1009
|
}
|
|
923
1010
|
} catch (err) {
|
|
924
1011
|
console.warn(`Invalid selector in exclude option: ${selector}`, err);
|
|
@@ -928,10 +1015,14 @@ async function deepClone(node, sessionCache, options) {
|
|
|
928
1015
|
if (typeof options.filter === "function") {
|
|
929
1016
|
try {
|
|
930
1017
|
if (!options.filter(node)) {
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
1018
|
+
if (options.filterMode === "visuallyHide") {
|
|
1019
|
+
const spacer = document.createElement("div");
|
|
1020
|
+
const rect = node.getBoundingClientRect();
|
|
1021
|
+
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
1022
|
+
return spacer;
|
|
1023
|
+
} else if (options.filterMode === "remove") {
|
|
1024
|
+
return null;
|
|
1025
|
+
}
|
|
935
1026
|
}
|
|
936
1027
|
} catch (err) {
|
|
937
1028
|
console.warn("Error in filter function:", err);
|
|
@@ -1774,7 +1865,7 @@ function collectUsedCodepoints(root) {
|
|
|
1774
1865
|
}
|
|
1775
1866
|
return used;
|
|
1776
1867
|
}
|
|
1777
|
-
async function ensureFontsReady(families, warmupRepetitions =
|
|
1868
|
+
async function ensureFontsReady(families, warmupRepetitions = 2) {
|
|
1778
1869
|
try {
|
|
1779
1870
|
await document.fonts.ready;
|
|
1780
1871
|
} catch {
|
|
@@ -2668,7 +2759,9 @@ function createContext(options = {}) {
|
|
|
2668
2759
|
scale: options.scale ?? 1,
|
|
2669
2760
|
// DOM filters
|
|
2670
2761
|
exclude: options.exclude ?? [],
|
|
2762
|
+
excludeMode: options.excludeMode ?? "visuallyHide",
|
|
2671
2763
|
filter: options.filter ?? null,
|
|
2764
|
+
filterMode: options.filterMode ?? "visuallyHide",
|
|
2672
2765
|
placeholders: options.placeholders !== false,
|
|
2673
2766
|
// default true
|
|
2674
2767
|
// Fuentes
|
|
@@ -2711,24 +2804,12 @@ async function toImg(url, options) {
|
|
|
2711
2804
|
// src/exporters/toCanvas.js
|
|
2712
2805
|
async function toCanvas(url, options) {
|
|
2713
2806
|
const { scale, dpr } = options;
|
|
2714
|
-
const safari = isSafari();
|
|
2715
2807
|
const img = new Image();
|
|
2716
2808
|
img.crossOrigin = "anonymous";
|
|
2717
2809
|
img.loading = "eager";
|
|
2718
2810
|
img.decoding = "sync";
|
|
2719
2811
|
img.src = url;
|
|
2720
|
-
let tempSlot = null;
|
|
2721
|
-
if (safari) {
|
|
2722
|
-
tempSlot = document.createElement("div");
|
|
2723
|
-
tempSlot.setAttribute("aria-hidden", "true");
|
|
2724
|
-
tempSlot.style.cssText = "position:absolute;left:-99999px;top:0;width:0;height:0;overflow:hidden;opacity:0;pointer-events:none;contain:size layout style;";
|
|
2725
|
-
document.body.appendChild(tempSlot);
|
|
2726
|
-
tempSlot.appendChild(img);
|
|
2727
|
-
}
|
|
2728
2812
|
await img.decode();
|
|
2729
|
-
if (safari) {
|
|
2730
|
-
await new Promise((r) => setTimeout(r, 100));
|
|
2731
|
-
}
|
|
2732
2813
|
const width = img.naturalWidth * scale;
|
|
2733
2814
|
const height = img.naturalHeight * scale;
|
|
2734
2815
|
const canvas = document.createElement("canvas");
|
|
@@ -2739,12 +2820,6 @@ async function toCanvas(url, options) {
|
|
|
2739
2820
|
const ctx = canvas.getContext("2d");
|
|
2740
2821
|
if (dpr !== 1) ctx.scale(dpr, dpr);
|
|
2741
2822
|
ctx.drawImage(img, 0, 0, width, height);
|
|
2742
|
-
if (tempSlot && tempSlot.parentNode) {
|
|
2743
|
-
try {
|
|
2744
|
-
tempSlot.parentNode.removeChild(tempSlot);
|
|
2745
|
-
} catch {
|
|
2746
|
-
}
|
|
2747
|
-
}
|
|
2748
2823
|
return canvas;
|
|
2749
2824
|
}
|
|
2750
2825
|
|
|
@@ -2800,8 +2875,19 @@ async function download(url, options) {
|
|
|
2800
2875
|
|
|
2801
2876
|
// src/api/snapdom.js
|
|
2802
2877
|
var INTERNAL_TOKEN = Symbol("snapdom.internal");
|
|
2878
|
+
var _safariWarmup = false;
|
|
2803
2879
|
async function snapdom(element, userOptions) {
|
|
2804
2880
|
if (!element) throw new Error("Element cannot be null or undefined");
|
|
2881
|
+
if (isSafari()) {
|
|
2882
|
+
for (let i = 0; i < 3; i++) {
|
|
2883
|
+
try {
|
|
2884
|
+
await safariWarmup(element, userOptions);
|
|
2885
|
+
console.log("Iteraci\xF3n n\xFAmero:", i);
|
|
2886
|
+
_safariWarmup = false;
|
|
2887
|
+
} catch (error) {
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2805
2891
|
const context = createContext(userOptions);
|
|
2806
2892
|
if (context.iconFonts && context.iconFonts.length > 0) extendIconFonts(context.iconFonts);
|
|
2807
2893
|
if (!context.snap) {
|
|
@@ -2845,24 +2931,65 @@ snapdom.toPng = (el, options) => snapdom(el, { ...options, format: "png" }).then
|
|
|
2845
2931
|
snapdom.toJpg = (el, options) => snapdom(el, { ...options, format: "jpeg" }).then((result) => result.toJpg());
|
|
2846
2932
|
snapdom.toWebp = (el, options) => snapdom(el, { ...options, format: "webp" }).then((result) => result.toWebp());
|
|
2847
2933
|
snapdom.download = (el, options) => snapdom(el, options).then((result) => result.download());
|
|
2934
|
+
async function safariWarmup(element, baseOptions) {
|
|
2935
|
+
if (_safariWarmup) return;
|
|
2936
|
+
const preflight = {
|
|
2937
|
+
...baseOptions,
|
|
2938
|
+
fast: true,
|
|
2939
|
+
embedFonts: true,
|
|
2940
|
+
scale: 0.2
|
|
2941
|
+
};
|
|
2942
|
+
let url;
|
|
2943
|
+
try {
|
|
2944
|
+
url = await captureDOM(element, preflight);
|
|
2945
|
+
} catch {
|
|
2946
|
+
return;
|
|
2947
|
+
}
|
|
2948
|
+
await new Promise((resolve) => {
|
|
2949
|
+
const img = new Image();
|
|
2950
|
+
img.decoding = "sync";
|
|
2951
|
+
img.loading = "eager";
|
|
2952
|
+
img.style.position = "fixed";
|
|
2953
|
+
img.style.left = 0;
|
|
2954
|
+
img.style.top = 0;
|
|
2955
|
+
img.style.width = "10px";
|
|
2956
|
+
img.style.height = "10px";
|
|
2957
|
+
img.style.opacity = "0.01";
|
|
2958
|
+
img.style.transform = "translateZ(10px)";
|
|
2959
|
+
img.style.willChange = "transform,opacity;";
|
|
2960
|
+
img.src = url;
|
|
2961
|
+
const cleanup = async () => {
|
|
2962
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
2963
|
+
if (img && img.parentNode) img.parentNode.removeChild(img);
|
|
2964
|
+
_safariWarmup = true;
|
|
2965
|
+
resolve();
|
|
2966
|
+
};
|
|
2967
|
+
document.body.appendChild(img);
|
|
2968
|
+
cleanup();
|
|
2969
|
+
});
|
|
2970
|
+
}
|
|
2848
2971
|
|
|
2849
2972
|
// src/api/preCache.js
|
|
2850
2973
|
async function preCache(root = document, options = {}) {
|
|
2851
2974
|
const {
|
|
2852
2975
|
embedFonts = true,
|
|
2853
|
-
cacheOpt = "full",
|
|
2854
2976
|
useProxy = ""
|
|
2855
2977
|
} = options;
|
|
2856
|
-
|
|
2978
|
+
const cacheMode = options.cache ?? options.cacheOpt ?? "full";
|
|
2979
|
+
applyCachePolicy(cacheMode);
|
|
2857
2980
|
try {
|
|
2858
|
-
await document.fonts
|
|
2981
|
+
await document.fonts?.ready;
|
|
2982
|
+
} catch {
|
|
2983
|
+
}
|
|
2984
|
+
try {
|
|
2985
|
+
precacheCommonTags();
|
|
2859
2986
|
} catch {
|
|
2860
2987
|
}
|
|
2861
|
-
precacheCommonTags();
|
|
2862
2988
|
cache.session = cache.session || {};
|
|
2863
2989
|
if (!cache.session.styleCache) {
|
|
2864
2990
|
cache.session.styleCache = /* @__PURE__ */ new WeakMap();
|
|
2865
2991
|
}
|
|
2992
|
+
cache.image = cache.image || /* @__PURE__ */ new Map();
|
|
2866
2993
|
try {
|
|
2867
2994
|
await inlineBackgroundImages(
|
|
2868
2995
|
root,
|
|
@@ -2883,11 +3010,14 @@ async function preCache(root = document, options = {}) {
|
|
|
2883
3010
|
}
|
|
2884
3011
|
const promises = [];
|
|
2885
3012
|
for (const img of imgEls) {
|
|
2886
|
-
const src = img?.src;
|
|
3013
|
+
const src = img?.currentSrc || img?.src;
|
|
2887
3014
|
if (!src) continue;
|
|
2888
3015
|
if (!cache.image.has(src)) {
|
|
2889
|
-
const p = Promise.resolve().then(
|
|
2890
|
-
|
|
3016
|
+
const p = Promise.resolve().then(async () => {
|
|
3017
|
+
const res = await snapFetch(src, { as: "dataURL", useProxy });
|
|
3018
|
+
if (res?.ok && typeof res.data === "string") {
|
|
3019
|
+
cache.image.set(src, res.data);
|
|
3020
|
+
}
|
|
2891
3021
|
}).catch(() => {
|
|
2892
3022
|
});
|
|
2893
3023
|
promises.push(p);
|
|
@@ -2914,7 +3044,8 @@ async function preCache(root = document, options = {}) {
|
|
|
2914
3044
|
try {
|
|
2915
3045
|
const required = collectUsedFontVariants(root);
|
|
2916
3046
|
const usedCodepoints = collectUsedCodepoints(root);
|
|
2917
|
-
|
|
3047
|
+
const safari = typeof isSafari === "function" ? isSafari() : !!isSafari;
|
|
3048
|
+
if (safari) {
|
|
2918
3049
|
const families = new Set(
|
|
2919
3050
|
Array.from(required).map((k) => String(k).split("__")[0]).filter(Boolean)
|
|
2920
3051
|
);
|
package/package.json
CHANGED
package/types/snapdom.d.ts
CHANGED
|
@@ -13,6 +13,9 @@ export type BlobType = "svg" | RasterMime;
|
|
|
13
13
|
export type IconFontMatcher = string | RegExp;
|
|
14
14
|
export type CachePolicy = "disabled" | "full" | "auto" | "soft";
|
|
15
15
|
|
|
16
|
+
export type ExcludeMode = 'visuallyHide' | 'remove';
|
|
17
|
+
export type FilterMode = 'visuallyHide' | 'remove';
|
|
18
|
+
|
|
16
19
|
export interface LocalFontDescriptor {
|
|
17
20
|
/** CSS font-family name (e.g. "Inter"). */
|
|
18
21
|
family: string;
|
|
@@ -87,12 +90,24 @@ export interface CaptureOptions {
|
|
|
87
90
|
/** CSS selectors removed from the cloned subtree before processing. */
|
|
88
91
|
exclude?: string[];
|
|
89
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Mode applied to excluded nodes of the cloned tree.
|
|
95
|
+
* Default: "visuallyHide"
|
|
96
|
+
*/
|
|
97
|
+
excludeMode?: ExcludeMode;
|
|
98
|
+
|
|
90
99
|
/**
|
|
91
100
|
* Advanced node filter; return false to exclude a node during traversal.
|
|
92
101
|
* Applied to the cloned subtree.
|
|
93
102
|
*/
|
|
94
103
|
filter?: (el: Element) => boolean;
|
|
95
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Mode applied to filtered nodes of the cloned tree.
|
|
107
|
+
* Default: "visuallyHide"
|
|
108
|
+
*/
|
|
109
|
+
filterMode?: FilterMode;
|
|
110
|
+
|
|
96
111
|
/**
|
|
97
112
|
* Whether to synthesize placeholders for broken images, etc.
|
|
98
113
|
* Default: true
|