Compare commits

...

17 Commits

Author SHA1 Message Date
Matias Niemelä 1622182737 docs(CHANGELOG): add changes for 1.4.3 2015-07-14 18:26:10 -07:00
Matias Niemelä 36efe6c1a2 test($animateCss): avoid unnecessary checking for transition-timing-function
There is no need to check for this in the test and it adds complexity
for linux-based browsers.
2015-07-14 14:07:50 -07:00
Matias Niemelä 5081982e30 test($animateCss): ensure that transitionStyle by itself doesn't trigger anything
Using `transitionStyle` without any other properties does not trigger an
animation so we could have a test to assert that it doesn't do that.
2015-07-14 13:45:11 -07:00
Matias Niemelä 97d79eec80 fix($animateCss): ensure animations execute if only a keyframeStyle is provided
`$animateCss` is a fan of transition animations, but it turns out that
if only a keyframeStyle is provided into the animation upon constrution
then it will quit because it assumes that nothing will be animated
(since no classes or styles are being applied). This patch ensures that
a keyframe style can solely be applied to an animation triggered with
`$animateCss`.

```js
// this will now work as expected
$animateCss(element, { keyframeStyle: '1s rotate' }).start();
```

Closes #12124
Closes #12340
2015-07-14 13:45:03 -07:00
Matias Niemelä e4aeae0c73 fix(ngAnimate): ensure that orphaned elements do not throw errors when animated
This fix ensures that both `$animateCss` and `$animate` swallow the error
when an animation takes place in the sitation that the element is removed
from the parent element sometime before or during the preparation stages of the
animation.

Closes #11975
Closes #12338
2015-07-14 21:06:55 +01:00
Dominic Watson 7202bfafcd docs(ngAnimate) - Correct keyframe to keyframeStyle 2015-07-14 10:42:05 -07:00
Steve Mao 4cef752985 docs(CONTRIBUTING): state what is mandatory or optional
Closes #12032
2015-07-13 13:24:52 +01:00
Steve Mao d38f6ff401 docs(CONTRIBUTING): how to write a breaking change
Closes #12032
2015-07-13 13:24:44 +01:00
Steve Mao 8f6dac9536 docs(CONTRIBUTING): revert is a modifier
EG: https://github.com/angular/angular.js/commit/462f444b06ae5cad3ccb761b1dba7131df01a655

Closes #12032
2015-07-13 13:24:34 +01:00
Peter Bacon Darwin de5b8dc781 docs(guide/controller): add a line about controller as 2015-07-13 13:22:01 +01:00
Peter Bacon Darwin 41834e6f4a docs(guide/controller): add a line about controller as 2015-07-13 13:18:29 +01:00
niteshthakur dbb42b5c85 docs(guide/controller): clarify that controllers are defined **by** a constructor function
A controller is a instantiated object created **from** a constructor function.
It was not accurate to describe a Controller **as** a constructor function.

Closes #11888
2015-07-13 13:18:29 +01:00
Peter Bacon Darwin f012374f12 docs($routeChangeSuccess): note that resolve values are available on current route
Closes #11413
2015-07-13 13:10:47 +01:00
Rouven Weßling 14e0b9c352 refactor(ngCsp): use document.head
The `head` property is available from IE9 onwards.

Closes #11905
2015-07-13 09:37:03 +01:00
Jerry Orta 9ea52d818b fix(loader): define isFunction
Closes: #12299
Closes: #12287
2015-07-10 22:54:58 +02:00
Martin Staffa d518a64d93 docs(CHANGELOG): add changes for 1.4.2 2015-07-06 22:19:53 +02:00
Wesley Cho fe0af2c073 chore(animate): remove dead code
- Remove unused `$$asyncCallback`

