fix(compiler): correct the `KeySpan` for animation events and properties (#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
This commit is contained in:
parent
61792cc6f5
commit
40e0bfdc0d
|
@ -244,6 +244,10 @@ export class BindingParser {
|
||||||
targetProps: ParsedProperty[], keySpan?: ParseSourceSpan) {
|
targetProps: ParsedProperty[], keySpan?: ParseSourceSpan) {
|
||||||
if (isAnimationLabel(name)) {
|
if (isAnimationLabel(name)) {
|
||||||
name = name.substring(1);
|
name = name.substring(1);
|
||||||
|
if (keySpan !== undefined) {
|
||||||
|
keySpan = moveParseSourceSpan(
|
||||||
|
keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
|
||||||
|
}
|
||||||
if (value) {
|
if (value) {
|
||||||
this._reportError(
|
this._reportError(
|
||||||
`Assigning animation triggers via @prop="exp" attributes with an expression is invalid.` +
|
`Assigning animation triggers via @prop="exp" attributes with an expression is invalid.` +
|
||||||
|
@ -274,9 +278,19 @@ export class BindingParser {
|
||||||
if (name.startsWith(ANIMATE_PROP_PREFIX)) {
|
if (name.startsWith(ANIMATE_PROP_PREFIX)) {
|
||||||
isAnimationProp = true;
|
isAnimationProp = true;
|
||||||
name = name.substring(ANIMATE_PROP_PREFIX.length);
|
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)) {
|
} else if (isAnimationLabel(name)) {
|
||||||
isAnimationProp = true;
|
isAnimationProp = true;
|
||||||
name = name.substring(1);
|
name = name.substring(1);
|
||||||
|
if (keySpan !== undefined) {
|
||||||
|
keySpan = moveParseSourceSpan(
|
||||||
|
keySpan, new AbsoluteSourceSpan(keySpan.start.offset + 1, keySpan.end.offset));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAnimationProp) {
|
if (isAnimationProp) {
|
||||||
|
@ -424,6 +438,10 @@ export class BindingParser {
|
||||||
|
|
||||||
if (isAnimationLabel(name)) {
|
if (isAnimationLabel(name)) {
|
||||||
name = name.substr(1);
|
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);
|
this._parseAnimationEvent(name, expression, sourceSpan, handlerSpan, targetEvents, keySpan);
|
||||||
} else {
|
} else {
|
||||||
this._parseRegularEvent(
|
this._parseRegularEvent(
|
||||||
|
|
|
@ -193,6 +193,30 @@ describe('R3 AST source spans', () => {
|
||||||
['BoundAttribute', 'data-prop="{{v}}"', 'prop', '{{v}}'],
|
['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', () => {
|
describe('templates', () => {
|
||||||
|
@ -401,6 +425,13 @@ describe('R3 AST source spans', () => {
|
||||||
['BoundEvent', 'data-bindon-prop="v"', 'prop', 'v'],
|
['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', () => {
|
describe('references', () => {
|
||||||
|
|
Loading…
Reference in New Issue