@zumer/snapdom 1.9.12-dev.0 → 1.9.12-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 +45 -41
- package/dist/snapdom.js +373 -61
- package/dist/snapdom.min.js +5 -5
- package/dist/snapdom.min.mjs +5 -5
- package/dist/snapdom.mjs +360 -53
- package/package.json +1 -1
- package/types/snapdom.d.ts +5 -5
package/dist/snapdom.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
/*
|
|
3
3
|
* snapdom
|
|
4
|
-
* v.1.9.12-dev.
|
|
4
|
+
* v.1.9.12-dev.2
|
|
5
5
|
* Author Juan Martin Muda
|
|
6
6
|
* License MIT
|
|
7
7
|
**/
|
|
@@ -673,7 +673,10 @@
|
|
|
673
673
|
}
|
|
674
674
|
}
|
|
675
675
|
function isSafari() {
|
|
676
|
-
|
|
676
|
+
const ua = typeof navigator !== "undefined" && navigator.userAgent ? navigator.userAgent : "";
|
|
677
|
+
const isSafariUA = /^((?!chrome|android).)*safari/i.test(ua);
|
|
678
|
+
const isWeChatUA = /(MicroMessenger|wxwork|WeCom|WindowsWechat|MacWechat)/i.test(ua);
|
|
679
|
+
return isSafariUA || isWeChatUA;
|
|
677
680
|
}
|
|
678
681
|
|
|
679
682
|
// src/modules/styles.js
|
|
@@ -708,7 +711,7 @@
|
|
|
708
711
|
} catch (e) {
|
|
709
712
|
}
|
|
710
713
|
}
|
|
711
|
-
function snapshotComputedStyleFull(style) {
|
|
714
|
+
function snapshotComputedStyleFull(style, options = {}) {
|
|
712
715
|
const out = {};
|
|
713
716
|
const vis = style.getPropertyValue("visibility");
|
|
714
717
|
for (let i = 0; i < style.length; i++) {
|
|
@@ -719,6 +722,24 @@
|
|
|
719
722
|
}
|
|
720
723
|
out[prop] = val;
|
|
721
724
|
}
|
|
725
|
+
if (options.embedFonts) {
|
|
726
|
+
const EXTRA_FONT_PROPS = [
|
|
727
|
+
"font-feature-settings",
|
|
728
|
+
"font-variation-settings",
|
|
729
|
+
"font-kerning",
|
|
730
|
+
"font-variant",
|
|
731
|
+
"font-variant-ligatures",
|
|
732
|
+
"font-optical-sizing"
|
|
733
|
+
];
|
|
734
|
+
for (const prop of EXTRA_FONT_PROPS) {
|
|
735
|
+
if (out[prop]) continue;
|
|
736
|
+
try {
|
|
737
|
+
const v = style.getPropertyValue(prop);
|
|
738
|
+
if (v) out[prop] = v;
|
|
739
|
+
} catch (e) {
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
}
|
|
722
743
|
if (vis === "hidden") out.opacity = "0";
|
|
723
744
|
return out;
|
|
724
745
|
}
|
|
@@ -731,11 +752,12 @@
|
|
|
731
752
|
__snapshotSig.set(snap, sig);
|
|
732
753
|
return sig;
|
|
733
754
|
}
|
|
734
|
-
function getSnapshot(el, preStyle = null) {
|
|
755
|
+
function getSnapshot(el, preStyle = null, options = {}) {
|
|
735
756
|
const rec = snapshotCache.get(el);
|
|
736
757
|
if (rec && rec.epoch === __epoch) return rec.snapshot;
|
|
737
758
|
const style = preStyle || getComputedStyle(el);
|
|
738
|
-
const snap = snapshotComputedStyleFull(style);
|
|
759
|
+
const snap = snapshotComputedStyleFull(style, options);
|
|
760
|
+
stripHeightForWrappers(el, style, snap);
|
|
739
761
|
snapshotCache.set(el, { epoch: __epoch, snapshot: snap });
|
|
740
762
|
return snap;
|
|
741
763
|
}
|
|
@@ -791,7 +813,7 @@
|
|
|
791
813
|
session.styleCache.set(source, getComputedStyle(source));
|
|
792
814
|
}
|
|
793
815
|
const pre = session.styleCache.get(source);
|
|
794
|
-
const snap = getSnapshot(source, pre);
|
|
816
|
+
const snap = getSnapshot(source, pre, ctx.options);
|
|
795
817
|
const sig = styleSignature(snap);
|
|
796
818
|
let key = persist.snapshotKeyCache.get(sig);
|
|
797
819
|
if (!key) {
|
|
@@ -802,6 +824,49 @@
|
|
|
802
824
|
session.styleMap.set(clone, key);
|
|
803
825
|
});
|
|
804
826
|
}
|
|
827
|
+
function isReplaced(el) {
|
|
828
|
+
return el instanceof HTMLImageElement || el instanceof HTMLCanvasElement || el instanceof HTMLVideoElement || el instanceof HTMLIFrameElement || el instanceof SVGElement || el instanceof HTMLObjectElement || el instanceof HTMLEmbedElement;
|
|
829
|
+
}
|
|
830
|
+
function hasBox(cs) {
|
|
831
|
+
if (cs.backgroundImage && cs.backgroundImage !== "none") return true;
|
|
832
|
+
if (cs.backgroundColor && cs.backgroundColor !== "rgba(0, 0, 0, 0)" && cs.backgroundColor !== "transparent") return true;
|
|
833
|
+
if ((parseFloat(cs.borderTopWidth) || 0) > 0) return true;
|
|
834
|
+
if ((parseFloat(cs.borderBottomWidth) || 0) > 0) return true;
|
|
835
|
+
if ((parseFloat(cs.paddingTop) || 0) > 0) return true;
|
|
836
|
+
if ((parseFloat(cs.paddingBottom) || 0) > 0) return true;
|
|
837
|
+
const ob = cs.overflowBlock || cs.overflowY || "visible";
|
|
838
|
+
return ob !== "visible";
|
|
839
|
+
}
|
|
840
|
+
function isFlexOrGridItem(el) {
|
|
841
|
+
const p = el.parentElement;
|
|
842
|
+
if (!p) return false;
|
|
843
|
+
const pd = getComputedStyle(p).display || "";
|
|
844
|
+
return pd.includes("flex") || pd.includes("grid");
|
|
845
|
+
}
|
|
846
|
+
function hasFlowFast(el, cs) {
|
|
847
|
+
if (el.textContent && /\S/.test(el.textContent)) return true;
|
|
848
|
+
const f = el.firstElementChild, l = el.lastElementChild;
|
|
849
|
+
if (f && f.tagName === "BR" || l && l.tagName === "BR") return true;
|
|
850
|
+
const sh = el.scrollHeight;
|
|
851
|
+
if (sh === 0) return false;
|
|
852
|
+
const pt = parseFloat(cs.paddingTop) || 0;
|
|
853
|
+
const pb = parseFloat(cs.paddingBottom) || 0;
|
|
854
|
+
return sh > pt + pb;
|
|
855
|
+
}
|
|
856
|
+
function stripHeightForWrappers(el, cs, snap) {
|
|
857
|
+
if (el instanceof HTMLElement && el.style && el.style.height) return;
|
|
858
|
+
const disp = cs.display || "";
|
|
859
|
+
if (disp.includes("flex") || disp.includes("grid")) return;
|
|
860
|
+
if (isReplaced(el)) return;
|
|
861
|
+
const pos = cs.position;
|
|
862
|
+
if (pos === "absolute" || pos === "fixed" || pos === "sticky") return;
|
|
863
|
+
if (cs.transform !== "none") return;
|
|
864
|
+
if (hasBox(cs)) return;
|
|
865
|
+
if (isFlexOrGridItem(el)) return;
|
|
866
|
+
if (!hasFlowFast(el, cs)) return;
|
|
867
|
+
delete snap.height;
|
|
868
|
+
delete snap["block-size"];
|
|
869
|
+
}
|
|
805
870
|
|
|
806
871
|
// src/core/clone.js
|
|
807
872
|
function idleCallback(childList, callback, fast) {
|
|
@@ -1043,7 +1108,7 @@
|
|
|
1043
1108
|
return node.cloneNode(true);
|
|
1044
1109
|
}
|
|
1045
1110
|
if (node.getAttribute("data-capture") === "exclude") {
|
|
1046
|
-
if (options.excludeMode === "
|
|
1111
|
+
if (options.excludeMode === "hide") {
|
|
1047
1112
|
const spacer = document.createElement("div");
|
|
1048
1113
|
const rect = node.getBoundingClientRect();
|
|
1049
1114
|
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
@@ -1056,7 +1121,7 @@
|
|
|
1056
1121
|
for (const selector of options.exclude) {
|
|
1057
1122
|
try {
|
|
1058
1123
|
if ((_a = node.matches) == null ? void 0 : _a.call(node, selector)) {
|
|
1059
|
-
if (options.excludeMode === "
|
|
1124
|
+
if (options.excludeMode === "hide") {
|
|
1060
1125
|
const spacer = document.createElement("div");
|
|
1061
1126
|
const rect = node.getBoundingClientRect();
|
|
1062
1127
|
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
@@ -1073,7 +1138,7 @@
|
|
|
1073
1138
|
if (typeof options.filter === "function") {
|
|
1074
1139
|
try {
|
|
1075
1140
|
if (!options.filter(node)) {
|
|
1076
|
-
if (options.filterMode === "
|
|
1141
|
+
if (options.filterMode === "hide") {
|
|
1077
1142
|
const spacer = document.createElement("div");
|
|
1078
1143
|
const rect = node.getBoundingClientRect();
|
|
1079
1144
|
spacer.style.cssText = `display:inline-block;width:${rect.width}px;height:${rect.height}px;visibility:hidden;`;
|
|
@@ -1969,7 +2034,186 @@
|
|
|
1969
2034
|
});
|
|
1970
2035
|
}
|
|
1971
2036
|
|
|
2037
|
+
// src/modules/counter.js
|
|
2038
|
+
function hasCounters(input) {
|
|
2039
|
+
return /\bcounter\s*\(|\bcounters\s*\(/.test(input || "");
|
|
2040
|
+
}
|
|
2041
|
+
function unquoteDoubleStrings(s) {
|
|
2042
|
+
return (s || "").replace(/"([^"]*)"/g, "$1");
|
|
2043
|
+
}
|
|
2044
|
+
function alpha(n, upper = false) {
|
|
2045
|
+
let s = "", x = Math.max(1, n);
|
|
2046
|
+
while (x > 0) {
|
|
2047
|
+
x--;
|
|
2048
|
+
s = String.fromCharCode(97 + x % 26) + s;
|
|
2049
|
+
x = Math.floor(x / 26);
|
|
2050
|
+
}
|
|
2051
|
+
return upper ? s.toUpperCase() : s;
|
|
2052
|
+
}
|
|
2053
|
+
function roman(n, upper = true) {
|
|
2054
|
+
const map = [[1e3, "M"], [900, "CM"], [500, "D"], [400, "CD"], [100, "C"], [90, "XC"], [50, "L"], [40, "XL"], [10, "X"], [9, "IX"], [5, "V"], [4, "IV"], [1, "I"]];
|
|
2055
|
+
let num = Math.max(1, Math.min(3999, n)), out = "";
|
|
2056
|
+
for (const [v, sym] of map) while (num >= v) {
|
|
2057
|
+
out += sym;
|
|
2058
|
+
num -= v;
|
|
2059
|
+
}
|
|
2060
|
+
return upper ? out : out.toLowerCase();
|
|
2061
|
+
}
|
|
2062
|
+
function formatCounter(value, style) {
|
|
2063
|
+
switch ((style || "decimal").toLowerCase()) {
|
|
2064
|
+
case "decimal":
|
|
2065
|
+
return String(Math.max(0, value));
|
|
2066
|
+
case "decimal-leading-zero":
|
|
2067
|
+
return (value < 10 ? "0" : "") + String(Math.max(0, value));
|
|
2068
|
+
case "lower-alpha":
|
|
2069
|
+
return alpha(value, false);
|
|
2070
|
+
case "upper-alpha":
|
|
2071
|
+
return alpha(value, true);
|
|
2072
|
+
case "lower-roman":
|
|
2073
|
+
return roman(value, false);
|
|
2074
|
+
case "upper-roman":
|
|
2075
|
+
return roman(value, true);
|
|
2076
|
+
default:
|
|
2077
|
+
return String(Math.max(0, value));
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
function buildCounterContext(root) {
|
|
2081
|
+
const nodeCounters = /* @__PURE__ */ new WeakMap();
|
|
2082
|
+
const rootEl = root instanceof Document ? root.documentElement : root;
|
|
2083
|
+
const isLi = (el) => el && el.tagName === "LI";
|
|
2084
|
+
const countPrevLi = (li) => {
|
|
2085
|
+
let c = 0, p = li == null ? void 0 : li.parentElement;
|
|
2086
|
+
if (!p) return 0;
|
|
2087
|
+
for (const sib of p.children) {
|
|
2088
|
+
if (sib === li) break;
|
|
2089
|
+
if (sib.tagName === "LI") c++;
|
|
2090
|
+
}
|
|
2091
|
+
return c;
|
|
2092
|
+
};
|
|
2093
|
+
const cloneMap = (m) => {
|
|
2094
|
+
const out = /* @__PURE__ */ new Map();
|
|
2095
|
+
for (const [k, arr] of m) out.set(k, arr.slice());
|
|
2096
|
+
return out;
|
|
2097
|
+
};
|
|
2098
|
+
const applyTo = (baseMap, parentMap, el) => {
|
|
2099
|
+
var _a, _b;
|
|
2100
|
+
const map = cloneMap(baseMap);
|
|
2101
|
+
let reset;
|
|
2102
|
+
try {
|
|
2103
|
+
reset = ((_a = el.style) == null ? void 0 : _a.counterReset) || getComputedStyle(el).counterReset;
|
|
2104
|
+
} catch (e) {
|
|
2105
|
+
}
|
|
2106
|
+
if (reset && reset !== "none") {
|
|
2107
|
+
for (const part of reset.split(",")) {
|
|
2108
|
+
const toks = part.trim().split(/\s+/);
|
|
2109
|
+
const name = toks[0];
|
|
2110
|
+
const val = Number.isFinite(Number(toks[1])) ? Number(toks[1]) : 0;
|
|
2111
|
+
if (!name) continue;
|
|
2112
|
+
const parentStack = parentMap.get(name);
|
|
2113
|
+
if (parentStack && parentStack.length) {
|
|
2114
|
+
const s = parentStack.slice();
|
|
2115
|
+
s.push(val);
|
|
2116
|
+
map.set(name, s);
|
|
2117
|
+
} else {
|
|
2118
|
+
map.set(name, [val]);
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
let inc;
|
|
2123
|
+
try {
|
|
2124
|
+
inc = ((_b = el.style) == null ? void 0 : _b.counterIncrement) || getComputedStyle(el).counterIncrement;
|
|
2125
|
+
} catch (e) {
|
|
2126
|
+
}
|
|
2127
|
+
if (inc && inc !== "none") {
|
|
2128
|
+
for (const part of inc.split(",")) {
|
|
2129
|
+
const toks = part.trim().split(/\s+/);
|
|
2130
|
+
const name = toks[0];
|
|
2131
|
+
const by = Number.isFinite(Number(toks[1])) ? Number(toks[1]) : 1;
|
|
2132
|
+
if (!name) continue;
|
|
2133
|
+
const stack = map.get(name) || [];
|
|
2134
|
+
if (stack.length === 0) stack.push(0);
|
|
2135
|
+
stack[stack.length - 1] += by;
|
|
2136
|
+
map.set(name, stack);
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
try {
|
|
2140
|
+
const cs = getComputedStyle(el);
|
|
2141
|
+
if (cs.display === "list-item" && isLi(el)) {
|
|
2142
|
+
const p = el.parentElement;
|
|
2143
|
+
let idx = 1;
|
|
2144
|
+
if (p && p.tagName === "OL") {
|
|
2145
|
+
const startAttr = p.getAttribute("start");
|
|
2146
|
+
const start = Number.isFinite(Number(startAttr)) ? Number(startAttr) : 1;
|
|
2147
|
+
const prev = countPrevLi(el);
|
|
2148
|
+
const ownAttr = el.getAttribute("value");
|
|
2149
|
+
idx = Number.isFinite(Number(ownAttr)) ? Number(ownAttr) : start + prev;
|
|
2150
|
+
} else {
|
|
2151
|
+
idx = 1 + countPrevLi(el);
|
|
2152
|
+
}
|
|
2153
|
+
const s = map.get("list-item") || [];
|
|
2154
|
+
if (s.length === 0) s.push(0);
|
|
2155
|
+
s[s.length - 1] = idx;
|
|
2156
|
+
map.set("list-item", s);
|
|
2157
|
+
}
|
|
2158
|
+
} catch (e) {
|
|
2159
|
+
}
|
|
2160
|
+
return map;
|
|
2161
|
+
};
|
|
2162
|
+
const build = (el, parentMap, carryMap) => {
|
|
2163
|
+
const curr = applyTo(carryMap, parentMap, el);
|
|
2164
|
+
nodeCounters.set(el, curr);
|
|
2165
|
+
let nextCarry = curr;
|
|
2166
|
+
for (const child of el.children) {
|
|
2167
|
+
const childCarry = build(child, curr, nextCarry);
|
|
2168
|
+
nextCarry = childCarry;
|
|
2169
|
+
}
|
|
2170
|
+
return curr;
|
|
2171
|
+
};
|
|
2172
|
+
const empty = /* @__PURE__ */ new Map();
|
|
2173
|
+
build(rootEl, empty, empty);
|
|
2174
|
+
return {
|
|
2175
|
+
get(node, name) {
|
|
2176
|
+
var _a;
|
|
2177
|
+
const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
|
|
2178
|
+
return s && s.length ? s[s.length - 1] : 0;
|
|
2179
|
+
},
|
|
2180
|
+
getStack(node, name) {
|
|
2181
|
+
var _a;
|
|
2182
|
+
const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
|
|
2183
|
+
return s ? s.slice() : [];
|
|
2184
|
+
}
|
|
2185
|
+
};
|
|
2186
|
+
}
|
|
2187
|
+
function resolveCountersInContent(raw, node, ctx) {
|
|
2188
|
+
if (!raw || raw === "none") return raw;
|
|
2189
|
+
try {
|
|
2190
|
+
const RX = /\b(counter|counters)\s*\(([^)]+)\)/g;
|
|
2191
|
+
let out = raw.replace(RX, (_, fn, args) => {
|
|
2192
|
+
var _a, _b, _c, _d;
|
|
2193
|
+
const parts = String(args).split(",").map((s) => s.trim());
|
|
2194
|
+
if (fn === "counter") {
|
|
2195
|
+
const name = (_a = parts[0]) == null ? void 0 : _a.replace(/^["']|["']$/g, "");
|
|
2196
|
+
const style = (parts[1] || "decimal").toLowerCase();
|
|
2197
|
+
const v = ctx.get(node, name);
|
|
2198
|
+
return formatCounter(v, style);
|
|
2199
|
+
} else {
|
|
2200
|
+
const name = (_b = parts[0]) == null ? void 0 : _b.replace(/^["']|["']$/g, "");
|
|
2201
|
+
const sep = (_d = (_c = parts[1]) == null ? void 0 : _c.replace(/^["']|["']$/g, "")) != null ? _d : "";
|
|
2202
|
+
const style = (parts[2] || "decimal").toLowerCase();
|
|
2203
|
+
const stack = ctx.getStack(node, name);
|
|
2204
|
+
if (!stack.length) return "";
|
|
2205
|
+
const pieces = stack.map((v) => formatCounter(v, style));
|
|
2206
|
+
return pieces.join(sep);
|
|
2207
|
+
}
|
|
2208
|
+
});
|
|
2209
|
+
return unquoteDoubleStrings(out);
|
|
2210
|
+
} catch (e) {
|
|
2211
|
+
return "- ";
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
|
|
1972
2215
|
// src/modules/pseudo.js
|
|
2216
|
+
var counterCtx = null;
|
|
1973
2217
|
function inlinePseudoElements(source, clone, sessionCache, options) {
|
|
1974
2218
|
return __async(this, null, function* () {
|
|
1975
2219
|
var _a;
|
|
@@ -2008,7 +2252,11 @@
|
|
|
2008
2252
|
continue;
|
|
2009
2253
|
}
|
|
2010
2254
|
const content = style.content;
|
|
2011
|
-
|
|
2255
|
+
let cleanContent = parseContent(content);
|
|
2256
|
+
if (hasCounters(content)) {
|
|
2257
|
+
counterCtx = buildCounterContext(source.ownerDocument || document);
|
|
2258
|
+
cleanContent = resolveCountersInContent(cleanContent, source, counterCtx);
|
|
2259
|
+
}
|
|
2012
2260
|
const bg = style.backgroundImage;
|
|
2013
2261
|
const bgColor = style.backgroundColor;
|
|
2014
2262
|
const fontFamily = style.fontFamily;
|
|
@@ -2025,10 +2273,10 @@
|
|
|
2025
2273
|
const hasExplicitContent = content !== "none" && cleanContent !== "";
|
|
2026
2274
|
const hasBg = bg && bg !== "none";
|
|
2027
2275
|
const hasBgColor = bgColor && bgColor !== "transparent" && bgColor !== "rgba(0, 0, 0, 0)";
|
|
2028
|
-
const
|
|
2276
|
+
const hasBox2 = display !== "inline" && (width > 0 || height > 0);
|
|
2029
2277
|
const hasBorder = borderStyle && borderStyle !== "none" && borderWidth > 0;
|
|
2030
2278
|
const hasTransform = transform && transform !== "none";
|
|
2031
|
-
const shouldRender = hasExplicitContent || hasBg || hasBgColor ||
|
|
2279
|
+
const shouldRender = hasExplicitContent || hasBg || hasBgColor || hasBox2 || hasBorder || hasTransform;
|
|
2032
2280
|
if (!shouldRender) continue;
|
|
2033
2281
|
const pseudoEl = document.createElement("span");
|
|
2034
2282
|
pseudoEl.dataset.snapdomPseudo = pseudo;
|
|
@@ -2070,7 +2318,7 @@
|
|
|
2070
2318
|
}
|
|
2071
2319
|
if (hasBgColor) pseudoEl.style.backgroundColor = bgColor;
|
|
2072
2320
|
const hasContent2 = pseudoEl.childNodes.length > 0 || ((_a = pseudoEl.textContent) == null ? void 0 : _a.trim()) !== "";
|
|
2073
|
-
const hasVisibleBox = hasContent2 || hasBg || hasBgColor ||
|
|
2321
|
+
const hasVisibleBox = hasContent2 || hasBg || hasBgColor || hasBox2 || hasBorder || hasTransform;
|
|
2074
2322
|
if (!hasVisibleBox) continue;
|
|
2075
2323
|
if (pseudo === "::before") {
|
|
2076
2324
|
clone.insertBefore(pseudoEl, clone.firstChild);
|
|
@@ -2408,8 +2656,8 @@
|
|
|
2408
2656
|
if (!img.height) img.height = img.naturalHeight || 100;
|
|
2409
2657
|
return;
|
|
2410
2658
|
}
|
|
2411
|
-
const {
|
|
2412
|
-
if (
|
|
2659
|
+
const { fallbackURL } = options || {};
|
|
2660
|
+
if (fallbackURL) {
|
|
2413
2661
|
try {
|
|
2414
2662
|
const dsW = parseInt(((_a = img.dataset) == null ? void 0 : _a.snapdomWidth) || "", 10) || 0;
|
|
2415
2663
|
const dsH = parseInt(((_b = img.dataset) == null ? void 0 : _b.snapdomHeight) || "", 10) || 0;
|
|
@@ -2417,14 +2665,14 @@
|
|
|
2417
2665
|
const attrH = parseInt(img.getAttribute("height") || "", 10) || 0;
|
|
2418
2666
|
const styleW = parseFloat(((_c = img.style) == null ? void 0 : _c.width) || "") || 0;
|
|
2419
2667
|
const styleH = parseFloat(((_d = img.style) == null ? void 0 : _d.height) || "") || 0;
|
|
2420
|
-
const
|
|
2421
|
-
const
|
|
2422
|
-
const fallbackUrl = typeof
|
|
2668
|
+
const fbW = dsW || styleW || attrW || img.width || void 0;
|
|
2669
|
+
const fbH = dsH || styleH || attrH || img.height || void 0;
|
|
2670
|
+
const fallbackUrl = typeof fallbackURL === "function" ? yield fallbackURL({ width: fbW, height: fbH, src, element: img }) : fallbackURL;
|
|
2423
2671
|
if (fallbackUrl) {
|
|
2424
2672
|
const fallbackData = yield snapFetch(fallbackUrl, { as: "dataURL", useProxy: options.useProxy });
|
|
2425
2673
|
img.src = fallbackData.data;
|
|
2426
|
-
if (!img.width &&
|
|
2427
|
-
if (!img.height &&
|
|
2674
|
+
if (!img.width && fbW) img.width = fbW;
|
|
2675
|
+
if (!img.height && fbH) img.height = fbH;
|
|
2428
2676
|
if (!img.width) img.width = img.naturalWidth || 100;
|
|
2429
2677
|
if (!img.height) img.height = img.naturalHeight || 100;
|
|
2430
2678
|
return;
|
|
@@ -2546,6 +2794,64 @@
|
|
|
2546
2794
|
});
|
|
2547
2795
|
}
|
|
2548
2796
|
|
|
2797
|
+
// src/modules/lineClamp.js
|
|
2798
|
+
function lineClamp(el) {
|
|
2799
|
+
var _a;
|
|
2800
|
+
if (!el) return () => {
|
|
2801
|
+
};
|
|
2802
|
+
const lines = getClamp(el);
|
|
2803
|
+
if (lines <= 0) return () => {
|
|
2804
|
+
};
|
|
2805
|
+
if (!isPlainTextContainer(el)) return () => {
|
|
2806
|
+
};
|
|
2807
|
+
const cs = getComputedStyle(el);
|
|
2808
|
+
const targetH = Math.round(usedLineHeightPx(cs) * lines + vpad(cs));
|
|
2809
|
+
const original = (_a = el.textContent) != null ? _a : "";
|
|
2810
|
+
const prevText = original;
|
|
2811
|
+
if (el.scrollHeight <= targetH + 0.5) {
|
|
2812
|
+
return () => {
|
|
2813
|
+
};
|
|
2814
|
+
}
|
|
2815
|
+
let lo = 0, hi = original.length, best = -1;
|
|
2816
|
+
while (lo <= hi) {
|
|
2817
|
+
const mid = lo + hi >> 1;
|
|
2818
|
+
el.textContent = original.slice(0, mid) + "\u2026";
|
|
2819
|
+
if (el.scrollHeight <= targetH + 0.5) {
|
|
2820
|
+
best = mid;
|
|
2821
|
+
lo = mid + 1;
|
|
2822
|
+
} else {
|
|
2823
|
+
hi = mid - 1;
|
|
2824
|
+
}
|
|
2825
|
+
}
|
|
2826
|
+
el.textContent = (best >= 0 ? original.slice(0, best) : "") + "\u2026";
|
|
2827
|
+
return () => {
|
|
2828
|
+
el.textContent = prevText;
|
|
2829
|
+
};
|
|
2830
|
+
}
|
|
2831
|
+
function getClamp(el) {
|
|
2832
|
+
const cs = getComputedStyle(el);
|
|
2833
|
+
let v = cs.getPropertyValue("-webkit-line-clamp") || cs.getPropertyValue("line-clamp");
|
|
2834
|
+
v = (v || "").trim();
|
|
2835
|
+
const n = parseInt(v, 10);
|
|
2836
|
+
return Number.isFinite(n) && n > 0 ? n : 0;
|
|
2837
|
+
}
|
|
2838
|
+
function usedLineHeightPx(cs) {
|
|
2839
|
+
const lh = (cs.lineHeight || "").trim();
|
|
2840
|
+
const fs = parseFloat(cs.fontSize) || 16;
|
|
2841
|
+
if (!lh || lh === "normal") return Math.round(fs * 1.2);
|
|
2842
|
+
if (lh.endsWith("px")) return parseFloat(lh);
|
|
2843
|
+
if (/^\d+(\.\d+)?$/.test(lh)) return Math.round(parseFloat(lh) * fs);
|
|
2844
|
+
if (lh.endsWith("%")) return Math.round(parseFloat(lh) / 100 * fs);
|
|
2845
|
+
return Math.round(fs * 1.2);
|
|
2846
|
+
}
|
|
2847
|
+
function vpad(cs) {
|
|
2848
|
+
return (parseFloat(cs.paddingTop) || 0) + (parseFloat(cs.paddingBottom) || 0);
|
|
2849
|
+
}
|
|
2850
|
+
function isPlainTextContainer(el) {
|
|
2851
|
+
if (el.childElementCount > 0) return false;
|
|
2852
|
+
return Array.from(el.childNodes).some((n) => n.nodeType === Node.TEXT_NODE);
|
|
2853
|
+
}
|
|
2854
|
+
|
|
2549
2855
|
// src/core/capture.js
|
|
2550
2856
|
function captureDOM(element, options) {
|
|
2551
2857
|
return __async(this, null, function* () {
|
|
@@ -2557,7 +2863,12 @@
|
|
|
2557
2863
|
let baseCSS = "";
|
|
2558
2864
|
let dataURL;
|
|
2559
2865
|
let svgString;
|
|
2560
|
-
|
|
2866
|
+
const undoClamp = lineClamp(element);
|
|
2867
|
+
try {
|
|
2868
|
+
({ clone, classCSS, styleCache } = yield prepareClone(element, options));
|
|
2869
|
+
} finally {
|
|
2870
|
+
undoClamp();
|
|
2871
|
+
}
|
|
2561
2872
|
yield new Promise((resolve) => {
|
|
2562
2873
|
idle(() => __async(null, null, function* () {
|
|
2563
2874
|
yield inlineImages(clone, options);
|
|
@@ -2608,28 +2919,28 @@
|
|
|
2608
2919
|
yield new Promise((resolve) => {
|
|
2609
2920
|
idle(() => {
|
|
2610
2921
|
var _a, _b, _c, _d, _e;
|
|
2611
|
-
const rect =
|
|
2612
|
-
let w = rect.width;
|
|
2613
|
-
let h = rect.height;
|
|
2922
|
+
const rect = element.getBoundingClientRect();
|
|
2923
|
+
let w = Number(rect.width) || 0;
|
|
2924
|
+
let h = Number(rect.height) || 0;
|
|
2614
2925
|
const hasW = Number.isFinite(options.width);
|
|
2615
2926
|
const hasH = Number.isFinite(options.height);
|
|
2616
2927
|
const scaleOpt = (_a = options.scale) != null ? _a : 1;
|
|
2617
2928
|
const hasScale = typeof scaleOpt === "number" && scaleOpt !== 1;
|
|
2618
2929
|
if (!hasScale) {
|
|
2619
|
-
const aspect =
|
|
2930
|
+
const aspect = h > 0 ? w / h : 1;
|
|
2620
2931
|
if (hasW && hasH) {
|
|
2621
|
-
w = options.width;
|
|
2622
|
-
h = options.height;
|
|
2932
|
+
w = Number(options.width);
|
|
2933
|
+
h = Number(options.height);
|
|
2623
2934
|
} else if (hasW) {
|
|
2624
|
-
w = options.width;
|
|
2625
|
-
h = w / aspect;
|
|
2935
|
+
w = Number(options.width);
|
|
2936
|
+
h = w / (aspect || 1);
|
|
2626
2937
|
} else if (hasH) {
|
|
2627
|
-
h = options.height;
|
|
2628
|
-
w = h * aspect;
|
|
2938
|
+
h = Number(options.height);
|
|
2939
|
+
w = h * (aspect || 1);
|
|
2629
2940
|
}
|
|
2630
2941
|
}
|
|
2631
|
-
w = Math.max(1, Math.ceil(w));
|
|
2632
|
-
h = Math.max(1, Math.ceil(h));
|
|
2942
|
+
w = Math.max(1, Math.ceil(Number.isFinite(w) ? w : 1));
|
|
2943
|
+
h = Math.max(1, Math.ceil(Number.isFinite(h) ? h : 1));
|
|
2633
2944
|
const csEl = getComputedStyle(element);
|
|
2634
2945
|
const baseTransform = csEl.transform && csEl.transform !== "none" ? csEl.transform : "";
|
|
2635
2946
|
const ind = readIndividualTransforms(element);
|
|
@@ -2700,7 +3011,9 @@
|
|
|
2700
3011
|
fo.appendChild(container);
|
|
2701
3012
|
const serializer = new XMLSerializer();
|
|
2702
3013
|
const foString = serializer.serializeToString(fo);
|
|
2703
|
-
const
|
|
3014
|
+
const finalW = !hasScale && (hasW || hasH) ? w : outW;
|
|
3015
|
+
const finalH = !hasScale && (hasH || hasW) ? h : outH;
|
|
3016
|
+
const svgHeader = `<svg xmlns="${svgNS}" width="${finalW}" height="${finalH}" viewBox="0 0 ${outW} ${outH}">`;
|
|
2704
3017
|
const svgFooter = "</svg>";
|
|
2705
3018
|
svgString = svgHeader + foString + svgFooter;
|
|
2706
3019
|
dataURL = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
|
|
@@ -2712,17 +3025,6 @@
|
|
|
2712
3025
|
return dataURL;
|
|
2713
3026
|
});
|
|
2714
3027
|
}
|
|
2715
|
-
function getNaturalBorderBoxSize(el) {
|
|
2716
|
-
const cs = getComputedStyle(el);
|
|
2717
|
-
const px = (v) => parseFloat(v) || 0;
|
|
2718
|
-
let w = px(cs.width);
|
|
2719
|
-
let h = px(cs.height);
|
|
2720
|
-
if (cs.boxSizing === "content-box") {
|
|
2721
|
-
w += px(cs.paddingLeft) + px(cs.paddingRight) + px(cs.borderLeftWidth) + px(cs.borderRightWidth);
|
|
2722
|
-
h += px(cs.paddingTop) + px(cs.paddingBottom) + px(cs.borderTopWidth) + px(cs.borderBottomWidth);
|
|
2723
|
-
}
|
|
2724
|
-
return { width: w, height: h };
|
|
2725
|
-
}
|
|
2726
3028
|
function matrixFromComputed(el) {
|
|
2727
3029
|
const tr = getComputedStyle(el).transform;
|
|
2728
3030
|
if (!tr || tr === "none") return new DOMMatrix();
|
|
@@ -2753,31 +3055,40 @@
|
|
|
2753
3055
|
return { minX, minY, width: maxX - minX, height: maxY - minY };
|
|
2754
3056
|
}
|
|
2755
3057
|
function readIndividualTransforms(el) {
|
|
2756
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m
|
|
3058
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
2757
3059
|
const out = { rotate: "0deg", scale: null, translate: null };
|
|
2758
|
-
const map =
|
|
3060
|
+
const map = typeof el.computedStyleMap === "function" ? el.computedStyleMap() : null;
|
|
2759
3061
|
if (map) {
|
|
2760
|
-
const
|
|
3062
|
+
const safeGet = (prop) => {
|
|
3063
|
+
try {
|
|
3064
|
+
if (typeof map.has === "function" && !map.has(prop)) return null;
|
|
3065
|
+
if (typeof map.get !== "function") return null;
|
|
3066
|
+
return map.get(prop);
|
|
3067
|
+
} catch (e) {
|
|
3068
|
+
return null;
|
|
3069
|
+
}
|
|
3070
|
+
};
|
|
3071
|
+
const rot = safeGet("rotate");
|
|
2761
3072
|
if (rot) {
|
|
2762
|
-
const ang = (
|
|
2763
|
-
if (ang && "unit" in ang) {
|
|
3073
|
+
const ang = (_a = rot.angle) != null ? _a : rot;
|
|
3074
|
+
if (ang && typeof ang === "object" && "unit" in ang) {
|
|
2764
3075
|
out.rotate = ang.unit === "rad" ? ang.value * 180 / Math.PI + "deg" : ang.value + ang.unit;
|
|
2765
3076
|
} else {
|
|
2766
3077
|
out.rotate = String(rot);
|
|
2767
3078
|
}
|
|
2768
3079
|
}
|
|
2769
|
-
const sc =
|
|
3080
|
+
const sc = safeGet("scale");
|
|
2770
3081
|
if (sc && sc.length) {
|
|
2771
|
-
const sx = (
|
|
2772
|
-
const sy = (
|
|
3082
|
+
const sx = (_c = (_b = sc[0]) == null ? void 0 : _b.value) != null ? _c : 1;
|
|
3083
|
+
const sy = (_e = (_d = sc[1]) == null ? void 0 : _d.value) != null ? _e : sx;
|
|
2773
3084
|
out.scale = `${sx} ${sy}`;
|
|
2774
3085
|
}
|
|
2775
|
-
const tr =
|
|
3086
|
+
const tr = safeGet("translate");
|
|
2776
3087
|
if (tr && tr.length) {
|
|
2777
|
-
const tx = (
|
|
2778
|
-
const ty = (
|
|
2779
|
-
const ux = (
|
|
2780
|
-
const uy = (
|
|
3088
|
+
const tx = (_g = (_f = tr[0]) == null ? void 0 : _f.value) != null ? _g : 0;
|
|
3089
|
+
const ty = (_i = (_h = tr[1]) == null ? void 0 : _h.value) != null ? _i : 0;
|
|
3090
|
+
const ux = (_k = (_j = tr[0]) == null ? void 0 : _j.unit) != null ? _k : "px";
|
|
3091
|
+
const uy = (_m = (_l = tr[1]) == null ? void 0 : _l.unit) != null ? _m : "px";
|
|
2781
3092
|
out.translate = `${tx}${ux} ${ty}${uy}`;
|
|
2782
3093
|
}
|
|
2783
3094
|
return out;
|
|
@@ -2858,9 +3169,9 @@
|
|
|
2858
3169
|
scale: (_d = options.scale) != null ? _d : 1,
|
|
2859
3170
|
// DOM filters
|
|
2860
3171
|
exclude: (_e = options.exclude) != null ? _e : [],
|
|
2861
|
-
excludeMode: (_f = options.excludeMode) != null ? _f : "
|
|
3172
|
+
excludeMode: (_f = options.excludeMode) != null ? _f : "hide",
|
|
2862
3173
|
filter: (_g = options.filter) != null ? _g : null,
|
|
2863
|
-
filterMode: (_h = options.filterMode) != null ? _h : "
|
|
3174
|
+
filterMode: (_h = options.filterMode) != null ? _h : "hide",
|
|
2864
3175
|
placeholders: options.placeholders !== false,
|
|
2865
3176
|
// default true
|
|
2866
3177
|
// Fuentes
|
|
@@ -2868,7 +3179,7 @@
|
|
|
2868
3179
|
iconFonts: Array.isArray(options.iconFonts) ? options.iconFonts : options.iconFonts ? [options.iconFonts] : [],
|
|
2869
3180
|
localFonts: Array.isArray(options.localFonts) ? options.localFonts : [],
|
|
2870
3181
|
excludeFonts: (_j = options.excludeFonts) != null ? _j : void 0,
|
|
2871
|
-
|
|
3182
|
+
fallbackURL: (_k = options.fallbackURL) != null ? _k : void 0,
|
|
2872
3183
|
/** Cache policy (disabled|full|auto|soft). Default: "soft" */
|
|
2873
3184
|
/** @type {CachePolicy} */
|
|
2874
3185
|
cache: cachePolicy,
|
|
@@ -2963,6 +3274,7 @@
|
|
|
2963
3274
|
// src/exporters/download.js
|
|
2964
3275
|
function download(url, options) {
|
|
2965
3276
|
return __async(this, null, function* () {
|
|
3277
|
+
options.dpr = 1;
|
|
2966
3278
|
if (options.format === "svg") {
|
|
2967
3279
|
const blob = yield toBlob(url, __spreadProps(__spreadValues({}, options), { type: "svg" }));
|
|
2968
3280
|
const objectURL = URL.createObjectURL(blob);
|