Fixes #12251
Closes #12254
2015-07-02 22:57:00 +02:00
14 changed files with 322 additions and 69 deletions
+160
View File
@@ -1,3 +1,163 @@
<a name="1.4.3"></a>
# 1.4.3 foam-acceleration (2015-07-06)
## Bug Fixes
- **$animateCss:** ensure animations execute if only a keyframeStyle is provided
([97d79eec](https://github.com/angular/angular.js/commit/97d79eec80092f5fae3336c23aa881a72436de55),
[#12124](https://github.com/angular/angular.js/issues/12124), [#12340](https://github.com/angular/angular.js/issues/12340))
- **$browser:** prevent infinite digest if changing hash when there is no hashPrefix
([f81ff3be](https://github.com/angular/angular.js/commit/f81ff3beb0c9d19d494c5878086fb57476442b8b),
[#10423](https://github.com/angular/angular.js/issues/10423), [#12145](https://github.com/angular/angular.js/issues/12145))
- **$compile:**
- throw error when requestng new and isolate scopes (async)
([6333d65b](https://github.com/angular/angular.js/commit/6333d65b76e0796cfbab8a2953af0c8014dba2e1),
[#12215](https://github.com/angular/angular.js/issues/12215), [#12217](https://github.com/angular/angular.js/issues/12217))
- do not write @-bound properties if attribute is not present
([8a1eb162](https://github.com/angular/angular.js/commit/8a1eb1625c080445ce1e519762e1f2d4fd842b72),
[#12151](https://github.com/angular/angular.js/issues/12151), [#12144](https://github.com/angular/angular.js/issues/12144))
- workaround for IE11 MutationObserver
([f3b1d0b7](https://github.com/angular/angular.js/commit/f3b1d0b723298a5f8ea21d0704405649cce1b5fc),
[#11781](https://github.com/angular/angular.js/issues/11781))
- exception when using "watch" as isolated scope binding variable in Firefox
([a6339d30](https://github.com/angular/angular.js/commit/a6339d30d1379689da5eec9647a953f64821f8b0),
[#11627](https://github.com/angular/angular.js/issues/11627))
- **$location:**
- allow navigating outside the original base URL
([6903b5ec](https://github.com/angular/angular.js/commit/6903b5ec4c04ed6b7c80ef7d638c48639ccdc4bb),
[#11302](https://github.com/angular/angular.js/issues/11302), [#4776](https://github.com/angular/angular.js/issues/4776))
- do not get caught in infinite digest in IE9
([91b60226](https://github.com/angular/angular.js/commit/91b602263b96b6fce1331208462e18eb647f4d60),
[#11439](https://github.com/angular/angular.js/issues/11439), [#11675](https://github.com/angular/angular.js/issues/11675), [#11935](https://github.com/angular/angular.js/issues/11935), [#12083](https://github.com/angular/angular.js/issues/12083))
- **$parse:**
- set null reference properties to `undefined`
([71fc3f4f](https://github.com/angular/angular.js/commit/71fc3f4fa0cd12eff335d57efed7c033554749f4),
[#12099](https://github.com/angular/angular.js/issues/12099))
- set null reference properties to `undefined`
([d19504a1](https://github.com/angular/angular.js/commit/d19504a179355d7801d59a8db0285a1322e04601),
[#11959](https://github.com/angular/angular.js/issues/11959))
- **$sanitize:** dont not remove tab index property
([799353c7](https://github.com/angular/angular.js/commit/799353c75de28e6fbf52dac6e0721e85b578575a),
[#8371](https://github.com/angular/angular.js/issues/8371), [#5853](https://github.com/angular/angular.js/issues/5853))
- **compile:** assign ctrl return values correctly for multiple directives
([8caf1802](https://github.com/angular/angular.js/commit/8caf1802e0e93389dec626ef35e04a302aa6c39d),
[#12029](https://github.com/angular/angular.js/issues/12029), [#12036](https://github.com/angular/angular.js/issues/12036))
- **copy:** do not copy the same object twice
([0e622f7b](https://github.com/angular/angular.js/commit/0e622f7b5bc3d5d0ab0fbc1a1bc69404bd7216d5))
- **forms:** parse exponential notation in numberInputType parser
([ebd0fbba](https://github.com/angular/angular.js/commit/ebd0fbba8ff90bee0cd016d574643d56a7f81ed0),
[#12121](https://github.com/angular/angular.js/issues/12121), [#12122](https://github.com/angular/angular.js/issues/12122))
- **linky:** allow case insensitive scheme detection
([8dc09e6d](https://github.com/angular/angular.js/commit/8dc09e6dabb84c2c611cdc9e40adfac989648200),
[#12073](https://github.com/angular/angular.js/issues/12073), [#12073](https://github.com/angular/angular.js/issues/12073))
- **loader:** define isFunction
([9ea52d81](https://github.com/angular/angular.js/commit/9ea52d818bcd2fb3ea8ccc85bf47f9fd5af68843))
- **merge:** treat dates as atomic values instead of objects.
([6cbbd966](https://github.com/angular/angular.js/commit/6cbbd966479448591f819cbf904e0a3b757613dc),
[#11720](https://github.com/angular/angular.js/issues/11720), [#11720](https://github.com/angular/angular.js/issues/11720))
- **ngAnimate:** ensure that orphaned elements do not throw errors when animated
([e4aeae0c](https://github.com/angular/angular.js/commit/e4aeae0c7303b94135e6df20e6c5e25f2aa0f586),
[#11975](https://github.com/angular/angular.js/issues/11975), [#12338](https://github.com/angular/angular.js/issues/12338))
- **ngAria:**
- update `aria-valuemin/max` when `min/max` change
([ebaa0f59](https://github.com/angular/angular.js/commit/ebaa0f598501702ae64d59ada0ae492eaf0e2db6),
[#11770](https://github.com/angular/angular.js/issues/11770), [#11774](https://github.com/angular/angular.js/issues/11774))
- ensure boolean values for aria-hidden and aria-disabled
([59273354](https://github.com/angular/angular.js/commit/59273354b57dd8d1ad2cd2f4740ffa8923e480f9),
[#11365](https://github.com/angular/angular.js/issues/11365))
- **ngModel:** form validation when there is an Object.prototype enumerable value
([0934b76b](https://github.com/angular/angular.js/commit/0934b76b72cec86093414834ac4cb7f0946b651d),
[#12066](https://github.com/angular/angular.js/issues/12066))
- **ngOptions:**
- only watch numeric properties of an array
([14638f4a](https://github.com/angular/angular.js/commit/14638f4a60053b085565e597fc74bd31cf0d372b))
- do not watch properties starting with $
([34a6da24](https://github.com/angular/angular.js/commit/34a6da24c17356d4ffc70aec3f621a140a9a61ab),
[#11930](https://github.com/angular/angular.js/issues/11930), [#12010](https://github.com/angular/angular.js/issues/12010))
- use reference check only when not using trackBy
([d7dc14dc](https://github.com/angular/angular.js/commit/d7dc14dc0cdeb9c187d227e19acc8aca7df9d740),
[#11936](https://github.com/angular/angular.js/issues/11936), [#11996](https://github.com/angular/angular.js/issues/11996))
- **orderBy:** ensure correct ordering with arrays of objects and no predicate
([48e1f560](https://github.com/angular/angular.js/commit/48e1f5605edd32a63318fd78f5165c7d1f1a20f9),
[#11866](https://github.com/angular/angular.js/issues/11866), [#11312](https://github.com/angular/angular.js/issues/11312), [#4282](https://github.com/angular/angular.js/issues/4282))
## Features
- **$compile:** show module name during multidir error
([351fe4b7](https://github.com/angular/angular.js/commit/351fe4b79c50a45a11af2fcd2aa7b6fd3b70058d),
[#11775](https://github.com/angular/angular.js/issues/11775))
- **$q:** $q.resolve as an alias for $q.when
([3ef52980](https://github.com/angular/angular.js/commit/3ef529806fef28b41ca4af86a330f39a95699cf6),
[#11944](https://github.com/angular/angular.js/issues/11944), [#11987](https://github.com/angular/angular.js/issues/11987))
- **ngAria:** add option to disable role=button
([1f5e42e8](https://github.com/angular/angular.js/commit/1f5e42e8821217026ef36a46d36f84d7cd32830a),
[#11580](https://github.com/angular/angular.js/issues/11580), [#12234](https://github.com/angular/angular.js/issues/12234))
## Performance Improvements
- **$compile:** avoid jquery data calls when there is no data
([9efb0d5e](https://github.com/angular/angular.js/commit/9efb0d5ee961b57c8fc144a3138a15955e4010e2))
<a name="1.4.2"></a>
# 1.4.2 nebular-readjustment (2015-07-06)
## Bug Fixes
- **$browser:** prevent infinite digest if changing hash when there is no hashPrefix
([f81ff3be](https://github.com/angular/angular.js/commit/f81ff3beb0c9d19d494c5878086fb57476442b8b),
[#10423](https://github.com/angular/angular.js/issues/10423), [#12145](https://github.com/angular/angular.js/issues/12145))
- **$compile:**
- throw error when requestng new and isolate scopes (async)
([6333d65b](https://github.com/angular/angular.js/commit/6333d65b76e0796cfbab8a2953af0c8014dba2e1),
[#12215](https://github.com/angular/angular.js/issues/12215), [#12217](https://github.com/angular/angular.js/issues/12217))
- **$location:** allow navigating outside the original base URL
([6903b5ec](https://github.com/angular/angular.js/commit/6903b5ec4c04ed6b7c80ef7d638c48639ccdc4bb),
[#11302](https://github.com/angular/angular.js/issues/11302), [#4776](https://github.com/angular/angular.js/issues/4776))
- **merge:** treat dates as atomic values instead of objects.
([6cbbd966](https://github.com/angular/angular.js/commit/6cbbd966479448591f819cbf904e0a3b757613dc),
[#11720](https://github.com/angular/angular.js/issues/11720), [#11720](https://github.com/angular/angular.js/issues/11720))
- **ngOptions:** only watch numeric properties of an array
([14638f4a](https://github.com/angular/angular.js/commit/14638f4a60053b085565e597fc74bd31cf0d372b))
- **orderBy:** ensure correct ordering with arrays of objects and no predicate
([48e1f560](https://github.com/angular/angular.js/commit/48e1f5605edd32a63318fd78f5165c7d1f1a20f9),
[#11866](https://github.com/angular/angular.js/issues/11866), [#11312](https://github.com/angular/angular.js/issues/11312), [#4282](https://github.com/angular/angular.js/issues/4282))
## Features
- **ngAria:** add option to disable role=button
([1f5e42e8](https://github.com/angular/angular.js/commit/1f5e42e8821217026ef36a46d36f84d7cd32830a),
[#11580](https://github.com/angular/angular.js/issues/11580), [#12234](https://github.com/angular/angular.js/issues/12234))
<a name="1.3.17"></a>
# 1.3.17 tsktskskly-euouae (2015-07-06)
## Bug Fixes
- **$browser:** prevent infinite digest if changing hash when there is no hashPrefix
([61a3fb67](https://github.com/angular/angular.js/commit/61a3fb676a186e22564fb0181c17647b35ca4e5e),
[#10423](https://github.com/angular/angular.js/issues/10423), [#12145](https://github.com/angular/angular.js/issues/12145))
- **$location:**
- allow navigating outside the original base URL
([0bb57d53](https://github.com/angular/angular.js/commit/0bb57d538f25a1b6f20025d87a451c39671b59aa),
[#11302](https://github.com/angular/angular.js/issues/11302), [#4776](https://github.com/angular/angular.js/issues/4776))
- do not get caught in infinite digest in IE9
([f486ebe8](https://github.com/angular/angular.js/commit/f486ebe80b6d7854d3eb9029f14d94299cf493cb),
[#11439](https://github.com/angular/angular.js/issues/11439), [#11675](https://github.com/angular/angular.js/issues/11675), [#11935](https://github.com/angular/angular.js/issues/11935), [#12083](https://github.com/angular/angular.js/issues/12083))
- **linky:** allow case insensitive scheme detection
([6b28aef1](https://github.com/angular/angular.js/commit/6b28aef1c537bfb2da21820d6ca154344efe266e),
[#12073](https://github.com/angular/angular.js/issues/12073), [#12074](https://github.com/angular/angular.js/issues/12074))
<a name="1.4.1"></a>
# 1.4.1 hyperionic-illumination (2015-06-16)
+6
View File
@@ -199,9 +199,14 @@ format that includes a **type**, a **scope** and a **subject**:
<footer>
```
The **header** is mandatory and the **scope** of the header is optional.
Any line of the commit message cannot be longer 100 characters! This allows the message to be easier
to read on github as well as in various git tools.
### Revert
If the commit reverts a previous commit, it should begin with `revert: `, followed by the header of the reverted commit. In the body it should say: `This reverts commit <hash>.`, where the hash is the SHA of the commit being reverted.
### Type
Must be one of the following:
@@ -235,6 +240,7 @@ The body should include the motivation for the change and contrast this with pre
The footer should contain any information about **Breaking Changes** and is also the place to
reference GitHub issues that this commit **Closes**.
**Breaking Changes** should start with the word `BREAKING CHANGE:` with a space or two newlines. The rest of the commit message is then used for this.
A detailed explanation can be found in this [document][commit-message-format].
+6 -3
View File
@@ -5,13 +5,16 @@
# Understanding Controllers
In Angular, a Controller is a JavaScript **constructor function** that is used to augment the
In Angular, a Controller is defined by a JavaScript **constructor function** that is used to augment the
{@link scope Angular Scope}.
When a Controller is attached to the DOM via the {@link ng.directive:ngController ng-controller}
directive, Angular will instantiate a new Controller object, using the specified Controller's
**constructor function**. A new **child scope** will be available as an injectable parameter to the
Controller's constructor function as `$scope`.
**constructor function**. A new **child scope** will be created and made available as an injectable
parameter to the Controller's constructor function as `$scope`.
If the controller has been attached using the `controller as` syntax then the controller instance will
be assigned to a property on the new scope.
Use controllers to:
+1 -1
View File
@@ -116,7 +116,7 @@ module.exports = {
.replace(/\\/g, '\\\\')
.replace(/'/g, "\\'")
.replace(/\r?\n/g, '\\n');
js = "!window.angular.$$csp() && window.angular.element(document).find('head').prepend('<style type=\"text/css\">" + css + "</style>');";
js = "!window.angular.$$csp() && window.angular.element(document.head).prepend('<style type=\"text/css\">" + css + "</style>');";
state.js.push(js);
return state;
-2
View File
@@ -87,7 +87,6 @@
$$TestabilityProvider,
$TimeoutProvider,
$$RAFProvider,
$$AsyncCallbackProvider,
$WindowProvider,
$$jqLiteProvider,
$$CookieReaderProvider
@@ -248,7 +247,6 @@ function publishExternalAPI(angular) {
$timeout: $TimeoutProvider,
$window: $WindowProvider,
$$rAF: $$RAFProvider,
$$asyncCallback: $$AsyncCallbackProvider,
$$jqLite: $$jqLiteProvider,
$$HashMap: $$HashMapProvider,
$$cookieReader: $$CookieReaderProvider
+1
View File
@@ -5,3 +5,4 @@
*/
'use strict';
(function() {
function isFunction(value) {return typeof value === 'function';};
+16 -4
View File
@@ -186,7 +186,7 @@
* to the element during the animation. Multiple events can be provided when spaces are used as a separator. (Note that this will not perform any DOM operation.)
* * `easing` - The CSS easing value that will be applied to the transition or keyframe animation (or both).
* * `transition` - The raw CSS transition style that will be used (e.g. `1s linear all`).
* * `keyframe` - The raw CSS keyframe animation style that will be used (e.g. `1s my_animation linear`).
* * `keyframeStyle` - The raw CSS keyframe animation style that will be used (e.g. `1s my_animation linear`).
* * `from` - The starting CSS styles (a key/value object) that will be applied at the start of the animation.
* * `to` - The ending CSS styles (a key/value object) that will be applied across the animation via a CSS transition.
* * `addClass` - A space separated list of CSS classes that will be added to the element and spread across the animation.
@@ -497,6 +497,10 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
function init(element, options) {
var node = getDomNode(element);
if (!node || !node.parentNode) {
return closeAndReturnNoopAnimator();
}
options = prepareAnimationOptions(options);
var temporaryStyles = [];
@@ -556,10 +560,14 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
var fullClassName = classes + ' ' + setupClasses;
var activeClasses = pendClasses(setupClasses, '-active');
var hasToStyles = styles.to && Object.keys(styles.to).length > 0;
var containsKeyframeAnimation = (options.keyframeStyle || '').length > 0;
// there is no way we can trigger an animation since no styles and
// no classes are being applied which would then trigger a transition
if (!hasToStyles && !setupClasses) {
// there is no way we can trigger an animation if no styles and
// no classes are being applied which would then trigger a transition,
// unless there a is raw keyframe value that is applied to the element.
if (!containsKeyframeAnimation
&& !hasToStyles
&& !setupClasses) {
return closeAndReturnNoopAnimator();
}
@@ -782,6 +790,10 @@ var $AnimateCssProvider = ['$animateProvider', function($animateProvider) {
function start() {
if (animationClosed) return;
if (!node.parentNode) {
close();
return;
}
var startTime, events = [];
+1 -1
View File
@@ -138,7 +138,7 @@ var $$AnimationProvider = ['$animateProvider', function($animateProvider) {
? (animationEntry.from.element || animationEntry.to.element)
: animationEntry.element;
if (getRunner(targetElement)) {
if (getRunner(targetElement) && getDomNode(targetElement).parentNode) {
var operation = invokeFirstDriver(animationEntry);
if (operation) {
startAnimationFn = operation.start;
+2 -18
View File
@@ -764,15 +764,14 @@ angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
};
});
$provide.decorator('$animate', ['$delegate', '$$asyncCallback', '$timeout', '$browser', '$$rAF',
function($delegate, $$asyncCallback, $timeout, $browser, $$rAF) {
$provide.decorator('$animate', ['$delegate', '$timeout', '$browser', '$$rAF',
function($delegate, $timeout, $browser, $$rAF) {
var animate = {
queue: [],
cancel: $delegate.cancel,
enabled: $delegate.enabled,
triggerCallbackEvents: function() {
$$rAF.flush();
$$asyncCallback.flush();
},
triggerCallbackPromise: function() {
$timeout.flush(0);
@@ -1764,20 +1763,6 @@ angular.mock.$RAFDecorator = ['$delegate', function($delegate) {
return rafFn;
}];
angular.mock.$AsyncCallbackDecorator = ['$delegate', function($delegate) {
var callbacks = [];
var addFn = function(fn) {
callbacks.push(fn);
};
addFn.flush = function() {
angular.forEach(callbacks, function(fn) {
fn();
});
callbacks = [];
};
return addFn;
}];
/**
*
*/
@@ -1884,7 +1869,6 @@ angular.module('ngMock', ['ng']).provider({
}).config(['$provide', function($provide) {
$provide.decorator('$timeout', angular.mock.$TimeoutDecorator);
$provide.decorator('$$rAF', angular.mock.$RAFDecorator);
$provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator);
$provide.decorator('$rootScope', angular.mock.$RootScopeDecorator);
$provide.decorator('$controller', angular.mock.$ControllerDecorator);
}]);
+3 -1
View File
@@ -407,7 +407,9 @@ function $RouteProvider() {
* @name $route#$routeChangeSuccess
* @eventType broadcast on root scope
* @description
* Broadcasted after a route dependencies are resolved.
* Broadcasted after a route change has happened successfully.
* The `resolve` dependencies are now available in the `current.locals` property.
*
* {@link ngRoute.directive:ngView ngView} listens for the directive
* to instantiate the controller and render the view.
*
-33
View File
@@ -1,33 +0,0 @@
'use strict';
describe('$$asyncCallback', function() {
it('should perform a callback asynchronously', inject(function($$asyncCallback) {
var message = 'hello there ';
$$asyncCallback(function() {
message += 'Angular';
});
expect(message).toBe('hello there ');
$$asyncCallback.flush();
expect(message).toBe('hello there Angular');
}));
describe('mocks', function() {
it('should queue up all async callbacks', inject(function($$asyncCallback) {
var callback = jasmine.createSpy('callback');
$$asyncCallback(callback);
$$asyncCallback(callback);
$$asyncCallback(callback);
expect(callback.callCount).toBe(0);
$$asyncCallback.flush();
expect(callback.callCount).toBe(3);
$$asyncCallback(callback);
$$asyncCallback(callback);
expect(callback.callCount).toBe(3);
$$asyncCallback.flush();
expect(callback.callCount).toBe(5);
}));
});
});
+76 -1
View File
@@ -51,6 +51,43 @@ describe("ngAnimate $animateCss", function() {
describe('when active', function() {
if (!browserSupportsCssAnimations()) return;
it("should silently quit the animation and not throw when an element has no parent during preparation",
inject(function($animateCss, $$rAF, $rootScope, $document, $rootElement) {
var element = jqLite('<div></div>');
expect(function() {
$animateCss(element, {
duration: 1000,
event: 'fake',
to: fakeStyle
}).start();
}).not.toThrow();
expect(element).not.toHaveClass('fake');
triggerAnimationStartFrame();
expect(element).not.toHaveClass('fake-active');
}));
it("should silently quit the animation and not throw when an element has no parent before starting",
inject(function($animateCss, $$rAF, $rootScope, $document, $rootElement) {
var element = jqLite('<div></div>');
jqLite($document[0].body).append($rootElement);
$rootElement.append(element);
$animateCss(element, {
duration: 1000,
addClass: 'wait-for-it',
to: fakeStyle
}).start();
element.remove();
expect(function() {
triggerAnimationStartFrame();
}).not.toThrow();
}));
describe("rAF usage", function() {
it("should buffer all requests into a single requestAnimationFrame call",
inject(function($animateCss, $$rAF, $rootScope, $document, $rootElement) {
@@ -2017,7 +2054,7 @@ describe("ngAnimate $animateCss", function() {
});
});
describe("[transtionStyle]", function() {
describe("[transitionStyle]", function() {
it("should apply the transition directly onto the element and animate accordingly",
inject(function($animateCss, $rootElement) {
@@ -2092,6 +2129,27 @@ describe("ngAnimate $animateCss", function() {
expect(element.css('transition-property')).toMatch('color');
expect(style).toContain('ease-in');
}));
it("should execute the animation only if there is any provided CSS styling to go with the transition",
inject(function($animateCss, $rootElement) {
var options = {
transitionStyle: '6s 4s ease-out all'
};
$animateCss(element, options).start();
triggerAnimationStartFrame();
expect(element.css(prefix + 'transition-delay')).not.toEqual('4s');
expect(element.css(prefix + 'transition-duration')).not.toEqual('6s');
options.to = { color: 'brown' };
$animateCss(element, options).start();
triggerAnimationStartFrame();
expect(element.css(prefix + 'transition-delay')).toEqual('4s');
expect(element.css(prefix + 'transition-duration')).toEqual('6s');
}));
});
describe("[keyframeStyle]", function() {
@@ -2167,6 +2225,23 @@ describe("ngAnimate $animateCss", function() {
expect(element.css(prefix + 'animation-duration')).toEqual('5.5s');
expect(element.css(prefix + 'animation-name')).toEqual('my_animation');
}));
it("should be able to execute the animation if it is the only provided value",
inject(function($animateCss, $rootElement) {
var options = {
keyframeStyle: 'my_animation 5.5s 10s'
};
var animator = $animateCss(element, options);
animator.start();
triggerAnimationStartFrame();
expect(element.css(prefix + 'animation-delay')).toEqual('10s');
expect(element.css(prefix + 'animation-duration')).toEqual('5.5s');
expect(element.css(prefix + 'animation-name')).toEqual('my_animation');
}));
});
describe("[from] and [to]", function() {
+23 -5
View File
@@ -80,8 +80,10 @@ describe('$$animation', function() {
};
});
inject(function($$animation, $rootScope) {
inject(function($$animation, $rootScope, $rootElement) {
element = jqLite('<div></div>');
$rootElement.append(element);
$$animation(element, 'enter');
$rootScope.$digest();
@@ -109,7 +111,8 @@ describe('$$animation', function() {
}));
it("should obtain the element, event, the provided options and the domOperation",
inject(function($$animation, $rootScope) {
inject(function($$animation, $rootScope, $rootElement) {
$rootElement.append(element);
var options = {};
options.foo = 'bar';
@@ -132,9 +135,11 @@ describe('$$animation', function() {
}));
it("should obtain the classes string which is a combination of className, addClass and removeClass",
inject(function($$animation, $rootScope) {
inject(function($$animation, $rootScope, $rootElement) {
element.addClass('blue red');
$rootElement.append(element);
$$animation(element, 'enter', {
addClass: 'green',
removeClass: 'orange',
@@ -165,8 +170,9 @@ describe('$$animation', function() {
});
});
inject(function($$animation, $rootScope) {
inject(function($$animation, $rootScope, $rootElement) {
element = jqLite('<div></div>');
$rootElement.append(element);
$$animation(element, 'enter');
$rootScope.$digest();
expect(log).toEqual(['second', 'first']);
@@ -237,8 +243,10 @@ describe('$$animation', function() {
});
});
inject(function($$animation, $rootScope) {
inject(function($$animation, $rootScope, $rootElement) {
element = jqLite('<div></div>');
$rootElement.append(element);
var runner = $$animation(element, 'enter');
$rootScope.$digest();
@@ -791,6 +799,8 @@ describe('$$animation', function() {
it('should temporarily assign the provided CSS class for the duration of the animation',
inject(function($rootScope, $$animation) {
parent.append(element);
$$animation(element, 'enter', {
tempClasses: 'temporary fudge'
});
@@ -809,6 +819,8 @@ describe('$$animation', function() {
it('should add and remove the ng-animate CSS class when the animation is active',
inject(function($$animation, $rootScope) {
parent.append(element);
$$animation(element, 'enter');
$rootScope.$digest();
expect(element).toHaveClass('ng-animate');
@@ -823,6 +835,8 @@ describe('$$animation', function() {
it('should apply the `ng-animate` and temporary CSS classes before the driver is invoked', function() {
var capturedElementClasses;
parent.append(element);
module(function($provide) {
$provide.factory('mockedTestDriver', function() {
return function(details) {
@@ -832,6 +846,8 @@ describe('$$animation', function() {
});
inject(function($$animation, $rootScope) {
parent.append(element);
$$animation(element, 'enter', {
tempClasses: 'temp-class-name'
});
@@ -845,6 +861,8 @@ describe('$$animation', function() {
it('should perform the DOM operation at the end of the animation if the driver doesn\'t run it already',
inject(function($$animation, $rootScope) {
parent.append(element);
var domOperationFired = false;
$$animation(element, 'enter', {
domOperation: function() {
+27
View File
@@ -105,6 +105,33 @@ describe('ngAnimate integration tests', function() {
expect(animationCompleted).toBe(true);
});
});
it('should not throw an error if the element is orphaned before the CSS animation starts',
inject(function($rootScope, $rootElement, $animate, $$rAF) {
ss.addRule('.animate-me', 'transition:2s linear all;');
var parent = jqLite('<div></div>');
html(parent);
var element = jqLite('<div class="animate-me">DOING</div>');
parent.append(element);
$animate.addClass(parent, 'on');
$animate.addClass(element, 'on');
$rootScope.$digest();
// this will run the first class-based animation
$$rAF.flush();
element.remove();
expect(function() {
$$rAF.flush();
}).not.toThrow();
dealoc(element);
}));
});
describe('JS animations', function() {