Skip to content

Commit

Permalink
[CSP] Add support for nested properties to CSP build (#4238)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimoTod committed May 28, 2024
1 parent 5664930 commit 2ddfff2
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 5 deletions.
17 changes: 12 additions & 5 deletions packages/csp/src/evaluator.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand Down
23 changes: 23 additions & 0 deletions packages/docs/src/en/advanced/csp.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,26 @@ Alpine.data('counter', () => ({
},
}))
```

The CSP build supports accessing nested properties (property accessors) using the dot notation.

```alpine
<!-- This works too -->
<div x-data="counter">
<button @click="foo.increment">Increment</button>
<span x-text="foo.count"></span>
</div>
```

```js
Alpine.data('counter', () => ({
foo: {
count: 1,

increment() {
this.count++
},
},
}))
```
23 changes: 23 additions & 0 deletions tests/cypress/integration/plugins/csp-compatibility.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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`
<div x-data="test">
<span x-text="foo.bar"></span>
<button @click="foo.change">Change Foo</button>
</div>
`,
`
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'))
}
)

0 comments on commit 2ddfff2

Please sign in to comment.