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 |
x30
x30
x30
x30
x90
x90
x90
x90
x90
x30
x30
x30
x30
x30
x30
x30
x30
x5454
x5454
x34320
x11440
x11440
x14532
x14532
x11440
x12119
x13475
x13475
x13475
x12119
x12119
x11440
x11440
x13655
x58740
x14685
x14685
x14685
x18054
x19937
x19937
x19937
x17485
x17585
x17585
x17585
x17427
x157227
x17451
x18033
x18191
x18191
x13655
x11440
x10873
x5454
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 = {
name: /^~test/,
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 Directive<null, typeof typings> & { name: RegExp }
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
|