mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
feat: call queue function for let assignments
This commit is contained in:
parent
9cc4ed81c8
commit
e614acb044
@ -19,7 +19,24 @@ container.querySelector("button").click();
|
||||
```html
|
||||
<div>
|
||||
<button>
|
||||
0
|
||||
1
|
||||
</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
div0/button0/#text0: "0" => "1"
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
container.querySelector("button").click();
|
||||
|
||||
```html
|
||||
<div>
|
||||
<button>
|
||||
1
|
||||
</button>
|
||||
</div>
|
||||
```
|
||||
@ -36,24 +53,7 @@ container.querySelector("button").click();
|
||||
```html
|
||||
<div>
|
||||
<button>
|
||||
0
|
||||
</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
container.querySelector("button").click();
|
||||
|
||||
```html
|
||||
<div>
|
||||
<button>
|
||||
0
|
||||
1
|
||||
</button>
|
||||
</div>
|
||||
```
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { write as _write, read as _read, on as _on, data as _data, bind as _bind, createRenderFn as _createRenderFn } from "@marko/runtime-fluurt/src/dom";
|
||||
import { queue as _queue, write as _write, read as _read, on as _on, data as _data, bind as _bind, createRenderFn as _createRenderFn } from "@marko/runtime-fluurt/src/dom";
|
||||
|
||||
function _apply() {
|
||||
_apply_clickCount(0);
|
||||
@ -7,7 +7,7 @@ function _apply() {
|
||||
const _onclick = function () {
|
||||
const clickCount = _read(2);
|
||||
|
||||
clickCount++;
|
||||
_queue(_apply_clickCount, 2, clickCount + 1);
|
||||
};
|
||||
|
||||
function _apply_clickCount(clickCount) {
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
<div>
|
||||
<let/clickCount = 0/>
|
||||
<button onclick() { clickCount++ }>${clickCount}</button>
|
||||
<button onclick() {
|
||||
clickCount++
|
||||
}>${clickCount}</button>
|
||||
</div>
|
||||
|
||||
@ -47,7 +47,7 @@ export default function enter(tag: t.NodePath<t.MarkoTag>) {
|
||||
identifiers.length === 1
|
||||
? t.expressionStatement(
|
||||
t.callExpression(
|
||||
writer.getApplyId(tag, identifiers[0].extra.binding!),
|
||||
writer.bindingToApplyId(tag, identifiers[0].extra.binding!),
|
||||
[defaultAttr.value]
|
||||
)
|
||||
)
|
||||
@ -58,7 +58,7 @@ export default function enter(tag: t.NodePath<t.MarkoTag>) {
|
||||
...identifiers.map((identifier) =>
|
||||
t.expressionStatement(
|
||||
t.callExpression(
|
||||
writer.getApplyId(tag, identifier.extra.binding!),
|
||||
writer.bindingToApplyId(tag, identifier.extra.binding!),
|
||||
[t.identifier(identifier.name)]
|
||||
)
|
||||
)
|
||||
|
||||
@ -4,21 +4,24 @@ import { assertNoBodyContent } from "../util/assert";
|
||||
import translateVar from "../util/translate-var";
|
||||
import { isOutputDOM } from "../util/marko-config";
|
||||
import * as writer from "../util/writer";
|
||||
import { callRuntime } from "../util/runtime";
|
||||
import replaceAssignments from "../util/replace-assignments";
|
||||
|
||||
export default function enter(tag: t.NodePath<t.MarkoTag>) {
|
||||
const { node } = tag;
|
||||
const tagVar = node.var;
|
||||
const [defaultAttr] = node.attributes;
|
||||
|
||||
assertNoParams(tag);
|
||||
assertNoBodyContent(tag);
|
||||
|
||||
if (!node.var) {
|
||||
if (!tagVar) {
|
||||
throw tag
|
||||
.get("name")
|
||||
.buildCodeFrameError("The 'let' tag requires a tag variable.");
|
||||
}
|
||||
|
||||
if (!t.isIdentifier(node.var)) {
|
||||
if (!t.isIdentifier(tagVar)) {
|
||||
throw tag
|
||||
.get("var")
|
||||
.buildCodeFrameError("The 'let' cannot be destructured.");
|
||||
@ -43,16 +46,19 @@ export default function enter(tag: t.NodePath<t.MarkoTag>) {
|
||||
}
|
||||
|
||||
if (isOutputDOM(tag)) {
|
||||
const binding = tagVar.extra.binding!;
|
||||
const applyId = writer.bindingToApplyId(tag, binding);
|
||||
const scopeId = writer.bindingToScopeId(tag, binding);
|
||||
// TODO: add defined guard if bindings exist.
|
||||
writer.addStatement(
|
||||
"apply",
|
||||
tag,
|
||||
defaultAttr.extra?.valueReferences,
|
||||
t.expressionStatement(
|
||||
t.callExpression(writer.getApplyId(tag, node.var.extra.binding!), [
|
||||
defaultAttr.value,
|
||||
])
|
||||
)
|
||||
t.expressionStatement(t.callExpression(applyId, [defaultAttr.value]))
|
||||
);
|
||||
|
||||
replaceAssignments(tag.scope.getBinding(binding.name)!, (v) =>
|
||||
callRuntime(tag, "queue", applyId, scopeId, v)
|
||||
);
|
||||
} else {
|
||||
translateVar(tag, defaultAttr.value);
|
||||
|
||||
33
packages/translator/src/util/replace-assignments.ts
Normal file
33
packages/translator/src/util/replace-assignments.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { types as t } from "@marko/compiler";
|
||||
|
||||
export default function replaceAssignments(
|
||||
binding: t.Binding,
|
||||
map: (value: t.Expression) => t.Expression
|
||||
): void {
|
||||
for (const assignment of binding.constantViolations) {
|
||||
let value: t.Expression | undefined;
|
||||
if (assignment.isUpdateExpression()) {
|
||||
value = t.binaryExpression(
|
||||
assignment.node.operator === "++" ? "+" : "-",
|
||||
binding.identifier,
|
||||
t.numericLiteral(1)
|
||||
);
|
||||
} else if (assignment.isAssignmentExpression()) {
|
||||
value =
|
||||
assignment.node.operator === "="
|
||||
? assignment.node.right
|
||||
: t.binaryExpression(
|
||||
assignment.node.operator.slice(
|
||||
0,
|
||||
-1
|
||||
) as t.BinaryExpression["operator"],
|
||||
binding.identifier,
|
||||
assignment.node.right
|
||||
);
|
||||
}
|
||||
|
||||
if (value) {
|
||||
assignment.parentPath!.replaceWith(map(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -283,7 +283,7 @@ export function addStatement(
|
||||
path,
|
||||
"queue",
|
||||
identifier,
|
||||
t.numericLiteral(bindingToScopeId(path, binding))
|
||||
bindingToScopeId(path, binding)
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -300,7 +300,7 @@ export function addStatement(
|
||||
}
|
||||
}
|
||||
|
||||
export function getApplyId(path: t.NodePath<any>, binding: Binding) {
|
||||
export function bindingToApplyId(path: t.NodePath<any>, binding: Binding) {
|
||||
const section = path.state.section as Section;
|
||||
const groupIndex = sorted.findIndex(compareReferenceGroups, section.apply, {
|
||||
references: [binding],
|
||||
@ -332,11 +332,7 @@ function writeApplyGroups(path: t.NodePath<any>, groups: ReferenceGroup[]) {
|
||||
params = references.map((binding) =>
|
||||
t.assignmentPattern(
|
||||
t.identifier(binding.name),
|
||||
callRuntime(
|
||||
path,
|
||||
"read",
|
||||
t.numericLiteral(bindingToScopeId(path, binding))
|
||||
)
|
||||
callRuntime(path, "read", bindingToScopeId(path, binding))
|
||||
)
|
||||
);
|
||||
body = t.blockStatement(statements);
|
||||
@ -348,7 +344,7 @@ function writeApplyGroups(path: t.NodePath<any>, groups: ReferenceGroup[]) {
|
||||
callRuntime(
|
||||
path,
|
||||
"write",
|
||||
t.numericLiteral(bindingToScopeId(path, references)),
|
||||
bindingToScopeId(path, references),
|
||||
param
|
||||
),
|
||||
statements.length === 1
|
||||
@ -381,11 +377,7 @@ function writeHydrateGroups(path: t.NodePath<any>, groups: ReferenceGroup[]) {
|
||||
? (Array.isArray(references) ? references : [references]).map((binding) =>
|
||||
t.assignmentPattern(
|
||||
t.identifier(binding.name),
|
||||
callRuntime(
|
||||
path,
|
||||
"read",
|
||||
t.numericLiteral(bindingToScopeId(path, binding))
|
||||
)
|
||||
callRuntime(path, "read", bindingToScopeId(path, binding))
|
||||
)
|
||||
)
|
||||
: [];
|
||||
@ -475,7 +467,7 @@ export function bindingToScopeId(
|
||||
path: t.NodePath<any>,
|
||||
{ sectionIndex, bindingIndex }: Binding
|
||||
) {
|
||||
return (
|
||||
return t.numericLiteral(
|
||||
path.hub.file.path.node.extra.sections![sectionIndex].visits + bindingIndex
|
||||
);
|
||||
}
|
||||
@ -536,11 +528,7 @@ function bindFunction(
|
||||
(Array.isArray(references) ? references : [references]).map((binding) =>
|
||||
t.variableDeclarator(
|
||||
t.identifier(binding.name),
|
||||
callRuntime(
|
||||
fn,
|
||||
"read",
|
||||
t.numericLiteral(bindingToScopeId(fn, binding))
|
||||
)
|
||||
callRuntime(fn, "read", bindingToScopeId(fn, binding))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user