@jxsuite/runtime 2.0.4 → 2.1.0

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/runtime.js CHANGED
@@ -2032,6 +2032,47 @@ function isPrivateStateKey(key) {
2032
2032
  return key.startsWith("#");
2033
2033
  }
2034
2034
 
2035
+ // ../schema/src/asset-paths.ts
2036
+ var URL_TERMINATOR = String.raw`"'\s<>()\\`;
2037
+ function parseSrcset(value) {
2038
+ const out = [];
2039
+ let i = 0;
2040
+ while (i < value.length) {
2041
+ while (i < value.length && (/\s/.test(value[i]) || value[i] === ",")) {
2042
+ i += 1;
2043
+ }
2044
+ if (i >= value.length) {
2045
+ break;
2046
+ }
2047
+ const start = i;
2048
+ while (i < value.length && !/\s/.test(value[i])) {
2049
+ i += 1;
2050
+ }
2051
+ let url = value.slice(start, i);
2052
+ if (url.endsWith(",")) {
2053
+ out.push({ descriptor: "", url: url.replace(/,+$/, "") });
2054
+ continue;
2055
+ }
2056
+ while (i < value.length && /\s/.test(value[i])) {
2057
+ i += 1;
2058
+ }
2059
+ const descStart = i;
2060
+ while (i < value.length && value[i] !== ",") {
2061
+ i += 1;
2062
+ }
2063
+ const descriptor = value.slice(descStart, i).trim();
2064
+ i += 1;
2065
+ url = url.replace(/,+$/, "");
2066
+ if (url !== "") {
2067
+ out.push({ descriptor, url });
2068
+ }
2069
+ }
2070
+ return out;
2071
+ }
2072
+ function formatSrcset(candidates) {
2073
+ return candidates.map(({ url, descriptor }) => descriptor ? `${url} ${descriptor}` : url).join(", ");
2074
+ }
2075
+
2035
2076
  // src/statements.ts
