mancha 0.17.0 → 0.17.4
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/.github/workflows/ci.yml +11 -10
- package/.prettierrc +2 -2
- package/.vscode/extensions.json +1 -1
- package/.vscode/launch.json +33 -43
- package/README.md +144 -84
- package/dist/browser.d.ts +2 -0
- package/dist/browser.js +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/css_gen_basic.js.map +1 -1
- package/dist/css_gen_utils.d.ts +786 -0
- package/dist/css_gen_utils.js +350 -399
- package/dist/css_gen_utils.js.map +1 -1
- package/dist/dome.d.ts +1 -0
- package/dist/dome.js +15 -0
- package/dist/dome.js.map +1 -1
- package/dist/expressions/ast.d.ts +16 -16
- package/dist/expressions/ast.test.js +89 -64
- package/dist/expressions/ast.test.js.map +1 -1
- package/dist/expressions/ast_factory.d.ts +1 -1
- package/dist/expressions/ast_factory.js +17 -17
- package/dist/expressions/ast_factory.js.map +1 -1
- package/dist/expressions/ast_factory.test.js +42 -36
- package/dist/expressions/ast_factory.test.js.map +1 -1
- package/dist/expressions/constants.js +56 -56
- package/dist/expressions/constants.js.map +1 -1
- package/dist/expressions/constants.test.js +57 -57
- package/dist/expressions/constants.test.js.map +1 -1
- package/dist/expressions/eval.d.ts +17 -17
- package/dist/expressions/eval.js +58 -60
- package/dist/expressions/eval.js.map +1 -1
- package/dist/expressions/eval.test.js +11 -8
- package/dist/expressions/eval.test.js.map +1 -1
- package/dist/expressions/expressions.test.d.ts +6 -6
- package/dist/expressions/expressions.test.js +6 -6
- package/dist/expressions/index.d.ts +6 -6
- package/dist/expressions/index.js +6 -6
- package/dist/expressions/parser.d.ts +3 -3
- package/dist/expressions/parser.js +45 -45
- package/dist/expressions/parser.js.map +1 -1
- package/dist/expressions/parser.test.js +43 -2
- package/dist/expressions/parser.test.js.map +1 -1
- package/dist/expressions/tokenizer.js +22 -25
- package/dist/expressions/tokenizer.js.map +1 -1
- package/dist/expressions/tokenizer.test.js +40 -15
- package/dist/expressions/tokenizer.test.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +1 -1
- package/dist/iterator.js.map +1 -1
- package/dist/mancha.js +1 -1
- package/dist/mancha.js.map +1 -1
- package/dist/plugins.js +96 -25
- package/dist/plugins.js.map +1 -1
- package/dist/query.js.map +1 -1
- package/dist/renderer.js +4 -2
- package/dist/renderer.js.map +1 -1
- package/dist/safe_browser.js +1 -1
- package/dist/safe_browser.js.map +1 -1
- package/dist/store.d.ts +10 -4
- package/dist/store.js +26 -10
- package/dist/store.js.map +1 -1
- package/dist/test_utils.d.ts +2 -0
- package/dist/test_utils.js +14 -1
- package/dist/test_utils.js.map +1 -1
- package/dist/trusted_attributes.js +2 -0
- package/dist/trusted_attributes.js.map +1 -1
- package/dist/type_checker.js +57 -22
- package/dist/type_checker.js.map +1 -1
- package/dist/worker.d.ts +2 -0
- package/dist/worker.js +1 -0
- package/dist/worker.js.map +1 -1
- package/docs/css.md +309 -0
- package/docs/quickstart.md +414 -241
- package/global.d.ts +2 -2
- package/gulpfile.ts +44 -0
- package/package.json +86 -84
- package/scripts/generate-css-docs.ts +263 -0
- package/tsconfig.json +42 -19
- package/tsec_exemptions.json +8 -3
- package/webpack.config.esmodule.ts +26 -0
- package/webpack.config.ts +21 -0
- package/gulpfile.js +0 -44
- package/webpack.config.esmodule.js +0 -23
- package/webpack.config.js +0 -18
package/.github/workflows/ci.yml
CHANGED
|
@@ -5,12 +5,12 @@ on:
|
|
|
5
5
|
branches:
|
|
6
6
|
- main
|
|
7
7
|
tags:
|
|
8
|
-
-
|
|
8
|
+
- "v*"
|
|
9
9
|
|
|
10
10
|
permissions:
|
|
11
11
|
contents: read
|
|
12
12
|
pages: write
|
|
13
|
-
id-token: write
|
|
13
|
+
id-token: write # Required for GitHub Pages and npm OIDC trusted publishing
|
|
14
14
|
|
|
15
15
|
concurrency:
|
|
16
16
|
group: "pages"
|
|
@@ -27,8 +27,8 @@ jobs:
|
|
|
27
27
|
- name: Setup Node.js
|
|
28
28
|
uses: actions/setup-node@v4
|
|
29
29
|
with:
|
|
30
|
-
node-version:
|
|
31
|
-
registry-url:
|
|
30
|
+
node-version: "24"
|
|
31
|
+
registry-url: "https://registry.npmjs.org"
|
|
32
32
|
|
|
33
33
|
- name: Install dependencies
|
|
34
34
|
run: npm ci
|
|
@@ -77,6 +77,9 @@ jobs:
|
|
|
77
77
|
runs-on: ubuntu-latest
|
|
78
78
|
name: Publish to NPM
|
|
79
79
|
if: startsWith(github.ref, 'refs/tags/v')
|
|
80
|
+
permissions:
|
|
81
|
+
contents: read
|
|
82
|
+
id-token: write # Required for npm OIDC trusted publishing
|
|
80
83
|
steps:
|
|
81
84
|
- name: Checkout code
|
|
82
85
|
uses: actions/checkout@v4
|
|
@@ -84,8 +87,8 @@ jobs:
|
|
|
84
87
|
- name: Setup Node.js
|
|
85
88
|
uses: actions/setup-node@v4
|
|
86
89
|
with:
|
|
87
|
-
node-version:
|
|
88
|
-
registry-url:
|
|
90
|
+
node-version: "24"
|
|
91
|
+
registry-url: "https://registry.npmjs.org"
|
|
89
92
|
|
|
90
93
|
- name: Install dependencies
|
|
91
94
|
run: npm ci
|
|
@@ -96,7 +99,5 @@ jobs:
|
|
|
96
99
|
name: build-artifacts
|
|
97
100
|
path: dist/
|
|
98
101
|
|
|
99
|
-
- name: Publish to NPM
|
|
100
|
-
run: npm publish
|
|
101
|
-
env:
|
|
102
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
102
|
+
- name: Publish to NPM with provenance
|
|
103
|
+
run: npm publish --provenance --access public
|
package/.prettierrc
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
}
|
|
2
|
+
"printWidth": 100
|
|
3
|
+
}
|
package/.vscode/extensions.json
CHANGED
package/.vscode/launch.json
CHANGED
|
@@ -1,44 +1,34 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"${file}"
|
|
36
|
-
],
|
|
37
|
-
"console": "integratedTerminal",
|
|
38
|
-
"internalConsoleOptions": "neverOpen",
|
|
39
|
-
"skipFiles": [
|
|
40
|
-
"<node_internals>/**/*.js"
|
|
41
|
-
]
|
|
42
|
-
}
|
|
43
|
-
]
|
|
44
|
-
}
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"name": "Mocha All",
|
|
9
|
+
"type": "node",
|
|
10
|
+
"request": "launch",
|
|
11
|
+
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
|
|
12
|
+
"args": [
|
|
13
|
+
"-r",
|
|
14
|
+
"ts-node/register",
|
|
15
|
+
"--no-timeouts",
|
|
16
|
+
"--colors",
|
|
17
|
+
"${workspaceFolder}/dist/**/*.test.ts"
|
|
18
|
+
],
|
|
19
|
+
"console": "integratedTerminal",
|
|
20
|
+
"internalConsoleOptions": "neverOpen",
|
|
21
|
+
"skipFiles": ["<node_internals>/**/*.js"]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "Mocha Current File",
|
|
25
|
+
"type": "node",
|
|
26
|
+
"request": "launch",
|
|
27
|
+
"program": "${workspaceFolder}/node_modules/mocha/bin/_mocha",
|
|
28
|
+
"args": ["-r", "ts-node/register", "--no-timeouts", "--colors", "${file}"],
|
|
29
|
+
"console": "integratedTerminal",
|
|
30
|
+
"internalConsoleOptions": "neverOpen",
|
|
31
|
+
"skipFiles": ["<node_internals>/**/*.js"]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
package/README.md
CHANGED
|
@@ -11,25 +11,25 @@ Here's a small sample of the things that you can do with `mancha`:
|
|
|
11
11
|
|
|
12
12
|
<!-- Scoped variables using the `:data` attribute. -->
|
|
13
13
|
<main class="p-4" :data="{count: 0, name: 'Stranger'}">
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
14
|
+
<!-- Custom HTML tag element registration. -->
|
|
15
|
+
<template is="counter">
|
|
16
|
+
<div>
|
|
17
|
+
<slot></slot>
|
|
18
|
+
<button :on:click="count = count + 1">Counter: {{ count }}</button>
|
|
19
|
+
</div>
|
|
20
|
+
</template>
|
|
21
|
+
|
|
22
|
+
<!-- Custom HTML tag element usage. -->
|
|
23
|
+
<counter class="my-2">Click me:</counter>
|
|
24
|
+
|
|
25
|
+
<!-- Reactive data binding. -->
|
|
26
|
+
<p>Enter your name: <input type="text" :bind="name" /></p>
|
|
27
|
+
<p>Hello, <span class="underline">{{ name }}</span>!</p>
|
|
28
|
+
|
|
29
|
+
<!-- Include HTML partials. -->
|
|
30
|
+
<footer class="text-xs">
|
|
31
|
+
<include src="html/partial/footer.tpl.html"></include>
|
|
32
|
+
</footer>
|
|
33
33
|
</main>
|
|
34
34
|
```
|
|
35
35
|
|
|
@@ -79,12 +79,12 @@ preprocessing consist of:
|
|
|
79
79
|
|
|
80
80
|
<!-- ./index.html -->
|
|
81
81
|
<div>
|
|
82
|
-
|
|
82
|
+
<include src="button.tpl.html"></include>
|
|
83
83
|
</div>
|
|
84
84
|
|
|
85
85
|
<!-- Result after rendering `index.html`. -->
|
|
86
86
|
<div>
|
|
87
|
-
|
|
87
|
+
<button>Click Me</button>
|
|
88
88
|
</div>
|
|
89
89
|
```
|
|
90
90
|
|
|
@@ -93,15 +93,15 @@ preprocessing consist of:
|
|
|
93
93
|
```html
|
|
94
94
|
<!-- Use <template is="my-component-name"> to register a component. -->
|
|
95
95
|
<template is="my-red-button">
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
96
|
+
<button style="background-color: red;">
|
|
97
|
+
<slot></slot>
|
|
98
|
+
</button>
|
|
99
99
|
</template>
|
|
100
100
|
|
|
101
101
|
<!-- Any node traversed after registration can use the component. -->
|
|
102
102
|
<my-red-button :on:click="console.log('clicked')">
|
|
103
|
-
|
|
104
|
-
|
|
103
|
+
<!-- The contents within will replace the `<slot></slot>` tag. -->
|
|
104
|
+
Click Me
|
|
105
105
|
</my-red-button>
|
|
106
106
|
```
|
|
107
107
|
|
|
@@ -138,7 +138,7 @@ element tag or attributes match a specific criteria. Here's the list of attribut
|
|
|
138
138
|
- `:bind` binds (two-way) a variable to the `value` or `checked` property of the element
|
|
139
139
|
```html
|
|
140
140
|
<div :data="{ name: 'Stranger' }">
|
|
141
|
-
|
|
141
|
+
<input type="text" :bind="name" />
|
|
142
142
|
</div>
|
|
143
143
|
```
|
|
144
144
|
- `:on:{event}` adds an event listener for `event` to the node
|
|
@@ -157,6 +157,17 @@ element tag or attributes match a specific criteria. Here's the list of attribut
|
|
|
157
157
|
```html
|
|
158
158
|
<video :prop:src="buildSrc()"></video>
|
|
159
159
|
```
|
|
160
|
+
- `:render` links an element to a JavaScript ES module for initialization
|
|
161
|
+
```html
|
|
162
|
+
<canvas :render="./chart-init.js"></canvas>
|
|
163
|
+
```
|
|
164
|
+
The module's default export is called with the element and renderer:
|
|
165
|
+
```js
|
|
166
|
+
// chart-init.js
|
|
167
|
+
export default function (elem, renderer) {
|
|
168
|
+
new Chart(elem, { type: "bar" });
|
|
169
|
+
}
|
|
170
|
+
```
|
|
160
171
|
- `{{ value }}` replaces `value` in text nodes
|
|
161
172
|
```html
|
|
162
173
|
<button :data="{label: 'Click Me'}">{{ label }}</button>
|
|
@@ -164,7 +175,7 @@ element tag or attributes match a specific criteria. Here's the list of attribut
|
|
|
164
175
|
- `:types` **(experimental)** declares TypeScript types for static type checking
|
|
165
176
|
```html
|
|
166
177
|
<div :types='{"user": "@import:./types/user.ts:User"}'>
|
|
167
|
-
|
|
178
|
+
<span>{{ user.name.toUpperCase() }}</span>
|
|
168
179
|
</div>
|
|
169
180
|
```
|
|
170
181
|
The value of `:types` is parsed with `jexpr` during static analysis. It must evaluate to a plain
|
|
@@ -184,51 +195,51 @@ operator, and arrow functions. For example:
|
|
|
184
195
|
```html
|
|
185
196
|
<!-- Valid expression: string concatenation -->
|
|
186
197
|
<body :data="{ pos: 1 }">
|
|
187
|
-
|
|
198
|
+
<p :text="'you are number ' + pos + ' in the queue'"></p>
|
|
188
199
|
</body>
|
|
189
200
|
|
|
190
201
|
<!-- Valid expression: optional chaining -->
|
|
191
202
|
<body :data="{ user: null }">
|
|
192
|
-
|
|
203
|
+
<p :text="user?.name ?? 'Anonymous'"></p>
|
|
193
204
|
</body>
|
|
194
205
|
|
|
195
206
|
<!-- Valid expression: spread operator -->
|
|
196
207
|
<body :data="{ list: [1, 2], extra: 3 }">
|
|
197
|
-
|
|
208
|
+
<div :for="item in [...list, extra]">{{ item }}</div>
|
|
198
209
|
</body>
|
|
199
210
|
|
|
200
211
|
<!-- Valid expression: arrow functions (e.g. in map) -->
|
|
201
212
|
<body :data="{ items: [1, 2, 3] }">
|
|
202
|
-
|
|
213
|
+
<div :for="n in items.map((x) => x * 2)">{{ n }}</div>
|
|
203
214
|
</body>
|
|
204
215
|
|
|
205
216
|
<!-- Valid expression: boolean logic -->
|
|
206
217
|
<body :data="{ pos: 1, finished: false }">
|
|
207
|
-
|
|
218
|
+
<p :show="pos >= 1 && !finished">you are number {{ pos }} in the queue</p>
|
|
208
219
|
</body>
|
|
209
220
|
|
|
210
221
|
<!-- Valid expression: ternary operators -->
|
|
211
222
|
<body :data="{ pos: 1 }">
|
|
212
|
-
|
|
223
|
+
<p :text="pos % 2 == 0 ? 'even' : 'odd'"></p>
|
|
213
224
|
</body>
|
|
214
225
|
|
|
215
226
|
<!-- Valid expression: function calling -->
|
|
216
227
|
<body :data="{ pos : 1 }">
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
228
|
+
<p :text="buildQueueMessage()"></p>
|
|
229
|
+
<script>
|
|
230
|
+
const { $ } = Mancha;
|
|
231
|
+
$.buildQueueMessage = function () {
|
|
232
|
+
return "you are number " + this.pos + " in the queue";
|
|
233
|
+
};
|
|
234
|
+
// Alternatively, anonymous functions without `this`:
|
|
235
|
+
// $.buildQueueMessage = () => 'you are number ' + $.pos + ' in the queue';
|
|
236
|
+
</script>
|
|
226
237
|
</body>
|
|
227
238
|
|
|
228
239
|
<!-- Valid expression: simple assignment -->
|
|
229
240
|
<body :data="{ pos: 1 }">
|
|
230
|
-
|
|
231
|
-
|
|
241
|
+
<p :text="'you are number ' + pos + ' in the queue'"></p>
|
|
242
|
+
<button :on:click="pos = pos + 1">Click to get there faster</button>
|
|
232
243
|
</body>
|
|
233
244
|
|
|
234
245
|
<!-- Invalid expression: multiple statements -->
|
|
@@ -236,7 +247,7 @@ operator, and arrow functions. For example:
|
|
|
236
247
|
|
|
237
248
|
<!-- Invalid expression: function definition (top-level) -->
|
|
238
249
|
<body :data="{ foo: function() { return 'yes'; } }">
|
|
239
|
-
|
|
250
|
+
<p :text="foo()"></p>
|
|
240
251
|
</body>
|
|
241
252
|
```
|
|
242
253
|
|
|
@@ -247,24 +258,26 @@ illustrated with an example:
|
|
|
247
258
|
|
|
248
259
|
```html
|
|
249
260
|
<body :data="{ name: 'stranger', key: '1234' }">
|
|
250
|
-
|
|
251
|
-
|
|
261
|
+
<!-- Hello, stranger -->
|
|
262
|
+
<h1>Hello, {{ name }}</h1>
|
|
252
263
|
|
|
253
|
-
|
|
254
|
-
|
|
264
|
+
<!-- Initially "undefined", but reactive to later changes -->
|
|
265
|
+
<span>{{ message }}</span>
|
|
255
266
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
267
|
+
<!-- How are you, danger? The secret message is "secret" and the key is "1234" -->
|
|
268
|
+
<p :data="{ name: 'danger', message: 'secret' }">
|
|
269
|
+
How are you, {{ name }}? The secret message is "{{ message }}" and the key is "{{ key }}"
|
|
270
|
+
</p>
|
|
260
271
|
</body>
|
|
261
272
|
```
|
|
262
273
|
|
|
263
274
|
By default, the target root element is the `body` tag. So, any variables defined in the body's
|
|
264
275
|
`:data` attribute are available to the main renderer.
|
|
265
276
|
|
|
266
|
-
In the example above, the
|
|
267
|
-
|
|
277
|
+
In the example above, the `<span>` references `message` which is not defined in the body's `:data`.
|
|
278
|
+
This auto-initializes `message` to `undefined` and attaches an observer, so setting `$.message`
|
|
279
|
+
later will update the `<span>` content. The `<p>` tag has its own local `message` variable which
|
|
280
|
+
shadows any parent value. Since the variables are not accessible via the global object, you'll need
|
|
268
281
|
to retrieve the renderer from the element's properties:
|
|
269
282
|
|
|
270
283
|
```js
|
|
@@ -275,8 +288,9 @@ await $.mount(document.body);
|
|
|
275
288
|
// This modifies the `name` variable in all the renderer contexts.
|
|
276
289
|
$.name = "world";
|
|
277
290
|
|
|
278
|
-
// This
|
|
279
|
-
//
|
|
291
|
+
// This updates the `<span>` content to "bandit" because `message` was
|
|
292
|
+
// auto-initialized when the template referenced it. However, the `<p>` tag
|
|
293
|
+
// still shows "secret" because it has its own local `message` variable.
|
|
280
294
|
$.message = "bandit";
|
|
281
295
|
|
|
282
296
|
// We extract the subrenderer from the element's properties. Only elements
|
|
@@ -289,15 +303,61 @@ subrenderer.$.message = "banana";
|
|
|
289
303
|
|
|
290
304
|
When accessing variables, `mancha` searches the current renderer first, then the parent, the
|
|
291
305
|
parent's parent, and so forth until the root renderer is reached. If the requested variable is not
|
|
292
|
-
found in the current renderer or any of the ancestor renderers, then `
|
|
306
|
+
found in the current renderer or any of the ancestor renderers, then `undefined` is returned:
|
|
293
307
|
|
|
294
308
|
```html
|
|
295
309
|
<body :data="{ name: 'stranger' }">
|
|
296
|
-
|
|
297
|
-
|
|
310
|
+
<!-- Hello, stranger! -->
|
|
311
|
+
<p :data="{}">Hello, {{ name }}!</p>
|
|
312
|
+
</body>
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Reactive Undefined Variables
|
|
316
|
+
|
|
317
|
+
When a variable is referenced in a template expression but not yet defined, `mancha` automatically
|
|
318
|
+
initializes it to `undefined` and attaches an observer. This means you can set the variable later
|
|
319
|
+
using the same renderer (or a subrenderer) and the template will reactively update:
|
|
320
|
+
|
|
321
|
+
```html
|
|
322
|
+
<body>
|
|
323
|
+
<!-- Initially shows "undefined", but updates reactively when `message` is set -->
|
|
324
|
+
<p>{{ message }}</p>
|
|
298
325
|
</body>
|
|
326
|
+
<script type="module">
|
|
327
|
+
const { $ } = Mancha;
|
|
328
|
+
await $.mount(document.body);
|
|
329
|
+
|
|
330
|
+
// The template initially renders with `message` as undefined.
|
|
331
|
+
// Setting it now will trigger a reactive update.
|
|
332
|
+
$.message = "Hello, World!";
|
|
333
|
+
</script>
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
This behavior is particularly useful with the `:render` attribute, where a JavaScript module can
|
|
337
|
+
set variables that are already referenced in the template:
|
|
338
|
+
|
|
339
|
+
```html
|
|
340
|
+
<div :render="./init.js">
|
|
341
|
+
<!-- These variables are set by the :render callback -->
|
|
342
|
+
<span>{{ title }}</span>
|
|
343
|
+
<ul :for="item in items">
|
|
344
|
+
<li>{{ item }}</li>
|
|
345
|
+
</ul>
|
|
346
|
+
</div>
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
```js
|
|
350
|
+
// init.js
|
|
351
|
+
export default async function (elem, renderer) {
|
|
352
|
+
await renderer.set("title", "My List");
|
|
353
|
+
await renderer.set("items", ["a", "b", "c"]);
|
|
354
|
+
}
|
|
299
355
|
```
|
|
300
356
|
|
|
357
|
+
The auto-initialization only happens when variables are accessed during an effect (such as template
|
|
358
|
+
rendering). Accessing a variable outside of an effect context will return `undefined` without
|
|
359
|
+
creating an observer.
|
|
360
|
+
|
|
301
361
|
When setting a variable, there are 3 possible cases:
|
|
302
362
|
|
|
303
363
|
1. The variable has already been defined in the current renderer. Then it gets updated in the
|
|
@@ -333,12 +393,12 @@ This allows you to react to URL changes declaratively within your components:
|
|
|
333
393
|
|
|
334
394
|
```html
|
|
335
395
|
<body :data="{ $$search: '' }">
|
|
336
|
-
|
|
337
|
-
|
|
396
|
+
<input type="text" :bind="$$search" placeholder="Search..." />
|
|
397
|
+
<div :show="$$search">Searching for: {{ $$search }}</div>
|
|
338
398
|
</body>
|
|
339
399
|
<script type="module">
|
|
340
|
-
|
|
341
|
-
|
|
400
|
+
import { Mancha } from "//unpkg.com/mancha";
|
|
401
|
+
await Mancha.mount(document.body);
|
|
342
402
|
</script>
|
|
343
403
|
```
|
|
344
404
|
|
|
@@ -363,7 +423,7 @@ To use `mancha` on the client (browser), use the `mancha` bundled file available
|
|
|
363
423
|
|
|
364
424
|
```html
|
|
365
425
|
<body :data="{ name: 'John' }">
|
|
366
|
-
|
|
426
|
+
<span>Hello, {{ name }}!</span>
|
|
367
427
|
</body>
|
|
368
428
|
|
|
369
429
|
<script src="//unpkg.com/mancha" target="body" css="basic+utils" init></script>
|
|
@@ -415,16 +475,16 @@ import vars from "./vars.json";
|
|
|
415
475
|
const app = express();
|
|
416
476
|
|
|
417
477
|
app.get("/", async (req, res) => {
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
478
|
+
const name = req.query.name || "Stranger";
|
|
479
|
+
// Instantiate a new renderer.
|
|
480
|
+
const renderer = new Renderer({ name, ...vars });
|
|
481
|
+
// Preprocess input HTML from a local file path.
|
|
482
|
+
const fragment = await renderer.preprocessLocal("src/index.html");
|
|
483
|
+
// Render and serialize output HTML.
|
|
484
|
+
const html = renderer.serializeHTML(await renderer.renderNode(fragment));
|
|
485
|
+
// Send it to the client.
|
|
486
|
+
res.set("Content-Type", "text/html");
|
|
487
|
+
res.send(html);
|
|
428
488
|
});
|
|
429
489
|
|
|
430
490
|
app.listen(process.env.PORT || 8080);
|
|
@@ -443,14 +503,14 @@ import htmlIndex from "./index.html";
|
|
|
443
503
|
import vars from "./vars.json";
|
|
444
504
|
|
|
445
505
|
self.addEventListener("fetch", async (event) => {
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
506
|
+
// Instantiate a new renderer.
|
|
507
|
+
const renderer = new Renderer({ ...vars });
|
|
508
|
+
// Preprocess input HTML from a string.
|
|
509
|
+
const fragment = await renderer.preprocessString(htmlIndex);
|
|
510
|
+
// Render and serialize output HTML.
|
|
511
|
+
const html = renderer.serializeHTML(await renderer.renderNode(fragment));
|
|
512
|
+
// Send it to the client.
|
|
513
|
+
event.respondWith(new Response(content, { headers: { "Content-Type": "text/html" } }));
|
|
454
514
|
});
|
|
455
515
|
```
|
|
456
516
|
|
package/dist/browser.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { IRenderer } from "./renderer.js";
|
|
2
2
|
import type { StoreState } from "./store.js";
|
|
3
3
|
import type { ParserParams, RenderParams } from "./interfaces.js";
|
|
4
|
+
export { IRenderer } from "./renderer.js";
|
|
5
|
+
export type { ParserParams, RenderParams, RendererPlugin } from "./interfaces.js";
|
|
4
6
|
export { default as basicCssRules } from "./css_gen_basic.js";
|
|
5
7
|
export { default as utilsCssRules } from "./css_gen_utils.js";
|
|
6
8
|
export declare class Renderer<T extends StoreState = StoreState> extends IRenderer<T> {
|