@zumer/snapdom 1.9.12-dev.2 → 1.9.12-dev.4
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 +664 -185
- package/dist/snapdom.min.js +5 -5
- package/dist/snapdom.min.mjs +5 -5
- package/dist/snapdom.mjs +658 -181
- package/package.json +1 -1
- package/types/snapdom.d.ts +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.4
|
|
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) {
|
|
@@ -675,8 +664,9 @@
|
|
|
675
664
|
function isSafari() {
|
|
676
665
|
const ua = typeof navigator !== "undefined" && navigator.userAgent ? navigator.userAgent : "";
|
|
677
666
|
const isSafariUA = /^((?!chrome|android).)*safari/i.test(ua);
|
|
667
|
+
const isUIWebView = /AppleWebKit/i.test(ua) && /Mobile/i.test(ua) && !/Safari/i.test(ua);
|
|
678
668
|
const isWeChatUA = /(MicroMessenger|wxwork|WeCom|WindowsWechat|MacWechat)/i.test(ua);
|
|
679
|
-
return isSafariUA || isWeChatUA;
|
|
669
|
+
return isSafariUA || isUIWebView || isWeChatUA;
|
|
680
670
|
}
|
|
681
671
|
|
|
682
672
|
// src/modules/styles.js
|
|
@@ -2172,11 +2162,21 @@
|
|
|
2172
2162
|
const empty = /* @__PURE__ */ new Map();
|
|
2173
2163
|
build(rootEl, empty, empty);
|
|
2174
2164
|
return {
|
|
2165
|
+
/**
|
|
2166
|
+
* Get top value for counter name at given node.
|
|
2167
|
+
* @param {Element} node
|
|
2168
|
+
* @param {string} name
|
|
2169
|
+
*/
|
|
2175
2170
|
get(node, name) {
|
|
2176
2171
|
var _a;
|
|
2177
2172
|
const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
|
|
2178
2173
|
return s && s.length ? s[s.length - 1] : 0;
|
|
2179
2174
|
},
|
|
2175
|
+
/**
|
|
2176
|
+
* Get full stack for counter name at given node.
|
|
2177
|
+
* @param {Element} node
|
|
2178
|
+
* @param {string} name
|
|
2179
|
+
*/
|
|
2180
2180
|
getStack(node, name) {
|
|
2181
2181
|
var _a;
|
|
2182
2182
|
const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
|
|
@@ -2214,10 +2214,111 @@
|
|
|
2214
2214
|
|
|
2215
2215
|
// src/modules/pseudo.js
|
|
2216
2216
|
var counterCtx = null;
|
|
2217
|
+
var __siblingCounters = /* @__PURE__ */ new WeakMap();
|
|
2218
|
+
function unquoteDoubleStrings2(s) {
|
|
2219
|
+
return (s || "").replace(/"([^"]*)"/g, "$1");
|
|
2220
|
+
}
|
|
2221
|
+
function collapseCssContent(raw) {
|
|
2222
|
+
if (!raw) return "";
|
|
2223
|
+
const tokens = [];
|
|
2224
|
+
const rx = /"([^"]*)"/g;
|
|
2225
|
+
let m;
|
|
2226
|
+
while (m = rx.exec(raw)) tokens.push(m[1]);
|
|
2227
|
+
if (tokens.length) return tokens.join("");
|
|
2228
|
+
return unquoteDoubleStrings2(raw);
|
|
2229
|
+
}
|
|
2230
|
+
function withSiblingOverrides(node, base) {
|
|
2231
|
+
const parent = node.parentElement;
|
|
2232
|
+
const map = parent ? __siblingCounters.get(parent) : null;
|
|
2233
|
+
if (!map) return base;
|
|
2234
|
+
return {
|
|
2235
|
+
get(n, name) {
|
|
2236
|
+
const v = base.get(n, name);
|
|
2237
|
+
const ov = map.get(name);
|
|
2238
|
+
return typeof ov === "number" ? Math.max(v, ov) : v;
|
|
2239
|
+
},
|
|
2240
|
+
getStack(n, name) {
|
|
2241
|
+
const s = base.getStack(n, name);
|
|
2242
|
+
if (!s.length) return s;
|
|
2243
|
+
const ov = map.get(name);
|
|
2244
|
+
if (typeof ov === "number") {
|
|
2245
|
+
const out = s.slice();
|
|
2246
|
+
out[out.length - 1] = Math.max(out[out.length - 1], ov);
|
|
2247
|
+
return out;
|
|
2248
|
+
}
|
|
2249
|
+
return s;
|
|
2250
|
+
}
|
|
2251
|
+
};
|
|
2252
|
+
}
|
|
2253
|
+
function deriveCounterCtxForPseudo(node, pseudoStyle, baseCtx) {
|
|
2254
|
+
const modStacks = /* @__PURE__ */ new Map();
|
|
2255
|
+
function parseListDecl(value) {
|
|
2256
|
+
const out = [];
|
|
2257
|
+
if (!value || value === "none") return out;
|
|
2258
|
+
for (const part of String(value).split(",")) {
|
|
2259
|
+
const toks = part.trim().split(/\s+/);
|
|
2260
|
+
const name = toks[0];
|
|
2261
|
+
const num = Number.isFinite(Number(toks[1])) ? Number(toks[1]) : void 0;
|
|
2262
|
+
if (name) out.push({ name, num });
|
|
2263
|
+
}
|
|
2264
|
+
return out;
|
|
2265
|
+
}
|
|
2266
|
+
const resets = parseListDecl(pseudoStyle == null ? void 0 : pseudoStyle.counterReset);
|
|
2267
|
+
const incs = parseListDecl(pseudoStyle == null ? void 0 : pseudoStyle.counterIncrement);
|
|
2268
|
+
function getStackDerived(name) {
|
|
2269
|
+
if (modStacks.has(name)) return modStacks.get(name).slice();
|
|
2270
|
+
let stack = baseCtx.getStack(node, name);
|
|
2271
|
+
stack = stack.length ? stack.slice() : [];
|
|
2272
|
+
const r = resets.find((x) => x.name === name);
|
|
2273
|
+
if (r) {
|
|
2274
|
+
const val = Number.isFinite(r.num) ? r.num : 0;
|
|
2275
|
+
stack = stack.length ? [...stack, val] : [val];
|
|
2276
|
+
}
|
|
2277
|
+
const inc = incs.find((x) => x.name === name);
|
|
2278
|
+
if (inc) {
|
|
2279
|
+
const by = Number.isFinite(inc.num) ? inc.num : 1;
|
|
2280
|
+
if (stack.length === 0) stack = [0];
|
|
2281
|
+
stack[stack.length - 1] += by;
|
|
2282
|
+
}
|
|
2283
|
+
modStacks.set(name, stack.slice());
|
|
2284
|
+
return stack;
|
|
2285
|
+
}
|
|
2286
|
+
return {
|
|
2287
|
+
get(_node, name) {
|
|
2288
|
+
const s = getStackDerived(name);
|
|
2289
|
+
return s.length ? s[s.length - 1] : 0;
|
|
2290
|
+
},
|
|
2291
|
+
getStack(_node, name) {
|
|
2292
|
+
return getStackDerived(name);
|
|
2293
|
+
},
|
|
2294
|
+
/** expone increments del pseudo para que el caller pueda propagar a hermanos */
|
|
2295
|
+
__incs: incs
|
|
2296
|
+
};
|
|
2297
|
+
}
|
|
2298
|
+
function resolvePseudoContentAndIncs(node, pseudo, baseCtx) {
|
|
2299
|
+
let ps;
|
|
2300
|
+
try {
|
|
2301
|
+
ps = getComputedStyle(node, pseudo);
|
|
2302
|
+
} catch (e) {
|
|
2303
|
+
}
|
|
2304
|
+
const raw = ps == null ? void 0 : ps.content;
|
|
2305
|
+
if (!raw || raw === "none" || raw === "normal") return { text: "", incs: [] };
|
|
2306
|
+
const baseWithSiblings = withSiblingOverrides(node, baseCtx);
|
|
2307
|
+
const derived = deriveCounterCtxForPseudo(node, ps, baseWithSiblings);
|
|
2308
|
+
let resolved = hasCounters(raw) ? resolveCountersInContent(raw, node, derived) : raw;
|
|
2309
|
+
const text = collapseCssContent(resolved);
|
|
2310
|
+
return { text, incs: derived.__incs || [] };
|
|
2311
|
+
}
|
|
2217
2312
|
function inlinePseudoElements(source, clone, sessionCache, options) {
|
|
2218
2313
|
return __async(this, null, function* () {
|
|
2219
2314
|
var _a;
|
|
2220
2315
|
if (!(source instanceof Element) || !(clone instanceof Element)) return;
|
|
2316
|
+
if (!counterCtx) {
|
|
2317
|
+
try {
|
|
2318
|
+
counterCtx = buildCounterContext(source.ownerDocument || document);
|
|
2319
|
+
} catch (e) {
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2221
2322
|
for (const pseudo of ["::before", "::after", "::first-letter"]) {
|
|
2222
2323
|
try {
|
|
2223
2324
|
const style = getStyle(source, pseudo);
|
|
@@ -2251,12 +2352,8 @@
|
|
|
2251
2352
|
clone.insertBefore(span, restNode);
|
|
2252
2353
|
continue;
|
|
2253
2354
|
}
|
|
2254
|
-
const
|
|
2255
|
-
|
|
2256
|
-
if (hasCounters(content)) {
|
|
2257
|
-
counterCtx = buildCounterContext(source.ownerDocument || document);
|
|
2258
|
-
cleanContent = resolveCountersInContent(cleanContent, source, counterCtx);
|
|
2259
|
-
}
|
|
2355
|
+
const rawContent = style.content;
|
|
2356
|
+
const { text: cleanContent, incs } = resolvePseudoContentAndIncs(source, pseudo, counterCtx);
|
|
2260
2357
|
const bg = style.backgroundImage;
|
|
2261
2358
|
const bgColor = style.backgroundColor;
|
|
2262
2359
|
const fontFamily = style.fontFamily;
|
|
@@ -2270,28 +2367,42 @@
|
|
|
2270
2367
|
const borderWidth = parseFloat(style.borderWidth);
|
|
2271
2368
|
const transform = style.transform;
|
|
2272
2369
|
const isIconFont22 = isIconFont2(fontFamily);
|
|
2273
|
-
const hasExplicitContent =
|
|
2370
|
+
const hasExplicitContent = rawContent !== "none" && cleanContent !== "";
|
|
2274
2371
|
const hasBg = bg && bg !== "none";
|
|
2275
2372
|
const hasBgColor = bgColor && bgColor !== "transparent" && bgColor !== "rgba(0, 0, 0, 0)";
|
|
2276
2373
|
const hasBox2 = display !== "inline" && (width > 0 || height > 0);
|
|
2277
2374
|
const hasBorder = borderStyle && borderStyle !== "none" && borderWidth > 0;
|
|
2278
2375
|
const hasTransform = transform && transform !== "none";
|
|
2279
|
-
const shouldRender = hasExplicitContent || hasBg || hasBgColor ||
|
|
2280
|
-
if (!shouldRender)
|
|
2376
|
+
const shouldRender = hasExplicitContent || hasBg || hasBgColor || hasBorder || hasTransform;
|
|
2377
|
+
if (!shouldRender) {
|
|
2378
|
+
if (incs && incs.length && source.parentElement) {
|
|
2379
|
+
const map = __siblingCounters.get(source.parentElement) || /* @__PURE__ */ new Map();
|
|
2380
|
+
for (const { name, num } of incs) {
|
|
2381
|
+
if (!name) continue;
|
|
2382
|
+
const baseWithSibs = withSiblingOverrides(source, counterCtx);
|
|
2383
|
+
const derived = deriveCounterCtxForPseudo(source, getComputedStyle(source, pseudo), baseWithSibs);
|
|
2384
|
+
const finalVal = derived.get(source, name);
|
|
2385
|
+
map.set(name, finalVal);
|
|
2386
|
+
}
|
|
2387
|
+
__siblingCounters.set(source.parentElement, map);
|
|
2388
|
+
}
|
|
2389
|
+
continue;
|
|
2390
|
+
}
|
|
2281
2391
|
const pseudoEl = document.createElement("span");
|
|
2282
2392
|
pseudoEl.dataset.snapdomPseudo = pseudo;
|
|
2283
2393
|
pseudoEl.style.verticalAlign = "middle";
|
|
2394
|
+
pseudoEl.style.pointerEvents = "none";
|
|
2284
2395
|
const snapshot = snapshotComputedStyle(style);
|
|
2285
2396
|
const key = getStyleKey(snapshot, "span");
|
|
2286
2397
|
sessionCache.styleMap.set(pseudoEl, key);
|
|
2287
|
-
if (isIconFont22 && cleanContent.length === 1) {
|
|
2288
|
-
const { dataUrl, width:
|
|
2398
|
+
if (isIconFont22 && cleanContent && cleanContent.length === 1) {
|
|
2399
|
+
const { dataUrl, width: w, height: h } = yield iconToImage(cleanContent, fontFamily, fontWeight, fontSize, color);
|
|
2289
2400
|
const imgEl = document.createElement("img");
|
|
2290
2401
|
imgEl.src = dataUrl;
|
|
2291
|
-
imgEl.style = `height:${fontSize}px;width:${
|
|
2402
|
+
imgEl.style = `height:${fontSize}px;width:${w / h * fontSize}px;object-fit:contain;`;
|
|
2292
2403
|
pseudoEl.appendChild(imgEl);
|
|
2293
2404
|
clone.dataset.snapdomHasIcon = "true";
|
|
2294
|
-
} else if (cleanContent.startsWith("url(")) {
|
|
2405
|
+
} else if (cleanContent && cleanContent.startsWith("url(")) {
|
|
2295
2406
|
const rawUrl = extractURL(cleanContent);
|
|
2296
2407
|
if (rawUrl == null ? void 0 : rawUrl.trim()) {
|
|
2297
2408
|
try {
|
|
@@ -2307,6 +2418,10 @@
|
|
|
2307
2418
|
} else if (!isIconFont22 && hasExplicitContent) {
|
|
2308
2419
|
pseudoEl.textContent = cleanContent;
|
|
2309
2420
|
}
|
|
2421
|
+
pseudoEl.style.background = "none";
|
|
2422
|
+
if ("mask" in pseudoEl.style) {
|
|
2423
|
+
pseudoEl.style.mask = "none";
|
|
2424
|
+
}
|
|
2310
2425
|
if (hasBg) {
|
|
2311
2426
|
try {
|
|
2312
2427
|
const bgSplits = splitBackgroundImage(bg);
|
|
@@ -2318,7 +2433,18 @@
|
|
|
2318
2433
|
}
|
|
2319
2434
|
if (hasBgColor) pseudoEl.style.backgroundColor = bgColor;
|
|
2320
2435
|
const hasContent2 = pseudoEl.childNodes.length > 0 || ((_a = pseudoEl.textContent) == null ? void 0 : _a.trim()) !== "";
|
|
2321
|
-
const hasVisibleBox = hasContent2 || hasBg || hasBgColor ||
|
|
2436
|
+
const hasVisibleBox = hasContent2 || hasBg || hasBgColor || hasBorder || hasTransform;
|
|
2437
|
+
if (incs && incs.length && source.parentElement) {
|
|
2438
|
+
const map = __siblingCounters.get(source.parentElement) || /* @__PURE__ */ new Map();
|
|
2439
|
+
const baseWithSibs = withSiblingOverrides(source, counterCtx);
|
|
2440
|
+
const derived = deriveCounterCtxForPseudo(source, getComputedStyle(source, pseudo), baseWithSibs);
|
|
2441
|
+
for (const { name } of incs) {
|
|
2442
|
+
if (!name) continue;
|
|
2443
|
+
const finalVal = derived.get(source, name);
|
|
2444
|
+
map.set(name, finalVal);
|
|
2445
|
+
}
|
|
2446
|
+
__siblingCounters.set(source.parentElement, map);
|
|
2447
|
+
}
|
|
2322
2448
|
if (!hasVisibleBox) continue;
|
|
2323
2449
|
if (pseudo === "::before") {
|
|
2324
2450
|
clone.insertBefore(pseudoEl, clone.firstChild);
|
|
@@ -2387,6 +2513,103 @@
|
|
|
2387
2513
|
});
|
|
2388
2514
|
}
|
|
2389
2515
|
|
|
2516
|
+
// src/modules/changeCSS.js
|
|
2517
|
+
function freezeSticky(originalRoot, cloneRoot) {
|
|
2518
|
+
var _a;
|
|
2519
|
+
if (!originalRoot || !cloneRoot) return;
|
|
2520
|
+
const scrollTop = originalRoot.scrollTop || 0;
|
|
2521
|
+
if (!scrollTop) return;
|
|
2522
|
+
if (getComputedStyle(cloneRoot).position === "static") {
|
|
2523
|
+
cloneRoot.style.position = "relative";
|
|
2524
|
+
}
|
|
2525
|
+
const rootRect = originalRoot.getBoundingClientRect();
|
|
2526
|
+
const viewportH = originalRoot.clientHeight;
|
|
2527
|
+
const PH_ATTR = "data-snap-ph";
|
|
2528
|
+
const walker = document.createTreeWalker(originalRoot, NodeFilter.SHOW_ELEMENT);
|
|
2529
|
+
while (walker.nextNode()) {
|
|
2530
|
+
const el = (
|
|
2531
|
+
/** @type {HTMLElement} */
|
|
2532
|
+
walker.currentNode
|
|
2533
|
+
);
|
|
2534
|
+
const cs = getComputedStyle(el);
|
|
2535
|
+
const pos = cs.position;
|
|
2536
|
+
if (pos !== "sticky" && pos !== "-webkit-sticky") continue;
|
|
2537
|
+
const topInit = _toPx(cs.top);
|
|
2538
|
+
const bottomInit = _toPx(cs.bottom);
|
|
2539
|
+
if (topInit == null && bottomInit == null) continue;
|
|
2540
|
+
const path = _pathOf(el, originalRoot);
|
|
2541
|
+
const cloneEl = _findByPathIgnoringPlaceholders(cloneRoot, path, PH_ATTR);
|
|
2542
|
+
if (!cloneEl) continue;
|
|
2543
|
+
const elRect = el.getBoundingClientRect();
|
|
2544
|
+
const widthPx = elRect.width;
|
|
2545
|
+
const heightPx = elRect.height;
|
|
2546
|
+
const leftPx = elRect.left - rootRect.left;
|
|
2547
|
+
if (!(widthPx > 0 && heightPx > 0)) continue;
|
|
2548
|
+
if (!Number.isFinite(leftPx)) continue;
|
|
2549
|
+
const topAbsPx = topInit != null ? topInit + scrollTop : scrollTop + (viewportH - heightPx - /** bottomInit non-null */
|
|
2550
|
+
bottomInit);
|
|
2551
|
+
if (!Number.isFinite(topAbsPx)) continue;
|
|
2552
|
+
const zParsed = Number.parseInt(cs.zIndex, 10);
|
|
2553
|
+
const hasZ = Number.isFinite(zParsed);
|
|
2554
|
+
const overlayZ = hasZ ? Math.max(zParsed, 1) + 1 : 2;
|
|
2555
|
+
const placeholderZ = hasZ ? zParsed - 1 : 0;
|
|
2556
|
+
const ph = cloneEl.cloneNode(false);
|
|
2557
|
+
ph.setAttribute(PH_ATTR, "1");
|
|
2558
|
+
ph.style.position = "sticky";
|
|
2559
|
+
ph.style.left = `${leftPx}px`;
|
|
2560
|
+
ph.style.top = `${topAbsPx}px`;
|
|
2561
|
+
ph.style.width = `${widthPx}px`;
|
|
2562
|
+
ph.style.height = `${heightPx}px`;
|
|
2563
|
+
ph.style.visibility = "hidden";
|
|
2564
|
+
ph.style.zIndex = String(placeholderZ);
|
|
2565
|
+
ph.style.overflow = "hidden";
|
|
2566
|
+
ph.style.background = "transparent";
|
|
2567
|
+
ph.style.boxShadow = "none";
|
|
2568
|
+
ph.style.filter = "none";
|
|
2569
|
+
(_a = cloneEl.parentElement) == null ? void 0 : _a.insertBefore(ph, cloneEl);
|
|
2570
|
+
cloneEl.style.position = "absolute";
|
|
2571
|
+
cloneEl.style.left = `${leftPx}px`;
|
|
2572
|
+
cloneEl.style.top = `${topAbsPx}px`;
|
|
2573
|
+
cloneEl.style.bottom = "auto";
|
|
2574
|
+
cloneEl.style.zIndex = String(overlayZ);
|
|
2575
|
+
cloneEl.style.pointerEvents = "none";
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
function _toPx(v) {
|
|
2579
|
+
if (!v || v === "auto") return null;
|
|
2580
|
+
const n = Number.parseFloat(v);
|
|
2581
|
+
return Number.isFinite(n) ? n : null;
|
|
2582
|
+
}
|
|
2583
|
+
function _pathOf(el, root) {
|
|
2584
|
+
const path = [];
|
|
2585
|
+
for (let cur = el; cur && cur !== root; ) {
|
|
2586
|
+
const p = cur.parentElement;
|
|
2587
|
+
if (!p) break;
|
|
2588
|
+
path.push(Array.prototype.indexOf.call(p.children, cur));
|
|
2589
|
+
cur = p;
|
|
2590
|
+
}
|
|
2591
|
+
return path.reverse();
|
|
2592
|
+
}
|
|
2593
|
+
function _findByPathIgnoringPlaceholders(root, path, phAttr) {
|
|
2594
|
+
let cur = root;
|
|
2595
|
+
for (let i = 0; i < path.length; i++) {
|
|
2596
|
+
const kids = _childrenWithoutPlaceholders(cur, phAttr);
|
|
2597
|
+
cur = /** @type {HTMLElement|undefined} */
|
|
2598
|
+
kids[path[i]];
|
|
2599
|
+
if (!cur) return null;
|
|
2600
|
+
}
|
|
2601
|
+
return cur instanceof HTMLElement ? cur : null;
|
|
2602
|
+
}
|
|
2603
|
+
function _childrenWithoutPlaceholders(el, phAttr) {
|
|
2604
|
+
const out = [];
|
|
2605
|
+
const ch = el.children;
|
|
2606
|
+
for (let i = 0; i < ch.length; i++) {
|
|
2607
|
+
const c = ch[i];
|
|
2608
|
+
if (!c.hasAttribute(phAttr)) out.push(c);
|
|
2609
|
+
}
|
|
2610
|
+
return out;
|
|
2611
|
+
}
|
|
2612
|
+
|
|
2390
2613
|
// src/core/prepare.js
|
|
2391
2614
|
function prepareClone(_0) {
|
|
2392
2615
|
return __async(this, arguments, function* (element, options = {}) {
|
|
@@ -2463,17 +2686,20 @@
|
|
|
2463
2686
|
cloneNode.appendChild(inner);
|
|
2464
2687
|
}
|
|
2465
2688
|
}
|
|
2689
|
+
const contentRoot = clone instanceof HTMLElement && clone.firstElementChild instanceof HTMLElement ? clone.firstElementChild : clone;
|
|
2690
|
+
freezeSticky(element, contentRoot);
|
|
2466
2691
|
if (element === sessionCache.nodeMap.get(clone)) {
|
|
2467
2692
|
const computed = sessionCache.styleCache.get(element) || window.getComputedStyle(element);
|
|
2468
2693
|
sessionCache.styleCache.set(element, computed);
|
|
2469
2694
|
const transform = stripTranslate(computed.transform);
|
|
2470
2695
|
clone.style.margin = "0";
|
|
2471
|
-
clone.style.position = "static";
|
|
2472
2696
|
clone.style.top = "auto";
|
|
2473
2697
|
clone.style.left = "auto";
|
|
2474
2698
|
clone.style.right = "auto";
|
|
2475
2699
|
clone.style.bottom = "auto";
|
|
2476
|
-
clone.style.
|
|
2700
|
+
clone.style.animation = "none";
|
|
2701
|
+
clone.style.transition = "none";
|
|
2702
|
+
clone.style.willChange = "auto";
|
|
2477
2703
|
clone.style.float = "none";
|
|
2478
2704
|
clone.style.clear = "none";
|
|
2479
2705
|
clone.style.transform = transform || "";
|
|
@@ -2886,7 +3112,7 @@
|
|
|
2886
3112
|
idle(() => __async(null, null, function* () {
|
|
2887
3113
|
const required = collectUsedFontVariants(element);
|
|
2888
3114
|
const usedCodepoints = collectUsedCodepoints(element);
|
|
2889
|
-
if (isSafari) {
|
|
3115
|
+
if (isSafari()) {
|
|
2890
3116
|
const families = new Set(
|
|
2891
3117
|
Array.from(required).map((k) => String(k).split("__")[0]).filter(Boolean)
|
|
2892
3118
|
);
|
|
@@ -2918,102 +3144,188 @@
|
|
|
2918
3144
|
}
|
|
2919
3145
|
yield new Promise((resolve) => {
|
|
2920
3146
|
idle(() => {
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
3147
|
+
const csEl = getComputedStyle(element);
|
|
3148
|
+
function parseFilterDropShadows(cs) {
|
|
3149
|
+
var _a;
|
|
3150
|
+
const raw = `${cs.filter || ""} ${cs.webkitFilter || ""}`.trim();
|
|
3151
|
+
if (!raw || raw === "none") {
|
|
3152
|
+
return { bleed: { top: 0, right: 0, bottom: 0, left: 0 }, has: false };
|
|
3153
|
+
}
|
|
3154
|
+
const tokens = raw.match(/drop-shadow\((?:[^()]|\([^()]*\))*\)/gi) || [];
|
|
3155
|
+
let t = 0, r = 0, b = 0, l = 0;
|
|
3156
|
+
let found = false;
|
|
3157
|
+
for (const tok of tokens) {
|
|
3158
|
+
found = true;
|
|
3159
|
+
const nums = ((_a = tok.match(/-?\d+(?:\.\d+)?px/gi)) == null ? void 0 : _a.map((v) => parseFloat(v))) || [];
|
|
3160
|
+
const [ox = 0, oy = 0, blur = 0] = nums;
|
|
3161
|
+
const extX = Math.abs(ox) + blur;
|
|
3162
|
+
const extY = Math.abs(oy) + blur;
|
|
3163
|
+
r = Math.max(r, extX + Math.max(ox, 0));
|
|
3164
|
+
l = Math.max(l, extX + Math.max(-ox, 0));
|
|
3165
|
+
b = Math.max(b, extY + Math.max(oy, 0));
|
|
3166
|
+
t = Math.max(t, extY + Math.max(-oy, 0));
|
|
3167
|
+
}
|
|
3168
|
+
return {
|
|
3169
|
+
bleed: { top: Math.ceil(t), right: Math.ceil(r), bottom: Math.ceil(b), left: Math.ceil(l) },
|
|
3170
|
+
has: found
|
|
3171
|
+
};
|
|
3172
|
+
}
|
|
3173
|
+
function parseBoxShadow(cs) {
|
|
3174
|
+
var _a;
|
|
3175
|
+
const v = cs.boxShadow || "";
|
|
3176
|
+
if (!v || v === "none") return { top: 0, right: 0, bottom: 0, left: 0 };
|
|
3177
|
+
const parts = v.split(/\),(?=(?:[^()]*\([^()]*\))*[^()]*$)/).map((s) => s.trim());
|
|
3178
|
+
let t = 0, r = 0, b2 = 0, l = 0;
|
|
3179
|
+
for (const part of parts) {
|
|
3180
|
+
const nums = ((_a = part.match(/-?\d+(\.\d+)?px/g)) == null ? void 0 : _a.map((n) => parseFloat(n))) || [];
|
|
3181
|
+
if (nums.length < 2) continue;
|
|
3182
|
+
const [ox2, oy2, blur = 0, spread = 0] = nums;
|
|
3183
|
+
const extX = Math.abs(ox2) + blur + spread;
|
|
3184
|
+
const extY = Math.abs(oy2) + blur + spread;
|
|
3185
|
+
r = Math.max(r, extX + Math.max(ox2, 0));
|
|
3186
|
+
l = Math.max(l, extX + Math.max(-ox2, 0));
|
|
3187
|
+
b2 = Math.max(b2, extY + Math.max(oy2, 0));
|
|
3188
|
+
t = Math.max(t, extY + Math.max(-oy2, 0));
|
|
2940
3189
|
}
|
|
3190
|
+
return { top: Math.ceil(t), right: Math.ceil(r), bottom: Math.ceil(b2), left: Math.ceil(l) };
|
|
2941
3191
|
}
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
const
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
3192
|
+
function parseFilterBlur(cs) {
|
|
3193
|
+
const m = (cs.filter || "").match(/blur\(\s*([0-9.]+)px\s*\)/);
|
|
3194
|
+
const b2 = m ? Math.ceil(parseFloat(m[1]) || 0) : 0;
|
|
3195
|
+
return { top: b2, right: b2, bottom: b2, left: b2 };
|
|
3196
|
+
}
|
|
3197
|
+
function parseOutline(cs) {
|
|
3198
|
+
if ((cs.outlineStyle || "none") === "none") return { top: 0, right: 0, bottom: 0, left: 0 };
|
|
3199
|
+
const w2 = Math.ceil(parseFloat(cs.outlineWidth || "0") || 0);
|
|
3200
|
+
return { top: w2, right: w2, bottom: w2, left: w2 };
|
|
3201
|
+
}
|
|
3202
|
+
function bboxWithOriginFull(w2, h2, M, ox2, oy2) {
|
|
3203
|
+
const a2 = M.a, b2 = M.b, c2 = M.c, d2 = M.d, e2 = M.e || 0, f2 = M.f || 0;
|
|
3204
|
+
function pt(x, y) {
|
|
3205
|
+
let X = x - ox2, Y = y - oy2;
|
|
3206
|
+
let X2 = a2 * X + c2 * Y, Y2 = b2 * X + d2 * Y;
|
|
3207
|
+
X2 += ox2 + e2;
|
|
3208
|
+
Y2 += oy2 + f2;
|
|
3209
|
+
return [X2, Y2];
|
|
3210
|
+
}
|
|
3211
|
+
const P = [pt(0, 0), pt(w2, 0), pt(0, h2), pt(w2, h2)];
|
|
3212
|
+
let minX2 = Infinity, minY2 = Infinity, maxX2 = -Infinity, maxY2 = -Infinity;
|
|
3213
|
+
for (const [X, Y] of P) {
|
|
3214
|
+
if (X < minX2) minX2 = X;
|
|
3215
|
+
if (Y < minY2) minY2 = Y;
|
|
3216
|
+
if (X > maxX2) maxX2 = X;
|
|
3217
|
+
if (Y > maxY2) maxY2 = Y;
|
|
3218
|
+
}
|
|
3219
|
+
return { minX: minX2, minY: minY2, maxX: maxX2, maxY: maxY2, width: maxX2 - minX2, height: maxY2 - minY2 };
|
|
3220
|
+
}
|
|
3221
|
+
function hasTFBBox(el) {
|
|
3222
|
+
return hasBBoxAffectingTransform(el);
|
|
3223
|
+
}
|
|
3224
|
+
const rect = element.getBoundingClientRect();
|
|
3225
|
+
const w0 = Math.max(1, Math.ceil(element.offsetWidth || parseFloat(csEl.width) || rect.width || 1));
|
|
3226
|
+
const h0 = Math.max(1, Math.ceil(element.offsetHeight || parseFloat(csEl.height) || rect.height || 1));
|
|
3227
|
+
const coerceNum = (v, def = NaN) => {
|
|
3228
|
+
const n = typeof v === "string" ? parseFloat(v) : v;
|
|
3229
|
+
return Number.isFinite(n) ? n : def;
|
|
3230
|
+
};
|
|
3231
|
+
const optW = coerceNum(options.width);
|
|
3232
|
+
const optH = coerceNum(options.height);
|
|
3233
|
+
let w = w0, h = h0;
|
|
3234
|
+
const hasW = Number.isFinite(optW);
|
|
3235
|
+
const hasH = Number.isFinite(optH);
|
|
3236
|
+
const aspect0 = h0 > 0 ? w0 / h0 : 1;
|
|
3237
|
+
if (hasW && hasH) {
|
|
3238
|
+
w = Math.max(1, Math.ceil(optW));
|
|
3239
|
+
h = Math.max(1, Math.ceil(optH));
|
|
3240
|
+
} else if (hasW) {
|
|
3241
|
+
w = Math.max(1, Math.ceil(optW));
|
|
3242
|
+
h = Math.max(1, Math.ceil(w / (aspect0 || 1)));
|
|
3243
|
+
} else if (hasH) {
|
|
3244
|
+
h = Math.max(1, Math.ceil(optH));
|
|
3245
|
+
w = Math.max(1, Math.ceil(h * (aspect0 || 1)));
|
|
2955
3246
|
} else {
|
|
3247
|
+
w = w0;
|
|
3248
|
+
h = h0;
|
|
3249
|
+
}
|
|
3250
|
+
let minX = 0, minY = 0, maxX = w0, maxY = h0;
|
|
3251
|
+
if (hasTFBBox(element)) {
|
|
3252
|
+
const baseTransform2 = csEl.transform && csEl.transform !== "none" ? csEl.transform : "";
|
|
3253
|
+
const ind2 = readIndividualTransforms(element);
|
|
2956
3254
|
const TOTAL = readTotalTransformMatrix({
|
|
2957
|
-
baseTransform,
|
|
2958
|
-
rotate:
|
|
2959
|
-
scale:
|
|
2960
|
-
translate:
|
|
3255
|
+
baseTransform: baseTransform2,
|
|
3256
|
+
rotate: ind2.rotate || "0deg",
|
|
3257
|
+
scale: ind2.scale,
|
|
3258
|
+
translate: ind2.translate
|
|
2961
3259
|
});
|
|
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;
|
|
3260
|
+
const { ox: ox2, oy: oy2 } = parseTransformOriginPx(csEl, w0, h0);
|
|
3261
|
+
const M = TOTAL.is2D ? TOTAL : new DOMMatrix(TOTAL.toString());
|
|
3262
|
+
const bb = bboxWithOriginFull(w0, h0, M, ox2, oy2);
|
|
3263
|
+
minX = bb.minX;
|
|
3264
|
+
minY = bb.minY;
|
|
3265
|
+
maxX = bb.maxX;
|
|
3266
|
+
maxY = bb.maxY;
|
|
2972
3267
|
}
|
|
3268
|
+
const bleedShadow = parseBoxShadow(csEl);
|
|
3269
|
+
const bleedBlur = parseFilterBlur(csEl);
|
|
3270
|
+
const bleedOutline = parseOutline(csEl);
|
|
3271
|
+
const drop = parseFilterDropShadows(csEl);
|
|
3272
|
+
const bleed = {
|
|
3273
|
+
top: bleedShadow.top + bleedBlur.top + bleedOutline.top + drop.bleed.top,
|
|
3274
|
+
right: bleedShadow.right + bleedBlur.right + bleedOutline.right + drop.bleed.right,
|
|
3275
|
+
bottom: bleedShadow.bottom + bleedBlur.bottom + bleedOutline.bottom + drop.bleed.bottom,
|
|
3276
|
+
left: bleedShadow.left + bleedBlur.left + bleedOutline.left + drop.bleed.left
|
|
3277
|
+
};
|
|
3278
|
+
minX -= bleed.left;
|
|
3279
|
+
minY -= bleed.top;
|
|
3280
|
+
maxX += bleed.right;
|
|
3281
|
+
maxY += bleed.bottom;
|
|
3282
|
+
const vbW0 = Math.max(1, Math.ceil(maxX - minX));
|
|
3283
|
+
const vbH0 = Math.max(1, Math.ceil(maxY - minY));
|
|
3284
|
+
const outW = Math.max(1, Math.round(vbW0 * (hasW || hasH ? w / w0 : 1)));
|
|
3285
|
+
const outH = Math.max(1, Math.round(vbH0 * (hasH || hasW ? h / h0 : 1)));
|
|
2973
3286
|
const svgNS = "http://www.w3.org/2000/svg";
|
|
3287
|
+
const pad = isSafari() ? 1 : 0;
|
|
2974
3288
|
const fo = document.createElementNS(svgNS, "foreignObject");
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
fo.setAttribute("x", String(
|
|
2978
|
-
fo.setAttribute("y", String(
|
|
3289
|
+
const vbMinX = Math.floor(minX);
|
|
3290
|
+
const vbMinY = Math.floor(minY);
|
|
3291
|
+
fo.setAttribute("x", String(-(vbMinX - pad)));
|
|
3292
|
+
fo.setAttribute("y", String(-(vbMinY - pad)));
|
|
3293
|
+
fo.setAttribute("width", String(Math.ceil(w0 + pad * 2)));
|
|
3294
|
+
fo.setAttribute("height", String(Math.ceil(h0 + pad * 2)));
|
|
2979
3295
|
fo.style.overflow = "visible";
|
|
2980
3296
|
const styleTag = document.createElement("style");
|
|
2981
3297
|
styleTag.textContent = baseCSS + fontsCSS + "svg{overflow:visible;} foreignObject{overflow:visible;}" + classCSS;
|
|
2982
3298
|
fo.appendChild(styleTag);
|
|
2983
3299
|
const container = document.createElement("div");
|
|
2984
3300
|
container.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
2985
|
-
container.style.width = `${
|
|
2986
|
-
container.style.height = `${
|
|
3301
|
+
container.style.width = `${w0}px`;
|
|
3302
|
+
container.style.height = `${h0}px`;
|
|
2987
3303
|
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
3304
|
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
3305
|
container.appendChild(clone);
|
|
3011
3306
|
fo.appendChild(container);
|
|
3012
3307
|
const serializer = new XMLSerializer();
|
|
3013
3308
|
const foString = serializer.serializeToString(fo);
|
|
3014
|
-
const
|
|
3015
|
-
const
|
|
3016
|
-
const
|
|
3309
|
+
const vbW = vbW0 + pad * 2;
|
|
3310
|
+
const vbH = vbH0 + pad * 2;
|
|
3311
|
+
const wantsSize = hasW || hasH;
|
|
3312
|
+
options.meta = {
|
|
3313
|
+
w0,
|
|
3314
|
+
// ancho natural del elemento
|
|
3315
|
+
h0,
|
|
3316
|
+
// alto natural
|
|
3317
|
+
vbW,
|
|
3318
|
+
// ancho del viewBox
|
|
3319
|
+
vbH,
|
|
3320
|
+
// alto del viewBox
|
|
3321
|
+
targetW: w,
|
|
3322
|
+
// ancho deseado según options.width
|
|
3323
|
+
targetH: h
|
|
3324
|
+
// alto deseado según options.height
|
|
3325
|
+
};
|
|
3326
|
+
const svgOutW = isSafari() && wantsSize ? vbW : outW + pad * 2;
|
|
3327
|
+
const svgOutH = isSafari() && wantsSize ? vbH : outH + pad * 2;
|
|
3328
|
+
const svgHeader = `<svg xmlns="${svgNS}" width="${svgOutW}" height="${svgOutH}" viewBox="0 0 ${vbW} ${vbH}">`;
|
|
3017
3329
|
const svgFooter = "</svg>";
|
|
3018
3330
|
svgString = svgHeader + foString + svgFooter;
|
|
3019
3331
|
dataURL = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
|
|
@@ -3034,28 +3346,8 @@
|
|
|
3034
3346
|
return new WebKitCSSMatrix(tr);
|
|
3035
3347
|
}
|
|
3036
3348
|
}
|
|
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
3349
|
function readIndividualTransforms(el) {
|
|
3058
|
-
var _a, _b, _c, _d, _e, _f, _g, _h
|
|
3350
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
3059
3351
|
const out = { rotate: "0deg", scale: null, translate: null };
|
|
3060
3352
|
const map = typeof el.computedStyleMap === "function" ? el.computedStyleMap() : null;
|
|
3061
3353
|
if (map) {
|
|
@@ -3070,26 +3362,37 @@
|
|
|
3070
3362
|
};
|
|
3071
3363
|
const rot = safeGet("rotate");
|
|
3072
3364
|
if (rot) {
|
|
3073
|
-
|
|
3074
|
-
|
|
3365
|
+
if (rot.angle) {
|
|
3366
|
+
const ang = rot.angle;
|
|
3075
3367
|
out.rotate = ang.unit === "rad" ? ang.value * 180 / Math.PI + "deg" : ang.value + ang.unit;
|
|
3368
|
+
} else if (rot.unit) {
|
|
3369
|
+
out.rotate = rot.unit === "rad" ? rot.value * 180 / Math.PI + "deg" : rot.value + rot.unit;
|
|
3076
3370
|
} else {
|
|
3077
3371
|
out.rotate = String(rot);
|
|
3078
3372
|
}
|
|
3373
|
+
} else {
|
|
3374
|
+
const cs2 = getComputedStyle(el);
|
|
3375
|
+
out.rotate = cs2.rotate && cs2.rotate !== "none" ? cs2.rotate : "0deg";
|
|
3079
3376
|
}
|
|
3080
3377
|
const sc = safeGet("scale");
|
|
3081
|
-
if (sc
|
|
3082
|
-
const sx = (
|
|
3083
|
-
const sy =
|
|
3378
|
+
if (sc) {
|
|
3379
|
+
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;
|
|
3380
|
+
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
3381
|
out.scale = `${sx} ${sy}`;
|
|
3382
|
+
} else {
|
|
3383
|
+
const cs2 = getComputedStyle(el);
|
|
3384
|
+
out.scale = cs2.scale && cs2.scale !== "none" ? cs2.scale : null;
|
|
3085
3385
|
}
|
|
3086
3386
|
const tr = safeGet("translate");
|
|
3087
|
-
if (tr
|
|
3088
|
-
const tx = (
|
|
3089
|
-
const ty = (
|
|
3090
|
-
const ux =
|
|
3091
|
-
const uy =
|
|
3387
|
+
if (tr) {
|
|
3388
|
+
const tx = "x" in tr && "value" in tr.x ? tr.x.value : Array.isArray(tr) ? (_e = tr[0]) == null ? void 0 : _e.value : 0;
|
|
3389
|
+
const ty = "y" in tr && "value" in tr.y ? tr.y.value : Array.isArray(tr) ? (_f = tr[1]) == null ? void 0 : _f.value : 0;
|
|
3390
|
+
const ux = "x" in tr && ((_g = tr.x) == null ? void 0 : _g.unit) ? tr.x.unit : "px";
|
|
3391
|
+
const uy = "y" in tr && ((_h = tr.y) == null ? void 0 : _h.unit) ? tr.y.unit : "px";
|
|
3092
3392
|
out.translate = `${tx}${ux} ${ty}${uy}`;
|
|
3393
|
+
} else {
|
|
3394
|
+
const cs2 = getComputedStyle(el);
|
|
3395
|
+
out.translate = cs2.translate && cs2.translate !== "none" ? cs2.translate : null;
|
|
3093
3396
|
}
|
|
3094
3397
|
return out;
|
|
3095
3398
|
}
|
|
@@ -3100,17 +3403,33 @@
|
|
|
3100
3403
|
return out;
|
|
3101
3404
|
}
|
|
3102
3405
|
function hasBBoxAffectingTransform(el) {
|
|
3103
|
-
const
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
return true;
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
const
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3406
|
+
const cs = getComputedStyle(el);
|
|
3407
|
+
const t = cs.transform || "none";
|
|
3408
|
+
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);
|
|
3409
|
+
if (hasMatrix) return true;
|
|
3410
|
+
const r = cs.rotate && cs.rotate !== "none" && cs.rotate !== "0deg";
|
|
3411
|
+
const s = cs.scale && cs.scale !== "none" && cs.scale !== "1";
|
|
3412
|
+
const tr = cs.translate && cs.translate !== "none" && cs.translate !== "0px 0px";
|
|
3413
|
+
return Boolean(r || s || tr);
|
|
3414
|
+
}
|
|
3415
|
+
function parseTransformOriginPx(cs, w, h) {
|
|
3416
|
+
const raw = (cs.transformOrigin || "0 0").trim().split(/\s+/);
|
|
3417
|
+
const [oxRaw, oyRaw] = [raw[0] || "0", raw[1] || "0"];
|
|
3418
|
+
const toPx = (token, size) => {
|
|
3419
|
+
const t = token.toLowerCase();
|
|
3420
|
+
if (t === "left" || t === "top") return 0;
|
|
3421
|
+
if (t === "center") return size / 2;
|
|
3422
|
+
if (t === "right") return size;
|
|
3423
|
+
if (t === "bottom") return size;
|
|
3424
|
+
if (t.endsWith("px")) return parseFloat(t) || 0;
|
|
3425
|
+
if (t.endsWith("%")) return (parseFloat(t) || 0) * size / 100;
|
|
3426
|
+
if (/^-?\d+(\.\d+)?$/.test(t)) return parseFloat(t) || 0;
|
|
3427
|
+
return 0;
|
|
3428
|
+
};
|
|
3429
|
+
return {
|
|
3430
|
+
ox: toPx(oxRaw, w),
|
|
3431
|
+
oy: toPx(oyRaw, h)
|
|
3432
|
+
};
|
|
3114
3433
|
}
|
|
3115
3434
|
var __measureHost = null;
|
|
3116
3435
|
function getMeasureHost() {
|
|
@@ -3199,41 +3518,201 @@
|
|
|
3199
3518
|
};
|
|
3200
3519
|
}
|
|
3201
3520
|
|
|
3202
|
-
// src/exporters/
|
|
3203
|
-
function
|
|
3521
|
+
// src/exporters/toCanvas.js
|
|
3522
|
+
function isSvgDataURL(u) {
|
|
3523
|
+
return typeof u === "string" && /^data:image\/svg\+xml/i.test(u);
|
|
3524
|
+
}
|
|
3525
|
+
function decodeSvgFromDataURL(u) {
|
|
3526
|
+
const i = u.indexOf(",");
|
|
3527
|
+
return i >= 0 ? decodeURIComponent(u.slice(i + 1)) : "";
|
|
3528
|
+
}
|
|
3529
|
+
function encodeSvgToDataURL(svgText) {
|
|
3530
|
+
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgText)}`;
|
|
3531
|
+
}
|
|
3532
|
+
function splitDecls(s) {
|
|
3533
|
+
let parts = [], buf = "", depth = 0;
|
|
3534
|
+
for (let i = 0; i < s.length; i++) {
|
|
3535
|
+
const ch = s[i];
|
|
3536
|
+
if (ch === "(") depth++;
|
|
3537
|
+
if (ch === ")") depth = Math.max(0, depth - 1);
|
|
3538
|
+
if (ch === ";" && depth === 0) {
|
|
3539
|
+
parts.push(buf);
|
|
3540
|
+
buf = "";
|
|
3541
|
+
} else buf += ch;
|
|
3542
|
+
}
|
|
3543
|
+
if (buf.trim()) parts.push(buf);
|
|
3544
|
+
return parts.map((x) => x.trim()).filter(Boolean);
|
|
3545
|
+
}
|
|
3546
|
+
function boxShadowToDropShadow(value) {
|
|
3547
|
+
const layers = [];
|
|
3548
|
+
let buf = "", depth = 0;
|
|
3549
|
+
for (let i = 0; i < value.length; i++) {
|
|
3550
|
+
const ch = value[i];
|
|
3551
|
+
if (ch === "(") depth++;
|
|
3552
|
+
if (ch === ")") depth = Math.max(0, depth - 1);
|
|
3553
|
+
if (ch === "," && depth === 0) {
|
|
3554
|
+
layers.push(buf.trim());
|
|
3555
|
+
buf = "";
|
|
3556
|
+
} else buf += ch;
|
|
3557
|
+
}
|
|
3558
|
+
if (buf.trim()) layers.push(buf.trim());
|
|
3559
|
+
const fns = [];
|
|
3560
|
+
for (const layer of layers) {
|
|
3561
|
+
if (/\binset\b/i.test(layer)) continue;
|
|
3562
|
+
const nums = layer.match(/-?\d+(?:\.\d+)?px/gi) || [];
|
|
3563
|
+
const [ox = "0px", oy = "0px", blur = "0px"] = nums;
|
|
3564
|
+
let color = layer.replace(/-?\d+(?:\.\d+)?px/gi, "").replace(/\binset\b/ig, "").trim().replace(/\s{2,}/g, " ");
|
|
3565
|
+
const hasColor = !!color && color !== ",";
|
|
3566
|
+
fns.push(`drop-shadow(${ox} ${oy} ${blur}${hasColor ? ` ${color}` : ""})`);
|
|
3567
|
+
}
|
|
3568
|
+
return fns.join(" ");
|
|
3569
|
+
}
|
|
3570
|
+
function rewriteDeclList(list) {
|
|
3571
|
+
const decls = splitDecls(list);
|
|
3572
|
+
let filter = null, wfilter = null, box = null;
|
|
3573
|
+
const rest = [];
|
|
3574
|
+
for (const d of decls) {
|
|
3575
|
+
const idx = d.indexOf(":");
|
|
3576
|
+
if (idx < 0) continue;
|
|
3577
|
+
const prop = d.slice(0, idx).trim().toLowerCase();
|
|
3578
|
+
const val = d.slice(idx + 1).trim();
|
|
3579
|
+
if (prop === "box-shadow") box = val;
|
|
3580
|
+
else if (prop === "filter") filter = val;
|
|
3581
|
+
else if (prop === "-webkit-filter") wfilter = val;
|
|
3582
|
+
else rest.push([prop, val]);
|
|
3583
|
+
}
|
|
3584
|
+
if (box) {
|
|
3585
|
+
const ds = boxShadowToDropShadow(box);
|
|
3586
|
+
if (ds) {
|
|
3587
|
+
filter = filter ? `${filter} ${ds}` : ds;
|
|
3588
|
+
wfilter = wfilter ? `${wfilter} ${ds}` : ds;
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
const out = [...rest];
|
|
3592
|
+
if (filter) out.push(["filter", filter]);
|
|
3593
|
+
if (wfilter) out.push(["-webkit-filter", wfilter]);
|
|
3594
|
+
return out.map(([k, v]) => `${k}:${v}`).join(";");
|
|
3595
|
+
}
|
|
3596
|
+
function rewriteCssBlock(css) {
|
|
3597
|
+
return css.replace(/([^{}]+)\{([^}]*)\}/g, (_m, sel, body) => `${sel}{${rewriteDeclList(body)}}`);
|
|
3598
|
+
}
|
|
3599
|
+
function rewriteSvgBoxShadowToDropShadow(svgText) {
|
|
3600
|
+
svgText = svgText.replace(
|
|
3601
|
+
/<style[^>]*>([\s\S]*?)<\/style>/gi,
|
|
3602
|
+
(m, css) => m.replace(css, rewriteCssBlock(css))
|
|
3603
|
+
);
|
|
3604
|
+
svgText = svgText.replace(
|
|
3605
|
+
/style=(['"])([\s\S]*?)\1/gi,
|
|
3606
|
+
(m, q, body) => `style=${q}${rewriteDeclList(body)}${q}`
|
|
3607
|
+
);
|
|
3608
|
+
return svgText;
|
|
3609
|
+
}
|
|
3610
|
+
function maybeConvertBoxShadowForSafari(url) {
|
|
3611
|
+
if (!isSafari() || !isSvgDataURL(url)) return url;
|
|
3612
|
+
try {
|
|
3613
|
+
const svg = decodeSvgFromDataURL(url);
|
|
3614
|
+
const fixed = rewriteSvgBoxShadowToDropShadow(svg);
|
|
3615
|
+
return encodeSvgToDataURL(fixed);
|
|
3616
|
+
} catch (e) {
|
|
3617
|
+
return url;
|
|
3618
|
+
}
|
|
3619
|
+
}
|
|
3620
|
+
function toCanvas(url, options) {
|
|
3204
3621
|
return __async(this, null, function* () {
|
|
3622
|
+
let { width: optW, height: optH, scale = 1, dpr = 1, meta = {} } = options;
|
|
3623
|
+
url = maybeConvertBoxShadowForSafari(url);
|
|
3205
3624
|
const img = new Image();
|
|
3625
|
+
img.loading = "eager";
|
|
3626
|
+
img.decoding = "sync";
|
|
3627
|
+
img.crossOrigin = "anonymous";
|
|
3206
3628
|
img.src = url;
|
|
3207
3629
|
yield img.decode();
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3630
|
+
const natW = img.naturalWidth;
|
|
3631
|
+
const natH = img.naturalHeight;
|
|
3632
|
+
const refW = Number.isFinite(meta.w0) ? meta.w0 : natW;
|
|
3633
|
+
const refH = Number.isFinite(meta.h0) ? meta.h0 : natH;
|
|
3634
|
+
let outW, outH;
|
|
3635
|
+
const hasW = Number.isFinite(optW);
|
|
3636
|
+
const hasH = Number.isFinite(optH);
|
|
3637
|
+
if (hasW && hasH) {
|
|
3638
|
+
outW = Math.max(1, optW);
|
|
3639
|
+
outH = Math.max(1, optH);
|
|
3640
|
+
} else if (hasW) {
|
|
3641
|
+
const k = optW / Math.max(1, refW);
|
|
3642
|
+
outW = optW;
|
|
3643
|
+
outH = Math.round(refH * k);
|
|
3644
|
+
} else if (hasH) {
|
|
3645
|
+
const k = optH / Math.max(1, refH);
|
|
3646
|
+
outH = optH;
|
|
3647
|
+
outW = Math.round(refW * k);
|
|
3648
|
+
} else {
|
|
3649
|
+
outW = natW;
|
|
3650
|
+
outH = natH;
|
|
3211
3651
|
}
|
|
3652
|
+
outW = Math.round(outW * scale);
|
|
3653
|
+
outH = Math.round(outH * scale);
|
|
3654
|
+
const canvas = document.createElement("canvas");
|
|
3655
|
+
canvas.width = Math.ceil(outW * dpr);
|
|
3656
|
+
canvas.height = Math.ceil(outH * dpr);
|
|
3657
|
+
canvas.style.width = `${outW}px`;
|
|
3658
|
+
canvas.style.height = `${outH}px`;
|
|
3659
|
+
const ctx = canvas.getContext("2d");
|
|
3660
|
+
if (dpr !== 1) ctx.scale(dpr, dpr);
|
|
3661
|
+
ctx.drawImage(img, 0, 0, outW, outH);
|
|
3662
|
+
return canvas;
|
|
3663
|
+
});
|
|
3664
|
+
}
|
|
3665
|
+
|
|
3666
|
+
// src/modules/rasterize.js
|
|
3667
|
+
function rasterize(url, options) {
|
|
3668
|
+
return __async(this, null, function* () {
|
|
3669
|
+
const canvas = yield toCanvas(url, options);
|
|
3670
|
+
const finalCanvas = options.backgroundColor ? createBackground(canvas, options.backgroundColor) : canvas;
|
|
3671
|
+
const img = new Image();
|
|
3672
|
+
img.src = finalCanvas.toDataURL(`image/${options.format}`, options.quality);
|
|
3673
|
+
yield img.decode();
|
|
3674
|
+
img.style.width = `${finalCanvas.width / options.dpr}px`;
|
|
3675
|
+
img.style.height = `${finalCanvas.height / options.dpr}px`;
|
|
3212
3676
|
return img;
|
|
3213
3677
|
});
|
|
3214
3678
|
}
|
|
3215
3679
|
|
|
3216
|
-
// src/exporters/
|
|
3217
|
-
function
|
|
3680
|
+
// src/exporters/toImg.js
|
|
3681
|
+
function toImg(url, options) {
|
|
3218
3682
|
return __async(this, null, function* () {
|
|
3219
|
-
const { scale,
|
|
3683
|
+
const { scale = 1, width, height, meta = {} } = options;
|
|
3684
|
+
const hasW = Number.isFinite(width);
|
|
3685
|
+
const hasH = Number.isFinite(height);
|
|
3686
|
+
const wantsScale = Number.isFinite(scale) && scale !== 1 || hasW || hasH;
|
|
3687
|
+
if (isSafari() && wantsScale) {
|
|
3688
|
+
const pngUrl = yield rasterize(url, __spreadProps(__spreadValues({}, options), { format: "png", quality: 1, meta }));
|
|
3689
|
+
return pngUrl;
|
|
3690
|
+
}
|
|
3220
3691
|
const img = new Image();
|
|
3221
|
-
img.crossOrigin = "anonymous";
|
|
3222
|
-
img.loading = "eager";
|
|
3223
3692
|
img.decoding = "sync";
|
|
3693
|
+
img.loading = "eager";
|
|
3224
3694
|
img.src = url;
|
|
3225
3695
|
yield img.decode();
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3696
|
+
if (hasW && hasH) {
|
|
3697
|
+
img.style.width = `${width}px`;
|
|
3698
|
+
img.style.height = `${height}px`;
|
|
3699
|
+
} else if (hasW) {
|
|
3700
|
+
const refW = Number.isFinite(meta.w0) ? meta.w0 : img.naturalWidth;
|
|
3701
|
+
const refH = Number.isFinite(meta.h0) ? meta.h0 : img.naturalHeight;
|
|
3702
|
+
const k = width / Math.max(1, refW);
|
|
3703
|
+
img.style.width = `${width}px`;
|
|
3704
|
+
img.style.height = `${Math.round(refH * k)}px`;
|
|
3705
|
+
} else if (hasH) {
|
|
3706
|
+
const refW = Number.isFinite(meta.w0) ? meta.w0 : img.naturalWidth;
|
|
3707
|
+
const refH = Number.isFinite(meta.h0) ? meta.h0 : img.naturalHeight;
|
|
3708
|
+
const k = height / Math.max(1, refH);
|
|
3709
|
+
img.style.height = `${height}px`;
|
|
3710
|
+
img.style.width = `${Math.round(refW * k)}px`;
|
|
3711
|
+
} else if (scale !== 1) {
|
|
3712
|
+
img.style.width = `${Math.round(img.naturalWidth * scale)}px`;
|
|
3713
|
+
img.style.height = `${Math.round(img.naturalHeight * scale)}px`;
|
|
3714
|
+
}
|
|
3715
|
+
return img;
|
|
3237
3716
|
});
|
|
3238
3717
|
}
|
|
3239
3718
|
|
|
@@ -3257,20 +3736,6 @@
|
|
|
3257
3736
|
});
|
|
3258
3737
|
}
|
|
3259
3738
|
|
|
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
3739
|
// src/exporters/download.js
|
|
3275
3740
|
function download(url, options) {
|
|
3276
3741
|
return __async(this, null, function* () {
|
|
@@ -3300,7 +3765,8 @@
|
|
|
3300
3765
|
function snapdom(element, userOptions) {
|
|
3301
3766
|
return __async(this, null, function* () {
|
|
3302
3767
|
if (!element) throw new Error("Element cannot be null or undefined");
|
|
3303
|
-
|
|
3768
|
+
const context = createContext(userOptions);
|
|
3769
|
+
if (isSafari() && (context.embedFonts === true || hasBackgroundOrMask(element))) {
|
|
3304
3770
|
for (let i = 0; i < 3; i++) {
|
|
3305
3771
|
try {
|
|
3306
3772
|
yield safariWarmup(element, userOptions);
|
|
@@ -3310,7 +3776,6 @@
|
|
|
3310
3776
|
}
|
|
3311
3777
|
}
|
|
3312
3778
|
}
|
|
3313
|
-
const context = createContext(userOptions);
|
|
3314
3779
|
if (context.iconFonts && context.iconFonts.length > 0) extendIconFonts(context.iconFonts);
|
|
3315
3780
|
if (!context.snap) {
|
|
3316
3781
|
context.snap = {
|
|
@@ -3392,6 +3857,20 @@
|
|
|
3392
3857
|
});
|
|
3393
3858
|
});
|
|
3394
3859
|
}
|
|
3860
|
+
function hasBackgroundOrMask(el) {
|
|
3861
|
+
const walker = document.createTreeWalker(el, NodeFilter.SHOW_ELEMENT);
|
|
3862
|
+
while (walker.nextNode()) {
|
|
3863
|
+
const node = (
|
|
3864
|
+
/** @type {Element} */
|
|
3865
|
+
walker.currentNode
|
|
3866
|
+
);
|
|
3867
|
+
const cs = getComputedStyle(node);
|
|
3868
|
+
const bg = cs.backgroundImage && cs.backgroundImage !== "none";
|
|
3869
|
+
const mask = cs.maskImage && cs.maskImage !== "none" || cs.webkitMaskImage && cs.webkitMaskImage !== "none";
|
|
3870
|
+
if (bg || mask) return true;
|
|
3871
|
+
}
|
|
3872
|
+
return false;
|
|
3873
|
+
}
|
|
3395
3874
|
|
|
3396
3875
|
// src/api/preCache.js
|
|
3397
3876
|
function preCache() {
|