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

Commit fc7d2d2

Browse files
committed
chore($$forceReflow): create service for issuing reflows in animations
1 parent c77b607 commit fc7d2d2

File tree

5 files changed

+93
-2
lines changed

5 files changed

+93
-2
lines changed

angularFiles.js

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ var angularFiles = {
2121
'src/ng/controller.js',
2222
'src/ng/document.js',
2323
'src/ng/exceptionHandler.js',
24+
'src/ng/forceReflow.js',
2425
'src/ng/http.js',
2526
'src/ng/httpBackend.js',
2627
'src/ng/interpolate.js',

src/AngularPublic.js

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@
6363
$DocumentProvider,
6464
$ExceptionHandlerProvider,
6565
$FilterProvider,
66+
$$ForceReflowProvider,
6667
$InterpolateProvider,
6768
$IntervalProvider,
6869
$$HashMapProvider,
@@ -219,6 +220,7 @@ function publishExternalAPI(angular) {
219220
$document: $DocumentProvider,
220221
$exceptionHandler: $ExceptionHandlerProvider,
221222
$filter: $FilterProvider,
223+
$$forceReflow: $$ForceReflowProvider,
222224
$interpolate: $InterpolateProvider,
223225
$interval: $IntervalProvider,
224226
$http: $HttpProvider,

src/ng/forceReflow.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
var $$ForceReflowProvider = function() {
4+
this.$get = ['$document', function($document) {
5+
return function(domNode) {
6+
//the line below will force the browser to perform a repaint so
7+
//that all the animated elements within the animation frame will
8+
//be properly updated and drawn on screen. This is required to
9+
//ensure that the preparation animation is properly flushed so that
10+
//the active state picks up from there. DO NOT REMOVE THIS LINE.
11+
//DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH
12+
//WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND
13+
//WILL TAKE YEARS AWAY FROM YOUR LIFE.
14+
if (domNode) {
15+
if (!domNode.nodeType && domNode instanceof jqLite) {
16+
domNode = domNode[0];
17+
}
18+
} else {
19+
domNode = $document[0].body;
20+
}
21+
return domNode.offsetWidth + 1;
22+
};
23+
}];
24+
};

src/ngMock/angular-mocks.js

+14-2
Original file line numberDiff line numberDiff line change
@@ -755,11 +755,23 @@ angular.mock.animate = angular.module('ngAnimateMock', ['ng'])
755755

756756
.config(['$provide', function($provide) {
757757

758-
$provide.decorator('$animate', ['$delegate', '$timeout', '$browser', '$$rAF',
759-
function($delegate, $timeout, $browser, $$rAF) {
758+
$provide.factory('$$forceReflow', function() {
759+
function reflowFn() {
760+
reflowFn.totalReflows++;
761+
}
762+
reflowFn.totalReflows = 0;
763+
return reflowFn;
764+
});
765+
766+
$provide.decorator('$animate', ['$delegate', '$timeout', '$browser', '$$rAF', '$$forceReflow',
767+
function($delegate, $timeout, $browser, $$rAF, $$forceReflow) {
768+
760769
var animate = {
761770
queue: [],
762771
cancel: $delegate.cancel,
772+
get reflows() {
773+
return $$forceReflow.totalReflows;
774+
},
763775
enabled: $delegate.enabled,
764776
triggerCallbackEvents: function() {
765777
$$rAF.flush();

test/ng/forceReflowSpec.js

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
'use strict';
2+
3+
describe('$$forceReflow', function() {
4+
it('should issue a reflow by touching the `document.body.client` when no param is provided', function() {
5+
module(function($provide) {
6+
var doc = jqLite('<div></div>');
7+
doc[0].body = {};
8+
doc[0].body.offsetWidth = 10;
9+
$provide.value('$document', doc);
10+
});
11+
inject(function($$forceReflow) {
12+
var value = $$forceReflow();
13+
expect(value).toBe(11);
14+
});
15+
});
16+
17+
it('should issue a reflow by touching the `domNode.offsetWidth` when a domNode param is provided',
18+
inject(function($$forceReflow) {
19+
20+
var elm = {};
21+
elm.offsetWidth = 100;
22+
expect($$forceReflow(elm)).toBe(101);
23+
}));
24+
25+
it('should issue a reflow by touching the `jqLiteNode[0].offsetWidth` when a jqLite node param is provided',
26+
inject(function($$forceReflow) {
27+
28+
var elm = {};
29+
elm.offsetWidth = 200;
30+
elm = jqLite(elm);
31+
expect($$forceReflow(elm)).toBe(201);
32+
}));
33+
34+
describe('$animate with ngAnimateMock', function() {
35+
beforeEach(module('ngAnimateMock'));
36+
37+
it('should keep track of how many reflows have been issued',
38+
inject(function($$forceReflow, $animate) {
39+
40+
var elm = {};
41+
elm.offsetWidth = 10;
42+
43+
expect($animate.reflows).toBe(0);
44+
45+
$$forceReflow(elm);
46+
$$forceReflow(elm);
47+
$$forceReflow(elm);
48+
49+
expect($animate.reflows).toBe(3);
50+
}));
51+
});
52+
});

0 commit comments

Comments
 (0)