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 |
x30
x30
x30
x30
x90
x90
x90
x90
x90
x30
x30
x30
x30
x30
x30
x30
x30
x30
x5526
x5526
x34752
x11584
x11584
x14745
x14745
x11584
x12263
x13619
x13619
x13619
x12263
x12263
x11584
x11584
x13802
x59352
x14838
x14838
x14838
x18207
x20093
x20093
x20093
x17641
x17741
x17741
x17741
x17583
x158631
x17607
x18192
x18350
x18350
x13802
x11584
x11017
x5526
x30
x30
x30
x2310
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: Directive<{
Name: RegExp
Typings: typeof typings
}> = {
name: /^~test/,
phase: Phase.TESTING,
typings,
multiple: true,
async execute(this: typeof _test, 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
},
}
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
|