diff --git a/packages/csp/src/evaluator.js b/packages/csp/src/evaluator.js index 7a2d2ed30..c0f12be87 100644 --- a/packages/csp/src/evaluator.js +++ b/packages/csp/src/evaluator.js @@ -28,11 +28,18 @@ function generateEvaluator(el, expression, dataStack) { return (receiver = () => {}, { scope = {}, params = [] } = {}) => { let completeScope = mergeProxies([scope, ...dataStack]) - if (completeScope[expression] === undefined) { - throwExpressionError(el, expression) - } - - runIfTypeOfFunction(receiver, completeScope[expression], completeScope, params) + let evaluatedExpression = expression.split('.').reduce( + (currentScope, currentExpression) => { + if (currentScope[currentExpression] === undefined) { + throwExpressionError(el, expression) + } + + return currentScope[currentExpression] + }, + completeScope, + ); + + runIfTypeOfFunction(receiver, evaluatedExpression, completeScope, params) } } diff --git a/packages/docs/src/en/advanced/csp.md b/packages/docs/src/en/advanced/csp.md index 1d3286750..8a3233dac 100644 --- a/packages/docs/src/en/advanced/csp.md +++ b/packages/docs/src/en/advanced/csp.md @@ -118,3 +118,26 @@ Alpine.data('counter', () => ({ }, })) ``` + +The CSP build supports accessing nested properties (property accessors) using the dot notation. + +```alpine + +
+ + + +
+``` + +```js +Alpine.data('counter', () => ({ + foo: { + count: 1, + + increment() { + this.count++ + }, + }, +})) +``` diff --git a/tests/cypress/integration/plugins/csp-compatibility.spec.js b/tests/cypress/integration/plugins/csp-compatibility.spec.js index 97e9e3e6b..94290cda8 100644 --- a/tests/cypress/integration/plugins/csp-compatibility.spec.js +++ b/tests/cypress/integration/plugins/csp-compatibility.spec.js @@ -20,3 +20,26 @@ test.csp('Can use components and basic expressions with CSP-compatible build', get('span').should(haveText('baz')) } ) + +test.csp('Supports nested properties', + [html` +
+ + + +
+ `, + ` + Alpine.data('test', () => ({ + foo: { + bar: 'baz', + change() { this.foo.bar = 'qux' }, + } + })) + `], + ({ get }) => { + get('span').should(haveText('baz')) + get('button').click() + get('span').should(haveText('qux')) + } +)