@zumer/snapdom 1.9.12-dev.2 → 1.9.12-dev.3

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