-
Notifications
You must be signed in to change notification settings - Fork 27.4k
fix(ngAnimate): correctly animate transcluded clones with templateUrl
#15514
fix(ngAnimate): correctly animate transcluded clones with templateUrl
#15514
Conversation
…ve redundant calls
…e redundant calls
I added one more commit with a (very basic) animation benchmark. It simply (Take the results with a grain of salt, as the benchmark scenario is a little artificial.) |
5ccff06
to
06124e3
Compare
var rootNode = getDomNode($rootElement); | ||
|
||
var bodyNodeDetected = (node === bodyNode) || node.nodeName === 'HTML'; | ||
var rootNodeDetected = (node === rootNode); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the parens? (here & in other places)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of reasons (at least):
- I find them more readable. I think it is a remnant from my early Java days (and this ancient document).
- It is also visually closer to
isMatchingElement(...)
😛
(Hey, I changed the trailing dots, I am not removing the parens.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we need an eslint rule for that :D But I prefer the parens too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like not having parents here but as long as ESLint will shout at me if I forget them I'd be satisfied as well. ;)
$templateCache.put('foo.html', '<div>FOO</div>'); | ||
$compile(parent)($rootScope); | ||
|
||
expect(capturedAnimation).toBe(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everywhere in other places it's only checked if capturedAnimation
is falsy. We should be consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, you want me to change all other places to toBe(null)
? Fair enough...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking the other way round but maybe your idea has more sense. ;)
In some cases it's initially undefined
, though, not null
, this file is not very consistent in that regard. Perhaps that's material for a separate PR (or at least a commit) but I just want us to be consistent. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, it's undefined
only in one test:
https://github.com/gkalpak/angular.js/blob/acd9e7b757cdb9f04ae7a12ff21fdc8d27f314b5/test/ngAnimate/animateSpec.js#L21-L46
I guess the changes are fine then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I (blindly) changed all occurrences of expect(capturedAnimation).toBeFalsy()
to expect(capturedAnimation).toBe(null)
and the tests were passing 😕
'use strict'; | ||
|
||
angular. | ||
module('animationBenchmark', ['ngAnimate'], config). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dislike this dot placement a lot. :P We use the leading dot in most places and I'd like to ESLint-enforce it one day...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Come on! I speeded up your animations 5%-7%. And all you care about is where I put a tiny little dot?
I'd like to ESLint-enforce it one day...
What a coincidence. I'd like to ESLint-enforce the trailing dot one day. So I am tryign to sneak in as many of them as possible, so when the day comes I can say: "Hey, look, there are more trailing dots than leading, let's stick with that 😛
I am afraid I am the only one around to favor the trailing dot, so I'll change it 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Come on! I speeded up your animations 5%-7%. And all you care about is where I put a tiny little dot?
No, I like this PR a lot! I'm just providing feedback for some small issues. :)
Good job overall, though, perhaps I should have spelled that out. 👏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just in case it wasn't clear, I was just kidding (in an attempt to distract everyone from the fact that I was busted trying to sneak in those trailing dots 😛
[ng-cloak] { display: none !important; } | ||
.animation-container .ng-enter, | ||
.animation-container .ng-leave { | ||
transition: all 0.1s |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A missing semi-colon;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
😱
be4adcf
to
acd9e7b
Compare
Addressed (most of) @mgol's comments. |
@@ -168,7 +168,7 @@ describe('animations', function() { | |||
inject(function($animate, $rootScope) { | |||
$animate.enter(element, parent); | |||
$rootScope.$digest(); | |||
expect(capturedAnimation).toBeFalsy(); | |||
expect(capturedAnimation).toBe(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd put those changes in a separate commit as they don't really have a lot in common with the original one.
acd9e7b
to
e1a8bd6
Compare
e1a8bd6
to
c215896
Compare
Rearranged the commits (and fixed a test failure). |
// Note: We still need to use the old `node` for certain things, such as looking up in | ||
// HashMaps where it was used as the key. | ||
|
||
element = stripCommentsFromElement(originalElement); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I take it this has no performance implications? This now applies to all animations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't benchmarked this change on its own. I assume it has an unnoticeable impact on performance (considering all the performance-heavy-ish stuff that is going on during animations).
But overall, this PR offers a non-negligible performance gain (see #15514 (comment)).
Previously, `$animate` would decide whether an animation should be cancelled based on some assumption that didn't hold in specific cases (e.g. when animating transcluded clones with `templateUrl` directives on them for the first time). As a result, the entering elements would not be animated in such cases. This affected commonly used, structural built-in directives (`ngIf`, `ngRepeat`, `ngSwitch` etc). This commit fixes it by avoiding invalid assumptions (i.e. by taking into account the transformations that take place while compiling such elements). Partly addresses angular#14074 and angular#14124. Fixes angular#15510
c215896
to
5341108
Compare
LGTM |
Previously, `$animate` would decide whether an animation should be cancelled based on some assumption that didn't hold in specific cases (e.g. when animating transcluded clones with `templateUrl` directives on them for the first time). As a result, the entering elements would not be animated in such cases. This affected commonly used, structural built-in directives (`ngIf`, `ngRepeat`, `ngSwitch` etc). This commit fixes it by avoiding invalid assumptions (i.e. by taking into account the transformations that take place while compiling such elements). Partly addresses #14074 and #14124. Fixes #15510 Closes #15514
Previously, `$animate` would decide whether an animation should be cancelled based on some assumption that didn't hold in specific cases (e.g. when animating transcluded clones with `templateUrl` directives on them for the first time). As a result, the entering elements would not be animated in such cases. This affected commonly used, structural built-in directives (`ngIf`, `ngRepeat`, `ngSwitch` etc). This commit fixes it by avoiding invalid assumptions (i.e. by taking into account the transformations that take place while compiling such elements). Partly addresses angular#14074 and angular#14124. Fixes angular#15510 Closes angular#15514
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Bug fix.
What is the current behavior? (You can also link to an open issue here)
$animate
decides whether an animation should be cancelled based on some assumption that don't hold in specific cases (e.g. when animating transcluded clones withtemplateUrl
directives on them for the first time). As a result, the entering elements will not be animated in such cases. This affects commonly used, structural built-in directives (ngIf
,ngRepeat
,ngSwitch
etc).See also #15510.
What is the new behavior (if this is a feature change)?
All entering animations work as expected (from the first time).
Does this PR introduce a breaking change?
No.
Please check if the PR fulfills these requirements
Docs have been added / updated (for bug fixes / features)Other information:
BTW, I believe this is a side effect of lazily compiling transcluded content.
In addition to the last
fix
commit that fixes the bug, this PR also includes severalrefactor
commits that simplify$animate
internally, mainly by removing unnecessary wrapping/unwrapping of DOM nodes injqLite
/jQuery
collections. This changes may also positively affect performance, especially in animation-heavy apps (although I haven't benchmarked it - yetit does indeed 😉).(It is probably easier to review one commit at a time.)
Party addresses #14074 and #14124.
Fixes #15510.