feat: valueChange on return tag (#2374)

This commit is contained in:
Dylan Piercey 2024-11-21 09:10:04 -07:00 committed by GitHub
parent 02f5cabcdd
commit d8a9ee58a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
44 changed files with 1406 additions and 74 deletions

View File

@ -0,0 +1,6 @@
---
"@marko/translator-tags": minor
"@marko/runtime-tags": minor
---
Support valueChange attribute on `<return>` tag.

View File

@ -7,8 +7,8 @@
{
"name": "*",
"total": {
"min": 17850,
"brotli": 6455
"min": 17902,
"brotli": 6477
}
},
{

View File

@ -1,4 +1,4 @@
// size: 17850 (min) 6455 (brotli)
// size: 17902 (min) 6477 (brotli)
var empty = [],
rest = Symbol();
function attrTag(attrs2) {
@ -417,7 +417,11 @@ function dynamicSubscribers(valueAccessor) {
function setTagVar(scope, childAccessor, tagVarSignal2) {
scope[childAccessor]["/"] = (valueOrOp) => tagVarSignal2(scope, valueOrOp);
}
var tagVarSignal = (scope, valueOrOp) => scope["/"]?.(valueOrOp),
var tagVarSignal = (scope, valueOrOp) => scope["/"]?.(valueOrOp);
function setTagVarChange(scope, changeHandler) {
scope["@"] = changeHandler;
}
var tagVarSignalChange = (scope, value2) => scope["@"]?.(value2),
renderBodyClosures = (renderBody, childScope, op) => {
let signals = renderBody?.c;
if (signals) for (let signal of signals) signal(childScope, op);

View File

@ -1 +1 @@
{"vars":{"props":{"$empty":"e","$rest":"t","$attrTag":"n","$attrTags":"r","$attrTagIterator":"i","$forIn":"l","$forOf":"o","$forTo":"f","$isScheduled":"u","$port2":"a","$flushAndWaitFrame":"c","$triggerMacroTask":"s","$noop":"d","$createScope":"h","$emptyScope":"g","$getEmptyScope":"p","$destroyScope":"v","$_destroyScope":"b","$onDestroy":"m","$removeAndDestroyScope":"k","$insertBefore":"y","$registeredValues":"w","$Render":"C","$isResuming":"A","$register":"S","$registerBoundSignal":"N","$init":"x","$registerSubscriber":"$","$nodeRef":"M","$MARK":"E","$CLEAN":"I","$DIRTY":"T","$state":"_","$value":"O","$accessorId":"B","$intersection":"V","$defaultGetOwnerScope":"j","$closure":"R","$dynamicClosure":"q","$childClosures":"D","$dynamicSubscribers":"P","$setTagVar":"W","$tagVarSignal":"L","$renderBodyClosures":"z","$tagIdsByGlobal":"F","$nextTagId":"U","$inChild":"G","$intersections":"J","$effect":"X","$pendingSignals":"Z","$pendingEffects":"H","$rendering":"K","$queueEffect":"Q","$run":"Y","$prepareEffects":"ee","$runEffects":"te","$runSignals":"ne","$resetAbortSignal":"re","$getAbortSignal":"ie","$stringifyClassObject":"le","$NON_DIMENSIONAL":"oe","$stringifyStyleObject":"fe","$toDelimitedString":"ue","$normalizeDynamicRenderer":"ae","$elementHandlersByEvent":"ce","$defaultDelegator":"se","$on":"de","$createDelegator":"he","$handleDelegated":"ge","$stripSpacesAndPunctuation":"pe","$controllable_input_checked":"ve","$controllable_input_checked_effect":"be","$controllable_input_checkedValue":"me","$controllable_input_checkedValue_effect":"ke","$controllable_input_value":"ye","$controllable_input_value_effect":"we","$controllable_select_value":"Ce","$controllable_select_value_effect":"Ae","$setSelectOptions":"Se","$controllable_detailsOrDialog_open":"Ne","$controllable_detailsOrDialog_open_effect":"xe","$inputType":"$e","$setValueAndUpdateSelection":"Me","$setCheckboxValue":"Ee","$delegateFormControl":"Ie","$formChangeHandlers":"Te","$syncControllable":"_e","$onFormChange":"Oe","$onFormReset":"Be","$hasValueChanged":"Ve","$hasCheckboxChanged":"je","$hasSelectChanged":"Re","$hasFormElementChanged":"qe","$normalizeStrProp":"De","$normalizeBoolProp":"Pe","$toValueProp":"We","$fallback":"Le","$parser":"ze","$parseHTML":"Fe","$eventHandlerReg":"Ue","$attr":"Ge","$setAttribute":"Je","$classAttr":"Xe","$styleAttr":"Ze","$data":"He","$attrs":"Ke","$hasAttrAlias":"Qe","$partialAttrs":"Ye","$attrsInternal":"et","$attrsEvents":"tt","$html":"nt","$props":"rt","$normalizeAttrValue":"it","$lifecycle":"lt","$walker":"ot","$trimWalkString":"ft","$walk":"ut","$walkInternal":"at","$createScopeWithRenderer":"ct","$createScopeWithTagNameOrRenderer":"st","$initRenderer":"dt","$dynamicTagAttrs":"ht","$createRendererWithOwner":"gt","$createRenderer":"pt","$_clone":"vt","$conditional":"bt","$inConditionalScope":"mt","$conditionalOnlyChild":"kt","$setConditionalRendererOnlyChild":"yt","$emptyMarkerMap":"wt","$emptyMarkerArray":"Ct","$emptyMap":"At","$emptyArray":"St","$loopOf":"Nt","$loopIn":"xt","$loopTo":"$t","$loop":"Mt","$inLoopScope":"Et","$bySecondArg":"It","$byFirstArg":"Tt","$isDifferentRenderer":"_t","$classIdToScope":"Ot","$compat":"Bt","$createTemplate":"Vt","$mount":"jt","$parseHTMLOrSingleNode":"Wt","$marker":"qt","$_clickCount_effect":"Dt","$_clickCount":"Xt","$_setup_":"Zt","$_expr_comment_id$ifBody":"ss","$_id$ifBody":"as","$_comment$ifBody":"ns","$_ifBody":"ts","$_expr_input_i$forBody":"os","$_if$forBody":"cs","$_open$forBody_effect":"is","$_open$forBody":"ms","$_id$forBody":"ls","$_i$forBody":"us","$_comment$forBody":"es","$_params_2$forBody":"ds","$_input$forBody":"rs","$_for":"bs","$_input_$1":"fs","$_input_":"ps","$_params__":"vs","$isEventHandler":"Rt","$getEventHandlerName":"Pt"}}}
{"vars":{"props":{"$empty":"e","$rest":"t","$attrTag":"n","$attrTags":"r","$attrTagIterator":"i","$forIn":"l","$forOf":"o","$forTo":"f","$isScheduled":"u","$port2":"a","$flushAndWaitFrame":"c","$triggerMacroTask":"s","$noop":"d","$createScope":"h","$emptyScope":"g","$getEmptyScope":"p","$destroyScope":"v","$_destroyScope":"b","$onDestroy":"m","$removeAndDestroyScope":"k","$insertBefore":"y","$registeredValues":"w","$Render":"C","$isResuming":"A","$register":"S","$registerBoundSignal":"N","$init":"x","$registerSubscriber":"$","$nodeRef":"M","$MARK":"E","$CLEAN":"I","$DIRTY":"T","$state":"_","$value":"O","$accessorId":"B","$intersection":"V","$defaultGetOwnerScope":"j","$closure":"R","$dynamicClosure":"q","$childClosures":"D","$dynamicSubscribers":"P","$setTagVar":"W","$tagVarSignal":"L","$renderBodyClosures":"z","$tagIdsByGlobal":"F","$nextTagId":"U","$inChild":"G","$intersections":"J","$effect":"X","$pendingSignals":"Z","$pendingEffects":"H","$rendering":"K","$queueEffect":"Q","$run":"Y","$prepareEffects":"ee","$runEffects":"te","$runSignals":"ne","$resetAbortSignal":"re","$getAbortSignal":"ie","$stringifyClassObject":"le","$NON_DIMENSIONAL":"oe","$stringifyStyleObject":"fe","$toDelimitedString":"ue","$normalizeDynamicRenderer":"ae","$elementHandlersByEvent":"ce","$defaultDelegator":"se","$on":"de","$createDelegator":"he","$handleDelegated":"ge","$stripSpacesAndPunctuation":"pe","$controllable_input_checked":"ve","$controllable_input_checked_effect":"be","$controllable_input_checkedValue":"me","$controllable_input_checkedValue_effect":"ke","$controllable_input_value":"ye","$controllable_input_value_effect":"we","$controllable_select_value":"Ce","$controllable_select_value_effect":"Ae","$setSelectOptions":"Se","$controllable_detailsOrDialog_open":"Ne","$controllable_detailsOrDialog_open_effect":"xe","$inputType":"$e","$setValueAndUpdateSelection":"Me","$setCheckboxValue":"Ee","$delegateFormControl":"Ie","$formChangeHandlers":"Te","$syncControllable":"_e","$onFormChange":"Oe","$onFormReset":"Be","$hasValueChanged":"Ve","$hasCheckboxChanged":"je","$hasSelectChanged":"Re","$hasFormElementChanged":"qe","$normalizeStrProp":"De","$normalizeBoolProp":"Pe","$toValueProp":"We","$fallback":"Le","$parser":"ze","$parseHTML":"Fe","$eventHandlerReg":"Ue","$attr":"Ge","$setAttribute":"Je","$classAttr":"Xe","$styleAttr":"Ze","$data":"He","$attrs":"Ke","$hasAttrAlias":"Qe","$partialAttrs":"Ye","$attrsInternal":"et","$attrsEvents":"tt","$html":"nt","$props":"rt","$normalizeAttrValue":"it","$lifecycle":"lt","$walker":"ot","$trimWalkString":"ft","$walk":"ut","$walkInternal":"at","$createScopeWithRenderer":"ct","$createScopeWithTagNameOrRenderer":"st","$initRenderer":"dt","$dynamicTagAttrs":"ht","$createRendererWithOwner":"gt","$createRenderer":"pt","$_clone":"vt","$conditional":"bt","$inConditionalScope":"mt","$conditionalOnlyChild":"kt","$setConditionalRendererOnlyChild":"yt","$emptyMarkerMap":"wt","$emptyMarkerArray":"Ct","$emptyMap":"At","$emptyArray":"St","$loopOf":"Nt","$loopIn":"xt","$loopTo":"$t","$loop":"Mt","$inLoopScope":"Et","$bySecondArg":"It","$byFirstArg":"Tt","$isDifferentRenderer":"_t","$classIdToScope":"Ot","$compat":"Bt","$createTemplate":"Vt","$mount":"jt","$parseHTMLOrSingleNode":"Wt","$marker":"qt","$_clickCount_effect":"Dt","$_clickCount":"Xt","$_setup_":"Zt","$_expr_comment_id$ifBody":"ss","$_id$ifBody":"as","$_comment$ifBody":"ns","$_ifBody":"ts","$_expr_input_i$forBody":"os","$_if$forBody":"cs","$_open$forBody_effect":"is","$_open$forBody":"ms","$_id$forBody":"ls","$_i$forBody":"us","$_comment$forBody":"es","$_params_2$forBody":"ds","$_input$forBody":"rs","$_for":"bs","$_input_$1":"fs","$_input_":"ps","$_params__":"vs","$isEventHandler":"Rt","$getEventHandlerName":"Pt","$setTagVarChange":"Lt","$tagVarSignalChange":"zt"}}}

View File

@ -38,6 +38,7 @@ export enum AccessorChar {
LifecycleAbortController = "-",
DynamicPlaceholderLastChild = "-",
TagVariable = "/",
TagVariableChange = "@",
ConditionalScope = "!",
ConditionalRenderer = "(",
LoopScopeArray = "!",

View File

@ -64,8 +64,10 @@ export {
intersections,
nextTagId,
setTagVar,
setTagVarChange,
state,
tagVarSignal,
tagVarSignalChange,
value,
} from "./dom/signals";
export { createTemplate } from "./dom/template";

View File

@ -269,6 +269,15 @@ export function setTagVar(
export const tagVarSignal = (scope: Scope, valueOrOp: unknown | SignalOp) =>
scope[AccessorChar.TagVariable]?.(valueOrOp);
export function setTagVarChange(
scope: Scope,
changeHandler: (value: unknown) => void,
) {
scope[AccessorChar.TagVariableChange] = changeHandler;
}
export const tagVarSignalChange = (scope: Scope, value: unknown) =>
scope[AccessorChar.TagVariableChange]?.(value);
export const renderBodyClosures = (
renderBody: Renderer | string | undefined,
childScope: Scope,

View File

@ -0,0 +1,10 @@
{
"vars": {
"props": {
"$_$": "t",
"$init": "a",
"$_x_effect": "n",
"$_x": "r"
}
}
}

View File

@ -0,0 +1,81 @@
# Render {}
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
2
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
3
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.reset").click()
```html
<button
class="inc"
>
0
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```

View File

@ -0,0 +1,106 @@
# Render {}
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```
# Mutations
```
inserted button0, button1
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
2
</button>
<button
class="reset"
>
reset
</button>
```
# Mutations
```
button0/#text0: "1" => "2"
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
3
</button>
<button
class="reset"
>
reset
</button>
```
# Mutations
```
button0/#text0: "2" => "3"
```
# Render
container.querySelector("button.reset").click()
```html
<button
class="inc"
>
0
</button>
<button
class="reset"
>
reset
</button>
```
# Mutations
```
button0/#text0: "3" => "0"
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```
# Mutations
```
button0/#text0: "0" => "1"
```

View File

@ -0,0 +1,25 @@
export const _template_ = "<button class=inc> </button>";
export const _walks_ = /* get, next(1), get, out(1) */" D l";
import * as _$ from "@marko/runtime-tags/debug/dom";
const _valueChange = _$.register("packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0/valueChange", _scope => function (_new_x) {
_x(_scope, _new_x);
});
const _onClick = _scope => {
const {
x
} = _scope;
return function () {
_x(_scope, x + 1);
};
};
const _x_effect = _$.effect("packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0_x", _scope => _$.on(_scope["#button/0"], "click", _onClick(_scope)));
const _x = /* @__PURE__ */_$.state("x", (_scope, x) => {
_$.data(_scope["#text/1"], x);
_x_effect(_scope);
_$.tagVarSignal(_scope, x);
}, () => _$.tagVarSignal);
export function _setup_(_scope) {
_x(_scope, 1);
_$.setTagVarChange(_scope, _valueChange(_scope));
}
export default /* @__PURE__ */_$.createTemplate("packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko", _template_, _walks_, _setup_);

View File

@ -0,0 +1,34 @@
// size: 351 (min) 182 (brotli)
_$.register(
"a0",
(_scope) =>
function (_new_x) {
_x(_scope, _new_x);
},
);
const _x_effect = _$.effect("a1", (_scope) =>
_$.on(
_scope[0],
"click",
((_scope) => {
const { 2: x } = _scope;
return function () {
_x(_scope, x + 1);
};
})(_scope),
),
),
_x = _$.state(
2,
(_scope, x) => {
_$.data(_scope[1], x), _x_effect(_scope), _$.tagVarSignal(_scope, x);
},
() => _$.tagVarSignal,
);
_$.registerBoundSignal("b0", (_scope, count) => {}),
_$.effect("b1", (_scope) =>
_$.on(_scope[1], "click", function () {
_$.tagVarSignalChange(_scope[0], 0);
}),
),
init();

View File

@ -0,0 +1,14 @@
export const _template_ = `${_counter_template}<button class=reset>reset</button>`;
export const _walks_ = /* beginChild, _counter_walks, endChild, get, over(1) */`/${_counter_walks}& b`;
import { _setup_ as _counter, _template_ as _counter_template, _walks_ as _counter_walks } from "./components/counter.marko";
import * as _$ from "@marko/runtime-tags/debug/dom";
const _count = _$.registerBoundSignal("packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0_count", (_scope, count) => {});
const _setup__effect = _$.effect("packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0", _scope => _$.on(_scope["#button/1"], "click", function () {
_$.tagVarSignalChange(_scope["#childScope/0"], 0);
}));
export function _setup_(_scope) {
_$.setTagVar(_scope, "#childScope/0", _count);
_counter(_scope["#childScope/0"]);
_setup__effect(_scope);
}
export default /* @__PURE__ */_$.createTemplate("packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko", _template_, _walks_, _setup_);

View File

@ -0,0 +1,17 @@
import * as _$ from "@marko/runtime-tags/debug/html";
const _renderer = /* @__PURE__ */_$.createRenderer((input, _tagVar) => {
const _scope0_id = _$.nextScopeId();
const x = 1;
_$.write(`<button class=inc>${_$.escapeXML(x)}${_$.markResumeNode(_scope0_id, "#text/1")}</button>${_$.markResumeNode(_scope0_id, "#button/0")}`);
const _return = x;
_$.writeEffect(_scope0_id, "packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0_x");
_$.writeScope(_scope0_id, {
"x": x,
"/": _tagVar,
"@": _$.register(function (_new_x) {
x = _new_x;
}, "packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0/valueChange", _scope0_id)
});
return _return;
});
export default /* @__PURE__ */_$.createTemplate("packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko", _renderer);

View File

@ -0,0 +1,13 @@
import _counter from "./components/counter.marko";
import * as _$ from "@marko/runtime-tags/debug/html";
const _renderer = /* @__PURE__ */_$.createRenderer((input, _tagVar) => {
const _scope0_id = _$.nextScopeId();
const _childScope = _$.peekNextScope();
const count = _counter({}, _$.register(() => {}, "packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0_count", _scope0_id));
_$.write(`<button class=reset>reset</button>${_$.markResumeNode(_scope0_id, "#button/1")}`);
_$.writeEffect(_scope0_id, "packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0");
_$.writeScope(_scope0_id, {
"#childScope/0": _$.writeExistingScope(_childScope)
});
});
export default /* @__PURE__ */_$.createTemplate("packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko", _renderer);

View File

@ -0,0 +1,81 @@
# Render {}
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
2
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
3
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.reset").click()
```html
<button
class="inc"
>
0
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```

View File

@ -0,0 +1,161 @@
# Render {}
```html
<html>
<head />
<body>
<button
class="inc"
>
1
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#childScope/0":_.b={x:1}},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
```
# Render
container.querySelector("button.inc").click()
```html
<html>
<head />
<body>
<button
class="inc"
>
2
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#childScope/0":_.b={x:1}},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
#document/html0/body1/button0/#text0: "1" => "2"
```
# Render
container.querySelector("button.inc").click()
```html
<html>
<head />
<body>
<button
class="inc"
>
3
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#childScope/0":_.b={x:1}},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
#document/html0/body1/button0/#text0: "2" => "3"
```
# Render
container.querySelector("button.reset").click()
```html
<html>
<head />
<body>
<button
class="inc"
>
0
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#childScope/0":_.b={x:1}},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
#document/html0/body1/button0/#text0: "3" => "0"
```
# Render
container.querySelector("button.inc").click()
```html
<html>
<head />
<body>
<button
class="inc"
>
1
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#childScope/0":_.b={x:1}},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
#document/html0/body1/button0/#text0: "0" => "1"
```

View File

@ -0,0 +1,13 @@
# Render "End"
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```

View File

@ -0,0 +1,44 @@
# Write
<button class=inc>1<!--M_*1 #text/1--></button><!--M_*1 #button/0--><button class=reset>reset</button><!--M_*0 #button/1--><script>WALKER_RUNTIME("M")("_");M._.r=[_=>(_.c={0:_.a={"#childScope/0":_.b={x:1}},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0",0];M._.w()</script>
# Render "End"
```html
<html>
<head />
<body>
<button
class="inc"
>
1
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#childScope/0":_.b={x:1}},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/custom-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
inserted #document/html0
inserted #document/html0/head0
inserted #document/html0/body1
inserted #document/html0/body1/button0
inserted #document/html0/body1/button0/#text0
inserted #document/html0/body1/button0/#comment1
inserted #document/html0/body1/#comment1
inserted #document/html0/body1/button2
inserted #document/html0/body1/button2/#text0
inserted #document/html0/body1/#comment3
inserted #document/html0/body1/script4
inserted #document/html0/body1/script4/#text0
```

View File

@ -0,0 +1,5 @@
<let/x = 1/>
<button.inc onClick() { x++ }>
${x}
</button>
<return:=x/>

View File

@ -0,0 +1,2 @@
<counter/count/>
<button.reset onClick() { count = 0 }>reset</button>

View File

@ -0,0 +1,10 @@
const increment = (container: Element) => {
container.querySelector<HTMLButtonElement>("button.inc")!.click();
};
const reset = (container: Element) => {
container.querySelector<HTMLButtonElement>("button.reset")!.click();
};
export const steps = [{}, increment, increment, reset, increment];

View File

@ -0,0 +1,13 @@
{
"vars": {
"props": {
"$_$": "t",
"$init": "a",
"$_x_effect": "n",
"$_x": "r",
"$_valueChange": "e",
"$_setup_": "i",
"$Counter": "o"
}
}
}

View File

@ -0,0 +1,81 @@
# Render {}
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
2
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
3
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.reset").click()
```html
<button
class="inc"
>
0
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```

View File

@ -0,0 +1,111 @@
# Render {}
```html
<!---->
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```
# Mutations
```
inserted #comment0, button1, button2
```
# Render
container.querySelector("button.inc").click()
```html
<!---->
<button
class="inc"
>
2
</button>
<button
class="reset"
>
reset
</button>
```
# Mutations
```
button1/#text0: "1" => "2"
```
# Render
container.querySelector("button.inc").click()
```html
<!---->
<button
class="inc"
>
3
</button>
<button
class="reset"
>
reset
</button>
```
# Mutations
```
button1/#text0: "2" => "3"
```
# Render
container.querySelector("button.reset").click()
```html
<!---->
<button
class="inc"
>
0
</button>
<button
class="reset"
>
reset
</button>
```
# Mutations
```
button1/#text0: "3" => "0"
```
# Render
container.querySelector("button.inc").click()
```html
<!---->
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```
# Mutations
```
button1/#text0: "0" => "1"
```

View File

@ -0,0 +1,25 @@
export const _template_ = "<button class=inc> </button>";
export const _walks_ = /* get, next(1), get, out(1) */" D l";
import * as _$ from "@marko/runtime-tags/debug/dom";
const _valueChange = _$.register("packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0/valueChange", _scope => function (_new_x) {
_x(_scope, _new_x);
});
const _onClick = _scope => {
const {
x
} = _scope;
return function () {
_x(_scope, x + 1);
};
};
const _x_effect = _$.effect("packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0_x", _scope => _$.on(_scope["#button/0"], "click", _onClick(_scope)));
const _x = /* @__PURE__ */_$.state("x", (_scope, x) => {
_$.data(_scope["#text/1"], x);
_x_effect(_scope);
_$.tagVarSignal(_scope, x);
}, () => _$.tagVarSignal);
export function _setup_(_scope) {
_x(_scope, 1);
_$.setTagVarChange(_scope, _valueChange(_scope));
}
export default /* @__PURE__ */_$.createTemplate("packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko", _template_, _walks_, _setup_);

View File

@ -0,0 +1,47 @@
// size: 532 (min) 295 (brotli)
const _valueChange = _$.register(
"a0",
(_scope) =>
function (_new_x) {
_x(_scope, _new_x);
},
),
_x_effect = _$.effect("a1", (_scope) =>
_$.on(
_scope[0],
"click",
((_scope) => {
const { 2: x } = _scope;
return function () {
_x(_scope, x + 1);
};
})(_scope),
),
),
_x = _$.state(
2,
(_scope, x) => {
_$.data(_scope[1], x), _x_effect(_scope), _$.tagVarSignal(_scope, x);
},
() => _$.tagVarSignal,
);
function _setup_(_scope) {
_x(_scope, 1), _$.setTagVarChange(_scope, _valueChange(_scope));
}
var Counter = _$.createTemplate(
"a",
"<button class=inc> </button>",
" D l",
_setup_,
);
_$.register("b0", function () {
return Counter;
}),
_$.dynamicTagAttrs(0),
_$.registerBoundSignal("b1", (_scope, count) => {}),
_$.effect("b2", (_scope) =>
_$.on(_scope[1], "click", function () {
_$.tagVarSignalChange(_scope["0!"], 0);
}),
),
init();

View File

@ -0,0 +1,22 @@
export const _template_ = "<!><!><button class=reset>reset</button>";
export const _walks_ = /* replace, over(1), get, over(1) */"D%b b";
_$.register("packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0/getCounter", getCounter);
import Counter from "./components/counter.marko";
function getCounter() {
return Counter; // breaks tag name analysis.
}
import * as _$ from "@marko/runtime-tags/debug/dom";
const _getCounter_input = _$.dynamicTagAttrs("#text/0");
const _dynamicTagName = /* @__PURE__ */_$.conditional("#text/0", _scope => {
_$.setTagVar(_scope, "#text/0!", _count);
_getCounter_input(_scope, () => ({}));
}, () => _getCounter_input);
const _count = _$.registerBoundSignal("packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0_count", (_scope, count) => {});
const _setup__effect = _$.effect("packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0", _scope => _$.on(_scope["#button/1"], "click", function () {
_$.tagVarSignalChange(_scope["#text/0!"], 0);
}));
export function _setup_(_scope) {
_setup__effect(_scope);
_dynamicTagName(_scope, getCounter());
}
export default /* @__PURE__ */_$.createTemplate("packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko", _template_, _walks_, _setup_);

View File

@ -0,0 +1,17 @@
import * as _$ from "@marko/runtime-tags/debug/html";
const _renderer = /* @__PURE__ */_$.createRenderer((input, _tagVar) => {
const _scope0_id = _$.nextScopeId();
const x = 1;
_$.write(`<button class=inc>${_$.escapeXML(x)}${_$.markResumeNode(_scope0_id, "#text/1")}</button>${_$.markResumeNode(_scope0_id, "#button/0")}`);
const _return = x;
_$.writeEffect(_scope0_id, "packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0_x");
_$.writeScope(_scope0_id, {
"x": x,
"/": _tagVar,
"@": _$.register(function (_new_x) {
x = _new_x;
}, "packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0/valueChange", _scope0_id)
});
return _return;
});
export default /* @__PURE__ */_$.createTemplate("packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko", _renderer);

View File

@ -0,0 +1,18 @@
import Counter from "./components/counter.marko";
function getCounter() {
return Counter; // breaks tag name analysis.
}
import * as _$ from "@marko/runtime-tags/debug/html";
const _renderer = /* @__PURE__ */_$.createRenderer((input, _tagVar) => {
const _scope0_id = _$.nextScopeId();
_$.register(getCounter, "packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0/getCounter");
const _dynamicScope = _$.peekNextScope();
const count = _$.dynamicTagInput(_dynamicScope, getCounter(), {}, void 0, _$.register(() => {}, "packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0_count", _scope0_id));
_$.write(`${_$.markResumeControlEnd(_scope0_id, "#text/0")}<button class=reset>reset</button>${_$.markResumeNode(_scope0_id, "#button/1")}`);
_$.writeEffect(_scope0_id, "packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0");
_$.writeScope(_scope0_id, {
"#text/0!": _$.writeExistingScope(_dynamicScope),
"#text/0(": _$.normalizeDynamicRenderer(getCounter())
});
});
export default /* @__PURE__ */_$.createTemplate("packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko", _renderer);

View File

@ -0,0 +1,81 @@
# Render {}
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
2
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
3
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.reset").click()
```html
<button
class="inc"
>
0
</button>
<button
class="reset"
>
reset
</button>
```
# Render
container.querySelector("button.inc").click()
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```

View File

@ -0,0 +1,172 @@
# Render {}
```html
<html>
<head />
<body>
<!--M_[1-->
<button
class="inc"
>
1
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<!--M_]0 #text/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#text/0!":_.b={x:1},"#text/0(":_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko"]},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
removed #document/html0/body1/#comment0 before #document/html0
inserted #document/html0/body1/#comment0
```
# Render
container.querySelector("button.inc").click()
```html
<html>
<head />
<body>
<!--M_[1-->
<button
class="inc"
>
2
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<!--M_]0 #text/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#text/0!":_.b={x:1},"#text/0(":_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko"]},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
#document/html0/body1/button1/#text0: "1" => "2"
```
# Render
container.querySelector("button.inc").click()
```html
<html>
<head />
<body>
<!--M_[1-->
<button
class="inc"
>
3
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<!--M_]0 #text/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#text/0!":_.b={x:1},"#text/0(":_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko"]},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
#document/html0/body1/button1/#text0: "2" => "3"
```
# Render
container.querySelector("button.reset").click()
```html
<html>
<head />
<body>
<!--M_[1-->
<button
class="inc"
>
0
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<!--M_]0 #text/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#text/0!":_.b={x:1},"#text/0(":_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko"]},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
#document/html0/body1/button1/#text0: "3" => "0"
```
# Render
container.querySelector("button.inc").click()
```html
<html>
<head />
<body>
<!--M_[1-->
<button
class="inc"
>
1
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<!--M_]0 #text/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#text/0!":_.b={x:1},"#text/0(":_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko"]},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
#document/html0/body1/button1/#text0: "0" => "1"
```

View File

@ -0,0 +1,13 @@
# Render "End"
```html
<button
class="inc"
>
1
</button>
<button
class="reset"
>
reset
</button>
```

View File

@ -0,0 +1,48 @@
# Write
<!--M_[1--><button class=inc>1<!--M_*1 #text/1--></button><!--M_*1 #button/0--><!--M_]0 #text/0--><button class=reset>reset</button><!--M_*0 #button/1--><script>WALKER_RUNTIME("M")("_");M._.r=[_=>(_.c={0:_.a={"#text/0!":_.b={x:1},"#text/0(":_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko"]},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0",0];M._.w()</script>
# Render "End"
```html
<!--M_[1-->
<html>
<head />
<body>
<button
class="inc"
>
1
<!--M_*1 #text/1-->
</button>
<!--M_*1 #button/0-->
<!--M_]0 #text/0-->
<button
class="reset"
>
reset
</button>
<!--M_*0 #button/1-->
<script>
WALKER_RUNTIME("M")("_");M._.r=[_=&gt;(_.c={0:_.a={"#text/0!":_.b={x:1},"#text/0(":_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko"]},1:_.b},_.b["/"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0_count"](_.a),_.b["@"]=_._["packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0/valueChange"](_.b),_.c),1,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/components/counter.marko_0_x",0,"packages/translator-tags/src/__tests__/fixtures/dynamic-tag-var-assignment/template.marko_0",0];M._.w()
</script>
</body>
</html>
```
# Mutations
```
inserted #document/#comment0
inserted #document/html1
inserted #document/html1/head0
inserted #document/html1/body1
inserted #document/html1/body1/button0
inserted #document/html1/body1/button0/#text0
inserted #document/html1/body1/button0/#comment1
inserted #document/html1/body1/#comment1
inserted #document/html1/body1/#comment2
inserted #document/html1/body1/button3
inserted #document/html1/body1/button3/#text0
inserted #document/html1/body1/#comment4
inserted #document/html1/body1/script5
inserted #document/html1/body1/script5/#text0
```

View File

@ -0,0 +1,5 @@
<let/x = 1/>
<button.inc onClick() { x++ }>
${x}
</button>
<return:=x/>

View File

@ -0,0 +1,6 @@
import Counter from "<counter>";
static function getCounter() {
return Counter; // breaks tag name analysis.
}
<${getCounter()}/count/>
<button.reset onClick() { count = 0 }>reset</button>

View File

@ -0,0 +1,10 @@
const increment = (container: Element) => {
container.querySelector<HTMLButtonElement>("button.inc")!.click();
};
const reset = (container: Element) => {
container.querySelector<HTMLButtonElement>("button.reset")!.click();
};
export const steps = [{}, increment, increment, reset, increment];

View File

@ -1,5 +1,5 @@
at packages/translator-tags/src/__tests__/fixtures/error-return-extra-attr/template.marko:1:11
> 1 | <return=3 y=5/>
| ^^^ The `return` tag only supports the `value` attribute.
| ^^^ Tag does not support the `y` attribute.
2 |

View File

@ -1,5 +1,5 @@
at packages/translator-tags/src/__tests__/fixtures/error-return-extra-attr/template.marko:1:11
> 1 | <return=3 y=5/>
| ^^^ The `return` tag only supports the `value` attribute.
| ^^^ Tag does not support the `y` attribute.
2 |

View File

@ -1,5 +1,5 @@
at packages/translator-tags/src/__tests__/fixtures/error-return-spread-attr/template.marko:1:9
> 1 | <return ...{ value: 2 }/>
| ^^^^^^^^^^^^^^^ The `return` tag does not support `...spread` attributes.
| ^^^^^^^^^^^^^^^ Tag does not support spread attributes.
2 |

View File

@ -1,5 +1,5 @@
at packages/translator-tags/src/__tests__/fixtures/error-return-spread-attr/template.marko:1:9
> 1 | <return ...{ value: 2 }/>
| ^^^^^^^^^^^^^^^ The `return` tag does not support `...spread` attributes.
| ^^^^^^^^^^^^^^^ Tag does not support spread attributes.
2 |

View File

@ -1,17 +1,20 @@
import {
assertAllowedAttributes,
assertNoArgs,
assertNoParams,
assertNoVar,
type Tag,
} from "@marko/babel-utils";
import { types as t } from "@marko/compiler";
import { AccessorChar } from "@marko/runtime-tags/common/types";
import { assertNoBodyContent, assertNoSpreadAttrs } from "../util/assert";
import { isOutputHTML } from "../util/marko-config";
import { assertNoBodyContent } from "../util/assert";
import { getKnownAttrValues } from "../util/get-known-attr-values";
import { importRuntime } from "../util/runtime";
import { getSection } from "../util/sections";
import { addValue } from "../util/signals";
import { addValue, getSerializedScopeProperties } from "../util/signals";
import { createSectionState } from "../util/state";
import { translateByTarget } from "../util/visitors";
import * as writer from "../util/writer";
const [returnId, _setReturnId] = createSectionState<t.Identifier | undefined>(
@ -27,7 +30,7 @@ export default {
assertNoVar(tag);
assertNoParams(tag);
assertNoBodyContent(tag);
assertNoSpreadAttrs(tag);
assertAllowedAttributes(tag, ["value", "valueChange"]);
if (usedTag.has(tag.hub)) {
throw tag
@ -38,71 +41,75 @@ export default {
}
usedTag.add(tag.hub);
const { node } = tag;
const [valueAttr] = node.attributes;
if (!t.isMarkoAttribute(valueAttr) || !valueAttr.default) {
if (!getKnownAttrValues(tag.node).value) {
throw tag
.get("name")
.buildCodeFrameError("The `return` tag requires a value.");
}
if (
node.attributes.length > 1 &&
(node.attributes[1] as t.MarkoAttribute).name !== "valueChange"
) {
const start = node.attributes[1].loc?.start;
const end = node.attributes[node.attributes.length - 1].loc?.end;
const msg = "The `return` tag only supports the `value` attribute.";
if (start == null || end == null) {
throw tag.get("name").buildCodeFrameError(msg);
} else {
throw tag.hub.buildError(
{ loc: { start, end } } as unknown as t.Node,
msg,
Error,
);
}
}
},
translate: {
exit(tag) {
const section = getSection(tag);
const {
node: {
attributes: [{ value }],
},
hub: { file },
} = tag;
if (isOutputHTML()) {
translate: translateByTarget({
html: {
exit(tag) {
const section = getSection(tag);
const attrs = getKnownAttrValues(tag.node);
writer.flushBefore(tag);
const returnId = file.path.scope.generateUidIdentifier("return");
_setReturnId(section, returnId);
tag
.replaceWith(
t.variableDeclaration("const", [
t.variableDeclarator(returnId, value),
]),
)[0]
.skip();
} else {
addValue(
section,
value.extra?.referencedBindings,
{
identifier: importRuntime("tagVarSignal"),
hasDownstreamIntersections: () => true,
},
value,
);
if (attrs.valueChange) {
// TODO: this should be based on the child actually mutating the tag variable.
getSerializedScopeProperties(section).set(
t.stringLiteral(AccessorChar.TagVariableChange),
attrs.valueChange,
);
}
if (attrs.value) {
const returnId =
tag.hub.file.path.scope.generateUidIdentifier("return");
_setReturnId(section, returnId);
tag
.replaceWith(
t.variableDeclaration("const", [
t.variableDeclarator(returnId, attrs.value),
]),
)[0]
.skip();
}
},
},
dom: {
exit(tag) {
const section = getSection(tag);
const attrs = getKnownAttrValues(tag.node);
if (attrs.value) {
addValue(
section,
attrs.value.extra?.referencedBindings,
{
identifier: importRuntime("tagVarSignal"),
hasDownstreamIntersections: () => true,
},
attrs.value,
);
}
if (attrs.valueChange) {
addValue(
section,
attrs.valueChange.extra?.referencedBindings,
{
identifier: importRuntime("setTagVarChange"),
hasDownstreamIntersections: () => false,
},
attrs.valueChange,
);
}
tag.remove();
}
},
},
},
}),
autocomplete: [
{
displayText: "return=<value>",

View File

@ -28,7 +28,7 @@ import {
trackParamsReferences,
trackVarReferences,
} from "../../util/references";
import { callRuntime } from "../../util/runtime";
import { callRuntime, importRuntime } from "../../util/runtime";
import { createScopeReadExpression } from "../../util/scope-read";
import {
getOrCreateSection,
@ -296,6 +296,12 @@ function translateDOM(tag: t.NodePath<t.MarkoTag>) {
node.var.extra!.binding!,
);
source.register = true;
source.buildAssignment = (_valueSection, value) => {
return t.callExpression(importRuntime("tagVarSignalChange"), [
createScopeReadExpression(source.section, childScopeBinding),
value,
]);
};
addStatement(
"render",
tagSection,

View File

@ -20,7 +20,8 @@ import {
trackParamsReferences,
trackVarReferences,
} from "../../util/references";
import { callRuntime } from "../../util/runtime";
import { callRuntime, importRuntime } from "../../util/runtime";
import { getScopeExpression } from "../../util/scope-read";
import {
getOrCreateSection,
getScopeIdIdentifier,
@ -277,11 +278,25 @@ export default {
);
if (tag.node.var) {
const childScopeLiteral = t.stringLiteral(
getScopeAccessorLiteral(extra[kDOMBinding]!).value +
AccessorChar.ConditionalScope,
);
const source = initValue(
// TODO: support destructuring
tag.node.var.extra!.binding!,
);
source.register = true;
source.buildAssignment = (valueSection, value) => {
return t.callExpression(importRuntime("tagVarSignalChange"), [
t.memberExpression(
getScopeExpression(source.section, valueSection),
childScopeLiteral,
true,
),
value,
]);
};
addStatement(
"render",
@ -291,10 +306,7 @@ export default {
callRuntime(
"setTagVar",
scopeIdentifier,
t.stringLiteral(
getScopeAccessorLiteral(extra[kDOMBinding]!).value +
AccessorChar.ConditionalScope,
),
childScopeLiteral,
source.identifier,
),
),