Skip to content

Commit

Permalink
fix(compiler): recover event parse when animation event name is empty (
Browse files Browse the repository at this point in the history
…#39925)

Now when the animation trigger output event is missing its phase value name, the `BoundEvent` will be ignored,
but it's useful for completion in language service.

PR Close #39925
  • Loading branch information
ivanwonder authored and atscott committed Jan 7, 2021
1 parent 5704372 commit 15b15be
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 20 deletions.
26 changes: 12 additions & 14 deletions packages/compiler/src/template_parser/binding_parser.ts
Expand Up @@ -443,21 +443,19 @@ export class BindingParser {
const matches = splitAtPeriod(name, [name, '']);
const eventName = matches[0];
const phase = matches[1].toLowerCase();
const ast = this._parseAction(expression, handlerSpan);
targetEvents.push(new ParsedEvent(
eventName, phase, ParsedEventType.Animation, ast, sourceSpan, handlerSpan, keySpan));

if (eventName.length === 0) {
this._reportError(`Animation event name is missing in binding`, sourceSpan);
}
if (phase) {
switch (phase) {
case 'start':
case 'done':
const ast = this._parseAction(expression, handlerSpan);
targetEvents.push(new ParsedEvent(
eventName, phase, ParsedEventType.Animation, ast, sourceSpan, handlerSpan, keySpan));
break;

default:
this._reportError(
`The provided animation output phase value "${phase}" for "@${
eventName}" is not supported (use start or done)`,
sourceSpan);
break;
if (phase !== 'start' && phase !== 'done') {
this._reportError(
`The provided animation output phase value "${phase}" for "@${
eventName}" is not supported (use start or done)`,
sourceSpan);
}
} else {
this._reportError(
Expand Down
25 changes: 23 additions & 2 deletions packages/compiler/test/render3/r3_template_transform_spec.ts
Expand Up @@ -92,8 +92,8 @@ class R3AstHumanizer implements t.Visitor<void> {
}
}

function expectFromHtml(html: string) {
const res = parse(html);
function expectFromHtml(html: string, ignoreError = false) {
const res = parse(html, {ignoreError});
return expectFromR3Nodes(res.nodes);
}

Expand Down Expand Up @@ -399,6 +399,27 @@ describe('R3 template transform', () => {
expect(() => parse('<div (event)="">')).toThrowError(/Empty expressions are not allowed/);
expect(() => parse('<div (event)=" ">')).toThrowError(/Empty expressions are not allowed/);
});

it('should parse bound animation events when event name is empty', () => {
expectFromHtml('<div (@)="onAnimationEvent($event)"></div>', true).toEqual([
['Element', 'div'],
['BoundEvent', '', null, 'onAnimationEvent($event)'],
]);
expect(() => parse('<div (@)></div>'))
.toThrowError(/Animation event name is missing in binding/);
});

it('should report invalid phase value of animation event', () => {
expect(() => parse('<div (@event.invalidPhase)></div>'))
.toThrowError(
/The provided animation output phase value "invalidphase" for "@event" is not supported \(use start or done\)/);
expect(() => parse('<div (@event.)></div>'))
.toThrowError(
/The animation trigger output event \(@event\) is missing its phase value name \(start or done are currently supported\)/);
expect(() => parse('<div (@event)></div>'))
.toThrowError(
/The animation trigger output event \(@event\) is missing its phase value name \(start or done are currently supported\)/);
});
});

describe('variables', () => {
Expand Down
10 changes: 6 additions & 4 deletions packages/compiler/test/render3/view/util.ts
Expand Up @@ -78,15 +78,17 @@ export function toStringExpression(expr: e.AST): string {

// Parse an html string to IVY specific info
export function parseR3(
input: string, options: {preserveWhitespaces?: boolean, leadingTriviaChars?: string[]} = {}):
Render3ParseResult {
input: string,
options: {preserveWhitespaces?: boolean,
leadingTriviaChars?: string[],
ignoreError?: boolean} = {}): Render3ParseResult {
const htmlParser = new HtmlParser();

const parseResult = htmlParser.parse(
input, 'path:://to/template',
{tokenizeExpansionForms: true, leadingTriviaChars: options.leadingTriviaChars});

if (parseResult.errors.length > 0) {
if (parseResult.errors.length > 0 && !options.ignoreError) {
const msg = parseResult.errors.map(e => e.toString()).join('\n');
throw new Error(msg);
}
Expand All @@ -105,7 +107,7 @@ export function parseR3(
new BindingParser(expressionParser, DEFAULT_INTERPOLATION_CONFIG, schemaRegistry, null, []);
const r3Result = htmlAstToRender3Ast(htmlNodes, bindingParser);

if (r3Result.errors.length > 0) {
if (r3Result.errors.length > 0 && !options.ignoreError) {
const msg = r3Result.errors.map(e => e.toString()).join('\n');
throw new Error(msg);
}
Expand Down

0 comments on commit 15b15be

Please sign in to comment.