Skip to content

Commit

Permalink
chore($$forceReflow): create service for issuing reflows in animations
Browse files Browse the repository at this point in the history
  • Loading branch information
matsko committed Jul 17, 2015
1 parent c77b607 commit fc7d2d2
Show file tree
Hide file tree
Showing 5 changed files with 93 additions and 2 deletions.
1 change: 1 addition & 0 deletions angularFiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ var angularFiles = {
'src/ng/controller.js',
'src/ng/document.js',
'src/ng/exceptionHandler.js',
'src/ng/forceReflow.js',
'src/ng/http.js',
'src/ng/httpBackend.js',
'src/ng/interpolate.js',
Expand Down
2 changes: 2 additions & 0 deletions src/AngularPublic.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
$DocumentProvider,
$ExceptionHandlerProvider,
$FilterProvider,
$$ForceReflowProvider,
$InterpolateProvider,
$IntervalProvider,
$$HashMapProvider,
Expand Down Expand Up @@ -219,6 +220,7 @@ function publishExternalAPI(angular) {
$document: $DocumentProvider,
$exceptionHandler: $ExceptionHandlerProvider,
$filter: $FilterProvider,
$$forceReflow: $$ForceReflowProvider,
$interpolate: $InterpolateProvider,
$interval: $IntervalProvider,
$http: $HttpProvider,
Expand Down
24 changes: 24 additions & 0 deletions src/ng/forceReflow.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
'use strict';

var $$ForceReflowProvider = function() {
this.$get = ['$document', function($document) {
return function(domNode) {
//the line below will force the browser to perform a repaint so
//that all the animated elements within the animation frame will
//be properly updated and drawn on screen. This is required to
//ensure that the preparation animation is properly flushed so that
//the active state picks up from there. DO NOT REMOVE THIS LINE.
//DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH
//WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND
//WILL TAKE YEARS AWAY FROM YOUR LIFE.
if (domNode) {
if (!domNode.nodeType && domNode instanceof jqLite) {
domNode = domNode[0];
}
} else {
domNode = $document[0].body;
}
return domNode.offsetWidth + 1;
};
}];
};
16 changes: 14 additions & 2 deletions src/ngMock/angular-mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -755,11 +755,23 @@ angular.mock.animate = angular.module('ngAnimateMock', ['ng'])

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

$provide.decorator('$animate', ['$delegate', '$timeout', '$browser', '$$rAF',
function($delegate, $timeout, $browser, $$rAF) {
$provide.factory('$$forceReflow', function() {
function reflowFn() {
reflowFn.totalReflows++;
}
reflowFn.totalReflows = 0;
return reflowFn;
});

$provide.decorator('$animate', ['$delegate', '$timeout', '$browser', '$$rAF', '$$forceReflow',
function($delegate, $timeout, $browser, $$rAF, $$forceReflow) {

var animate = {
queue: [],
cancel: $delegate.cancel,
get reflows() {
return $$forceReflow.totalReflows;
},
enabled: $delegate.enabled,
triggerCallbackEvents: function() {
$$rAF.flush();
Expand Down
52 changes: 52 additions & 0 deletions test/ng/forceReflowSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
'use strict';

describe('$$forceReflow', function() {
it('should issue a reflow by touching the `document.body.client` when no param is provided', function() {
module(function($provide) {
var doc = jqLite('<div></div>');
doc[0].body = {};
doc[0].body.offsetWidth = 10;
$provide.value('$document', doc);
});
inject(function($$forceReflow) {
var value = $$forceReflow();
expect(value).toBe(11);
});
});

it('should issue a reflow by touching the `domNode.offsetWidth` when a domNode param is provided',
inject(function($$forceReflow) {

var elm = {};
elm.offsetWidth = 100;
expect($$forceReflow(elm)).toBe(101);
}));

it('should issue a reflow by touching the `jqLiteNode[0].offsetWidth` when a jqLite node param is provided',
inject(function($$forceReflow) {

var elm = {};
elm.offsetWidth = 200;
elm = jqLite(elm);
expect($$forceReflow(elm)).toBe(201);
}));

describe('$animate with ngAnimateMock', function() {
beforeEach(module('ngAnimateMock'));

it('should keep track of how many reflows have been issued',
inject(function($$forceReflow, $animate) {

var elm = {};
elm.offsetWidth = 10;

expect($animate.reflows).toBe(0);

$$forceReflow(elm);
$$forceReflow(elm);
$$forceReflow(elm);

expect($animate.reflows).toBe(3);
}));
});
});

0 comments on commit fc7d2d2

Please sign in to comment.