@jxsuite/runtime 2.1.0 → 3.0.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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## Overview
6
6
 
7
- The runtime mounts Jx documents into the browser DOM. It walks the JSON tree, constructs DOM nodes, and wires reactive effects using [`@vue/reactivity`](https://github.com/vuejs/core/tree/main/packages/reactivity). State is tracked automatically — no virtual DOM, no diffing.
7
+ The runtime mounts Jx documents into the browser DOM. It walks the JSON tree, constructs DOM nodes, and wires reactive effects using [`@vue/reactivity`](https://github.com/vuejs/core/tree/main/packages/reactivity). State is tracked automatically: no virtual DOM, no diffing.
8
8
 
9
9
  ## Installation
10
10
 
@@ -55,7 +55,7 @@ Each document goes through four steps:
55
55
  | Map item | `{ "$ref": "$map/item" }` | Current item in `Array` iteration |
56
56
  | Parent | `{ "$ref": "parent#/color" }` | Prop passed via `$props` |
57
57
  | Window | `{ "$ref": "window#/config" }` | Window global |
58
- | External | `{ "$ref": "./card.json" }` | Component doc — via `$switch`/`$elements`, not a bare child |
58
+ | External | `{ "$ref": "./card.json" }` | Component doc (via `$switch`/`$elements`, not a bare child) |
59
59
 
60
60
  ## Custom element support
61
61
 
package/dist/runtime.js CHANGED
@@ -2194,7 +2194,7 @@ function checkSchemaVersion($schema) {
2194
2194
  }
2195
2195
  }
2196
2196
  async function Jx(source, target = document.body, options) {
2197
- const base = typeof source === "string" ? new URL(source, location.href).href : location.href;
2197
+ const base = options?.base ? new URL(options.base, location.href).href : typeof source === "string" ? new URL(source, location.href).href : location.href;
2198
2198
  const doc = await resolve(source);
2199
2199
  checkSchemaVersion(doc.$schema);
2200
2200
  if (doc.$elements) {
@@ -2528,6 +2528,32 @@ function evaluateTemplate(str, state) {
2528
2528
  const fn = new Function("state", "$map", "item", "index", `return \`${str}\``);
2529
2529
  return fn(state, $map, $map?.item, $map?.index);
2530
2530
  }
2531
+ function isSingleExpression(str) {
2532
+ if (!str.startsWith("${") || !str.endsWith("}")) {
2533
+ return false;
2534
+ }
2535
+ let depth = 0;
2536
+ for (let i = 1;i < str.length; i += 1) {
2537
+ const c = str[i];
2538
+ if (c === "{") {
2539
+ depth += 1;
2540
+ } else if (c === "}") {
2541
+ depth -= 1;
2542
+ if (depth === 0) {
2543
+ return i === str.length - 1;
2544
+ }
2545
+ }
2546
+ }
2547
+ return false;
2548
+ }
2549
+ function evaluateAttrTemplate(str, state) {
2550
+ if (!isSingleExpression(str)) {
2551
+ return evaluateTemplate(str, state);
2552
+ }
2553
+ const $map = state?.$map;
2554
+ const fn = new Function("state", "$map", "item", "index", `return (${str.slice(2, -1)})`);
2555
+ return fn(state, $map, $map?.item, $map?.index);
2556
+ }
2531
2557
  var _moduleCache = new Map;
2532
2558
  async function resolveFunction(def2, state, key, base) {
2533
2559
  if (def2.body && def2.$src) {
@@ -2924,16 +2950,33 @@ function reapplyStyle(el, styleDef, mediaQueries = {}, state = {}) {
2924
2950
  delete el.dataset.jx;
2925
2951
  applyStyle(el, styleDef ?? {}, mediaQueries, state);
2926
2952
  }
2953
+ var ENUMERATED_ATTRS = new Set(["contenteditable", "draggable", "spellcheck"]);
2954
+ function booleanAttrValue(name, value) {
2955
+ const lower = name.toLowerCase();
2956
+ if (lower.startsWith("aria-") || ENUMERATED_ATTRS.has(lower)) {
2957
+ return String(value);
2958
+ }
2959
+ return value ? "" : null;
2960
+ }
2927
2961
  function applyAttributes(el, attrs, state) {
2928
2962
  for (const [k, v] of Object.entries(attrs)) {
2929
2963
  const attr = canvasAttrName(el, k);
2930
2964
  const write = (resolved) => {
2965
+ if (typeof resolved === "boolean") {
2966
+ const text = booleanAttrValue(attr, resolved);
2967
+ if (text === null) {
2968
+ el.removeAttribute(attr);
2969
+ } else {
2970
+ el.setAttribute(attr, text);
2971
+ }
2972
+ return;
2973
+ }
2931
2974
  el.setAttribute(attr, canvasAssetValue(el.tagName, k, String(resolved ?? "")));
2932
2975
  };
2933
2976
  if (isRefObj(v)) {
2934
2977
  effect(() => write(resolveRef(v.$ref, state)));
2935
2978
  } else if (isTemplateString(v)) {
2936
- effect(() => write(evaluateTemplate(v, state)));
2979
+ effect(() => write(evaluateAttrTemplate(v, state)));
2937
2980
  } else {
2938
2981
  write(v);
2939
2982
  }
@@ -3924,6 +3967,7 @@ export {
3924
3967
  SUPPORTED_SCHEMA_VERSION,
3925
3968
  _resetPrivatePropWarnings,
3926
3969
  applyStyle,
3970
+ booleanAttrValue,
3927
3971
  buildScope,
3928
3972
  camelToKebab,
3929
3973
  canvasStyleValue,
@@ -3931,6 +3975,7 @@ export {
3931
3975
  elementStyleTags,
3932
3976
  hasSchemaKeywords,
3933
3977
  isSignal,
3978
+ isSingleExpression,
3934
3979
  observeScope,
3935
3980
  pureSchemeOf,
3936
3981
  reapplyStyle,
@@ -3955,5 +4000,5 @@ export {
3955
4000
  transposeCanvasUnits
3956
4001
  };
3957
4002
 
3958
- //# debugId=632439861BE4D5D264756E2164756E21
4003
+ //# debugId=33CA9AA2BD53687064756E2164756E21
3959
4004
  //# sourceMappingURL=runtime.js.map