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 |
x30
x30
x30
x30
x90
x90
x90
x90
x30
x30
x30
x30
x30
x30
x30
x30
x5118
x5118
x32304
x10768
x10768
x13768
x13768
x10768
x11446
x12800
x12800
x12800
x11446
x11446
x10768
x10768
x12740
x54888
x13722
x13722
x13722
x16653
x18317
x18317
x18317
x16183
x16283
x16283
x16283
x16029
x16163
x16163
x12740
x10768
x10201
x5118
x30
x30
x30
x2310
x30 |
|
import { type Directive, type NonVoid, Phase } from "@mizu/internal/engine"
export type * from "@mizu/internal/engine"
const PHASE_TESTING_DELTA = -0.5
export const typings = {
modifiers: {
text: { type: Boolean },
comment: { type: Boolean },
eval: { type: Boolean },
throw: { type: Boolean },
},
} 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.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
|