@zumer/snapdom 1.9.12-dev.2 → 1.9.12-dev.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/snapdom.js +556 -182
- package/dist/snapdom.min.js +5 -5
- package/dist/snapdom.min.mjs +5 -5
- package/dist/snapdom.mjs +551 -178
- package/package.json +1 -1
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.3
|
|
5
5
|
* Author Juan Martin Muda
|
|
6
6
|
* License MIT
|
|
7
7
|
**/
|
|
@@ -628,17 +628,6 @@
|
|
|
628
628
|
}
|
|
629
629
|
return map.get(pseudo);
|
|
630
630
|
}
|
|
631
|
-
function parseContent(content) {
|
|
632
|
-
let clean = content.replace(/^['"]|['"]$/g, "");
|
|
633
|
-
if (clean.startsWith("\\")) {
|
|
634
|
-
try {
|
|
635
|
-
return String.fromCharCode(parseInt(clean.replace("\\", ""), 16));
|
|
636
|
-
} catch (e) {
|
|
637
|
-
return clean;
|
|
638
|
-
}
|
|
639
|
-
}
|
|
640
|
-
return clean;
|
|
641
|
-
}
|
|
642
631
|
function snapshotComputedStyle(style) {
|
|
643
632
|
const snap = {};
|
|
644
633
|
for (let prop of style) {
|
|
@@ -2172,11 +2161,21 @@
|
|
|
2172
2161
|
const empty = /* @__PURE__ */ new Map();
|
|
2173
2162
|
build(rootEl, empty, empty);
|
|
2174
2163
|
return {
|
|
2164
|
+
/**
|
|
2165
|
+
* Get top value for counter name at given node.
|
|
2166
|
+
* @param {Element} node
|
|
2167
|
+
* @param {string} name
|
|
2168
|
+
*/
|
|
2175
2169
|
get(node, name) {
|
|
2176
2170
|
var _a;
|
|
2177
2171
|
const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
|
|
2178
2172
|
return s && s.length ? s[s.length - 1] : 0;
|
|
2179
2173
|
},
|
|
2174
|
+
/**
|
|
2175
|
+
* Get full stack for counter name at given node.
|
|
2176
|
+
* @param {Element} node
|
|
2177
|
+
* @param {string} name
|
|
2178
|
+
*/
|
|
2180
2179
|
getStack(node, name) {
|
|
2181
2180
|
var _a;
|
|
2182
2181
|
const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
|
|
@@ -2214,10 +2213,111 @@
|
|
|
2214
2213
|
|
|
2215
2214
|
// src/modules/pseudo.js
|
|
2216
2215
|
var counterCtx = null;
|
|
2216
|
+
var __siblingCounters = /* @__PURE__ */ new WeakMap();
|
|
2217
|
+
function unquoteDoubleStrings2(s) {
|
|
2218
|
+
return (s || "").replace(/"([^"]*)"/g, "$1");
|
|
2219
|
+
}
|
|
2220
|
+
function collapseCssContent(raw) {
|
|
2221
|
+
if (!raw) return "";
|
|
2222
|
+
const tokens = [];
|
|
2223
|
+
const rx = /"([^"]*)"/g;
|
|
2224
|
+
let m;
|
|
2225
|
+
while (m = rx.exec(raw)) tokens.push(m[1]);
|
|
2226
|
+
if (tokens.length) return tokens.join("");
|
|
2227
|
+
return unquoteDoubleStrings2(raw);
|
|
2228
|
+
}
|
|
2229
|
+
function withSiblingOverrides(node, base) {
|
|
2230
|
+
const parent = node.parentElement;
|
|
2231
|
+
const map = parent ? __siblingCounters.get(parent) : null;
|
|
2232
|
+
if (!map) return base;
|
|
2233
|
+
return {
|
|
2234
|
+
get(n, name) {
|
|
2235
|
+
const v = base.get(n, name);
|
|
2236
|
+
const ov = map.get(name);
|
|
2237
|
+
return typeof ov === "number" ? Math.max(v, ov) : v;
|
|
2238
|
+
},
|
|
2239
|
+
getStack(n, name) {
|
|
2240
|
+
const s = base.getStack(n, name);
|
|
2241
|
+
if (!s.length) return s;
|
|
2242
|
+
const ov = map.get(name);
|
|
2243
|
+
if (typeof ov === "number") {
|
|
2244
|
+
const out = s.slice();
|
|
2245
|
+
out[out.length - 1] = Math.max(out[out.length - 1], ov);
|
|
2246
|
+
return out;
|
|
2247
|
+
}
|
|
2248
|
+
return s;
|
|
2249
|
+
}
|
|
2250
|
+
};
|
|
2251
|
+
}
|
|
2252
|
+
function deriveCounterCtxForPseudo(node, pseudoStyle, baseCtx) {
|
|
2253
|
+
const modStacks = /* @__PURE__ */ new Map();
|
|
2254
|
+
function parseListDecl(value) {
|
|
2255
|
+
const out = [];
|
|
2256
|
+
if (!value || value === "none") return out;
|
|
2257
|
+
for (const part of String(value).split(",")) {
|
|
2258
|
+
const toks = part.trim().split(/\s+/);
|
|
2259
|
+
const name = toks[0];
|
|
2260
|
+
const num = Number.isFinite(Number(toks[1])) ? Number(toks[1]) : void 0;
|
|
2261
|
+
if (name) out.push({ name, num });
|
|
2262
|
+
}
|
|
2263
|
+
return out;
|
|
2264
|
+
}
|
|
2265
|
+
const resets = parseListDecl(pseudoStyle == null ? void 0 : pseudoStyle.counterReset);
|
|
2266
|
+
const incs = parseListDecl(pseudoStyle == null ? void 0 : pseudoStyle.counterIncrement);
|
|
2267
|
+
function getStackDerived(name) {
|
|
2268
|
+
if (modStacks.has(name)) return modStacks.get(name).slice();
|
|
2269
|
+
let stack = baseCtx.getStack(node, name);
|
|
2270
|
+
stack = stack.length ? stack.slice() : [];
|
|
2271
|
+
const r = resets.find((x) => x.name === name);
|
|
2272
|
+
if (r) {
|
|
2273
|
+
const val = Number.isFinite(r.num) ? r.num : 0;
|
|
2274
|
+
stack = stack.length ? [...stack, val] : [val];
|
|
2275
|
+
}
|
|
2276
|
+
const inc = incs.find((x) => x.name === name);
|
|
2277
|
+
if (inc) {
|
|
2278
|
+
const by = Number.isFinite(inc.num) ? inc.num : 1;
|
|
2279
|
+
if (stack.length === 0) stack = [0];
|
|
2280
|
+
stack[stack.length - 1] += by;
|
|
2281
|
+
}
|
|
2282
|
+
modStacks.set(name, stack.slice());
|
|
2283
|
+
return stack;
|
|
2284
|
+
}
|
|
2285
|
+
return {
|
|
2286
|
+
get(_node, name) {
|
|
2287
|
+
const s = getStackDerived(name);
|
|
2288
|
+
return s.length ? s[s.length - 1] : 0;
|
|
2289
|
+
},
|
|
2290
|
+
getStack(_node, name) {
|
|
2291
|
+
return getStackDerived(name);
|
|
2292
|
+
},
|
|
2293
|
+
/** expone increments del pseudo para que el caller pueda propagar a hermanos */
|
|
2294
|
+
__incs: incs
|
|
2295
|
+
};
|
|
2296
|
+
}
|
|
2297
|
+
function resolvePseudoContentAndIncs(node, pseudo, baseCtx) {
|
|
2298
|
+
let ps;
|
|
2299
|
+
try {
|
|
2300
|
+
ps = getComputedStyle(node, pseudo);
|
|
2301
|
+
} catch (e) {
|
|
2302
|
+
}
|
|
2303
|
+
const raw = ps == null ? void 0 : ps.content;
|
|
2304
|
+
if (!raw || raw === "none" || raw === "normal") return { text: "", incs: [] };
|
|
2305
|
+
const baseWithSiblings = withSiblingOverrides(node, baseCtx);
|
|
2306
|
+
const derived = deriveCounterCtxForPseudo(node, ps, baseWithSiblings);
|
|
2307
|
+
let resolved = hasCounters(raw) ? resolveCountersInContent(raw, node, derived) : raw;
|
|
2308
|
+
const text = collapseCssContent(resolved);
|
|
2309
|
+
return { text, incs: derived.__incs || [] };
|
|
2310
|
+
}
|
|
2217
2311
|
function inlinePseudoElements(source, clone, sessionCache, options) {
|
|
2218
2312
|
return __async(this, null, function* () {
|
|
2219
2313
|
var _a;
|
|
2220
2314
|
if (!(source instanceof Element) || !(clone instanceof Element)) return;
|
|
2315
|
+
if (!counterCtx) {
|
|
2316
|
+
try {
|
|
2317
|
+
counterCtx = buildCounterContext(source.ownerDocument || document);
|
|
2318
|
+
} catch (e) {
|
|
2319
|
+
}
|
|
2320
|
+
}
|
|
2221
2321
|
for (const pseudo of ["::before", "::after", "::first-letter"]) {
|
|
2222
2322
|
try {
|
|
2223
2323
|
const style = getStyle(source, pseudo);
|
|
@@ -2251,12 +2351,8 @@
|
|
|
2251
2351
|
clone.insertBefore(span, restNode);
|
|
2252
2352
|
continue;
|
|
2253
2353
|
}
|
|
2254
|
-
const
|
|
2255
|
-
|
|
2256
|
-
if (hasCounters(content)) {
|
|
2257
|
-
counterCtx = buildCounterContext(source.ownerDocument || document);
|
|
2258
|
-
cleanContent = resolveCountersInContent(cleanContent, source, counterCtx);
|
|
2259
|
-
}
|
|
2354
|
+
const rawContent = style.content;
|
|
2355
|
+
const { text: cleanContent, incs } = resolvePseudoContentAndIncs(source, pseudo, counterCtx);
|
|
2260
2356
|
const bg = style.backgroundImage;
|
|
2261
2357
|
const bgColor = style.backgroundColor;
|
|
2262
2358
|
const fontFamily = style.fontFamily;
|
|
@@ -2270,28 +2366,41 @@
|
|
|
2270
2366
|
const borderWidth = parseFloat(style.borderWidth);
|
|
2271
2367
|
const transform = style.transform;
|
|
2272
2368
|
const isIconFont22 = isIconFont2(fontFamily);
|
|
2273
|
-
const hasExplicitContent =
|
|
2369
|
+
const hasExplicitContent = rawContent !== "none" && cleanContent !== "";
|
|
2274
2370
|
const hasBg = bg && bg !== "none";
|
|
2275
2371
|
const hasBgColor = bgColor && bgColor !== "transparent" && bgColor !== "rgba(0, 0, 0, 0)";
|
|
2276
2372
|
const hasBox2 = display !== "inline" && (width > 0 || height > 0);
|
|
2277
2373
|
const hasBorder = borderStyle && borderStyle !== "none" && borderWidth > 0;
|
|
2278
2374
|
const hasTransform = transform && transform !== "none";
|
|
2279
2375
|
const shouldRender = hasExplicitContent || hasBg || hasBgColor || hasBox2 || hasBorder || hasTransform;
|
|
2280
|
-
if (!shouldRender)
|
|
2376
|
+
if (!shouldRender) {
|
|
2377
|
+
if (incs && incs.length && source.parentElement) {
|
|
2378
|
+
const map = __siblingCounters.get(source.parentElement) || /* @__PURE__ */ new Map();
|
|
2379
|
+
for (const { name, num } of incs) {
|
|
2380
|
+
if (!name) continue;
|
|
2381
|
+
const baseWithSibs = withSiblingOverrides(source, counterCtx);
|
|
2382
|
+
const derived = deriveCounterCtxForPseudo(source, getComputedStyle(source, pseudo), baseWithSibs);
|
|
2383
|
+
const finalVal = derived.get(source, name);
|
|
2384
|
+
map.set(name, finalVal);
|
|
2385
|
+
}
|
|
2386
|
+
__siblingCounters.set(source.parentElement, map);
|
|
2387
|
+
}
|
|
2388
|
+
continue;
|
|
2389
|
+
}
|
|
2281
2390
|
const pseudoEl = document.createElement("span");
|
|
2282
2391
|
pseudoEl.dataset.snapdomPseudo = pseudo;
|
|
2283
2392
|
pseudoEl.style.verticalAlign = "middle";
|
|
2284
2393
|
const snapshot = snapshotComputedStyle(style);
|
|
2285
2394
|
const key = getStyleKey(snapshot, "span");
|
|
2286
2395
|
sessionCache.styleMap.set(pseudoEl, key);
|
|
2287
|
-
if (isIconFont22 && cleanContent.length === 1) {
|
|
2288
|
-
const { dataUrl, width:
|
|
2396
|
+
if (isIconFont22 && cleanContent && cleanContent.length === 1) {
|
|
2397
|
+
const { dataUrl, width: w, height: h } = yield iconToImage(cleanContent, fontFamily, fontWeight, fontSize, color);
|
|
2289
2398
|
const imgEl = document.createElement("img");
|
|
2290
2399
|
imgEl.src = dataUrl;
|
|
2291
|
-
imgEl.style = `height:${fontSize}px;width:${
|
|
2400
|
+
imgEl.style = `height:${fontSize}px;width:${w / h * fontSize}px;object-fit:contain;`;
|
|
2292
2401
|
pseudoEl.appendChild(imgEl);
|
|
2293
2402
|
clone.dataset.snapdomHasIcon = "true";
|
|
2294
|
-
} else if (cleanContent.startsWith("url(")) {
|
|
2403
|
+
} else if (cleanContent && cleanContent.startsWith("url(")) {
|
|
2295
2404
|
const rawUrl = extractURL(cleanContent);
|
|
2296
2405
|
if (rawUrl == null ? void 0 : rawUrl.trim()) {
|
|
2297
2406
|
try {
|
|
@@ -2319,6 +2428,17 @@
|
|
|
2319
2428
|
if (hasBgColor) pseudoEl.style.backgroundColor = bgColor;
|
|
2320
2429
|
const hasContent2 = pseudoEl.childNodes.length > 0 || ((_a = pseudoEl.textContent) == null ? void 0 : _a.trim()) !== "";
|
|
2321
2430
|
const hasVisibleBox = hasContent2 || hasBg || hasBgColor || hasBox2 || hasBorder || hasTransform;
|
|
2431
|
+
if (incs && incs.length && source.parentElement) {
|
|
2432
|
+
const map = __siblingCounters.get(source.parentElement) || /* @__PURE__ */ new Map();
|
|
2433
|
+
const baseWithSibs = withSiblingOverrides(source, counterCtx);
|
|
2434
|
+
const derived = deriveCounterCtxForPseudo(source, getComputedStyle(source, pseudo), baseWithSibs);
|
|
2435
|
+
for (const { name } of incs) {
|
|
2436
|
+
if (!name) continue;
|
|
2437
|
+
const finalVal = derived.get(source, name);
|
|
2438
|
+
map.set(name, finalVal);
|
|
2439
|
+
}
|
|
2440
|
+
__siblingCounters.set(source.parentElement, map);
|
|
2441
|
+
}
|
|
2322
2442
|
if (!hasVisibleBox) continue;
|
|
2323
2443
|
if (pseudo === "::before") {
|
|
2324
2444
|
clone.insertBefore(pseudoEl, clone.firstChild);
|
|
@@ -2468,12 +2588,13 @@
|
|
|
2468
2588
|
sessionCache.styleCache.set(element, computed);
|
|
2469
2589
|
const transform = stripTranslate(computed.transform);
|
|
2470
2590
|
clone.style.margin = "0";
|
|
2471
|
-
clone.style.position = "static";
|
|
2472
2591
|
clone.style.top = "auto";
|
|
2473
2592
|
clone.style.left = "auto";
|
|
2474
2593
|
clone.style.right = "auto";
|
|
2475
2594
|
clone.style.bottom = "auto";
|
|
2476
|
-
clone.style.
|
|
2595
|
+
clone.style.animation = "none";
|
|
2596
|
+
clone.style.transition = "none";
|
|
2597
|
+
clone.style.willChange = "auto";
|
|
2477
2598
|
clone.style.float = "none";
|
|
2478
2599
|
clone.style.clear = "none";
|
|
2479
2600
|
clone.style.transform = transform || "";
|
|
@@ -2886,7 +3007,7 @@
|
|
|
2886
3007
|
idle(() => __async(null, null, function* () {
|
|
2887
3008
|
const required = collectUsedFontVariants(element);
|
|
2888
3009
|
const usedCodepoints = collectUsedCodepoints(element);
|
|
2889
|
-
if (isSafari) {
|
|
3010
|
+
if (isSafari()) {
|
|
2890
3011
|
const families = new Set(
|
|
2891
3012
|
Array.from(required).map((k) => String(k).split("__")[0]).filter(Boolean)
|
|
2892
3013
|
);
|
|
@@ -2918,102 +3039,188 @@
|
|
|
2918
3039
|
}
|
|
2919
3040
|
yield new Promise((resolve) => {
|
|
2920
3041
|
idle(() => {
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
const scaleOpt = (_a = options.scale) != null ? _a : 1;
|
|
2928
|
-
const hasScale = typeof scaleOpt === "number" && scaleOpt !== 1;
|
|
2929
|
-
if (!hasScale) {
|
|
2930
|
-
const aspect = h > 0 ? w / h : 1;
|
|
2931
|
-
if (hasW && hasH) {
|
|
2932
|
-
w = Number(options.width);
|
|
2933
|
-
h = Number(options.height);
|
|
2934
|
-
} else if (hasW) {
|
|
2935
|
-
w = Number(options.width);
|
|
2936
|
-
h = w / (aspect || 1);
|
|
2937
|
-
} else if (hasH) {
|
|
2938
|
-
h = Number(options.height);
|
|
2939
|
-
w = h * (aspect || 1);
|
|
3042
|
+
const csEl = getComputedStyle(element);
|
|
3043
|
+
function parseFilterDropShadows(cs) {
|
|
3044
|
+
var _a;
|
|
3045
|
+
const raw = `${cs.filter || ""} ${cs.webkitFilter || ""}`.trim();
|
|
3046
|
+
if (!raw || raw === "none") {
|
|
3047
|
+
return { bleed: { top: 0, right: 0, bottom: 0, left: 0 }, has: false };
|
|
2940
3048
|
}
|
|
3049
|
+
const tokens = raw.match(/drop-shadow\((?:[^()]|\([^()]*\))*\)/gi) || [];
|
|
3050
|
+
let t = 0, r = 0, b = 0, l = 0;
|
|
3051
|
+
let found = false;
|
|
3052
|
+
for (const tok of tokens) {
|
|
3053
|
+
found = true;
|
|
3054
|
+
const nums = ((_a = tok.match(/-?\d+(?:\.\d+)?px/gi)) == null ? void 0 : _a.map((v) => parseFloat(v))) || [];
|
|
3055
|
+
const [ox = 0, oy = 0, blur = 0] = nums;
|
|
3056
|
+
const extX = Math.abs(ox) + blur;
|
|
3057
|
+
const extY = Math.abs(oy) + blur;
|
|
3058
|
+
r = Math.max(r, extX + Math.max(ox, 0));
|
|
3059
|
+
l = Math.max(l, extX + Math.max(-ox, 0));
|
|
3060
|
+
b = Math.max(b, extY + Math.max(oy, 0));
|
|
3061
|
+
t = Math.max(t, extY + Math.max(-oy, 0));
|
|
3062
|
+
}
|
|
3063
|
+
return {
|
|
3064
|
+
bleed: { top: Math.ceil(t), right: Math.ceil(r), bottom: Math.ceil(b), left: Math.ceil(l) },
|
|
3065
|
+
has: found
|
|
3066
|
+
};
|
|
2941
3067
|
}
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
3068
|
+
function parseBoxShadow(cs) {
|
|
3069
|
+
var _a;
|
|
3070
|
+
const v = cs.boxShadow || "";
|
|
3071
|
+
if (!v || v === "none") return { top: 0, right: 0, bottom: 0, left: 0 };
|
|
3072
|
+
const parts = v.split(/\),(?=(?:[^()]*\([^()]*\))*[^()]*$)/).map((s) => s.trim());
|
|
3073
|
+
let t = 0, r = 0, b2 = 0, l = 0;
|
|
3074
|
+
for (const part of parts) {
|
|
3075
|
+
const nums = ((_a = part.match(/-?\d+(\.\d+)?px/g)) == null ? void 0 : _a.map((n) => parseFloat(n))) || [];
|
|
3076
|
+
if (nums.length < 2) continue;
|
|
3077
|
+
const [ox2, oy2, blur = 0, spread = 0] = nums;
|
|
3078
|
+
const extX = Math.abs(ox2) + blur + spread;
|
|
3079
|
+
const extY = Math.abs(oy2) + blur + spread;
|
|
3080
|
+
r = Math.max(r, extX + Math.max(ox2, 0));
|
|
3081
|
+
l = Math.max(l, extX + Math.max(-ox2, 0));
|
|
3082
|
+
b2 = Math.max(b2, extY + Math.max(oy2, 0));
|
|
3083
|
+
t = Math.max(t, extY + Math.max(-oy2, 0));
|
|
3084
|
+
}
|
|
3085
|
+
return { top: Math.ceil(t), right: Math.ceil(r), bottom: Math.ceil(b2), left: Math.ceil(l) };
|
|
3086
|
+
}
|
|
3087
|
+
function parseFilterBlur(cs) {
|
|
3088
|
+
const m = (cs.filter || "").match(/blur\(\s*([0-9.]+)px\s*\)/);
|
|
3089
|
+
const b2 = m ? Math.ceil(parseFloat(m[1]) || 0) : 0;
|
|
3090
|
+
return { top: b2, right: b2, bottom: b2, left: b2 };
|
|
3091
|
+
}
|
|
3092
|
+
function parseOutline(cs) {
|
|
3093
|
+
if ((cs.outlineStyle || "none") === "none") return { top: 0, right: 0, bottom: 0, left: 0 };
|
|
3094
|
+
const w2 = Math.ceil(parseFloat(cs.outlineWidth || "0") || 0);
|
|
3095
|
+
return { top: w2, right: w2, bottom: w2, left: w2 };
|
|
3096
|
+
}
|
|
3097
|
+
function bboxWithOriginFull(w2, h2, M, ox2, oy2) {
|
|
3098
|
+
const a2 = M.a, b2 = M.b, c2 = M.c, d2 = M.d, e2 = M.e || 0, f2 = M.f || 0;
|
|
3099
|
+
function pt(x, y) {
|
|
3100
|
+
let X = x - ox2, Y = y - oy2;
|
|
3101
|
+
let X2 = a2 * X + c2 * Y, Y2 = b2 * X + d2 * Y;
|
|
3102
|
+
X2 += ox2 + e2;
|
|
3103
|
+
Y2 += oy2 + f2;
|
|
3104
|
+
return [X2, Y2];
|
|
3105
|
+
}
|
|
3106
|
+
const P = [pt(0, 0), pt(w2, 0), pt(0, h2), pt(w2, h2)];
|
|
3107
|
+
let minX2 = Infinity, minY2 = Infinity, maxX2 = -Infinity, maxY2 = -Infinity;
|
|
3108
|
+
for (const [X, Y] of P) {
|
|
3109
|
+
if (X < minX2) minX2 = X;
|
|
3110
|
+
if (Y < minY2) minY2 = Y;
|
|
3111
|
+
if (X > maxX2) maxX2 = X;
|
|
3112
|
+
if (Y > maxY2) maxY2 = Y;
|
|
3113
|
+
}
|
|
3114
|
+
return { minX: minX2, minY: minY2, maxX: maxX2, maxY: maxY2, width: maxX2 - minX2, height: maxY2 - minY2 };
|
|
3115
|
+
}
|
|
3116
|
+
function hasTFBBox(el) {
|
|
3117
|
+
return hasBBoxAffectingTransform(el);
|
|
3118
|
+
}
|
|
3119
|
+
const rect = element.getBoundingClientRect();
|
|
3120
|
+
const w0 = Math.max(1, Math.ceil(element.offsetWidth || parseFloat(csEl.width) || rect.width || 1));
|
|
3121
|
+
const h0 = Math.max(1, Math.ceil(element.offsetHeight || parseFloat(csEl.height) || rect.height || 1));
|
|
3122
|
+
const coerceNum = (v, def = NaN) => {
|
|
3123
|
+
const n = typeof v === "string" ? parseFloat(v) : v;
|
|
3124
|
+
return Number.isFinite(n) ? n : def;
|
|
3125
|
+
};
|
|
3126
|
+
const optW = coerceNum(options.width);
|
|
3127
|
+
const optH = coerceNum(options.height);
|
|
3128
|
+
let w = w0, h = h0;
|
|
3129
|
+
const hasW = Number.isFinite(optW);
|
|
3130
|
+
const hasH = Number.isFinite(optH);
|
|
3131
|
+
const aspect0 = h0 > 0 ? w0 / h0 : 1;
|
|
3132
|
+
if (hasW && hasH) {
|
|
3133
|
+
w = Math.max(1, Math.ceil(optW));
|
|
3134
|
+
h = Math.max(1, Math.ceil(optH));
|
|
3135
|
+
} else if (hasW) {
|
|
3136
|
+
w = Math.max(1, Math.ceil(optW));
|
|
3137
|
+
h = Math.max(1, Math.ceil(w / (aspect0 || 1)));
|
|
3138
|
+
} else if (hasH) {
|
|
3139
|
+
h = Math.max(1, Math.ceil(optH));
|
|
3140
|
+
w = Math.max(1, Math.ceil(h * (aspect0 || 1)));
|
|
2955
3141
|
} else {
|
|
3142
|
+
w = w0;
|
|
3143
|
+
h = h0;
|
|
3144
|
+
}
|
|
3145
|
+
let minX = 0, minY = 0, maxX = w0, maxY = h0;
|
|
3146
|
+
if (hasTFBBox(element)) {
|
|
3147
|
+
const baseTransform2 = csEl.transform && csEl.transform !== "none" ? csEl.transform : "";
|
|
3148
|
+
const ind2 = readIndividualTransforms(element);
|
|
2956
3149
|
const TOTAL = readTotalTransformMatrix({
|
|
2957
|
-
baseTransform,
|
|
2958
|
-
rotate:
|
|
2959
|
-
scale:
|
|
2960
|
-
translate:
|
|
3150
|
+
baseTransform: baseTransform2,
|
|
3151
|
+
rotate: ind2.rotate || "0deg",
|
|
3152
|
+
scale: ind2.scale,
|
|
3153
|
+
translate: ind2.translate
|
|
2961
3154
|
});
|
|
2962
|
-
const
|
|
2963
|
-
const
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
outH = Math.max(1, Math.ceil(bb.height));
|
|
2970
|
-
tx = -bb.minX;
|
|
2971
|
-
ty = -bb.minY;
|
|
3155
|
+
const { ox: ox2, oy: oy2 } = parseTransformOriginPx(csEl, w0, h0);
|
|
3156
|
+
const M = TOTAL.is2D ? TOTAL : new DOMMatrix(TOTAL.toString());
|
|
3157
|
+
const bb = bboxWithOriginFull(w0, h0, M, ox2, oy2);
|
|
3158
|
+
minX = bb.minX;
|
|
3159
|
+
minY = bb.minY;
|
|
3160
|
+
maxX = bb.maxX;
|
|
3161
|
+
maxY = bb.maxY;
|
|
2972
3162
|
}
|
|
3163
|
+
const bleedShadow = parseBoxShadow(csEl);
|
|
3164
|
+
const bleedBlur = parseFilterBlur(csEl);
|
|
3165
|
+
const bleedOutline = parseOutline(csEl);
|
|
3166
|
+
const drop = parseFilterDropShadows(csEl);
|
|
3167
|
+
const bleed = {
|
|
3168
|
+
top: bleedShadow.top + bleedBlur.top + bleedOutline.top + drop.bleed.top,
|
|
3169
|
+
right: bleedShadow.right + bleedBlur.right + bleedOutline.right + drop.bleed.right,
|
|
3170
|
+
bottom: bleedShadow.bottom + bleedBlur.bottom + bleedOutline.bottom + drop.bleed.bottom,
|
|
3171
|
+
left: bleedShadow.left + bleedBlur.left + bleedOutline.left + drop.bleed.left
|
|
3172
|
+
};
|
|
3173
|
+
minX -= bleed.left;
|
|
3174
|
+
minY -= bleed.top;
|
|
3175
|
+
maxX += bleed.right;
|
|
3176
|
+
maxY += bleed.bottom;
|
|
3177
|
+
const vbW0 = Math.max(1, Math.ceil(maxX - minX));
|
|
3178
|
+
const vbH0 = Math.max(1, Math.ceil(maxY - minY));
|
|
3179
|
+
const outW = Math.max(1, Math.round(vbW0 * (hasW || hasH ? w / w0 : 1)));
|
|
3180
|
+
const outH = Math.max(1, Math.round(vbH0 * (hasH || hasW ? h / h0 : 1)));
|
|
2973
3181
|
const svgNS = "http://www.w3.org/2000/svg";
|
|
3182
|
+
const pad = isSafari() ? 1 : 0;
|
|
2974
3183
|
const fo = document.createElementNS(svgNS, "foreignObject");
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
fo.setAttribute("x", String(
|
|
2978
|
-
fo.setAttribute("y", String(
|
|
3184
|
+
const vbMinX = Math.floor(minX);
|
|
3185
|
+
const vbMinY = Math.floor(minY);
|
|
3186
|
+
fo.setAttribute("x", String(-(vbMinX - pad)));
|
|
3187
|
+
fo.setAttribute("y", String(-(vbMinY - pad)));
|
|
3188
|
+
fo.setAttribute("width", String(Math.ceil(w0 + pad * 2)));
|
|
3189
|
+
fo.setAttribute("height", String(Math.ceil(h0 + pad * 2)));
|
|
2979
3190
|
fo.style.overflow = "visible";
|
|
2980
3191
|
const styleTag = document.createElement("style");
|
|
2981
3192
|
styleTag.textContent = baseCSS + fontsCSS + "svg{overflow:visible;} foreignObject{overflow:visible;}" + classCSS;
|
|
2982
3193
|
fo.appendChild(styleTag);
|
|
2983
3194
|
const container = document.createElement("div");
|
|
2984
3195
|
container.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
2985
|
-
container.style.width = `${
|
|
2986
|
-
container.style.height = `${
|
|
3196
|
+
container.style.width = `${w0}px`;
|
|
3197
|
+
container.style.height = `${h0}px`;
|
|
2987
3198
|
container.style.overflow = "visible";
|
|
2988
|
-
container.style.transformOrigin = "0 0";
|
|
2989
|
-
const cancels = [];
|
|
2990
|
-
if (cancelTranslateX || cancelTranslateY) {
|
|
2991
|
-
cancels.push(`translate(${cancelTranslateX}px, ${cancelTranslateY}px)`);
|
|
2992
|
-
}
|
|
2993
|
-
if (!hasScale && (hasW || hasH)) {
|
|
2994
|
-
const sxWH = rect.width ? w / rect.width : 1;
|
|
2995
|
-
const syWH = rect.height ? h / rect.height : 1;
|
|
2996
|
-
cancels.push(`scale(${sxWH}, ${syWH})`);
|
|
2997
|
-
} else if (hasScale) {
|
|
2998
|
-
cancels.push(`scale(${scaleOpt})`);
|
|
2999
|
-
}
|
|
3000
|
-
if (cancels.length) container.style.transform = cancels.join(" ");
|
|
3001
3199
|
clone.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
3002
|
-
clone.style.transformOrigin = "0 0";
|
|
3003
|
-
clone.style.position = "static";
|
|
3004
|
-
clone.style.left = "0";
|
|
3005
|
-
clone.style.top = "0";
|
|
3006
|
-
if (baseTransform) clone.style.transform = baseTransform;
|
|
3007
|
-
clone.style.rotate = ind.rotate || "0deg";
|
|
3008
|
-
clone.style.scale = ind.scale || "1";
|
|
3009
|
-
clone.style.translate = ind.translate || "0 0";
|
|
3010
3200
|
container.appendChild(clone);
|
|
3011
3201
|
fo.appendChild(container);
|
|
3012
3202
|
const serializer = new XMLSerializer();
|
|
3013
3203
|
const foString = serializer.serializeToString(fo);
|
|
3014
|
-
const
|
|
3015
|
-
const
|
|
3016
|
-
const
|
|
3204
|
+
const vbW = vbW0 + pad * 2;
|
|
3205
|
+
const vbH = vbH0 + pad * 2;
|
|
3206
|
+
const wantsSize = hasW || hasH;
|
|
3207
|
+
options.meta = {
|
|
3208
|
+
w0,
|
|
3209
|
+
// ancho natural del elemento
|
|
3210
|
+
h0,
|
|
3211
|
+
// alto natural
|
|
3212
|
+
vbW,
|
|
3213
|
+
// ancho del viewBox
|
|
3214
|
+
vbH,
|
|
3215
|
+
// alto del viewBox
|
|
3216
|
+
targetW: w,
|
|
3217
|
+
// ancho deseado según options.width
|
|
3218
|
+
targetH: h
|
|
3219
|
+
// alto deseado según options.height
|
|
3220
|
+
};
|
|
3221
|
+
const svgOutW = isSafari() && wantsSize ? vbW : outW + pad * 2;
|
|
3222
|
+
const svgOutH = isSafari() && wantsSize ? vbH : outH + pad * 2;
|
|
3223
|
+
const svgHeader = `<svg xmlns="${svgNS}" width="${svgOutW}" height="${svgOutH}" viewBox="0 0 ${vbW} ${vbH}">`;
|
|
3017
3224
|
const svgFooter = "</svg>";
|
|
3018
3225
|
svgString = svgHeader + foString + svgFooter;
|
|
3019
3226
|
dataURL = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
|
|
@@ -3034,28 +3241,8 @@
|
|
|
3034
3241
|
return new WebKitCSSMatrix(tr);
|
|
3035
3242
|
}
|
|
3036
3243
|
}
|
|
3037
|
-
function matrix2DNoTranslate(M) {
|
|
3038
|
-
return new DOMMatrix([M.a, M.b, M.c, M.d, 0, 0]);
|
|
3039
|
-
}
|
|
3040
|
-
function bboxFromMatrix(w, h, M2D) {
|
|
3041
|
-
const pts = [
|
|
3042
|
-
{ x: 0, y: 0 },
|
|
3043
|
-
{ x: w, y: 0 },
|
|
3044
|
-
{ x: 0, y: h },
|
|
3045
|
-
{ x: w, y: h }
|
|
3046
|
-
];
|
|
3047
|
-
const t = pts.map((p) => ({
|
|
3048
|
-
x: M2D.a * p.x + M2D.c * p.y,
|
|
3049
|
-
y: M2D.b * p.x + M2D.d * p.y
|
|
3050
|
-
}));
|
|
3051
|
-
const minX = Math.min(...t.map((p) => p.x));
|
|
3052
|
-
const maxX = Math.max(...t.map((p) => p.x));
|
|
3053
|
-
const minY = Math.min(...t.map((p) => p.y));
|
|
3054
|
-
const maxY = Math.max(...t.map((p) => p.y));
|
|
3055
|
-
return { minX, minY, width: maxX - minX, height: maxY - minY };
|
|
3056
|
-
}
|
|
3057
3244
|
function readIndividualTransforms(el) {
|
|
3058
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
3245
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
3059
3246
|
const out = { rotate: "0deg", scale: null, translate: null };
|
|
3060
3247
|
const map = typeof el.computedStyleMap === "function" ? el.computedStyleMap() : null;
|
|
3061
3248
|
if (map) {
|
|
@@ -3070,26 +3257,37 @@
|
|
|
3070
3257
|
};
|
|
3071
3258
|
const rot = safeGet("rotate");
|
|
3072
3259
|
if (rot) {
|
|
3073
|
-
|
|
3074
|
-
|
|
3260
|
+
if (rot.angle) {
|
|
3261
|
+
const ang = rot.angle;
|
|
3075
3262
|
out.rotate = ang.unit === "rad" ? ang.value * 180 / Math.PI + "deg" : ang.value + ang.unit;
|
|
3263
|
+
} else if (rot.unit) {
|
|
3264
|
+
out.rotate = rot.unit === "rad" ? rot.value * 180 / Math.PI + "deg" : rot.value + rot.unit;
|
|
3076
3265
|
} else {
|
|
3077
3266
|
out.rotate = String(rot);
|
|
3078
3267
|
}
|
|
3268
|
+
} else {
|
|
3269
|
+
const cs2 = getComputedStyle(el);
|
|
3270
|
+
out.rotate = cs2.rotate && cs2.rotate !== "none" ? cs2.rotate : "0deg";
|
|
3079
3271
|
}
|
|
3080
3272
|
const sc = safeGet("scale");
|
|
3081
|
-
if (sc
|
|
3082
|
-
const sx = (
|
|
3083
|
-
const sy =
|
|
3273
|
+
if (sc) {
|
|
3274
|
+
const sx = "x" in sc && ((_a = sc.x) == null ? void 0 : _a.value) != null ? sc.x.value : Array.isArray(sc) ? (_b = sc[0]) == null ? void 0 : _b.value : Number(sc) || 1;
|
|
3275
|
+
const sy = "y" in sc && ((_c = sc.y) == null ? void 0 : _c.value) != null ? sc.y.value : Array.isArray(sc) ? (_d = sc[1]) == null ? void 0 : _d.value : sx;
|
|
3084
3276
|
out.scale = `${sx} ${sy}`;
|
|
3277
|
+
} else {
|
|
3278
|
+
const cs2 = getComputedStyle(el);
|
|
3279
|
+
out.scale = cs2.scale && cs2.scale !== "none" ? cs2.scale : null;
|
|
3085
3280
|
}
|
|
3086
3281
|
const tr = safeGet("translate");
|
|
3087
|
-
if (tr
|
|
3088
|
-
const tx = (
|
|
3089
|
-
const ty = (
|
|
3090
|
-
const ux =
|
|
3091
|
-
const uy =
|
|
3282
|
+
if (tr) {
|
|
3283
|
+
const tx = "x" in tr && "value" in tr.x ? tr.x.value : Array.isArray(tr) ? (_e = tr[0]) == null ? void 0 : _e.value : 0;
|
|
3284
|
+
const ty = "y" in tr && "value" in tr.y ? tr.y.value : Array.isArray(tr) ? (_f = tr[1]) == null ? void 0 : _f.value : 0;
|
|
3285
|
+
const ux = "x" in tr && ((_g = tr.x) == null ? void 0 : _g.unit) ? tr.x.unit : "px";
|
|
3286
|
+
const uy = "y" in tr && ((_h = tr.y) == null ? void 0 : _h.unit) ? tr.y.unit : "px";
|
|
3092
3287
|
out.translate = `${tx}${ux} ${ty}${uy}`;
|
|
3288
|
+
} else {
|
|
3289
|
+
const cs2 = getComputedStyle(el);
|
|
3290
|
+
out.translate = cs2.translate && cs2.translate !== "none" ? cs2.translate : null;
|
|
3093
3291
|
}
|
|
3094
3292
|
return out;
|
|
3095
3293
|
}
|
|
@@ -3100,17 +3298,33 @@
|
|
|
3100
3298
|
return out;
|
|
3101
3299
|
}
|
|
3102
3300
|
function hasBBoxAffectingTransform(el) {
|
|
3103
|
-
const
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
return true;
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
const
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3301
|
+
const cs = getComputedStyle(el);
|
|
3302
|
+
const t = cs.transform || "none";
|
|
3303
|
+
const hasMatrix = t !== "none" && !/^matrix\(\s*1\s*,\s*0\s*,\s*0\s*,\s*1\s*,\s*0\s*,\s*0\s*\)$/i.test(t);
|
|
3304
|
+
if (hasMatrix) return true;
|
|
3305
|
+
const r = cs.rotate && cs.rotate !== "none" && cs.rotate !== "0deg";
|
|
3306
|
+
const s = cs.scale && cs.scale !== "none" && cs.scale !== "1";
|
|
3307
|
+
const tr = cs.translate && cs.translate !== "none" && cs.translate !== "0px 0px";
|
|
3308
|
+
return Boolean(r || s || tr);
|
|
3309
|
+
}
|
|
3310
|
+
function parseTransformOriginPx(cs, w, h) {
|
|
3311
|
+
const raw = (cs.transformOrigin || "0 0").trim().split(/\s+/);
|
|
3312
|
+
const [oxRaw, oyRaw] = [raw[0] || "0", raw[1] || "0"];
|
|
3313
|
+
const toPx = (token, size) => {
|
|
3314
|
+
const t = token.toLowerCase();
|
|
3315
|
+
if (t === "left" || t === "top") return 0;
|
|
3316
|
+
if (t === "center") return size / 2;
|
|
3317
|
+
if (t === "right") return size;
|
|
3318
|
+
if (t === "bottom") return size;
|
|
3319
|
+
if (t.endsWith("px")) return parseFloat(t) || 0;
|
|
3320
|
+
if (t.endsWith("%")) return (parseFloat(t) || 0) * size / 100;
|
|
3321
|
+
if (/^-?\d+(\.\d+)?$/.test(t)) return parseFloat(t) || 0;
|
|
3322
|
+
return 0;
|
|
3323
|
+
};
|
|
3324
|
+
return {
|
|
3325
|
+
ox: toPx(oxRaw, w),
|
|
3326
|
+
oy: toPx(oyRaw, h)
|
|
3327
|
+
};
|
|
3114
3328
|
}
|
|
3115
3329
|
var __measureHost = null;
|
|
3116
3330
|
function getMeasureHost() {
|
|
@@ -3199,41 +3413,201 @@
|
|
|
3199
3413
|
};
|
|
3200
3414
|
}
|
|
3201
3415
|
|
|
3202
|
-
// src/exporters/
|
|
3203
|
-
function
|
|
3416
|
+
// src/exporters/toCanvas.js
|
|
3417
|
+
function isSvgDataURL(u) {
|
|
3418
|
+
return typeof u === "string" && /^data:image\/svg\+xml/i.test(u);
|
|
3419
|
+
}
|
|
3420
|
+
function decodeSvgFromDataURL(u) {
|
|
3421
|
+
const i = u.indexOf(",");
|
|
3422
|
+
return i >= 0 ? decodeURIComponent(u.slice(i + 1)) : "";
|
|
3423
|
+
}
|
|
3424
|
+
function encodeSvgToDataURL(svgText) {
|
|
3425
|
+
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgText)}`;
|
|
3426
|
+
}
|
|
3427
|
+
function splitDecls(s) {
|
|
3428
|
+
let parts = [], buf = "", depth = 0;
|
|
3429
|
+
for (let i = 0; i < s.length; i++) {
|
|
3430
|
+
const ch = s[i];
|
|
3431
|
+
if (ch === "(") depth++;
|
|
3432
|
+
if (ch === ")") depth = Math.max(0, depth - 1);
|
|
3433
|
+
if (ch === ";" && depth === 0) {
|
|
3434
|
+
parts.push(buf);
|
|
3435
|
+
buf = "";
|
|
3436
|
+
} else buf += ch;
|
|
3437
|
+
}
|
|
3438
|
+
if (buf.trim()) parts.push(buf);
|
|
3439
|
+
return parts.map((x) => x.trim()).filter(Boolean);
|
|
3440
|
+
}
|
|
3441
|
+
function boxShadowToDropShadow(value) {
|
|
3442
|
+
const layers = [];
|
|
3443
|
+
let buf = "", depth = 0;
|
|
3444
|
+
for (let i = 0; i < value.length; i++) {
|
|
3445
|
+
const ch = value[i];
|
|
3446
|
+
if (ch === "(") depth++;
|
|
3447
|
+
if (ch === ")") depth = Math.max(0, depth - 1);
|
|
3448
|
+
if (ch === "," && depth === 0) {
|
|
3449
|
+
layers.push(buf.trim());
|
|
3450
|
+
buf = "";
|
|
3451
|
+
} else buf += ch;
|
|
3452
|
+
}
|
|
3453
|
+
if (buf.trim()) layers.push(buf.trim());
|
|
3454
|
+
const fns = [];
|
|
3455
|
+
for (const layer of layers) {
|
|
3456
|
+
if (/\binset\b/i.test(layer)) continue;
|
|
3457
|
+
const nums = layer.match(/-?\d+(?:\.\d+)?px/gi) || [];
|
|
3458
|
+
const [ox = "0px", oy = "0px", blur = "0px"] = nums;
|
|
3459
|
+
let color = layer.replace(/-?\d+(?:\.\d+)?px/gi, "").replace(/\binset\b/ig, "").trim().replace(/\s{2,}/g, " ");
|
|
3460
|
+
const hasColor = !!color && color !== ",";
|
|
3461
|
+
fns.push(`drop-shadow(${ox} ${oy} ${blur}${hasColor ? ` ${color}` : ""})`);
|
|
3462
|
+
}
|
|
3463
|
+
return fns.join(" ");
|
|
3464
|
+
}
|
|
3465
|
+
function rewriteDeclList(list) {
|
|
3466
|
+
const decls = splitDecls(list);
|
|
3467
|
+
let filter = null, wfilter = null, box = null;
|
|
3468
|
+
const rest = [];
|
|
3469
|
+
for (const d of decls) {
|
|
3470
|
+
const idx = d.indexOf(":");
|
|
3471
|
+
if (idx < 0) continue;
|
|
3472
|
+
const prop = d.slice(0, idx).trim().toLowerCase();
|
|
3473
|
+
const val = d.slice(idx + 1).trim();
|
|
3474
|
+
if (prop === "box-shadow") box = val;
|
|
3475
|
+
else if (prop === "filter") filter = val;
|
|
3476
|
+
else if (prop === "-webkit-filter") wfilter = val;
|
|
3477
|
+
else rest.push([prop, val]);
|
|
3478
|
+
}
|
|
3479
|
+
if (box) {
|
|
3480
|
+
const ds = boxShadowToDropShadow(box);
|
|
3481
|
+
if (ds) {
|
|
3482
|
+
filter = filter ? `${filter} ${ds}` : ds;
|
|
3483
|
+
wfilter = wfilter ? `${wfilter} ${ds}` : ds;
|
|
3484
|
+
}
|
|
3485
|
+
}
|
|
3486
|
+
const out = [...rest];
|
|
3487
|
+
if (filter) out.push(["filter", filter]);
|
|
3488
|
+
if (wfilter) out.push(["-webkit-filter", wfilter]);
|
|
3489
|
+
return out.map(([k, v]) => `${k}:${v}`).join(";");
|
|
3490
|
+
}
|
|
3491
|
+
function rewriteCssBlock(css) {
|
|
3492
|
+
return css.replace(/([^{}]+)\{([^}]*)\}/g, (_m, sel, body) => `${sel}{${rewriteDeclList(body)}}`);
|
|
3493
|
+
}
|
|
3494
|
+
function rewriteSvgBoxShadowToDropShadow(svgText) {
|
|
3495
|
+
svgText = svgText.replace(
|
|
3496
|
+
/<style[^>]*>([\s\S]*?)<\/style>/gi,
|
|
3497
|
+
(m, css) => m.replace(css, rewriteCssBlock(css))
|
|
3498
|
+
);
|
|
3499
|
+
svgText = svgText.replace(
|
|
3500
|
+
/style=(['"])([\s\S]*?)\1/gi,
|
|
3501
|
+
(m, q, body) => `style=${q}${rewriteDeclList(body)}${q}`
|
|
3502
|
+
);
|
|
3503
|
+
return svgText;
|
|
3504
|
+
}
|
|
3505
|
+
function maybeConvertBoxShadowForSafari(url) {
|
|
3506
|
+
if (!isSafari() || !isSvgDataURL(url)) return url;
|
|
3507
|
+
try {
|
|
3508
|
+
const svg = decodeSvgFromDataURL(url);
|
|
3509
|
+
const fixed = rewriteSvgBoxShadowToDropShadow(svg);
|
|
3510
|
+
return encodeSvgToDataURL(fixed);
|
|
3511
|
+
} catch (e) {
|
|
3512
|
+
return url;
|
|
3513
|
+
}
|
|
3514
|
+
}
|
|
3515
|
+
function toCanvas(url, options) {
|
|
3204
3516
|
return __async(this, null, function* () {
|
|
3517
|
+
let { width: optW, height: optH, scale = 1, dpr = 1, meta = {} } = options;
|
|
3518
|
+
url = maybeConvertBoxShadowForSafari(url);
|
|
3205
3519
|
const img = new Image();
|
|
3520
|
+
img.loading = "eager";
|
|
3521
|
+
img.decoding = "sync";
|
|
3522
|
+
img.crossOrigin = "anonymous";
|
|
3206
3523
|
img.src = url;
|
|
3207
3524
|
yield img.decode();
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3525
|
+
const natW = img.naturalWidth;
|
|
3526
|
+
const natH = img.naturalHeight;
|
|
3527
|
+
const refW = Number.isFinite(meta.w0) ? meta.w0 : natW;
|
|
3528
|
+
const refH = Number.isFinite(meta.h0) ? meta.h0 : natH;
|
|
3529
|
+
let outW, outH;
|
|
3530
|
+
const hasW = Number.isFinite(optW);
|
|
3531
|
+
const hasH = Number.isFinite(optH);
|
|
3532
|
+
if (hasW && hasH) {
|
|
3533
|
+
outW = Math.max(1, optW);
|
|
3534
|
+
outH = Math.max(1, optH);
|
|
3535
|
+
} else if (hasW) {
|
|
3536
|
+
const k = optW / Math.max(1, refW);
|
|
3537
|
+
outW = optW;
|
|
3538
|
+
outH = Math.round(refH * k);
|
|
3539
|
+
} else if (hasH) {
|
|
3540
|
+
const k = optH / Math.max(1, refH);
|
|
3541
|
+
outH = optH;
|
|
3542
|
+
outW = Math.round(refW * k);
|
|
3543
|
+
} else {
|
|
3544
|
+
outW = natW;
|
|
3545
|
+
outH = natH;
|
|
3211
3546
|
}
|
|
3547
|
+
outW = Math.round(outW * scale);
|
|
3548
|
+
outH = Math.round(outH * scale);
|
|
3549
|
+
const canvas = document.createElement("canvas");
|
|
3550
|
+
canvas.width = Math.ceil(outW * dpr);
|
|
3551
|
+
canvas.height = Math.ceil(outH * dpr);
|
|
3552
|
+
canvas.style.width = `${outW}px`;
|
|
3553
|
+
canvas.style.height = `${outH}px`;
|
|
3554
|
+
const ctx = canvas.getContext("2d");
|
|
3555
|
+
if (dpr !== 1) ctx.scale(dpr, dpr);
|
|
3556
|
+
ctx.drawImage(img, 0, 0, outW, outH);
|
|
3557
|
+
return canvas;
|
|
3558
|
+
});
|
|
3559
|
+
}
|
|
3560
|
+
|
|
3561
|
+
// src/modules/rasterize.js
|
|
3562
|
+
function rasterize(url, options) {
|
|
3563
|
+
return __async(this, null, function* () {
|
|
3564
|
+
const canvas = yield toCanvas(url, options);
|
|
3565
|
+
const finalCanvas = options.backgroundColor ? createBackground(canvas, options.backgroundColor) : canvas;
|
|
3566
|
+
const img = new Image();
|
|
3567
|
+
img.src = finalCanvas.toDataURL(`image/${options.format}`, options.quality);
|
|
3568
|
+
yield img.decode();
|
|
3569
|
+
img.style.width = `${finalCanvas.width / options.dpr}px`;
|
|
3570
|
+
img.style.height = `${finalCanvas.height / options.dpr}px`;
|
|
3212
3571
|
return img;
|
|
3213
3572
|
});
|
|
3214
3573
|
}
|
|
3215
3574
|
|
|
3216
|
-
// src/exporters/
|
|
3217
|
-
function
|
|
3575
|
+
// src/exporters/toImg.js
|
|
3576
|
+
function toImg(url, options) {
|
|
3218
3577
|
return __async(this, null, function* () {
|
|
3219
|
-
const { scale,
|
|
3578
|
+
const { scale = 1, width, height, meta = {} } = options;
|
|
3579
|
+
const hasW = Number.isFinite(width);
|
|
3580
|
+
const hasH = Number.isFinite(height);
|
|
3581
|
+
const wantsScale = Number.isFinite(scale) && scale !== 1 || hasW || hasH;
|
|
3582
|
+
if (isSafari() && wantsScale) {
|
|
3583
|
+
const pngUrl = yield rasterize(url, __spreadProps(__spreadValues({}, options), { format: "png", quality: 1, meta }));
|
|
3584
|
+
return pngUrl;
|
|
3585
|
+
}
|
|
3220
3586
|
const img = new Image();
|
|
3221
|
-
img.crossOrigin = "anonymous";
|
|
3222
|
-
img.loading = "eager";
|
|
3223
3587
|
img.decoding = "sync";
|
|
3588
|
+
img.loading = "eager";
|
|
3224
3589
|
img.src = url;
|
|
3225
3590
|
yield img.decode();
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3591
|
+
if (hasW && hasH) {
|
|
3592
|
+
img.style.width = `${width}px`;
|
|
3593
|
+
img.style.height = `${height}px`;
|
|
3594
|
+
} else if (hasW) {
|
|
3595
|
+
const refW = Number.isFinite(meta.w0) ? meta.w0 : img.naturalWidth;
|
|
3596
|
+
const refH = Number.isFinite(meta.h0) ? meta.h0 : img.naturalHeight;
|
|
3597
|
+
const k = width / Math.max(1, refW);
|
|
3598
|
+
img.style.width = `${width}px`;
|
|
3599
|
+
img.style.height = `${Math.round(refH * k)}px`;
|
|
3600
|
+
} else if (hasH) {
|
|
3601
|
+
const refW = Number.isFinite(meta.w0) ? meta.w0 : img.naturalWidth;
|
|
3602
|
+
const refH = Number.isFinite(meta.h0) ? meta.h0 : img.naturalHeight;
|
|
3603
|
+
const k = height / Math.max(1, refH);
|
|
3604
|
+
img.style.height = `${height}px`;
|
|
3605
|
+
img.style.width = `${Math.round(refW * k)}px`;
|
|
3606
|
+
} else if (scale !== 1) {
|
|
3607
|
+
img.style.width = `${Math.round(img.naturalWidth * scale)}px`;
|
|
3608
|
+
img.style.height = `${Math.round(img.naturalHeight * scale)}px`;
|
|
3609
|
+
}
|
|
3610
|
+
return img;
|
|
3237
3611
|
});
|
|
3238
3612
|
}
|
|
3239
3613
|
|
|
@@ -3257,20 +3631,6 @@
|
|
|
3257
3631
|
});
|
|
3258
3632
|
}
|
|
3259
3633
|
|
|
3260
|
-
// src/modules/rasterize.js
|
|
3261
|
-
function rasterize(url, options) {
|
|
3262
|
-
return __async(this, null, function* () {
|
|
3263
|
-
const canvas = yield toCanvas(url, options);
|
|
3264
|
-
const finalCanvas = options.backgroundColor ? createBackground(canvas, options.backgroundColor) : canvas;
|
|
3265
|
-
const img = new Image();
|
|
3266
|
-
img.src = finalCanvas.toDataURL(`image/${options.format}`, options.quality);
|
|
3267
|
-
yield img.decode();
|
|
3268
|
-
img.style.width = `${finalCanvas.width / options.dpr}px`;
|
|
3269
|
-
img.style.height = `${finalCanvas.height / options.dpr}px`;
|
|
3270
|
-
return img;
|
|
3271
|
-
});
|
|
3272
|
-
}
|
|
3273
|
-
|
|
3274
3634
|
// src/exporters/download.js
|
|
3275
3635
|
function download(url, options) {
|
|
3276
3636
|
return __async(this, null, function* () {
|
|
@@ -3300,7 +3660,8 @@
|
|
|
3300
3660
|
function snapdom(element, userOptions) {
|
|
3301
3661
|
return __async(this, null, function* () {
|
|
3302
3662
|
if (!element) throw new Error("Element cannot be null or undefined");
|
|
3303
|
-
|
|
3663
|
+
const context = createContext(userOptions);
|
|
3664
|
+
if (isSafari() && (context.embedFonts === true || hasBackgroundOrMask(element))) {
|
|
3304
3665
|
for (let i = 0; i < 3; i++) {
|
|
3305
3666
|
try {
|
|
3306
3667
|
yield safariWarmup(element, userOptions);
|
|
@@ -3310,7 +3671,6 @@
|
|
|
3310
3671
|
}
|
|
3311
3672
|
}
|
|
3312
3673
|
}
|
|
3313
|
-
const context = createContext(userOptions);
|
|
3314
3674
|
if (context.iconFonts && context.iconFonts.length > 0) extendIconFonts(context.iconFonts);
|
|
3315
3675
|
if (!context.snap) {
|
|
3316
3676
|
context.snap = {
|
|
@@ -3392,6 +3752,20 @@
|
|
|
3392
3752
|
});
|
|
3393
3753
|
});
|
|
3394
3754
|
}
|
|
3755
|
+
function hasBackgroundOrMask(el) {
|
|
3756
|
+
const walker = document.createTreeWalker(el, NodeFilter.SHOW_ELEMENT);
|
|
3757
|
+
while (walker.nextNode()) {
|
|
3758
|
+
const node = (
|
|
3759
|
+
/** @type {Element} */
|
|
3760
|
+
walker.currentNode
|
|
3761
|
+
);
|
|
3762
|
+
const cs = getComputedStyle(node);
|
|
3763
|
+
const bg = cs.backgroundImage && cs.backgroundImage !== "none";
|
|
3764
|
+
const mask = cs.maskImage && cs.maskImage !== "none" || cs.webkitMaskImage && cs.webkitMaskImage !== "none";
|
|
3765
|
+
if (bg || mask) return true;
|
|
3766
|
+
}
|
|
3767
|
+
return false;
|
|
3768
|
+
}
|
|
3395
3769
|
|
|
3396
3770
|
// src/api/preCache.js
|
|
3397
3771
|
function preCache() {
|