2036
2077
  function statementKind(statement) {
2037
2078
  if ("operator" in statement) {
@@ -2268,6 +2309,52 @@ function canvasAttrName(el, key) {
2268
2309
  }
2269
2310
  return key;
2270
2311
  }
2312
+ var _canvasAssetResolver = null;
2313
+ function setCanvasAssetResolver(fn) {
2314
+ _canvasAssetResolver = fn;
2315
+ }
2316
+ var ASSET_KEYS = new Set(["src", "poster", "data"]);
2317
+ var SRCSET_KEYS = new Set(["srcset", "imagesrcset"]);
2318
+ var HREF_ASSET_TAGS = new Set(["LINK"]);
2319
+ function isAssetKey(tagName, key) {
2320
+ return ASSET_KEYS.has(key) || key === "href" && HREF_ASSET_TAGS.has(tagName);
2321
+ }
2322
+ function canvasAssetValue(tagName, key, value) {
2323
+ if (!_canvasAssetResolver || value === "") {
2324
+ return value;
2325
+ }
2326
+ const name = key.toLowerCase();
2327
+ if (SRCSET_KEYS.has(name)) {
2328
+ const candidates = parseSrcset(value);
2329
+ let changed = false;
2330
+ const next = candidates.map((candidate) => {
2331
+ const resolved = _canvasAssetResolver?.(candidate.url, name) ?? null;
2332
+ if (resolved === null || resolved === candidate.url) {
2333
+ return candidate;
2334
+ }
2335
+ changed = true;
2336
+ return { descriptor: candidate.descriptor, url: resolved };
2337
+ });
2338
+ return changed ? formatSrcset(next) : value;
2339
+ }
2340
+ if (!isAssetKey(tagName, name)) {
2341
+ return value;
2342
+ }
2343
+ return _canvasAssetResolver(value, name) ?? value;
2344
+ }
2345
+ var CSS_URL_RE = /\burl\(\s*(?<q>["']?)(?<u>[^"')]*)\k<q>\s*\)/g;
2346
+ function canvasStyleUrls(value) {
2347
+ if (!_canvasAssetResolver || !value.includes("url(")) {
2348
+ return value;
2349
+ }
2350
+ return value.replaceAll(CSS_URL_RE, (whole, quote, url) => {
2351
+ const resolved = url === "" ? null : _canvasAssetResolver?.(url, "url()") ?? null;
2352
+ return resolved === null ? whole : `url(${quote}${resolved}${quote})`;
2353
+ });
2354
+ }
2355
+ function canvasStyleValue(value) {
2356
+ return transposeCanvasUnits(canvasStyleUrls(value));
2357
+ }
2271
2358
  var _stampPropBindings = false;
2272
2359
  function setStampPropBindings(on) {
2273
2360
  _stampPropBindings = on;
@@ -2544,6 +2631,17 @@ var RESERVED_KEYS = new Set([
2544
2631
  "observedAttributes"
2545
2632
  ]);
2546
2633
  var warnedRefChildren = new Set;
2634
+ var SVG_NS = "http://www.w3.org/2000/svg";
2635
+ var MATHML_NS = "http://www.w3.org/1998/Math/MathML";
2636
+ function elementNamespace(tagName, inherited) {
2637
+ if (tagName === "svg") {
2638
+ return SVG_NS;
2639
+ }
2640
+ if (tagName === "math") {
2641
+ return MATHML_NS;
2642
+ }
2643
+ return inherited ?? null;
2644
+ }
2547
2645
  function renderNode(def2, state, options) {
2548
2646
  const path = options?._path ?? [];
2549
2647
  if (typeof def2 === "string" || typeof def2 === "number" || typeof def2 === "boolean") {
@@ -2586,7 +2684,9 @@ function renderNode(def2, state, options) {
2586
2684
  if (def2.$switch) {
2587
2685
  return renderSwitch(def2, localState, options);
2588
2686
  }
2589
- const el = document.createElement(tagName);
2687
+ const ns = elementNamespace(tagName, options?._ns);
2688
+ const childNs = tagName === "foreignObject" ? null : ns;
2689
+ const el = ns ? document.createElementNS(ns, tagName) : document.createElement(tagName);
2590
2690
  if (options?.onNodeCreated) {
2591
2691
  options.onNodeCreated(el, path, def2, localState);
2592
2692
  }
@@ -2595,12 +2695,12 @@ function renderNode(def2, state, options) {
2595
2695
  applyAttributes(el, def2.attributes ?? {}, localState);
2596
2696
  const kids = def2.children;
2597
2697
  if (isMappedArray(kids)) {
2598
- const arrOpts = options ? { ...options, _path: [...path, "children"] } : undefined;
2698
+ const arrOpts = options || childNs ? { ...options, _ns: childNs, _path: [...path, "children"] } : undefined;
2599
2699
  renderMappedArrayInto(el, kids, localState, arrOpts);
2600
2700
  } else if (Array.isArray(kids)) {
2601
2701
  for (let i = 0;i < kids.length; i++) {
2602
2702
  const child = kids[i];
2603
- const childOpts = options ? { ...options, _path: [...path, "children", i] } : undefined;
2703
+ const childOpts = options || childNs ? { ...options, _ns: childNs, _path: [...path, "children", i] } : undefined;
2604
2704
  if (isMappedArray(child)) {
2605
2705
  renderMappedArrayInto(el, child, localState, childOpts);
2606
2706
  } else {
@@ -2659,6 +2759,15 @@ function bindProperty(el, key, val, state) {
2659
2759
  if (boundProp) {
2660
2760
  el.dataset.jxBoundProp = boundProp;
2661
2761
  }
2762
+ const asAsset = (resolved) => typeof resolved === "string" ? canvasAssetValue(el.tagName, key, resolved) : resolved;
2763
+ const write = (resolved) => {
2764
+ const node = el;
2765
+ if (key === "className" && !(node instanceof HTMLElement)) {
2766
+ node.setAttribute("class", resolved == null ? "" : String(resolved));
2767
+ return;
2768
+ }
2769
+ target[key] = resolved;
2770
+ };
2662
2771
  if (isRefObj(val)) {
2663
2772
  const refVal = val;
2664
2773
  if (key === "id") {
@@ -2666,17 +2775,17 @@ function bindProperty(el, key, val, state) {
2666
2775
  return;
2667
2776
  }
2668
2777
  effect(() => {
2669
- target[key] = resolveRef(refVal.$ref, state);
2778
+ write(asAsset(resolveRef(refVal.$ref, state)));
2670
2779
  });
2671
2780
  return;
2672
2781
  }
2673
2782
  if (isTemplateString(val)) {
2674
2783
  effect(() => {
2675
- target[key] = evaluateTemplate(val, state);
2784
+ write(asAsset(evaluateTemplate(val, state)));
2676
2785
  });
2677
2786
  return;
2678
2787
  }
2679
- target[key] = val;
2788
+ write(asAsset(val));
2680
2789
  }
2681
2790
  function applyStyle(el, styleDef, mediaQueries = {}, state = {}) {
2682
2791
  const nested = {};
@@ -2711,19 +2820,19 @@ function applyStyle(el, styleDef, mediaQueries = {}, state = {}) {
2711
2820
  if (prop.startsWith("--")) {
2712
2821
  if (isTemplateString(val)) {
2713
2822
  effect(() => {
2714
- el.style.setProperty(prop, transposeCanvasUnits(evaluateTemplate(val, state)));
2823
+ el.style.setProperty(prop, canvasStyleValue(evaluateTemplate(val, state)));
2715
2824
  });
2716
2825
  } else {
2717
- el.style.setProperty(prop, transposeCanvasUnits(scalar));
2826
+ el.style.setProperty(prop, canvasStyleValue(scalar));
2718
2827
  }
2719
2828
  } else if (isTemplateString(val)) {
2720
2829
  effect(() => {
2721
- el.style[prop] = transposeCanvasUnits(evaluateTemplate(val, state));
2830
+ el.style[prop] = canvasStyleValue(evaluateTemplate(val, state));
2722
2831
  });
2723
2832
  } else if (mediaOverriddenProps.has(prop)) {
2724
2833
  baseDecls[prop] = scalar;
2725
2834
  } else {
2726
- el.style[prop] = transposeCanvasUnits(scalar);
2835
+ el.style[prop] = canvasStyleValue(scalar);
2727
2836
  }
2728
2837
  }
2729
2838
  const hasNested = Object.keys(nested).length > 0;
@@ -2782,7 +2891,7 @@ function applyStyle(el, styleDef, mediaQueries = {}, state = {}) {
2782
2891
  if (key === "@--") {
2783
2892
  continue;
2784
2893
  }
2785
- const query = key.startsWith("@--") ? mediaQueries[key.slice(1)] ?? key.slice(1) : key.startsWith("@(") ? key.slice(1) : null;
2894
+ const query = resolveAtQuery(key, mediaQueries);
2786
2895
  const atRule = query === null ? key : `@media ${query}`;
2787
2896
  const scope = `[data-jx="${uid}"]`;
2788
2897
  const scheme = query === null ? null : pureSchemeOf(query);
@@ -2818,12 +2927,15 @@ function reapplyStyle(el, styleDef, mediaQueries = {}, state = {}) {
2818
2927
  function applyAttributes(el, attrs, state) {
2819
2928
  for (const [k, v] of Object.entries(attrs)) {
2820
2929
  const attr = canvasAttrName(el, k);
2930
+ const write = (resolved) => {
2931
+ el.setAttribute(attr, canvasAssetValue(el.tagName, k, String(resolved ?? "")));
2932
+ };
2821
2933
  if (isRefObj(v)) {
2822
- effect(() => el.setAttribute(attr, String(resolveRef(v.$ref, state) ?? "")));
2934
+ effect(() => write(resolveRef(v.$ref, state)));
2823
2935
  } else if (isTemplateString(v)) {
2824
- effect(() => el.setAttribute(attr, String(evaluateTemplate(v, state))));
2936
+ effect(() => write(evaluateTemplate(v, state)));
2825
2937
  } else {
2826
- el.setAttribute(attr, String(v));
2938
+ write(v);
2827
2939
  }
2828
2940
  }
2829
2941
  }
@@ -3502,7 +3614,18 @@ function camelToKebab(s) {
3502
3614
  return s.replaceAll(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
3503
3615
  }
3504
3616
  function toCSSText(rules) {
3505
- return Object.entries(rules).filter(([k, v]) => !isNestedSelector(k) && (v === null || typeof v !== "object")).map(([p, v]) => `${camelToKebab(p)}: ${transposeCanvasUnits(String(v))}`).join("; ");
3617
+ return Object.entries(rules).filter(([k, v]) => !isNestedSelector(k) && (v === null || typeof v !== "object")).map(([p, v]) => `${camelToKebab(p)}: ${canvasStyleValue(String(v))}`).join("; ");
3618
+ }
3619
+ var MEDIA_TYPES = new Set(["all", "print", "screen", "speech"]);
3620
+ function resolveAtQuery(atKey, mediaQueries) {
3621
+ if (atKey.startsWith("@--")) {
3622
+ return mediaQueries[atKey.slice(1)] ?? atKey.slice(1);
3623
+ }
3624
+ if (atKey.startsWith("@(")) {
3625
+ const inner = atKey.slice(2, -1).trim();
3626
+ return MEDIA_TYPES.has(inner.toLowerCase()) ? inner : atKey.slice(1);
3627
+ }
3628
+ return null;
3506
3629
  }
3507
3630
  var COLOR_SCHEME_ATTR = "data-color-scheme";
3508
3631
  var COLOR_SCHEME_STORAGE_KEY = "jx-color-scheme";
@@ -3564,9 +3687,14 @@ function injectHead(entries, _base) {
3564
3687
  const attrs = { ...entry.attributes };
3565
3688
  for (const key of ["href", "src"]) {
3566
3689
  const v = attrs[key];
3567
- if (typeof v === "string" && v && !v.startsWith("/") && !v.startsWith(".") && !v.startsWith("http")) {
3690
+ if (typeof v !== "string" || v === "") {
3691
+ continue;
3692
+ }
3693
+ if (!v.startsWith("/") && !v.startsWith(".") && !v.startsWith("http")) {
3568
3694
  attrs[key] = `/node_modules/${v}`;
3695
+ continue;
3569
3696
  }
3697
+ attrs[key] = canvasAssetValue(tag.toUpperCase(), key, v);
3570
3698
  }
3571
3699
  const selector = `${tag}${attrs.href ? `[href="${attrs.href}"]` : ""}${attrs.src ? `[src="${attrs.src}"]` : ""}`;
3572
3700
  if (selector !== tag && document.head.querySelector(selector)) {
@@ -3681,6 +3809,9 @@ async function defineElement(source, baseUrl) {
3681
3809
  }
3682
3810
  applyStyle(this, def2.style ?? {}, state["$media"] ?? {}, state);
3683
3811
  applyAttributes(this, def2.attributes ?? {}, state);
3812
+ if (!Array.isArray(def2.children) && def2.textContent !== undefined) {
3813
+ bindProperty(this, "textContent", def2.textContent, state);
3814
+ }
3684
3815
  const children = Array.isArray(def2.children) ? def2.children : [];
3685
3816
  for (const childDef of children) {
3686
3817
  this.append(renderNode(childDef, state));
@@ -3727,19 +3858,21 @@ function renderCustomElementWithProps(def2, state, options, path) {
3727
3858
  if (refusePrivateProp(key, "$props")) {
3728
3859
  continue;
3729
3860
  }
3861
+ const write = (resolved) => {
3862
+ el[key] = typeof resolved === "string" ? canvasAssetValue(el.tagName, key, resolved) : resolved;
3863
+ };
3730
3864
  if (isRefObj(val)) {
3731
3865
  const refVal = val;
3732
- const resolved = resolveRef(refVal.$ref, state);
3733
- el[key] = resolved;
3866
+ write(resolveRef(refVal.$ref, state));
3734
3867
  effect(() => {
3735
- el[key] = resolveRef(refVal.$ref, state);
3868
+ write(resolveRef(refVal.$ref, state));
3736
3869
  });
3737
3870
  } else if (isTemplateString(val)) {
3738
3871
  effect(() => {
3739
- el[key] = evaluateTemplate(val, state);
3872
+ write(evaluateTemplate(val, state));
3740
3873
  });
3741
3874
  } else {
3742
- el[key] = val;
3875
+ write(val);
3743
3876
  }
3744
3877
  }
3745
3878
  applyStyle(el, def2.style ?? {}, state["$media"] ?? {}, state);
@@ -3793,6 +3926,7 @@ export {
3793
3926
  applyStyle,
3794
3927
  buildScope,
3795
3928
  camelToKebab,
3929
+ canvasStyleValue,
3796
3930
  defineElement,
3797
3931
  elementStyleTags,
3798
3932
  hasSchemaKeywords,
@@ -3802,11 +3936,13 @@ export {
3802
3936
  reapplyStyle,
3803
3937
  renderNode,
3804
3938
  resolve,
3939
+ resolveAtQuery,
3805
3940
  resolvePrototype,
3806
3941
  resolveRef,
3807
3942
  resolveTagName,
3808
3943
  runScoped,
3809
3944
  schemeSelectors,
3945
+ setCanvasAssetResolver,
3810
3946
  setCanvasDelinkAnchors,
3811
3947
  setCanvasViewportTranspose,
3812
3948
  setResolveToken,
@@ -3819,5 +3955,5 @@ export {
3819
3955
  transposeCanvasUnits
3820
3956
  };
3821
3957
 
3822
- //# debugId=619B22D180EBAE7164756E2164756E21
3958
+ //# debugId=632439861BE4D5D264756E2164756E21
3823
3959
  //# sourceMappingURL=runtime.js.map