allow event handlers to call store methods

pull/951/head
Rich Harris 7 years ago
parent 945d8ce526
commit a87d30e0e6

@ -1,6 +1,6 @@
import flattenReference from '../../utils/flattenReference';
import list from '../../utils/list';
import { Validator } from '../index';
import validate, { Validator } from '../index';
import validCalleeObjects from '../../utils/validCalleeObjects';
import { Node } from '../../interfaces';
@ -28,6 +28,13 @@ export default function validateEventHandlerCallee(
return;
}
if (name === 'store' && attribute.expression.callee.type === 'MemberExpression') {
if (!validator.options.store) {
validator.warn('compile with `store: true` in order to call store methods', attribute.expression.start);
}
return;
}
if (
(callee.type === 'Identifier' && validBuiltins.has(callee.name)) ||
validator.methods.has(callee.name)
@ -35,6 +42,7 @@ export default function validateEventHandlerCallee(
return;
const validCallees = ['this.*', 'event.*', 'options.*', 'console.*'].concat(
validator.options.store ? 'store.*' : [],
Array.from(validBuiltins),
Array.from(validator.methods.keys())
);

@ -22,6 +22,7 @@ export class Validator {
readonly source: string;
readonly filename: string;
options: CompileOptions;
onwarn: ({}) => void;
locator?: (pos: number) => Location;
@ -37,8 +38,8 @@ export class Validator {
constructor(parsed: Parsed, source: string, options: CompileOptions) {
this.source = source;
this.filename = options.filename;
this.onwarn = options.onwarn;
this.options = options;
this.namespace = null;
this.defaultExport = null;
@ -78,7 +79,7 @@ export default function validate(
stylesheet: Stylesheet,
options: CompileOptions
) {
const { onwarn, onerror, name, filename } = options;
const { onwarn, onerror, name, filename, store } = options;
try {
if (name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) {
@ -99,6 +100,7 @@ export default function validate(
onwarn,
name,
filename,
store
});
if (parsed.js) {

@ -0,0 +1 @@
<input on:input='store.setName(this.value)'>

@ -0,0 +1,34 @@
import Store from '../../../../store.js';
class MyStore extends Store {
setName(name) {
this.set({ name });
}
}
const store = new MyStore({
name: 'world'
});
export default {
store,
html: `
<h1>Hello world!</h1>
<input>
`,
test(assert, component, target, window) {
const input = target.querySelector('input');
const event = new window.Event('input');
input.value = 'everybody';
input.dispatchEvent(event);
assert.equal(store.get('name'), 'everybody');
assert.htmlEqual(target.innerHTML, `
<h1>Hello everybody!</h1>
<input>
`);
}
};

@ -0,0 +1,10 @@
<h1>Hello {{$name}}!</h1>
<NameInput/>
<script>
import NameInput from './NameInput.html';
export default {
components: { NameInput }
};
</script>

@ -0,0 +1 @@
<button on:click='store.foo()'>foo</button>

@ -0,0 +1,8 @@
[{
"message": "compile with `store: true` in order to call store methods",
"loc": {
"line": 1,
"column": 18
},
"pos": 18
}]
Loading…
Cancel
Save