@jxsuite/runtime 2.1.0 → 3.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/README.md +2 -2
- package/dist/runtime.js +82 -35
- package/dist/runtime.js.map +8 -7
- package/package.json +8 -6
- package/src/css.ts +119 -0
- package/src/runtime.ts +136 -101
- package/src/types.ts +11 -0
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
|
|
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
|
|
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
|
@@ -1384,6 +1384,40 @@ function computed(getterOrOptions, debugOptions, isSSR = false) {
|
|
|
1384
1384
|
return cRef;
|
|
1385
1385
|
}
|
|
1386
1386
|
|
|
1387
|
+
// src/css.ts
|
|
1388
|
+
function camelToKebab(s) {
|
|
1389
|
+
return s.replaceAll(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
1390
|
+
}
|
|
1391
|
+
var MEDIA_TYPES = new Set(["all", "print", "screen", "speech"]);
|
|
1392
|
+
function resolveAtQuery(atKey, mediaQueries) {
|
|
1393
|
+
if (atKey.startsWith("@--")) {
|
|
1394
|
+
return mediaQueries[atKey.slice(1)] ?? atKey.slice(1);
|
|
1395
|
+
}
|
|
1396
|
+
if (atKey.startsWith("@(")) {
|
|
1397
|
+
const inner = atKey.slice(2, -1).trim();
|
|
1398
|
+
return MEDIA_TYPES.has(inner.toLowerCase()) ? inner : atKey.slice(1);
|
|
1399
|
+
}
|
|
1400
|
+
return null;
|
|
1401
|
+
}
|
|
1402
|
+
var COLOR_SCHEME_ATTR = "data-color-scheme";
|
|
1403
|
+
var COLOR_SCHEME_STORAGE_KEY = "jx-color-scheme";
|
|
1404
|
+
function pureSchemeOf(query) {
|
|
1405
|
+
const m = /^\(\s*prefers-color-scheme\s*:\s*(light|dark)\s*\)$/.exec(query.trim());
|
|
1406
|
+
return m?.[1] ?? null;
|
|
1407
|
+
}
|
|
1408
|
+
function schemeSelectors(selector, scheme) {
|
|
1409
|
+
if (selector === ":root" || selector === "html") {
|
|
1410
|
+
return {
|
|
1411
|
+
auto: `${selector}:where(:not([${COLOR_SCHEME_ATTR}]))`,
|
|
1412
|
+
forced: `${selector}:where([${COLOR_SCHEME_ATTR}="${scheme}"])`
|
|
1413
|
+
};
|
|
1414
|
+
}
|
|
1415
|
+
return {
|
|
1416
|
+
auto: `:where(:root:not([${COLOR_SCHEME_ATTR}])) ${selector}`,
|
|
1417
|
+
forced: `:where(:root[${COLOR_SCHEME_ATTR}="${scheme}"]) ${selector}`
|
|
1418
|
+
};
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1387
1421
|
// ../schema/src/intl.ts
|
|
1388
1422
|
var DEFAULT_FORMAT_LOCALE = "en-US";
|
|
1389
1423
|
var DEFAULT_TIME_ZONE = "UTC";
|
|
@@ -2194,7 +2228,7 @@ function checkSchemaVersion($schema) {
|
|
|
2194
2228
|
}
|
|
2195
2229
|
}
|
|
2196
2230
|
async function Jx(source, target = document.body, options) {
|
|
2197
|
-
const base = typeof source === "string" ? new URL(source, location.href).href : location.href;
|
|
2231
|
+
const base = options?.base ? new URL(options.base, location.href).href : typeof source === "string" ? new URL(source, location.href).href : location.href;
|
|
2198
2232
|
const doc = await resolve(source);
|
|
2199
2233
|
checkSchemaVersion(doc.$schema);
|
|
2200
2234
|
if (doc.$elements) {
|
|
@@ -2528,6 +2562,32 @@ function evaluateTemplate(str, state) {
|
|
|
2528
2562
|
const fn = new Function("state", "$map", "item", "index", `return \`${str}\``);
|
|
2529
2563
|
return fn(state, $map, $map?.item, $map?.index);
|
|
2530
2564
|
}
|
|
2565
|
+
function isSingleExpression(str) {
|
|
2566
|
+
if (!str.startsWith("${") || !str.endsWith("}")) {
|
|
2567
|
+
return false;
|
|
2568
|
+
}
|
|
2569
|
+
let depth = 0;
|
|
2570
|
+
for (let i = 1;i < str.length; i += 1) {
|
|
2571
|
+
const c = str[i];
|
|
2572
|
+
if (c === "{") {
|
|
2573
|
+
depth += 1;
|
|
2574
|
+
} else if (c === "}") {
|
|
2575
|
+
depth -= 1;
|
|
2576
|
+
if (depth === 0) {
|
|
2577
|
+
return i === str.length - 1;
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
}
|
|
2581
|
+
return false;
|
|
2582
|
+
}
|
|
2583
|
+
function evaluateAttrTemplate(str, state) {
|
|
2584
|
+
if (!isSingleExpression(str)) {
|
|
2585
|
+
return evaluateTemplate(str, state);
|
|
2586
|
+
}
|
|
2587
|
+
const $map = state?.$map;
|
|
2588
|
+
const fn = new Function("state", "$map", "item", "index", `return (${str.slice(2, -1)})`);
|
|
2589
|
+
return fn(state, $map, $map?.item, $map?.index);
|
|
2590
|
+
}
|
|
2531
2591
|
var _moduleCache = new Map;
|
|
2532
2592
|
async function resolveFunction(def2, state, key, base) {
|
|
2533
2593
|
if (def2.body && def2.$src) {
|
|
@@ -2924,16 +2984,33 @@ function reapplyStyle(el, styleDef, mediaQueries = {}, state = {}) {
|
|
|
2924
2984
|
delete el.dataset.jx;
|
|
2925
2985
|
applyStyle(el, styleDef ?? {}, mediaQueries, state);
|
|
2926
2986
|
}
|
|
2987
|
+
var ENUMERATED_ATTRS = new Set(["contenteditable", "draggable", "spellcheck"]);
|
|
2988
|
+
function booleanAttrValue(name, value) {
|
|
2989
|
+
const lower = name.toLowerCase();
|
|
2990
|
+
if (lower.startsWith("aria-") || ENUMERATED_ATTRS.has(lower)) {
|
|
2991
|
+
return String(value);
|
|
2992
|
+
}
|
|
2993
|
+
return value ? "" : null;
|
|
2994
|
+
}
|
|
2927
2995
|
function applyAttributes(el, attrs, state) {
|
|
2928
2996
|
for (const [k, v] of Object.entries(attrs)) {
|
|
2929
2997
|
const attr = canvasAttrName(el, k);
|
|
2930
2998
|
const write = (resolved) => {
|
|
2999
|
+
if (typeof resolved === "boolean") {
|
|
3000
|
+
const text = booleanAttrValue(attr, resolved);
|
|
3001
|
+
if (text === null) {
|
|
3002
|
+
el.removeAttribute(attr);
|
|
3003
|
+
} else {
|
|
3004
|
+
el.setAttribute(attr, text);
|
|
3005
|
+
}
|
|
3006
|
+
return;
|
|
3007
|
+
}
|
|
2931
3008
|
el.setAttribute(attr, canvasAssetValue(el.tagName, k, String(resolved ?? "")));
|
|
2932
3009
|
};
|
|
2933
3010
|
if (isRefObj(v)) {
|
|
2934
3011
|
effect(() => write(resolveRef(v.$ref, state)));
|
|
2935
3012
|
} else if (isTemplateString(v)) {
|
|
2936
|
-
effect(() => write(
|
|
3013
|
+
effect(() => write(evaluateAttrTemplate(v, state)));
|
|
2937
3014
|
} else {
|
|
2938
3015
|
write(v);
|
|
2939
3016
|
}
|
|
@@ -3610,41 +3687,9 @@ function mergeProps(def2, parentState) {
|
|
|
3610
3687
|
}
|
|
3611
3688
|
return child;
|
|
3612
3689
|
}
|
|
3613
|
-
function camelToKebab(s) {
|
|
3614
|
-
return s.replaceAll(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
3615
|
-
}
|
|
3616
3690
|
function toCSSText(rules) {
|
|
3617
3691
|
return Object.entries(rules).filter(([k, v]) => !isNestedSelector(k) && (v === null || typeof v !== "object")).map(([p, v]) => `${camelToKebab(p)}: ${canvasStyleValue(String(v))}`).join("; ");
|
|
3618
3692
|
}
|
|
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;
|
|
3629
|
-
}
|
|
3630
|
-
var COLOR_SCHEME_ATTR = "data-color-scheme";
|
|
3631
|
-
var COLOR_SCHEME_STORAGE_KEY = "jx-color-scheme";
|
|
3632
|
-
function pureSchemeOf(query) {
|
|
3633
|
-
const m = /^\(\s*prefers-color-scheme\s*:\s*(light|dark)\s*\)$/.exec(query.trim());
|
|
3634
|
-
return m?.[1] ?? null;
|
|
3635
|
-
}
|
|
3636
|
-
function schemeSelectors(selector, scheme) {
|
|
3637
|
-
if (selector === ":root" || selector === "html") {
|
|
3638
|
-
return {
|
|
3639
|
-
auto: `${selector}:where(:not([${COLOR_SCHEME_ATTR}]))`,
|
|
3640
|
-
forced: `${selector}:where([${COLOR_SCHEME_ATTR}="${scheme}"])`
|
|
3641
|
-
};
|
|
3642
|
-
}
|
|
3643
|
-
return {
|
|
3644
|
-
auto: `:where(:root:not([${COLOR_SCHEME_ATTR}])) ${selector}`,
|
|
3645
|
-
forced: `:where(:root[${COLOR_SCHEME_ATTR}="${scheme}"]) ${selector}`
|
|
3646
|
-
};
|
|
3647
|
-
}
|
|
3648
3693
|
var _rootMedia = {};
|
|
3649
3694
|
var _elementDefs = new Map;
|
|
3650
3695
|
function setRootMedia(map) {
|
|
@@ -3924,6 +3969,7 @@ export {
|
|
|
3924
3969
|
SUPPORTED_SCHEMA_VERSION,
|
|
3925
3970
|
_resetPrivatePropWarnings,
|
|
3926
3971
|
applyStyle,
|
|
3972
|
+
booleanAttrValue,
|
|
3927
3973
|
buildScope,
|
|
3928
3974
|
camelToKebab,
|
|
3929
3975
|
canvasStyleValue,
|
|
@@ -3931,6 +3977,7 @@ export {
|
|
|
3931
3977
|
elementStyleTags,
|
|
3932
3978
|
hasSchemaKeywords,
|
|
3933
3979
|
isSignal,
|
|
3980
|
+
isSingleExpression,
|
|
3934
3981
|
observeScope,
|
|
3935
3982
|
pureSchemeOf,
|
|
3936
3983
|
reapplyStyle,
|
|
@@ -3955,5 +4002,5 @@ export {
|
|
|
3955
4002
|
transposeCanvasUnits
|
|
3956
4003
|
};
|
|
3957
4004
|
|
|
3958
|
-
//# debugId=
|
|
4005
|
+
//# debugId=899C7FD9D6AF1F1D64756E2164756E21
|
|
3959
4006
|
//# sourceMappingURL=runtime.js.map
|