@zumer/snapdom 1.9.5 → 1.9.6-dev.1
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 +5 -2
- package/dist/snapdom.js +476 -303
- package/dist/snapdom.min.js +10 -10
- package/dist/snapdom.min.mjs +13 -13
- package/dist/snapdom.mjs +241 -198
- package/package.json +4 -1
- package/types/snapdom.d.ts +1 -1
package/dist/snapdom.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
|
|
2
2
|
/*
|
|
3
3
|
* snapdom
|
|
4
|
-
* v.1.9.
|
|
4
|
+
* v.1.9.6-dev.0
|
|
5
5
|
* Author Juan Martin Muda
|
|
6
6
|
* License MIT
|
|
7
7
|
**/
|
|
8
8
|
|
|
9
9
|
(() => {
|
|
10
10
|
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
11
12
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
12
13
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
13
14
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -35,6 +36,12 @@
|
|
|
35
36
|
}
|
|
36
37
|
return target;
|
|
37
38
|
};
|
|
39
|
+
var __esm = (fn, res) => function __init() {
|
|
40
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
41
|
+
};
|
|
42
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
43
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
44
|
+
};
|
|
38
45
|
var __async = (__this, __arguments, generator) => {
|
|
39
46
|
return new Promise((resolve, reject) => {
|
|
40
47
|
var fulfilled = (value) => {
|
|
@@ -57,67 +64,49 @@
|
|
|
57
64
|
};
|
|
58
65
|
|
|
59
66
|
// src/core/cache.js
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
function resetCache() {
|
|
68
|
+
cache.computedStyle = /* @__PURE__ */ new WeakMap();
|
|
69
|
+
cache.snapshot = /* @__PURE__ */ new WeakMap();
|
|
70
|
+
cache.snapshotKey.clear();
|
|
71
|
+
cache.preStyleMap.clear();
|
|
72
|
+
cache.preStyle = /* @__PURE__ */ new WeakMap();
|
|
73
|
+
cache.preNodeMap.clear();
|
|
74
|
+
}
|
|
75
|
+
var cache;
|
|
76
|
+
var init_cache = __esm({
|
|
77
|
+
"src/core/cache.js"() {
|
|
78
|
+
cache = {
|
|
79
|
+
image: /* @__PURE__ */ new Map(),
|
|
80
|
+
background: /* @__PURE__ */ new Map(),
|
|
81
|
+
resource: /* @__PURE__ */ new Map(),
|
|
82
|
+
defaultStyle: /* @__PURE__ */ new Map(),
|
|
83
|
+
baseStyle: /* @__PURE__ */ new Map(),
|
|
84
|
+
computedStyle: /* @__PURE__ */ new WeakMap(),
|
|
85
|
+
font: /* @__PURE__ */ new Set(),
|
|
86
|
+
snapshot: /* @__PURE__ */ new WeakMap(),
|
|
87
|
+
snapshotKey: /* @__PURE__ */ new Map(),
|
|
88
|
+
preStyleMap: /* @__PURE__ */ new Map(),
|
|
89
|
+
preStyle: /* @__PURE__ */ new WeakMap(),
|
|
90
|
+
preNodeMap: /* @__PURE__ */ new Map(),
|
|
91
|
+
reset: resetCache
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
});
|
|
67
95
|
|
|
68
96
|
// src/utils/cssTools.js
|
|
69
|
-
var commonTags = [
|
|
70
|
-
"div",
|
|
71
|
-
"span",
|
|
72
|
-
"p",
|
|
73
|
-
"a",
|
|
74
|
-
"img",
|
|
75
|
-
"ul",
|
|
76
|
-
"li",
|
|
77
|
-
"button",
|
|
78
|
-
"input",
|
|
79
|
-
"select",
|
|
80
|
-
"textarea",
|
|
81
|
-
"label",
|
|
82
|
-
"section",
|
|
83
|
-
"article",
|
|
84
|
-
"header",
|
|
85
|
-
"footer",
|
|
86
|
-
"nav",
|
|
87
|
-
"main",
|
|
88
|
-
"aside",
|
|
89
|
-
"h1",
|
|
90
|
-
"h2",
|
|
91
|
-
"h3",
|
|
92
|
-
"h4",
|
|
93
|
-
"h5",
|
|
94
|
-
"h6",
|
|
95
|
-
"svg",
|
|
96
|
-
"path",
|
|
97
|
-
"circle",
|
|
98
|
-
"rect",
|
|
99
|
-
"line",
|
|
100
|
-
"g",
|
|
101
|
-
"table",
|
|
102
|
-
"thead",
|
|
103
|
-
"tbody",
|
|
104
|
-
"tr",
|
|
105
|
-
"td",
|
|
106
|
-
"th"
|
|
107
|
-
];
|
|
108
97
|
function precacheCommonTags() {
|
|
109
98
|
for (let tag of commonTags) {
|
|
110
99
|
getDefaultStyleForTag(tag);
|
|
111
100
|
}
|
|
112
101
|
}
|
|
113
102
|
function getDefaultStyleForTag(tagName) {
|
|
114
|
-
if (
|
|
115
|
-
return
|
|
103
|
+
if (cache.defaultStyle.has(tagName)) {
|
|
104
|
+
return cache.defaultStyle.get(tagName);
|
|
116
105
|
}
|
|
117
106
|
const skipTags = /* @__PURE__ */ new Set(["script", "style", "meta", "link", "noscript", "template"]);
|
|
118
107
|
if (skipTags.has(tagName)) {
|
|
119
108
|
const empty = {};
|
|
120
|
-
|
|
109
|
+
cache.defaultStyle.set(tagName, empty);
|
|
121
110
|
return empty;
|
|
122
111
|
}
|
|
123
112
|
let sandbox = document.getElementById("snapdom-sandbox");
|
|
@@ -141,7 +130,7 @@
|
|
|
141
130
|
defaults[prop] = styles.getPropertyValue(prop);
|
|
142
131
|
}
|
|
143
132
|
sandbox.removeChild(el);
|
|
144
|
-
|
|
133
|
+
cache.defaultStyle.set(tagName, defaults);
|
|
145
134
|
return defaults;
|
|
146
135
|
}
|
|
147
136
|
function getStyleKey(snapshot, tagName, compress = false) {
|
|
@@ -177,7 +166,7 @@
|
|
|
177
166
|
function generateDedupedBaseCSS(usedTagNames) {
|
|
178
167
|
const groups = /* @__PURE__ */ new Map();
|
|
179
168
|
for (let tagName of usedTagNames) {
|
|
180
|
-
const styles =
|
|
169
|
+
const styles = cache.defaultStyle.get(tagName);
|
|
181
170
|
if (!styles) continue;
|
|
182
171
|
const key = Object.entries(styles).map(([k, v]) => `${k}:${v};`).sort().join("");
|
|
183
172
|
if (!groups.has(key)) {
|
|
@@ -192,8 +181,8 @@
|
|
|
192
181
|
}
|
|
193
182
|
return css;
|
|
194
183
|
}
|
|
195
|
-
function generateCSSClasses(
|
|
196
|
-
const keySet = new Set(
|
|
184
|
+
function generateCSSClasses() {
|
|
185
|
+
const keySet = new Set(cache.preStyleMap.values());
|
|
197
186
|
const classMap = /* @__PURE__ */ new Map();
|
|
198
187
|
let counter = 1;
|
|
199
188
|
for (const key of keySet) {
|
|
@@ -201,20 +190,64 @@
|
|
|
201
190
|
}
|
|
202
191
|
return classMap;
|
|
203
192
|
}
|
|
193
|
+
var commonTags;
|
|
194
|
+
var init_cssTools = __esm({
|
|
195
|
+
"src/utils/cssTools.js"() {
|
|
196
|
+
init_cache();
|
|
197
|
+
commonTags = [
|
|
198
|
+
"div",
|
|
199
|
+
"span",
|
|
200
|
+
"p",
|
|
201
|
+
"a",
|
|
202
|
+
"img",
|
|
203
|
+
"ul",
|
|
204
|
+
"li",
|
|
205
|
+
"button",
|
|
206
|
+
"input",
|
|
207
|
+
"select",
|
|
208
|
+
"textarea",
|
|
209
|
+
"label",
|
|
210
|
+
"section",
|
|
211
|
+
"article",
|
|
212
|
+
"header",
|
|
213
|
+
"footer",
|
|
214
|
+
"nav",
|
|
215
|
+
"main",
|
|
216
|
+
"aside",
|
|
217
|
+
"h1",
|
|
218
|
+
"h2",
|
|
219
|
+
"h3",
|
|
220
|
+
"h4",
|
|
221
|
+
"h5",
|
|
222
|
+
"h6",
|
|
223
|
+
"svg",
|
|
224
|
+
"path",
|
|
225
|
+
"circle",
|
|
226
|
+
"rect",
|
|
227
|
+
"line",
|
|
228
|
+
"g",
|
|
229
|
+
"table",
|
|
230
|
+
"thead",
|
|
231
|
+
"tbody",
|
|
232
|
+
"tr",
|
|
233
|
+
"td",
|
|
234
|
+
"th"
|
|
235
|
+
];
|
|
236
|
+
}
|
|
237
|
+
});
|
|
204
238
|
|
|
205
239
|
// src/utils/helpers.js
|
|
206
240
|
function inlineSingleBackgroundEntry(_0) {
|
|
207
241
|
return __async(this, arguments, function* (entry, options = {}) {
|
|
208
|
-
const
|
|
209
|
-
const rawUrl = match == null ? void 0 : match[1];
|
|
242
|
+
const rawUrl = extractURL(entry);
|
|
210
243
|
const isGradient = /^((repeating-)?(linear|radial|conic)-gradient)\(/i.test(entry);
|
|
211
244
|
if (rawUrl) {
|
|
212
245
|
const encodedUrl = safeEncodeURI(rawUrl);
|
|
213
|
-
if (
|
|
214
|
-
return options.skipInline ? void 0 : `url(${
|
|
246
|
+
if (cache.background.has(encodedUrl)) {
|
|
247
|
+
return options.skipInline ? void 0 : `url(${cache.background.get(encodedUrl)})`;
|
|
215
248
|
} else {
|
|
216
249
|
const dataUrl = yield fetchImage(encodedUrl, { useProxy: options.useProxy });
|
|
217
|
-
|
|
250
|
+
cache.background.set(encodedUrl, dataUrl);
|
|
218
251
|
return options.skipInline ? void 0 : `url("${dataUrl}")`;
|
|
219
252
|
}
|
|
220
253
|
}
|
|
@@ -236,10 +269,10 @@
|
|
|
236
269
|
if (!(el instanceof Element)) {
|
|
237
270
|
return window.getComputedStyle(el, pseudo);
|
|
238
271
|
}
|
|
239
|
-
let map =
|
|
272
|
+
let map = cache.computedStyle.get(el);
|
|
240
273
|
if (!map) {
|
|
241
274
|
map = /* @__PURE__ */ new Map();
|
|
242
|
-
|
|
275
|
+
cache.computedStyle.set(el, map);
|
|
243
276
|
}
|
|
244
277
|
if (!map.has(pseudo)) {
|
|
245
278
|
const st = window.getComputedStyle(el, pseudo);
|
|
@@ -315,13 +348,13 @@
|
|
|
315
348
|
}
|
|
316
349
|
const crossOriginValue = getCrossOriginMode(src);
|
|
317
350
|
console.log(`[SnapDOM - fetchImage] Start loading image: ${src} with crossOrigin=${crossOriginValue}`);
|
|
318
|
-
if (
|
|
351
|
+
if (cache.image.has(src)) {
|
|
319
352
|
console.log(`[SnapDOM - fetchImage] Cache hit for: ${src}`);
|
|
320
|
-
return Promise.resolve(
|
|
353
|
+
return Promise.resolve(cache.image.get(src));
|
|
321
354
|
}
|
|
322
355
|
const isDataURI = src.startsWith("data:image/");
|
|
323
356
|
if (isDataURI) {
|
|
324
|
-
|
|
357
|
+
cache.image.set(src, src);
|
|
325
358
|
return Promise.resolve(src);
|
|
326
359
|
}
|
|
327
360
|
const isSVG = /\.svg(\?.*)?$/i.test(src);
|
|
@@ -334,7 +367,7 @@
|
|
|
334
367
|
});
|
|
335
368
|
const svgText = yield response.text();
|
|
336
369
|
const encoded = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgText)}`;
|
|
337
|
-
|
|
370
|
+
cache.image.set(src, encoded);
|
|
338
371
|
return encoded;
|
|
339
372
|
} catch (e) {
|
|
340
373
|
return fetchWithFallback(src);
|
|
@@ -358,12 +391,12 @@
|
|
|
358
391
|
const ctx = canvas.getContext("2d");
|
|
359
392
|
ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
|
|
360
393
|
const dataURL = canvas.toDataURL("image/png");
|
|
361
|
-
|
|
394
|
+
cache.image.set(src, dataURL);
|
|
362
395
|
resolve(dataURL);
|
|
363
396
|
} catch (e) {
|
|
364
397
|
try {
|
|
365
398
|
const fallbackDataURL = yield fetchWithFallback(src);
|
|
366
|
-
|
|
399
|
+
cache.image.set(src, fallbackDataURL);
|
|
367
400
|
resolve(fallbackDataURL);
|
|
368
401
|
} catch (e2) {
|
|
369
402
|
reject(e2);
|
|
@@ -375,7 +408,7 @@
|
|
|
375
408
|
console.error(`[SnapDOM - fetchImage] Image failed to load: ${src}`);
|
|
376
409
|
try {
|
|
377
410
|
const fallbackDataURL = yield fetchWithFallback(src);
|
|
378
|
-
|
|
411
|
+
cache.image.set(src, fallbackDataURL);
|
|
379
412
|
resolve(fallbackDataURL);
|
|
380
413
|
} catch (e) {
|
|
381
414
|
reject(e);
|
|
@@ -437,10 +470,13 @@
|
|
|
437
470
|
parts.push(bg.slice(lastIndex).trim());
|
|
438
471
|
return parts;
|
|
439
472
|
}
|
|
473
|
+
var init_helpers = __esm({
|
|
474
|
+
"src/utils/helpers.js"() {
|
|
475
|
+
init_cache();
|
|
476
|
+
}
|
|
477
|
+
});
|
|
440
478
|
|
|
441
479
|
// src/modules/styles.js
|
|
442
|
-
var snapshotCache = /* @__PURE__ */ new WeakMap();
|
|
443
|
-
var snapshotKeyCache = /* @__PURE__ */ new Map();
|
|
444
480
|
function snapshotComputedStyleFull(style) {
|
|
445
481
|
const result = {};
|
|
446
482
|
for (let i = 0; i < style.length; i++) {
|
|
@@ -453,166 +489,200 @@
|
|
|
453
489
|
}
|
|
454
490
|
return result;
|
|
455
491
|
}
|
|
456
|
-
function inlineAllStyles(source, clone,
|
|
492
|
+
function inlineAllStyles(source, clone, compress) {
|
|
457
493
|
var _a;
|
|
458
494
|
if (source.tagName === "STYLE") return;
|
|
459
|
-
if (!cache.has(source)) {
|
|
460
|
-
cache.set(source, getStyle(source));
|
|
495
|
+
if (!cache.preStyle.has(source)) {
|
|
496
|
+
cache.preStyle.set(source, getStyle(source));
|
|
461
497
|
}
|
|
462
|
-
const style = cache.get(source);
|
|
463
|
-
if (!
|
|
498
|
+
const style = cache.preStyle.get(source);
|
|
499
|
+
if (!cache.snapshot.has(source)) {
|
|
464
500
|
const snapshot2 = snapshotComputedStyleFull(style);
|
|
465
|
-
|
|
501
|
+
cache.snapshot.set(source, snapshot2);
|
|
466
502
|
}
|
|
467
|
-
const snapshot =
|
|
503
|
+
const snapshot = cache.snapshot.get(source);
|
|
468
504
|
const hash = Object.entries(snapshot).sort(([a], [b]) => a.localeCompare(b)).map(([prop, val]) => `${prop}:${val}`).join(";");
|
|
469
|
-
if (
|
|
470
|
-
|
|
505
|
+
if (cache.snapshotKey.has(hash)) {
|
|
506
|
+
cache.preStyleMap.set(clone, cache.snapshotKey.get(hash));
|
|
471
507
|
return;
|
|
472
508
|
}
|
|
473
509
|
const tagName = ((_a = source.tagName) == null ? void 0 : _a.toLowerCase()) || "div";
|
|
474
510
|
const key = getStyleKey(snapshot, tagName, compress);
|
|
475
|
-
|
|
476
|
-
|
|
511
|
+
cache.snapshotKey.set(hash, key);
|
|
512
|
+
cache.preStyleMap.set(clone, key);
|
|
477
513
|
}
|
|
514
|
+
var init_styles = __esm({
|
|
515
|
+
"src/modules/styles.js"() {
|
|
516
|
+
init_cssTools();
|
|
517
|
+
init_helpers();
|
|
518
|
+
init_cache();
|
|
519
|
+
}
|
|
520
|
+
});
|
|
478
521
|
|
|
479
522
|
// src/core/clone.js
|
|
480
523
|
function isSlotElement(node) {
|
|
481
524
|
return node.nodeType === Node.ELEMENT_NODE && node.tagName === "SLOT";
|
|
482
525
|
}
|
|
483
|
-
function deepClone(node,
|
|
526
|
+
function deepClone(node, compress, options = {}, originalRoot) {
|
|
484
527
|
var _a, _b;
|
|
485
|
-
if (node
|
|
486
|
-
|
|
487
|
-
}
|
|
488
|
-
if (node.nodeType !== Node.ELEMENT_NODE) return node.cloneNode(true);
|
|
489
|
-
if (node.getAttribute("data-capture") === "exclude") {
|
|
490
|
-
const spacer = document.createElement("div");
|
|
491
|
-
const rect = node.getBoundingClientRect();
|
|
492
|
-
spacer.style.cssText = `display: inline-block; width: ${rect.width}px; height: ${rect.height}px; visibility: hidden;`;
|
|
493
|
-
return spacer;
|
|
528
|
+
if (!node) {
|
|
529
|
+
throw new Error("Invalid node: node is null or undefined");
|
|
494
530
|
}
|
|
495
|
-
|
|
496
|
-
|
|
531
|
+
try {
|
|
532
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
533
|
+
return node.cloneNode(true);
|
|
534
|
+
}
|
|
535
|
+
if (node.nodeType !== Node.ELEMENT_NODE) {
|
|
536
|
+
return node.cloneNode(true);
|
|
537
|
+
}
|
|
538
|
+
if (node.getAttribute("data-capture") === "exclude") {
|
|
539
|
+
const spacer = document.createElement("div");
|
|
540
|
+
const rect = node.getBoundingClientRect();
|
|
541
|
+
spacer.style.cssText = `display: inline-block; width: ${rect.width}px; height: ${rect.height}px; visibility: hidden;`;
|
|
542
|
+
return spacer;
|
|
543
|
+
}
|
|
544
|
+
if (options.exclude && Array.isArray(options.exclude)) {
|
|
545
|
+
for (const selector of options.exclude) {
|
|
546
|
+
try {
|
|
547
|
+
if ((_a = node.matches) == null ? void 0 : _a.call(node, selector)) {
|
|
548
|
+
const spacer = document.createElement("div");
|
|
549
|
+
const rect = node.getBoundingClientRect();
|
|
550
|
+
spacer.style.cssText = `display: inline-block; width: ${rect.width}px; height: ${rect.height}px; visibility: hidden;`;
|
|
551
|
+
return spacer;
|
|
552
|
+
}
|
|
553
|
+
} catch (err) {
|
|
554
|
+
console.warn(`Invalid selector in exclude option: ${selector}`, err);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
if (typeof options.filter === "function") {
|
|
497
559
|
try {
|
|
498
|
-
if ((
|
|
560
|
+
if (!options.filter(node, originalRoot || node)) {
|
|
499
561
|
const spacer = document.createElement("div");
|
|
500
562
|
const rect = node.getBoundingClientRect();
|
|
501
563
|
spacer.style.cssText = `display: inline-block; width: ${rect.width}px; height: ${rect.height}px; visibility: hidden;`;
|
|
502
564
|
return spacer;
|
|
503
565
|
}
|
|
504
566
|
} catch (err) {
|
|
505
|
-
console.warn(
|
|
567
|
+
console.warn("Error in filter function:", err);
|
|
506
568
|
}
|
|
507
569
|
}
|
|
508
|
-
|
|
509
|
-
|
|
570
|
+
if (node.tagName === "IFRAME") {
|
|
571
|
+
const fallback = document.createElement("div");
|
|
572
|
+
fallback.textContent = "";
|
|
573
|
+
fallback.style.cssText = `width: ${node.offsetWidth}px; height: ${node.offsetHeight}px; background-image: repeating-linear-gradient(45deg, #ddd, #ddd 5px, #f9f9f9 5px, #f9f9f9 10px);display: flex;align-items: center;justify-content: center;font-size: 12px;color: #555; border: 1px solid #aaa;`;
|
|
574
|
+
return fallback;
|
|
575
|
+
}
|
|
576
|
+
if (node.getAttribute("data-capture") === "placeholder") {
|
|
577
|
+
const clone2 = node.cloneNode(false);
|
|
578
|
+
cache.preNodeMap.set(clone2, node);
|
|
579
|
+
inlineAllStyles(node, clone2, compress);
|
|
580
|
+
const placeholder = document.createElement("div");
|
|
581
|
+
placeholder.textContent = node.getAttribute("data-placeholder-text") || "";
|
|
582
|
+
placeholder.style.cssText = `color: #666;font-size: 12px;text-align: center;line-height: 1.4;padding: 0.5em;box-sizing: border-box;`;
|
|
583
|
+
clone2.appendChild(placeholder);
|
|
584
|
+
return clone2;
|
|
585
|
+
}
|
|
586
|
+
if (node.tagName === "CANVAS") {
|
|
587
|
+
const dataURL = node.toDataURL();
|
|
588
|
+
const img = document.createElement("img");
|
|
589
|
+
img.src = dataURL;
|
|
590
|
+
img.width = node.width;
|
|
591
|
+
img.height = node.height;
|
|
592
|
+
img.style.display = "inline-block";
|
|
593
|
+
img.style.width = node.style.width || `${node.width}px`;
|
|
594
|
+
img.style.height = node.style.height || `${node.height}px`;
|
|
595
|
+
return img;
|
|
596
|
+
}
|
|
597
|
+
let clone;
|
|
510
598
|
try {
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
spacer.style.cssText = `display: inline-block; width: ${rect.width}px; height: ${rect.height}px; visibility: hidden;`;
|
|
515
|
-
return spacer;
|
|
599
|
+
clone = node.cloneNode(false);
|
|
600
|
+
if (!clone) {
|
|
601
|
+
throw new Error("Failed to clone node: cloneNode returned null");
|
|
516
602
|
}
|
|
603
|
+
cache.preNodeMap.set(clone, node);
|
|
517
604
|
} catch (err) {
|
|
518
|
-
console.
|
|
519
|
-
|
|
520
|
-
}
|
|
521
|
-
if (node.tagName === "IFRAME") {
|
|
522
|
-
const fallback = document.createElement("div");
|
|
523
|
-
fallback.textContent = "";
|
|
524
|
-
fallback.style.cssText = `width: ${node.offsetWidth}px; height: ${node.offsetHeight}px; background-image: repeating-linear-gradient(45deg, #ddd, #ddd 5px, #f9f9f9 5px, #f9f9f9 10px);display: flex;align-items: center;justify-content: center;font-size: 12px;color: #555; border: 1px solid #aaa;`;
|
|
525
|
-
return fallback;
|
|
526
|
-
}
|
|
527
|
-
if (node.getAttribute("data-capture") === "placeholder") {
|
|
528
|
-
const clone2 = node.cloneNode(false);
|
|
529
|
-
nodeMap.set(clone2, node);
|
|
530
|
-
inlineAllStyles(node, clone2, styleMap, styleCache, compress);
|
|
531
|
-
const placeholder = document.createElement("div");
|
|
532
|
-
placeholder.textContent = node.getAttribute("data-placeholder-text") || "";
|
|
533
|
-
placeholder.style.cssText = `color: #666;font-size: 12px;text-align: center;line-height: 1.4;padding: 0.5em;box-sizing: border-box;`;
|
|
534
|
-
clone2.appendChild(placeholder);
|
|
535
|
-
return clone2;
|
|
536
|
-
}
|
|
537
|
-
if (node.tagName === "CANVAS") {
|
|
538
|
-
const dataURL = node.toDataURL();
|
|
539
|
-
const img = document.createElement("img");
|
|
540
|
-
img.src = dataURL;
|
|
541
|
-
img.width = node.width;
|
|
542
|
-
img.height = node.height;
|
|
543
|
-
img.style.display = "inline-block";
|
|
544
|
-
img.style.width = node.style.width || `${node.width}px`;
|
|
545
|
-
img.style.height = node.style.height || `${node.height}px`;
|
|
546
|
-
return img;
|
|
547
|
-
}
|
|
548
|
-
const clone = node.cloneNode(false);
|
|
549
|
-
nodeMap.set(clone, node);
|
|
550
|
-
if (node instanceof HTMLInputElement) {
|
|
551
|
-
clone.value = node.value;
|
|
552
|
-
clone.setAttribute("value", node.value);
|
|
553
|
-
if (node.checked !== void 0) {
|
|
554
|
-
clone.checked = node.checked;
|
|
555
|
-
if (node.checked) clone.setAttribute("checked", "");
|
|
605
|
+
console.error("[Snapdom] Failed to clone node:", node, err);
|
|
606
|
+
throw err;
|
|
556
607
|
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
clone.value = node.value;
|
|
564
|
-
Array.from(clone.options).forEach((opt) => {
|
|
565
|
-
if (opt.value === node.value) {
|
|
566
|
-
opt.setAttribute("selected", "");
|
|
567
|
-
} else {
|
|
568
|
-
opt.removeAttribute("selected");
|
|
608
|
+
if (node instanceof HTMLInputElement) {
|
|
609
|
+
clone.value = node.value;
|
|
610
|
+
clone.setAttribute("value", node.value);
|
|
611
|
+
if (node.checked !== void 0) {
|
|
612
|
+
clone.checked = node.checked;
|
|
613
|
+
if (node.checked) clone.setAttribute("checked", "");
|
|
569
614
|
}
|
|
570
|
-
})
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
const baseChildren = node.shadowRoot ? node.shadowRoot.childNodes : node.childNodes;
|
|
585
|
-
for (const child of baseChildren) {
|
|
586
|
-
const clonedChild = deepClone(child, styleMap, styleCache, nodeMap, compress, options, originalRoot || node);
|
|
587
|
-
if (clonedChild) clone.appendChild(clonedChild);
|
|
615
|
+
} else if (node instanceof HTMLTextAreaElement) {
|
|
616
|
+
const rect = node.getBoundingClientRect();
|
|
617
|
+
clone.textContent = node.value;
|
|
618
|
+
clone.style.width = `${rect.width}px`;
|
|
619
|
+
clone.style.height = `${rect.height}px`;
|
|
620
|
+
} else if (node instanceof HTMLSelectElement) {
|
|
621
|
+
clone.value = node.value;
|
|
622
|
+
Array.from(clone.options).forEach((opt) => {
|
|
623
|
+
if (opt.value === node.value) {
|
|
624
|
+
opt.setAttribute("selected", "");
|
|
625
|
+
} else {
|
|
626
|
+
opt.removeAttribute("selected");
|
|
627
|
+
}
|
|
628
|
+
});
|
|
588
629
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
const
|
|
593
|
-
|
|
630
|
+
inlineAllStyles(node, clone, compress);
|
|
631
|
+
try {
|
|
632
|
+
if (isSlotElement(node)) {
|
|
633
|
+
const assigned = ((_b = node.assignedNodes) == null ? void 0 : _b.call(node, { flatten: true })) || [];
|
|
634
|
+
const nodesToClone = assigned.length > 0 ? assigned : Array.from(node.childNodes);
|
|
635
|
+
const fragment = document.createDocumentFragment();
|
|
636
|
+
for (const child of nodesToClone) {
|
|
637
|
+
try {
|
|
638
|
+
const clonedChild = deepClone(child, compress, options, originalRoot || node);
|
|
639
|
+
if (clonedChild) fragment.appendChild(clonedChild);
|
|
640
|
+
} catch (err) {
|
|
641
|
+
console.warn("[Snapdom] Failed to clone slot content:", child, err);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
return fragment;
|
|
645
|
+
} else {
|
|
646
|
+
const baseChildren = node.shadowRoot ? node.shadowRoot.childNodes : node.childNodes;
|
|
647
|
+
for (const child of baseChildren) {
|
|
648
|
+
try {
|
|
649
|
+
const clonedChild = deepClone(child, compress, options, originalRoot || node);
|
|
650
|
+
if (clonedChild) clone.appendChild(clonedChild);
|
|
651
|
+
} catch (err) {
|
|
652
|
+
console.warn("[Snapdom] Failed to clone child node:", child, err);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
if (node.shadowRoot && node.childNodes.length > 0 && !node.shadowRoot.querySelector("slot")) {
|
|
656
|
+
const lightDomContent = document.createDocumentFragment();
|
|
657
|
+
for (const child of node.childNodes) {
|
|
658
|
+
try {
|
|
659
|
+
const clonedChild = deepClone(child, compress, options, originalRoot || node);
|
|
660
|
+
if (clonedChild) lightDomContent.appendChild(clonedChild);
|
|
661
|
+
} catch (err) {
|
|
662
|
+
console.warn("[Snapdom] Failed to clone light DOM child:", child, err);
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
clone.appendChild(lightDomContent);
|
|
666
|
+
}
|
|
594
667
|
}
|
|
595
|
-
|
|
668
|
+
} catch (err) {
|
|
669
|
+
console.error("[Snapdom] Error cloning children:", err);
|
|
670
|
+
throw err;
|
|
596
671
|
}
|
|
672
|
+
return clone;
|
|
673
|
+
} catch (error) {
|
|
674
|
+
console.error("[Snapdom] Error in deepClone:", error);
|
|
675
|
+
throw error;
|
|
597
676
|
}
|
|
598
|
-
return clone;
|
|
599
677
|
}
|
|
678
|
+
var init_clone = __esm({
|
|
679
|
+
"src/core/clone.js"() {
|
|
680
|
+
init_styles();
|
|
681
|
+
init_cache();
|
|
682
|
+
}
|
|
683
|
+
});
|
|
600
684
|
|
|
601
685
|
// src/modules/iconFonts.js
|
|
602
|
-
var defaultIconFonts = [
|
|
603
|
-
// /uicons/i,
|
|
604
|
-
/font\s*awesome/i,
|
|
605
|
-
/material\s*icons/i,
|
|
606
|
-
/ionicons/i,
|
|
607
|
-
/glyphicons/i,
|
|
608
|
-
/feather/i,
|
|
609
|
-
/bootstrap\s*icons/i,
|
|
610
|
-
/remix\s*icons/i,
|
|
611
|
-
/heroicons/i,
|
|
612
|
-
/layui/i,
|
|
613
|
-
/lucide/i
|
|
614
|
-
];
|
|
615
|
-
var userIconFonts = [];
|
|
616
686
|
function extendIconFonts(fonts) {
|
|
617
687
|
const list = Array.isArray(fonts) ? fonts : [fonts];
|
|
618
688
|
for (const f of list) {
|
|
@@ -634,6 +704,25 @@
|
|
|
634
704
|
if (/icon/i.test(text) || /glyph/i.test(text) || /symbols/i.test(text) || /feather/i.test(text) || /fontawesome/i.test(text)) return true;
|
|
635
705
|
return false;
|
|
636
706
|
}
|
|
707
|
+
var defaultIconFonts, userIconFonts;
|
|
708
|
+
var init_iconFonts = __esm({
|
|
709
|
+
"src/modules/iconFonts.js"() {
|
|
710
|
+
defaultIconFonts = [
|
|
711
|
+
// /uicons/i,
|
|
712
|
+
/font\s*awesome/i,
|
|
713
|
+
/material\s*icons/i,
|
|
714
|
+
/ionicons/i,
|
|
715
|
+
/glyphicons/i,
|
|
716
|
+
/feather/i,
|
|
717
|
+
/bootstrap\s*icons/i,
|
|
718
|
+
/remix\s*icons/i,
|
|
719
|
+
/heroicons/i,
|
|
720
|
+
/layui/i,
|
|
721
|
+
/lucide/i
|
|
722
|
+
];
|
|
723
|
+
userIconFonts = [];
|
|
724
|
+
}
|
|
725
|
+
});
|
|
637
726
|
|
|
638
727
|
// src/modules/fonts.js
|
|
639
728
|
function iconToImage(unicodeChar, fontFamily, fontWeight, fontSize = 32, color = "#000") {
|
|
@@ -678,14 +767,14 @@
|
|
|
678
767
|
}
|
|
679
768
|
function embedCustomFonts() {
|
|
680
769
|
return __async(this, arguments, function* ({ preCached = false } = {}) {
|
|
681
|
-
if (
|
|
770
|
+
if (cache.resource.has("fonts-embed-css")) {
|
|
682
771
|
if (preCached) {
|
|
683
772
|
const style = document.createElement("style");
|
|
684
773
|
style.setAttribute("data-snapdom", "embedFonts");
|
|
685
|
-
style.textContent =
|
|
774
|
+
style.textContent = cache.resource.get("fonts-embed-css");
|
|
686
775
|
document.head.appendChild(style);
|
|
687
776
|
}
|
|
688
|
-
return
|
|
777
|
+
return cache.resource.get("fonts-embed-css");
|
|
689
778
|
}
|
|
690
779
|
const importRegex = /@import\s+url\(["']?([^"')]+)["']?\)/g;
|
|
691
780
|
const styleImports = [];
|
|
@@ -718,11 +807,11 @@
|
|
|
718
807
|
url = new URL(url, link.href).href;
|
|
719
808
|
}
|
|
720
809
|
if (isIconFont(url)) return null;
|
|
721
|
-
if (
|
|
722
|
-
|
|
723
|
-
return { original: match[0], inlined: `url(${
|
|
810
|
+
if (cache.resource.has(url)) {
|
|
811
|
+
cache.font.add(url);
|
|
812
|
+
return { original: match[0], inlined: `url(${cache.resource.get(url)})` };
|
|
724
813
|
}
|
|
725
|
-
if (
|
|
814
|
+
if (cache.font.has(url)) return null;
|
|
726
815
|
try {
|
|
727
816
|
const fontRes = yield fetch(url);
|
|
728
817
|
const blob = yield fontRes.blob();
|
|
@@ -731,8 +820,8 @@
|
|
|
731
820
|
reader.onload = () => resolve(reader.result);
|
|
732
821
|
reader.readAsDataURL(blob);
|
|
733
822
|
});
|
|
734
|
-
|
|
735
|
-
|
|
823
|
+
cache.resource.set(url, b64);
|
|
824
|
+
cache.font.add(url);
|
|
736
825
|
return { original: match[0], inlined: `url(${b64})` };
|
|
737
826
|
} catch (e) {
|
|
738
827
|
console.warn("[snapdom] Failed to fetch font resource:", url);
|
|
@@ -768,12 +857,12 @@
|
|
|
768
857
|
url = new URL(url, sheet.href || location.href).href;
|
|
769
858
|
}
|
|
770
859
|
if (isIconFont(url)) continue;
|
|
771
|
-
if (
|
|
772
|
-
|
|
773
|
-
inlinedSrc = inlinedSrc.replace(match[0], `url(${
|
|
860
|
+
if (cache.resource.has(url)) {
|
|
861
|
+
cache.font.add(url);
|
|
862
|
+
inlinedSrc = inlinedSrc.replace(match[0], `url(${cache.resource.get(url)})`);
|
|
774
863
|
continue;
|
|
775
864
|
}
|
|
776
|
-
if (
|
|
865
|
+
if (cache.font.has(url)) continue;
|
|
777
866
|
try {
|
|
778
867
|
const res = yield fetch(url);
|
|
779
868
|
const blob = yield res.blob();
|
|
@@ -782,8 +871,8 @@
|
|
|
782
871
|
reader.onload = () => resolve(reader.result);
|
|
783
872
|
reader.readAsDataURL(blob);
|
|
784
873
|
});
|
|
785
|
-
|
|
786
|
-
|
|
874
|
+
cache.resource.set(url, b64);
|
|
875
|
+
cache.font.add(url);
|
|
787
876
|
inlinedSrc = inlinedSrc.replace(match[0], `url(${b64})`);
|
|
788
877
|
} catch (e) {
|
|
789
878
|
console.warn("[snapdom] Failed to fetch font URL:", url);
|
|
@@ -808,10 +897,10 @@
|
|
|
808
897
|
if (isIconFont(font.family)) continue;
|
|
809
898
|
let b64 = font._snapdomSrc;
|
|
810
899
|
if (!b64.startsWith("data:")) {
|
|
811
|
-
if (
|
|
812
|
-
b64 =
|
|
813
|
-
|
|
814
|
-
} else if (!
|
|
900
|
+
if (cache.resource.has(font._snapdomSrc)) {
|
|
901
|
+
b64 = cache.resource.get(font._snapdomSrc);
|
|
902
|
+
cache.font.add(font._snapdomSrc);
|
|
903
|
+
} else if (!cache.font.has(font._snapdomSrc)) {
|
|
815
904
|
try {
|
|
816
905
|
const res = yield fetch(font._snapdomSrc);
|
|
817
906
|
const blob = yield res.blob();
|
|
@@ -820,8 +909,8 @@
|
|
|
820
909
|
reader.onload = () => resolve(reader.result);
|
|
821
910
|
reader.readAsDataURL(blob);
|
|
822
911
|
});
|
|
823
|
-
|
|
824
|
-
|
|
912
|
+
cache.resource.set(font._snapdomSrc, b64);
|
|
913
|
+
cache.font.add(font._snapdomSrc);
|
|
825
914
|
} catch (e) {
|
|
826
915
|
console.warn("[snapdom] Failed to fetch dynamic font src:", font._snapdomSrc);
|
|
827
916
|
continue;
|
|
@@ -838,7 +927,7 @@
|
|
|
838
927
|
}
|
|
839
928
|
}
|
|
840
929
|
if (finalCSS) {
|
|
841
|
-
|
|
930
|
+
cache.resource.set("fonts-embed-css", finalCSS);
|
|
842
931
|
if (preCached) {
|
|
843
932
|
const style = document.createElement("style");
|
|
844
933
|
style.setAttribute("data-snapdom", "embedFonts");
|
|
@@ -849,9 +938,16 @@
|
|
|
849
938
|
return finalCSS;
|
|
850
939
|
});
|
|
851
940
|
}
|
|
941
|
+
var init_fonts = __esm({
|
|
942
|
+
"src/modules/fonts.js"() {
|
|
943
|
+
init_helpers();
|
|
944
|
+
init_cache();
|
|
945
|
+
init_iconFonts();
|
|
946
|
+
}
|
|
947
|
+
});
|
|
852
948
|
|
|
853
949
|
// src/modules/pseudo.js
|
|
854
|
-
function inlinePseudoElements(source, clone,
|
|
950
|
+
function inlinePseudoElements(source, clone, compress, embedFonts = false, useProxy) {
|
|
855
951
|
return __async(this, null, function* () {
|
|
856
952
|
if (!(source instanceof Element) || !(clone instanceof Element)) return;
|
|
857
953
|
for (const pseudo of ["::before", "::after", "::first-letter"]) {
|
|
@@ -876,7 +972,7 @@
|
|
|
876
972
|
span.dataset.snapdomPseudo = "::first-letter";
|
|
877
973
|
const snapshot = snapshotComputedStyle(style);
|
|
878
974
|
const key = getStyleKey(snapshot, "span", compress);
|
|
879
|
-
|
|
975
|
+
cache.preStyleMap.set(span, key);
|
|
880
976
|
const restNode = document.createTextNode(rest);
|
|
881
977
|
clone.replaceChild(restNode, textNode);
|
|
882
978
|
clone.insertBefore(span, restNode);
|
|
@@ -897,7 +993,7 @@
|
|
|
897
993
|
pseudoEl.dataset.snapdomPseudo = pseudo;
|
|
898
994
|
const snapshot = snapshotComputedStyle(style);
|
|
899
995
|
const key = getStyleKey(snapshot, "span", compress);
|
|
900
|
-
|
|
996
|
+
cache.preStyleMap.set(pseudoEl, key);
|
|
901
997
|
const isIconFont2 = isIconFont(fontFamily);
|
|
902
998
|
const cleanContent = parseContent(content);
|
|
903
999
|
if (isIconFont2 && cleanContent.length === 1) {
|
|
@@ -948,8 +1044,6 @@
|
|
|
948
1044
|
yield inlinePseudoElements(
|
|
949
1045
|
sChildren[i],
|
|
950
1046
|
cChildren[i],
|
|
951
|
-
styleMap,
|
|
952
|
-
styleCache,
|
|
953
1047
|
compress,
|
|
954
1048
|
embedFonts,
|
|
955
1049
|
useProxy
|
|
@@ -957,6 +1051,15 @@
|
|
|
957
1051
|
}
|
|
958
1052
|
});
|
|
959
1053
|
}
|
|
1054
|
+
var init_pseudo = __esm({
|
|
1055
|
+
"src/modules/pseudo.js"() {
|
|
1056
|
+
init_helpers();
|
|
1057
|
+
init_cssTools();
|
|
1058
|
+
init_fonts();
|
|
1059
|
+
init_iconFonts();
|
|
1060
|
+
init_cache();
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
960
1063
|
|
|
961
1064
|
// src/modules/svgDefs.js
|
|
962
1065
|
function inlineExternalDef(root) {
|
|
@@ -987,23 +1090,25 @@
|
|
|
987
1090
|
}
|
|
988
1091
|
});
|
|
989
1092
|
}
|
|
1093
|
+
var init_svgDefs = __esm({
|
|
1094
|
+
"src/modules/svgDefs.js"() {
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
990
1097
|
|
|
991
1098
|
// src/core/prepare.js
|
|
992
1099
|
function prepareClone(_0) {
|
|
993
1100
|
return __async(this, arguments, function* (element, compress = false, embedFonts = false, options = {}) {
|
|
994
1101
|
var _a;
|
|
995
|
-
const styleMap = /* @__PURE__ */ new Map();
|
|
996
|
-
const styleCache = /* @__PURE__ */ new WeakMap();
|
|
997
|
-
const nodeMap = /* @__PURE__ */ new Map();
|
|
998
1102
|
let clone;
|
|
1103
|
+
let classCSS = "";
|
|
999
1104
|
try {
|
|
1000
|
-
clone = deepClone(element,
|
|
1105
|
+
clone = deepClone(element, compress, options, element);
|
|
1001
1106
|
} catch (e) {
|
|
1002
1107
|
console.warn("deepClone failed:", e);
|
|
1003
1108
|
throw e;
|
|
1004
1109
|
}
|
|
1005
1110
|
try {
|
|
1006
|
-
yield inlinePseudoElements(element, clone,
|
|
1111
|
+
yield inlinePseudoElements(element, clone, compress, embedFonts, options.useProxy);
|
|
1007
1112
|
} catch (e) {
|
|
1008
1113
|
console.warn("inlinePseudoElements failed:", e);
|
|
1009
1114
|
}
|
|
@@ -1012,11 +1117,10 @@
|
|
|
1012
1117
|
} catch (e) {
|
|
1013
1118
|
console.warn("inlineExternalDef failed:", e);
|
|
1014
1119
|
}
|
|
1015
|
-
let classCSS = "";
|
|
1016
1120
|
if (compress) {
|
|
1017
|
-
const keyToClass = generateCSSClasses(
|
|
1121
|
+
const keyToClass = generateCSSClasses();
|
|
1018
1122
|
classCSS = Array.from(keyToClass.entries()).map(([key, className]) => `.${className}{${key}}`).join("");
|
|
1019
|
-
for (const [node, key] of
|
|
1123
|
+
for (const [node, key] of cache.preStyleMap.entries()) {
|
|
1020
1124
|
if (node.tagName === "STYLE") continue;
|
|
1021
1125
|
const className = keyToClass.get(key);
|
|
1022
1126
|
if (className) node.classList.add(className);
|
|
@@ -1025,12 +1129,12 @@
|
|
|
1025
1129
|
if (bgImage && bgImage !== "none") node.style.backgroundImage = bgImage;
|
|
1026
1130
|
}
|
|
1027
1131
|
} else {
|
|
1028
|
-
for (const [node, key] of
|
|
1132
|
+
for (const [node, key] of cache.preStyleMap.entries()) {
|
|
1029
1133
|
if (node.tagName === "STYLE") continue;
|
|
1030
1134
|
node.setAttribute("style", key.replace(/;/g, "; "));
|
|
1031
1135
|
}
|
|
1032
1136
|
}
|
|
1033
|
-
for (const [cloneNode, originalNode] of
|
|
1137
|
+
for (const [cloneNode, originalNode] of cache.preNodeMap.entries()) {
|
|
1034
1138
|
const scrollX = originalNode.scrollLeft;
|
|
1035
1139
|
const scrollY = originalNode.scrollTop;
|
|
1036
1140
|
const hasScroll = scrollX || scrollY;
|
|
@@ -1049,9 +1153,9 @@
|
|
|
1049
1153
|
cloneNode.appendChild(inner);
|
|
1050
1154
|
}
|
|
1051
1155
|
}
|
|
1052
|
-
if (element ===
|
|
1053
|
-
const computed =
|
|
1054
|
-
|
|
1156
|
+
if (element === cache.preNodeMap.get(clone)) {
|
|
1157
|
+
const computed = cache.preStyle.get(element) || window.getComputedStyle(element);
|
|
1158
|
+
cache.preStyle.set(element, computed);
|
|
1055
1159
|
const transform = stripTranslate(computed.transform);
|
|
1056
1160
|
clone.style.margin = "0";
|
|
1057
1161
|
clone.style.position = "static";
|
|
@@ -1064,15 +1168,25 @@
|
|
|
1064
1168
|
clone.style.clear = "none";
|
|
1065
1169
|
clone.style.transform = transform || "";
|
|
1066
1170
|
}
|
|
1067
|
-
for (const [cloneNode, originalNode] of
|
|
1171
|
+
for (const [cloneNode, originalNode] of cache.preNodeMap.entries()) {
|
|
1068
1172
|
if (originalNode.tagName === "PRE") {
|
|
1069
1173
|
cloneNode.style.marginTop = "0";
|
|
1070
1174
|
cloneNode.style.marginBlockStart = "0";
|
|
1071
1175
|
}
|
|
1072
1176
|
}
|
|
1073
|
-
return { clone, classCSS
|
|
1177
|
+
return { clone, classCSS };
|
|
1074
1178
|
});
|
|
1075
1179
|
}
|
|
1180
|
+
var init_prepare = __esm({
|
|
1181
|
+
"src/core/prepare.js"() {
|
|
1182
|
+
init_cssTools();
|
|
1183
|
+
init_helpers();
|
|
1184
|
+
init_clone();
|
|
1185
|
+
init_pseudo();
|
|
1186
|
+
init_svgDefs();
|
|
1187
|
+
init_cache();
|
|
1188
|
+
}
|
|
1189
|
+
});
|
|
1076
1190
|
|
|
1077
1191
|
// src/modules/images.js
|
|
1078
1192
|
function inlineImages(_0) {
|
|
@@ -1098,10 +1212,15 @@
|
|
|
1098
1212
|
}
|
|
1099
1213
|
});
|
|
1100
1214
|
}
|
|
1215
|
+
var init_images = __esm({
|
|
1216
|
+
"src/modules/images.js"() {
|
|
1217
|
+
init_helpers();
|
|
1218
|
+
}
|
|
1219
|
+
});
|
|
1101
1220
|
|
|
1102
1221
|
// src/modules/background.js
|
|
1103
|
-
function inlineBackgroundImages(_0, _1
|
|
1104
|
-
return __async(this, arguments, function* (source, clone,
|
|
1222
|
+
function inlineBackgroundImages(_0, _1) {
|
|
1223
|
+
return __async(this, arguments, function* (source, clone, options = {}) {
|
|
1105
1224
|
const queue = [[source, clone]];
|
|
1106
1225
|
const imageProps = [
|
|
1107
1226
|
"background-image",
|
|
@@ -1115,8 +1234,8 @@
|
|
|
1115
1234
|
];
|
|
1116
1235
|
while (queue.length) {
|
|
1117
1236
|
const [srcNode, cloneNode] = queue.shift();
|
|
1118
|
-
const style =
|
|
1119
|
-
if (!
|
|
1237
|
+
const style = cache.preStyle.get(srcNode) || getStyle(srcNode);
|
|
1238
|
+
if (!cache.preStyle.has(srcNode)) cache.preStyle.set(srcNode, style);
|
|
1120
1239
|
for (const prop of imageProps) {
|
|
1121
1240
|
const val = style.getPropertyValue(prop);
|
|
1122
1241
|
if (!val || val === "none") continue;
|
|
@@ -1140,18 +1259,25 @@
|
|
|
1140
1259
|
}
|
|
1141
1260
|
});
|
|
1142
1261
|
}
|
|
1262
|
+
var init_background = __esm({
|
|
1263
|
+
"src/modules/background.js"() {
|
|
1264
|
+
init_helpers();
|
|
1265
|
+
init_cache();
|
|
1266
|
+
}
|
|
1267
|
+
});
|
|
1143
1268
|
|
|
1144
1269
|
// src/core/capture.js
|
|
1145
1270
|
function captureDOM(_0) {
|
|
1146
1271
|
return __async(this, arguments, function* (element, options = {}) {
|
|
1147
1272
|
if (!element) throw new Error("Element cannot be null or undefined");
|
|
1273
|
+
cache.reset();
|
|
1148
1274
|
const { compress = true, embedFonts = false, fast = true, scale = 1, useProxy = "" } = options;
|
|
1149
|
-
let clone, classCSS
|
|
1275
|
+
let clone, classCSS;
|
|
1150
1276
|
let fontsCSS = "";
|
|
1151
1277
|
let baseCSS = "";
|
|
1152
1278
|
let dataURL;
|
|
1153
1279
|
let svgString;
|
|
1154
|
-
({ clone, classCSS
|
|
1280
|
+
({ clone, classCSS } = yield prepareClone(element, compress, embedFonts, options));
|
|
1155
1281
|
yield new Promise((resolve) => {
|
|
1156
1282
|
idle(() => __async(null, null, function* () {
|
|
1157
1283
|
yield inlineImages(clone, options);
|
|
@@ -1160,7 +1286,7 @@
|
|
|
1160
1286
|
});
|
|
1161
1287
|
yield new Promise((resolve) => {
|
|
1162
1288
|
idle(() => __async(null, null, function* () {
|
|
1163
|
-
yield inlineBackgroundImages(element, clone,
|
|
1289
|
+
yield inlineBackgroundImages(element, clone, options);
|
|
1164
1290
|
resolve();
|
|
1165
1291
|
}), { fast });
|
|
1166
1292
|
});
|
|
@@ -1175,13 +1301,13 @@
|
|
|
1175
1301
|
if (compress) {
|
|
1176
1302
|
const usedTags = collectUsedTagNames(clone).sort();
|
|
1177
1303
|
const tagKey = usedTags.join(",");
|
|
1178
|
-
if (
|
|
1179
|
-
baseCSS =
|
|
1304
|
+
if (cache.baseStyle.has(tagKey)) {
|
|
1305
|
+
baseCSS = cache.baseStyle.get(tagKey);
|
|
1180
1306
|
} else {
|
|
1181
1307
|
yield new Promise((resolve) => {
|
|
1182
1308
|
idle(() => {
|
|
1183
1309
|
baseCSS = generateDedupedBaseCSS(usedTags);
|
|
1184
|
-
|
|
1310
|
+
cache.baseStyle.set(tagKey, baseCSS);
|
|
1185
1311
|
resolve();
|
|
1186
1312
|
}, { fast });
|
|
1187
1313
|
});
|
|
@@ -1245,6 +1371,17 @@
|
|
|
1245
1371
|
return dataURL;
|
|
1246
1372
|
});
|
|
1247
1373
|
}
|
|
1374
|
+
var init_capture = __esm({
|
|
1375
|
+
"src/core/capture.js"() {
|
|
1376
|
+
init_prepare();
|
|
1377
|
+
init_images();
|
|
1378
|
+
init_background();
|
|
1379
|
+
init_helpers();
|
|
1380
|
+
init_cssTools();
|
|
1381
|
+
init_fonts();
|
|
1382
|
+
init_cache();
|
|
1383
|
+
}
|
|
1384
|
+
});
|
|
1248
1385
|
|
|
1249
1386
|
// src/api/snapdom.js
|
|
1250
1387
|
function toImg(_0, _1) {
|
|
@@ -1318,8 +1455,10 @@
|
|
|
1318
1455
|
});
|
|
1319
1456
|
}
|
|
1320
1457
|
function toRasterImg(_0, _1) {
|
|
1321
|
-
return __async(this, arguments, function* (url, { dpr = 1, scale = 1, backgroundColor
|
|
1322
|
-
const
|
|
1458
|
+
return __async(this, arguments, function* (url, { dpr = 1, scale = 1, backgroundColor, quality }, format = "png") {
|
|
1459
|
+
const defaultBg = ["jpg", "jpeg", "webp"].includes(format) ? "#fff" : void 0;
|
|
1460
|
+
const finalBg = backgroundColor != null ? backgroundColor : defaultBg;
|
|
1461
|
+
const canvas = yield createBackground(url, { dpr, scale }, finalBg);
|
|
1323
1462
|
const img = new Image();
|
|
1324
1463
|
img.src = canvas.toDataURL(`image/${format}`, quality);
|
|
1325
1464
|
yield img.decode();
|
|
@@ -1366,56 +1505,63 @@
|
|
|
1366
1505
|
return yield snapdom.capture(element, options);
|
|
1367
1506
|
});
|
|
1368
1507
|
}
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1508
|
+
var init_snapdom = __esm({
|
|
1509
|
+
"src/api/snapdom.js"() {
|
|
1510
|
+
init_capture();
|
|
1511
|
+
init_helpers();
|
|
1512
|
+
init_iconFonts();
|
|
1513
|
+
snapdom.capture = (_0, ..._1) => __async(null, [_0, ..._1], function* (el, options = {}) {
|
|
1514
|
+
const url = yield captureDOM(el, options);
|
|
1515
|
+
const dpr = window.devicePixelRatio || 1;
|
|
1516
|
+
const scale = options.scale || 1;
|
|
1517
|
+
return {
|
|
1518
|
+
url,
|
|
1519
|
+
options,
|
|
1520
|
+
toRaw: () => url,
|
|
1521
|
+
toImg: () => toImg(url, { dpr, scale }),
|
|
1522
|
+
toCanvas: () => toCanvas(url, { dpr, scale }),
|
|
1523
|
+
toBlob: (options2) => toBlob(url, __spreadValues({ dpr, scale }, options2)),
|
|
1524
|
+
toPng: (options2) => toRasterImg(url, __spreadValues({ dpr, scale }, options2), "png"),
|
|
1525
|
+
toJpg: (options2) => toRasterImg(url, __spreadValues({ dpr, scale }, options2), "jpeg"),
|
|
1526
|
+
toWebp: (options2) => toRasterImg(url, __spreadValues({ dpr, scale }, options2), "webp"),
|
|
1527
|
+
download: ({ format = "png", filename = "capture", backgroundColor } = {}) => download(url, { dpr, scale, backgroundColor, format, filename })
|
|
1528
|
+
};
|
|
1529
|
+
});
|
|
1530
|
+
snapdom.toRaw = (el, options) => __async(null, null, function* () {
|
|
1531
|
+
return (yield snapdom.capture(el, options)).toRaw();
|
|
1532
|
+
});
|
|
1533
|
+
snapdom.toImg = (el, options) => __async(null, null, function* () {
|
|
1534
|
+
return (yield snapdom.capture(el, options)).toImg();
|
|
1535
|
+
});
|
|
1536
|
+
snapdom.toCanvas = (el, options) => __async(null, null, function* () {
|
|
1537
|
+
return (yield snapdom.capture(el, options)).toCanvas();
|
|
1538
|
+
});
|
|
1539
|
+
snapdom.toBlob = (el, options) => __async(null, null, function* () {
|
|
1540
|
+
return (yield snapdom.capture(el, options)).toBlob(options);
|
|
1541
|
+
});
|
|
1542
|
+
snapdom.toPng = (el, options) => __async(null, null, function* () {
|
|
1543
|
+
return (yield snapdom.capture(el, options)).toPng(options);
|
|
1544
|
+
});
|
|
1545
|
+
snapdom.toJpg = (el, options) => __async(null, null, function* () {
|
|
1546
|
+
return (yield snapdom.capture(el, options)).toJpg(options);
|
|
1547
|
+
});
|
|
1548
|
+
snapdom.toWebp = (el, options) => __async(null, null, function* () {
|
|
1549
|
+
return (yield snapdom.capture(el, options)).toWebp(options);
|
|
1550
|
+
});
|
|
1551
|
+
snapdom.download = (_0, ..._1) => __async(null, [_0, ..._1], function* (el, options = {}) {
|
|
1552
|
+
const _a = options, {
|
|
1553
|
+
format = "png",
|
|
1554
|
+
filename = "capture",
|
|
1555
|
+
backgroundColor
|
|
1556
|
+
} = _a, rest = __objRest(_a, [
|
|
1557
|
+
"format",
|
|
1558
|
+
"filename",
|
|
1559
|
+
"backgroundColor"
|
|
1560
|
+
]);
|
|
1561
|
+
const capture = yield snapdom.capture(el, rest);
|
|
1562
|
+
return yield capture.download({ format, filename, backgroundColor });
|
|
1563
|
+
});
|
|
1564
|
+
}
|
|
1419
1565
|
});
|
|
1420
1566
|
|
|
1421
1567
|
// src/api/preCache.js
|
|
@@ -1423,10 +1569,7 @@
|
|
|
1423
1569
|
return __async(this, arguments, function* (root = document, options = {}) {
|
|
1424
1570
|
const { embedFonts = true, reset = false } = options;
|
|
1425
1571
|
if (reset) {
|
|
1426
|
-
|
|
1427
|
-
bgCache.clear();
|
|
1428
|
-
resourceCache.clear();
|
|
1429
|
-
baseCSSCache.clear();
|
|
1572
|
+
cache.reset();
|
|
1430
1573
|
return;
|
|
1431
1574
|
}
|
|
1432
1575
|
yield document.fonts.ready;
|
|
@@ -1439,9 +1582,9 @@
|
|
|
1439
1582
|
const promises = [];
|
|
1440
1583
|
for (const img of imgEls) {
|
|
1441
1584
|
const src = img.src;
|
|
1442
|
-
if (!
|
|
1585
|
+
if (!cache.image.has(src)) {
|
|
1443
1586
|
promises.push(
|
|
1444
|
-
fetchImage(src, { useProxy: options.useProxy }).then((dataURL) =>
|
|
1587
|
+
fetchImage(src, { useProxy: options.useProxy }).then((dataURL) => cache.image.set(src, dataURL)).catch(() => {
|
|
1445
1588
|
})
|
|
1446
1589
|
);
|
|
1447
1590
|
}
|
|
@@ -1467,8 +1610,38 @@
|
|
|
1467
1610
|
yield Promise.all(promises);
|
|
1468
1611
|
});
|
|
1469
1612
|
}
|
|
1613
|
+
var init_preCache = __esm({
|
|
1614
|
+
"src/api/preCache.js"() {
|
|
1615
|
+
init_helpers();
|
|
1616
|
+
init_fonts();
|
|
1617
|
+
init_cssTools();
|
|
1618
|
+
init_cache();
|
|
1619
|
+
}
|
|
1620
|
+
});
|
|
1470
1621
|
|
|
1471
1622
|
// src/index.browser.js
|
|
1472
|
-
|
|
1473
|
-
|
|
1623
|
+
var require_index_browser = __commonJS({
|
|
1624
|
+
"src/index.browser.js"(exports, module) {
|
|
1625
|
+
init_snapdom();
|
|
1626
|
+
init_preCache();
|
|
1627
|
+
window.snapdom = snapdom;
|
|
1628
|
+
if (typeof window !== "undefined") {
|
|
1629
|
+
window.snapdom = snapdom;
|
|
1630
|
+
window.preCache = preCache;
|
|
1631
|
+
}
|
|
1632
|
+
if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
|
|
1633
|
+
module.exports = { snapdom, preCache };
|
|
1634
|
+
}
|
|
1635
|
+
if (typeof define === "function" && define.amd) {
|
|
1636
|
+
define([], function() {
|
|
1637
|
+
return { snapdom, preCache };
|
|
1638
|
+
});
|
|
1639
|
+
}
|
|
1640
|
+
if (typeof globalThis !== "undefined") {
|
|
1641
|
+
globalThis.snapdom = snapdom;
|
|
1642
|
+
globalThis.preCache = preCache;
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
});
|
|
1646
|
+
require_index_browser();
|
|
1474
1647
|
})();
|