lightview 2.3.5 → 2.3.7
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/.gemini/XPATH_IMPLEMENTATION.md +186 -0
- package/1769196538097-package.json +43 -0
- package/_headers +5 -0
- package/_routes.json +7 -0
- package/build-bundles.mjs +10 -0
- package/build_tmp/lightview-router.js +185 -0
- package/build_tmp/lightview-x.js +1608 -0
- package/build_tmp/lightview.js +932 -0
- package/docs/articles/calculator-no-javascript-hackernoon.md +283 -0
- package/docs/articles/calculator-no-javascript.md +290 -0
- package/docs/articles/part1-reference.md +236 -0
- package/docs/calculator.cdomc +77 -0
- package/docs/calculator.css +316 -0
- package/docs/calculator.html +5 -410
- package/docs/cdom-nav.html +37 -31
- package/docs/cdom-xpath.html +160 -0
- package/docs/cdom.html +71 -12
- package/functions/_middleware.js +20 -3
- package/jprx/helpers/dom.js +69 -0
- package/jprx/helpers/logic.js +9 -3
- package/jprx/index.js +3 -1
- package/jprx/package.json +1 -1
- package/jprx/parser.js +363 -82
- package/lightview-all.js +476 -77
- package/lightview-cdom.js +474 -74
- package/lightview-x.js +4 -3
- package/lightview.js +10 -0
- package/package.json +2 -2
- package/src/lightview-cdom.js +185 -11
- package/src/lightview-x.js +5 -2
- package/src/lightview.js +16 -0
- package/test-xpath.html +63 -0
- package/test_error.txt +0 -0
- package/test_output.txt +0 -0
- package/test_output_full.txt +0 -0
- package/tests/cdom/operators.test.js +141 -0
- package/wrangler.toml +1 -0
- package/start-dev.js +0 -93
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
<script src="/lightview-router.js?base=/index.html"></script>
|
|
2
|
+
|
|
3
|
+
<div class="docs-layout">
|
|
4
|
+
<aside class="docs-sidebar" src="/docs/cdom-nav.html"></aside>
|
|
5
|
+
|
|
6
|
+
<main class="docs-content">
|
|
7
|
+
<h1>XPath Navigation in cDOM</h1>
|
|
8
|
+
<p class="text-secondary" style="font-size: 1.125rem;">
|
|
9
|
+
Navigate and derive element properties from the existing DOM structure.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<div class="experimental-notice"
|
|
13
|
+
style="margin: 1.5rem 0; padding: 1.25rem; border-radius: var(--site-radius); background: var(--site-accent-light); border: 1px solid var(--site-warning); color: var(--site-text);">
|
|
14
|
+
<div style="display: flex; gap: 0.75rem; align-items: flex-start;">
|
|
15
|
+
<span style="font-size: 1.5rem;">🚨</span>
|
|
16
|
+
<div>
|
|
17
|
+
<strong style="display: block; margin-bottom: 0.25rem; font-size: 1.1rem;">cDOM vs JPRX</strong>
|
|
18
|
+
<p style="margin: 0; font-size: 0.95rem; opacity: 0.9;">
|
|
19
|
+
Static XPaths are availbale to <strong>cDOM</strong> during the construction phase,
|
|
20
|
+
whereas <strong>JPRX</strong> has an <code>xpath</code> helper that returns a computed signal.
|
|
21
|
+
See <a href="/docs/cdom.html#helpers-dom">JPRX documentation</a> on the helper for more info
|
|
22
|
+
about xpath and reactivity.
|
|
23
|
+
</p>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<h2 id="overview">Overview</h2>
|
|
29
|
+
<p>
|
|
30
|
+
cDOM allows elements to derive their properties from the existing DOM tree. This can be done statically
|
|
31
|
+
for one-time setup or reactively for values that change over time.
|
|
32
|
+
</p>
|
|
33
|
+
<ol>
|
|
34
|
+
<li><strong>Static XPath (<code>#</code> prefix)</strong>: Available to cDOM. Evaluated once during DOM
|
|
35
|
+
construction.</li>
|
|
36
|
+
<li><strong>Reactive XPath (<code>=xpath()</code> helper)</strong>: Available to JPRX. Evaluates as an
|
|
37
|
+
expression and returns a computed signal.</li>
|
|
38
|
+
</ol>
|
|
39
|
+
|
|
40
|
+
<h2 id="static-xpath">Static XPath (<code>#</code> prefix)</h2>
|
|
41
|
+
<p>
|
|
42
|
+
Static XPath expressions are perfect for keeping your definitions <strong>DRY (Don't Repeat
|
|
43
|
+
Yourself)</strong>.
|
|
44
|
+
By referencing values like <code>id</code> or <code>class</code> from parent elements, you avoid duplicating
|
|
45
|
+
data in your cDOM structure.
|
|
46
|
+
</p>
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
<div id="xpath-live-demo" style="margin: 2rem 0;">
|
|
50
|
+
<p class="text-sm font-bold opacity-60 uppercase mb-3">Live Interactive Example</p>
|
|
51
|
+
<pre><script>
|
|
52
|
+
examplify(document.currentScript.nextElementSibling, {
|
|
53
|
+
at: document.currentScript.parentElement,
|
|
54
|
+
scripts: ['/lightview.js', '/lightview-x.js', '/lightview-cdom.js'],
|
|
55
|
+
type: 'module',
|
|
56
|
+
height: '180px',
|
|
57
|
+
autoRun: true
|
|
58
|
+
});
|
|
59
|
+
</script><code>await import('/lightview-cdom.js');
|
|
60
|
+
const { parseJPRX, hydrate } = globalThis.LightviewCDOM;
|
|
61
|
+
const { $ } = Lightview;
|
|
62
|
+
|
|
63
|
+
const cdom = `{
|
|
64
|
+
div: {
|
|
65
|
+
id: "profile-container",
|
|
66
|
+
class: "card",
|
|
67
|
+
"data-theme": "dark",
|
|
68
|
+
children: [
|
|
69
|
+
{ h3: "User Profile" },
|
|
70
|
+
{ button: {
|
|
71
|
+
id: "7",
|
|
72
|
+
// XPath #@id gets "7" from this button's id
|
|
73
|
+
// XPath #../@id gets "profile-container" from the parent div
|
|
74
|
+
children: ["Button ", #@id, " in section ", #../@id]
|
|
75
|
+
}}
|
|
76
|
+
]
|
|
77
|
+
}
|
|
78
|
+
}`;
|
|
79
|
+
|
|
80
|
+
$('#example').content(hydrate(parseJPRX(cdom)));</code></pre>
|
|
81
|
+
</div>
|
|
82
|
+
|
|
83
|
+
<h2 id="allowed-axes">Allowed Axes (Backward-Looking Only)</h2>
|
|
84
|
+
<p>
|
|
85
|
+
To maintain high performance and safety during construction, cDOM only allows
|
|
86
|
+
<strong>backward-looking</strong>
|
|
87
|
+
XPath axes. You can reference nodes that are already constructed (parents, ancestors, earlier siblings).
|
|
88
|
+
</p>
|
|
89
|
+
<table class="api-table">
|
|
90
|
+
<thead>
|
|
91
|
+
<tr>
|
|
92
|
+
<th>Axis</th>
|
|
93
|
+
<th>Result</th>
|
|
94
|
+
</tr>
|
|
95
|
+
</thead>
|
|
96
|
+
<tbody>
|
|
97
|
+
<tr>
|
|
98
|
+
<td><code>self::</code> / <code>.</code></td>
|
|
99
|
+
<td>The current node.</td>
|
|
100
|
+
</tr>
|
|
101
|
+
<tr>
|
|
102
|
+
<td><code>parent::</code> / <code>..</code></td>
|
|
103
|
+
<td>The parent element.</td>
|
|
104
|
+
</tr>
|
|
105
|
+
<tr>
|
|
106
|
+
<td><code>ancestor::</code></td>
|
|
107
|
+
<td>Higher-level ancestors.</td>
|
|
108
|
+
</tr>
|
|
109
|
+
<tr>
|
|
110
|
+
<td><code>preceding-sibling::</code></td>
|
|
111
|
+
<td>Elements that appear before the current one in the same parent.</td>
|
|
112
|
+
</tr>
|
|
113
|
+
</tbody>
|
|
114
|
+
</table>
|
|
115
|
+
<p class="text-warning">
|
|
116
|
+
<strong>Forbidden:</strong> <code>child::</code>, <code>descendant::</code>, and <code>following::</code>
|
|
117
|
+
axes are disabled as they could create infinite loops or reference nodes that do not exist yet.
|
|
118
|
+
</p>
|
|
119
|
+
|
|
120
|
+
<h2 id="reactive-xpath">Reactive XPath (<code>=xpath()</code>)</h2>
|
|
121
|
+
<p>
|
|
122
|
+
If you need an XPath expression to update reactively if attributes elsewhere in the DOM change,
|
|
123
|
+
use the <code>=xpath()</code> helper within a JPRX expression.
|
|
124
|
+
</p>
|
|
125
|
+
<div class="code-block">
|
|
126
|
+
<pre><code>{
|
|
127
|
+
div: {
|
|
128
|
+
title: "=xpath('../@data-section')",
|
|
129
|
+
class: "=concat('item ', xpath('../@theme'))"
|
|
130
|
+
}
|
|
131
|
+
}</code></pre>
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<h2 id="cdomc">Concise cDOM (cDOMC) Support</h2>
|
|
135
|
+
<p>
|
|
136
|
+
In cDOMC (the shorthand format used in <code>.cdomc</code> files), the parser is <strong>structurally
|
|
137
|
+
aware</strong>
|
|
138
|
+
of XPath expressions. You do not need to quote them even if they contain square brackets or spaces.
|
|
139
|
+
</p>
|
|
140
|
+
<div class="code-block">
|
|
141
|
+
<pre><code>// Clean unquoted syntax in .cdomc files
|
|
142
|
+
{
|
|
143
|
+
button: {
|
|
144
|
+
id: "7",
|
|
145
|
+
children: [#../@id]
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Support for complex paths with predicates
|
|
150
|
+
{ span: [#ancestor::div[@data-role='container']/@title] }</code></pre>
|
|
151
|
+
</div>
|
|
152
|
+
|
|
153
|
+
<h2 id="safety">Security & Safety</h2>
|
|
154
|
+
<p>
|
|
155
|
+
XPath navigation in cDOM is inherently safer than using arbitrary JavaScript for DOM traversal.
|
|
156
|
+
It provides a restricted, read-only view of the existing structural tree without the risks
|
|
157
|
+
of code injection or side effects.
|
|
158
|
+
</p>
|
|
159
|
+
</main>
|
|
160
|
+
</div>
|
package/docs/cdom.html
CHANGED
|
@@ -108,8 +108,9 @@
|
|
|
108
108
|
<p>
|
|
109
109
|
cDOM uses <strong>JPRX (JSON Pointer Reactive eXpressions)</strong> as its expression language. JPRX
|
|
110
110
|
extends <a href="https://www.rfc-editor.org/rfc/rfc6901" target="_blank">JSON Pointer (RFC 6901)</a>
|
|
111
|
-
with reactivity, relative paths, and helper functions.
|
|
112
|
-
|
|
111
|
+
with reactivity, relative paths, and helper functions. cDOM also supports <strong>standard XPath</strong>
|
|
112
|
+
for powerful DOM navigation during element construction. Together with deep integration for
|
|
113
|
+
<a href="https://json-schema.org/" target="_blank">JSON Schema</a> (Standard Draft 7+), cDOM provides
|
|
113
114
|
industrial-strength data validation and automatic type coercion.
|
|
114
115
|
</p>
|
|
115
116
|
|
|
@@ -156,8 +157,57 @@ $('#example').content(hydrate(parseJPRX(cdom)));</code></pre>
|
|
|
156
157
|
<p>
|
|
157
158
|
The UI automatically updates whenever <code>count</code> changes — no manual DOM manipulation required.
|
|
158
159
|
</p>
|
|
160
|
+
|
|
161
|
+
<!-- ===== XPATH NAVIGATION ===== -->
|
|
162
|
+
<h2 id="xpath-navigation">Using XPath</h2>
|
|
159
163
|
<p>
|
|
160
|
-
|
|
164
|
+
cDOM allows elements to navigate and reference the DOM structure during construction using standard
|
|
165
|
+
<strong>XPath</strong>. This is strictly a <strong>cDOM feature</strong> (not JPRX) used for structural
|
|
166
|
+
navigation.
|
|
167
|
+
</p>
|
|
168
|
+
<p>
|
|
169
|
+
XPath is incredibly useful for keeping your definitions <strong>DRY (Don't Repeat Yourself)</strong> by
|
|
170
|
+
referencing existing attributes instead of repeating values.
|
|
171
|
+
</p>
|
|
172
|
+
<div id="xpath-demo">
|
|
173
|
+
<pre><script>
|
|
174
|
+
examplify(document.currentScript.nextElementSibling, {
|
|
175
|
+
at: document.currentScript.parentElement,
|
|
176
|
+
scripts: ['/lightview.js', '/lightview-x.js', '/lightview-cdom.js'],
|
|
177
|
+
type: 'module',
|
|
178
|
+
height: '180px',
|
|
179
|
+
autoRun: true,
|
|
180
|
+
controls: false
|
|
181
|
+
});
|
|
182
|
+
</script><code>await import('/lightview-cdom.js');
|
|
183
|
+
const { parseJPRX, hydrate } = globalThis.LightviewCDOM;
|
|
184
|
+
const { $ } = Lightview;
|
|
185
|
+
|
|
186
|
+
const cdom = `{
|
|
187
|
+
div: {
|
|
188
|
+
id: "profile-container",
|
|
189
|
+
class: "card",
|
|
190
|
+
"data-theme": "dark",
|
|
191
|
+
children: [
|
|
192
|
+
{ h3: "User Profile" },
|
|
193
|
+
{ button: {
|
|
194
|
+
id: "7",
|
|
195
|
+
// XPath #../@id gets the "7" from this button's id
|
|
196
|
+
// XPath #../../@id gets "profile-container" from the g-parent div
|
|
197
|
+
children: ["Button ", #../@id, " in section ", #../../@id]
|
|
198
|
+
}}
|
|
199
|
+
]
|
|
200
|
+
}
|
|
201
|
+
}`;
|
|
202
|
+
|
|
203
|
+
$('#example').content(hydrate(parseJPRX(cdom)));</code></pre>
|
|
204
|
+
</div>
|
|
205
|
+
<p>
|
|
206
|
+
In the example above, the button's text is derived entirely from its own <code>id</code> and its
|
|
207
|
+
parent's <code>id</code> using <code>#../@id</code> and <code>#../../@id</code>.
|
|
208
|
+
</p>
|
|
209
|
+
<p>
|
|
210
|
+
For more details, see the <a href="/docs/cdom-xpath.html">Full XPath Documentation</a>.
|
|
161
211
|
</p>
|
|
162
212
|
|
|
163
213
|
<!-- ===== ADVANTAGES ===== -->
|
|
@@ -596,7 +646,7 @@ const cdomString = `{
|
|
|
596
646
|
children: [
|
|
597
647
|
{ h3: "Shopping Cart" },
|
|
598
648
|
{ ul: {
|
|
599
|
-
children: =map(/store/cart/items, { li: { children: [_/name, " - ",
|
|
649
|
+
children: =map(/store/cart/items, { li: { children: [_/name, " - ", currency(_/price)] } })
|
|
600
650
|
}},
|
|
601
651
|
{ p: {
|
|
602
652
|
style: "font-weight: bold; margin-top: 1rem;",
|
|
@@ -1007,10 +1057,22 @@ const liveConfig = LightviewCDOM.hydrate(config);</code></pre>
|
|
|
1007
1057
|
|
|
1008
1058
|
<h3 id="helpers-network">Network</h3>
|
|
1009
1059
|
<p>HTTP requests.</p>
|
|
1010
|
-
<div class="code-block">
|
|
1060
|
+
<div class="code-block" style="margin-bottom: 2rem;">
|
|
1011
1061
|
<pre><code>fetch(url, options?)
|
|
1012
1062
|
<span id="helpers-mount"></span>mount(url, options?)</span></code></pre>
|
|
1013
1063
|
</div>
|
|
1064
|
+
|
|
1065
|
+
<h3 id="helpers-dom">DOM & XPath</h3>
|
|
1066
|
+
<p>Structural navigation and manipulation.</p>
|
|
1067
|
+
<div class="code-block">
|
|
1068
|
+
<pre><code>move(selector, location?), xpath(expression)</code></pre>
|
|
1069
|
+
</div>
|
|
1070
|
+
<p style="margin-top: 1rem;">
|
|
1071
|
+
The <code>src</code> attribute handler is the primary mechanism for Hypermedia updates. It fetches
|
|
1072
|
+
content
|
|
1073
|
+
(cDOM, vDOM, or oDOM) and injects it into the DOM. If the content contains a <code>=move</code>
|
|
1074
|
+
helper, it will automatically relocate itself upon mounting.
|
|
1075
|
+
</p>
|
|
1014
1076
|
<table class="api-table">
|
|
1015
1077
|
<thead>
|
|
1016
1078
|
<tr>
|
|
@@ -1049,13 +1111,10 @@ const liveConfig = LightviewCDOM.hydrate(config);</code></pre>
|
|
|
1049
1111
|
</tr>
|
|
1050
1112
|
</tbody>
|
|
1051
1113
|
</table>
|
|
1052
|
-
<p style="margin-top:
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1114
|
+
<p class="text-xs italic opacity-70" style="margin-top: 0.5rem;">
|
|
1115
|
+
<strong>xpath(expression):</strong> Returns a reactive computed signal based on the DOM structure
|
|
1116
|
+
at evaluation time. Note that full MutationObserver reactivity is currently a TODO.
|
|
1117
|
+
For static DOM navigation, use the <code>#</code> prefix in cDOM.
|
|
1056
1118
|
</p>
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
1119
|
</main>
|
|
1061
1120
|
</div>
|
package/functions/_middleware.js
CHANGED
|
@@ -1,13 +1,30 @@
|
|
|
1
1
|
import { marked } from 'marked';
|
|
2
|
-
import { processServerScripts } from './processServerScripts.js';
|
|
2
|
+
//import { processServerScripts } from './processServerScripts.js';
|
|
3
3
|
|
|
4
4
|
export const onRequest = async (context) => {
|
|
5
5
|
const url = new URL(context.request.url);
|
|
6
6
|
const isMd = url.pathname.endsWith('.md');
|
|
7
7
|
const isHtml = url.pathname.endsWith('.html') || (url.pathname.endsWith('/') && !url.pathname.includes('.'));
|
|
8
|
+
const isCdom = url.pathname.endsWith('.cdom');
|
|
9
|
+
console.log(`[Middleware] Processing: ${url.pathname}`);
|
|
10
|
+
// Intercept requests for .cdom files to set correct Content-Type
|
|
11
|
+
if (isCdom) {
|
|
12
|
+
console.log(`[Middleware] Processing: ${url.pathname}`);
|
|
13
|
+
const response = await context.next();
|
|
14
|
+
if (response.ok) {
|
|
15
|
+
const text = await response.text();
|
|
16
|
+
return new Response(text, {
|
|
17
|
+
status: 200,
|
|
18
|
+
headers: {
|
|
19
|
+
'content-type': 'text/plain; charset=utf-8',
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return response;
|
|
24
|
+
}
|
|
8
25
|
|
|
9
26
|
// Intercept requests for .md and .html files
|
|
10
|
-
if (isMd || isHtml
|
|
27
|
+
if (isMd) { // || isHtml
|
|
11
28
|
console.log(`[Middleware] Processing: ${url.pathname}`);
|
|
12
29
|
|
|
13
30
|
// Fetch the asset (the actual file)
|
|
@@ -23,7 +40,7 @@ export const onRequest = async (context) => {
|
|
|
23
40
|
}
|
|
24
41
|
|
|
25
42
|
// 2. Process Server-Side Scripts (runat="server")
|
|
26
|
-
processedHtml = await processServerScripts(processedHtml, context.request);
|
|
43
|
+
//processedHtml = await processServerScripts(processedHtml, context.request);
|
|
27
44
|
|
|
28
45
|
return new Response(processedHtml, {
|
|
29
46
|
status: 200,
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM-related JPRX helpers for navigating and querying the DOM structure.
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Registers DOM-related helpers including the xpath() helper.
|
|
7
|
+
* @param {Function} registerHelper - The helper registration function
|
|
8
|
+
*/
|
|
9
|
+
export const registerDOMHelpers = (registerHelper) => {
|
|
10
|
+
/**
|
|
11
|
+
* Evaluates an XPath expression against the current DOM element.
|
|
12
|
+
* Returns a computed signal that re-evaluates when observed nodes change.
|
|
13
|
+
* Only supports backward-looking axes (parent, ancestor, preceding-sibling, etc.)
|
|
14
|
+
*
|
|
15
|
+
* @param {string} expression - The XPath expression to evaluate
|
|
16
|
+
* @param {object} context - The evaluation context (contains __node__)
|
|
17
|
+
* @returns {any} The result of the XPath evaluation
|
|
18
|
+
*/
|
|
19
|
+
registerHelper('xpath', function (expression) {
|
|
20
|
+
const domNode = this; // 'this' is bound to the DOM element
|
|
21
|
+
|
|
22
|
+
if (!domNode || !(domNode instanceof Element)) {
|
|
23
|
+
console.warn('[Lightview-CDOM] xpath() called without valid DOM context');
|
|
24
|
+
return '';
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Validate the expression (no forward-looking axes)
|
|
28
|
+
const forbiddenAxes = /\b(child|descendant|following|following-sibling)::/;
|
|
29
|
+
if (forbiddenAxes.test(expression)) {
|
|
30
|
+
console.error(`[Lightview-CDOM] xpath(): Forward-looking axes not allowed: ${expression}`);
|
|
31
|
+
return '';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const hasShorthandChild = /\/[a-zA-Z]/.test(expression) && !expression.startsWith('/html');
|
|
35
|
+
if (hasShorthandChild) {
|
|
36
|
+
console.error(`[Lightview-CDOM] xpath(): Shorthand child axis (/) not allowed: ${expression}`);
|
|
37
|
+
return '';
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Get Lightview's computed function
|
|
41
|
+
const LV = globalThis.Lightview;
|
|
42
|
+
if (!LV || !LV.computed) {
|
|
43
|
+
console.warn('[Lightview-CDOM] xpath(): Lightview not available');
|
|
44
|
+
return '';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Return a computed signal that evaluates the XPath
|
|
48
|
+
return LV.computed(() => {
|
|
49
|
+
try {
|
|
50
|
+
const result = document.evaluate(
|
|
51
|
+
expression,
|
|
52
|
+
domNode,
|
|
53
|
+
null,
|
|
54
|
+
XPathResult.STRING_TYPE,
|
|
55
|
+
null
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
// TODO: Set up MutationObserver for reactivity
|
|
59
|
+
// For now, this just evaluates once
|
|
60
|
+
// Future: Observe parent/ancestor/sibling changes
|
|
61
|
+
|
|
62
|
+
return result.stringValue;
|
|
63
|
+
} catch (e) {
|
|
64
|
+
console.error(`[Lightview-CDOM] xpath() evaluation failed:`, e.message);
|
|
65
|
+
return '';
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}, { pathAware: false });
|
|
69
|
+
};
|
package/jprx/helpers/logic.js
CHANGED
|
@@ -6,8 +6,10 @@ export const ifHelper = (condition, thenVal, elseVal) => condition ? thenVal : e
|
|
|
6
6
|
export const andHelper = (...args) => args.every(Boolean);
|
|
7
7
|
export const orHelper = (...args) => args.some(Boolean);
|
|
8
8
|
export const notHelper = (val) => !val;
|
|
9
|
-
export const eqHelper = (a, b) => a
|
|
10
|
-
export const
|
|
9
|
+
export const eqHelper = (a, b) => a == b;
|
|
10
|
+
export const strictEqHelper = (a, b) => a === b;
|
|
11
|
+
export const neqHelper = (a, b) => a != b;
|
|
12
|
+
export const strictNeqHelper = (a, b) => a !== b;
|
|
11
13
|
|
|
12
14
|
export const registerLogicHelpers = (register) => {
|
|
13
15
|
register('if', ifHelper);
|
|
@@ -18,7 +20,11 @@ export const registerLogicHelpers = (register) => {
|
|
|
18
20
|
register('not', notHelper);
|
|
19
21
|
register('!', notHelper);
|
|
20
22
|
register('eq', eqHelper);
|
|
23
|
+
register('strictEq', strictEqHelper);
|
|
21
24
|
register('==', eqHelper);
|
|
22
|
-
register('===',
|
|
25
|
+
register('===', strictEqHelper);
|
|
23
26
|
register('neq', neqHelper);
|
|
27
|
+
register('strictNeq', strictNeqHelper);
|
|
28
|
+
register('!=', neqHelper);
|
|
29
|
+
register('!==', strictNeqHelper);
|
|
24
30
|
};
|
package/jprx/index.js
CHANGED
|
@@ -19,7 +19,8 @@ export {
|
|
|
19
19
|
resolvePathAsContext,
|
|
20
20
|
resolveExpression,
|
|
21
21
|
parseCDOMC,
|
|
22
|
-
parseJPRX,
|
|
22
|
+
parseCDOMC as parseJPRX,
|
|
23
|
+
parseJPRX as oldParseJPRX,
|
|
23
24
|
unwrapSignal,
|
|
24
25
|
getRegistry,
|
|
25
26
|
BindingTarget
|
|
@@ -39,6 +40,7 @@ export { registerStatsHelpers } from './helpers/stats.js';
|
|
|
39
40
|
export { registerStateHelpers, set } from './helpers/state.js';
|
|
40
41
|
export { registerNetworkHelpers } from './helpers/network.js';
|
|
41
42
|
export { registerCalcHelpers, calc } from './helpers/calc.js';
|
|
43
|
+
export { registerDOMHelpers } from './helpers/dom.js';
|
|
42
44
|
|
|
43
45
|
// Convenience function to register all standard helpers
|
|
44
46
|
export const registerAllHelpers = (registerFn) => {
|