Skip to content

Commit

Permalink
fix(compiler): correct the KeySpan for animation events and propert…
Browse files Browse the repository at this point in the history
…ies (#40347)

We should provide the completion when the cursor is in the attribute
name after the `@` and `animate-`, but now the `KeySpan` starts from the
`@` or `animate-`. For example, the animation event `(@name.done)="v"`,
we can know where the cursor is by the `KeySpan` of `name.done` exactly,
it's in the event name or in the phase name.

PR Close #40347
  • Loading branch information
ivanwonder authored and AndrewKushnir committed Jan 15, 2021
1 parent 8e0b01e commit 524415e
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 0 deletions.
18 changes: 18 additions & 0 deletions packages/compiler/src/template_parser/binding_parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,10 @@ export class BindingParser {
targetProps: ParsedProperty[], keySpan?: ParseSourceSpan) {
if (isAnimationLabel(name)) {
name = name.substring(1);
if (keySpan !== undefined) {
keySpan = moveParseSourceSpan(
keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
}
if (value) {
this._reportError(
`Assigning animation triggers via @prop="exp" attributes with an expression is invalid.` +
Expand Down Expand Up @@ -274,9 +278,19 @@ export class BindingParser {
if (name.startsWith(ANIMATE_PROP_PREFIX)) {
isAnimationProp = true;
name = name.substring(ANIMATE_PROP_PREFIX.length);
if (keySpan !== undefined) {
keySpan = moveParseSourceSpan(
keySpan,
new AbsoluteSourceSpan(
keySpan.start.offset + ANIMATE_PROP_PREFIX.length, keySpan.end.offset));
}
} else if (isAnimationLabel(name)) {
isAnimationProp = true;
name = name.substring(1);
if (keySpan !== undefined) {
keySpan = moveParseSourceSpan(
keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
}
}

if (isAnimationProp) {
Expand Down Expand Up @@ -424,6 +438,10 @@ export class BindingParser {

if (isAnimationLabel(name)) {
name = name.substr(1);
if (keySpan !== undefined) {
keySpan = moveParseSourceSpan(
keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
}
this._parseAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents, keySpan);
} else {
this._parseRegularEvent(
Expand Down
31 changes: 31 additions & 0 deletions packages/compiler/test/render3/r3_ast_spans_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,30 @@ describe('R3 AST source spans', () => {
['BoundAttribute', 'data-prop="{{v}}"', 'prop', '{{v}}'],
]);
});

it('is correct for bound properties via @', () => {
expectFromHtml('<div bind-@animation="v"></div>').toEqual([
['Element', '<div bind-@animation="v"></div>', '<div bind-@animation="v">', '</div>'],
['BoundAttribute', 'bind-@animation="v"', 'animation', 'v'],
]);
});

it('is correct for bound properties via animation-', () => {
expectFromHtml('<div bind-animate-animationName="v"></div>').toEqual([
[
'Element', '<div bind-animate-animationName="v"></div>',
'<div bind-animate-animationName="v">', '</div>'
],
['BoundAttribute', 'bind-animate-animationName="v"', 'animationName', 'v'],
]);
});

it('is correct for bound properties via @ without value', () => {
expectFromHtml('<div @animation></div>').toEqual([
['Element', '<div @animation></div>', '<div @animation>', '</div>'],
['BoundAttribute', '@animation', 'animation', '<empty>'],
]);
});
});

describe('templates', () => {
Expand Down Expand Up @@ -401,6 +425,13 @@ describe('R3 AST source spans', () => {
['BoundEvent', 'data-bindon-prop="v"', 'prop', 'v'],
]);
});

it('is correct for bound events via @', () => {
expectFromHtml('<div (@name.done)="v"></div>').toEqual([
['Element', '<div (@name.done)="v"></div>', '<div (@name.done)="v">', '</div>'],
['BoundEvent', '(@name.done)="v"', 'name.done', 'v'],
]);
});
});

describe('references', () => {
Expand Down

0 comments on commit 524415e

Please sign in to comment.