Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit 5046bd4

Browse files
committed
feat(carousel): remove replace: true usage
- Remove `replace: true` usage from the carousel and the slide BREAKING CHANGE: Due to the removal of `replace: true`, this causes a slight HTML structure change to the carousel and the slide elements - see documentation demos to see how it changes. This also caused removal of the ngTouch built in support - if one is using ng-touch, one needs to add the `ng-swipe-left` and `ng-swipe-right` directives to the carousel element with relevant logic. Closes #5987
1 parent 2458c28 commit 5046bd4

File tree

5 files changed

+69
-90
lines changed

5 files changed

+69
-90
lines changed

src/carousel/carousel.js

+13-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ angular.module('ui.bootstrap.carousel', [])
88
currentInterval, isPlaying, bufferedTransitions = [];
99

1010
var destroyed = false;
11+
$element.addClass('carousel');
1112

1213
self.addSlide = function(slide, element) {
1314
slides.push({
@@ -145,6 +146,9 @@ angular.module('ui.bootstrap.carousel', [])
145146
}
146147
};
147148

149+
$element.on('mouseenter', $scope.pause);
150+
$element.on('mouseleave', $scope.play);
151+
148152
$scope.$on('$destroy', function() {
149153
destroyed = true;
150154
resetTimer();
@@ -280,9 +284,9 @@ angular.module('ui.bootstrap.carousel', [])
280284
.directive('uibCarousel', function() {
281285
return {
282286
transclude: true,
283-
replace: true,
284287
controller: 'UibCarouselController',
285288
controllerAs: 'carousel',
289+
restrict: 'A',
286290
templateUrl: function(element, attrs) {
287291
return attrs.templateUrl || 'uib/template/carousel/carousel.html';
288292
},
@@ -296,11 +300,11 @@ angular.module('ui.bootstrap.carousel', [])
296300
};
297301
})
298302

299-
.directive('uibSlide', function() {
303+
.directive('uibSlide', ['$animate', function($animate) {
300304
return {
301305
require: '^uibCarousel',
306+
restrict: 'A',
302307
transclude: true,
303-
replace: true,
304308
templateUrl: function(element, attrs) {
305309
return attrs.templateUrl || 'uib/template/carousel/slide.html';
306310
},
@@ -309,14 +313,19 @@ angular.module('ui.bootstrap.carousel', [])
309313
index: '=?'
310314
},
311315
link: function (scope, element, attrs, carouselCtrl) {
316+
element.addClass('item');
312317
carouselCtrl.addSlide(scope, element);
313318
//when the scope is destroyed then remove the slide from the current slides array
314319
scope.$on('$destroy', function() {
315320
carouselCtrl.removeSlide(scope);
316321
});
322+
323+
scope.$watch('active', function(active) {
324+
$animate[active ? 'addClass' : 'removeClass'](element, 'active');
325+
});
317326
}
318327
};
319-
})
328+
}])
320329

321330
.animation('.item', ['$animateCss',
322331
function($animateCss) {

src/carousel/docs/demo.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
<div ng-controller="CarouselDemoCtrl">
22
<div style="height: 305px">
3-
<uib-carousel active="active" interval="myInterval" no-wrap="noWrapSlides">
4-
<uib-slide ng-repeat="slide in slides track by slide.id" index="slide.id">
3+
<div uib-carousel active="active" interval="myInterval" no-wrap="noWrapSlides">
4+
<div uib-slide ng-repeat="slide in slides track by slide.id" index="slide.id">
55
<img ng-src="{{slide.image}}" style="margin:auto;">
66
<div class="carousel-caption">
77
<h4>Slide {{slide.id}}</h4>
88
<p>{{slide.text}}</p>
99
</div>
10-
</uib-slide>
11-
</uib-carousel>
10+
</div>
11+
</div>
1212
</div>
1313
<div class="row">
1414
<div class="col-md-6">

src/carousel/test/carousel.spec.js

+37-63
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,5 @@
11
describe('carousel', function() {
2-
beforeEach(module('ui.bootstrap.carousel', function($compileProvider, $provide) {
3-
angular.forEach(['ngSwipeLeft', 'ngSwipeRight'], makeMock);
4-
function makeMock(name) {
5-
$provide.value(name + 'Directive', []); //remove existing directive if it exists
6-
$compileProvider.directive(name, function() {
7-
return function(scope, element, attr) {
8-
element.on(name, function() {
9-
scope.$apply(attr[name]);
10-
});
11-
};
12-
});
13-
}
14-
}));
2+
beforeEach(module('ui.bootstrap.carousel'));
153
beforeEach(module('ngAnimateMock'));
164
beforeEach(module('uib/template/carousel/carousel.html', 'uib/template/carousel/slide.html'));
175

@@ -36,11 +24,11 @@ describe('carousel', function() {
3624
{content: 'three', index: 2}
3725
];
3826
elm = $compile(
39-
'<uib-carousel active="active" interval="interval" no-transition="true" no-pause="nopause">' +
40-
'<uib-slide ng-repeat="slide in slides track by slide.index" index="slide.index">' +
27+
'<div uib-carousel active="active" interval="interval" no-transition="true" no-pause="nopause">' +
28+
'<div uib-slide ng-repeat="slide in slides track by slide.index" index="slide.index">' +
4129
'{{slide.content}}' +
42-
'</uib-slide>' +
43-
'</uib-carousel>'
30+
'</div>' +
31+
'</div>'
4432
)(scope);
4533
scope.interval = 5000;
4634
scope.nopause = undefined;
@@ -60,19 +48,19 @@ describe('carousel', function() {
6048
it('should allow overriding of the carousel template', function() {
6149
$templateCache.put('foo/bar.html', '<div>foo</div>');
6250

63-
elm = $compile('<uib-carousel template-url="foo/bar.html"></uib-carousel>')(scope);
51+
elm = $compile('<div uib-carousel template-url="foo/bar.html"></div>')(scope);
6452
$rootScope.$digest();
6553

66-
expect(elm.html()).toBe('foo');
54+
expect(elm.html()).toBe('<div>foo</div>');
6755
});
6856

6957
it('should allow overriding of the slide template', function() {
7058
$templateCache.put('foo/bar.html', '<div class="slide">bar</div>');
7159

7260
elm = $compile(
73-
'<uib-carousel interval="interval" no-transition="true" no-pause="nopause">' +
74-
'<uib-slide template-url="foo/bar.html"></uib-slide>' +
75-
'</uib-carousel>'
61+
'<div uib-carousel interval="interval" no-transition="true" no-pause="nopause">' +
62+
'<div uib-slide template-url="foo/bar.html"></div>' +
63+
'</div>'
7664
)(scope);
7765
$rootScope.$digest();
7866

@@ -101,11 +89,11 @@ describe('carousel', function() {
10189

10290
it('should stop cycling slides forward when noWrap is truthy', function () {
10391
elm = $compile(
104-
'<uib-carousel active="active" interval="interval" no-wrap="noWrap">' +
105-
'<uib-slide ng-repeat="slide in slides track by slide.index" index="slide.index">' +
92+
'<div uib-carousel active="active" interval="interval" no-wrap="noWrap">' +
93+
'<div uib-slide ng-repeat="slide in slides track by slide.index" index="slide.index">' +
10694
'{{slide.content}}' +
107-
'</uib-slide>' +
108-
'</uib-carousel>'
95+
'</div>' +
96+
'</div>'
10997
)(scope);
11098

11199
scope.noWrap = true;
@@ -124,11 +112,11 @@ describe('carousel', function() {
124112

125113
it('should stop cycling slides backward when noWrap is truthy', function () {
126114
elm = $compile(
127-
'<uib-carousel active="active" interval="interval" no-wrap="noWrap">' +
128-
'<uib-slide ng-repeat="slide in slides track by slide.index" index="slide.index">' +
115+
'<div uib-carousel active="active" interval="interval" no-wrap="noWrap">' +
116+
'<div uib-slide ng-repeat="slide in slides track by slide.index" index="slide.index">' +
129117
'{{slide.content}}' +
130-
'</uib-slide>' +
131-
'</uib-carousel>'
118+
'</div>' +
119+
'</div>'
132120
)(scope);
133121

134122
scope.noWrap = true;
@@ -147,11 +135,11 @@ describe('carousel', function() {
147135
scope.slides = [{active:false,content:'one'}];
148136
scope.$apply();
149137
elm = $compile(
150-
'<uib-carousel active="active" interval="interval" no-transition="true">' +
151-
'<uib-slide ng-repeat="slide in slides" index="$index">' +
138+
'<div uib-carousel active="active" interval="interval" no-transition="true">' +
139+
'<div uib-slide ng-repeat="slide in slides" index="$index">' +
152140
'{{slide.content}}' +
153-
'</uib-slide>' +
154-
'</uib-carousel>'
141+
'</div>' +
142+
'</div>'
155143
)(scope);
156144
var indicators = elm.find('ol.carousel-indicators > li');
157145
expect(indicators.length).toBe(0);
@@ -228,20 +216,6 @@ describe('carousel', function() {
228216
testSlideActive(0);
229217
});
230218

231-
describe('swiping', function() {
232-
it('should go next on swipeLeft', function() {
233-
testSlideActive(0);
234-
elm.triggerHandler('ngSwipeLeft');
235-
testSlideActive(1);
236-
});
237-
238-
it('should go prev on swipeRight', function() {
239-
testSlideActive(0);
240-
elm.triggerHandler('ngSwipeRight');
241-
testSlideActive(2);
242-
});
243-
});
244-
245219
it('should select a slide when clicking on slide indicators', function () {
246220
var indicators = elm.find('ol.carousel-indicators > li');
247221
indicators.eq(1).click();
@@ -269,7 +243,7 @@ describe('carousel', function() {
269243
});
270244

271245
it('should bind the content to slides', function() {
272-
var contents = elm.find('div.item');
246+
var contents = elm.find('div.item [ng-transclude]');
273247

274248
expect(contents.length).toBe(3);
275249
expect(contents.eq(0).text()).toBe('one');
@@ -343,7 +317,7 @@ describe('carousel', function() {
343317
{content:'new3', index: 6}
344318
];
345319
scope.$apply();
346-
var contents = elm.find('div.item');
320+
var contents = elm.find('div.item [ng-transclude]');
347321
expect(contents.length).toBe(3);
348322
expect(contents.eq(0).text()).toBe('new1');
349323
expect(contents.eq(1).text()).toBe('new2');
@@ -441,11 +415,11 @@ describe('carousel', function() {
441415
{content: 'three', id: 2}
442416
];
443417
elm = $compile(
444-
'<uib-carousel active="active" interval="interval" no-transition="true" no-pause="nopause">' +
445-
'<uib-slide ng-repeat="slide in slides | orderBy: \'id\' track by slide.id" index="slide.id">' +
418+
'<div uib-carousel active="active" interval="interval" no-transition="true" no-pause="nopause">' +
419+
'<div uib-slide ng-repeat="slide in slides | orderBy: \'id\' track by slide.id" index="slide.id">' +
446420
'{{slide.content}}' +
447-
'</uib-slide>' +
448-
'</uib-carousel>'
421+
'</div>' +
422+
'</div>'
449423
)(scope);
450424
scope.$apply();
451425
});
@@ -465,7 +439,7 @@ describe('carousel', function() {
465439
scope.slides[1].id = 2;
466440
scope.slides[2].id = 1;
467441
scope.$apply();
468-
var contents = elm.find('div.item');
442+
var contents = elm.find('div.item [ng-transclude]');
469443
expect(contents.length).toBe(3);
470444
expect(contents.eq(0).text()).toBe('three');
471445
expect(contents.eq(1).text()).toBe('two');
@@ -491,7 +465,7 @@ describe('carousel', function() {
491465
scope.slides[2].id = 4;
492466
scope.slides.push({content:'four', id: 5});
493467
scope.$apply();
494-
var contents = elm.find('div.item');
468+
var contents = elm.find('div.item [ng-transclude]');
495469
expect(contents.length).toBe(4);
496470
expect(contents.eq(0).text()).toBe('two');
497471
expect(contents.eq(1).text()).toBe('one');
@@ -503,7 +477,7 @@ describe('carousel', function() {
503477
testSlideActive(1);
504478
scope.slides.splice(1, 1);
505479
scope.$apply();
506-
var contents = elm.find('div.item');
480+
var contents = elm.find('div.item [ng-transclude]');
507481
expect(contents.length).toBe(2);
508482
expect(contents.eq(0).text()).toBe('three');
509483
expect(contents.eq(1).text()).toBe('one');
@@ -583,7 +557,7 @@ describe('carousel', function() {
583557
$templateCache.put('uib/template/carousel/carousel.html', '<div>{{carousel.text}}</div>');
584558

585559
var scope = $rootScope.$new();
586-
var elm = $compile('<uib-carousel interval="bar" no-transition="false" no-pause="true"></uib-carousel>')(scope);
560+
var elm = $compile('<div uib-carousel interval="bar" no-transition="false" no-pause="true"></div>')(scope);
587561
$rootScope.$digest();
588562

589563
var ctrl = elm.controller('uibCarousel');
@@ -593,7 +567,7 @@ describe('carousel', function() {
593567
ctrl.text = 'foo';
594568
$rootScope.$digest();
595569

596-
expect(elm.html()).toBe('foo');
570+
expect(elm.html()).toBe('<div class="ng-binding">foo</div>');
597571
}));
598572
});
599573

@@ -605,11 +579,11 @@ describe('carousel', function() {
605579
{active:false,content:'three'}
606580
];
607581
var elm = $compile(
608-
'<uib-carousel active="active" interval="interval" no-transition="true" no-pause="nopause">' +
609-
'<uib-slide ng-repeat="slide in slides" index="$index" actual="slide">' +
582+
'<div uib-carousel active="active" interval="interval" no-transition="true" no-pause="nopause">' +
583+
'<div uib-slide ng-repeat="slide in slides" index="$index" actual="slide">' +
610584
'{{slide.content}}' +
611-
'</uib-slide>' +
612-
'</uib-carousel>'
585+
'</div>' +
586+
'</div>'
613587
)(scope);
614588
$rootScope.$digest();
615589

template/carousel/carousel.html

+14-16
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
<div ng-mouseenter="pause()" ng-mouseleave="play()" class="carousel" ng-swipe-right="prev()" ng-swipe-left="next()">
2-
<div class="carousel-inner" ng-transclude></div>
3-
<a role="button" href class="left carousel-control" ng-click="prev()" ng-class="{ disabled: isPrevDisabled() }" ng-show="slides.length > 1">
4-
<span aria-hidden="true" class="glyphicon glyphicon-chevron-left"></span>
5-
<span class="sr-only">previous</span>
6-
</a>
7-
<a role="button" href class="right carousel-control" ng-click="next()" ng-class="{ disabled: isNextDisabled() }" ng-show="slides.length > 1">
8-
<span aria-hidden="true" class="glyphicon glyphicon-chevron-right"></span>
9-
<span class="sr-only">next</span>
10-
</a>
11-
<ol class="carousel-indicators" ng-show="slides.length > 1">
12-
<li ng-repeat="slide in slides | orderBy:indexOfSlide track by $index" ng-class="{ active: isActive(slide) }" ng-click="select(slide)">
13-
<span class="sr-only">slide {{ $index + 1 }} of {{ slides.length }}<span ng-if="isActive(slide)">, currently active</span></span>
14-
</li>
15-
</ol>
16-
</div>
1+
<div class="carousel-inner" ng-transclude></div>
2+
<a role="button" href class="left carousel-control" ng-click="prev()" ng-class="{ disabled: isPrevDisabled() }" ng-show="slides.length > 1">
3+
<span aria-hidden="true" class="glyphicon glyphicon-chevron-left"></span>
4+
<span class="sr-only">previous</span>
5+
</a>
6+
<a role="button" href class="right carousel-control" ng-click="next()" ng-class="{ disabled: isNextDisabled() }" ng-show="slides.length > 1">
7+
<span aria-hidden="true" class="glyphicon glyphicon-chevron-right"></span>
8+
<span class="sr-only">next</span>
9+
</a>
10+
<ol class="carousel-indicators" ng-show="slides.length > 1">
11+
<li ng-repeat="slide in slides | orderBy:indexOfSlide track by $index" ng-class="{ active: isActive(slide) }" ng-click="select(slide)">
12+
<span class="sr-only">slide {{ $index + 1 }} of {{ slides.length }}<span ng-if="isActive(slide)">, currently active</span></span>
13+
</li>
14+
</ol>

template/carousel/slide.html

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
<div ng-class="{
2-
'active': active
3-
}" class="item text-center" ng-transclude></div>
1+
<div class="text-center" ng-transclude></div>

0 commit comments

Comments
 (0)