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

Commit e5f4d7b

Browse files
matskoIgorMinar
authored andcommitted
feat($animate): allow $animate to pass custom styles into animations
$animate now supports an optional parameter which provides CSS styling which will be provided into the CSS-based animations as well as any custom animation functions. Once the animation is complete then the styles will be applied directly to the element. If no animation is detected or the `ngAnimate` module is not active then the styles will be applied immediately. BREAKING CHANGE: staggering animations that use transitions will now always block the transition from starting (via `transition: 0s none`) up until the stagger step kicks in. The former behaviour was that the block was removed as soon as the pending class was added. This fix allows for styles to be applied in the pending class without causing an animation to trigger prematurely.
1 parent 63ef085 commit e5f4d7b

File tree

6 files changed

+597
-81
lines changed

6 files changed

+597
-81
lines changed

src/ng/animate.js

+37-15
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ var $AnimateProvider = ['$provide', function($provide) {
122122
}
123123
});
124124

125-
return (toAdd.length + toRemove.length) > 0 && [toAdd.length && toAdd, toRemove.length && toRemove];
125+
return (toAdd.length + toRemove.length) > 0 &&
126+
[toAdd.length ? toAdd : null, toRemove.length ? toRemove : null];
126127
}
127128

128129
function cachedClassManipulation(cache, classes, op) {
@@ -144,6 +145,13 @@ var $AnimateProvider = ['$provide', function($provide) {
144145
return currentDefer.promise;
145146
}
146147

148+
function applyStyles(element, options) {
149+
if (angular.isObject(options)) {
150+
var styles = extend(options.from || {}, options.to || {});
151+
element.css(styles);
152+
}
153+
}
154+
147155
/**
148156
*
149157
* @ngdoc service
@@ -176,9 +184,11 @@ var $AnimateProvider = ['$provide', function($provide) {
176184
* a child (if the after element is not present)
177185
* @param {DOMElement} after the sibling element which will append the element
178186
* after itself
187+
* @param {object=} options an optional collection of styles that will be applied to the element.
179188
* @return {Promise} the animation callback promise
180189
*/
181-
enter : function(element, parent, after) {
190+
enter : function(element, parent, after, options) {
191+
applyStyles(element, options);
182192
after ? after.after(element)
183193
: parent.prepend(element);
184194
return asyncPromise();
@@ -192,9 +202,10 @@ var $AnimateProvider = ['$provide', function($provide) {
192202
* @description Removes the element from the DOM. When the function is called a promise
193203
* is returned that will be resolved at a later time.
194204
* @param {DOMElement} element the element which will be removed from the DOM
205+
* @param {object=} options an optional collection of options that will be applied to the element.
195206
* @return {Promise} the animation callback promise
196207
*/
197-
leave : function(element) {
208+
leave : function(element, options) {
198209
element.remove();
199210
return asyncPromise();
200211
},
@@ -214,12 +225,13 @@ var $AnimateProvider = ['$provide', function($provide) {
214225
* inserted into (if the after element is not present)
215226
* @param {DOMElement} after the sibling element where the element will be
216227
* positioned next to
228+
* @param {object=} options an optional collection of options that will be applied to the element.
217229
* @return {Promise} the animation callback promise
218230
*/
219-
move : function(element, parent, after) {
231+
move : function(element, parent, after, options) {
220232
// Do not remove element before insert. Removing will cause data associated with the
221233
// element to be dropped. Insert will implicitly do the remove.
222-
return this.enter(element, parent, after);
234+
return this.enter(element, parent, after, options);
223235
},
224236

225237
/**
@@ -232,20 +244,23 @@ var $AnimateProvider = ['$provide', function($provide) {
232244
* @param {DOMElement} element the element which will have the className value
233245
* added to it
234246
* @param {string} className the CSS class which will be added to the element
247+
* @param {object=} options an optional collection of options that will be applied to the element.
235248
* @return {Promise} the animation callback promise
236249
*/
237-
addClass : function(element, className) {
238-
return this.setClass(element, className, []);
250+
addClass : function(element, className, options) {
251+
return this.setClass(element, className, [], options);
239252
},
240253

241-
$$addClassImmediately : function(element, className) {
254+
$$addClassImmediately : function(element, className, options) {
242255
element = jqLite(element);
243256
className = !isString(className)
244257
? (isArray(className) ? className.join(' ') : '')
245258
: className;
246259
forEach(element, function (element) {
247260
jqLiteAddClass(element, className);
248261
});
262+
applyStyles(element, options);
263+
return asyncPromise();
249264
},
250265

251266
/**
@@ -258,20 +273,22 @@ var $AnimateProvider = ['$provide', function($provide) {
258273
* @param {DOMElement} element the element which will have the className value
259274
* removed from it
260275
* @param {string} className the CSS class which will be removed from the element
276+
* @param {object=} options an optional collection of options that will be applied to the element.
261277
* @return {Promise} the animation callback promise
262278
*/
263-
removeClass : function(element, className) {
264-
return this.setClass(element, [], className);
279+
removeClass : function(element, className, options) {
280+
return this.setClass(element, [], className, options);
265281
},
266282

267-
$$removeClassImmediately : function(element, className) {
283+
$$removeClassImmediately : function(element, className, options) {
268284
element = jqLite(element);
269285
className = !isString(className)
270286
? (isArray(className) ? className.join(' ') : '')
271287
: className;
272288
forEach(element, function (element) {
273289
jqLiteRemoveClass(element, className);
274290
});
291+
applyStyles(element, options);
275292
return asyncPromise();
276293
},
277294

@@ -286,9 +303,10 @@ var $AnimateProvider = ['$provide', function($provide) {
286303
* removed from it
287304
* @param {string} add the CSS classes which will be added to the element
288305
* @param {string} remove the CSS class which will be removed from the element
306+
* @param {object=} options an optional collection of options that will be applied to the element.
289307
* @return {Promise} the animation callback promise
290308
*/
291-
setClass : function(element, add, remove) {
309+
setClass : function(element, add, remove, options) {
292310
var self = this;
293311
var STORAGE_KEY = '$$animateClasses';
294312
var createdCache = false;
@@ -297,9 +315,12 @@ var $AnimateProvider = ['$provide', function($provide) {
297315
var cache = element.data(STORAGE_KEY);
298316
if (!cache) {
299317
cache = {
300-
classes: {}
318+
classes: {},
319+
options : options
301320
};
302321
createdCache = true;
322+
} else if (options && cache.options) {
323+
cache.options = angular.extend(cache.options || {}, options);
303324
}
304325

305326
var classes = cache.classes;
@@ -320,7 +341,7 @@ var $AnimateProvider = ['$provide', function($provide) {
320341
if (cache) {
321342
var classes = resolveElementClasses(element, cache.classes);
322343
if (classes) {
323-
self.$$setClassImmediately(element, classes[0], classes[1]);
344+
self.$$setClassImmediately(element, classes[0], classes[1], cache.options);
324345
}
325346
}
326347

@@ -332,9 +353,10 @@ var $AnimateProvider = ['$provide', function($provide) {
332353
return cache.promise;
333354
},
334355

335-
$$setClassImmediately : function(element, add, remove) {
356+
$$setClassImmediately : function(element, add, remove, options) {
336357
add && this.$$addClassImmediately(element, add);
337358
remove && this.$$removeClassImmediately(element, remove);
359+
applyStyles(element, options);
338360
return asyncPromise();
339361
},
340362

src/ng/directive/ngShowHide.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,9 @@ var ngShowDirective = ['$animate', function($animate) {
167167
// we can control when the element is actually displayed on screen without having
168168
// to have a global/greedy CSS selector that breaks when other animations are run.
169169
// Read: https://github.com/angular/angular.js/issues/9103#issuecomment-58335845
170-
$animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, NG_HIDE_IN_PROGRESS_CLASS);
170+
$animate[value ? 'removeClass' : 'addClass'](element, NG_HIDE_CLASS, {
171+
tempClasses : NG_HIDE_IN_PROGRESS_CLASS
172+
});
171173
});
172174
}
173175
};
@@ -324,7 +326,9 @@ var ngHideDirective = ['$animate', function($animate) {
324326
scope.$watch(attr.ngHide, function ngHideWatchAction(value){
325327
// The comment inside of the ngShowDirective explains why we add and
326328
// remove a temporary class for the show/hide animation
327-
$animate[value ? 'addClass' : 'removeClass'](element,NG_HIDE_CLASS, NG_HIDE_IN_PROGRESS_CLASS);
329+
$animate[value ? 'addClass' : 'removeClass'](element,NG_HIDE_CLASS, {
330+
tempClasses : NG_HIDE_IN_PROGRESS_CLASS
331+
});
328332
});
329333
}
330334
};

0 commit comments

Comments
 (0)