@zumer/snapdom 1.9.3 → 1.9.6-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/dist/snapdom.js CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  /*
3
3
  * snapdom
4
- * v.1.9.3
4
+ * v.1.9.6-dev.0
5
5
  * Author Juan Martin Muda
6
6
  * License MIT
7
7
  **/
@@ -57,13 +57,29 @@
57
57
  };
58
58
 
59
59
  // src/core/cache.js
60
- var imageCache = /* @__PURE__ */ new Map();
61
- var bgCache = /* @__PURE__ */ new Map();
62
- var resourceCache = /* @__PURE__ */ new Map();
63
- var defaultStylesCache = /* @__PURE__ */ new Map();
64
- var baseCSSCache = /* @__PURE__ */ new Map();
65
- var computedStyleCache = /* @__PURE__ */ new WeakMap();
66
- var processedFontURLs = /* @__PURE__ */ new Set();
60
+ var cache = {
61
+ image: /* @__PURE__ */ new Map(),
62
+ background: /* @__PURE__ */ new Map(),
63
+ resource: /* @__PURE__ */ new Map(),
64
+ defaultStyle: /* @__PURE__ */ new Map(),
65
+ baseStyle: /* @__PURE__ */ new Map(),
66
+ computedStyle: /* @__PURE__ */ new WeakMap(),
67
+ font: /* @__PURE__ */ new Set(),
68
+ snapshot: /* @__PURE__ */ new WeakMap(),
69
+ snapshotKey: /* @__PURE__ */ new Map(),
70
+ preStyleMap: /* @__PURE__ */ new Map(),
71
+ preStyle: /* @__PURE__ */ new WeakMap(),
72
+ preNodeMap: /* @__PURE__ */ new Map(),
73
+ reset: resetCache
74
+ };
75
+ function resetCache() {
76
+ cache.computedStyle = /* @__PURE__ */ new WeakMap();
77
+ cache.snapshot = /* @__PURE__ */ new WeakMap();
78
+ cache.snapshotKey.clear();
79
+ cache.preStyleMap.clear();
80
+ cache.preStyle = /* @__PURE__ */ new WeakMap();
81
+ cache.preNodeMap.clear();
82
+ }
67
83
 
68
84
  // src/utils/cssTools.js
69
85
  var commonTags = [
@@ -111,13 +127,13 @@
111
127
  }
112
128
  }
113
129
  function getDefaultStyleForTag(tagName) {
114
- if (defaultStylesCache.has(tagName)) {
115
- return defaultStylesCache.get(tagName);
130
+ if (cache.defaultStyle.has(tagName)) {
131
+ return cache.defaultStyle.get(tagName);
116
132
  }
117
133
  const skipTags = /* @__PURE__ */ new Set(["script", "style", "meta", "link", "noscript", "template"]);
118
134
  if (skipTags.has(tagName)) {
119
135
  const empty = {};
120
- defaultStylesCache.set(tagName, empty);
136
+ cache.defaultStyle.set(tagName, empty);
121
137
  return empty;
122
138
  }
123
139
  let sandbox = document.getElementById("snapdom-sandbox");
@@ -141,7 +157,7 @@
141
157
  defaults[prop] = styles.getPropertyValue(prop);
142
158
  }
143
159
  sandbox.removeChild(el);
144
- defaultStylesCache.set(tagName, defaults);
160
+ cache.defaultStyle.set(tagName, defaults);
145
161
  return defaults;
146
162
  }
