mirror of
https://github.com/marko-js/marko.git
synced 2025-12-08 19:26:05 +00:00
fix: prevent increment decrement from pruning change handler binding (#2913)
* fix: prevent increment decrement from pruning change handler binding
This commit is contained in:
parent
917c88ed23
commit
280f4d3141
5
.changeset/lemon-plums-visit.md
Normal file
5
.changeset/lemon-plums-visit.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"@marko/runtime-tags": patch
|
||||
---
|
||||
|
||||
Ensure increment and decrement assignments don't prune change handler bindings
|
||||
@ -0,0 +1,16 @@
|
||||
{
|
||||
"vars": {
|
||||
"props": {
|
||||
"$_": "o",
|
||||
"$init": "t",
|
||||
"$$pattern2": "n",
|
||||
"$$bar": "r",
|
||||
"$$foo2__script": "m",
|
||||
"$$foo2": "e",
|
||||
"$$foo": "a",
|
||||
"$$foo__OR__fooChange__script": "c",
|
||||
"$$foo__OR__fooChange": "_",
|
||||
"$$fooChange2": "f"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
# Render
|
||||
```html
|
||||
<button>
|
||||
0:0
|
||||
</button>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button>
|
||||
1:1
|
||||
</button>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button>
|
||||
2:2
|
||||
</button>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button>
|
||||
3:3
|
||||
</button>
|
||||
```
|
||||
@ -0,0 +1,59 @@
|
||||
# Render
|
||||
```html
|
||||
<button>
|
||||
0:0
|
||||
</button>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
INSERT button
|
||||
```
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button>
|
||||
1:1
|
||||
</button>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE button/#text2 "0" => "1"
|
||||
UPDATE button/#text0 "0" => "1"
|
||||
```
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button>
|
||||
2:2
|
||||
</button>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE button/#text2 "1" => "2"
|
||||
UPDATE button/#text0 "1" => "2"
|
||||
```
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button>
|
||||
3:3
|
||||
</button>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE button/#text2 "2" => "3"
|
||||
UPDATE button/#text0 "2" => "3"
|
||||
```
|
||||
@ -0,0 +1,26 @@
|
||||
// size: 330 (min) 206 (brotli)
|
||||
const $pattern2 = _._const(4, ($scope, $pattern) => {
|
||||
($foo2($scope, $pattern.foo), $fooChange2($scope, $pattern.fooChange));
|
||||
}),
|
||||
$bar = _._let(3, ($scope, bar) => {
|
||||
(_._text($scope[2], bar),
|
||||
$pattern2($scope, { foo: bar, fooChange: $foo($scope) }));
|
||||
}),
|
||||
$foo__OR__fooChange__script = _._script(
|
||||
"a1",
|
||||
($scope, { 5: foo, 6: $fooChange }) =>
|
||||
_._on($scope[0], "click", function () {
|
||||
$fooChange(++foo);
|
||||
}),
|
||||
),
|
||||
$foo__OR__fooChange = _._or(7, $foo__OR__fooChange__script),
|
||||
$foo2 = _._const(5, ($scope, foo) => {
|
||||
(_._text($scope[1], foo), $foo__OR__fooChange($scope));
|
||||
}),
|
||||
$fooChange2 = _._const(6, $foo__OR__fooChange);
|
||||
function $foo($scope) {
|
||||
return function (v) {
|
||||
$bar($scope, v);
|
||||
};
|
||||
}
|
||||
(_._resume("a0", $foo), init());
|
||||
@ -0,0 +1,36 @@
|
||||
export const $template = "<button><!>:<!></button>";
|
||||
export const $walks = /* get, next(1), replace, over(2), replace, out(1) */" D%c%l";
|
||||
import * as _ from "@marko/runtime-tags/debug/dom";
|
||||
const $pattern2 = /* @__PURE__ */_._const("$pattern", ($scope, $pattern) => {
|
||||
$foo2($scope, $pattern.foo);
|
||||
$fooChange2($scope, $pattern.fooChange);
|
||||
});
|
||||
const $bar = /* @__PURE__ */_._let("bar/3", ($scope, bar) => {
|
||||
_._text($scope["#text/2"], bar);
|
||||
$pattern2($scope, {
|
||||
foo: bar,
|
||||
fooChange: $foo($scope)
|
||||
});
|
||||
});
|
||||
export function $setup($scope) {
|
||||
$bar($scope, 0);
|
||||
}
|
||||
const $foo__OR__fooChange__script = _._script("__tests__/template.marko_0_foo_$fooChange", ($scope, {
|
||||
foo,
|
||||
$fooChange
|
||||
}) => _._on($scope["#button/0"], "click", function () {
|
||||
$fooChange(++foo);
|
||||
}));
|
||||
const $foo__OR__fooChange = /* @__PURE__ */_._or(7, $foo__OR__fooChange__script);
|
||||
const $foo2 = /* @__PURE__ */_._const("foo", ($scope, foo) => {
|
||||
_._text($scope["#text/1"], foo);
|
||||
$foo__OR__fooChange($scope);
|
||||
});
|
||||
const $fooChange2 = /* @__PURE__ */_._const("$fooChange", $foo__OR__fooChange);
|
||||
function $foo($scope) {
|
||||
return function (v) {
|
||||
$bar($scope, v);
|
||||
};
|
||||
}
|
||||
_._resume("__tests__/template.marko_0/foo", $foo);
|
||||
export default /* @__PURE__ */_._template("__tests__/template.marko", $template, $walks, $setup);
|
||||
@ -0,0 +1,24 @@
|
||||
import * as _ from "@marko/runtime-tags/debug/html";
|
||||
export default _._template("__tests__/template.marko", input => {
|
||||
const $scope0_id = _._scope_id();
|
||||
let bar = 0;
|
||||
const {
|
||||
foo,
|
||||
fooChange: $fooChange
|
||||
} = {
|
||||
foo: bar,
|
||||
fooChange: _._resume(function (v) {
|
||||
bar = v;
|
||||
}, "__tests__/template.marko_0/foo", $scope0_id)
|
||||
};
|
||||
_._html(`<button>${_._escape(foo)}${_._el_resume($scope0_id, "#text/1")}:<!>${_._escape(bar)}${_._el_resume($scope0_id, "#text/2")}</button>${_._el_resume($scope0_id, "#button/0")}`);
|
||||
_._script($scope0_id, "__tests__/template.marko_0_foo_$fooChange");
|
||||
_._scope($scope0_id, {
|
||||
foo,
|
||||
$fooChange
|
||||
}, "__tests__/template.marko", 0, {
|
||||
foo: "2:9",
|
||||
$fooChange: "9:20"
|
||||
});
|
||||
_._resume_branch($scope0_id);
|
||||
});
|
||||
@ -0,0 +1,39 @@
|
||||
# Render
|
||||
```html
|
||||
<button>
|
||||
0:0
|
||||
</button>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button>
|
||||
1:1
|
||||
</button>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button>
|
||||
2:2
|
||||
</button>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<button>
|
||||
3:3
|
||||
</button>
|
||||
```
|
||||
@ -0,0 +1,147 @@
|
||||
# Render
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<button>
|
||||
0
|
||||
<!--M_*1 #text/1-->
|
||||
:
|
||||
<!---->
|
||||
0
|
||||
<!--M_*1 #text/2-->
|
||||
</button>
|
||||
<!--M_*1 #button/0-->
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.b = [0, _.a = {
|
||||
foo: 0
|
||||
}], _.a.$fooChange = _._[
|
||||
"__tests__/template.marko_0/foo"
|
||||
](_.a), _.b),
|
||||
"__tests__/template.marko_0_foo_$fooChange",
|
||||
1
|
||||
];
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<button>
|
||||
1
|
||||
<!--M_*1 #text/1-->
|
||||
:
|
||||
<!---->
|
||||
1
|
||||
<!--M_*1 #text/2-->
|
||||
</button>
|
||||
<!--M_*1 #button/0-->
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.b = [0, _.a = {
|
||||
foo: 0
|
||||
}], _.a.$fooChange = _._[
|
||||
"__tests__/template.marko_0/foo"
|
||||
](_.a), _.b),
|
||||
"__tests__/template.marko_0_foo_$fooChange",
|
||||
1
|
||||
];
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE html/body/button/#text2 "0" => "1"
|
||||
UPDATE html/body/button/#text0 "0" => "1"
|
||||
```
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<button>
|
||||
2
|
||||
<!--M_*1 #text/1-->
|
||||
:
|
||||
<!---->
|
||||
2
|
||||
<!--M_*1 #text/2-->
|
||||
</button>
|
||||
<!--M_*1 #button/0-->
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.b = [0, _.a = {
|
||||
foo: 0
|
||||
}], _.a.$fooChange = _._[
|
||||
"__tests__/template.marko_0/foo"
|
||||
](_.a), _.b),
|
||||
"__tests__/template.marko_0_foo_$fooChange",
|
||||
1
|
||||
];
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE html/body/button/#text2 "1" => "2"
|
||||
UPDATE html/body/button/#text0 "1" => "2"
|
||||
```
|
||||
|
||||
# Render
|
||||
```js
|
||||
container.querySelector("button").click();
|
||||
```
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<button>
|
||||
3
|
||||
<!--M_*1 #text/1-->
|
||||
:
|
||||
<!---->
|
||||
3
|
||||
<!--M_*1 #text/2-->
|
||||
</button>
|
||||
<!--M_*1 #button/0-->
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.b = [0, _.a = {
|
||||
foo: 0
|
||||
}], _.a.$fooChange = _._[
|
||||
"__tests__/template.marko_0/foo"
|
||||
](_.a), _.b),
|
||||
"__tests__/template.marko_0_foo_$fooChange",
|
||||
1
|
||||
];
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
UPDATE html/body/button/#text2 "2" => "3"
|
||||
UPDATE html/body/button/#text0 "2" => "3"
|
||||
```
|
||||
@ -0,0 +1,6 @@
|
||||
# Render End
|
||||
```html
|
||||
<button>
|
||||
0:0
|
||||
</button>
|
||||
```
|
||||
@ -0,0 +1,51 @@
|
||||
# Write
|
||||
```html
|
||||
<button>0<!--M_*1 #text/1-->:<!>0<!--M_*1 #text/2--></button><!--M_*1 #button/0--><script>WALKER_RUNTIME("M")("_");M._.r=[_=>(_.b=[0,_.a={foo:0}],_.a.$fooChange=_._["__tests__/template.marko_0/foo"](_.a),_.b),"__tests__/template.marko_0_foo_$fooChange",1];M._.w()</script>
|
||||
```
|
||||
|
||||
# Render End
|
||||
```html
|
||||
<html>
|
||||
<head />
|
||||
<body>
|
||||
<button>
|
||||
0
|
||||
<!--M_*1 #text/1-->
|
||||
:
|
||||
<!---->
|
||||
0
|
||||
<!--M_*1 #text/2-->
|
||||
</button>
|
||||
<!--M_*1 #button/0-->
|
||||
<script>
|
||||
WALKER_RUNTIME("M")("_");
|
||||
M._.r = [_ => (_.b = [0, _.a = {
|
||||
foo: 0
|
||||
}], _.a.$fooChange = _._[
|
||||
"__tests__/template.marko_0/foo"
|
||||
](_.a), _.b),
|
||||
"__tests__/template.marko_0_foo_$fooChange",
|
||||
1
|
||||
];
|
||||
M._.w()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
# Mutations
|
||||
```
|
||||
INSERT html
|
||||
INSERT html/head
|
||||
INSERT html/body
|
||||
INSERT html/body/button
|
||||
INSERT html/body/button/#text0
|
||||
INSERT html/body/button/#comment0
|
||||
INSERT html/body/button/#text1
|
||||
INSERT html/body/button/#comment1
|
||||
INSERT html/body/button/#text2
|
||||
INSERT html/body/button/#comment2
|
||||
INSERT html/body/#comment
|
||||
INSERT html/body/script
|
||||
INSERT html/body/script/#text
|
||||
```
|
||||
@ -0,0 +1,10 @@
|
||||
let/bar=0
|
||||
const/{ foo }={
|
||||
foo: bar,
|
||||
fooChange(v) {
|
||||
bar = v;
|
||||
}
|
||||
}
|
||||
|
||||
button onClick() { foo++ }
|
||||
-- ${foo}:${bar}
|
||||
@ -0,0 +1,5 @@
|
||||
export const steps = [{}, click, click, click];
|
||||
|
||||
function click(container: Element) {
|
||||
container.querySelector("button")!.click();
|
||||
}
|
||||
@ -1730,10 +1730,9 @@ function resolveReferencedBindings(
|
||||
const rootBindings = getRootBindings(reads);
|
||||
for (const read of reads) {
|
||||
let { binding } = read;
|
||||
if (read.node) {
|
||||
const exprReference = ((read.node.extra ??= {}).read ??=
|
||||
if (read.node && read.node.extra?.assignmentTo !== binding) {
|
||||
({ binding } = (read.node.extra ??= {}).read ??=
|
||||
resolveExpressionReference(rootBindings, binding));
|
||||
({ binding } = (read.node.extra ??= {}).read = exprReference);
|
||||
}
|
||||
referencedBindings = bindingUtil.add(referencedBindings, binding);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user