Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(eval): add *eval directive #13

Merged
merged 1 commit into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions @mizu/eval/deno.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"name": "@mizu/eval",
"version": "0.1.0",
"exports": {
".": "./mod.ts"
}
}
17 changes: 17 additions & 0 deletions @mizu/eval/mod.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<mizu-directive id="eval" directory="eval">
<code #name><span class="hljs-keyword">*eval</span><wbr /><span class="muted">="expression"</span></code>
<p #description>
Evaluate a JavaScript expression in the context of the element.
</p>
<code #example *skip>
<div *eval="console.log('$data')">
<!--...-->
</div>
</code>
<mizu-warn #note>
Usage of this directive is discouraged and it is recommended to use alternative directives whenever possible for improved maintainability and security reasons. It is nevertheless still offered to help covering edge cases.
</mizu-warn>
<mizu-note #note>
It is executed after the element and all of its children have been completely processed.
</mizu-note>
</mizu-directive>
31 changes: 31 additions & 0 deletions @mizu/eval/mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Imports
import { type Cache, type Directive, Phase } from "@mizu/mizu/core/engine"
export type * from "@mizu/mizu/core/engine"

/** `*eval` directive. */
export const _eval = {
name: "*eval",
phase: Phase.CUSTOM_PROCESSING,
init(renderer) {
renderer.cache<Cache<typeof _eval>>(this.name, new WeakMap())
},
execute(renderer, element, { attributes: [attribute], cache }) {
if (renderer.isComment(element)) {
return
}
cache.set(element, attribute)
},
async cleanup(renderer, element, { cache, ...options }) {
if (renderer.isComment(element)) {
return
}
if (cache.has(element)) {
const attribute = cache.get(element)!
cache.delete(element)
await renderer.evaluate(element, attribute.value, options)
}
},
} as Directive<WeakMap<HTMLElement, Attr>>

/** Default exports. */
export default _eval
26 changes: 26 additions & 0 deletions @mizu/eval/mod_test.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<load directives="@mizu/eval,@mizu/test"></load>

<test name="[*eval] evaluates raw script">
<render>
<div *eval="this.textContent = 'bar'">foo</div>
</render>
<expect>
<div>bar</div>
</expect>
</test>

<test name="[*eval] can remove element itself">
<render>
<div *eval="this.remove()"></div>
</render>
<expect></expect>
</test>

<test name="[*eval] skips commented elements">
<render>
<p ~test.comment *eval="this.remove()"></p>
</render>
<expect>
<!--[~test.comment=""]-->
</expect>
</test>
1 change: 1 addition & 0 deletions @mizu/eval/mod_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
await import("@mizu/mizu/core/testing").then(({ test }) => test(import.meta))
2 changes: 1 addition & 1 deletion deno.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
// "@mizu/clean",
// "@mizu/code",
"@mizu/custom-element",
// "@mizu/eval",
"@mizu/eval",
// "@mizu/event",
"@mizu/for",
"@mizu/html",
Expand Down