Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 40a537c

Browse files
committed
fix(ngAnimate): do not use jQuery class API
jQeury's class API causes problems with SVG elements --- using jqLite in all cases prevents issues. Closes #10024 Closes #10329
1 parent cb19229 commit 40a537c

File tree

2 files changed

+24
-26
lines changed

2 files changed

+24
-26
lines changed

src/ngAnimate/animate.js

+19-21
Original file line numberDiff line numberDiff line change
@@ -474,10 +474,12 @@ angular.module('ngAnimate', ['ng'])
474474
return extractElementNode(elm1) == extractElementNode(elm2);
475475
}
476476

477+
var $coreAnimate;
478+
477479
$provide.decorator('$animate',
478480
['$delegate', '$$q', '$injector', '$sniffer', '$rootElement', '$$asyncCallback', '$rootScope', '$document', '$templateRequest',
479481
function($delegate, $$q, $injector, $sniffer, $rootElement, $$asyncCallback, $rootScope, $document, $templateRequest) {
480-
482+
$coreAnimate = $delegate;
481483
$rootElement.data(NG_ANIMATE_STATE, rootAnimateState);
482484

483485
// Wait until all directive and route-related templates are downloaded and
@@ -1380,11 +1382,9 @@ angular.module('ngAnimate', ['ng'])
13801382

13811383
//the ng-animate class does nothing, but it's here to allow for
13821384
//parent animations to find and cancel child animations when needed
1383-
element.addClass(NG_ANIMATE_CLASS_NAME);
1385+
$delegate.$$addClassImmediately(element, NG_ANIMATE_CLASS_NAME);
13841386
if (options && options.tempClasses) {
1385-
forEach(options.tempClasses, function(className) {
1386-
element.addClass(className);
1387-
});
1387+
$delegate.$$addClassImmediately(element, options.tempClasses);
13881388
}
13891389

13901390
var localAnimationCount = globalAnimationCounter++;
@@ -1460,9 +1460,7 @@ angular.module('ngAnimate', ['ng'])
14601460

14611461
closeAnimation.hasBeenRun = true;
14621462
if (options && options.tempClasses) {
1463-
forEach(options.tempClasses, function(className) {
1464-
element.removeClass(className);
1465-
});
1463+
$delegate.$$removeClassImmediately(element, options.tempClasses);
14661464
}
14671465

14681466
var data = element.data(NG_ANIMATE_STATE);
@@ -1523,7 +1521,7 @@ angular.module('ngAnimate', ['ng'])
15231521
}
15241522

15251523
if (removeAnimations || !data.totalActive) {
1526-
element.removeClass(NG_ANIMATE_CLASS_NAME);
1524+
$delegate.$$removeClassImmediately(element, NG_ANIMATE_CLASS_NAME);
15271525
element.removeData(NG_ANIMATE_STATE);
15281526
}
15291527
}
@@ -1764,22 +1762,22 @@ angular.module('ngAnimate', ['ng'])
17641762
var staggerCacheKey = cacheKey + ' ' + staggerClassName;
17651763
var applyClasses = !lookupCache[staggerCacheKey];
17661764

1767-
applyClasses && element.addClass(staggerClassName);
1765+
applyClasses && $coreAnimate.$$addClassImmediately(element, staggerClassName);
17681766

17691767
stagger = getElementAnimationDetails(element, staggerCacheKey);
17701768

1771-
applyClasses && element.removeClass(staggerClassName);
1769+
applyClasses && $coreAnimate.$$removeClassImmediately(element, staggerClassName);
17721770
}
17731771

1774-
element.addClass(className);
1772+
$coreAnimate.$$addClassImmediately(element, className);
17751773

17761774
var formerData = element.data(NG_ANIMATE_CSS_DATA_KEY) || {};
17771775
var timings = getElementAnimationDetails(element, eventCacheKey);
17781776
var transitionDuration = timings.transitionDuration;
17791777
var animationDuration = timings.animationDuration;
17801778

17811779
if (structural && transitionDuration === 0 && animationDuration === 0) {
1782-
element.removeClass(className);
1780+
$coreAnimate.$$removeClassImmediately(element, className);
17831781
return false;
17841782
}
17851783

@@ -1851,7 +1849,7 @@ angular.module('ngAnimate', ['ng'])
18511849
}
18521850

18531851
if (!staggerTime) {
1854-
element.addClass(activeClassName);
1852+
$coreAnimate.$$addClassImmediately(element, activeClassName);
18551853
if (elementData.blockTransition) {
18561854
blockTransitions(node, false);
18571855
}
@@ -1861,7 +1859,7 @@ angular.module('ngAnimate', ['ng'])
18611859
var timings = getElementAnimationDetails(element, eventCacheKey);
18621860
var maxDuration = Math.max(timings.transitionDuration, timings.animationDuration);
18631861
if (maxDuration === 0) {
1864-
element.removeClass(activeClassName);
1862+
$coreAnimate.$$removeClassImmediately(element, activeClassName);
18651863
animateClose(element, className);
18661864
activeAnimationComplete();
18671865
return;
@@ -1896,7 +1894,7 @@ angular.module('ngAnimate', ['ng'])
18961894

18971895
var staggerTimeout;
18981896
if (staggerTime > 0) {
1899-
element.addClass(pendingClassName);
1897+
$coreAnimate.$$addClassImmediately(element, pendingClassName);
19001898
staggerTimeout = $timeout(function() {
19011899
staggerTimeout = null;
19021900

@@ -1907,8 +1905,8 @@ angular.module('ngAnimate', ['ng'])
19071905
blockAnimations(node, false);
19081906
}
19091907

1910-
element.addClass(activeClassName);
1911-
element.removeClass(pendingClassName);
1908+
$coreAnimate.$$addClassImmediately(element, activeClassName);
1909+
$coreAnimate.$$removeClassImmediately(element, pendingClassName);
19121910

19131911
if (styles) {
19141912
if (timings.transitionDuration === 0) {
@@ -1935,8 +1933,8 @@ angular.module('ngAnimate', ['ng'])
19351933
// timeout done method.
19361934
function onEnd() {
19371935
element.off(css3AnimationEvents, onAnimationProgress);
1938-
element.removeClass(activeClassName);
1939-
element.removeClass(pendingClassName);
1936+
$coreAnimate.$$removeClassImmediately(element, activeClassName);
1937+
$coreAnimate.$$removeClassImmediately(element, pendingClassName);
19401938
if (staggerTimeout) {
19411939
$timeout.cancel(staggerTimeout);
19421940
}
@@ -2024,7 +2022,7 @@ angular.module('ngAnimate', ['ng'])
20242022
}
20252023

20262024
function animateClose(element, className) {
2027-
element.removeClass(className);
2025+
$coreAnimate.$$removeClassImmediately(element, className);
20282026
var data = element.data(NG_ANIMATE_CSS_DATA_KEY);
20292027
if (data) {
20302028
if (data.running) {

test/ngAnimate/animateSpec.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -5316,7 +5316,7 @@ describe("ngAnimate", function() {
53165316
//jQuery doesn't handle SVG elements natively. Instead, an add-on library
53175317
//is required which is called jquery.svg.js. Therefore, when jQuery is
53185318
//active here there is no point to test this since it won't work by default.
5319-
if (!$sniffer.transitions || !_jqLiteMode) return;
5319+
if (!$sniffer.transitions) return;
53205320

53215321
ss.addRule('circle.ng-enter', '-webkit-transition:1s linear all;' +
53225322
'transition:1s linear all;');
@@ -5336,13 +5336,13 @@ describe("ngAnimate", function() {
53365336

53375337
var child = element.find('circle');
53385338

5339-
expect(child.hasClass('ng-enter')).toBe(true);
5340-
expect(child.hasClass('ng-enter-active')).toBe(true);
5339+
expect(jqLiteHasClass(child[0], 'ng-enter')).toBe(true);
5340+
expect(jqLiteHasClass(child[0], 'ng-enter-active')).toBe(true);
53415341

53425342
browserTrigger(child, 'transitionend', { timeStamp: Date.now() + 1000, elapsedTime: 1 });
53435343

5344-
expect(child.hasClass('ng-enter')).toBe(false);
5345-
expect(child.hasClass('ng-enter-active')).toBe(false);
5344+
expect(jqLiteHasClass(child[0], 'ng-enter')).toBe(false);
5345+
expect(jqLiteHasClass(child[0], 'ng-enter-active')).toBe(false);
53465346
}));
53475347

53485348

0 commit comments

Comments
 (0)