Stub out reacting to a button click
This commit is contained in:
parent
48c07e792d
commit
d5a7033adc
3 changed files with 77 additions and 29 deletions
78
src/3x5.ts
78
src/3x5.ts
|
@ -1,4 +1,4 @@
|
|||
import { Button } from './lib/button';
|
||||
import { Button, RegisterButtonOnClick } from './lib/button';
|
||||
import { Card, CardVm, GetField } from './lib/card';
|
||||
import { Here, RegisterJumpHere } from './lib/debug';
|
||||
import { Expr } from './lib/expr';
|
||||
|
@ -30,21 +30,6 @@ function parseFields(card: Card, fields: string) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param state VM state
|
||||
* @param code Script to run
|
||||
* @returns Markup to render / output
|
||||
*/
|
||||
function renderCard(state: CardVm, code: string) {
|
||||
const script = parse(code);
|
||||
if (script[0]) {
|
||||
runNoctl(state, script[1], (word) => (state.output += AsHtml(word) + "\n"));
|
||||
} else {
|
||||
state.output = script[1];
|
||||
}
|
||||
return state.output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Global state: a single card
|
||||
*/
|
||||
|
@ -69,6 +54,12 @@ const codeInput = document.createElement("textarea");
|
|||
Object.assign(codeInput.style, TEXTAREA_STYLE, { height: "20em" });
|
||||
codeInput.value = String.raw`
|
||||
h1 [get title]
|
||||
|
||||
button disabled
|
||||
button "Hello" -onClick {
|
||||
alert Hiya
|
||||
}
|
||||
|
||||
para [2 + 2]
|
||||
block {
|
||||
This is a paragraph of text, with one [b bold] word. Yes, this means there has to be some magic in text processing... <b>this</b> won't work.
|
||||
|
@ -116,29 +107,65 @@ const state = document.createElement("pre");
|
|||
const display = document.createElement("blockquote");
|
||||
const debugDisplay = document.createElement("pre");
|
||||
|
||||
const COMMANDS = {
|
||||
...HTML,
|
||||
get: GetField,
|
||||
expr: Expr,
|
||||
here: Here,
|
||||
button: Button,
|
||||
};
|
||||
|
||||
function render() {
|
||||
parseFields(theCard, fieldInput.value);
|
||||
theCard.code = codeInput.value;
|
||||
|
||||
const vm: CardVm = {
|
||||
mode: "render",
|
||||
commands: {
|
||||
...HTML,
|
||||
get: GetField,
|
||||
expr: Expr,
|
||||
here: Here,
|
||||
button: Button,
|
||||
},
|
||||
mode: ["render"],
|
||||
commands: COMMANDS,
|
||||
output: "",
|
||||
card: theCard,
|
||||
};
|
||||
const html = renderCard(vm, theCard.code);
|
||||
|
||||
const script = parse(theCard.code);
|
||||
|
||||
let html = "";
|
||||
if (script[0]) {
|
||||
runNoctl(vm, script[1], (word) => (vm.output += AsHtml(word) + "\n"));
|
||||
} else {
|
||||
vm.output = script[1];
|
||||
}
|
||||
html = vm.output;
|
||||
|
||||
state.textContent = JSON.stringify(theCard, null, 2);
|
||||
display.innerHTML = html;
|
||||
debugDisplay.textContent = html;
|
||||
}
|
||||
|
||||
function triggerEvent(handlerPos: number) {
|
||||
parseFields(theCard, fieldInput.value);
|
||||
theCard.code = codeInput.value;
|
||||
|
||||
const vm: CardVm = {
|
||||
mode: ["findingAction", handlerPos],
|
||||
commands: COMMANDS,
|
||||
output: "",
|
||||
card: theCard,
|
||||
};
|
||||
|
||||
const script = parse(theCard.code);
|
||||
|
||||
let html = "";
|
||||
if (script[0]) {
|
||||
runNoctl(vm, script[1], (word) => {});
|
||||
} else {
|
||||
vm.output = script[1];
|
||||
}
|
||||
html = vm.output;
|
||||
console.debug(html);
|
||||
|
||||
state.textContent = JSON.stringify(theCard, null, 2);
|
||||
}
|
||||
|
||||
render();
|
||||
document.body.append(
|
||||
fieldInput,
|
||||
|
@ -150,3 +177,4 @@ document.body.append(
|
|||
);
|
||||
|
||||
RegisterJumpHere(codeInput);
|
||||
RegisterButtonOnClick(triggerEvent);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Proc } from '../vm';
|
||||
import { AsHtml, ProcResult, TextPiece } from '../words';
|
||||
import { AsHtml, ProcResult, SourcePos, TextPiece } from '../words';
|
||||
import { CardContext } from './card';
|
||||
import { getOptRaw } from './options';
|
||||
|
||||
|
@ -10,7 +10,7 @@ export const Button: Proc<CardContext> = (vm, argv: TextPiece[]): ProcResult =>
|
|||
({ onClick: [onClick = null] }, [label]) => {
|
||||
let buttonTrigger = "disabled";
|
||||
if (onClick && "pos" in onClick && onClick.pos != undefined) {
|
||||
buttonTrigger = `data-notcl-onClick="${onClick.pos}"`;
|
||||
buttonTrigger = `data-notcl-button="${onClick.pos}"`;
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -18,3 +18,21 @@ export const Button: Proc<CardContext> = (vm, argv: TextPiece[]): ProcResult =>
|
|||
};
|
||||
}
|
||||
);
|
||||
|
||||
export function RegisterButtonOnClick(
|
||||
triggerDispatch: (pos: SourcePos) => void
|
||||
) {
|
||||
document.body.addEventListener(
|
||||
"click",
|
||||
(evt) => {
|
||||
const dataNoctlButton = (evt.target as HTMLElement)?.getAttribute?.(
|
||||
"data-notcl-button"
|
||||
);
|
||||
if (dataNoctlButton !== null) {
|
||||
const handlerPos = Number(dataNoctlButton);
|
||||
triggerDispatch(handlerPos);
|
||||
}
|
||||
},
|
||||
{ passive: true }
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
import {
|
||||
AsText, Concat, ErrorResult, InterpolatedPiece, ProcResult, Script, TextPiece, Word
|
||||
AsText, Concat, ErrorResult, InterpolatedPiece, ProcResult, Script, SourcePos, TextPiece, Word
|
||||
} from './words';
|
||||
|
||||
/**
|
||||
* "Mode" of the environment a script runs in; determines access to mutability features and such.
|
||||
*
|
||||
* "findingAction": preparing a response to a UI action, which can involve recalculating variables, but has no side-effects itself.
|
||||
*
|
||||
* "action": response to a UI action; allowed to modify card fields and access time and random numbers.
|
||||
*
|
||||
* "render": deterministic generation of display markup from card and workspace state; can only modify temporary variables.
|
||||
*/
|
||||
export type ScriptType = "action" | "render";
|
||||
export type ScriptType = ["findingAction", SourcePos] | ["action"] | ["render"];
|
||||
|
||||
export type Proc<Context> = (
|
||||
state: Vm<Context>,
|
||||
|
|
Loading…
Reference in a new issue