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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86 |
x30
x30
x30
x30
x30
x30
x30
x30
x30
x30
x30
x30
x30
x30
x30
x30
x30
x30
x5544
x5544
x6106
x6106
x6106
x3161
x3161
x6106
x679
x4
x4
x4
x679
x679
x6106
x6106
x2266
x32
x32
x32
x32
x2247
x1934
x1934
x1934
x811
x100
x100
x100
x753
x24
x24
x609
x5
x5
x2266
x6106
x5539
x5544
x30
x30
x30
x720
x30 |
|
import { type Directive, type NonVoid, Phase } from "@mizu/internal/engine"
export type * from "@mizu/internal/engine"
export const PHASE_TESTING_DELTA = -0.5 as number
export const typings = {
modifiers: {
text: { type: Boolean },
comment: { type: Boolean },
eval: { type: Boolean },
throw: { type: Boolean },
event: { type: String },
},
} as const
export const _test = {
name: /^~test/,
prefix: "",
phase: Phase.TESTING,
typings,
multiple: true,
async execute(renderer, element, { attributes, ...options }) {
const returned = {} as NonVoid<Awaited<ReturnType<NonNullable<Directive["execute"]>>>>
for (const attribute of attributes) {
const parsed = renderer.parseAttribute(attribute, this.typings, { modifiers: true })
parsed.tag ??= Phase[Phase.TESTING]
if ((parsed.tag) && (this.phase !== (Phase[parsed.tag.toLocaleUpperCase() as keyof typeof Phase] + PHASE_TESTING_DELTA))) {
continue
}
if (renderer.isComment(element)) {
if ((parsed.modifiers.comment) && (!await renderer.evaluate(element, attribute.value || "'true'", options))) {
returned.element = renderer.uncomment(element)
element = returned.element
}
renderer.setAttribute(element, attribute.name, attribute.value)
continue
}
else if (renderer.isHtmlElement(element)) {
if ((parsed.modifiers.comment) && (await renderer.evaluate(element, attribute.value || "'true'", options))) {
returned.element = renderer.comment(element, { expression: attribute.value, directive: attribute.name })
element = returned.element
continue
}
if (parsed.modifiers.text) {
element.textContent = `${await renderer.evaluate(element, attribute.value, options)}`
continue
}
if (parsed.modifiers.eval) {
await renderer.evaluate(element, attribute.value, options)
continue
}
if (parsed.modifiers.event) {
element.addEventListener(parsed.modifiers.event, (event) => renderer.evaluate(element, attribute.value, { context: options.context, state: { ...options.state, $event: event }, args: [event] }))
}
if ((parsed.modifiers.throw) && (await renderer.evaluate(element, attribute.value || "'true'", options))) {
throw new EvalError(`Expected error from: ${element.outerHTML.replace(element.innerHTML, "")}`)
}
}
}
return returned
},
} as const satisfies Directive<{
Name: RegExp
Typings: typeof typings
}>
const _tests = Object.entries(Phase)
.filter(([, value]) => (Number.isFinite(value)) && (Number(value) > Phase.META))
.map(([key, value]) => ({ ..._test, name: new RegExp(`${_test.name.source}(?<${key.toLocaleLowerCase()}>)`), phase: (value as number) + PHASE_TESTING_DELTA })) as Array<typeof _test>
export default _tests
|