@rohal12/spindle 0.59.10 → 0.59.12
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/pkg/format.js +1 -1
- package/dist/pkg/headless.js +7727 -7471
- package/dist/pkg/macro-registry.json +1 -0
- package/dist/pkg/story-variables.js +480 -319
- package/package.json +1 -1
- package/src/components/macros/Computed.tsx +3 -9
- package/src/components/macros/For.tsx +34 -1
- package/src/components/macros/If.tsx +2 -7
- package/src/components/macros/SaveManager.tsx +5 -2
- package/src/components/macros/Switch.tsx +4 -2
- package/src/components/macros/Widget.tsx +1 -19
- package/src/components/macros/WidgetInvocation.tsx +13 -23
- package/src/components/macros/branches.ts +20 -0
- package/src/define-macro.ts +2 -0
- package/src/hooks/use-modal-focus.ts +50 -3
- package/src/index.tsx +9 -22
- package/src/js-lexer.ts +18 -1
- package/src/markup/render.tsx +44 -11
- package/src/markup/spindle.peggy +11 -0
- package/src/saves/save-manager.ts +9 -0
- package/src/story-init.ts +4 -0
- package/src/styles.css +5 -0
- package/src/triggers.ts +4 -2
- package/src/utils/control-edits.ts +15 -0
- package/src/widgets/register-widget-def.ts +44 -0
package/src/triggers.ts
CHANGED
|
@@ -251,7 +251,7 @@ export function checkTriggersOnNavigation(): void {
|
|
|
251
251
|
|
|
252
252
|
/**
|
|
253
253
|
* Re-evaluate watchers whenever a namespace their conditions can read
|
|
254
|
-
* ($variables, _temporary, %transient)
|
|
254
|
+
* ($variables, _temporary, %transient) or the render counts change. Navigation is left to the
|
|
255
255
|
* store: navigate() checks watchers once the new moment is complete
|
|
256
256
|
* (checkTriggersOnNavigation), while history traversal and loads
|
|
257
257
|
* reinitialize watcher state instead of firing.
|
|
@@ -269,7 +269,9 @@ export function connectTriggersToStore(): () => void {
|
|
|
269
269
|
if (
|
|
270
270
|
state.variables === before.variables &&
|
|
271
271
|
state.temporary === before.temporary &&
|
|
272
|
-
state.transient === before.transient
|
|
272
|
+
state.transient === before.transient &&
|
|
273
|
+
// hasRendered() / rendered() read the counts an {include} bumps
|
|
274
|
+
state.renderCounts === before.renderCounts
|
|
273
275
|
) {
|
|
274
276
|
return;
|
|
275
277
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Counts the edits a reader made through a control bound to a story
|
|
3
|
+
* variable (`{textbox}`, `{checkbox}`, ...). {for} tells these apart from a
|
|
4
|
+
* list that is replaced: typing into a control inside an iteration changes
|
|
5
|
+
* its item, but must not remount the iteration and drop the control's focus.
|
|
6
|
+
*/
|
|
7
|
+
let version = 0;
|
|
8
|
+
|
|
9
|
+
export function noteControlEdit(): void {
|
|
10
|
+
version++;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function controlEditVersion(): number {
|
|
14
|
+
return version;
|
|
15
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { registerWidget } from './widget-registry';
|
|
2
|
+
import { astContainsChildren } from './ast-scanner';
|
|
3
|
+
import { registerBlockMacro, type ASTNode } from '../markup/ast';
|
|
4
|
+
import { errorMessage } from '../utils/error-message';
|
|
5
|
+
import { parseWidgetDef, type WidgetDef } from './widget-def';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Register the widget a definition declares, with its body. Widgets whose
|
|
9
|
+
* body renders {@children} take a closing tag, so they are registered as
|
|
10
|
+
* block macros too: passages parsed later nest their content. A parameter
|
|
11
|
+
* that no namespace can hold throws (see registerWidget), registering
|
|
12
|
+
* nothing.
|
|
13
|
+
*/
|
|
14
|
+
export function registerWidgetDef(
|
|
15
|
+
{ name, params }: WidgetDef,
|
|
16
|
+
body: ASTNode[],
|
|
17
|
+
): void {
|
|
18
|
+
const isBlock = astContainsChildren(body);
|
|
19
|
+
registerWidget(name, body, params, isBlock);
|
|
20
|
+
if (isBlock) registerBlockMacro(name);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Register the widgets `nodes` (a passage's markup) define at its top level,
|
|
25
|
+
* as the {widget} macro does when it renders. A widget that fails to register
|
|
26
|
+
* is reported; the others still register.
|
|
27
|
+
*/
|
|
28
|
+
export function registerWidgetDefinitions(
|
|
29
|
+
nodes: ASTNode[],
|
|
30
|
+
passageName: string,
|
|
31
|
+
): void {
|
|
32
|
+
for (const node of nodes) {
|
|
33
|
+
if (node.type === 'macro' && node.name === 'widget' && node.rawArgs) {
|
|
34
|
+
const def = parseWidgetDef(node.rawArgs);
|
|
35
|
+
try {
|
|
36
|
+
registerWidgetDef(def, node.children as ASTNode[]);
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.error(
|
|
39
|
+
`spindle: widget "${def.name}" in passage "${passageName}" was not registered: ${errorMessage(err)}`,
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|