parse transition directives

pull/525/head
Rich-Harris 8 years ago
parent 9427f63b95
commit 2784ae0ade

@ -1,19 +1,11 @@
import { parse, parseExpressionAt } from 'acorn';
import { parseExpressionAt } from 'acorn';
import spaces from '../../utils/spaces.js';
export function readEventHandlerDirective ( parser, start, name ) {
const quoteMark = (
parser.eat( `'` ) ? `'` :
parser.eat( `"` ) ? `"` :
null
);
const expressionStart = parser.index;
function readExpression ( parser, start, quoteMark ) {
let str = '';
let escaped = false;
for ( let i = expressionStart; i < parser.template.length; i += 1 ) {
for ( let i = start; i < parser.template.length; i += 1 ) {
const char = parser.template[i];
if ( quoteMark ) {
@ -21,7 +13,6 @@ export function readEventHandlerDirective ( parser, start, name ) {
if ( escaped ) {
str += quoteMark;
} else {
parser.index = i + 1;
break;
}
} else if ( escaped ) {
@ -35,7 +26,6 @@ export function readEventHandlerDirective ( parser, start, name ) {
}
else if ( /\s/.test( char ) ) {
parser.index = i;
break;
}
@ -44,13 +34,25 @@ export function readEventHandlerDirective ( parser, start, name ) {
}
}
const ast = parse( spaces( expressionStart ) + str );
const expression = parseExpressionAt( spaces( start ) + str, start );
parser.index = expression.end;
if ( ast.body.length > 1 ) {
parser.error( `Event handler should be a single call expression`, ast.body[1].start );
}
parser.allowWhitespace();
if ( quoteMark ) parser.eat( quoteMark, true );
const expression = ast.body[0].expression;
return expression;
}
export function readEventHandlerDirective ( parser, start, name ) {
const quoteMark = (
parser.eat( `'` ) ? `'` :
parser.eat( `"` ) ? `"` :
null
);
const expressionStart = parser.index;
const expression = readExpression( parser, expressionStart, quoteMark );
if ( expression.type !== 'CallExpression' ) {
parser.error( `Expected call expression`, expressionStart );
@ -127,3 +129,29 @@ export function readBindingDirective ( parser, start, name ) {
value
};
}
export function readTransitionDirective ( parser, start, name, type ) {
const quoteMark = (
parser.eat( `'` ) ? `'` :
parser.eat( `"` ) ? `"` :
null
);
const expressionStart = parser.index;
const expression = readExpression( parser, expressionStart, quoteMark );
if ( expression.type !== 'ObjectExpression' ) {
parser.error( `Expected object expression`, expressionStart );
}
return {
start,
end: parser.index,
type: 'Transition',
name,
intro: type === 'in' || type === 'transition',
outro: type === 'out' || type === 'transition',
expression
};
}

@ -1,7 +1,7 @@
import readExpression from '../read/expression.js';
import readScript from '../read/script.js';
import readStyle from '../read/style.js';
import { readEventHandlerDirective, readBindingDirective } from '../read/directives.js';
import { readEventHandlerDirective, readBindingDirective, readTransitionDirective } from '../read/directives.js';
import { trimStart, trimEnd } from '../../utils/trim.js';
import { decodeCharacterReferences } from '../utils/html.js';
import isVoidElementName from '../../utils/isVoidElementName.js';
@ -253,6 +253,12 @@ function readAttribute ( parser, uniqueNames ) {
};
}
const match = /^(in|out|transition):/.exec( name );
if ( match ) {
parser.eat( '=', true );
return readTransitionDirective( parser, start, name.slice( match[0].length ), match[1] );
}
let value;
// :foo is shorthand for foo='{{foo}}'

@ -0,0 +1 @@
<div in:style='{opacity: 0}'>fades in</div>

@ -0,0 +1,65 @@
{
"hash": 3160753914,
"html": {
"start": 0,
"end": 43,
"type": "Fragment",
"children": [
{
"start": 0,
"end": 43,
"type": "Element",
"name": "div",
"attributes": [
{
"start": 5,
"end": 28,
"type": "Transition",
"name": "style",
"intro": true,
"outro": false,
"expression": {
"start": 15,
"end": 27,
"type": "ObjectExpression",
"properties": [
{
"start": 16,
"end": 26,
"type": "Property",
"method": false,
"computed": false,
"shorthand": false,
"kind": "init",
"key": {
"type": "Identifier",
"start": 16,
"end": 23,
"name": "opacity"
},
"value": {
"start": 25,
"end": 26,
"type": "Literal",
"value": 0,
"raw": "0"
}
}
]
}
}
],
"children": [
{
"start": 29,
"end": 37,
"type": "Text",
"data": "fades in"
}
]
}
]
},
"css": null,
"js": null
}
Loading…
Cancel
Save