@zumer/snapdom 1.9.14 → 2.0.0-dev.1
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 +253 -22
- package/dist/snapdom.js +771 -231
- package/dist/snapdom.min.js +7 -7
- package/dist/snapdom.min.mjs +7 -7
- package/dist/snapdom.mjs +733 -227
- package/package.json +1 -1
- package/types/snapdom.d.ts +269 -176
package/dist/snapdom.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
/*
|
|
3
3
|
* snapdom
|
|
4
|
-
* v.
|
|
4
|
+
* v.2.0.0-dev.1
|
|
5
5
|
* Author Juan Martin Muda
|
|
6
6
|
* License MIT
|
|
7
7
|
**/
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
14
14
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
15
15
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
16
|
+
var __pow = Math.pow;
|
|
16
17
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
17
18
|
var __spreadValues = (a, b) => {
|
|
18
19
|
for (var prop in b || (b = {}))
|
|
@@ -63,6 +64,7 @@
|
|
|
63
64
|
}
|
|
64
65
|
};
|
|
65
66
|
function applyCachePolicy(policy = "soft") {
|
|
67
|
+
cache.session.__counterEpoch = (cache.session.__counterEpoch || 0) + 1;
|
|
66
68
|
switch (policy) {
|
|
67
69
|
case "auto": {
|
|
68
70
|
cache.session.styleMap = /* @__PURE__ */ new Map();
|
|
@@ -859,6 +861,27 @@
|
|
|
859
861
|
}
|
|
860
862
|
|
|
861
863
|
// src/modules/CSSVar.js
|
|
864
|
+
var KEY_PROPS = ["fill", "stroke", "color", "background-color", "stop-color"];
|
|
865
|
+
var __BASELINE_CACHE = /* @__PURE__ */ new Map();
|
|
866
|
+
function getBaselineComputed(tagName, ns) {
|
|
867
|
+
const key = ns + "::" + tagName.toLowerCase();
|
|
868
|
+
let entry = __BASELINE_CACHE.get(key);
|
|
869
|
+
if (entry) return entry;
|
|
870
|
+
const doc = document;
|
|
871
|
+
const el = ns === "http://www.w3.org/2000/svg" ? doc.createElementNS(ns, tagName) : doc.createElement(tagName);
|
|
872
|
+
const holder = doc.createElement("div");
|
|
873
|
+
holder.style.cssText = "position:absolute;left:-99999px;top:-99999px;contain:strict;display:block;";
|
|
874
|
+
holder.appendChild(el);
|
|
875
|
+
doc.documentElement.appendChild(holder);
|
|
876
|
+
const cs = getComputedStyle(el);
|
|
877
|
+
const base = {};
|
|
878
|
+
for (const p of KEY_PROPS) {
|
|
879
|
+
base[p] = cs.getPropertyValue(p) || "";
|
|
880
|
+
}
|
|
881
|
+
holder.remove();
|
|
882
|
+
__BASELINE_CACHE.set(key, base);
|
|
883
|
+
return base;
|
|
884
|
+
}
|
|
862
885
|
function resolveCSSVars(sourceEl, cloneEl) {
|
|
863
886
|
var _a, _b, _c;
|
|
864
887
|
if (!(sourceEl instanceof Element) || !(cloneEl instanceof Element)) return;
|
|
@@ -874,42 +897,62 @@
|
|
|
874
897
|
}
|
|
875
898
|
}
|
|
876
899
|
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
900
|
+
let cs = null;
|
|
901
|
+
if (hasVar) {
|
|
902
|
+
try {
|
|
903
|
+
cs = getComputedStyle(sourceEl);
|
|
904
|
+
} catch (e) {
|
|
905
|
+
}
|
|
883
906
|
}
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
907
|
+
if (hasVar) {
|
|
908
|
+
const author = sourceEl.style;
|
|
909
|
+
if (author && author.length) {
|
|
910
|
+
for (let i = 0; i < author.length; i++) {
|
|
911
|
+
const prop = author[i];
|
|
912
|
+
const val = author.getPropertyValue(prop);
|
|
913
|
+
if (!val || !val.includes("var(")) continue;
|
|
914
|
+
const resolved = cs && cs.getPropertyValue(prop);
|
|
915
|
+
if (resolved) {
|
|
916
|
+
try {
|
|
917
|
+
cloneEl.style.setProperty(prop, resolved.trim(), author.getPropertyPriority(prop));
|
|
918
|
+
} catch (e) {
|
|
919
|
+
}
|
|
895
920
|
}
|
|
896
921
|
}
|
|
897
922
|
}
|
|
898
923
|
}
|
|
899
|
-
if ((_c = sourceEl.attributes) == null ? void 0 : _c.length) {
|
|
924
|
+
if (hasVar && ((_c = sourceEl.attributes) == null ? void 0 : _c.length)) {
|
|
900
925
|
const attrs = sourceEl.attributes;
|
|
901
926
|
for (let i = 0; i < attrs.length; i++) {
|
|
902
927
|
const a = attrs[i];
|
|
903
928
|
if (!a || typeof a.value !== "string" || !a.value.includes("var(")) continue;
|
|
904
929
|
const propName = a.name;
|
|
905
|
-
|
|
930
|
+
const resolved = cs && cs.getPropertyValue(propName);
|
|
931
|
+
if (resolved) {
|
|
932
|
+
try {
|
|
933
|
+
cloneEl.style.setProperty(propName, resolved.trim());
|
|
934
|
+
} catch (e) {
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
if (!hasVar) {
|
|
940
|
+
if (!cs) {
|
|
906
941
|
try {
|
|
907
|
-
|
|
942
|
+
cs = getComputedStyle(sourceEl);
|
|
908
943
|
} catch (e) {
|
|
944
|
+
cs = null;
|
|
909
945
|
}
|
|
910
|
-
|
|
946
|
+
}
|
|
947
|
+
if (!cs) return;
|
|
948
|
+
const ns = sourceEl.namespaceURI || "html";
|
|
949
|
+
const base = getBaselineComputed(sourceEl.tagName, ns);
|
|
950
|
+
for (const prop of KEY_PROPS) {
|
|
951
|
+
const v = cs.getPropertyValue(prop) || "";
|
|
952
|
+
const b = base[prop] || "";
|
|
953
|
+
if (v && v !== b) {
|
|
911
954
|
try {
|
|
912
|
-
cloneEl.style.setProperty(
|
|
955
|
+
cloneEl.style.setProperty(prop, v.trim());
|
|
913
956
|
} catch (e) {
|
|
914
957
|
}
|
|
915
958
|
}
|
|
@@ -1239,11 +1282,50 @@
|
|
|
1239
1282
|
return clone2;
|
|
1240
1283
|
}
|
|
1241
1284
|
if (node.tagName === "CANVAS") {
|
|
1242
|
-
|
|
1285
|
+
let url = "";
|
|
1286
|
+
try {
|
|
1287
|
+
const ctx = node.getContext("2d", { willReadFrequently: true });
|
|
1288
|
+
try {
|
|
1289
|
+
ctx && ctx.getImageData(0, 0, 1, 1);
|
|
1290
|
+
} catch (e) {
|
|
1291
|
+
}
|
|
1292
|
+
yield new Promise((r) => requestAnimationFrame(r));
|
|
1293
|
+
url = node.toDataURL("image/png");
|
|
1294
|
+
if (!url || url === "data:,") {
|
|
1295
|
+
try {
|
|
1296
|
+
ctx && ctx.getImageData(0, 0, 1, 1);
|
|
1297
|
+
} catch (e) {
|
|
1298
|
+
}
|
|
1299
|
+
yield new Promise((r) => requestAnimationFrame(r));
|
|
1300
|
+
url = node.toDataURL("image/png");
|
|
1301
|
+
if (!url || url === "data:,") {
|
|
1302
|
+
const scratch = document.createElement("canvas");
|
|
1303
|
+
scratch.width = node.width;
|
|
1304
|
+
scratch.height = node.height;
|
|
1305
|
+
const sctx = scratch.getContext("2d");
|
|
1306
|
+
if (sctx) {
|
|
1307
|
+
sctx.drawImage(node, 0, 0);
|
|
1308
|
+
url = scratch.toDataURL("image/png");
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
} catch (e) {
|
|
1313
|
+
}
|
|
1243
1314
|
const img = document.createElement("img");
|
|
1244
|
-
|
|
1315
|
+
try {
|
|
1316
|
+
img.decoding = "sync";
|
|
1317
|
+
img.loading = "eager";
|
|
1318
|
+
} catch (e) {
|
|
1319
|
+
}
|
|
1320
|
+
if (url) img.src = url;
|
|
1245
1321
|
img.width = node.width;
|
|
1246
1322
|
img.height = node.height;
|
|
1323
|
+
try {
|
|
1324
|
+
const cs = getComputedStyle(node);
|
|
1325
|
+
if (cs.width) img.style.width = cs.width;
|
|
1326
|
+
if (cs.height) img.style.height = cs.height;
|
|
1327
|
+
} catch (e) {
|
|
1328
|
+
}
|
|
1247
1329
|
sessionCache.nodeMap.set(img, node);
|
|
1248
1330
|
inlineAllStyles(node, img, sessionCache, options);
|
|
1249
1331
|
return img;
|
|
@@ -1422,6 +1504,130 @@
|
|
|
1422
1504
|
if (/icon/i.test(text) || /glyph/i.test(text) || /symbols/i.test(text) || /feather/i.test(text) || /fontawesome/i.test(text)) return true;
|
|
1423
1505
|
return false;
|
|
1424
1506
|
}
|
|
1507
|
+
function isMaterialFamily(family = "") {
|
|
1508
|
+
const s = String(family).toLowerCase();
|
|
1509
|
+
return /\bmaterial\s*icons\b/.test(s) || /\bmaterial\s*symbols\b/.test(s);
|
|
1510
|
+
}
|
|
1511
|
+
function ensureMaterialFontsReady(family = "Material Icons", px = 24) {
|
|
1512
|
+
return __async(this, null, function* () {
|
|
1513
|
+
try {
|
|
1514
|
+
yield Promise.all([
|
|
1515
|
+
document.fonts.load(`400 ${px}px "${family.replace(/["']/g, "")}"`),
|
|
1516
|
+
document.fonts.ready
|
|
1517
|
+
]);
|
|
1518
|
+
} catch (e) {
|
|
1519
|
+
}
|
|
1520
|
+
});
|
|
1521
|
+
}
|
|
1522
|
+
function resolvePaintColor(cs) {
|
|
1523
|
+
var _a, _b;
|
|
1524
|
+
let fill = ((_a = cs.getPropertyValue("-webkit-text-fill-color")) == null ? void 0 : _a.trim()) || "";
|
|
1525
|
+
const isTransparent = /rgba?\(\s*0\s*,\s*0\s*,\s*0\s*,\s*0\s*\)/i.test(fill);
|
|
1526
|
+
if (fill && !isTransparent && fill.toLowerCase() !== "currentcolor") {
|
|
1527
|
+
return fill;
|
|
1528
|
+
}
|
|
1529
|
+
const c = (_b = cs.color) == null ? void 0 : _b.trim();
|
|
1530
|
+
return c && c !== "inherit" ? c : "#000";
|
|
1531
|
+
}
|
|
1532
|
+
function materialIconToImage(_0) {
|
|
1533
|
+
return __async(this, arguments, function* (ligatureText, {
|
|
1534
|
+
family = "Material Icons",
|
|
1535
|
+
weight = "normal",
|
|
1536
|
+
fontSize = 32,
|
|
1537
|
+
color = "#000",
|
|
1538
|
+
variation = ""
|
|
1539
|
+
} = {}) {
|
|
1540
|
+
const fam = String(family || "").replace(/^['"]+|['"]+$/g, "");
|
|
1541
|
+
const dpr = window.devicePixelRatio || 1;
|
|
1542
|
+
yield ensureMaterialFontsReady(fam, fontSize);
|
|
1543
|
+
const span = document.createElement("span");
|
|
1544
|
+
span.textContent = ligatureText;
|
|
1545
|
+
span.style.position = "absolute";
|
|
1546
|
+
span.style.visibility = "hidden";
|
|
1547
|
+
span.style.left = "-99999px";
|
|
1548
|
+
span.style.whiteSpace = "nowrap";
|
|
1549
|
+
span.style.fontFamily = `"${fam}"`;
|
|
1550
|
+
span.style.fontWeight = String(weight || "normal");
|
|
1551
|
+
span.style.fontSize = `${fontSize}px`;
|
|
1552
|
+
span.style.lineHeight = "1";
|
|
1553
|
+
span.style.margin = "0";
|
|
1554
|
+
span.style.padding = "0";
|
|
1555
|
+
span.style.fontFeatureSettings = "'liga' 1";
|
|
1556
|
+
span.style.fontVariantLigatures = "normal";
|
|
1557
|
+
if (variation) span.style.fontVariationSettings = variation;
|
|
1558
|
+
span.style.color = color;
|
|
1559
|
+
document.body.appendChild(span);
|
|
1560
|
+
const rect = span.getBoundingClientRect();
|
|
1561
|
+
const width = Math.max(1, Math.ceil(rect.width));
|
|
1562
|
+
const height = Math.max(1, Math.ceil(rect.height));
|
|
1563
|
+
document.body.removeChild(span);
|
|
1564
|
+
const canvas = document.createElement("canvas");
|
|
1565
|
+
canvas.width = width * dpr;
|
|
1566
|
+
canvas.height = height * dpr;
|
|
1567
|
+
const ctx = canvas.getContext("2d");
|
|
1568
|
+
ctx.scale(dpr, dpr);
|
|
1569
|
+
ctx.font = `${weight ? `${weight} ` : ""}${fontSize}px "${fam}"`;
|
|
1570
|
+
ctx.textAlign = "left";
|
|
1571
|
+
ctx.textBaseline = "top";
|
|
1572
|
+
ctx.fillStyle = color;
|
|
1573
|
+
try {
|
|
1574
|
+
ctx.fontKerning = "normal";
|
|
1575
|
+
} catch (e) {
|
|
1576
|
+
}
|
|
1577
|
+
ctx.fillText(ligatureText, 0, 0);
|
|
1578
|
+
return {
|
|
1579
|
+
dataUrl: canvas.toDataURL(),
|
|
1580
|
+
width,
|
|
1581
|
+
height
|
|
1582
|
+
};
|
|
1583
|
+
});
|
|
1584
|
+
}
|
|
1585
|
+
function ligatureIconToImage(cloneRoot, sourceRoot) {
|
|
1586
|
+
return __async(this, null, function* () {
|
|
1587
|
+
if (!(cloneRoot instanceof Element)) return 0;
|
|
1588
|
+
const selector = '.material-icons, [class*="material-symbols"]';
|
|
1589
|
+
const cloneNodes = Array.from(
|
|
1590
|
+
cloneRoot.querySelectorAll(selector)
|
|
1591
|
+
).filter((n) => n && n.textContent && n.textContent.trim());
|
|
1592
|
+
if (cloneNodes.length === 0) return 0;
|
|
1593
|
+
const sourceNodes = sourceRoot instanceof Element ? Array.from(sourceRoot.querySelectorAll(selector)).filter((n) => n && n.textContent && n.textContent.trim()) : [];
|
|
1594
|
+
let replaced = 0;
|
|
1595
|
+
for (let i = 0; i < cloneNodes.length; i++) {
|
|
1596
|
+
const el = cloneNodes[i];
|
|
1597
|
+
const src = sourceNodes[i] || null;
|
|
1598
|
+
try {
|
|
1599
|
+
const csSrc = src ? getComputedStyle(src) : getComputedStyle(el);
|
|
1600
|
+
const family = csSrc.fontFamily || "Material Icons";
|
|
1601
|
+
if (!isMaterialFamily(family)) continue;
|
|
1602
|
+
const text = (src || el).textContent.trim();
|
|
1603
|
+
if (!text) continue;
|
|
1604
|
+
const size = parseInt(csSrc.fontSize, 10) || 24;
|
|
1605
|
+
const weight = csSrc.fontWeight && csSrc.fontWeight !== "normal" ? csSrc.fontWeight : "normal";
|
|
1606
|
+
const color = resolvePaintColor(csSrc);
|
|
1607
|
+
const variation = csSrc.fontVariationSettings && csSrc.fontVariationSettings !== "normal" ? csSrc.fontVariationSettings : "";
|
|
1608
|
+
const { dataUrl, width, height } = yield materialIconToImage(text, {
|
|
1609
|
+
family,
|
|
1610
|
+
weight,
|
|
1611
|
+
fontSize: size,
|
|
1612
|
+
color,
|
|
1613
|
+
variation
|
|
1614
|
+
});
|
|
1615
|
+
el.textContent = "";
|
|
1616
|
+
const img = el.ownerDocument.createElement("img");
|
|
1617
|
+
img.src = dataUrl;
|
|
1618
|
+
img.alt = text;
|
|
1619
|
+
img.style.height = `${size}px`;
|
|
1620
|
+
img.style.width = `${Math.max(1, Math.round(width / height * size))}px`;
|
|
1621
|
+
img.style.objectFit = "contain";
|
|
1622
|
+
img.style.verticalAlign = getComputedStyle(el).verticalAlign || "baseline";
|
|
1623
|
+
el.appendChild(img);
|
|
1624
|
+
replaced++;
|
|
1625
|
+
} catch (e) {
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
return replaced;
|
|
1629
|
+
});
|
|
1630
|
+
}
|
|
1425
1631
|
|
|
1426
1632
|
// src/modules/fonts.js
|
|
1427
1633
|
function iconToImage(unicodeChar, fontFamily, fontWeight, fontSize = 32, color = "#000") {
|
|
@@ -2254,6 +2460,11 @@ ${imported}
|
|
|
2254
2460
|
}
|
|
2255
2461
|
}
|
|
2256
2462
|
function buildCounterContext(root) {
|
|
2463
|
+
const getEpoch = () => {
|
|
2464
|
+
var _a, _b, _c;
|
|
2465
|
+
return (_c = (_b = (_a = cache) == null ? void 0 : _a.session) == null ? void 0 : _b.__counterEpoch) != null ? _c : 0;
|
|
2466
|
+
};
|
|
2467
|
+
let run = getEpoch();
|
|
2257
2468
|
const nodeCounters = /* @__PURE__ */ new WeakMap();
|
|
2258
2469
|
const rootEl = root instanceof Document ? root.documentElement : root;
|
|
2259
2470
|
const isLi = (el) => el && el.tagName === "LI";
|
|
@@ -2347,6 +2558,14 @@ ${imported}
|
|
|
2347
2558
|
};
|
|
2348
2559
|
const empty = /* @__PURE__ */ new Map();
|
|
2349
2560
|
build(rootEl, empty, empty);
|
|
2561
|
+
function ensureFresh() {
|
|
2562
|
+
const now = getEpoch();
|
|
2563
|
+
if (now !== run) {
|
|
2564
|
+
run = now;
|
|
2565
|
+
const empty2 = /* @__PURE__ */ new Map();
|
|
2566
|
+
build(rootEl, empty2, empty2);
|
|
2567
|
+
}
|
|
2568
|
+
}
|
|
2350
2569
|
return {
|
|
2351
2570
|
/**
|
|
2352
2571
|
* Get top value for counter name at given node.
|
|
@@ -2355,6 +2574,7 @@ ${imported}
|
|
|
2355
2574
|
*/
|
|
2356
2575
|
get(node, name) {
|
|
2357
2576
|
var _a;
|
|
2577
|
+
ensureFresh();
|
|
2358
2578
|
const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
|
|
2359
2579
|
return s && s.length ? s[s.length - 1] : 0;
|
|
2360
2580
|
},
|
|
@@ -2365,6 +2585,7 @@ ${imported}
|
|
|
2365
2585
|
*/
|
|
2366
2586
|
getStack(node, name) {
|
|
2367
2587
|
var _a;
|
|
2588
|
+
ensureFresh();
|
|
2368
2589
|
const s = (_a = nodeCounters.get(node)) == null ? void 0 : _a.get(name);
|
|
2369
2590
|
return s ? s.slice() : [];
|
|
2370
2591
|
}
|
|
@@ -2399,8 +2620,8 @@ ${imported}
|
|
|
2399
2620
|
}
|
|
2400
2621
|
|
|
2401
2622
|
// src/modules/pseudo.js
|
|
2402
|
-
var counterCtx = null;
|
|
2403
2623
|
var __siblingCounters = /* @__PURE__ */ new WeakMap();
|
|
2624
|
+
var __pseudoEpoch = -1;
|
|
2404
2625
|
function unquoteDoubleStrings2(s) {
|
|
2405
2626
|
return (s || "").replace(/"([^"]*)"/g, "$1");
|
|
2406
2627
|
}
|
|
@@ -2497,14 +2718,21 @@ ${imported}
|
|
|
2497
2718
|
}
|
|
2498
2719
|
function inlinePseudoElements(source, clone, sessionCache, options) {
|
|
2499
2720
|
return __async(this, null, function* () {
|
|
2500
|
-
var _a;
|
|
2721
|
+
var _a, _b, _c, _d;
|
|
2501
2722
|
if (!(source instanceof Element) || !(clone instanceof Element)) return;
|
|
2502
|
-
|
|
2723
|
+
const epoch = (_c = (_b = (_a = cache) == null ? void 0 : _a.session) == null ? void 0 : _b.__counterEpoch) != null ? _c : 0;
|
|
2724
|
+
if (__pseudoEpoch !== epoch) {
|
|
2725
|
+
__siblingCounters = /* @__PURE__ */ new WeakMap();
|
|
2726
|
+
if (sessionCache) sessionCache.__counterCtx = null;
|
|
2727
|
+
__pseudoEpoch = epoch;
|
|
2728
|
+
}
|
|
2729
|
+
if (!sessionCache.__counterCtx) {
|
|
2503
2730
|
try {
|
|
2504
|
-
|
|
2731
|
+
sessionCache.__counterCtx = buildCounterContext(source.ownerDocument || document);
|
|
2505
2732
|
} catch (e) {
|
|
2506
2733
|
}
|
|
2507
2734
|
}
|
|
2735
|
+
const counterCtx = sessionCache.__counterCtx;
|
|
2508
2736
|
for (const pseudo of ["::before", "::after", "::first-letter"]) {
|
|
2509
2737
|
try {
|
|
2510
2738
|
const style = getStyle(source, pseudo);
|
|
@@ -2572,7 +2800,8 @@ ${imported}
|
|
|
2572
2800
|
}
|
|
2573
2801
|
const pseudoEl = document.createElement("span");
|
|
2574
2802
|
pseudoEl.dataset.snapdomPseudo = pseudo;
|
|
2575
|
-
pseudoEl.style.
|
|
2803
|
+
pseudoEl.style.display = "inline";
|
|
2804
|
+
pseudoEl.style.verticalAlign = "baseline";
|
|
2576
2805
|
pseudoEl.style.pointerEvents = "none";
|
|
2577
2806
|
const snapshot = snapshotComputedStyle(style);
|
|
2578
2807
|
const key = getStyleKey(snapshot, "span");
|
|
@@ -2600,9 +2829,23 @@ ${imported}
|
|
|
2600
2829
|
} else if (!isIconFont22 && hasExplicitContent) {
|
|
2601
2830
|
pseudoEl.textContent = cleanContent;
|
|
2602
2831
|
}
|
|
2603
|
-
pseudoEl.style.
|
|
2604
|
-
if ("
|
|
2605
|
-
|
|
2832
|
+
pseudoEl.style.backgroundImage = "none";
|
|
2833
|
+
if ("maskImage" in pseudoEl.style) pseudoEl.style.maskImage = "none";
|
|
2834
|
+
if ("webkitMaskImage" in pseudoEl.style) pseudoEl.style.webkitMaskImage = "none";
|
|
2835
|
+
try {
|
|
2836
|
+
pseudoEl.style.backgroundRepeat = style.backgroundRepeat;
|
|
2837
|
+
pseudoEl.style.backgroundSize = style.backgroundSize;
|
|
2838
|
+
if (style.backgroundPositionX && style.backgroundPositionY) {
|
|
2839
|
+
pseudoEl.style.backgroundPositionX = style.backgroundPositionX;
|
|
2840
|
+
pseudoEl.style.backgroundPositionY = style.backgroundPositionY;
|
|
2841
|
+
} else {
|
|
2842
|
+
pseudoEl.style.backgroundPosition = style.backgroundPosition;
|
|
2843
|
+
}
|
|
2844
|
+
pseudoEl.style.backgroundOrigin = style.backgroundOrigin;
|
|
2845
|
+
pseudoEl.style.backgroundClip = style.backgroundClip;
|
|
2846
|
+
pseudoEl.style.backgroundAttachment = style.backgroundAttachment;
|
|
2847
|
+
pseudoEl.style.backgroundBlendMode = style.backgroundBlendMode;
|
|
2848
|
+
} catch (e) {
|
|
2606
2849
|
}
|
|
2607
2850
|
if (hasBg) {
|
|
2608
2851
|
try {
|
|
@@ -2614,7 +2857,7 @@ ${imported}
|
|
|
2614
2857
|
}
|
|
2615
2858
|
}
|
|
2616
2859
|
if (hasBgColor) pseudoEl.style.backgroundColor = bgColor;
|
|
2617
|
-
const hasContent2 = pseudoEl.childNodes.length > 0 || ((
|
|
2860
|
+
const hasContent2 = pseudoEl.childNodes.length > 0 || ((_d = pseudoEl.textContent) == null ? void 0 : _d.trim()) !== "";
|
|
2618
2861
|
const hasVisibleBox = hasContent2 || hasBg || hasBgColor || hasBorder || hasTransform;
|
|
2619
2862
|
if (incs && incs.length && source.parentElement) {
|
|
2620
2863
|
const map = __siblingCounters.get(source.parentElement) || /* @__PURE__ */ new Map();
|
|
@@ -2646,53 +2889,114 @@ ${imported}
|
|
|
2646
2889
|
}
|
|
2647
2890
|
|
|
2648
2891
|
// src/modules/svgDefs.js
|
|
2649
|
-
function inlineExternalDefsAndSymbols(
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2892
|
+
function inlineExternalDefsAndSymbols(element, lookupRoot) {
|
|
2893
|
+
var _a, _b, _c, _d;
|
|
2894
|
+
if (!element || !(element instanceof Element)) return;
|
|
2895
|
+
const doc = element.ownerDocument || document;
|
|
2896
|
+
const searchRoot = lookupRoot || doc;
|
|
2897
|
+
const svgRoots = element instanceof SVGSVGElement ? [element] : Array.from(element.querySelectorAll("svg"));
|
|
2898
|
+
if (svgRoots.length === 0) return;
|
|
2899
|
+
const URL_ID_RE = /url\(\s*#([^)]+)\)/g;
|
|
2900
|
+
const URL_ATTRS = [
|
|
2901
|
+
"fill",
|
|
2902
|
+
"stroke",
|
|
2903
|
+
"filter",
|
|
2904
|
+
"clip-path",
|
|
2905
|
+
"mask",
|
|
2906
|
+
"marker",
|
|
2907
|
+
"marker-start",
|
|
2908
|
+
"marker-mid",
|
|
2909
|
+
"marker-end"
|
|
2910
|
+
];
|
|
2911
|
+
const cssEscape = (s) => window.CSS && CSS.escape ? CSS.escape(s) : s.replace(/[^a-zA-Z0-9_-]/g, "\\$&");
|
|
2912
|
+
const globalExistingIds = new Set(
|
|
2913
|
+
Array.from(element.querySelectorAll("[id]")).map((n) => n.id)
|
|
2914
|
+
);
|
|
2915
|
+
const neededIds = /* @__PURE__ */ new Set();
|
|
2916
|
+
let sawAnyReference = false;
|
|
2917
|
+
const addUrlIdsFromValue = (val) => {
|
|
2918
|
+
if (!val) return;
|
|
2919
|
+
URL_ID_RE.lastIndex = 0;
|
|
2920
|
+
let m;
|
|
2921
|
+
while (m = URL_ID_RE.exec(val)) {
|
|
2922
|
+
sawAnyReference = true;
|
|
2923
|
+
const id = (m[1] || "").trim();
|
|
2924
|
+
if (id && !globalExistingIds.has(id)) neededIds.add(id);
|
|
2656
2925
|
}
|
|
2657
|
-
}
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
existingIds.add(el.id);
|
|
2673
|
-
});
|
|
2674
|
-
usedIds.forEach((id) => {
|
|
2675
|
-
if (existingIds.has(id)) return;
|
|
2676
|
-
const symbol = globalSymbols.find((sym) => sym.id === id);
|
|
2677
|
-
if (symbol) {
|
|
2678
|
-
container.appendChild(symbol.cloneNode(true));
|
|
2679
|
-
existingIds.add(id);
|
|
2680
|
-
return;
|
|
2926
|
+
};
|
|
2927
|
+
const collectReferencesInSvg = (rootSvg) => {
|
|
2928
|
+
const uses = rootSvg.querySelectorAll('use[href^="#"], use[xlink\\:href^="#"]');
|
|
2929
|
+
for (const u of uses) {
|
|
2930
|
+
const href = u.getAttribute("href") || u.getAttribute("xlink:href");
|
|
2931
|
+
if (!href || !href.startsWith("#")) continue;
|
|
2932
|
+
sawAnyReference = true;
|
|
2933
|
+
const id = href.slice(1).trim();
|
|
2934
|
+
if (id && !globalExistingIds.has(id)) neededIds.add(id);
|
|
2935
|
+
}
|
|
2936
|
+
let query = '*[style*="url("],*[fill^="url("], *[stroke^="url("],*[filter^="url("], *[clip-path^="url("],*[mask^="url("],*[marker^="url("], *[marker-start^="url("],*[marker-mid^="url("], *[marker-end^="url("]';
|
|
2937
|
+
const candidates = rootSvg.querySelectorAll(query);
|
|
2938
|
+
for (const el of candidates) {
|
|
2939
|
+
addUrlIdsFromValue(el.getAttribute("style") || "");
|
|
2940
|
+
for (const a of URL_ATTRS) addUrlIdsFromValue(el.getAttribute(a));
|
|
2681
2941
|
}
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2942
|
+
};
|
|
2943
|
+
for (const svg of svgRoots) collectReferencesInSvg(svg);
|
|
2944
|
+
if (!sawAnyReference) return;
|
|
2945
|
+
let defsHost = element.querySelector("svg.inline-defs-container");
|
|
2946
|
+
if (!defsHost) {
|
|
2947
|
+
defsHost = doc.createElementNS("http://www.w3.org/2000/svg", "svg");
|
|
2948
|
+
defsHost.classList.add("inline-defs-container");
|
|
2949
|
+
defsHost.setAttribute("aria-hidden", "true");
|
|
2950
|
+
defsHost.setAttribute("style", "position:absolute;width:0;height:0;overflow:hidden");
|
|
2951
|
+
element.insertBefore(defsHost, element.firstChild || null);
|
|
2952
|
+
}
|
|
2953
|
+
let localDefs = defsHost.querySelector("defs") || null;
|
|
2954
|
+
const findGlobalById = (id) => {
|
|
2955
|
+
if (!id) return null;
|
|
2956
|
+
if (globalExistingIds.has(id)) return null;
|
|
2957
|
+
const esc = cssEscape(id);
|
|
2958
|
+
const tryFind = (sel) => {
|
|
2959
|
+
const el = searchRoot.querySelector(sel);
|
|
2960
|
+
return el && !element.contains(el) ? el : null;
|
|
2961
|
+
};
|
|
2962
|
+
return tryFind(`svg defs > *#${esc}`) || tryFind(`svg > symbol#${esc}`) || tryFind(`*#${esc}`);
|
|
2963
|
+
};
|
|
2964
|
+
if (!neededIds.size) return;
|
|
2965
|
+
const queued = new Set(neededIds);
|
|
2966
|
+
const inlined = /* @__PURE__ */ new Set();
|
|
2967
|
+
while (queued.size) {
|
|
2968
|
+
const id = queued.values().next().value;
|
|
2969
|
+
queued.delete(id);
|
|
2970
|
+
if (!id || globalExistingIds.has(id) || inlined.has(id)) continue;
|
|
2971
|
+
const source = findGlobalById(id);
|
|
2972
|
+
if (!source) {
|
|
2973
|
+
inlined.add(id);
|
|
2974
|
+
continue;
|
|
2975
|
+
}
|
|
2976
|
+
if (!localDefs) {
|
|
2977
|
+
localDefs = doc.createElementNS("http://www.w3.org/2000/svg", "defs");
|
|
2978
|
+
defsHost.appendChild(localDefs);
|
|
2979
|
+
}
|
|
2980
|
+
const clone = source.cloneNode(true);
|
|
2981
|
+
if (!clone.id) clone.setAttribute("id", id);
|
|
2982
|
+
localDefs.appendChild(clone);
|
|
2983
|
+
inlined.add(id);
|
|
2984
|
+
globalExistingIds.add(id);
|
|
2985
|
+
const walk = [clone, ...clone.querySelectorAll("*")];
|
|
2986
|
+
for (const node of walk) {
|
|
2987
|
+
const h = ((_a = node.getAttribute) == null ? void 0 : _a.call(node, "href")) || ((_b = node.getAttribute) == null ? void 0 : _b.call(node, "xlink:href"));
|
|
2988
|
+
if (h && h.startsWith("#")) {
|
|
2989
|
+
const ref = h.slice(1).trim();
|
|
2990
|
+
if (ref && !globalExistingIds.has(ref) && !inlined.has(ref)) queued.add(ref);
|
|
2991
|
+
}
|
|
2992
|
+
const style = ((_c = node.getAttribute) == null ? void 0 : _c.call(node, "style")) || "";
|
|
2993
|
+
if (style) addUrlIdsFromValue(style);
|
|
2994
|
+
for (const a of URL_ATTRS) {
|
|
2995
|
+
const v = (_d = node.getAttribute) == null ? void 0 : _d.call(node, a);
|
|
2996
|
+
if (v) addUrlIdsFromValue(v);
|
|
2693
2997
|
}
|
|
2694
2998
|
}
|
|
2695
|
-
}
|
|
2999
|
+
}
|
|
2696
3000
|
}
|
|
2697
3001
|
|
|
2698
3002
|
// src/modules/changeCSS.js
|
|
@@ -3155,6 +3459,17 @@ ${imported}
|
|
|
3155
3459
|
"-webkit-mask-position-x",
|
|
3156
3460
|
"-webkit-mask-position-y"
|
|
3157
3461
|
];
|
|
3462
|
+
const BG_LAYOUT_PROPS = [
|
|
3463
|
+
"background-position",
|
|
3464
|
+
"background-position-x",
|
|
3465
|
+
"background-position-y",
|
|
3466
|
+
"background-size",
|
|
3467
|
+
"background-repeat",
|
|
3468
|
+
"background-origin",
|
|
3469
|
+
"background-clip",
|
|
3470
|
+
"background-attachment",
|
|
3471
|
+
"background-blend-mode"
|
|
3472
|
+
];
|
|
3158
3473
|
const BORDER_AUX_PROPS = [
|
|
3159
3474
|
"border-image-slice",
|
|
3160
3475
|
"border-image-width",
|
|
@@ -3170,6 +3485,11 @@ ${imported}
|
|
|
3170
3485
|
const bis = style.getPropertyValue("border-image-source");
|
|
3171
3486
|
return bi && bi !== "none" || bis && bis !== "none";
|
|
3172
3487
|
})();
|
|
3488
|
+
for (const prop of BG_LAYOUT_PROPS) {
|
|
3489
|
+
const v = style.getPropertyValue(prop);
|
|
3490
|
+
if (!v) continue;
|
|
3491
|
+
cloneNode.style.setProperty(prop, v);
|
|
3492
|
+
}
|
|
3173
3493
|
for (const prop of URL_PROPS) {
|
|
3174
3494
|
const val = style.getPropertyValue(prop);
|
|
3175
3495
|
if (!val || val === "none") continue;
|
|
@@ -3194,7 +3514,7 @@ ${imported}
|
|
|
3194
3514
|
}
|
|
3195
3515
|
}
|
|
3196
3516
|
const sChildren = Array.from(srcNode.children);
|
|
3197
|
-
const cChildren = Array.from(cloneNode.children);
|
|
3517
|
+
const cChildren = Array.from(cloneNode.children).filter((el) => !(el.dataset && el.dataset.snapdomPseudo));
|
|
3198
3518
|
for (let i = 0; i < Math.min(sChildren.length, cChildren.length); i++) {
|
|
3199
3519
|
queue.push([sChildren[i], cChildren[i]]);
|
|
3200
3520
|
}
|
|
@@ -3260,6 +3580,85 @@ ${imported}
|
|
|
3260
3580
|
return Array.from(el.childNodes).some((n) => n.nodeType === Node.TEXT_NODE);
|
|
3261
3581
|
}
|
|
3262
3582
|
|
|
3583
|
+
// src/core/plugins.js
|
|
3584
|
+
var __plugins = [];
|
|
3585
|
+
function normalizePlugin(spec) {
|
|
3586
|
+
if (!spec) return null;
|
|
3587
|
+
if (Array.isArray(spec)) {
|
|
3588
|
+
const [factory, options] = spec;
|
|
3589
|
+
return typeof factory === "function" ? factory(options) : factory;
|
|
3590
|
+
}
|
|
3591
|
+
if (typeof spec === "object" && "plugin" in spec) {
|
|
3592
|
+
const { plugin, options } = spec;
|
|
3593
|
+
return typeof plugin === "function" ? plugin(options) : plugin;
|
|
3594
|
+
}
|
|
3595
|
+
if (typeof spec === "function") return spec();
|
|
3596
|
+
return spec;
|
|
3597
|
+
}
|
|
3598
|
+
function registerPlugins(...defs) {
|
|
3599
|
+
const flat = defs.flat();
|
|
3600
|
+
for (const d of flat) {
|
|
3601
|
+
const inst = normalizePlugin(d);
|
|
3602
|
+
if (!inst) continue;
|
|
3603
|
+
if (!__plugins.some((p) => p && p.name && inst.name && p.name === inst.name)) {
|
|
3604
|
+
__plugins.push(inst);
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
function getContextPlugins(context) {
|
|
3609
|
+
const arr = context && Array.isArray(context.plugins) ? context.plugins : __plugins;
|
|
3610
|
+
return arr || __plugins;
|
|
3611
|
+
}
|
|
3612
|
+
function runHook(name, context, payload) {
|
|
3613
|
+
return __async(this, null, function* () {
|
|
3614
|
+
let acc = payload;
|
|
3615
|
+
const list = getContextPlugins(context);
|
|
3616
|
+
for (const p of list) {
|
|
3617
|
+
const fn = p && typeof p[name] === "function" ? p[name] : null;
|
|
3618
|
+
if (!fn) continue;
|
|
3619
|
+
const out = yield fn(context, acc);
|
|
3620
|
+
if (typeof out !== "undefined") acc = out;
|
|
3621
|
+
}
|
|
3622
|
+
return acc;
|
|
3623
|
+
});
|
|
3624
|
+
}
|
|
3625
|
+
function runAll(name, context, payload) {
|
|
3626
|
+
return __async(this, null, function* () {
|
|
3627
|
+
const outs = [];
|
|
3628
|
+
const list = getContextPlugins(context);
|
|
3629
|
+
for (const p of list) {
|
|
3630
|
+
const fn = p && typeof p[name] === "function" ? p[name] : null;
|
|
3631
|
+
if (!fn) continue;
|
|
3632
|
+
const out = yield fn(context, payload);
|
|
3633
|
+
if (typeof out !== "undefined") outs.push(out);
|
|
3634
|
+
}
|
|
3635
|
+
return outs;
|
|
3636
|
+
});
|
|
3637
|
+
}
|
|
3638
|
+
function mergePlugins(localDefs) {
|
|
3639
|
+
const out = [];
|
|
3640
|
+
if (Array.isArray(localDefs)) {
|
|
3641
|
+
for (const d of localDefs) {
|
|
3642
|
+
const inst = normalizePlugin(d);
|
|
3643
|
+
if (!inst || !inst.name) continue;
|
|
3644
|
+
const i = out.findIndex((x) => x && x.name === inst.name);
|
|
3645
|
+
if (i >= 0) out.splice(i, 1);
|
|
3646
|
+
out.push(inst);
|
|
3647
|
+
}
|
|
3648
|
+
}
|
|
3649
|
+
for (const g of __plugins) {
|
|
3650
|
+
if (g && g.name && !out.some((x) => x.name === g.name)) {
|
|
3651
|
+
out.push(g);
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
return Object.freeze(out);
|
|
3655
|
+
}
|
|
3656
|
+
function attachSessionPlugins(context, localDefs, force = false) {
|
|
3657
|
+
if (!context || context.plugins && !force) return context;
|
|
3658
|
+
context.plugins = mergePlugins(localDefs);
|
|
3659
|
+
return context;
|
|
3660
|
+
}
|
|
3661
|
+
|
|
3263
3662
|
// src/core/capture.js
|
|
3264
3663
|
function stripRootShadows(originalEl, cloneRoot) {
|
|
3265
3664
|
if (!originalEl || !cloneRoot || !cloneRoot.style) return;
|
|
@@ -3288,43 +3687,52 @@ ${imported}
|
|
|
3288
3687
|
if (!element) throw new Error("Element cannot be null or undefined");
|
|
3289
3688
|
applyCachePolicy(options.cache);
|
|
3290
3689
|
const fast = options.fast;
|
|
3291
|
-
const
|
|
3292
|
-
const
|
|
3690
|
+
const outerTransforms = options.outerTransforms !== false;
|
|
3691
|
+
const outerShadows = !!options.outerShadows;
|
|
3692
|
+
let state = { element, options, plugins: options.plugins };
|
|
3293
3693
|
let clone, classCSS, styleCache;
|
|
3294
3694
|
let fontsCSS = "";
|
|
3295
3695
|
let baseCSS = "";
|
|
3296
3696
|
let dataURL;
|
|
3297
3697
|
let svgString;
|
|
3298
3698
|
let rootTransform2D = null;
|
|
3299
|
-
|
|
3699
|
+
yield runHook("beforeSnap", state);
|
|
3700
|
+
yield runHook("beforeClone", state);
|
|
3701
|
+
const undoClamp = lineClamp(state.element);
|
|
3300
3702
|
try {
|
|
3301
|
-
({ clone, classCSS, styleCache } = yield prepareClone(element, options));
|
|
3302
|
-
if (
|
|
3303
|
-
rootTransform2D = normalizeRootTransforms(element, clone);
|
|
3703
|
+
({ clone, classCSS, styleCache } = yield prepareClone(state.element, state.options));
|
|
3704
|
+
if (!outerTransforms && clone) {
|
|
3705
|
+
rootTransform2D = normalizeRootTransforms(state.element, clone);
|
|
3304
3706
|
}
|
|
3305
|
-
if (
|
|
3306
|
-
stripRootShadows(element, clone);
|
|
3707
|
+
if (!outerShadows && clone) {
|
|
3708
|
+
stripRootShadows(state.element, clone);
|
|
3307
3709
|
}
|
|
3308
3710
|
} finally {
|
|
3309
3711
|
undoClamp();
|
|
3310
3712
|
}
|
|
3713
|
+
state = __spreadValues({ clone, classCSS, styleCache }, state);
|
|
3714
|
+
yield runHook("afterClone", state);
|
|
3715
|
+
try {
|
|
3716
|
+
yield ligatureIconToImage(state.clone, state.element);
|
|
3717
|
+
} catch (e) {
|
|
3718
|
+
}
|
|
3311
3719
|
yield new Promise((resolve) => {
|
|
3312
3720
|
idle(() => __async(null, null, function* () {
|
|
3313
|
-
yield inlineImages(clone, options);
|
|
3721
|
+
yield inlineImages(state.clone, state.options);
|
|
3314
3722
|
resolve();
|
|
3315
3723
|
}), { fast });
|
|
3316
3724
|
});
|
|
3317
3725
|
yield new Promise((resolve) => {
|
|
3318
3726
|
idle(() => __async(null, null, function* () {
|
|
3319
|
-
yield inlineBackgroundImages(element, clone, styleCache, options);
|
|
3727
|
+
yield inlineBackgroundImages(state.element, state.clone, state.styleCache, state.options);
|
|
3320
3728
|
resolve();
|
|
3321
3729
|
}), { fast });
|
|
3322
3730
|
});
|
|
3323
3731
|
if (options.embedFonts) {
|
|
3324
3732
|
yield new Promise((resolve) => {
|
|
3325
3733
|
idle(() => __async(null, null, function* () {
|
|
3326
|
-
const required = collectUsedFontVariants(element);
|
|
3327
|
-
const usedCodepoints = collectUsedCodepoints(element);
|
|
3734
|
+
const required = collectUsedFontVariants(state.element);
|
|
3735
|
+
const usedCodepoints = collectUsedCodepoints(state.element);
|
|
3328
3736
|
if (isSafari()) {
|
|
3329
3737
|
const families = new Set(
|
|
3330
3738
|
Array.from(required).map((k) => String(k).split("__")[0]).filter(Boolean)
|
|
@@ -3335,14 +3743,14 @@ ${imported}
|
|
|
3335
3743
|
required,
|
|
3336
3744
|
usedCodepoints,
|
|
3337
3745
|
preCached: false,
|
|
3338
|
-
exclude: options.excludeFonts,
|
|
3339
|
-
useProxy: options.useProxy
|
|
3746
|
+
exclude: state.options.excludeFonts,
|
|
3747
|
+
useProxy: state.options.useProxy
|
|
3340
3748
|
});
|
|
3341
3749
|
resolve();
|
|
3342
3750
|
}), { fast });
|
|
3343
3751
|
});
|
|
3344
3752
|
}
|
|
3345
|
-
const usedTags = collectUsedTagNames(clone).sort();
|
|
3753
|
+
const usedTags = collectUsedTagNames(state.clone).sort();
|
|
3346
3754
|
const tagKey = usedTags.join(",");
|
|
3347
3755
|
if (cache.baseStyle.has(tagKey)) {
|
|
3348
3756
|
baseCSS = cache.baseStyle.get(tagKey);
|
|
@@ -3355,70 +3763,57 @@ ${imported}
|
|
|
3355
3763
|
}, { fast });
|
|
3356
3764
|
});
|
|
3357
3765
|
}
|
|
3766
|
+
state = __spreadValues({ fontsCSS, baseCSS }, state);
|
|
3767
|
+
yield runHook("beforeRender", state);
|
|
3358
3768
|
yield new Promise((resolve) => {
|
|
3359
3769
|
idle(() => {
|
|
3360
|
-
const csEl = getComputedStyle(element);
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
if (!raw || raw === "none") {
|
|
3365
|
-
return { bleed: { top: 0, right: 0, bottom: 0, left: 0 }, has: false };
|
|
3366
|
-
}
|
|
3367
|
-
const tokens = raw.match(/drop-shadow\((?:[^()]|\([^()]*\))*\)/gi) || [];
|
|
3368
|
-
let t = 0, r = 0, b = 0, l = 0;
|
|
3369
|
-
let found = false;
|
|
3370
|
-
for (const tok of tokens) {
|
|
3371
|
-
found = true;
|
|
3372
|
-
const nums = ((_a = tok.match(/-?\d+(?:\.\d+)?px/gi)) == null ? void 0 : _a.map((v) => parseFloat(v))) || [];
|
|
3373
|
-
const [ox = 0, oy = 0, blur = 0] = nums;
|
|
3374
|
-
const extX = Math.abs(ox) + blur;
|
|
3375
|
-
const extY = Math.abs(oy) + blur;
|
|
3376
|
-
r = Math.max(r, extX + Math.max(ox, 0));
|
|
3377
|
-
l = Math.max(l, extX + Math.max(-ox, 0));
|
|
3378
|
-
b = Math.max(b, extY + Math.max(oy, 0));
|
|
3379
|
-
t = Math.max(t, extY + Math.max(-oy, 0));
|
|
3380
|
-
}
|
|
3381
|
-
return { bleed: { top: Math.ceil(t), right: Math.ceil(r), bottom: Math.ceil(b), left: Math.ceil(l) }, has: found };
|
|
3382
|
-
}
|
|
3383
|
-
const rect = element.getBoundingClientRect();
|
|
3384
|
-
const w0 = Math.max(1, Math.ceil(element.offsetWidth || parseFloat(csEl.width) || rect.width || 1));
|
|
3385
|
-
const h0 = Math.max(1, Math.ceil(element.offsetHeight || parseFloat(csEl.height) || rect.height || 1));
|
|
3770
|
+
const csEl = getComputedStyle(state.element);
|
|
3771
|
+
const rect = state.element.getBoundingClientRect();
|
|
3772
|
+
const w0 = Math.max(1, limitDecimals(state.element.offsetWidth || parseFloat(csEl.width) || rect.width || 1));
|
|
3773
|
+
const h0 = Math.max(1, limitDecimals(state.element.offsetHeight || parseFloat(csEl.height) || rect.height || 1));
|
|
3386
3774
|
const coerceNum = (v, def = NaN) => {
|
|
3387
3775
|
const n = typeof v === "string" ? parseFloat(v) : v;
|
|
3388
3776
|
return Number.isFinite(n) ? n : def;
|
|
3389
3777
|
};
|
|
3390
|
-
const optW = coerceNum(options.width);
|
|
3391
|
-
const optH = coerceNum(options.height);
|
|
3778
|
+
const optW = coerceNum(state.options.width);
|
|
3779
|
+
const optH = coerceNum(state.options.height);
|
|
3392
3780
|
let w = w0, h = h0;
|
|
3393
3781
|
const hasW = Number.isFinite(optW);
|
|
3394
3782
|
const hasH = Number.isFinite(optH);
|
|
3395
3783
|
const aspect0 = h0 > 0 ? w0 / h0 : 1;
|
|
3396
3784
|
if (hasW && hasH) {
|
|
3397
|
-
w = Math.max(1,
|
|
3398
|
-
h = Math.max(1,
|
|
3785
|
+
w = Math.max(1, limitDecimals(optW));
|
|
3786
|
+
h = Math.max(1, limitDecimals(optH));
|
|
3399
3787
|
} else if (hasW) {
|
|
3400
|
-
w = Math.max(1,
|
|
3401
|
-
h = Math.max(1,
|
|
3788
|
+
w = Math.max(1, limitDecimals(optW));
|
|
3789
|
+
h = Math.max(1, limitDecimals(w / (aspect0 || 1)));
|
|
3402
3790
|
} else if (hasH) {
|
|
3403
|
-
h = Math.max(1,
|
|
3404
|
-
w = Math.max(1,
|
|
3791
|
+
h = Math.max(1, limitDecimals(optH));
|
|
3792
|
+
w = Math.max(1, limitDecimals(h * (aspect0 || 1)));
|
|
3405
3793
|
} else {
|
|
3406
3794
|
w = w0;
|
|
3407
3795
|
h = h0;
|
|
3408
3796
|
}
|
|
3409
3797
|
let minX = 0, minY = 0, maxX = w0, maxY = h0;
|
|
3410
|
-
if (
|
|
3411
|
-
const M2 = {
|
|
3798
|
+
if (!outerTransforms && rootTransform2D && Number.isFinite(rootTransform2D.a)) {
|
|
3799
|
+
const M2 = {
|
|
3800
|
+
a: rootTransform2D.a,
|
|
3801
|
+
b: rootTransform2D.b || 0,
|
|
3802
|
+
c: rootTransform2D.c || 0,
|
|
3803
|
+
d: rootTransform2D.d || 1,
|
|
3804
|
+
e: 0,
|
|
3805
|
+
f: 0
|
|
3806
|
+
};
|
|
3412
3807
|
const bb2 = bboxWithOriginFull(w0, h0, M2, 0, 0);
|
|
3413
|
-
minX = bb2.minX;
|
|
3414
|
-
minY = bb2.minY;
|
|
3415
|
-
maxX = bb2.maxX;
|
|
3416
|
-
maxY = bb2.maxY;
|
|
3808
|
+
minX = limitDecimals(bb2.minX);
|
|
3809
|
+
minY = limitDecimals(bb2.minY);
|
|
3810
|
+
maxX = limitDecimals(bb2.maxX);
|
|
3811
|
+
maxY = limitDecimals(bb2.maxY);
|
|
3417
3812
|
} else {
|
|
3418
|
-
const useTFBBox =
|
|
3813
|
+
const useTFBBox = outerTransforms && hasTFBBox(state.element);
|
|
3419
3814
|
if (useTFBBox) {
|
|
3420
3815
|
const baseTransform2 = csEl.transform && csEl.transform !== "none" ? csEl.transform : "";
|
|
3421
|
-
const ind2 = readIndividualTransforms(element);
|
|
3816
|
+
const ind2 = readIndividualTransforms(state.element);
|
|
3422
3817
|
const TOTAL = readTotalTransformMatrix({
|
|
3423
3818
|
baseTransform: baseTransform2,
|
|
3424
3819
|
rotate: ind2.rotate || "0deg",
|
|
@@ -3428,73 +3823,108 @@ ${imported}
|
|
|
3428
3823
|
const { ox: ox2, oy: oy2 } = parseTransformOriginPx(csEl, w0, h0);
|
|
3429
3824
|
const M = TOTAL.is2D ? TOTAL : new DOMMatrix(TOTAL.toString());
|
|
3430
3825
|
const bb = bboxWithOriginFull(w0, h0, M, ox2, oy2);
|
|
3431
|
-
minX = bb.minX;
|
|
3432
|
-
minY = bb.minY;
|
|
3433
|
-
maxX = bb.maxX;
|
|
3434
|
-
maxY = bb.maxY;
|
|
3826
|
+
minX = limitDecimals(bb.minX);
|
|
3827
|
+
minY = limitDecimals(bb.minY);
|
|
3828
|
+
maxX = limitDecimals(bb.maxX);
|
|
3829
|
+
maxY = limitDecimals(bb.maxY);
|
|
3435
3830
|
}
|
|
3436
3831
|
}
|
|
3437
3832
|
const bleedShadow = parseBoxShadow(csEl);
|
|
3438
3833
|
const bleedBlur = parseFilterBlur(csEl);
|
|
3439
3834
|
const bleedOutline = parseOutline(csEl);
|
|
3440
3835
|
const drop = parseFilterDropShadows(csEl);
|
|
3441
|
-
const bleed =
|
|
3442
|
-
top: bleedShadow.top + bleedBlur.top + bleedOutline.top + drop.bleed.top,
|
|
3443
|
-
right: bleedShadow.right + bleedBlur.right + bleedOutline.right + drop.bleed.right,
|
|
3444
|
-
bottom: bleedShadow.bottom + bleedBlur.bottom + bleedOutline.bottom + drop.bleed.bottom,
|
|
3445
|
-
left: bleedShadow.left + bleedBlur.left + bleedOutline.left + drop.bleed.left
|
|
3836
|
+
const bleed = !outerShadows ? { top: 0, right: 0, bottom: 0, left: 0 } : {
|
|
3837
|
+
top: limitDecimals(bleedShadow.top + bleedBlur.top + bleedOutline.top + drop.bleed.top),
|
|
3838
|
+
right: limitDecimals(bleedShadow.right + bleedBlur.right + bleedOutline.right + drop.bleed.right),
|
|
3839
|
+
bottom: limitDecimals(bleedShadow.bottom + bleedBlur.bottom + bleedOutline.bottom + drop.bleed.bottom),
|
|
3840
|
+
left: limitDecimals(bleedShadow.left + bleedBlur.left + bleedOutline.left + drop.bleed.left)
|
|
3446
3841
|
};
|
|
3447
|
-
minX
|
|
3448
|
-
minY
|
|
3449
|
-
maxX
|
|
3450
|
-
maxY
|
|
3451
|
-
const vbW0 = Math.max(1,
|
|
3452
|
-
const vbH0 = Math.max(1,
|
|
3453
|
-
const
|
|
3454
|
-
const
|
|
3842
|
+
minX = limitDecimals(minX - bleed.left);
|
|
3843
|
+
minY = limitDecimals(minY - bleed.top);
|
|
3844
|
+
maxX = limitDecimals(maxX + bleed.right);
|
|
3845
|
+
maxY = limitDecimals(maxY + bleed.bottom);
|
|
3846
|
+
const vbW0 = Math.max(1, limitDecimals(maxX - minX));
|
|
3847
|
+
const vbH0 = Math.max(1, limitDecimals(maxY - minY));
|
|
3848
|
+
const scaleW = hasW || hasH ? limitDecimals(w / w0) : 1;
|
|
3849
|
+
const scaleH = hasH || hasW ? limitDecimals(h / h0) : 1;
|
|
3850
|
+
const outW = Math.max(1, limitDecimals(vbW0 * scaleW));
|
|
3851
|
+
const outH = Math.max(1, limitDecimals(vbH0 * scaleH));
|
|
3455
3852
|
const svgNS = "http://www.w3.org/2000/svg";
|
|
3456
3853
|
const basePad = isSafari() ? 1 : 0;
|
|
3457
|
-
const extraPad =
|
|
3458
|
-
const pad = basePad + extraPad;
|
|
3854
|
+
const extraPad = !outerTransforms ? 1 : 0;
|
|
3855
|
+
const pad = limitDecimals(basePad + extraPad);
|
|
3459
3856
|
const fo = document.createElementNS(svgNS, "foreignObject");
|
|
3460
|
-
const vbMinX =
|
|
3461
|
-
const vbMinY =
|
|
3462
|
-
fo.setAttribute("x", String(-(vbMinX - pad)));
|
|
3463
|
-
fo.setAttribute("y", String(-(vbMinY - pad)));
|
|
3464
|
-
fo.setAttribute("width", String(
|
|
3465
|
-
fo.setAttribute("height", String(
|
|
3857
|
+
const vbMinX = limitDecimals(minX);
|
|
3858
|
+
const vbMinY = limitDecimals(minY);
|
|
3859
|
+
fo.setAttribute("x", String(limitDecimals(-(vbMinX - pad))));
|
|
3860
|
+
fo.setAttribute("y", String(limitDecimals(-(vbMinY - pad))));
|
|
3861
|
+
fo.setAttribute("width", String(limitDecimals(w0 + pad * 2)));
|
|
3862
|
+
fo.setAttribute("height", String(limitDecimals(h0 + pad * 2)));
|
|
3466
3863
|
fo.style.overflow = "visible";
|
|
3467
3864
|
const styleTag = document.createElement("style");
|
|
3468
|
-
styleTag.textContent = baseCSS + fontsCSS + "svg{overflow:visible;} foreignObject{overflow:visible;}" + classCSS;
|
|
3865
|
+
styleTag.textContent = state.baseCSS + state.fontsCSS + "svg{overflow:visible;} foreignObject{overflow:visible;}" + state.classCSS;
|
|
3469
3866
|
fo.appendChild(styleTag);
|
|
3470
3867
|
const container = document.createElement("div");
|
|
3471
3868
|
container.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
3472
|
-
container.style.width = `${w0}px`;
|
|
3473
|
-
container.style.height = `${h0}px`;
|
|
3869
|
+
container.style.width = `${limitDecimals(w0)}px`;
|
|
3870
|
+
container.style.height = `${limitDecimals(h0)}px`;
|
|
3474
3871
|
container.style.overflow = "visible";
|
|
3475
|
-
clone.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
3476
|
-
container.appendChild(clone);
|
|
3872
|
+
state.clone.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
3873
|
+
container.appendChild(state.clone);
|
|
3477
3874
|
fo.appendChild(container);
|
|
3478
3875
|
const serializer = new XMLSerializer();
|
|
3479
3876
|
const foString = serializer.serializeToString(fo);
|
|
3480
|
-
const vbW = vbW0 + pad * 2;
|
|
3481
|
-
const vbH = vbH0 + pad * 2;
|
|
3877
|
+
const vbW = limitDecimals(vbW0 + pad * 2);
|
|
3878
|
+
const vbH = limitDecimals(vbH0 + pad * 2);
|
|
3482
3879
|
const wantsSize = hasW || hasH;
|
|
3483
3880
|
options.meta = { w0, h0, vbW, vbH, targetW: w, targetH: h };
|
|
3484
|
-
const svgOutW = isSafari() && wantsSize ? vbW : outW + pad * 2;
|
|
3485
|
-
const svgOutH = isSafari() && wantsSize ? vbH : outH + pad * 2;
|
|
3881
|
+
const svgOutW = isSafari() && wantsSize ? vbW : limitDecimals(outW + pad * 2);
|
|
3882
|
+
const svgOutH = isSafari() && wantsSize ? vbH : limitDecimals(outH + pad * 2);
|
|
3486
3883
|
const svgHeader = `<svg xmlns="${svgNS}" width="${svgOutW}" height="${svgOutH}" viewBox="0 0 ${vbW} ${vbH}">`;
|
|
3487
3884
|
const svgFooter = "</svg>";
|
|
3488
3885
|
svgString = svgHeader + foString + svgFooter;
|
|
3489
3886
|
dataURL = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgString)}`;
|
|
3887
|
+
state = __spreadValues({ svgString, dataURL }, state);
|
|
3490
3888
|
resolve();
|
|
3491
3889
|
}, { fast });
|
|
3492
3890
|
});
|
|
3891
|
+
yield runHook("afterRender", state);
|
|
3493
3892
|
const sandbox = document.getElementById("snapdom-sandbox");
|
|
3494
3893
|
if (sandbox && sandbox.style.position === "absolute") sandbox.remove();
|
|
3495
|
-
return dataURL;
|
|
3894
|
+
return state.dataURL;
|
|
3496
3895
|
});
|
|
3497
3896
|
}
|
|
3897
|
+
var limitDecimals = (v, n = 3) => Number.isFinite(v) ? Math.round(v * __pow(10, n)) / __pow(10, n) : v;
|
|
3898
|
+
function parseFilterDropShadows(cs) {
|
|
3899
|
+
var _a;
|
|
3900
|
+
const raw = `${cs.filter || ""} ${cs.webkitFilter || ""}`.trim();
|
|
3901
|
+
if (!raw || raw === "none") {
|
|
3902
|
+
return { bleed: { top: 0, right: 0, bottom: 0, left: 0 }, has: false };
|
|
3903
|
+
}
|
|
3904
|
+
const tokens = raw.match(/drop-shadow\((?:[^()]|\([^()]*\))*\)/gi) || [];
|
|
3905
|
+
let t = 0, r = 0, b = 0, l = 0;
|
|
3906
|
+
let found = false;
|
|
3907
|
+
for (const tok of tokens) {
|
|
3908
|
+
found = true;
|
|
3909
|
+
const nums = ((_a = tok.match(/-?\d+(?:\.\d+)?px/gi)) == null ? void 0 : _a.map((v) => parseFloat(v))) || [];
|
|
3910
|
+
const [ox = 0, oy = 0, blur = 0] = nums;
|
|
3911
|
+
const extX = Math.abs(ox) + blur;
|
|
3912
|
+
const extY = Math.abs(oy) + blur;
|
|
3913
|
+
r = Math.max(r, extX + Math.max(ox, 0));
|
|
3914
|
+
l = Math.max(l, extX + Math.max(-ox, 0));
|
|
3915
|
+
b = Math.max(b, extY + Math.max(oy, 0));
|
|
3916
|
+
t = Math.max(t, extY + Math.max(-oy, 0));
|
|
3917
|
+
}
|
|
3918
|
+
return {
|
|
3919
|
+
bleed: {
|
|
3920
|
+
top: limitDecimals(t),
|
|
3921
|
+
right: limitDecimals(r),
|
|
3922
|
+
bottom: limitDecimals(b),
|
|
3923
|
+
left: limitDecimals(l)
|
|
3924
|
+
},
|
|
3925
|
+
has: found
|
|
3926
|
+
};
|
|
3927
|
+
}
|
|
3498
3928
|
function normalizeRootTransforms(originalEl, cloneRoot) {
|
|
3499
3929
|
if (!originalEl || !cloneRoot || !cloneRoot.style) return null;
|
|
3500
3930
|
const cs = getComputedStyle(originalEl);
|
|
@@ -3747,7 +4177,8 @@ ${imported}
|
|
|
3747
4177
|
}
|
|
3748
4178
|
function createContext(options = {}) {
|
|
3749
4179
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t;
|
|
3750
|
-
|
|
4180
|
+
let resolvedFormat = (_a = options.format) != null ? _a : "png";
|
|
4181
|
+
if (resolvedFormat === "jpg") resolvedFormat = "jpeg";
|
|
3751
4182
|
const cachePolicy = normalizeCachePolicy(options.cache);
|
|
3752
4183
|
return {
|
|
3753
4184
|
// Debug & perf
|
|
@@ -3779,11 +4210,11 @@ ${imported}
|
|
|
3779
4210
|
type: (_n = options.type) != null ? _n : "svg",
|
|
3780
4211
|
quality: (_o = options.quality) != null ? _o : 0.92,
|
|
3781
4212
|
dpr: (_p = options.dpr) != null ? _p : window.devicePixelRatio || 1,
|
|
3782
|
-
backgroundColor: (_q = options.backgroundColor) != null ? _q : ["
|
|
4213
|
+
backgroundColor: (_q = options.backgroundColor) != null ? _q : ["jpeg", "webp"].includes(resolvedFormat) ? "#ffffff" : null,
|
|
3783
4214
|
filename: (_r = options.filename) != null ? _r : "snapDOM",
|
|
3784
4215
|
// NEW flags (user-friendly)
|
|
3785
|
-
|
|
3786
|
-
|
|
4216
|
+
outerTransforms: (_s = options.outerTransforms) != null ? _s : true,
|
|
4217
|
+
outerShadows: (_t = options.outerShadows) != null ? _t : false
|
|
3787
4218
|
// Plugins (reservado)
|
|
3788
4219
|
// plugins: normalizePlugins(...),
|
|
3789
4220
|
};
|
|
@@ -3911,20 +4342,20 @@ ${imported}
|
|
|
3911
4342
|
} else if (hasW) {
|
|
3912
4343
|
const k = optW / Math.max(1, refW);
|
|
3913
4344
|
outW = optW;
|
|
3914
|
-
outH =
|
|
4345
|
+
outH = refH * k;
|
|
3915
4346
|
} else if (hasH) {
|
|
3916
4347
|
const k = optH / Math.max(1, refH);
|
|
3917
4348
|
outH = optH;
|
|
3918
|
-
outW =
|
|
4349
|
+
outW = refW * k;
|
|
3919
4350
|
} else {
|
|
3920
4351
|
outW = natW;
|
|
3921
4352
|
outH = natH;
|
|
3922
4353
|
}
|
|
3923
|
-
outW =
|
|
3924
|
-
outH =
|
|
4354
|
+
outW = outW * scale;
|
|
4355
|
+
outH = outH * scale;
|
|
3925
4356
|
const canvas = document.createElement("canvas");
|
|
3926
|
-
canvas.width =
|
|
3927
|
-
canvas.height =
|
|
4357
|
+
canvas.width = outW * dpr;
|
|
4358
|
+
canvas.height = outH * dpr;
|
|
3928
4359
|
canvas.style.width = `${outW}px`;
|
|
3929
4360
|
canvas.style.height = `${outH}px`;
|
|
3930
4361
|
const ctx = canvas.getContext("2d");
|
|
@@ -4042,17 +4473,23 @@ ${imported}
|
|
|
4042
4473
|
}
|
|
4043
4474
|
|
|
4044
4475
|
// src/api/snapdom.js
|
|
4476
|
+
snapdom.plugins = (...defs) => {
|
|
4477
|
+
registerPlugins(...defs);
|
|
4478
|
+
return snapdom;
|
|
4479
|
+
};
|
|
4045
4480
|
var INTERNAL_TOKEN = Symbol("snapdom.internal");
|
|
4481
|
+
var INTERNAL_EXPORT_TOKEN = Symbol("snapdom.internal.silent");
|
|
4046
4482
|
var _safariWarmup = false;
|
|
4047
4483
|
function snapdom(element, userOptions) {
|
|
4048
4484
|
return __async(this, null, function* () {
|
|
4049
4485
|
if (!element) throw new Error("Element cannot be null or undefined");
|
|
4050
4486
|
const context = createContext(userOptions);
|
|
4487
|
+
attachSessionPlugins(context, userOptions && userOptions.plugins);
|
|
4051
4488
|
if (isSafari() && (context.embedFonts === true || hasBackgroundOrMask(element))) {
|
|
4052
4489
|
for (let i = 0; i < 3; i++) {
|
|
4053
4490
|
try {
|
|
4054
4491
|
yield safariWarmup(element, userOptions);
|
|
4055
|
-
console.log("
|
|
4492
|
+
console.log("safariWarmup:", i);
|
|
4056
4493
|
_safariWarmup = false;
|
|
4057
4494
|
} catch (e) {
|
|
4058
4495
|
}
|
|
@@ -4068,31 +4505,108 @@ ${imported}
|
|
|
4068
4505
|
return snapdom.capture(element, context, INTERNAL_TOKEN);
|
|
4069
4506
|
});
|
|
4070
4507
|
}
|
|
4508
|
+
snapdom.plugins = (...defs) => {
|
|
4509
|
+
registerPlugins(...defs);
|
|
4510
|
+
return snapdom;
|
|
4511
|
+
};
|
|
4071
4512
|
snapdom.capture = (el, context, _token) => __async(null, null, function* () {
|
|
4072
4513
|
if (_token !== INTERNAL_TOKEN) throw new Error("[snapdom.capture] is internal. Use snapdom(...) instead.");
|
|
4073
4514
|
const url = yield captureDOM(el, context);
|
|
4074
|
-
const
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4515
|
+
const coreExports = {
|
|
4516
|
+
img: (ctx, opts) => __async(null, null, function* () {
|
|
4517
|
+
return toImg(url, __spreadValues(__spreadValues({}, ctx), opts || {}));
|
|
4518
|
+
}),
|
|
4519
|
+
svg: (ctx, opts) => __async(null, null, function* () {
|
|
4520
|
+
return toImg(url, __spreadValues(__spreadValues({}, ctx), opts || {}));
|
|
4521
|
+
}),
|
|
4522
|
+
canvas: (ctx, opts) => __async(null, null, function* () {
|
|
4523
|
+
return toCanvas(url, __spreadValues(__spreadValues({}, ctx), opts || {}));
|
|
4524
|
+
}),
|
|
4525
|
+
blob: (ctx, opts) => __async(null, null, function* () {
|
|
4526
|
+
return toBlob(url, __spreadValues(__spreadValues({}, ctx), opts || {}));
|
|
4527
|
+
}),
|
|
4528
|
+
png: (ctx, opts) => __async(null, null, function* () {
|
|
4529
|
+
return rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, ctx), opts || {}), { format: "png" }));
|
|
4530
|
+
}),
|
|
4531
|
+
jpeg: (ctx, opts) => __async(null, null, function* () {
|
|
4532
|
+
return rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, ctx), opts || {}), { format: "jpeg" }));
|
|
4533
|
+
}),
|
|
4534
|
+
webp: (ctx, opts) => __async(null, null, function* () {
|
|
4535
|
+
return rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, ctx), opts || {}), { format: "webp" }));
|
|
4536
|
+
}),
|
|
4537
|
+
download: (ctx, opts) => __async(null, null, function* () {
|
|
4538
|
+
return download(url, __spreadValues(__spreadValues({}, ctx), opts || {}));
|
|
4539
|
+
})
|
|
4083
4540
|
};
|
|
4084
|
-
|
|
4541
|
+
const _pluginExports = {
|
|
4542
|
+
svg: (opts) => toImg(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { [INTERNAL_EXPORT_TOKEN]: true })),
|
|
4543
|
+
canvas: (opts) => toCanvas(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { [INTERNAL_EXPORT_TOKEN]: true })),
|
|
4544
|
+
png: (opts) => rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { format: "png", [INTERNAL_EXPORT_TOKEN]: true })),
|
|
4545
|
+
jpeg: (opts) => rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { format: "jpeg", [INTERNAL_EXPORT_TOKEN]: true })),
|
|
4546
|
+
jpg: (opts) => rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { format: "jpeg", [INTERNAL_EXPORT_TOKEN]: true })),
|
|
4547
|
+
webp: (opts) => rasterize(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { format: "webp", [INTERNAL_EXPORT_TOKEN]: true })),
|
|
4548
|
+
blob: (opts) => toBlob(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { [INTERNAL_EXPORT_TOKEN]: true })),
|
|
4549
|
+
img: (opts) => toImg(url, __spreadProps(__spreadValues(__spreadValues({}, context), opts || {}), { [INTERNAL_EXPORT_TOKEN]: true }))
|
|
4550
|
+
};
|
|
4551
|
+
const _defineCtx = __spreadProps(__spreadValues({}, context), { export: { url }, exports: _pluginExports });
|
|
4552
|
+
const providedMaps = yield runAll("defineExports", _defineCtx);
|
|
4553
|
+
const provided = Object.assign({}, ...providedMaps.filter((x) => x && typeof x === "object"));
|
|
4554
|
+
const exportsMap = __spreadValues(__spreadValues({}, coreExports), provided);
|
|
4555
|
+
if (exportsMap.jpeg && !exportsMap.jpg) {
|
|
4556
|
+
exportsMap.jpg = (ctx, opts) => exportsMap.jpeg(ctx, opts);
|
|
4557
|
+
}
|
|
4558
|
+
function normalizeExportOptions(type, opts) {
|
|
4559
|
+
const next = __spreadValues(__spreadValues({}, context), opts || {});
|
|
4560
|
+
if (type === "jpeg" || type === "jpg") {
|
|
4561
|
+
const noBg = next.backgroundColor == null || next.backgroundColor === "transparent";
|
|
4562
|
+
if (noBg) next.backgroundColor = "#ffffff";
|
|
4563
|
+
}
|
|
4564
|
+
return next;
|
|
4565
|
+
}
|
|
4566
|
+
let afterSnapFired = false;
|
|
4567
|
+
let _exportQueue = Promise.resolve();
|
|
4568
|
+
function runExport(type, opts) {
|
|
4569
|
+
return __async(this, null, function* () {
|
|
4570
|
+
const job = () => __async(null, null, function* () {
|
|
4571
|
+
const work = exportsMap[type];
|
|
4572
|
+
if (!work) throw new Error(`[snapdom] Unknown export type: ${type}`);
|
|
4573
|
+
const nextOpts = normalizeExportOptions(type, opts);
|
|
4574
|
+
const ctx = __spreadProps(__spreadValues({}, context), { export: { type, options: nextOpts, url } });
|
|
4575
|
+
yield runHook("beforeExport", ctx);
|
|
4576
|
+
const result2 = yield work(ctx, nextOpts);
|
|
4577
|
+
yield runHook("afterExport", ctx, result2);
|
|
4578
|
+
if (!afterSnapFired) {
|
|
4579
|
+
afterSnapFired = true;
|
|
4580
|
+
yield runHook("afterSnap", context);
|
|
4581
|
+
}
|
|
4582
|
+
return result2;
|
|
4583
|
+
});
|
|
4584
|
+
return _exportQueue = _exportQueue.then(job);
|
|
4585
|
+
});
|
|
4586
|
+
}
|
|
4587
|
+
const result = {
|
|
4085
4588
|
url,
|
|
4086
4589
|
toRaw: () => url,
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4590
|
+
to: (type, opts) => runExport(type, opts),
|
|
4591
|
+
// Métodos “clásicos” que los tests esperan:
|
|
4592
|
+
toImg: (opts) => runExport("img", opts),
|
|
4593
|
+
toSvg: (opts) => runExport("svg", opts),
|
|
4594
|
+
toCanvas: (opts) => runExport("canvas", opts),
|
|
4595
|
+
toBlob: (opts) => runExport("blob", opts),
|
|
4596
|
+
toPng: (opts) => runExport("png", opts),
|
|
4597
|
+
toJpg: (opts) => runExport("jpg", opts),
|
|
4598
|
+
// ← alias requerido por los tests
|
|
4599
|
+
toWebp: (opts) => runExport("webp", opts),
|
|
4600
|
+
download: (opts) => runExport("download", opts)
|
|
4601
|
+
// ← método directo (no toDownload)
|
|
4095
4602
|
};
|
|
4603
|
+
for (const key of Object.keys(exportsMap)) {
|
|
4604
|
+
const helper = "to" + key.charAt(0).toUpperCase() + key.slice(1);
|
|
4605
|
+
if (!result[helper]) {
|
|
4606
|
+
result[helper] = (opts) => runExport(key, opts);
|
|
4607
|
+
}
|
|
4608
|
+
}
|
|
4609
|
+
return result;
|
|
4096
4610
|
});
|
|
4097
4611
|
snapdom.toRaw = (el, options) => snapdom(el, options).then((result) => result.toRaw());
|
|
4098
4612
|
snapdom.toImg = (el, options) => snapdom(el, options).then((result) => result.toImg());
|
|
@@ -4115,30 +4629,47 @@ ${imported}
|
|
|
4115
4629
|
try {
|
|
4116
4630
|
url = yield captureDOM(element, preflight);
|
|
4117
4631
|
} catch (e) {
|
|
4118
|
-
return;
|
|
4119
4632
|
}
|
|
4120
|
-
yield new Promise((
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4633
|
+
yield new Promise((r) => requestAnimationFrame(() => requestAnimationFrame(r)));
|
|
4634
|
+
if (url) {
|
|
4635
|
+
yield new Promise((resolve) => {
|
|
4636
|
+
const img = new Image();
|
|
4637
|
+
try {
|
|
4638
|
+
img.decoding = "sync";
|
|
4639
|
+
img.loading = "eager";
|
|
4640
|
+
} catch (e) {
|
|
4641
|
+
}
|
|
4642
|
+
img.style.cssText = "position:fixed;left:0px;top:0px;width:10px;height:10px;opacity:0.01;pointer-events:none;";
|
|
4643
|
+
img.src = url;
|
|
4644
|
+
document.body.appendChild(img);
|
|
4645
|
+
(() => __async(null, null, function* () {
|
|
4646
|
+
try {
|
|
4647
|
+
if (typeof img.decode === "function") yield img.decode();
|
|
4648
|
+
} catch (e) {
|
|
4649
|
+
}
|
|
4650
|
+
const start = performance.now();
|
|
4651
|
+
while (!(img.complete && img.naturalWidth > 0) && performance.now() - start < 900) {
|
|
4652
|
+
yield new Promise((r) => setTimeout(r, 50));
|
|
4653
|
+
}
|
|
4654
|
+
yield new Promise((r) => requestAnimationFrame(r));
|
|
4655
|
+
try {
|
|
4656
|
+
img.remove();
|
|
4657
|
+
} catch (e) {
|
|
4658
|
+
}
|
|
4659
|
+
resolve();
|
|
4660
|
+
}))();
|
|
4138
4661
|
});
|
|
4139
|
-
|
|
4140
|
-
|
|
4662
|
+
}
|
|
4663
|
+
element.querySelectorAll("canvas").forEach((c) => {
|
|
4664
|
+
try {
|
|
4665
|
+
const ctx = c.getContext("2d", { willReadFrequently: true });
|
|
4666
|
+
if (ctx) {
|
|
4667
|
+
ctx.getImageData(0, 0, 1, 1);
|
|
4668
|
+
}
|
|
4669
|
+
} catch (e) {
|
|
4670
|
+
}
|
|
4141
4671
|
});
|
|
4672
|
+
_safariWarmup = true;
|
|
4142
4673
|
});
|
|
4143
4674
|
}
|
|
4144
4675
|
function hasBackgroundOrMask(el) {
|
|
@@ -4152,6 +4683,7 @@ ${imported}
|
|
|
4152
4683
|
const bg = cs.backgroundImage && cs.backgroundImage !== "none";
|
|
4153
4684
|
const mask = cs.maskImage && cs.maskImage !== "none" || cs.webkitMaskImage && cs.webkitMaskImage !== "none";
|
|
4154
4685
|
if (bg || mask) return true;
|
|
4686
|
+
if (node.tagName === "CANVAS") return true;
|
|
4155
4687
|
}
|
|
4156
4688
|
return false;
|
|
4157
4689
|
}
|
|
@@ -4159,7 +4691,7 @@ ${imported}
|
|
|
4159
4691
|
// src/api/preCache.js
|
|
4160
4692
|
function preCache() {
|
|
4161
4693
|
return __async(this, arguments, function* (root = document, options = {}) {
|
|
4162
|
-
var _a, _b, _c, _d;
|
|
4694
|
+
var _a, _b, _c, _d, _e, _f;
|
|
4163
4695
|
const {
|
|
4164
4696
|
embedFonts = true,
|
|
4165
4697
|
useProxy = ""
|
|
@@ -4179,6 +4711,7 @@ ${imported}
|
|
|
4179
4711
|
cache.session.styleCache = /* @__PURE__ */ new WeakMap();
|
|
4180
4712
|
}
|
|
4181
4713
|
cache.image = cache.image || /* @__PURE__ */ new Map();
|
|
4714
|
+
cache.background = cache.background || /* @__PURE__ */ new Map();
|
|
4182
4715
|
try {
|
|
4183
4716
|
yield inlineBackgroundImages(
|
|
4184
4717
|
root,
|
|
@@ -4191,7 +4724,13 @@ ${imported}
|
|
|
4191
4724
|
}
|
|
4192
4725
|
let imgEls = [], allEls = [];
|
|
4193
4726
|
try {
|
|
4194
|
-
if (root
|
|
4727
|
+
if (root && root.nodeType === 1) {
|
|
4728
|
+
const descendants = root.querySelectorAll ? Array.from(root.querySelectorAll("*")) : [];
|
|
4729
|
+
allEls = [root, ...descendants];
|
|
4730
|
+
imgEls = [];
|
|
4731
|
+
if (root.tagName === "IMG" && root.getAttribute("src")) imgEls.push(root);
|
|
4732
|
+
imgEls.push(...Array.from(((_d = root.querySelectorAll) == null ? void 0 : _d.call(root, "img[src]")) || []));
|
|
4733
|
+
} else if (root == null ? void 0 : root.querySelectorAll) {
|
|
4195
4734
|
imgEls = Array.from(root.querySelectorAll("img[src]"));
|
|
4196
4735
|
allEls = Array.from(root.querySelectorAll("*"));
|
|
4197
4736
|
}
|
|
@@ -4215,17 +4754,18 @@ ${imported}
|
|
|
4215
4754
|
for (const el of allEls) {
|
|
4216
4755
|
let bg = "";
|
|
4217
4756
|
try {
|
|
4218
|
-
bg =
|
|
4757
|
+
bg = ((_e = el == null ? void 0 : el.style) == null ? void 0 : _e.backgroundImage) || "";
|
|
4758
|
+
if (!bg || bg === "none") {
|
|
4759
|
+
bg = getStyle(el).backgroundImage;
|
|
4760
|
+
}
|
|
4219
4761
|
} catch (e) {
|
|
4220
4762
|
}
|
|
4221
4763
|
if (bg && bg !== "none") {
|
|
4222
|
-
const
|
|
4223
|
-
for (const entry of
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
promises.push(p);
|
|
4228
|
-
}
|
|
4764
|
+
const urlEntries = bg.match(/url\((?:[^()"']+|"(?:[^"]*)"|'(?:[^']*)')\)/gi) || [];
|
|
4765
|
+
for (const entry of urlEntries) {
|
|
4766
|
+
const p = Promise.resolve().then(() => inlineSingleBackgroundEntry(entry, __spreadProps(__spreadValues({}, options), { useProxy }))).catch(() => {
|
|
4767
|
+
});
|
|
4768
|
+
promises.push(p);
|
|
4229
4769
|
}
|
|
4230
4770
|
}
|
|
4231
4771
|
}
|
|
@@ -4245,7 +4785,7 @@ ${imported}
|
|
|
4245
4785
|
usedCodepoints,
|
|
4246
4786
|
exclude: options.excludeFonts,
|
|
4247
4787
|
localFonts: options.localFonts,
|
|
4248
|
-
useProxy: (
|
|
4788
|
+
useProxy: (_f = options.useProxy) != null ? _f : useProxy
|
|
4249
4789
|
});
|
|
4250
4790
|
} catch (e) {
|
|
4251
4791
|
}
|