147
163
  function getStyleKey(snapshot, tagName, compress = false) {
@@ -177,7 +193,7 @@
177
193
  function generateDedupedBaseCSS(usedTagNames) {
178
194
  const groups = /* @__PURE__ */ new Map();
179
195
  for (let tagName of usedTagNames) {
180
- const styles = defaultStylesCache.get(tagName);
196
+ const styles = cache.defaultStyle.get(tagName);
181
197
  if (!styles) continue;
182
198
  const key = Object.entries(styles).map(([k, v]) => `${k}:${v};`).sort().join("");
183
199
  if (!groups.has(key)) {
@@ -192,8 +208,8 @@
192
208
  }
193
209
  return css;
194
210
  }
195
- function generateCSSClasses(styleMap) {
196
- const keySet = new Set(styleMap.values());
211
+ function generateCSSClasses() {
212
+ const keySet = new Set(cache.preStyleMap.values());
197
213
  const classMap = /* @__PURE__ */ new Map();
198
214
  let counter = 1;
199
215
  for (const key of keySet) {
@@ -205,17 +221,15 @@
205
221
  // src/utils/helpers.js
206
222
  function inlineSingleBackgroundEntry(_0) {
207
223
  return __async(this, arguments, function* (entry, options = {}) {
208
- const isUrl = entry.startsWith("url(");
224
+ const rawUrl = extractURL(entry);
209
225
  const isGradient = /^((repeating-)?(linear|radial|conic)-gradient)\(/i.test(entry);
210
- if (isUrl) {
211
- const rawUrl = extractURL(entry);
212
- if (!rawUrl) return entry;
226
+ if (rawUrl) {
213
227
  const encodedUrl = safeEncodeURI(rawUrl);
214
- if (bgCache.has(encodedUrl)) {
215
- return options.skipInline ? void 0 : `url(${bgCache.get(encodedUrl)})`;
228
+ if (cache.background.has(encodedUrl)) {
229
+ return options.skipInline ? void 0 : `url(${cache.background.get(encodedUrl)})`;
216
230
  } else {
217
231
  const dataUrl = yield fetchImage(encodedUrl, { useProxy: options.useProxy });
218
- bgCache.set(encodedUrl, dataUrl);
232
+ cache.background.set(encodedUrl, dataUrl);
219
233
  return options.skipInline ? void 0 : `url("${dataUrl}")`;
220
234
  }
221
235
  }
@@ -237,10 +251,10 @@
237
251
  if (!(el instanceof Element)) {
238
252
  return window.getComputedStyle(el, pseudo);
239
253
  }
240
- let map = computedStyleCache.get(el);
254
+ let map = cache.computedStyle.get(el);
241
255
  if (!map) {
242
256
  map = /* @__PURE__ */ new Map();
243
- computedStyleCache.set(el, map);
257
+ cache.computedStyle.set(el, map);
244
258
  }
245
259
  if (!map.has(pseudo)) {
246
260
  const st = window.getComputedStyle(el, pseudo);
@@ -316,13 +330,13 @@
316
330
  }
317
331
  const crossOriginValue = getCrossOriginMode(src);
318
332
  console.log(`[SnapDOM - fetchImage] Start loading image: ${src} with crossOrigin=${crossOriginValue}`);
319
- if (imageCache.has(src)) {
333
+ if (cache.image.has(src)) {
320
334
  console.log(`[SnapDOM - fetchImage] Cache hit for: ${src}`);
321
- return Promise.resolve(imageCache.get(src));
335
+ return Promise.resolve(cache.image.get(src));
322
336
  }
323
337
  const isDataURI = src.startsWith("data:image/");
324
338
  if (isDataURI) {
325
- imageCache.set(src, src);
339
+ cache.image.set(src, src);
326
340
  return Promise.resolve(src);
327
341
  }
328
342
  const isSVG = /\.svg(\?.*)?$/i.test(src);
@@ -335,7 +349,7 @@
335
349
  });
336
350
  const svgText = yield response.text();
337
351
  const encoded = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgText)}`;
338
- imageCache.set(src, encoded);
352
+ cache.image.set(src, encoded);
339
353
  return encoded;
340
354
  } catch (e) {
341
355
  return fetchWithFallback(src);
@@ -359,12 +373,12 @@
359
373
  const ctx = canvas.getContext("2d");
360
374
  ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
361
375
  const dataURL = canvas.toDataURL("image/png");
362
- imageCache.set(src, dataURL);
376
+ cache.image.set(src, dataURL);
363
377
  resolve(dataURL);
364
378
  } catch (e) {
365
379
  try {
366
380
  const fallbackDataURL = yield fetchWithFallback(src);
367
- imageCache.set(src, fallbackDataURL);
381
+ cache.image.set(src, fallbackDataURL);
368
382
  resolve(fallbackDataURL);
369
383
  } catch (e2) {
370
384
  reject(e2);
@@ -376,7 +390,7 @@
376
390
  console.error(`[SnapDOM - fetchImage] Image failed to load: ${src}`);
377
391
  try {
378
392
  const fallbackDataURL = yield fetchWithFallback(src);
379
- imageCache.set(src, fallbackDataURL);
393
+ cache.image.set(src, fallbackDataURL);
380
394
  resolve(fallbackDataURL);
381
395
  } catch (e) {
382
396
  reject(e);
@@ -440,8 +454,6 @@
440
454
  }
441
455
 
442
456
  // src/modules/styles.js
443
- var snapshotCache = /* @__PURE__ */ new WeakMap();
444
- var snapshotKeyCache = /* @__PURE__ */ new Map();
445
457
  function snapshotComputedStyleFull(style) {
446
458
  const result = {};
447
459
  for (let i = 0; i < style.length; i++) {
@@ -454,37 +466,36 @@
454
466
  }
455
467
  return result;
456
468
  }
457
- function inlineAllStyles(source, clone, styleMap, cache, compress) {
469
+ function inlineAllStyles(source, clone, compress) {
458
470
  var _a;
459
471
  if (source.tagName === "STYLE") return;
460
- if (!cache.has(source)) {
461
- cache.set(source, getStyle(source));
472
+ if (!cache.preStyle.has(source)) {
473
+ cache.preStyle.set(source, getStyle(source));
462
474
  }
463
- const style = cache.get(source);
464
- if (!snapshotCache.has(source)) {
475
+ const style = cache.preStyle.get(source);
476
+ if (!cache.snapshot.has(source)) {
465
477
  const snapshot2 = snapshotComputedStyleFull(style);
466
- snapshotCache.set(source, snapshot2);
478
+ cache.snapshot.set(source, snapshot2);
467
479
  }
468
- const snapshot = snapshotCache.get(source);
480
+ const snapshot = cache.snapshot.get(source);
469
481
  const hash = Object.entries(snapshot).sort(([a], [b]) => a.localeCompare(b)).map(([prop, val]) => `${prop}:${val}`).join(";");
470
- if (snapshotKeyCache.has(hash)) {
471
- styleMap.set(clone, snapshotKeyCache.get(hash));
482
+ if (cache.snapshotKey.has(hash)) {
483
+ cache.preStyleMap.set(clone, cache.snapshotKey.get(hash));
472
484
  return;
473
485
  }
474
486
  const tagName = ((_a = source.tagName) == null ? void 0 : _a.toLowerCase()) || "div";
475
487
  const key = getStyleKey(snapshot, tagName, compress);
476
- snapshotKeyCache.set(hash, key);
477
- styleMap.set(clone, key);
488
+ cache.snapshotKey.set(hash, key);
489
+ cache.preStyleMap.set(clone, key);
478
490
  }
479
491
 
480
492
  // src/core/clone.js
481
- function deepClone(node, styleMap, styleCache, nodeMap, compress, options = {}, originalRoot) {
482
- var _a;
493
+ function isSlotElement(node) {
494
+ return node.nodeType === Node.ELEMENT_NODE && node.tagName === "SLOT";
495
+ }
496
+ function deepClone(node, compress, options = {}, originalRoot) {
497
+ var _a, _b;
483
498
  if (node.nodeType === Node.TEXT_NODE) {
484
- if ((_a = node.parentElement) == null ? void 0 : _a.shadowRoot) {
485
- const tag = node.parentElement.tagName.toLowerCase();
486
- if (customElements.get(tag)) return null;
487
- }
488
499
  return node.cloneNode(true);
489
500
  }
490
501
  if (node.nodeType !== Node.ELEMENT_NODE) return node.cloneNode(true);
@@ -494,10 +505,10 @@
494
505
  spacer.style.cssText = `display: inline-block; width: ${rect.width}px; height: ${rect.height}px; visibility: hidden;`;
495
506
  return spacer;
496
507
  }
497
- if (options.exclude && Array.isArray(options.exclude) && options.exclude.length > 0) {
508
+ if (options.exclude && Array.isArray(options.exclude)) {
498
509
  for (const selector of options.exclude) {
499
510
  try {
500
- if (node.matches && node.matches(selector)) {
511
+ if ((_a = node.matches) == null ? void 0 : _a.call(node, selector)) {
501
512
  const spacer = document.createElement("div");
502
513
  const rect = node.getBoundingClientRect();
503
514
  spacer.style.cssText = `display: inline-block; width: ${rect.width}px; height: ${rect.height}px; visibility: hidden;`;
@@ -528,8 +539,8 @@
528
539
  }
529
540
  if (node.getAttribute("data-capture") === "placeholder") {
530
541
  const clone2 = node.cloneNode(false);
531
- nodeMap.set(clone2, node);
532
- inlineAllStyles(node, clone2, styleMap, styleCache, compress);
542
+ cache.preNodeMap.set(clone2, node);
543
+ inlineAllStyles(node, clone2, compress);
533
544
  const placeholder = document.createElement("div");
534
545
  placeholder.textContent = node.getAttribute("data-placeholder-text") || "";
535
546
  placeholder.style.cssText = `color: #666;font-size: 12px;text-align: center;line-height: 1.4;padding: 0.5em;box-sizing: border-box;`;
@@ -548,7 +559,7 @@
548
559
  return img;
549
560
  }
550
561
  const clone = node.cloneNode(false);
551
- nodeMap.set(clone, node);
562
+ cache.preNodeMap.set(clone, node);
552
563
  if (node instanceof HTMLInputElement) {
553
564
  clone.value = node.value;
554
565
  clone.setAttribute("value", node.value);
@@ -557,8 +568,10 @@
557
568
  if (node.checked) clone.setAttribute("checked", "");
558
569
  }
559
570
  } else if (node instanceof HTMLTextAreaElement) {
560
- clone.value = node.value;
571
+ const rect = node.getBoundingClientRect();
561
572
  clone.textContent = node.value;
573
+ clone.style.width = `${rect.width}px`;
574
+ clone.style.height = `${rect.height}px`;
562
575
  } else if (node instanceof HTMLSelectElement) {
563
576
  clone.value = node.value;
564
577
  Array.from(clone.options).forEach((opt) => {
@@ -569,19 +582,31 @@
569
582
  }
570
583
  });
571
584
  }
572
- inlineAllStyles(node, clone, styleMap, styleCache, compress);
573
- const frag = document.createDocumentFragment();
574
- const rootElement = originalRoot || node;
575
- node.childNodes.forEach((child) => {
576
- const clonedChild = deepClone(child, styleMap, styleCache, nodeMap, compress, options, rootElement);
577
- if (clonedChild) frag.appendChild(clonedChild);
578
- });
579
- clone.appendChild(frag);
580
- if (node.shadowRoot) {
581
- const shadowContent = Array.from(node.shadowRoot.children).filter((el) => el.tagName !== "STYLE").map((el) => deepClone(el, styleMap, styleCache, nodeMap, compress, options, rootElement)).filter(Boolean);
582
- const shadowFrag = document.createDocumentFragment();
583
- shadowContent.forEach((child) => shadowFrag.appendChild(child));
584
- clone.appendChild(shadowFrag);
585
+ inlineAllStyles(node, clone, compress);
586
+ if (isSlotElement(node)) {
587
+ const assigned = ((_b = node.assignedNodes) == null ? void 0 : _b.call(node, { flatten: true })) || [];
588
+ const nodesToClone = assigned.length > 0 ? assigned : Array.from(node.childNodes);
589
+ const fragment = document.createDocumentFragment();
590
+ for (const child of nodesToClone) {
591
+ const clonedChild = deepClone(child, compress, options, originalRoot || node);
592
+ if (clonedChild) fragment.appendChild(clonedChild);
593
+ }
594
+ return fragment;
595
+ } else if (node instanceof HTMLTextAreaElement) {
596
+ } else {
597
+ const baseChildren = node.shadowRoot ? node.shadowRoot.childNodes : node.childNodes;
598
+ for (const child of baseChildren) {
599
+ const clonedChild = deepClone(child, compress, options, originalRoot || node);
600
+ if (clonedChild) clone.appendChild(clonedChild);
601
+ }
602
+ if (node.shadowRoot && node.childNodes.length > 0 && !node.shadowRoot.querySelector("slot")) {
603
+ const lightDomContent = document.createDocumentFragment();
604
+ for (const child of node.childNodes) {
605
+ const clonedChild = deepClone(child, compress, options, originalRoot || node);
606
+ if (clonedChild) lightDomContent.appendChild(clonedChild);
607
+ }
608
+ clone.appendChild(lightDomContent);
609
+ }
585
610
  }
586
611
  return clone;
587
612
  }
@@ -666,14 +691,14 @@
666
691
  }
667
692
  function embedCustomFonts() {
668
693
  return __async(this, arguments, function* ({ preCached = false } = {}) {
669
- if (resourceCache.has("fonts-embed-css")) {
694
+ if (cache.resource.has("fonts-embed-css")) {
670
695
  if (preCached) {
671
696
  const style = document.createElement("style");
672
697
  style.setAttribute("data-snapdom", "embedFonts");
673
- style.textContent = resourceCache.get("fonts-embed-css");
698
+ style.textContent = cache.resource.get("fonts-embed-css");
674
699
  document.head.appendChild(style);
675
700
  }
676
- return resourceCache.get("fonts-embed-css");
701
+ return cache.resource.get("fonts-embed-css");
677
702
  }
678
703
  const importRegex = /@import\s+url\(["']?([^"')]+)["']?\)/g;
679
704
  const styleImports = [];
@@ -706,11 +731,11 @@
706
731
  url = new URL(url, link.href).href;
707
732
  }
708
733
  if (isIconFont(url)) return null;
709
- if (resourceCache.has(url)) {
710
- processedFontURLs.add(url);
711
- return { original: match[0], inlined: `url(${resourceCache.get(url)})` };
734
+ if (cache.resource.has(url)) {
735
+ cache.font.add(url);
736
+ return { original: match[0], inlined: `url(${cache.resource.get(url)})` };
712
737
  }
713
- if (processedFontURLs.has(url)) return null;
738
+ if (cache.font.has(url)) return null;
714
739
  try {
715
740
  const fontRes = yield fetch(url);
716
741
  const blob = yield fontRes.blob();
@@ -719,8 +744,8 @@
719
744
  reader.onload = () => resolve(reader.result);
720
745
  reader.readAsDataURL(blob);
721
746
  });
722
- resourceCache.set(url, b64);
723
- processedFontURLs.add(url);
747
+ cache.resource.set(url, b64);
748
+ cache.font.add(url);
724
749
  return { original: match[0], inlined: `url(${b64})` };
725
750
  } catch (e) {
726
751
  console.warn("[snapdom] Failed to fetch font resource:", url);
@@ -756,12 +781,12 @@
756
781
  url = new URL(url, sheet.href || location.href).href;
757
782
  }
758
783
  if (isIconFont(url)) continue;
759
- if (resourceCache.has(url)) {
760
- processedFontURLs.add(url);
761
- inlinedSrc = inlinedSrc.replace(match[0], `url(${resourceCache.get(url)})`);
784
+ if (cache.resource.has(url)) {
785
+ cache.font.add(url);
786
+ inlinedSrc = inlinedSrc.replace(match[0], `url(${cache.resource.get(url)})`);
762
787
  continue;
763
788
  }
764
- if (processedFontURLs.has(url)) continue;
789
+ if (cache.font.has(url)) continue;
765
790
  try {
766
791
  const res = yield fetch(url);
767
792
  const blob = yield res.blob();
@@ -770,8 +795,8 @@
770
795
  reader.onload = () => resolve(reader.result);
771
796
  reader.readAsDataURL(blob);
772
797
  });
773
- resourceCache.set(url, b64);
774
- processedFontURLs.add(url);
798
+ cache.resource.set(url, b64);
799
+ cache.font.add(url);
775
800
  inlinedSrc = inlinedSrc.replace(match[0], `url(${b64})`);
776
801
  } catch (e) {
777
802
  console.warn("[snapdom] Failed to fetch font URL:", url);
@@ -796,10 +821,10 @@
796
821
  if (isIconFont(font.family)) continue;
797
822
  let b64 = font._snapdomSrc;
798
823
  if (!b64.startsWith("data:")) {
799
- if (resourceCache.has(font._snapdomSrc)) {
800
- b64 = resourceCache.get(font._snapdomSrc);
801
- processedFontURLs.add(font._snapdomSrc);
802
- } else if (!processedFontURLs.has(font._snapdomSrc)) {
824
+ if (cache.resource.has(font._snapdomSrc)) {
825
+ b64 = cache.resource.get(font._snapdomSrc);
826
+ cache.font.add(font._snapdomSrc);
827
+ } else if (!cache.font.has(font._snapdomSrc)) {
803
828
  try {
804
829
  const res = yield fetch(font._snapdomSrc);
805
830
  const blob = yield res.blob();
@@ -808,8 +833,8 @@
808
833
  reader.onload = () => resolve(reader.result);
809
834
  reader.readAsDataURL(blob);
810
835
  });
811
- resourceCache.set(font._snapdomSrc, b64);
812
- processedFontURLs.add(font._snapdomSrc);
836
+ cache.resource.set(font._snapdomSrc, b64);
837
+ cache.font.add(font._snapdomSrc);
813
838
  } catch (e) {
814
839
  console.warn("[snapdom] Failed to fetch dynamic font src:", font._snapdomSrc);
815
840
  continue;
@@ -826,7 +851,7 @@
826
851
  }
827
852
  }
828
853
  if (finalCSS) {
829
- resourceCache.set("fonts-embed-css", finalCSS);
854
+ cache.resource.set("fonts-embed-css", finalCSS);
830
855
  if (preCached) {
831
856
  const style = document.createElement("style");
832
857
  style.setAttribute("data-snapdom", "embedFonts");
@@ -839,7 +864,7 @@
839
864
  }
840
865
 
841
866
  // src/modules/pseudo.js
842
- function inlinePseudoElements(source, clone, styleMap, styleCache, compress, embedFonts = false, useProxy) {
867
+ function inlinePseudoElements(source, clone, compress, embedFonts = false, useProxy) {
843
868
  return __async(this, null, function* () {
844
869
  if (!(source instanceof Element) || !(clone instanceof Element)) return;
845
870
  for (const pseudo of ["::before", "::after", "::first-letter"]) {
@@ -864,7 +889,7 @@
864
889
  span.dataset.snapdomPseudo = "::first-letter";
865
890
  const snapshot = snapshotComputedStyle(style);
866
891
  const key = getStyleKey(snapshot, "span", compress);
867
- styleMap.set(span, key);
892
+ cache.preStyleMap.set(span, key);
868
893
  const restNode = document.createTextNode(rest);
869
894
  clone.replaceChild(restNode, textNode);
870
895
  clone.insertBefore(span, restNode);
@@ -885,7 +910,7 @@
885
910
  pseudoEl.dataset.snapdomPseudo = pseudo;
886
911
  const snapshot = snapshotComputedStyle(style);
887
912
  const key = getStyleKey(snapshot, "span", compress);
888
- styleMap.set(pseudoEl, key);
913
+ cache.preStyleMap.set(pseudoEl, key);
889
914
  const isIconFont2 = isIconFont(fontFamily);
890
915
  const cleanContent = parseContent(content);
891
916
  if (isIconFont2 && cleanContent.length === 1) {
@@ -936,8 +961,6 @@
936
961
  yield inlinePseudoElements(
937
962
  sChildren[i],
938
963
  cChildren[i],
939
- styleMap,
940
- styleCache,
941
964
  compress,
942
965
  embedFonts,
943
966
  useProxy
@@ -980,18 +1003,15 @@
980
1003
  function prepareClone(_0) {
981
1004
  return __async(this, arguments, function* (element, compress = false, embedFonts = false, options = {}) {
982
1005
  var _a;
983
- const styleMap = /* @__PURE__ */ new Map();
984
- const styleCache = /* @__PURE__ */ new WeakMap();
985
- const nodeMap = /* @__PURE__ */ new Map();
986
- let clone;
1006
+ let clone, classCSS;
987
1007
  try {
988
- clone = deepClone(element, styleMap, styleCache, nodeMap, compress, options, element);
1008
+ clone = deepClone(element, compress, options, element);
989
1009
  } catch (e) {
990
1010
  console.warn("deepClone failed:", e);
991
1011
  throw e;
992
1012
  }
993
1013
  try {
994
- yield inlinePseudoElements(element, clone, styleMap, styleCache, compress, embedFonts, options.useProxy);
1014
+ yield inlinePseudoElements(element, clone, compress, embedFonts, options.useProxy);
995
1015
  } catch (e) {
996
1016
  console.warn("inlinePseudoElements failed:", e);
997
1017
  }
@@ -1000,11 +1020,10 @@
1000
1020
  } catch (e) {
1001
1021
  console.warn("inlineExternalDef failed:", e);
1002
1022
  }
1003
- let classCSS = "";
1004
1023
  if (compress) {
1005
- const keyToClass = generateCSSClasses(styleMap);
1024
+ const keyToClass = generateCSSClasses();
1006
1025
  classCSS = Array.from(keyToClass.entries()).map(([key, className]) => `.${className}{${key}}`).join("");
1007
- for (const [node, key] of styleMap.entries()) {
1026
+ for (const [node, key] of cache.preStyleMap.entries()) {
1008
1027
  if (node.tagName === "STYLE") continue;
1009
1028
  const className = keyToClass.get(key);
1010
1029
  if (className) node.classList.add(className);
@@ -1013,12 +1032,12 @@
1013
1032
  if (bgImage && bgImage !== "none") node.style.backgroundImage = bgImage;
1014
1033
  }
1015
1034
  } else {
1016
- for (const [node, key] of styleMap.entries()) {
1035
+ for (const [node, key] of cache.preStyleMap.entries()) {
1017
1036
  if (node.tagName === "STYLE") continue;
1018
1037
  node.setAttribute("style", key.replace(/;/g, "; "));
1019
1038
  }
1020
1039
  }
1021
- for (const [cloneNode, originalNode] of nodeMap.entries()) {
1040
+ for (const [cloneNode, originalNode] of cache.preNodeMap.entries()) {
1022
1041
  const scrollX = originalNode.scrollLeft;
1023
1042
  const scrollY = originalNode.scrollTop;
1024
1043
  const hasScroll = scrollX || scrollY;
@@ -1037,9 +1056,9 @@
1037
1056
  cloneNode.appendChild(inner);
1038
1057
  }
1039
1058
  }
1040
- if (element === nodeMap.get(clone)) {
1041
- const computed = styleCache.get(element) || window.getComputedStyle(element);
1042
- styleCache.set(element, computed);
1059
+ if (element === cache.preNodeMap.get(clone)) {
1060
+ const computed = cache.preStyle.get(element) || window.getComputedStyle(element);
1061
+ cache.preStyle.set(element, computed);
1043
1062
  const transform = stripTranslate(computed.transform);
1044
1063
  clone.style.margin = "0";
1045
1064
  clone.style.position = "static";
@@ -1052,13 +1071,13 @@
1052
1071
  clone.style.clear = "none";
1053
1072
  clone.style.transform = transform || "";
1054
1073
  }
1055
- for (const [cloneNode, originalNode] of nodeMap.entries()) {
1074
+ for (const [cloneNode, originalNode] of cache.preNodeMap.entries()) {
1056
1075
  if (originalNode.tagName === "PRE") {
1057
1076
  cloneNode.style.marginTop = "0";
1058
1077
  cloneNode.style.marginBlockStart = "0";
1059
1078
  }
1060
1079
  }
1061
- return { clone, classCSS, styleCache };
1080
+ return { clone, classCSS };
1062
1081
  });
1063
1082
  }
1064
1083
 
@@ -1088,30 +1107,35 @@
1088
1107
  }
1089
1108
 
1090
1109
  // src/modules/background.js
1091
- function inlineBackgroundImages(_0, _1, _2) {
1092
- return __async(this, arguments, function* (source, clone, styleCache, options = {}) {
1110
+ function inlineBackgroundImages(_0, _1) {
1111
+ return __async(this, arguments, function* (source, clone, options = {}) {
1093
1112
  const queue = [[source, clone]];
1113
+ const imageProps = [
1114
+ "background-image",
1115
+ "mask",
1116
+ "mask-image",
1117
+ "-webkit-mask-image",
1118
+ "mask-source",
1119
+ "mask-box-image-source",
1120
+ "mask-border-source",
1121
+ "-webkit-mask-box-image-source"
1122
+ ];
1094
1123
  while (queue.length) {
1095
1124
  const [srcNode, cloneNode] = queue.shift();
1096
- const style = styleCache.get(srcNode) || getStyle(srcNode);
1097
- if (!styleCache.has(srcNode)) styleCache.set(srcNode, style);
1098
- const bg = style.getPropertyValue("background-image");
1099
- const bgColor = style.getPropertyValue("background-color");
1100
- if (!bg || bg === "none") {
1101
- const sChildren2 = Array.from(srcNode.children);
1102
- const cChildren2 = Array.from(cloneNode.children);
1103
- for (let i = 0; i < Math.min(sChildren2.length, cChildren2.length); i++) {
1104
- queue.push([sChildren2[i], cChildren2[i]]);
1125
+ const style = cache.preStyle.get(srcNode) || getStyle(srcNode);
1126
+ if (!cache.preStyle.has(srcNode)) cache.preStyle.set(srcNode, style);
1127
+ for (const prop of imageProps) {
1128
+ const val = style.getPropertyValue(prop);
1129
+ if (!val || val === "none") continue;
1130
+ const splits = splitBackgroundImage(val);
1131
+ const inlined = yield Promise.all(
1132
+ splits.map((entry) => inlineSingleBackgroundEntry(entry, options))
1133
+ );
1134
+ if (inlined.some((p) => p && p !== "none" && !/^url\(undefined/.test(p))) {
1135
+ cloneNode.style.setProperty(prop, inlined.join(", "));
1105
1136
  }
1106
- continue;
1107
- }
1108
- const bgSplits = splitBackgroundImage(bg);
1109
- const newBgParts = yield Promise.all(
1110
- bgSplits.map((entry) => inlineSingleBackgroundEntry(entry, options))
1111
- );
1112
- if (newBgParts.some((p) => p && p !== "none" && !/^url\(undefined\)/.test(p))) {
1113
- cloneNode.style.backgroundImage = newBgParts.join(", ");
1114
1137
  }
1138
+ const bgColor = style.getPropertyValue("background-color");
1115
1139
  if (bgColor && bgColor !== "transparent" && bgColor !== "rgba(0, 0, 0, 0)") {
1116
1140
  cloneNode.style.backgroundColor = bgColor;
1117
1141
  }
@@ -1128,13 +1152,14 @@
1128
1152
  function captureDOM(_0) {
1129
1153
  return __async(this, arguments, function* (element, options = {}) {
1130
1154
  if (!element) throw new Error("Element cannot be null or undefined");
1155
+ cache.reset();
1131
1156
  const { compress = true, embedFonts = false, fast = true, scale = 1, useProxy = "" } = options;
1132
- let clone, classCSS, styleCache;
1157
+ let clone, classCSS;
1133
1158
  let fontsCSS = "";
1134
1159
  let baseCSS = "";
1135
1160
  let dataURL;
1136
1161
  let svgString;
1137
- ({ clone, classCSS, styleCache } = yield prepareClone(element, compress, embedFonts, options));
1162
+ ({ clone, classCSS } = yield prepareClone(element, compress, embedFonts, options));
1138
1163
  yield new Promise((resolve) => {
1139
1164
  idle(() => __async(null, null, function* () {
1140
1165
  yield inlineImages(clone, options);
@@ -1143,7 +1168,7 @@
1143
1168
  });
1144
1169
  yield new Promise((resolve) => {
1145
1170
  idle(() => __async(null, null, function* () {
1146
- yield inlineBackgroundImages(element, clone, styleCache, options);
1171
+ yield inlineBackgroundImages(element, clone, options);
1147
1172
  resolve();
1148
1173
  }), { fast });
1149
1174
  });
@@ -1158,13 +1183,13 @@
1158
1183
  if (compress) {
1159
1184
  const usedTags = collectUsedTagNames(clone).sort();
1160
1185
  const tagKey = usedTags.join(",");
1161
- if (baseCSSCache.has(tagKey)) {
1162
- baseCSS = baseCSSCache.get(tagKey);
1186
+ if (cache.baseStyle.has(tagKey)) {
1187
+ baseCSS = cache.baseStyle.get(tagKey);
1163
1188
  } else {
1164
1189
  yield new Promise((resolve) => {
1165
1190
  idle(() => {
1166
1191
  baseCSS = generateDedupedBaseCSS(usedTags);
1167
- baseCSSCache.set(tagKey, baseCSS);
1192
+ cache.baseStyle.set(tagKey, baseCSS);
1168
1193
  resolve();
1169
1194
  }, { fast });
1170
1195
  });
@@ -1406,10 +1431,7 @@
1406
1431
  return __async(this, arguments, function* (root = document, options = {}) {
1407
1432
  const { embedFonts = true, reset = false } = options;
1408
1433
  if (reset) {
1409
- imageCache.clear();
1410
- bgCache.clear();
1411
- resourceCache.clear();
1412
- baseCSSCache.clear();
1434
+ cache.reset();
1413
1435
  return;
1414
1436
  }
1415
1437
  yield document.fonts.ready;
@@ -1422,9 +1444,9 @@
1422
1444
  const promises = [];
1423
1445
  for (const img of imgEls) {
1424
1446
  const src = img.src;
1425
- if (!imageCache.has(src)) {
1447
+ if (!cache.image.has(src)) {
1426
1448
  promises.push(
1427
- fetchImage(src, { useProxy: options.useProxy }).then((dataURL) => imageCache.set(src, dataURL)).catch(() => {
1449
+ fetchImage(src, { useProxy: options.useProxy }).then((dataURL) => cache.image.set(src, dataURL)).catch(() => {
1428
1450
  })
1429
1451
  );
1430
1452
  }