Merge pull request #1245 from sveltejs/gh-1242-followup

don't treat :foo as a directive
pull/1246/head
Rich Harris 7 years ago committed by GitHub
commit 270e1d188b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -4,53 +4,52 @@ import { Parser } from '../index';
const DIRECTIVES = { const DIRECTIVES = {
Ref: { Ref: {
names: [ 'ref' ], names: ['ref'],
attribute(start, end, type, name) { attribute(start, end, type, name) {
return { start, end, type, name }; return { start, end, type, name };
} },
allowedExpressionTypes: [],
error: 'ref directives cannot have a value'
}, },
EventHandler: { EventHandler: {
names: [ 'on' ], names: ['on'],
allowedExpressionTypes: [ 'CallExpression' ], attribute(start, end, type, name, expression) {
return { start, end, type, name, expression };
},
allowedExpressionTypes: ['CallExpression'],
error: 'Expected a method call'
}, },
Binding: { Binding: {
names: [ '', 'bind' ], names: ['bind'],
allowedExpressionTypes: [ 'Identifier', 'MemberExpression' ], attribute(start, end, type, name, expression) {
attribute(start, end, type, name, expression, directiveName) { return {
let value; start, end, type, name,
value: expression || {
// :foo is shorthand for foo='{{foo}}'
if (!directiveName) {
const valueStart = start + 1;
const valueEnd = start + name.length;
type = 'Attribute';
value = getShorthandValue(start + 1, name);
} else {
value = expression || {
type: 'Identifier', type: 'Identifier',
start: start + 5, start: start + 5,
end, end,
name, name,
};
} }
};
return { start, end, type, name, value };
}, },
allowedExpressionTypes: ['Identifier', 'MemberExpression'],
error: 'Can only bind to an identifier (e.g. `foo`) or a member expression (e.g. `foo.bar` or `foo[baz]`)'
}, },
Transition: { Transition: {
names: [ 'in', 'out', 'transition' ], names: ['in', 'out', 'transition'],
allowedExpressionTypes: [ 'ObjectExpression' ],
attribute(start, end, type, name, expression, directiveName) { attribute(start, end, type, name, expression, directiveName) {
return { return {
start, end, type, name, expression, start, end, type, name, expression,
intro: directiveName === 'in' || directiveName === 'transition', intro: directiveName === 'in' || directiveName === 'transition',
outro: directiveName === 'out' || directiveName === 'transition', outro: directiveName === 'out' || directiveName === 'transition',
} };
},
}, },
allowedExpressionTypes: ['ObjectExpression'],
error: 'Transition argument must be an object literal, e.g. `{ duration: 400 }`'
}
}; };
@ -83,7 +82,7 @@ function readExpression(parser: Parser, start: number, quoteMark: string|null) {
} else { } else {
str += char; str += char;
} }
} else if (/[\s\r\n\/>]/.test(char)) { } else if (/[\s\/>]/.test(char)) {
break; break;
} else { } else {
str += char; str += char;
@ -106,9 +105,20 @@ export function readDirective(
start: number, start: number,
attrName: string attrName: string
) { ) {
const [ directiveName, name ] = attrName.split(':'); const [directiveName, name] = attrName.split(':');
if (name === undefined) return; // No colon in the name if (name === undefined) return; // No colon in the name
if (directiveName === '') {
// not a directive — :foo is short for foo={{foo}}
return {
start: start,
end: start + name.length + 1,
type: 'Attribute',
name,
value: getShorthandValue(start + 1, name)
};
}
const type = lookupByName[directiveName]; const type = lookupByName[directiveName];
if (!type) return; // not a registered directive if (!type) return; // not a registered directive
@ -133,21 +143,11 @@ export function readDirective(
expression = readExpression(parser, expressionStart, quoteMark); expression = readExpression(parser, expressionStart, quoteMark);
if (directive.allowedExpressionTypes.indexOf(expression.type) === -1) { if (directive.allowedExpressionTypes.indexOf(expression.type) === -1) {
parser.error(`Expected ${directive.allowedExpressionTypes.join(' or ')}`, expressionStart); parser.error(directive.error, expressionStart);
} }
} }
if (directive.attribute) {
return directive.attribute(start, parser.index, type, name, expression, directiveName); return directive.attribute(start, parser.index, type, name, expression, directiveName);
} else {
return {
start,
end: parser.index,
type: type,
name,
expression,
};
}
} }

@ -1,5 +1,5 @@
{ {
"message": "Expected Identifier or MemberExpression", "message": "Can only bind to an identifier (e.g. `foo`) or a member expression (e.g. `foo.bar` or `foo[baz]`)",
"pos": 19, "pos": 19,
"loc": { "loc": {
"line": 1, "line": 1,

@ -1,5 +1,5 @@
{ {
"message": "Expected CallExpression", "message": "Expected a method call",
"loc": { "loc": {
"line": 1, "line": 1,
"column": 15 "column": 15

@ -0,0 +1,8 @@
{
"message": "ref directives cannot have a value",
"loc": {
"line": 1,
"column": 14
},
"pos": 14
}
Loading…
Cancel
Save