@zumer/snapdom 1.9.10-dev.0 → 1.9.10-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -3
- package/dist/snapdom.js +608 -200
- package/dist/snapdom.min.js +4 -4
- package/dist/snapdom.min.mjs +5 -5
- package/dist/snapdom.mjs +471 -73
- package/package.json +1 -1
- package/types/snapdom.d.ts +15 -1
package/dist/snapdom.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
/*
|
|
3
3
|
* snapdom
|
|
4
|
-
* v.1.9.10-dev.
|
|
4
|
+
* v.1.9.10-dev.2
|
|
5
5
|
* Author Juan Martin Muda
|
|
6
6
|
* License MIT
|
|
7
7
|
**/
|
|
@@ -82,10 +82,13 @@
|
|
|
82
82
|
cache.session.styleMap = /* @__PURE__ */ new Map();
|
|
83
83
|
cache.session.nodeMap = /* @__PURE__ */ new Map();
|
|
84
84
|
cache.session.styleCache = /* @__PURE__ */ new WeakMap();
|
|
85
|
-
cache.
|
|
86
|
-
cache.
|
|
87
|
-
cache.
|
|
88
|
-
cache.
|
|
85
|
+
cache.computedStyle = /* @__PURE__ */ new WeakMap();
|
|
86
|
+
cache.baseStyle = /* @__PURE__ */ new Map();
|
|
87
|
+
cache.defaultStyle = /* @__PURE__ */ new Map();
|
|
88
|
+
cache.image = /* @__PURE__ */ new Map();
|
|
89
|
+
cache.background = /* @__PURE__ */ new Map();
|
|
90
|
+
cache.resource = /* @__PURE__ */ new Map();
|
|
91
|
+
cache.font = /* @__PURE__ */ new Set();
|
|
89
92
|
return;
|
|
90
93
|
}
|
|
91
94
|
default: {
|
|
@@ -344,7 +347,6 @@
|
|
|
344
347
|
"script",
|
|
345
348
|
"template",
|
|
346
349
|
// SVG whole namespace (safe for LeaderLine/presentation attrs)
|
|
347
|
-
"svg",
|
|
348
350
|
"g",
|
|
349
351
|
"defs",
|
|
350
352
|
"use",
|
|
@@ -688,6 +690,11 @@
|
|
|
688
690
|
const ctx = _resolveCtx(sessionOrCtx, opts);
|
|
689
691
|
const resetMode = ctx.options && ctx.options.cache || "auto";
|
|
690
692
|
if (resetMode !== "disabled") setupInvalidationOnce(document.documentElement);
|
|
693
|
+
if (resetMode === "disabled" && !ctx.session.__bumpedForDisabled) {
|
|
694
|
+
bumpEpoch();
|
|
695
|
+
snapshotKeyCache.clear();
|
|
696
|
+
ctx.session.__bumpedForDisabled = true;
|
|
697
|
+
}
|
|
691
698
|
if (NO_DEFAULTS_TAGS.has((_a = source.tagName) == null ? void 0 : _a.toLowerCase())) {
|
|
692
699
|
const author = (_b = source.getAttribute) == null ? void 0 : _b.call(source, "style");
|
|
693
700
|
if (author) clone.setAttribute("style", author);
|
|
@@ -710,6 +717,31 @@
|
|
|
710
717
|
}
|
|
711
718
|
|
|
712
719
|
// src/core/clone.js
|
|
720
|
+
function idleCallback(childList, callback, fast) {
|
|
721
|
+
return Promise.all(childList.map((child) => {
|
|
722
|
+
return new Promise((resolve) => {
|
|
723
|
+
function deal() {
|
|
724
|
+
idle(
|
|
725
|
+
(deadline) => {
|
|
726
|
+
if (deadline instanceof IdleDeadline) {
|
|
727
|
+
if (deadline.timeRemaining()) {
|
|
728
|
+
callback(child, resolve);
|
|
729
|
+
} else {
|
|
730
|
+
deal();
|
|
731
|
+
}
|
|
732
|
+
} else {
|
|
733
|
+
callback(child, resolve);
|
|
734
|
+
}
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
fast
|
|
738
|
+
}
|
|
739
|
+
);
|
|
740
|
+
}
|
|
741
|
+
deal();
|
|
742
|
+
});
|
|
743
|
+
}));
|
|
744
|
+
}
|
|
713
745
|
function addNotSlottedRightmost(sel) {
|
|
714
746
|
sel = sel.trim();
|
|
715
747
|
if (!sel) return sel;
|
|
@@ -831,177 +863,321 @@
|
|
|
831
863
|
root.querySelectorAll("*").forEach((el) => el.setAttribute("data-sd-slotted", ""));
|
|
832
864
|
}
|
|
833
865
|
}
|
|
866
|
+
function getAccessibleIframeDocument(iframe, attempts = 3) {
|
|
867
|
+
return __async(this, null, function* () {
|
|
868
|
+
const probe = () => {
|
|
869
|
+
var _a;
|
|
870
|
+
try {
|
|
871
|
+
return iframe.contentDocument || ((_a = iframe.contentWindow) == null ? void 0 : _a.document) || null;
|
|
872
|
+
} catch (e) {
|
|
873
|
+
return null;
|
|
874
|
+
}
|
|
875
|
+
};
|
|
876
|
+
let doc = probe();
|
|
877
|
+
let i = 0;
|
|
878
|
+
while (i < attempts && (!doc || !doc.body && !doc.documentElement)) {
|
|
879
|
+
yield new Promise((r) => setTimeout(r, 0));
|
|
880
|
+
doc = probe();
|
|
881
|
+
i++;
|
|
882
|
+
}
|
|
883
|
+
return doc && (doc.body || doc.documentElement) ? doc : null;
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
function measureContentBox(el) {
|
|
887
|
+
const rect = el.getBoundingClientRect();
|
|
888
|
+
let bl = 0, br = 0, bt = 0, bb = 0;
|
|
889
|
+
try {
|
|
890
|
+
const cs = getComputedStyle(el);
|
|
891
|
+
bl = parseFloat(cs.borderLeftWidth) || 0;
|
|
892
|
+
br = parseFloat(cs.borderRightWidth) || 0;
|
|
893
|
+
bt = parseFloat(cs.borderTopWidth) || 0;
|
|
894
|
+
bb = parseFloat(cs.borderBottomWidth) || 0;
|
|
895
|
+
} catch (e) {
|
|
896
|
+
}
|
|
897
|
+
const contentWidth = Math.max(0, Math.round(rect.width - (bl + br)));
|
|
898
|
+
const contentHeight = Math.max(0, Math.round(rect.height - (bt + bb)));
|
|
899
|
+
return { contentWidth, contentHeight, rect };
|
|
900
|
+
}
|
|
901
|
+
function pinIframeViewport(doc, w, h) {
|
|
902
|
+
const style = doc.createElement("style");
|
|
903
|
+
style.setAttribute("data-sd-iframe-pin", "");
|
|
904
|
+
style.textContent = `html, body {margin: 0 !important;padding: 0 !important;width: ${w}px !important;height: ${h}px !important;min-width: ${w}px !important;min-height: ${h}px !important;box-sizing: border-box !important;overflow: hidden !important;background-clip: border-box !important;}`;
|
|
905
|
+
(doc.head || doc.documentElement).appendChild(style);
|
|
906
|
+
return () => {
|
|
907
|
+
try {
|
|
908
|
+
style.remove();
|
|
909
|
+
} catch (e) {
|
|
910
|
+
}
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
function rasterizeIframe(iframe, sessionCache, options) {
|
|
914
|
+
return __async(this, null, function* () {
|
|
915
|
+
const doc = yield getAccessibleIframeDocument(iframe, 3);
|
|
916
|
+
if (!doc) throw new Error("iframe document not accessible/ready");
|
|
917
|
+
const { contentWidth, contentHeight, rect } = measureContentBox(iframe);
|
|
918
|
+
const snap = options == null ? void 0 : options.snap;
|
|
919
|
+
if (!snap || typeof snap.toPng !== "function") {
|
|
920
|
+
throw new Error("snapdom.toPng not available in iframe or window");
|
|
921
|
+
}
|
|
922
|
+
const nested = __spreadProps(__spreadValues({}, options), { scale: 1 });
|
|
923
|
+
const unpin = pinIframeViewport(doc, contentWidth, contentHeight);
|
|
924
|
+
let imgEl;
|
|
925
|
+
try {
|
|
926
|
+
imgEl = yield snap.toPng(doc.documentElement, nested);
|
|
927
|
+
} finally {
|
|
928
|
+
unpin();
|
|
929
|
+
}
|
|
930
|
+
imgEl.style.display = "block";
|
|
931
|
+
imgEl.style.width = `${contentWidth}px`;
|
|
932
|
+
imgEl.style.height = `${contentHeight}px`;
|
|
933
|
+
const wrapper = document.createElement("div");
|
|
934
|
+
sessionCache.nodeMap.set(wrapper, iframe);
|
|
935
|
+
inlineAllStyles(iframe, wrapper, sessionCache, options);
|
|
936
|
+
wrapper.style.overflow = "hidden";
|
|
937
|
+
wrapper.style.display = "block";
|
|
938
|
+
if (!wrapper.style.width) wrapper.style.width = `${Math.round(rect.width)}px`;
|
|
939
|
+
if (!wrapper.style.height) wrapper.style.height = `${Math.round(rect.height)}px`;
|
|
940
|
+
wrapper.appendChild(imgEl);
|
|
941
|
+
return wrapper;
|
|
942
|
+
});
|
|
943
|
+
}
|
|
834
944
|
function deepClone(node, sessionCache, options) {
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
if (node.
|
|
842
|
-
|
|
945
|
+
return __async(this, null, function* () {
|
|
946
|
+
var _a, _b, _c, _d, _e, _f;
|
|
947
|
+
if (!node) throw new Error("Invalid node");
|
|
948
|
+
const clonedAssignedNodes = /* @__PURE__ */ new Set();
|
|
949
|
+
let pendingSelectValue = null;
|
|
950
|
+
let pendingTextAreaValue = null;
|
|
951
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
952
|
+
const tag = (node.localName || node.tagName || "").toLowerCase();
|
|
953
|
+
if (node.id === "snapdom-sandbox" || node.hasAttribute("data-snapdom-sandbox")) {
|
|
954
|
+
return null;
|
|
955
|
+
}
|
|
956
|
+
if (NO_CAPTURE_TAGS.has(tag)) {
|
|
957
|
+
return null;
|
|
958
|
+
}
|
|
843
959
|
}
|
|
844
|
-
if (
|
|
845
|
-
return
|
|
960
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
961
|
+
return node.cloneNode(true);
|
|
846
962
|
}
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
963
|
+
if (node.nodeType !== Node.ELEMENT_NODE) {
|
|
964
|
+
return node.cloneNode(true);
|
|
965
|
+
}
|
|
966
|
+
if (node.getAttribute("data-capture") === "exclude") {
|
|
967
|
+
const spacer = document.createElement("div");
|
|
968
|
+
const rect = node.getBoundingClientRect();
|
|
969
|
+
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
970
|
+
return spacer;
|
|
971
|
+
}
|
|
972
|
+
if (options.exclude && Array.isArray(options.exclude)) {
|
|
973
|
+
for (const selector of options.exclude) {
|
|
974
|
+
try {
|
|
975
|
+
if ((_a = node.matches) == null ? void 0 : _a.call(node, selector)) {
|
|
976
|
+
const spacer = document.createElement("div");
|
|
977
|
+
const rect = node.getBoundingClientRect();
|
|
978
|
+
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
979
|
+
return spacer;
|
|
980
|
+
}
|
|
981
|
+
} catch (err) {
|
|
982
|
+
console.warn(`Invalid selector in exclude option: ${selector}`, err);
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
if (typeof options.filter === "function") {
|
|
862
987
|
try {
|
|
863
|
-
if (
|
|
988
|
+
if (!options.filter(node)) {
|
|
864
989
|
const spacer = document.createElement("div");
|
|
865
990
|
const rect = node.getBoundingClientRect();
|
|
866
991
|
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
867
992
|
return spacer;
|
|
868
993
|
}
|
|
869
994
|
} catch (err) {
|
|
870
|
-
console.warn(
|
|
995
|
+
console.warn("Error in filter function:", err);
|
|
871
996
|
}
|
|
872
997
|
}
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
998
|
+
if (node.tagName === "IFRAME") {
|
|
999
|
+
let sameOrigin = false;
|
|
1000
|
+
try {
|
|
1001
|
+
sameOrigin = !!(node.contentDocument || ((_b = node.contentWindow) == null ? void 0 : _b.document));
|
|
1002
|
+
} catch (e) {
|
|
1003
|
+
sameOrigin = false;
|
|
1004
|
+
}
|
|
1005
|
+
if (sameOrigin) {
|
|
1006
|
+
try {
|
|
1007
|
+
const wrapper = yield rasterizeIframe(node, sessionCache, options);
|
|
1008
|
+
return wrapper;
|
|
1009
|
+
} catch (err) {
|
|
1010
|
+
console.warn("[SnapDOM] iframe rasterization failed, fallback:", err);
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
if (options.placeholders) {
|
|
1014
|
+
const fallback = document.createElement("div");
|
|
1015
|
+
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;`;
|
|
1016
|
+
inlineAllStyles(node, fallback, sessionCache, options);
|
|
1017
|
+
return fallback;
|
|
1018
|
+
} else {
|
|
878
1019
|
const rect = node.getBoundingClientRect();
|
|
1020
|
+
const spacer = document.createElement("div");
|
|
879
1021
|
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
1022
|
+
inlineAllStyles(node, spacer, sessionCache, options);
|
|
880
1023
|
return spacer;
|
|
881
1024
|
}
|
|
882
|
-
} catch (err) {
|
|
883
|
-
console.warn("Error in filter function:", err);
|
|
884
1025
|
}
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
img.src = dataURL;
|
|
905
|
-
img.width = node.width;
|
|
906
|
-
img.height = node.height;
|
|
907
|
-
sessionCache.nodeMap.set(img, node);
|
|
908
|
-
inlineAllStyles(node, img, sessionCache, options);
|
|
909
|
-
return img;
|
|
910
|
-
}
|
|
911
|
-
let clone;
|
|
912
|
-
try {
|
|
913
|
-
clone = node.cloneNode(false);
|
|
914
|
-
sessionCache.nodeMap.set(clone, node);
|
|
915
|
-
if (node.tagName === "IMG") {
|
|
916
|
-
freezeImgSrcset(node, clone);
|
|
917
|
-
}
|
|
918
|
-
} catch (err) {
|
|
919
|
-
console.error("[Snapdom] Failed to clone node:", node, err);
|
|
920
|
-
throw err;
|
|
921
|
-
}
|
|
922
|
-
if (node instanceof HTMLTextAreaElement) {
|
|
923
|
-
clone.textContent = node.value;
|
|
924
|
-
clone.value = node.value;
|
|
925
|
-
const rect = node.getBoundingClientRect();
|
|
926
|
-
clone.style.width = `${rect.width}px`;
|
|
927
|
-
clone.style.height = `${rect.height}px`;
|
|
928
|
-
return clone;
|
|
929
|
-
}
|
|
930
|
-
if (node instanceof HTMLInputElement) {
|
|
931
|
-
clone.value = node.value;
|
|
932
|
-
clone.setAttribute("value", node.value);
|
|
933
|
-
if (node.checked !== void 0) {
|
|
934
|
-
clone.checked = node.checked;
|
|
935
|
-
if (node.checked) clone.setAttribute("checked", "");
|
|
936
|
-
if (node.indeterminate) clone.indeterminate = node.indeterminate;
|
|
1026
|
+
if (node.getAttribute("data-capture") === "placeholder") {
|
|
1027
|
+
const clone2 = node.cloneNode(false);
|
|
1028
|
+
sessionCache.nodeMap.set(clone2, node);
|
|
1029
|
+
inlineAllStyles(node, clone2, sessionCache, options);
|
|
1030
|
+
const placeholder = document.createElement("div");
|
|
1031
|
+
placeholder.textContent = node.getAttribute("data-placeholder-text") || "";
|
|
1032
|
+
placeholder.style.cssText = `color:#666;font-size:12px;text-align:center;line-height:1.4;padding:0.5em;box-sizing:border-box;`;
|
|
1033
|
+
clone2.appendChild(placeholder);
|
|
1034
|
+
return clone2;
|
|
1035
|
+
}
|
|
1036
|
+
if (node.tagName === "CANVAS") {
|
|
1037
|
+
const dataURL = node.toDataURL();
|
|
1038
|
+
const img = document.createElement("img");
|
|
1039
|
+
img.src = dataURL;
|
|
1040
|
+
img.width = node.width;
|
|
1041
|
+
img.height = node.height;
|
|
1042
|
+
sessionCache.nodeMap.set(img, node);
|
|
1043
|
+
inlineAllStyles(node, img, sessionCache, options);
|
|
1044
|
+
return img;
|
|
937
1045
|
}
|
|
938
|
-
|
|
939
|
-
if (node instanceof HTMLSelectElement) {
|
|
940
|
-
pendingSelectValue = node.value;
|
|
941
|
-
}
|
|
942
|
-
inlineAllStyles(node, clone, sessionCache, options);
|
|
943
|
-
if (node.shadowRoot) {
|
|
1046
|
+
let clone;
|
|
944
1047
|
try {
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
1048
|
+
clone = node.cloneNode(false);
|
|
1049
|
+
sessionCache.nodeMap.set(clone, node);
|
|
1050
|
+
if (node.tagName === "IMG") {
|
|
1051
|
+
freezeImgSrcset(node, clone);
|
|
948
1052
|
try {
|
|
949
|
-
|
|
1053
|
+
const rect = node.getBoundingClientRect();
|
|
1054
|
+
let w = Math.round(rect.width || 0);
|
|
1055
|
+
let h = Math.round(rect.height || 0);
|
|
1056
|
+
if (!w || !h) {
|
|
1057
|
+
const computed = window.getComputedStyle(node);
|
|
1058
|
+
const cssW = parseFloat(computed.width) || 0;
|
|
1059
|
+
const cssH = parseFloat(computed.height) || 0;
|
|
1060
|
+
const attrW = parseInt(node.getAttribute("width") || "", 10) || 0;
|
|
1061
|
+
const attrH = parseInt(node.getAttribute("height") || "", 10) || 0;
|
|
1062
|
+
const propW = node.width || node.naturalWidth || 0;
|
|
1063
|
+
const propH = node.height || node.naturalHeight || 0;
|
|
1064
|
+
w = Math.round(w || cssW || attrW || propW || 0);
|
|
1065
|
+
h = Math.round(h || cssH || attrH || propH || 0);
|
|
1066
|
+
}
|
|
1067
|
+
if (w) clone.dataset.snapdomWidth = String(w);
|
|
1068
|
+
if (h) clone.dataset.snapdomHeight = String(h);
|
|
950
1069
|
} catch (e) {
|
|
951
|
-
assigned = ((_d = s.assignedNodes) == null ? void 0 : _d.call(s)) || [];
|
|
952
1070
|
}
|
|
953
|
-
for (const an of assigned) clonedAssignedNodes.add(an);
|
|
954
1071
|
}
|
|
955
|
-
} catch (
|
|
1072
|
+
} catch (err) {
|
|
1073
|
+
console.error("[Snapdom] Failed to clone node:", node, err);
|
|
1074
|
+
throw err;
|
|
1075
|
+
}
|
|
1076
|
+
if (node instanceof HTMLTextAreaElement) {
|
|
1077
|
+
const rect = node.getBoundingClientRect();
|
|
1078
|
+
clone.style.width = `${rect.width}px`;
|
|
1079
|
+
clone.style.height = `${rect.height}px`;
|
|
1080
|
+
}
|
|
1081
|
+
if (node instanceof HTMLInputElement) {
|
|
1082
|
+
clone.value = node.value;
|
|
1083
|
+
clone.setAttribute("value", node.value);
|
|
1084
|
+
if (node.checked !== void 0) {
|
|
1085
|
+
clone.checked = node.checked;
|
|
1086
|
+
if (node.checked) clone.setAttribute("checked", "");
|
|
1087
|
+
if (node.indeterminate) clone.indeterminate = node.indeterminate;
|
|
1088
|
+
}
|
|
956
1089
|
}
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
try {
|
|
960
|
-
clone.setAttribute("data-sd", scopeId);
|
|
961
|
-
} catch (e) {
|
|
1090
|
+
if (node instanceof HTMLSelectElement) {
|
|
1091
|
+
pendingSelectValue = node.value;
|
|
962
1092
|
}
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
1093
|
+
if (node instanceof HTMLTextAreaElement) {
|
|
1094
|
+
pendingTextAreaValue = node.value;
|
|
1095
|
+
}
|
|
1096
|
+
inlineAllStyles(node, clone, sessionCache, options);
|
|
1097
|
+
if (node.shadowRoot) {
|
|
1098
|
+
let callback2 = function(child, resolve) {
|
|
1099
|
+
if (child.nodeType === Node.ELEMENT_NODE && child.tagName === "STYLE") {
|
|
1100
|
+
return resolve(null);
|
|
1101
|
+
} else {
|
|
1102
|
+
deepClone(child, sessionCache, options).then((clonedChild) => {
|
|
1103
|
+
resolve(clonedChild || null);
|
|
1104
|
+
}).catch((e) => {
|
|
1105
|
+
resolve(null);
|
|
1106
|
+
});
|
|
1107
|
+
}
|
|
1108
|
+
};
|
|
1109
|
+
try {
|
|
1110
|
+
const slots = node.shadowRoot.querySelectorAll("slot");
|
|
1111
|
+
for (const s of slots) {
|
|
1112
|
+
let assigned = [];
|
|
1113
|
+
try {
|
|
1114
|
+
assigned = ((_c = s.assignedNodes) == null ? void 0 : _c.call(s, { flatten: true })) || ((_d = s.assignedNodes) == null ? void 0 : _d.call(s)) || [];
|
|
1115
|
+
} catch (e) {
|
|
1116
|
+
assigned = ((_e = s.assignedNodes) == null ? void 0 : _e.call(s)) || [];
|
|
1117
|
+
}
|
|
1118
|
+
for (const an of assigned) clonedAssignedNodes.add(an);
|
|
1119
|
+
}
|
|
1120
|
+
} catch (e) {
|
|
1121
|
+
}
|
|
1122
|
+
const scopeId = nextShadowScopeId(sessionCache);
|
|
1123
|
+
const scopeSelector = `[data-sd="${scopeId}"]`;
|
|
1124
|
+
try {
|
|
1125
|
+
clone.setAttribute("data-sd", scopeId);
|
|
1126
|
+
} catch (e) {
|
|
985
1127
|
}
|
|
1128
|
+
const rawCSS = extractShadowCSS(node.shadowRoot);
|
|
1129
|
+
const rewritten = rewriteShadowCSS(rawCSS, scopeSelector);
|
|
1130
|
+
const neededVars = collectCustomPropsFromCSS(rawCSS);
|
|
1131
|
+
const seed = buildSeedCustomPropsRule(node, neededVars, scopeSelector);
|
|
1132
|
+
injectScopedStyle(clone, seed + rewritten, scopeId);
|
|
1133
|
+
const shadowFrag = document.createDocumentFragment();
|
|
1134
|
+
const cloneList2 = yield idleCallback(Array.from(node.shadowRoot.childNodes), callback2, options.fast);
|
|
1135
|
+
shadowFrag.append(...cloneList2.filter((clonedChild) => !!clonedChild));
|
|
1136
|
+
clone.appendChild(shadowFrag);
|
|
1137
|
+
}
|
|
1138
|
+
if (node.tagName === "SLOT") {
|
|
1139
|
+
let callback2 = function(child, resolve) {
|
|
1140
|
+
deepClone(child, sessionCache, options).then((clonedChild) => {
|
|
1141
|
+
if (clonedChild) {
|
|
1142
|
+
markSlottedSubtree(clonedChild);
|
|
1143
|
+
}
|
|
1144
|
+
resolve(clonedChild || null);
|
|
1145
|
+
}).catch((e) => {
|
|
1146
|
+
resolve(null);
|
|
1147
|
+
});
|
|
1148
|
+
};
|
|
1149
|
+
const assigned = ((_f = node.assignedNodes) == null ? void 0 : _f.call(node, { flatten: true })) || [];
|
|
1150
|
+
const nodesToClone = assigned.length > 0 ? assigned : Array.from(node.childNodes);
|
|
1151
|
+
const fragment = document.createDocumentFragment();
|
|
1152
|
+
const cloneList2 = yield idleCallback(Array.from(nodesToClone), callback2, options.fast);
|
|
1153
|
+
fragment.append(...cloneList2.filter((clonedChild) => !!clonedChild));
|
|
1154
|
+
return fragment;
|
|
1155
|
+
}
|
|
1156
|
+
function callback(child, resolve) {
|
|
1157
|
+
if (clonedAssignedNodes.has(child)) return resolve(null);
|
|
1158
|
+
deepClone(child, sessionCache, options).then((clonedChild) => {
|
|
1159
|
+
resolve(clonedChild || null);
|
|
1160
|
+
}).catch((e) => {
|
|
1161
|
+
resolve(null);
|
|
1162
|
+
});
|
|
986
1163
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
if (opt.value === pendingSelectValue) {
|
|
998
|
-
opt.setAttribute("selected", "");
|
|
999
|
-
} else {
|
|
1000
|
-
opt.removeAttribute("selected");
|
|
1164
|
+
const cloneList = yield idleCallback(Array.from(node.childNodes), callback, options.fast);
|
|
1165
|
+
clone.append(...cloneList.filter((clonedChild) => !!clonedChild));
|
|
1166
|
+
if (pendingSelectValue !== null && clone instanceof HTMLSelectElement) {
|
|
1167
|
+
clone.value = pendingSelectValue;
|
|
1168
|
+
for (const opt of clone.options) {
|
|
1169
|
+
if (opt.value === pendingSelectValue) {
|
|
1170
|
+
opt.setAttribute("selected", "");
|
|
1171
|
+
} else {
|
|
1172
|
+
opt.removeAttribute("selected");
|
|
1173
|
+
}
|
|
1001
1174
|
}
|
|
1002
1175
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1176
|
+
if (pendingTextAreaValue !== null && clone instanceof HTMLTextAreaElement) {
|
|
1177
|
+
clone.textContent = pendingTextAreaValue;
|
|
1178
|
+
}
|
|
1179
|
+
return clone;
|
|
1180
|
+
});
|
|
1005
1181
|
}
|
|
1006
1182
|
|
|
1007
1183
|
// src/modules/iconFonts.js
|
|
@@ -1891,7 +2067,7 @@
|
|
|
1891
2067
|
console.warn("inlineExternal defs or symbol failed:", e);
|
|
1892
2068
|
}
|
|
1893
2069
|
try {
|
|
1894
|
-
clone = deepClone(element, sessionCache, options, element);
|
|
2070
|
+
clone = yield deepClone(element, sessionCache, options, element);
|
|
1895
2071
|
} catch (e) {
|
|
1896
2072
|
console.warn("deepClone failed:", e);
|
|
1897
2073
|
throw e;
|
|
@@ -2125,6 +2301,7 @@
|
|
|
2125
2301
|
return __async(this, arguments, function* (clone, options = {}) {
|
|
2126
2302
|
const imgs = Array.from(clone.querySelectorAll("img"));
|
|
2127
2303
|
const processImg = (img) => __async(null, null, function* () {
|
|
2304
|
+
var _a, _b, _c, _d;
|
|
2128
2305
|
if (!img.getAttribute("src")) {
|
|
2129
2306
|
const eff = img.currentSrc || img.src || "";
|
|
2130
2307
|
if (eff) img.setAttribute("src", eff);
|
|
@@ -2140,22 +2317,52 @@
|
|
|
2140
2317
|
if (!img.height) img.height = img.naturalHeight || 100;
|
|
2141
2318
|
return;
|
|
2142
2319
|
}
|
|
2320
|
+
const { defaultImageUrl } = options || {};
|
|
2321
|
+
if (defaultImageUrl) {
|
|
2322
|
+
try {
|
|
2323
|
+
const dsW = parseInt(((_a = img.dataset) == null ? void 0 : _a.snapdomWidth) || "", 10) || 0;
|
|
2324
|
+
const dsH = parseInt(((_b = img.dataset) == null ? void 0 : _b.snapdomHeight) || "", 10) || 0;
|
|
2325
|
+
const attrW = parseInt(img.getAttribute("width") || "", 10) || 0;
|
|
2326
|
+
const attrH = parseInt(img.getAttribute("height") || "", 10) || 0;
|
|
2327
|
+
const styleW = parseFloat(((_c = img.style) == null ? void 0 : _c.width) || "") || 0;
|
|
2328
|
+
const styleH = parseFloat(((_d = img.style) == null ? void 0 : _d.height) || "") || 0;
|
|
2329
|
+
const width = dsW || styleW || attrW || img.width || void 0;
|
|
2330
|
+
const height = dsH || styleH || attrH || img.height || void 0;
|
|
2331
|
+
const fallbackUrl = typeof defaultImageUrl === "function" ? yield defaultImageUrl({ width, height, src, element: img }) : defaultImageUrl;
|
|
2332
|
+
if (fallbackUrl) {
|
|
2333
|
+
const fallbackData = yield snapFetch(fallbackUrl, { as: "dataURL", useProxy: options.useProxy });
|
|
2334
|
+
img.src = fallbackData.data;
|
|
2335
|
+
if (!img.width && width) img.width = width;
|
|
2336
|
+
if (!img.height && height) img.height = height;
|
|
2337
|
+
if (!img.width) img.width = img.naturalWidth || 100;
|
|
2338
|
+
if (!img.height) img.height = img.naturalHeight || 100;
|
|
2339
|
+
return;
|
|
2340
|
+
}
|
|
2341
|
+
} catch (e) {
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2143
2344
|
const w = img.width || img.naturalWidth || 100;
|
|
2144
2345
|
const h = img.height || img.naturalHeight || 100;
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2346
|
+
if (options.placeholders !== false) {
|
|
2347
|
+
const fallback = document.createElement("div");
|
|
2348
|
+
fallback.style.cssText = [
|
|
2349
|
+
`width:${w}px`,
|
|
2350
|
+
`height:${h}px`,
|
|
2351
|
+
"background:#ccc",
|
|
2352
|
+
"display:inline-block",
|
|
2353
|
+
"text-align:center",
|
|
2354
|
+
`line-height:${h}px`,
|
|
2355
|
+
"color:#666",
|
|
2356
|
+
"font-size:12px",
|
|
2357
|
+
"overflow:hidden"
|
|
2358
|
+
].join(";");
|
|
2359
|
+
fallback.textContent = "img";
|
|
2360
|
+
img.replaceWith(fallback);
|
|
2361
|
+
} else {
|
|
2362
|
+
const spacer = document.createElement("div");
|
|
2363
|
+
spacer.style.cssText = `display:inline-block;width:${w}px;height:${h}px;visibility:hidden;`;
|
|
2364
|
+
img.replaceWith(spacer);
|
|
2365
|
+
}
|
|
2159
2366
|
});
|
|
2160
2367
|
for (let i = 0; i < imgs.length; i += 4) {
|
|
2161
2368
|
const group = imgs.slice(i, i + 4).map(processImg);
|
|
@@ -2251,7 +2458,13 @@
|
|
|
2251
2458
|
);
|
|
2252
2459
|
yield ensureFontsReady(families, 2);
|
|
2253
2460
|
}
|
|
2254
|
-
fontsCSS = yield embedCustomFonts({
|
|
2461
|
+
fontsCSS = yield embedCustomFonts({
|
|
2462
|
+
required,
|
|
2463
|
+
usedCodepoints,
|
|
2464
|
+
preCached: false,
|
|
2465
|
+
exclude: options.excludeFonts,
|
|
2466
|
+
useProxy: options.useProxy
|
|
2467
|
+
});
|
|
2255
2468
|
resolve();
|
|
2256
2469
|
}), { fast });
|
|
2257
2470
|
});
|
|
@@ -2271,12 +2484,14 @@
|
|
|
2271
2484
|
}
|
|
2272
2485
|
yield new Promise((resolve) => {
|
|
2273
2486
|
idle(() => {
|
|
2274
|
-
|
|
2487
|
+
var _a, _b, _c, _d, _e;
|
|
2488
|
+
const rect = getNaturalBorderBoxSize(element);
|
|
2275
2489
|
let w = rect.width;
|
|
2276
2490
|
let h = rect.height;
|
|
2277
2491
|
const hasW = Number.isFinite(options.width);
|
|
2278
2492
|
const hasH = Number.isFinite(options.height);
|
|
2279
|
-
const
|
|
2493
|
+
const scaleOpt = (_a = options.scale) != null ? _a : 1;
|
|
2494
|
+
const hasScale = typeof scaleOpt === "number" && scaleOpt !== 1;
|
|
2280
2495
|
if (!hasScale) {
|
|
2281
2496
|
const aspect = rect.width / rect.height;
|
|
2282
2497
|
if (hasW && hasH) {
|
|
@@ -2290,30 +2505,79 @@
|
|
|
2290
2505
|
w = h * aspect;
|
|
2291
2506
|
}
|
|
2292
2507
|
}
|
|
2293
|
-
w = Math.ceil(w);
|
|
2294
|
-
h = Math.ceil(h);
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
const
|
|
2301
|
-
const
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2508
|
+
w = Math.max(1, Math.ceil(w));
|
|
2509
|
+
h = Math.max(1, Math.ceil(h));
|
|
2510
|
+
const csEl = getComputedStyle(element);
|
|
2511
|
+
const baseTransform = csEl.transform && csEl.transform !== "none" ? csEl.transform : "";
|
|
2512
|
+
const ind = readIndividualTransforms(element);
|
|
2513
|
+
let outW, outH, tx, ty, cancelTranslateX = 0, cancelTranslateY = 0;
|
|
2514
|
+
if (!hasBBoxAffectingTransform(element)) {
|
|
2515
|
+
const r = element.getBoundingClientRect();
|
|
2516
|
+
const vp = inflateRect(r, { top: 0, right: 0, bottom: 0, left: 0 });
|
|
2517
|
+
outW = Math.max(1, vp.width);
|
|
2518
|
+
outH = Math.max(1, vp.height);
|
|
2519
|
+
tx = -(vp.x - Math.floor(r.left));
|
|
2520
|
+
ty = -(vp.y - Math.floor(r.top));
|
|
2521
|
+
} else {
|
|
2522
|
+
const TOTAL = readTotalTransformMatrix({
|
|
2523
|
+
baseTransform,
|
|
2524
|
+
rotate: ind.rotate || "0deg",
|
|
2525
|
+
scale: ind.scale,
|
|
2526
|
+
translate: ind.translate
|
|
2527
|
+
});
|
|
2528
|
+
const e = (_c = (_b = TOTAL.e) != null ? _b : TOTAL.m41) != null ? _c : 0;
|
|
2529
|
+
const f = (_e = (_d = TOTAL.f) != null ? _d : TOTAL.m42) != null ? _e : 0;
|
|
2530
|
+
cancelTranslateX = -e;
|
|
2531
|
+
cancelTranslateY = -f;
|
|
2532
|
+
const M2D = TOTAL.is2D ? matrix2DNoTranslate(TOTAL) : matrix2DNoTranslate(new DOMMatrix(TOTAL.toString()));
|
|
2533
|
+
const bb = bboxFromMatrix(w, h, M2D);
|
|
2534
|
+
outW = Math.max(1, Math.ceil(bb.width));
|
|
2535
|
+
outH = Math.max(1, Math.ceil(bb.height));
|
|
2536
|
+
tx = -bb.minX;
|
|
2537
|
+
ty = -bb.minY;
|
|
2305
2538
|
}
|
|
2306
2539
|
const svgNS = "http://www.w3.org/2000/svg";
|
|
2307
2540
|
const fo = document.createElementNS(svgNS, "foreignObject");
|
|
2308
2541
|
fo.setAttribute("width", "100%");
|
|
2309
2542
|
fo.setAttribute("height", "100%");
|
|
2543
|
+
fo.setAttribute("x", String(tx));
|
|
2544
|
+
fo.setAttribute("y", String(ty));
|
|
2545
|
+
fo.style.overflow = "visible";
|
|
2310
2546
|
const styleTag = document.createElement("style");
|
|
2311
|
-
styleTag.textContent = baseCSS + fontsCSS + "svg{overflow:visible;}" + classCSS;
|
|
2547
|
+
styleTag.textContent = baseCSS + fontsCSS + "svg{overflow:visible;} foreignObject{overflow:visible;}" + classCSS;
|
|
2312
2548
|
fo.appendChild(styleTag);
|
|
2313
|
-
|
|
2549
|
+
const container = document.createElement("div");
|
|
2550
|
+
container.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
2551
|
+
container.style.width = `${w}px`;
|
|
2552
|
+
container.style.height = `${h}px`;
|
|
2553
|
+
container.style.overflow = "visible";
|
|
2554
|
+
container.style.transformOrigin = "0 0";
|
|
2555
|
+
const cancels = [];
|
|
2556
|
+
if (cancelTranslateX || cancelTranslateY) {
|
|
2557
|
+
cancels.push(`translate(${cancelTranslateX}px, ${cancelTranslateY}px)`);
|
|
2558
|
+
}
|
|
2559
|
+
if (!hasScale && (hasW || hasH)) {
|
|
2560
|
+
const sxWH = rect.width ? w / rect.width : 1;
|
|
2561
|
+
const syWH = rect.height ? h / rect.height : 1;
|
|
2562
|
+
cancels.push(`scale(${sxWH}, ${syWH})`);
|
|
2563
|
+
} else if (hasScale) {
|
|
2564
|
+
cancels.push(`scale(${scaleOpt})`);
|
|
2565
|
+
}
|
|
2566
|
+
if (cancels.length) container.style.transform = cancels.join(" ");
|
|
2567
|
+
clone.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
2568
|
+
clone.style.transformOrigin = "0 0";
|
|
2569
|
+
clone.style.position = "static";
|
|
2570
|
+
clone.style.left = "0";
|
|
2571
|
+
clone.style.top = "0";
|
|
2572
|
+
if (baseTransform) clone.style.transform = baseTransform;
|
|
2573
|
+
clone.style.rotate = ind.rotate || "0deg";
|
|
2574
|
+
clone.style.scale = ind.scale || "1";
|
|
2575
|
+
clone.style.translate = ind.translate || "0 0";
|
|
2576
|
+
container.appendChild(clone);
|
|
2577
|
+
fo.appendChild(container);
|
|
2314
2578
|
const serializer = new XMLSerializer();
|
|
2315
2579
|
const foString = serializer.serializeToString(fo);
|
|
2316
|
-
const svgHeader = `<svg xmlns="${svgNS}" width="${
|
|
2580
|
+
const svgHeader = `<svg xmlns="${svgNS}" width="${outW}" height="${outH}" viewBox="0 0 ${outW} ${outH}">`;
|
|
2317
2581
|
const svgFooter = "</svg>";
|
|
2318
2582
|
svgString = svgHeader + foString + svgFooter;
|
|
2319
2583
|
dataURL = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
|
|
@@ -2325,6 +2589,129 @@
|
|
|
2325
2589
|
return dataURL;
|
|
2326
2590
|
});
|
|
2327
2591
|
}
|
|
2592
|
+
function getNaturalBorderBoxSize(el) {
|
|
2593
|
+
const cs = getComputedStyle(el);
|
|
2594
|
+
const px = (v) => parseFloat(v) || 0;
|
|
2595
|
+
let w = px(cs.width);
|
|
2596
|
+
let h = px(cs.height);
|
|
2597
|
+
if (cs.boxSizing === "content-box") {
|
|
2598
|
+
w += px(cs.paddingLeft) + px(cs.paddingRight) + px(cs.borderLeftWidth) + px(cs.borderRightWidth);
|
|
2599
|
+
h += px(cs.paddingTop) + px(cs.paddingBottom) + px(cs.borderTopWidth) + px(cs.borderBottomWidth);
|
|
2600
|
+
}
|
|
2601
|
+
return { width: w, height: h };
|
|
2602
|
+
}
|
|
2603
|
+
function matrixFromComputed(el) {
|
|
2604
|
+
const tr = getComputedStyle(el).transform;
|
|
2605
|
+
if (!tr || tr === "none") return new DOMMatrix();
|
|
2606
|
+
try {
|
|
2607
|
+
return new DOMMatrix(tr);
|
|
2608
|
+
} catch (e) {
|
|
2609
|
+
return new WebKitCSSMatrix(tr);
|
|
2610
|
+
}
|
|
2611
|
+
}
|
|
2612
|
+
function matrix2DNoTranslate(M) {
|
|
2613
|
+
return new DOMMatrix([M.a, M.b, M.c, M.d, 0, 0]);
|
|
2614
|
+
}
|
|
2615
|
+
function bboxFromMatrix(w, h, M2D) {
|
|
2616
|
+
const pts = [
|
|
2617
|
+
{ x: 0, y: 0 },
|
|
2618
|
+
{ x: w, y: 0 },
|
|
2619
|
+
{ x: 0, y: h },
|
|
2620
|
+
{ x: w, y: h }
|
|
2621
|
+
];
|
|
2622
|
+
const t = pts.map((p) => ({
|
|
2623
|
+
x: M2D.a * p.x + M2D.c * p.y,
|
|
2624
|
+
y: M2D.b * p.x + M2D.d * p.y
|
|
2625
|
+
}));
|
|
2626
|
+
const minX = Math.min(...t.map((p) => p.x));
|
|
2627
|
+
const maxX = Math.max(...t.map((p) => p.x));
|
|
2628
|
+
const minY = Math.min(...t.map((p) => p.y));
|
|
2629
|
+
const maxY = Math.max(...t.map((p) => p.y));
|
|
2630
|
+
return { minX, minY, width: maxX - minX, height: maxY - minY };
|
|
2631
|
+
}
|
|
2632
|
+
function readIndividualTransforms(el) {
|
|
2633
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
2634
|
+
const out = { rotate: "0deg", scale: null, translate: null };
|
|
2635
|
+
const map = (_a = el.computedStyleMap) == null ? void 0 : _a.call(el);
|
|
2636
|
+
if (map) {
|
|
2637
|
+
const rot = map.get("rotate");
|
|
2638
|
+
if (rot) {
|
|
2639
|
+
const ang = (_b = rot.angle) != null ? _b : rot;
|
|
2640
|
+
if (ang && "unit" in ang) {
|
|
2641
|
+
out.rotate = ang.unit === "rad" ? ang.value * 180 / Math.PI + "deg" : ang.value + ang.unit;
|
|
2642
|
+
} else {
|
|
2643
|
+
out.rotate = String(rot);
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
const sc = map.get("scale");
|
|
2647
|
+
if (sc && sc.length) {
|
|
2648
|
+
const sx = (_d = (_c = sc[0]) == null ? void 0 : _c.value) != null ? _d : 1;
|
|
2649
|
+
const sy = (_f = (_e = sc[1]) == null ? void 0 : _e.value) != null ? _f : sx;
|
|
2650
|
+
out.scale = `${sx} ${sy}`;
|
|
2651
|
+
}
|
|
2652
|
+
const tr = map.get("translate");
|
|
2653
|
+
if (tr && tr.length) {
|
|
2654
|
+
const tx = (_h = (_g = tr[0]) == null ? void 0 : _g.value) != null ? _h : 0;
|
|
2655
|
+
const ty = (_j = (_i = tr[1]) == null ? void 0 : _i.value) != null ? _j : 0;
|
|
2656
|
+
const ux = (_l = (_k = tr[0]) == null ? void 0 : _k.unit) != null ? _l : "px";
|
|
2657
|
+
const uy = (_n = (_m = tr[1]) == null ? void 0 : _m.unit) != null ? _n : "px";
|
|
2658
|
+
out.translate = `${tx}${ux} ${ty}${uy}`;
|
|
2659
|
+
}
|
|
2660
|
+
return out;
|
|
2661
|
+
}
|
|
2662
|
+
const cs = getComputedStyle(el);
|
|
2663
|
+
out.rotate = cs.rotate && cs.rotate !== "none" ? cs.rotate : "0deg";
|
|
2664
|
+
out.scale = cs.scale && cs.scale !== "none" ? cs.scale : null;
|
|
2665
|
+
out.translate = cs.translate && cs.translate !== "none" ? cs.translate : null;
|
|
2666
|
+
return out;
|
|
2667
|
+
}
|
|
2668
|
+
function hasBBoxAffectingTransform(el) {
|
|
2669
|
+
const t = getComputedStyle(el).transform || "none";
|
|
2670
|
+
if (t === "none" || t === "matrix(1, 0, 0, 1, 0, 0)") return false;
|
|
2671
|
+
if (/^matrix\(\s*1\s*,\s*0\s*,\s*0\s*,\s*1\s*,/i.test(t)) return false;
|
|
2672
|
+
return true;
|
|
2673
|
+
}
|
|
2674
|
+
function inflateRect(r, p) {
|
|
2675
|
+
const x = Math.floor(r.left - p.left);
|
|
2676
|
+
const y = Math.floor(r.top - p.top);
|
|
2677
|
+
const w = Math.ceil(r.width + p.left + p.right);
|
|
2678
|
+
const h = Math.ceil(r.height + p.top + p.bottom);
|
|
2679
|
+
return { x, y, width: w, height: h };
|
|
2680
|
+
}
|
|
2681
|
+
var __measureHost = null;
|
|
2682
|
+
function getMeasureHost() {
|
|
2683
|
+
if (__measureHost) return __measureHost;
|
|
2684
|
+
const n = document.createElement("div");
|
|
2685
|
+
n.id = "snapdom-measure-slot";
|
|
2686
|
+
n.setAttribute("aria-hidden", "true");
|
|
2687
|
+
Object.assign(n.style, {
|
|
2688
|
+
position: "absolute",
|
|
2689
|
+
left: "-99999px",
|
|
2690
|
+
top: "0px",
|
|
2691
|
+
width: "0px",
|
|
2692
|
+
height: "0px",
|
|
2693
|
+
overflow: "hidden",
|
|
2694
|
+
opacity: "0",
|
|
2695
|
+
pointerEvents: "none",
|
|
2696
|
+
contain: "size layout style"
|
|
2697
|
+
});
|
|
2698
|
+
document.documentElement.appendChild(n);
|
|
2699
|
+
__measureHost = n;
|
|
2700
|
+
return n;
|
|
2701
|
+
}
|
|
2702
|
+
function readTotalTransformMatrix(t) {
|
|
2703
|
+
const host = getMeasureHost();
|
|
2704
|
+
const tmp = document.createElement("div");
|
|
2705
|
+
tmp.style.transformOrigin = "0 0";
|
|
2706
|
+
if (t.baseTransform) tmp.style.transform = t.baseTransform;
|
|
2707
|
+
if (t.rotate) tmp.style.rotate = t.rotate;
|
|
2708
|
+
if (t.scale) tmp.style.scale = t.scale;
|
|
2709
|
+
if (t.translate) tmp.style.translate = t.translate;
|
|
2710
|
+
host.appendChild(tmp);
|
|
2711
|
+
const M = matrixFromComputed(tmp);
|
|
2712
|
+
host.removeChild(tmp);
|
|
2713
|
+
return M;
|
|
2714
|
+
}
|
|
2328
2715
|
|
|
2329
2716
|
// src/core/context.js
|
|
2330
2717
|
function normalizeCachePolicy(v) {
|
|
@@ -2340,7 +2727,7 @@
|
|
|
2340
2727
|
return "soft";
|
|
2341
2728
|
}
|
|
2342
2729
|
function createContext(options = {}) {
|
|
2343
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
|
|
2730
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
2344
2731
|
const resolvedFormat = (_a = options.format) != null ? _a : "png";
|
|
2345
2732
|
const cachePolicy = normalizeCachePolicy(options.cache);
|
|
2346
2733
|
return {
|
|
@@ -2351,25 +2738,28 @@
|
|
|
2351
2738
|
// DOM filters
|
|
2352
2739
|
exclude: (_e = options.exclude) != null ? _e : [],
|
|
2353
2740
|
filter: (_f = options.filter) != null ? _f : null,
|
|
2741
|
+
placeholders: options.placeholders !== false,
|
|
2742
|
+
// default true
|
|
2354
2743
|
// Fuentes
|
|
2355
2744
|
embedFonts: (_g = options.embedFonts) != null ? _g : false,
|
|
2356
2745
|
iconFonts: Array.isArray(options.iconFonts) ? options.iconFonts : options.iconFonts ? [options.iconFonts] : [],
|
|
2357
2746
|
localFonts: Array.isArray(options.localFonts) ? options.localFonts : [],
|
|
2358
2747
|
excludeFonts: (_h = options.excludeFonts) != null ? _h : void 0,
|
|
2748
|
+
defaultImageUrl: (_i = options.defaultImageUrl) != null ? _i : void 0,
|
|
2359
2749
|
/** Cache policy (disabled|full|auto|soft). Default: "soft" */
|
|
2360
2750
|
/** @type {CachePolicy} */
|
|
2361
2751
|
cache: cachePolicy,
|
|
2362
2752
|
// Red
|
|
2363
2753
|
useProxy: typeof options.useProxy === "string" ? options.useProxy : "",
|
|
2364
2754
|
// Salida
|
|
2365
|
-
width: (
|
|
2366
|
-
height: (
|
|
2755
|
+
width: (_j = options.width) != null ? _j : null,
|
|
2756
|
+
height: (_k = options.height) != null ? _k : null,
|
|
2367
2757
|
format: resolvedFormat,
|
|
2368
|
-
type: (
|
|
2369
|
-
quality: (
|
|
2370
|
-
dpr: (
|
|
2371
|
-
backgroundColor: (
|
|
2372
|
-
filename: (
|
|
2758
|
+
type: (_l = options.type) != null ? _l : "svg",
|
|
2759
|
+
quality: (_m = options.quality) != null ? _m : 0.92,
|
|
2760
|
+
dpr: (_n = options.dpr) != null ? _n : window.devicePixelRatio || 1,
|
|
2761
|
+
backgroundColor: (_o = options.backgroundColor) != null ? _o : ["jpg", "jpeg", "webp"].includes(resolvedFormat) ? "#ffffff" : null,
|
|
2762
|
+
filename: (_p = options.filename) != null ? _p : "snapDOM"
|
|
2373
2763
|
// Plugins (reservado para futura activación)
|
|
2374
2764
|
// plugins: normalizePlugins(...),
|
|
2375
2765
|
};
|
|
@@ -2392,31 +2782,41 @@
|
|
|
2392
2782
|
// src/exporters/toCanvas.js
|
|
2393
2783
|
function toCanvas(url, options) {
|
|
2394
2784
|
return __async(this, null, function* () {
|
|
2785
|
+
const { scale, dpr } = options;
|
|
2786
|
+
const safari = isSafari();
|
|
2395
2787
|
const img = new Image();
|
|
2396
2788
|
img.crossOrigin = "anonymous";
|
|
2397
2789
|
img.loading = "eager";
|
|
2398
2790
|
img.decoding = "sync";
|
|
2399
2791
|
img.src = url;
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2792
|
+
let tempSlot = null;
|
|
2793
|
+
if (safari) {
|
|
2794
|
+
tempSlot = document.createElement("div");
|
|
2795
|
+
tempSlot.setAttribute("aria-hidden", "true");
|
|
2796
|
+
tempSlot.style.cssText = "position:absolute;left:-99999px;top:0;width:0;height:0;overflow:hidden;opacity:0;pointer-events:none;contain:size layout style;";
|
|
2797
|
+
document.body.appendChild(tempSlot);
|
|
2798
|
+
tempSlot.appendChild(img);
|
|
2405
2799
|
}
|
|
2406
2800
|
yield img.decode();
|
|
2407
|
-
if (
|
|
2408
|
-
|
|
2409
|
-
|
|
2801
|
+
if (safari) {
|
|
2802
|
+
yield new Promise((r) => setTimeout(r, 100));
|
|
2803
|
+
}
|
|
2804
|
+
const width = img.naturalWidth * scale;
|
|
2805
|
+
const height = img.naturalHeight * scale;
|
|
2410
2806
|
const canvas = document.createElement("canvas");
|
|
2411
|
-
const dpr = options.dpr;
|
|
2412
2807
|
canvas.width = Math.ceil(width * dpr);
|
|
2413
2808
|
canvas.height = Math.ceil(height * dpr);
|
|
2414
2809
|
canvas.style.width = `${width}px`;
|
|
2415
2810
|
canvas.style.height = `${height}px`;
|
|
2416
2811
|
const ctx = canvas.getContext("2d");
|
|
2417
|
-
ctx.scale(dpr, dpr);
|
|
2812
|
+
if (dpr !== 1) ctx.scale(dpr, dpr);
|
|
2418
2813
|
ctx.drawImage(img, 0, 0, width, height);
|
|
2419
|
-
if (
|
|
2814
|
+
if (tempSlot && tempSlot.parentNode) {
|
|
2815
|
+
try {
|
|
2816
|
+
tempSlot.parentNode.removeChild(tempSlot);
|
|
2817
|
+
} catch (e) {
|
|
2818
|
+
}
|
|
2819
|
+
}
|
|
2420
2820
|
return canvas;
|
|
2421
2821
|
});
|
|
2422
2822
|
}
|
|
@@ -2484,6 +2884,14 @@
|
|
|
2484
2884
|
if (!element) throw new Error("Element cannot be null or undefined");
|
|
2485
2885
|
const context = createContext(userOptions);
|
|
2486
2886
|
if (context.iconFonts && context.iconFonts.length > 0) extendIconFonts(context.iconFonts);
|
|
2887
|
+
if (!context.snap) {
|
|
2888
|
+
context.snap = {
|
|
2889
|
+
/** Delegates to this module’s PNG path (tu build devuelve <img>). */
|
|
2890
|
+
toPng: (el, opts) => snapdom.toPng(el, opts),
|
|
2891
|
+
/** Útil si en algún flujo necesitás vector o <img> directo. */
|
|
2892
|
+
toImg: (el, opts) => snapdom.toImg(el, opts)
|
|
2893
|
+
};
|
|
2894
|
+
}
|
|
2487
2895
|
return snapdom.capture(element, context, INTERNAL_TOKEN);
|
|
2488
2896
|
});
|
|
2489
2897
|
}
|