diff --git a/src/compile/nodes/shared/Expression.ts b/src/compile/nodes/shared/Expression.ts index 2e11e8dd18..e97cc610fa 100644 --- a/src/compile/nodes/shared/Expression.ts +++ b/src/compile/nodes/shared/Expression.ts @@ -256,6 +256,12 @@ export default class Expression { pending_assignments.add(name); } }); + } else if (node.type === 'UpdateExpression') { + const { name } = getObject(node.argument); + + if (!scope.declarations.has(name)) { + pending_assignments.add(name); + } } } else { if (node.type === 'AssignmentExpression') { diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts index 2bf4eb821a..ba78e51afa 100644 --- a/src/compile/render-dom/index.ts +++ b/src/compile/render-dom/index.ts @@ -181,6 +181,15 @@ export default function dom( }); } + else if (node.type === 'UpdateExpression') { + const { name } = getObject(node.argument); + + if (scope.findOwner(name) === component.instance_scope) { + pending_assignments.add(name); + component.has_reactive_assignments = true; + } + } + if (pending_assignments.size > 0) { if (node.type === 'ArrowFunctionExpression') { const insert = [...pending_assignments].map(name => `$$make_dirty('${name}')`).join(';'); diff --git a/src/utils/getObject.ts b/src/utils/getObject.ts index 4cde63eb8f..4393d5ff9a 100644 --- a/src/utils/getObject.ts +++ b/src/utils/getObject.ts @@ -1,6 +1,7 @@ import { Node } from '../interfaces'; export default function getObject(node: Node) { + while (node.type === 'ParenthesizedExpression') node = node.expression; while (node.type === 'MemberExpression') node = node.object; return node; } diff --git a/test/runtime/samples/instrumentation-script-update/_config.js b/test/runtime/samples/instrumentation-script-update/_config.js new file mode 100644 index 0000000000..4e97140faf --- /dev/null +++ b/test/runtime/samples/instrumentation-script-update/_config.js @@ -0,0 +1,17 @@ +export default { + html: ` + +
x: 0
+ `, + + async test({ assert, component, target, window }) { + const buttons = target.querySelectorAll('button'); + const click = new window.MouseEvent('click'); + + await buttons[0].dispatchEvent(click); + assert.htmlEqual(target.innerHTML, ` + +x: 1
+ `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/instrumentation-script-update/main.html b/test/runtime/samples/instrumentation-script-update/main.html new file mode 100644 index 0000000000..2ab583a96a --- /dev/null +++ b/test/runtime/samples/instrumentation-script-update/main.html @@ -0,0 +1,11 @@ + + + + +x: {x}
\ No newline at end of file diff --git a/test/runtime/samples/instrumentation-template-update/_config.js b/test/runtime/samples/instrumentation-template-update/_config.js new file mode 100644 index 0000000000..4e97140faf --- /dev/null +++ b/test/runtime/samples/instrumentation-template-update/_config.js @@ -0,0 +1,17 @@ +export default { + html: ` + +x: 0
+ `, + + async test({ assert, component, target, window }) { + const buttons = target.querySelectorAll('button'); + const click = new window.MouseEvent('click'); + + await buttons[0].dispatchEvent(click); + assert.htmlEqual(target.innerHTML, ` + +x: 1
+ `); + } +}; \ No newline at end of file diff --git a/test/runtime/samples/instrumentation-template-update/main.html b/test/runtime/samples/instrumentation-template-update/main.html new file mode 100644 index 0000000000..8ace384c32 --- /dev/null +++ b/test/runtime/samples/instrumentation-template-update/main.html @@ -0,0 +1,7 @@ + + + + +x: {x}
\ No newline at end of file