@zumer/snapdom 1.9.10-dev.1 → 1.9.10
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 +94 -43
- package/dist/snapdom.js +614 -197
- package/dist/snapdom.min.js +4 -4
- package/dist/snapdom.min.mjs +5 -5
- package/dist/snapdom.mjs +465 -58
- package/package.json +1 -1
- package/types/snapdom.d.ts +108 -50
package/dist/snapdom.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
/*
|
|
3
3
|
* snapdom
|
|
4
|
-
* v.1.9.10
|
|
4
|
+
* v.1.9.10
|
|
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: {
|
|
@@ -687,6 +690,11 @@
|
|
|
687
690
|
const ctx = _resolveCtx(sessionOrCtx, opts);
|
|
688
691
|
const resetMode = ctx.options && ctx.options.cache || "auto";
|
|
689
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
|
+
}
|
|
690
698
|
if (NO_DEFAULTS_TAGS.has((_a = source.tagName) == null ? void 0 : _a.toLowerCase())) {
|
|
691
699
|
const author = (_b = source.getAttribute) == null ? void 0 : _b.call(source, "style");
|
|
692
700
|
if (author) clone.setAttribute("style", author);
|
|
@@ -709,6 +717,31 @@
|
|
|
709
717
|
}
|
|
710
718
|
|
|
711
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
|
+
}
|
|
712
745
|
function addNotSlottedRightmost(sel) {
|
|
713
746
|
sel = sel.trim();
|
|
714
747
|
if (!sel) return sel;
|
|
@@ -830,185 +863,321 @@
|
|
|
830
863
|
root.querySelectorAll("*").forEach((el) => el.setAttribute("data-sd-slotted", ""));
|
|
831
864
|
}
|
|
832
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
|
+
}
|
|
833
944
|
function deepClone(node, sessionCache, options) {
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
if (node.
|
|
841
|
-
|
|
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
|
+
}
|
|
842
959
|
}
|
|
843
|
-
if (
|
|
844
|
-
return
|
|
960
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
961
|
+
return node.cloneNode(true);
|
|
845
962
|
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
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") {
|
|
861
987
|
try {
|
|
862
|
-
if (
|
|
988
|
+
if (!options.filter(node)) {
|
|
863
989
|
const spacer = document.createElement("div");
|
|
864
990
|
const rect = node.getBoundingClientRect();
|
|
865
991
|
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
866
992
|
return spacer;
|
|
867
993
|
}
|
|
868
994
|
} catch (err) {
|
|
869
|
-
console.warn(
|
|
995
|
+
console.warn("Error in filter function:", err);
|
|
870
996
|
}
|
|
871
997
|
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
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 {
|
|
877
1019
|
const rect = node.getBoundingClientRect();
|
|
1020
|
+
const spacer = document.createElement("div");
|
|
878
1021
|
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
1022
|
+
inlineAllStyles(node, spacer, sessionCache, options);
|
|
879
1023
|
return spacer;
|
|
880
1024
|
}
|
|
881
|
-
} catch (err) {
|
|
882
|
-
console.warn("Error in filter function:", err);
|
|
883
1025
|
}
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
const placeholder = document.createElement("div");
|
|
904
|
-
placeholder.textContent = node.getAttribute("data-placeholder-text") || "";
|
|
905
|
-
placeholder.style.cssText = `color:#666;font-size:12px;text-align:center;line-height:1.4;padding:0.5em;box-sizing:border-box;`;
|
|
906
|
-
clone2.appendChild(placeholder);
|
|
907
|
-
return clone2;
|
|
908
|
-
}
|
|
909
|
-
if (node.tagName === "CANVAS") {
|
|
910
|
-
const dataURL = node.toDataURL();
|
|
911
|
-
const img = document.createElement("img");
|
|
912
|
-
img.src = dataURL;
|
|
913
|
-
img.width = node.width;
|
|
914
|
-
img.height = node.height;
|
|
915
|
-
sessionCache.nodeMap.set(img, node);
|
|
916
|
-
inlineAllStyles(node, img, sessionCache, options);
|
|
917
|
-
return img;
|
|
918
|
-
}
|
|
919
|
-
let clone;
|
|
920
|
-
try {
|
|
921
|
-
clone = node.cloneNode(false);
|
|
922
|
-
sessionCache.nodeMap.set(clone, node);
|
|
923
|
-
if (node.tagName === "IMG") {
|
|
924
|
-
freezeImgSrcset(node, clone);
|
|
925
|
-
}
|
|
926
|
-
} catch (err) {
|
|
927
|
-
console.error("[Snapdom] Failed to clone node:", node, err);
|
|
928
|
-
throw err;
|
|
929
|
-
}
|
|
930
|
-
if (node instanceof HTMLTextAreaElement) {
|
|
931
|
-
clone.textContent = node.value;
|
|
932
|
-
clone.value = node.value;
|
|
933
|
-
const rect = node.getBoundingClientRect();
|
|
934
|
-
clone.style.width = `${rect.width}px`;
|
|
935
|
-
clone.style.height = `${rect.height}px`;
|
|
936
|
-
}
|
|
937
|
-
if (node instanceof HTMLInputElement) {
|
|
938
|
-
clone.value = node.value;
|
|
939
|
-
clone.setAttribute("value", node.value);
|
|
940
|
-
if (node.checked !== void 0) {
|
|
941
|
-
clone.checked = node.checked;
|
|
942
|
-
if (node.checked) clone.setAttribute("checked", "");
|
|
943
|
-
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;
|
|
944
1045
|
}
|
|
945
|
-
|
|
946
|
-
if (node instanceof HTMLSelectElement) {
|
|
947
|
-
pendingSelectValue = node.value;
|
|
948
|
-
}
|
|
949
|
-
inlineAllStyles(node, clone, sessionCache, options);
|
|
950
|
-
if (node.shadowRoot) {
|
|
1046
|
+
let clone;
|
|
951
1047
|
try {
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
1048
|
+
clone = node.cloneNode(false);
|
|
1049
|
+
sessionCache.nodeMap.set(clone, node);
|
|
1050
|
+
if (node.tagName === "IMG") {
|
|
1051
|
+
freezeImgSrcset(node, clone);
|
|
955
1052
|
try {
|
|
956
|
-
|
|
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);
|
|
957
1069
|
} catch (e) {
|
|
958
|
-
assigned = ((_d = s.assignedNodes) == null ? void 0 : _d.call(s)) || [];
|
|
959
1070
|
}
|
|
960
|
-
for (const an of assigned) clonedAssignedNodes.add(an);
|
|
961
1071
|
}
|
|
962
|
-
} catch (
|
|
1072
|
+
} catch (err) {
|
|
1073
|
+
console.error("[Snapdom] Failed to clone node:", node, err);
|
|
1074
|
+
throw err;
|
|
963
1075
|
}
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
clone.
|
|
968
|
-
}
|
|
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
|
+
}
|
|
969
1089
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1090
|
+
if (node instanceof HTMLSelectElement) {
|
|
1091
|
+
pendingSelectValue = node.value;
|
|
1092
|
+
}
|
|
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) {
|
|
992
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
|
+
});
|
|
993
1163
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
if (opt.value === pendingSelectValue) {
|
|
1005
|
-
opt.setAttribute("selected", "");
|
|
1006
|
-
} else {
|
|
1007
|
-
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
|
+
}
|
|
1008
1174
|
}
|
|
1009
1175
|
}
|
|
1010
|
-
|
|
1011
|
-
|
|
1176
|
+
if (pendingTextAreaValue !== null && clone instanceof HTMLTextAreaElement) {
|
|
1177
|
+
clone.textContent = pendingTextAreaValue;
|
|
1178
|
+
}
|
|
1179
|
+
return clone;
|
|
1180
|
+
});
|
|
1012
1181
|
}
|
|
1013
1182
|
|
|
1014
1183
|
// src/modules/iconFonts.js
|
|
@@ -1898,7 +2067,7 @@
|
|
|
1898
2067
|
console.warn("inlineExternal defs or symbol failed:", e);
|
|
1899
2068
|
}
|
|
1900
2069
|
try {
|
|
1901
|
-
clone = deepClone(element, sessionCache, options, element);
|
|
2070
|
+
clone = yield deepClone(element, sessionCache, options, element);
|
|
1902
2071
|
} catch (e) {
|
|
1903
2072
|
console.warn("deepClone failed:", e);
|
|
1904
2073
|
throw e;
|
|
@@ -2132,6 +2301,7 @@
|
|
|
2132
2301
|
return __async(this, arguments, function* (clone, options = {}) {
|
|
2133
2302
|
const imgs = Array.from(clone.querySelectorAll("img"));
|
|
2134
2303
|
const processImg = (img) => __async(null, null, function* () {
|
|
2304
|
+
var _a, _b, _c, _d;
|
|
2135
2305
|
if (!img.getAttribute("src")) {
|
|
2136
2306
|
const eff = img.currentSrc || img.src || "";
|
|
2137
2307
|
if (eff) img.setAttribute("src", eff);
|
|
@@ -2147,6 +2317,30 @@
|
|
|
2147
2317
|
if (!img.height) img.height = img.naturalHeight || 100;
|
|
2148
2318
|
return;
|
|
2149
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
|
+
}
|
|
2150
2344
|
const w = img.width || img.naturalWidth || 100;
|
|
2151
2345
|
const h = img.height || img.naturalHeight || 100;
|
|
2152
2346
|
if (options.placeholders !== false) {
|
|
@@ -2181,17 +2375,40 @@
|
|
|
2181
2375
|
function inlineBackgroundImages(_0, _1, _2) {
|
|
2182
2376
|
return __async(this, arguments, function* (source, clone, styleCache, options = {}) {
|
|
2183
2377
|
const queue = [[source, clone]];
|
|
2184
|
-
const
|
|
2378
|
+
const URL_PROPS = [
|
|
2185
2379
|
"background-image",
|
|
2380
|
+
// Mask shorthands & images (both standard and WebKit)
|
|
2186
2381
|
"mask",
|
|
2187
2382
|
"mask-image",
|
|
2383
|
+
"-webkit-mask",
|
|
2188
2384
|
"-webkit-mask-image",
|
|
2385
|
+
// Mask sources (rare, but keep)
|
|
2189
2386
|
"mask-source",
|
|
2190
2387
|
"mask-box-image-source",
|
|
2191
2388
|
"mask-border-source",
|
|
2192
2389
|
"-webkit-mask-box-image-source",
|
|
2390
|
+
// Border image
|
|
2193
2391
|
"border-image",
|
|
2194
|
-
"border-image-source"
|
|
2392
|
+
"border-image-source"
|
|
2393
|
+
];
|
|
2394
|
+
const MASK_LAYOUT_PROPS = [
|
|
2395
|
+
"mask-position",
|
|
2396
|
+
"mask-size",
|
|
2397
|
+
"mask-repeat",
|
|
2398
|
+
// WebKit variants
|
|
2399
|
+
"-webkit-mask-position",
|
|
2400
|
+
"-webkit-mask-size",
|
|
2401
|
+
"-webkit-mask-repeat",
|
|
2402
|
+
// Extra (optional but helpful across engines)
|
|
2403
|
+
"mask-origin",
|
|
2404
|
+
"mask-clip",
|
|
2405
|
+
"-webkit-mask-origin",
|
|
2406
|
+
"-webkit-mask-clip",
|
|
2407
|
+
// Some engines expose X/Y position separately:
|
|
2408
|
+
"-webkit-mask-position-x",
|
|
2409
|
+
"-webkit-mask-position-y"
|
|
2410
|
+
];
|
|
2411
|
+
const BORDER_AUX_PROPS = [
|
|
2195
2412
|
"border-image-slice",
|
|
2196
2413
|
"border-image-width",
|
|
2197
2414
|
"border-image-outset",
|
|
@@ -2206,10 +2423,7 @@
|
|
|
2206
2423
|
const bis = style.getPropertyValue("border-image-source");
|
|
2207
2424
|
return bi && bi !== "none" || bis && bis !== "none";
|
|
2208
2425
|
})();
|
|
2209
|
-
for (const prop of
|
|
2210
|
-
if (["border-image-slice", "border-image-width", "border-image-outset", "border-image-repeat"].includes(prop) && !hasBorderImage) {
|
|
2211
|
-
continue;
|
|
2212
|
-
}
|
|
2426
|
+
for (const prop of URL_PROPS) {
|
|
2213
2427
|
const val = style.getPropertyValue(prop);
|
|
2214
2428
|
if (!val || val === "none") continue;
|
|
2215
2429
|
const splits = splitBackgroundImage(val);
|
|
@@ -2220,6 +2434,18 @@
|
|
|
2220
2434
|
cloneNode.style.setProperty(prop, inlined.join(", "));
|
|
2221
2435
|
}
|
|
2222
2436
|
}
|
|
2437
|
+
for (const prop of MASK_LAYOUT_PROPS) {
|
|
2438
|
+
const val = style.getPropertyValue(prop);
|
|
2439
|
+
if (!val || val === "initial") continue;
|
|
2440
|
+
cloneNode.style.setProperty(prop, val);
|
|
2441
|
+
}
|
|
2442
|
+
if (hasBorderImage) {
|
|
2443
|
+
for (const prop of BORDER_AUX_PROPS) {
|
|
2444
|
+
const val = style.getPropertyValue(prop);
|
|
2445
|
+
if (!val || val === "initial") continue;
|
|
2446
|
+
cloneNode.style.setProperty(prop, val);
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2223
2449
|
const sChildren = Array.from(srcNode.children);
|
|
2224
2450
|
const cChildren = Array.from(cloneNode.children);
|
|
2225
2451
|
for (let i = 0; i < Math.min(sChildren.length, cChildren.length); i++) {
|
|
@@ -2264,7 +2490,13 @@
|
|
|
2264
2490
|
);
|
|
2265
2491
|
yield ensureFontsReady(families, 2);
|
|
2266
2492
|
}
|
|
2267
|
-
fontsCSS = yield embedCustomFonts({
|
|
2493
|
+
fontsCSS = yield embedCustomFonts({
|
|
2494
|
+
required,
|
|
2495
|
+
usedCodepoints,
|
|
2496
|
+
preCached: false,
|
|
2497
|
+
exclude: options.excludeFonts,
|
|
2498
|
+
useProxy: options.useProxy
|
|
2499
|
+
});
|
|
2268
2500
|
resolve();
|
|
2269
2501
|
}), { fast });
|
|
2270
2502
|
});
|
|
@@ -2284,12 +2516,14 @@
|
|
|
2284
2516
|
}
|
|
2285
2517
|
yield new Promise((resolve) => {
|
|
2286
2518
|
idle(() => {
|
|
2287
|
-
|
|
2519
|
+
var _a, _b, _c, _d, _e;
|
|
2520
|
+
const rect = getNaturalBorderBoxSize(element);
|
|
2288
2521
|
let w = rect.width;
|
|
2289
2522
|
let h = rect.height;
|
|
2290
2523
|
const hasW = Number.isFinite(options.width);
|
|
2291
2524
|
const hasH = Number.isFinite(options.height);
|
|
2292
|
-
const
|
|
2525
|
+
const scaleOpt = (_a = options.scale) != null ? _a : 1;
|
|
2526
|
+
const hasScale = typeof scaleOpt === "number" && scaleOpt !== 1;
|
|
2293
2527
|
if (!hasScale) {
|
|
2294
2528
|
const aspect = rect.width / rect.height;
|
|
2295
2529
|
if (hasW && hasH) {
|
|
@@ -2303,30 +2537,79 @@
|
|
|
2303
2537
|
w = h * aspect;
|
|
2304
2538
|
}
|
|
2305
2539
|
}
|
|
2306
|
-
w = Math.ceil(w);
|
|
2307
|
-
h = Math.ceil(h);
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
const
|
|
2314
|
-
const
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2540
|
+
w = Math.max(1, Math.ceil(w));
|
|
2541
|
+
h = Math.max(1, Math.ceil(h));
|
|
2542
|
+
const csEl = getComputedStyle(element);
|
|
2543
|
+
const baseTransform = csEl.transform && csEl.transform !== "none" ? csEl.transform : "";
|
|
2544
|
+
const ind = readIndividualTransforms(element);
|
|
2545
|
+
let outW, outH, tx, ty, cancelTranslateX = 0, cancelTranslateY = 0;
|
|
2546
|
+
if (!hasBBoxAffectingTransform(element)) {
|
|
2547
|
+
const r = element.getBoundingClientRect();
|
|
2548
|
+
const vp = inflateRect(r, { top: 0, right: 0, bottom: 0, left: 0 });
|
|
2549
|
+
outW = Math.max(1, vp.width);
|
|
2550
|
+
outH = Math.max(1, vp.height);
|
|
2551
|
+
tx = -(vp.x - Math.floor(r.left));
|
|
2552
|
+
ty = -(vp.y - Math.floor(r.top));
|
|
2553
|
+
} else {
|
|
2554
|
+
const TOTAL = readTotalTransformMatrix({
|
|
2555
|
+
baseTransform,
|
|
2556
|
+
rotate: ind.rotate || "0deg",
|
|
2557
|
+
scale: ind.scale,
|
|
2558
|
+
translate: ind.translate
|
|
2559
|
+
});
|
|
2560
|
+
const e = (_c = (_b = TOTAL.e) != null ? _b : TOTAL.m41) != null ? _c : 0;
|
|
2561
|
+
const f = (_e = (_d = TOTAL.f) != null ? _d : TOTAL.m42) != null ? _e : 0;
|
|
2562
|
+
cancelTranslateX = -e;
|
|
2563
|
+
cancelTranslateY = -f;
|
|
2564
|
+
const M2D = TOTAL.is2D ? matrix2DNoTranslate(TOTAL) : matrix2DNoTranslate(new DOMMatrix(TOTAL.toString()));
|
|
2565
|
+
const bb = bboxFromMatrix(w, h, M2D);
|
|
2566
|
+
outW = Math.max(1, Math.ceil(bb.width));
|
|
2567
|
+
outH = Math.max(1, Math.ceil(bb.height));
|
|
2568
|
+
tx = -bb.minX;
|
|
2569
|
+
ty = -bb.minY;
|
|
2318
2570
|
}
|
|
2319
2571
|
const svgNS = "http://www.w3.org/2000/svg";
|
|
2320
2572
|
const fo = document.createElementNS(svgNS, "foreignObject");
|
|
2321
2573
|
fo.setAttribute("width", "100%");
|
|
2322
2574
|
fo.setAttribute("height", "100%");
|
|
2575
|
+
fo.setAttribute("x", String(tx));
|
|
2576
|
+
fo.setAttribute("y", String(ty));
|
|
2577
|
+
fo.style.overflow = "visible";
|
|
2323
2578
|
const styleTag = document.createElement("style");
|
|
2324
|
-
styleTag.textContent = baseCSS + fontsCSS + "svg{overflow:visible;}" + classCSS;
|
|
2579
|
+
styleTag.textContent = baseCSS + fontsCSS + "svg{overflow:visible;} foreignObject{overflow:visible;}" + classCSS;
|
|
2325
2580
|
fo.appendChild(styleTag);
|
|
2326
|
-
|
|
2581
|
+
const container = document.createElement("div");
|
|
2582
|
+
container.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
2583
|
+
container.style.width = `${w}px`;
|
|
2584
|
+
container.style.height = `${h}px`;
|
|
2585
|
+
container.style.overflow = "visible";
|
|
2586
|
+
container.style.transformOrigin = "0 0";
|
|
2587
|
+
const cancels = [];
|
|
2588
|
+
if (cancelTranslateX || cancelTranslateY) {
|
|
2589
|
+
cancels.push(`translate(${cancelTranslateX}px, ${cancelTranslateY}px)`);
|
|
2590
|
+
}
|
|
2591
|
+
if (!hasScale && (hasW || hasH)) {
|
|
2592
|
+
const sxWH = rect.width ? w / rect.width : 1;
|
|
2593
|
+
const syWH = rect.height ? h / rect.height : 1;
|
|
2594
|
+
cancels.push(`scale(${sxWH}, ${syWH})`);
|
|
2595
|
+
} else if (hasScale) {
|
|
2596
|
+
cancels.push(`scale(${scaleOpt})`);
|
|
2597
|
+
}
|
|
2598
|
+
if (cancels.length) container.style.transform = cancels.join(" ");
|
|
2599
|
+
clone.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
2600
|
+
clone.style.transformOrigin = "0 0";
|
|
2601
|
+
clone.style.position = "static";
|
|
2602
|
+
clone.style.left = "0";
|
|
2603
|
+
clone.style.top = "0";
|
|
2604
|
+
if (baseTransform) clone.style.transform = baseTransform;
|
|
2605
|
+
clone.style.rotate = ind.rotate || "0deg";
|
|
2606
|
+
clone.style.scale = ind.scale || "1";
|
|
2607
|
+
clone.style.translate = ind.translate || "0 0";
|
|
2608
|
+
container.appendChild(clone);
|
|
2609
|
+
fo.appendChild(container);
|
|
2327
2610
|
const serializer = new XMLSerializer();
|
|
2328
2611
|
const foString = serializer.serializeToString(fo);
|
|
2329
|
-
const svgHeader = `<svg xmlns="${svgNS}" width="${
|
|
2612
|
+
const svgHeader = `<svg xmlns="${svgNS}" width="${outW}" height="${outH}" viewBox="0 0 ${outW} ${outH}">`;
|
|
2330
2613
|
const svgFooter = "</svg>";
|
|
2331
2614
|
svgString = svgHeader + foString + svgFooter;
|
|
2332
2615
|
dataURL = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
|
|
@@ -2338,11 +2621,132 @@
|
|
|
2338
2621
|
return dataURL;
|
|
2339
2622
|
});
|
|
2340
2623
|
}
|
|
2624
|
+
function getNaturalBorderBoxSize(el) {
|
|
2625
|
+
const cs = getComputedStyle(el);
|
|
2626
|
+
const px = (v) => parseFloat(v) || 0;
|
|
2627
|
+
let w = px(cs.width);
|
|
2628
|
+
let h = px(cs.height);
|
|
2629
|
+
if (cs.boxSizing === "content-box") {
|
|
2630
|
+
w += px(cs.paddingLeft) + px(cs.paddingRight) + px(cs.borderLeftWidth) + px(cs.borderRightWidth);
|
|
2631
|
+
h += px(cs.paddingTop) + px(cs.paddingBottom) + px(cs.borderTopWidth) + px(cs.borderBottomWidth);
|
|
2632
|
+
}
|
|
2633
|
+
return { width: w, height: h };
|
|
2634
|
+
}
|
|
2635
|
+
function matrixFromComputed(el) {
|
|
2636
|
+
const tr = getComputedStyle(el).transform;
|
|
2637
|
+
if (!tr || tr === "none") return new DOMMatrix();
|
|
2638
|
+
try {
|
|
2639
|
+
return new DOMMatrix(tr);
|
|
2640
|
+
} catch (e) {
|
|
2641
|
+
return new WebKitCSSMatrix(tr);
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
function matrix2DNoTranslate(M) {
|
|
2645
|
+
return new DOMMatrix([M.a, M.b, M.c, M.d, 0, 0]);
|
|
2646
|
+
}
|
|
2647
|
+
function bboxFromMatrix(w, h, M2D) {
|
|
2648
|
+
const pts = [
|
|
2649
|
+
{ x: 0, y: 0 },
|
|
2650
|
+
{ x: w, y: 0 },
|
|
2651
|
+
{ x: 0, y: h },
|
|
2652
|
+
{ x: w, y: h }
|
|
2653
|
+
];
|
|
2654
|
+
const t = pts.map((p) => ({
|
|
2655
|
+
x: M2D.a * p.x + M2D.c * p.y,
|
|
2656
|
+
y: M2D.b * p.x + M2D.d * p.y
|
|
2657
|
+
}));
|
|
2658
|
+
const minX = Math.min(...t.map((p) => p.x));
|
|
2659
|
+
const maxX = Math.max(...t.map((p) => p.x));
|
|
2660
|
+
const minY = Math.min(...t.map((p) => p.y));
|
|
2661
|
+
const maxY = Math.max(...t.map((p) => p.y));
|
|
2662
|
+
return { minX, minY, width: maxX - minX, height: maxY - minY };
|
|
2663
|
+
}
|
|
2664
|
+
function readIndividualTransforms(el) {
|
|
2665
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
|
|
2666
|
+
const out = { rotate: "0deg", scale: null, translate: null };
|
|
2667
|
+
const map = (_a = el.computedStyleMap) == null ? void 0 : _a.call(el);
|
|
2668
|
+
if (map) {
|
|
2669
|
+
const rot = map.get("rotate");
|
|
2670
|
+
if (rot) {
|
|
2671
|
+
const ang = (_b = rot.angle) != null ? _b : rot;
|
|
2672
|
+
if (ang && "unit" in ang) {
|
|
2673
|
+
out.rotate = ang.unit === "rad" ? ang.value * 180 / Math.PI + "deg" : ang.value + ang.unit;
|
|
2674
|
+
} else {
|
|
2675
|
+
out.rotate = String(rot);
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
const sc = map.get("scale");
|
|
2679
|
+
if (sc && sc.length) {
|
|
2680
|
+
const sx = (_d = (_c = sc[0]) == null ? void 0 : _c.value) != null ? _d : 1;
|
|
2681
|
+
const sy = (_f = (_e = sc[1]) == null ? void 0 : _e.value) != null ? _f : sx;
|
|
2682
|
+
out.scale = `${sx} ${sy}`;
|
|
2683
|
+
}
|
|
2684
|
+
const tr = map.get("translate");
|
|
2685
|
+
if (tr && tr.length) {
|
|
2686
|
+
const tx = (_h = (_g = tr[0]) == null ? void 0 : _g.value) != null ? _h : 0;
|
|
2687
|
+
const ty = (_j = (_i = tr[1]) == null ? void 0 : _i.value) != null ? _j : 0;
|
|
2688
|
+
const ux = (_l = (_k = tr[0]) == null ? void 0 : _k.unit) != null ? _l : "px";
|
|
2689
|
+
const uy = (_n = (_m = tr[1]) == null ? void 0 : _m.unit) != null ? _n : "px";
|
|
2690
|
+
out.translate = `${tx}${ux} ${ty}${uy}`;
|
|
2691
|
+
}
|
|
2692
|
+
return out;
|
|
2693
|
+
}
|
|
2694
|
+
const cs = getComputedStyle(el);
|
|
2695
|
+
out.rotate = cs.rotate && cs.rotate !== "none" ? cs.rotate : "0deg";
|
|
2696
|
+
out.scale = cs.scale && cs.scale !== "none" ? cs.scale : null;
|
|
2697
|
+
out.translate = cs.translate && cs.translate !== "none" ? cs.translate : null;
|
|
2698
|
+
return out;
|
|
2699
|
+
}
|
|
2700
|
+
function hasBBoxAffectingTransform(el) {
|
|
2701
|
+
const t = getComputedStyle(el).transform || "none";
|
|
2702
|
+
if (t === "none" || t === "matrix(1, 0, 0, 1, 0, 0)") return false;
|
|
2703
|
+
if (/^matrix\(\s*1\s*,\s*0\s*,\s*0\s*,\s*1\s*,/i.test(t)) return false;
|
|
2704
|
+
return true;
|
|
2705
|
+
}
|
|
2706
|
+
function inflateRect(r, p) {
|
|
2707
|
+
const x = Math.floor(r.left - p.left);
|
|
2708
|
+
const y = Math.floor(r.top - p.top);
|
|
2709
|
+
const w = Math.ceil(r.width + p.left + p.right);
|
|
2710
|
+
const h = Math.ceil(r.height + p.top + p.bottom);
|
|
2711
|
+
return { x, y, width: w, height: h };
|
|
2712
|
+
}
|
|
2713
|
+
var __measureHost = null;
|
|
2714
|
+
function getMeasureHost() {
|
|
2715
|
+
if (__measureHost) return __measureHost;
|
|
2716
|
+
const n = document.createElement("div");
|
|
2717
|
+
n.id = "snapdom-measure-slot";
|
|
2718
|
+
n.setAttribute("aria-hidden", "true");
|
|
2719
|
+
Object.assign(n.style, {
|
|
2720
|
+
position: "absolute",
|
|
2721
|
+
left: "-99999px",
|
|
2722
|
+
top: "0px",
|
|
2723
|
+
width: "0px",
|
|
2724
|
+
height: "0px",
|
|
2725
|
+
overflow: "hidden",
|
|
2726
|
+
opacity: "0",
|
|
2727
|
+
pointerEvents: "none",
|
|
2728
|
+
contain: "size layout style"
|
|
2729
|
+
});
|
|
2730
|
+
document.documentElement.appendChild(n);
|
|
2731
|
+
__measureHost = n;
|
|
2732
|
+
return n;
|
|
2733
|
+
}
|
|
2734
|
+
function readTotalTransformMatrix(t) {
|
|
2735
|
+
const host = getMeasureHost();
|
|
2736
|
+
const tmp = document.createElement("div");
|
|
2737
|
+
tmp.style.transformOrigin = "0 0";
|
|
2738
|
+
if (t.baseTransform) tmp.style.transform = t.baseTransform;
|
|
2739
|
+
if (t.rotate) tmp.style.rotate = t.rotate;
|
|
2740
|
+
if (t.scale) tmp.style.scale = t.scale;
|
|
2741
|
+
if (t.translate) tmp.style.translate = t.translate;
|
|
2742
|
+
host.appendChild(tmp);
|
|
2743
|
+
const M = matrixFromComputed(tmp);
|
|
2744
|
+
host.removeChild(tmp);
|
|
2745
|
+
return M;
|
|
2746
|
+
}
|
|
2341
2747
|
|
|
2342
2748
|
// src/core/context.js
|
|
2343
2749
|
function normalizeCachePolicy(v) {
|
|
2344
|
-
if (v === true) return "soft";
|
|
2345
|
-
if (v === false) return "disabled";
|
|
2346
2750
|
if (typeof v === "string") {
|
|
2347
2751
|
const s = v.toLowerCase().trim();
|
|
2348
2752
|
if (s === "disabled" || s === "full" || s === "auto" || s === "soft") return (
|
|
@@ -2353,7 +2757,7 @@
|
|
|
2353
2757
|
return "soft";
|
|
2354
2758
|
}
|
|
2355
2759
|
function createContext(options = {}) {
|
|
2356
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
|
|
2760
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
2357
2761
|
const resolvedFormat = (_a = options.format) != null ? _a : "png";
|
|
2358
2762
|
const cachePolicy = normalizeCachePolicy(options.cache);
|
|
2359
2763
|
return {
|
|
@@ -2371,20 +2775,21 @@
|
|
|
2371
2775
|
iconFonts: Array.isArray(options.iconFonts) ? options.iconFonts : options.iconFonts ? [options.iconFonts] : [],
|
|
2372
2776
|
localFonts: Array.isArray(options.localFonts) ? options.localFonts : [],
|
|
2373
2777
|
excludeFonts: (_h = options.excludeFonts) != null ? _h : void 0,
|
|
2778
|
+
defaultImageUrl: (_i = options.defaultImageUrl) != null ? _i : void 0,
|
|
2374
2779
|
/** Cache policy (disabled|full|auto|soft). Default: "soft" */
|
|
2375
2780
|
/** @type {CachePolicy} */
|
|
2376
2781
|
cache: cachePolicy,
|
|
2377
2782
|
// Red
|
|
2378
2783
|
useProxy: typeof options.useProxy === "string" ? options.useProxy : "",
|
|
2379
2784
|
// Salida
|
|
2380
|
-
width: (
|
|
2381
|
-
height: (
|
|
2785
|
+
width: (_j = options.width) != null ? _j : null,
|
|
2786
|
+
height: (_k = options.height) != null ? _k : null,
|
|
2382
2787
|
format: resolvedFormat,
|
|
2383
|
-
type: (
|
|
2384
|
-
quality: (
|
|
2385
|
-
dpr: (
|
|
2386
|
-
backgroundColor: (
|
|
2387
|
-
filename: (
|
|
2788
|
+
type: (_l = options.type) != null ? _l : "svg",
|
|
2789
|
+
quality: (_m = options.quality) != null ? _m : 0.92,
|
|
2790
|
+
dpr: (_n = options.dpr) != null ? _n : window.devicePixelRatio || 1,
|
|
2791
|
+
backgroundColor: (_o = options.backgroundColor) != null ? _o : ["jpg", "jpeg", "webp"].includes(resolvedFormat) ? "#ffffff" : null,
|
|
2792
|
+
filename: (_p = options.filename) != null ? _p : "snapDOM"
|
|
2388
2793
|
// Plugins (reservado para futura activación)
|
|
2389
2794
|
// plugins: normalizePlugins(...),
|
|
2390
2795
|
};
|
|
@@ -2407,7 +2812,7 @@
|
|
|
2407
2812
|
// src/exporters/toCanvas.js
|
|
2408
2813
|
function toCanvas(url, options) {
|
|
2409
2814
|
return __async(this, null, function* () {
|
|
2410
|
-
const { scale
|
|
2815
|
+
const { scale, dpr } = options;
|
|
2411
2816
|
const safari = isSafari();
|
|
2412
2817
|
const img = new Image();
|
|
2413
2818
|
img.crossOrigin = "anonymous";
|
|
@@ -2426,8 +2831,8 @@
|
|
|
2426
2831
|
if (safari) {
|
|
2427
2832
|
yield new Promise((r) => setTimeout(r, 100));
|
|
2428
2833
|
}
|
|
2429
|
-
const width = img.naturalWidth *
|
|
2430
|
-
const height = img.naturalHeight *
|
|
2834
|
+
const width = img.naturalWidth * scale;
|
|
2835
|
+
const height = img.naturalHeight * scale;
|
|
2431
2836
|
const canvas = document.createElement("canvas");
|
|
2432
2837
|
canvas.width = Math.ceil(width * dpr);
|
|
2433
2838
|
canvas.height = Math.ceil(height * dpr);
|
|
@@ -2509,16 +2914,28 @@
|
|
|
2509
2914
|
if (!element) throw new Error("Element cannot be null or undefined");
|
|
2510
2915
|
const context = createContext(userOptions);
|
|
2511
2916
|
if (context.iconFonts && context.iconFonts.length > 0) extendIconFonts(context.iconFonts);
|
|
2917
|
+
if (!context.snap) {
|
|
2918
|
+
context.snap = {
|
|
2919
|
+
toPng: (el, opts) => snapdom.toPng(el, opts),
|
|
2920
|
+
toImg: (el, opts) => snapdom.toImg(el, opts)
|
|
2921
|
+
};
|
|
2922
|
+
}
|
|
2512
2923
|
return snapdom.capture(element, context, INTERNAL_TOKEN);
|
|
2513
2924
|
});
|
|
2514
2925
|
}
|
|
2515
2926
|
snapdom.capture = (el, context, _token) => __async(null, null, function* () {
|
|
2516
|
-
if (_token !== INTERNAL_TOKEN)
|
|
2517
|
-
throw new Error("[snapdom.capture] is internal. Use snapdom(...) instead.");
|
|
2518
|
-
}
|
|
2927
|
+
if (_token !== INTERNAL_TOKEN) throw new Error("[snapdom.capture] is internal. Use snapdom(...) instead.");
|
|
2519
2928
|
const url = yield captureDOM(el, context);
|
|
2520
2929
|
const ensureContext = (opts) => __spreadValues(__spreadValues({}, context), opts || {});
|
|
2521
|
-
const withFormat = (format) => (opts) =>
|
|
2930
|
+
const withFormat = (format) => (opts) => {
|
|
2931
|
+
const next = ensureContext(__spreadProps(__spreadValues({}, opts || {}), { format }));
|
|
2932
|
+
const wantsJpeg = format === "jpeg" || format === "jpg";
|
|
2933
|
+
const noBg = next.backgroundColor == null || next.backgroundColor === "transparent";
|
|
2934
|
+
if (wantsJpeg && noBg) {
|
|
2935
|
+
next.backgroundColor = "#ffffff";
|
|
2936
|
+
}
|
|
2937
|
+
return rasterize(url, next);
|
|
2938
|
+
};
|
|
2522
2939
|
return {
|
|
2523
2940
|
url,
|
|
2524
2941
|
toRaw: () => url,
|