fix(compiler): recover event parse when animation event name is empty (#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
This commit is contained in:
parent
57043721db
commit
15b15be259
|
@ -443,21 +443,19 @@ export class BindingParser {
|
|||
const matches = splitAtPeriod(name, [name, '']);
|
||||
const eventName = matches[0];
|
||||
const phase = matches[1].toLowerCase();
|
||||
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;
|
||||
const ast = this._parseAction(expression, handlerSpan);
|
||||
targetEvents.push(new ParsedEvent(
|
||||
eventName, phase, ParsedEventType.Animation, ast, sourceSpan, handlerSpan, keySpan));
|
||||
|
||||
default:
|
||||
this._reportError(
|
||||
`The provided animation output phase value "${phase}" for "@${
|
||||
eventName}" is not supported (use start or done)`,
|
||||
sourceSpan);
|
||||
break;
|
||||
if (eventName.length === 0) {
|
||||
this._reportError(`Animation event name is missing in binding`, sourceSpan);
|
||||
}
|
||||
if (phase) {
|
||||
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(
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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', () => {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue