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

Commit 72edd4d

Browse files
committed
fix($animate): ignore invalid option parameter values
Prior to this fix there was another patch that threw an exception if the provided options value was not of an object type. While this is correct in terms of logic, it caused issues with plugins and tools that are designed to work with multiple version of Angular. This fix ensures that these plugins work since an invalid options value is ignored by `$animate`. Closes #11826
1 parent 0fc5851 commit 72edd4d

File tree

2 files changed

+96
-7
lines changed

2 files changed

+96
-7
lines changed

src/ng/animate.js

+20-7
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,19 @@ function splitClasses(classes) {
4040
return obj;
4141
}
4242

43+
// if any other type of options value besides an Object value is
44+
// passed into the $animate.method() animation then this helper code
45+
// will be run which will ignore it. While this patch is not the
46+
// greatest solution to this, a lot of existing plugins depend on
47+
// $animate to either call the callback (< 1.2) or return a promise
48+
// that can be changed. This helper function ensures that the options
49+
// are wiped clean incase a callback function is provided.
50+
function prepareAnimateOptions(options) {
51+
return isObject(options)
52+
? options
53+
: {};
54+
}
55+
4356
var $$CoreAnimateRunnerProvider = function() {
4457
this.$get = ['$q', '$$rAF', function($q, $$rAF) {
4558
function AnimateRunner() {}
@@ -420,7 +433,7 @@ var $AnimateProvider = ['$provide', function($provide) {
420433
after = after && jqLite(after);
421434
parent = parent || after.parent();
422435
domInsert(element, parent, after);
423-
return $$animateQueue.push(element, 'enter', options);
436+
return $$animateQueue.push(element, 'enter', prepareAnimateOptions(options));
424437
},
425438

426439
/**
@@ -446,7 +459,7 @@ var $AnimateProvider = ['$provide', function($provide) {
446459
after = after && jqLite(after);
447460
parent = parent || after.parent();
448461
domInsert(element, parent, after);
449-
return $$animateQueue.push(element, 'move', options);
462+
return $$animateQueue.push(element, 'move', prepareAnimateOptions(options));
450463
},
451464

452465
/**
@@ -463,7 +476,7 @@ var $AnimateProvider = ['$provide', function($provide) {
463476
* @return {Promise} the animation callback promise
464477
*/
465478
leave: function(element, options) {
466-
return $$animateQueue.push(element, 'leave', options, function() {
479+
return $$animateQueue.push(element, 'leave', prepareAnimateOptions(options), function() {
467480
element.remove();
468481
});
469482
},
@@ -487,7 +500,7 @@ var $AnimateProvider = ['$provide', function($provide) {
487500
* @return {Promise} the animation callback promise
488501
*/
489502
addClass: function(element, className, options) {
490-
options = options || {};
503+
options = prepareAnimateOptions(options);
491504
options.addClass = mergeClasses(options.addclass, className);
492505
return $$animateQueue.push(element, 'addClass', options);
493506
},
@@ -511,7 +524,7 @@ var $AnimateProvider = ['$provide', function($provide) {
511524
* @return {Promise} the animation callback promise
512525
*/
513526
removeClass: function(element, className, options) {
514-
options = options || {};
527+
options = prepareAnimateOptions(options);
515528
options.removeClass = mergeClasses(options.removeClass, className);
516529
return $$animateQueue.push(element, 'removeClass', options);
517530
},
@@ -536,7 +549,7 @@ var $AnimateProvider = ['$provide', function($provide) {
536549
* @return {Promise} the animation callback promise
537550
*/
538551
setClass: function(element, add, remove, options) {
539-
options = options || {};
552+
options = prepareAnimateOptions(options);
540553
options.addClass = mergeClasses(options.addClass, add);
541554
options.removeClass = mergeClasses(options.removeClass, remove);
542555
return $$animateQueue.push(element, 'setClass', options);
@@ -564,7 +577,7 @@ var $AnimateProvider = ['$provide', function($provide) {
564577
* @return {Promise} the animation callback promise
565578
*/
566579
animate: function(element, from, to, className, options) {
567-
options = options || {};
580+
options = prepareAnimateOptions(options);
568581
options.from = options.from ? extend(options.from, from) : from;
569582
options.to = options.to ? extend(options.to, to) : to;
570583

test/ng/animateSpec.js

+76
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,82 @@ describe("$animate", function() {
242242
expect(element[0].previousSibling).toBe(after);
243243
});
244244
});
245+
246+
they('$prop() should operate using a native DOM element',
247+
['enter', 'move', 'leave', 'addClass', 'removeClass', 'setClass', 'animate'], function(event) {
248+
249+
var captureSpy = jasmine.createSpy();
250+
251+
module(function($provide) {
252+
$provide.value('$$animateQueue', {
253+
push: captureSpy
254+
});
255+
});
256+
257+
inject(function($animate, $rootScope, $document, $rootElement) {
258+
var element = jqLite('<div></div>');
259+
var parent2 = jqLite('<div></div>');
260+
var parent = $rootElement;
261+
parent.append(parent2);
262+
263+
if (event !== 'enter' && event !== 'move') {
264+
parent.append(element);
265+
}
266+
267+
var fn, invalidOptions = function() { };
268+
269+
switch (event) {
270+
case 'enter':
271+
case 'move':
272+
fn = function() {
273+
$animate[event](element, parent, parent2, invalidOptions);
274+
};
275+
break;
276+
277+
case 'addClass':
278+
fn = function() {
279+
$animate.addClass(element, 'klass', invalidOptions);
280+
};
281+
break;
282+
283+
case 'removeClass':
284+
element.className = 'klass';
285+
fn = function() {
286+
$animate.removeClass(element, 'klass', invalidOptions);
287+
};
288+
break;
289+
290+
case 'setClass':
291+
element.className = 'two';
292+
fn = function() {
293+
$animate.setClass(element, 'one', 'two', invalidOptions);
294+
};
295+
break;
296+
297+
case 'leave':
298+
fn = function() {
299+
$animate.leave(element, invalidOptions);
300+
};
301+
break;
302+
303+
case 'animate':
304+
var toStyles = { color: 'red' };
305+
fn = function() {
306+
$animate.animate(element, {}, toStyles, 'klass', invalidOptions);
307+
};
308+
break;
309+
}
310+
311+
expect(function() {
312+
fn();
313+
$rootScope.$digest();
314+
}).not.toThrow();
315+
316+
var optionsArg = captureSpy.mostRecentCall.args[2];
317+
expect(optionsArg).not.toBe(invalidOptions);
318+
expect(isObject(optionsArg)).toBeTruthy();
319+
});
320+
});
245321
});
246322

247323
describe('CSS class DOM manipulation', function() {

0 commit comments

Comments
 (0)