From 180e58de522c2577e5a0814139d27e8e20491602 Mon Sep 17 00:00:00 2001 From: squelix Date: Wed, 15 Jun 2016 14:25:51 +0200 Subject: [PATCH 1/7] feat(directive): add possibility to collapse horizontally New directive to collapse horizontally or vertically : put 'horizontal' to collapse horizontally or pu nothing to do vertically --- src/collapse/collapse.js | 131 ++++++--- src/collapse/docs/demo.html | 8 +- src/collapse/docs/demo.js | 1 + src/collapse/docs/readme.md | 4 + .../test/collapseHorizontally.spec.js | 255 ++++++++++++++++++ 5 files changed, 362 insertions(+), 37 deletions(-) create mode 100644 src/collapse/test/collapseHorizontally.spec.js diff --git a/src/collapse/collapse.js b/src/collapse/collapse.js index cafd93a3ea..4e92d3acb5 100644 --- a/src/collapse/collapse.js +++ b/src/collapse/collapse.js @@ -7,14 +7,24 @@ angular.module('ui.bootstrap.collapse', []) var expandingExpr = $parse(attrs.expanding), expandedExpr = $parse(attrs.expanded), collapsingExpr = $parse(attrs.collapsing), - collapsedExpr = $parse(attrs.collapsed); + collapsedExpr = $parse(attrs.collapsed), + horizontal = false; if (!scope.$eval(attrs.uibCollapse)) { - element.addClass('in') - .addClass('collapse') - .attr('aria-expanded', true) - .attr('aria-hidden', false) - .css({height: 'auto'}); + if (horizontal) { + element.addClass('in') + .addClass('collapse') + .attr('aria-expanded', true) + .attr('aria-hidden', false) + .css({width: 'auto'}) + .css({height: 'inherit'}); + } else { + element.addClass('in') + .addClass('collapse') + .attr('aria-expanded', true) + .attr('aria-hidden', false) + .css({height: 'auto'}); + } } function expand() { @@ -29,24 +39,44 @@ angular.module('ui.bootstrap.collapse', []) .attr('aria-expanded', true) .attr('aria-hidden', false); - if ($animateCss) { - $animateCss(element, { - addClass: 'in', - easing: 'ease', - to: { height: element[0].scrollHeight + 'px' } - }).start()['finally'](expandDone); + if (horizontal) { + if ($animateCss) { + $animateCss(element, { + addClass: 'in', + easing: 'ease', + to: {width: element[0].scrollWidth + 'px'} + }).start()['finally'](expandDone); + } else { + $animate.addClass(element, 'in', { + to: {width: element[0].scrollWidth + 'px'} + }).then(expandDone); + } } else { - $animate.addClass(element, 'in', { - to: { height: element[0].scrollHeight + 'px' } - }).then(expandDone); + if ($animateCss) { + $animateCss(element, { + addClass: 'in', + easing: 'ease', + to: {height: element[0].scrollHeight + 'px'} + }).start()['finally'](expandDone); + } else { + $animate.addClass(element, 'in', { + to: {height: element[0].scrollHeight + 'px'} + }).then(expandDone); + } } }); } function expandDone() { - element.removeClass('collapsing') - .addClass('collapse') - .css({height: 'auto'}); + if (horizontal) { + element.removeClass('collapsing') + .addClass('collapse') + .css({width: 'auto'}); + } else { + element.removeClass('collapsing') + .addClass('collapse') + .css({height: 'auto'}); + } expandedExpr(scope); } @@ -57,33 +87,62 @@ angular.module('ui.bootstrap.collapse', []) $q.resolve(collapsingExpr(scope)) .then(function() { - element + if (horizontal) { + element + // IMPORTANT: The width must be set before adding "collapsing" class. + // Otherwise, the browser attempts to animate from width 0 (in + // collapsing class) to the given width here. + .css({width: element[0].scrollWidth + 'px'}) + // initially all panel collapse have the collapse class, this removal + // prevents the animation from jumping to collapsed state + .removeClass('collapse') + .addClass('collapsing') + .attr('aria-expanded', false) + .attr('aria-hidden', true); + + if ($animateCss) { + $animateCss(element, { + removeClass: 'in', + to: {width: '0'} + }).start()['finally'](collapseDone); + } else { + $animate.removeClass(element, 'in', { + to: {width: '0'} + }).then(collapseDone); + } + } else { + element // IMPORTANT: The height must be set before adding "collapsing" class. // Otherwise, the browser attempts to animate from height 0 (in // collapsing class) to the given height here. - .css({height: element[0].scrollHeight + 'px'}) - // initially all panel collapse have the collapse class, this removal - // prevents the animation from jumping to collapsed state - .removeClass('collapse') - .addClass('collapsing') - .attr('aria-expanded', false) - .attr('aria-hidden', true); + .css({height: element[0].scrollHeight + 'px'}) + // initially all panel collapse have the collapse class, this removal + // prevents the animation from jumping to collapsed state + .removeClass('collapse') + .addClass('collapsing') + .attr('aria-expanded', false) + .attr('aria-hidden', true); - if ($animateCss) { - $animateCss(element, { - removeClass: 'in', - to: {height: '0'} - }).start()['finally'](collapseDone); - } else { - $animate.removeClass(element, 'in', { - to: {height: '0'} - }).then(collapseDone); + if ($animateCss) { + $animateCss(element, { + removeClass: 'in', + to: {height: '0'} + }).start()['finally'](collapseDone); + } else { + $animate.removeClass(element, 'in', { + to: {height: '0'} + }).then(collapseDone); + } } }); } function collapseDone() { - element.css({height: '0'}); // Required so that collapse works when animation is disabled + if (horizontal) { + element.css({width: '0'}); // Required so that collapse works when animation is disabled + } else { + element.css({height: '0'}); // Required so that collapse works when animation is disabled + } element.removeClass('collapsing') .addClass('collapse'); collapsedExpr(scope); diff --git a/src/collapse/docs/demo.html b/src/collapse/docs/demo.html index 462bda3ba0..51e25f089b 100644 --- a/src/collapse/docs/demo.html +++ b/src/collapse/docs/demo.html @@ -1,7 +1,13 @@
- +
Some content
+ + +
+
+
Some content
+
diff --git a/src/collapse/docs/demo.js b/src/collapse/docs/demo.js index 897eecaf58..b838cb2117 100644 --- a/src/collapse/docs/demo.js +++ b/src/collapse/docs/demo.js @@ -1,3 +1,4 @@ angular.module('ui.bootstrap.demo').controller('CollapseDemoCtrl', function ($scope) { $scope.isCollapsed = false; + $scope.isCollapsedHorizontal = false; }); diff --git a/src/collapse/docs/readme.md b/src/collapse/docs/readme.md index 60237b9952..80612c95e9 100644 --- a/src/collapse/docs/readme.md +++ b/src/collapse/docs/readme.md @@ -27,4 +27,8 @@ _(Default: `false`)_ - Whether the element should be collapsed or not. + +* `horizontal` + $ - + An optional attribute that permit to collapse horizontally. diff --git a/src/collapse/test/collapseHorizontally.spec.js b/src/collapse/test/collapseHorizontally.spec.js new file mode 100644 index 0000000000..af576c7856 --- /dev/null +++ b/src/collapse/test/collapseHorizontally.spec.js @@ -0,0 +1,255 @@ +describe('collapse directive', function() { + var elementH, compileFnH, scope, $compile, $animate, $q; + + beforeEach(module('ui.bootstrap.collapse')); + beforeEach(module('ngAnimateMock')); + beforeEach(inject(function(_$rootScope_, _$compile_, _$animate_, _$q_) { + scope = _$rootScope_; + $compile = _$compile_; + $animate = _$animate_; + $q = _$q_; + })); + + beforeEach(function() { + elementH = angular.element( + '
' + + 'Some Content
'); + compileFnH = $compile(elementH); + angular.element(document.body).append(elementH); + }); + + afterEach(function() { + elementH.remove(); + }); + + function initCallbacks() { + scope.collapsing = jasmine.createSpy('scope.collapsing'); + scope.collapsed = jasmine.createSpy('scope.collapsed'); + scope.expanding = jasmine.createSpy('scope.expanding'); + scope.expanded = jasmine.createSpy('scope.expanded'); + } + + function assertCallbacks(expected) { + ['collapsing', 'collapsed', 'expanding', 'expanded'].forEach(function(cbName) { + if (expected[cbName]) { + expect(scope[cbName]).toHaveBeenCalled(); + } else { + expect(scope[cbName]).not.toHaveBeenCalled(); + } + }); + } + + it('should be hidden on initialization if isCollapsed = true', function() { + initCallbacks(); + scope.isCollapsed = true; + compileFnH(scope); + scope.$digest(); + expect(elementH.height()).toBe(0); + assertCallbacks({ collapsed: true }); + }); + + it('should not trigger any animation on initialization if isCollapsed = true', function() { + var wrapperFn = function() { + $animate.flush(); + }; + + scope.isCollapsed = true; + compileFnH(scope); + scope.$digest(); + + expect(wrapperFn).toThrowError(/No pending animations ready to be closed or flushed/); + }); + + it('should collapse if isCollapsed = true on subsequent use', function() { + scope.isCollapsed = false; + compileFnH(scope); + scope.$digest(); + initCallbacks(); + scope.isCollapsed = true; + scope.$digest(); + $animate.flush(); + expect(elementH.height()).toBe(0); + assertCallbacks({ collapsing: true, collapsed: true }); + }); + + it('should show after toggled from collapsed', function() { + initCallbacks(); + scope.isCollapsed = true; + compileFnH(scope); + scope.$digest(); + expect(elementH.height()).toBe(0); + assertCallbacks({ collapsed: true }); + scope.collapsed.calls.reset(); + + scope.isCollapsed = false; + scope.$digest(); + $animate.flush(); + expect(elementH.width()).not.toBe(0); + assertCallbacks({ expanding: true, expanded: true }); + }); + + it('should not trigger any animation on initialization if isCollapsed = false', function() { + var wrapperFn = function() { + $animate.flush(); + }; + + scope.isCollapsed = false; + compileFnH(scope); + scope.$digest(); + + expect(wrapperFn).toThrowError(/No pending animations ready to be closed or flushed/); + }); + + it('should expand if isCollapsed = false on subsequent use', function() { + scope.isCollapsed = false; + compileFnH(scope); + scope.$digest(); + scope.isCollapsed = true; + scope.$digest(); + $animate.flush(); + initCallbacks(); + scope.isCollapsed = false; + scope.$digest(); + $animate.flush(); + expect(elementH.width()).not.toBe(0); + assertCallbacks({ expanding: true, expanded: true }); + }); + + it('should collapse if isCollapsed = true on subsequent uses', function() { + scope.isCollapsed = false; + compileFnH(scope); + scope.$digest(); + scope.isCollapsed = true; + scope.$digest(); + $animate.flush(); + scope.isCollapsed = false; + scope.$digest(); + $animate.flush(); + initCallbacks(); + scope.isCollapsed = true; + scope.$digest(); + $animate.flush(); + expect(elementH.height()).toBe(0); + assertCallbacks({ collapsing: true, collapsed: true }); + }); + + it('should change aria-expanded attribute', function() { + scope.isCollapsed = false; + compileFnH(scope); + scope.$digest(); + expect(elementH.attr('aria-expanded')).toBe('true'); + + scope.isCollapsed = true; + scope.$digest(); + $animate.flush(); + expect(elementH.attr('aria-expanded')).toBe('false'); + }); + + it('should change aria-hidden attribute', function() { + scope.isCollapsed = false; + compileFnH(scope); + scope.$digest(); + expect(elementH.attr('aria-hidden')).toBe('false'); + + scope.isCollapsed = true; + scope.$digest(); + $animate.flush(); + expect(elementH.attr('aria-hidden')).toBe('true'); + }); + + describe('expanding callback returning a promise', function() { + var defer, collapsedWidth; + + beforeEach(function() { + defer = $q.defer(); + + scope.isCollapsed = true; + scope.expanding = function() { + return defer.promise; + }; + compileFnH(scope); + scope.$digest(); + collapsedWidth = elementH.width(); + + // set flag to expand ... + scope.isCollapsed = false; + scope.$digest(); + + // ... shouldn't expand yet ... + expect(elementH.attr('aria-expanded')).not.toBe('true'); + expect(elementH.width()).toBe(collapsedWidth); + }); + + it('should wait for it to resolve before animating', function() { + defer.resolve(); + + // should now expand + scope.$digest(); + $animate.flush(); + + expect(elementH.attr('aria-expanded')).toBe('true'); + expect(elementH.width()).toBe(collapsedWidth); + }); + + it('should not animate if it rejects', function() { + defer.reject(); + + // should NOT expand + scope.$digest(); + + expect(elementH.attr('aria-expanded')).not.toBe('true'); + expect(elementH.width()).toBe(collapsedWidth); + }); + }); + + describe('collapsing callback returning a promise', function() { + var defer, expandedWidth; + + beforeEach(function() { + defer = $q.defer(); + scope.isCollapsed = false; + scope.collapsing = function() { + return defer.promise; + }; + compileFnH(scope); + scope.$digest(); + + expandedWidth = elementH.width(); + + // set flag to collapse ... + scope.isCollapsed = true; + scope.$digest(); + + // ... but it shouldn't collapse yet ... + expect(elementH.attr('aria-expanded')).not.toBe('false'); + expect(elementH.width()).toBe(expandedWidth); + }); + + it('should wait for it to resolve before animating', function() { + defer.resolve(); + + // should now collapse + scope.$digest(); + $animate.flush(); + + expect(elementH.attr('aria-expanded')).toBe('false'); + expect(elementH.width()).toBe(expandedWidth); + }); + + it('should not animate if it rejects', function() { + defer.reject(); + + // should NOT collapse + scope.$digest(); + + expect(elementH.attr('aria-expanded')).not.toBe('false'); + expect(elementH.width()).toBe(expandedWidth); + }); + }); + +}); From 9eb64871a4946b6952721ea79c4cb5a683307e4a Mon Sep 17 00:00:00 2001 From: squelix Date: Wed, 15 Jun 2016 14:57:15 +0200 Subject: [PATCH 2/7] fix(example): correct the horizontal collapse example Correct the horizontal collapse example --- src/collapse/docs/demo.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/collapse/docs/demo.html b/src/collapse/docs/demo.html index 51e25f089b..5367fc275e 100644 --- a/src/collapse/docs/demo.html +++ b/src/collapse/docs/demo.html @@ -5,9 +5,9 @@
Some content
- +
-
+
Some content
From 7d55c1e59d59fcac0fcc06886ba28f1c184add19 Mon Sep 17 00:00:00 2001 From: squelix Date: Wed, 15 Jun 2016 15:23:12 +0200 Subject: [PATCH 3/7] fix(collapse): forget to horizontal attribute Forget to detect the 'horizontal' attribute --- src/collapse/collapse.js | 2 ++ src/collapse/test/collapseHorizontally.spec.js | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/collapse/collapse.js b/src/collapse/collapse.js index 4e92d3acb5..6aeb8fbd42 100644 --- a/src/collapse/collapse.js +++ b/src/collapse/collapse.js @@ -10,6 +10,8 @@ angular.module('ui.bootstrap.collapse', []) collapsedExpr = $parse(attrs.collapsed), horizontal = false; + horizontal = !!('horizontal' in attrs); + if (!scope.$eval(attrs.uibCollapse)) { if (horizontal) { element.addClass('in') diff --git a/src/collapse/test/collapseHorizontally.spec.js b/src/collapse/test/collapseHorizontally.spec.js index af576c7856..e5b22bdb56 100644 --- a/src/collapse/test/collapseHorizontally.spec.js +++ b/src/collapse/test/collapseHorizontally.spec.js @@ -49,7 +49,7 @@ describe('collapse directive', function() { scope.isCollapsed = true; compileFnH(scope); scope.$digest(); - expect(elementH.height()).toBe(0); + expect(elementH.width()).toBe(0); assertCallbacks({ collapsed: true }); }); @@ -73,7 +73,7 @@ describe('collapse directive', function() { scope.isCollapsed = true; scope.$digest(); $animate.flush(); - expect(elementH.height()).toBe(0); + expect(elementH.width()).toBe(0); assertCallbacks({ collapsing: true, collapsed: true }); }); @@ -82,7 +82,7 @@ describe('collapse directive', function() { scope.isCollapsed = true; compileFnH(scope); scope.$digest(); - expect(elementH.height()).toBe(0); + expect(elementH.width()).toBe(0); assertCallbacks({ collapsed: true }); scope.collapsed.calls.reset(); @@ -134,7 +134,7 @@ describe('collapse directive', function() { scope.isCollapsed = true; scope.$digest(); $animate.flush(); - expect(elementH.height()).toBe(0); + expect(elementH.width()).toBe(0); assertCallbacks({ collapsing: true, collapsed: true }); }); @@ -193,7 +193,7 @@ describe('collapse directive', function() { $animate.flush(); expect(elementH.attr('aria-expanded')).toBe('true'); - expect(elementH.width()).toBe(collapsedWidth); + expect(elementH.width()).toBeGreaterThan(collapsedWidth); }); it('should not animate if it rejects', function() { @@ -238,7 +238,7 @@ describe('collapse directive', function() { $animate.flush(); expect(elementH.attr('aria-expanded')).toBe('false'); - expect(elementH.width()).toBe(expandedWidth); + expect(elementH.width()).toBeLessThan(expandedWidth); }); it('should not animate if it rejects', function() { From 1759daec59ac66ca7cfc63a2dd4424dcf2090f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20DEPARDON?= Date: Wed, 15 Jun 2016 16:14:49 +0200 Subject: [PATCH 4/7] Update dropdown.js --- src/dropdown/dropdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dropdown/dropdown.js b/src/dropdown/dropdown.js index 97ce5f10d6..b195224840 100644 --- a/src/dropdown/dropdown.js +++ b/src/dropdown/dropdown.js @@ -1,6 +1,6 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position']) -.constant('uibDropdownConfig', { +.value('uibDropdownConfig', { appendToOpenClass: 'uib-dropdown-open', openClass: 'open' }) From 4973dc78d8f436776e1a8b42b2763de8aff064f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20DEPARDON?= Date: Wed, 15 Jun 2016 16:24:08 +0200 Subject: [PATCH 5/7] Update dropdown.js --- src/dropdown/dropdown.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dropdown/dropdown.js b/src/dropdown/dropdown.js index b195224840..97ce5f10d6 100644 --- a/src/dropdown/dropdown.js +++ b/src/dropdown/dropdown.js @@ -1,6 +1,6 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position']) -.value('uibDropdownConfig', { +.constant('uibDropdownConfig', { appendToOpenClass: 'uib-dropdown-open', openClass: 'open' }) From a134e988e6ac35e3c9b4a15cf92d25c2d0569f23 Mon Sep 17 00:00:00 2001 From: squelix Date: Wed, 15 Jun 2016 17:03:57 +0200 Subject: [PATCH 6/7] fix(collapse): refactor Refactor to avoid duplication --- src/collapse/collapse.js | 164 ++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 99 deletions(-) diff --git a/src/collapse/collapse.js b/src/collapse/collapse.js index 6aeb8fbd42..9e6b5521d4 100644 --- a/src/collapse/collapse.js +++ b/src/collapse/collapse.js @@ -1,84 +1,79 @@ angular.module('ui.bootstrap.collapse', []) - .directive('uibCollapse', ['$animate', '$q', '$parse', '$injector', function($animate, $q, $parse, $injector) { + .directive('uibCollapse', ['$animate', '$q', '$parse', '$injector', function ($animate, $q, $parse, $injector) { var $animateCss = $injector.has('$animateCss') ? $injector.get('$animateCss') : null; return { - link: function(scope, element, attrs) { + link: function (scope, element, attrs) { var expandingExpr = $parse(attrs.expanding), - expandedExpr = $parse(attrs.expanded), - collapsingExpr = $parse(attrs.collapsing), - collapsedExpr = $parse(attrs.collapsed), - horizontal = false; + expandedExpr = $parse(attrs.expanded), + collapsingExpr = $parse(attrs.collapsing), + collapsedExpr = $parse(attrs.collapsed), + horizontal = false, + cssWidth = {}, + cssHeight = {}, + cssTo = {}; - horizontal = !!('horizontal' in attrs); + init(); - if (!scope.$eval(attrs.uibCollapse)) { + function init() { + horizontal = !!('horizontal' in attrs); if (horizontal) { - element.addClass('in') - .addClass('collapse') - .attr('aria-expanded', true) - .attr('aria-hidden', false) - .css({width: 'auto'}) - .css({height: 'inherit'}); + cssWidth = {width: 'auto'}; + cssHeight = {height: 'inherit'}; + cssTo = {width: '0'}; } else { + cssWidth = {width: 'inherit'}; + cssHeight = {height: 'auto'}; + cssTo = {height: '0'}; + } + if (!scope.$eval(attrs.uibCollapse)) { element.addClass('in') .addClass('collapse') .attr('aria-expanded', true) .attr('aria-hidden', false) - .css({height: 'auto'}); + .css(cssWidth) + .css(cssHeight); } } + function getScrollFromElement(element) { + if (horizontal) { + return {width: element.scrollWidth + 'px'}; + } + return {height: element.scrollHeight + 'px'}; + } + function expand() { if (element.hasClass('collapse') && element.hasClass('in')) { return; } $q.resolve(expandingExpr(scope)) - .then(function() { + .then(function () { element.removeClass('collapse') .addClass('collapsing') .attr('aria-expanded', true) .attr('aria-hidden', false); - if (horizontal) { - if ($animateCss) { - $animateCss(element, { - addClass: 'in', - easing: 'ease', - to: {width: element[0].scrollWidth + 'px'} - }).start()['finally'](expandDone); - } else { - $animate.addClass(element, 'in', { - to: {width: element[0].scrollWidth + 'px'} - }).then(expandDone); - } + if ($animateCss) { + $animateCss(element, { + addClass: 'in', + easing: 'ease', + to: getScrollFromElement(element[0]) + }).start()['finally'](expandDone); } else { - if ($animateCss) { - $animateCss(element, { - addClass: 'in', - easing: 'ease', - to: {height: element[0].scrollHeight + 'px'} - }).start()['finally'](expandDone); - } else { - $animate.addClass(element, 'in', { - to: {height: element[0].scrollHeight + 'px'} - }).then(expandDone); - } + $animate.addClass(element, 'in', { + to: getScrollFromElement(element[0]) + }).then(expandDone); } }); } function expandDone() { - if (horizontal) { - element.removeClass('collapsing') - .addClass('collapse') - .css({width: 'auto'}); - } else { - element.removeClass('collapsing') - .addClass('collapse') - .css({height: 'auto'}); - } + element.removeClass('collapsing') + .addClass('collapse') + .css(cssWidth) + .css(cssHeight); expandedExpr(scope); } @@ -88,69 +83,40 @@ angular.module('ui.bootstrap.collapse', []) } $q.resolve(collapsingExpr(scope)) - .then(function() { - if (horizontal) { - element - // IMPORTANT: The width must be set before adding "collapsing" class. - // Otherwise, the browser attempts to animate from width 0 (in - // collapsing class) to the given width here. - .css({width: element[0].scrollWidth + 'px'}) - // initially all panel collapse have the collapse class, this removal - // prevents the animation from jumping to collapsed state - .removeClass('collapse') - .addClass('collapsing') - .attr('aria-expanded', false) - .attr('aria-hidden', true); + .then(function () { + element + // IMPORTANT: The width must be set before adding "collapsing" class. + // Otherwise, the browser attempts to animate from width 0 (in + // collapsing class) to the given width here. + .css(getScrollFromElement(element[0])) + // initially all panel collapse have the collapse class, this removal + // prevents the animation from jumping to collapsed state + .removeClass('collapse') + .addClass('collapsing') + .attr('aria-expanded', false) + .attr('aria-hidden', true); - if ($animateCss) { - $animateCss(element, { - removeClass: 'in', - to: {width: '0'} - }).start()['finally'](collapseDone); - } else { - $animate.removeClass(element, 'in', { - to: {width: '0'} - }).then(collapseDone); - } + if ($animateCss) { + $animateCss(element, { + removeClass: 'in', + to: cssTo + }).start()['finally'](collapseDone); } else { - element - // IMPORTANT: The height must be set before adding "collapsing" class. - // Otherwise, the browser attempts to animate from height 0 (in - // collapsing class) to the given height here. - .css({height: element[0].scrollHeight + 'px'}) - // initially all panel collapse have the collapse class, this removal - // prevents the animation from jumping to collapsed state - .removeClass('collapse') - .addClass('collapsing') - .attr('aria-expanded', false) - .attr('aria-hidden', true); - - if ($animateCss) { - $animateCss(element, { - removeClass: 'in', - to: {height: '0'} - }).start()['finally'](collapseDone); - } else { - $animate.removeClass(element, 'in', { - to: {height: '0'} - }).then(collapseDone); - } + $animate.removeClass(element, 'in', { + to: cssTo + }).then(collapseDone); } }); } function collapseDone() { - if (horizontal) { - element.css({width: '0'}); // Required so that collapse works when animation is disabled - } else { - element.css({height: '0'}); // Required so that collapse works when animation is disabled - } + element.css(cssTo); // Required so that collapse works when animation is disabled element.removeClass('collapsing') .addClass('collapse'); collapsedExpr(scope); } - scope.$watch(attrs.uibCollapse, function(shouldCollapse) { + scope.$watch(attrs.uibCollapse, function (shouldCollapse) { if (shouldCollapse) { collapse(); } else { From 888196766c9670aedcd3d89fba6f75f65623e464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Depardon?= Date: Thu, 16 Jun 2016 08:18:21 +0200 Subject: [PATCH 7/7] fix(collapse): refactor Refactor to had one call of css() and remove spaces --- src/collapse/collapse.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/collapse/collapse.js b/src/collapse/collapse.js index 9e6b5521d4..5f3a84006f 100644 --- a/src/collapse/collapse.js +++ b/src/collapse/collapse.js @@ -1,16 +1,15 @@ angular.module('ui.bootstrap.collapse', []) - .directive('uibCollapse', ['$animate', '$q', '$parse', '$injector', function ($animate, $q, $parse, $injector) { + .directive('uibCollapse', ['$animate', '$q', '$parse', '$injector', function($animate, $q, $parse, $injector) { var $animateCss = $injector.has('$animateCss') ? $injector.get('$animateCss') : null; return { - link: function (scope, element, attrs) { + link: function(scope, element, attrs) { var expandingExpr = $parse(attrs.expanding), expandedExpr = $parse(attrs.expanded), collapsingExpr = $parse(attrs.collapsing), collapsedExpr = $parse(attrs.collapsed), horizontal = false, - cssWidth = {}, - cssHeight = {}, + css = {}, cssTo = {}; init(); @@ -18,12 +17,16 @@ angular.module('ui.bootstrap.collapse', []) function init() { horizontal = !!('horizontal' in attrs); if (horizontal) { - cssWidth = {width: 'auto'}; - cssHeight = {height: 'inherit'}; + css = { + width: 'auto', + height: 'inherit' + }; cssTo = {width: '0'}; } else { - cssWidth = {width: 'inherit'}; - cssHeight = {height: 'auto'}; + css = { + width: 'inherit', + height: 'auto' + }; cssTo = {height: '0'}; } if (!scope.$eval(attrs.uibCollapse)) { @@ -31,8 +34,7 @@ angular.module('ui.bootstrap.collapse', []) .addClass('collapse') .attr('aria-expanded', true) .attr('aria-hidden', false) - .css(cssWidth) - .css(cssHeight); + .css(css); } } @@ -49,7 +51,7 @@ angular.module('ui.bootstrap.collapse', []) } $q.resolve(expandingExpr(scope)) - .then(function () { + .then(function() { element.removeClass('collapse') .addClass('collapsing') .attr('aria-expanded', true) @@ -72,8 +74,7 @@ angular.module('ui.bootstrap.collapse', []) function expandDone() { element.removeClass('collapsing') .addClass('collapse') - .css(cssWidth) - .css(cssHeight); + .css(css); expandedExpr(scope); } @@ -83,7 +84,7 @@ angular.module('ui.bootstrap.collapse', []) } $q.resolve(collapsingExpr(scope)) - .then(function () { + .then(function() { element // IMPORTANT: The width must be set before adding "collapsing" class. // Otherwise, the browser attempts to animate from width 0 (in @@ -116,7 +117,7 @@ angular.module('ui.bootstrap.collapse', []) collapsedExpr(scope); } - scope.$watch(attrs.uibCollapse, function (shouldCollapse) { + scope.$watch(attrs.uibCollapse, function(shouldCollapse) { if (shouldCollapse) { collapse(); } else {