UNPKG

thalassa-aqueduct

Version:

Dynamic haproxy load balancer and configuration. Part of Thalassa

332 lines (311 loc) 10.2 kB
/** * @ngdoc overview * @name ui.bootstrap.carousel * * @description * AngularJS version of an image carousel. * */ angular.module('ui.bootstrap.carousel', ['ui.bootstrap.transition']) .controller('CarouselController', ['$scope', '$timeout', '$transition', '$q', function ($scope, $timeout, $transition, $q) { var self = this, slides = self.slides = [], currentIndex = -1, currentTimeout, isPlaying; self.currentSlide = null; /* direction: "prev" or "next" */ self.select = function(nextSlide, direction) { var nextIndex = slides.indexOf(nextSlide); //Decide direction if it's not given if (direction === undefined) { direction = nextIndex > currentIndex ? "next" : "prev"; } if (nextSlide && nextSlide !== self.currentSlide) { if ($scope.$currentTransition) { $scope.$currentTransition.cancel(); //Timeout so ng-class in template has time to fix classes for finished slide $timeout(goNext); } else { goNext(); } } function goNext() { //If we have a slide to transition from and we have a transition type and we're allowed, go if (self.currentSlide && angular.isString(direction) && !$scope.noTransition && nextSlide.$element) { //We shouldn't do class manip in here, but it's the same weird thing bootstrap does. need to fix sometime nextSlide.$element.addClass(direction); nextSlide.$element[0].offsetWidth = nextSlide.$element[0].offsetWidth; //force reflow //Set all other slides to stop doing their stuff for the new transition angular.forEach(slides, function(slide) { angular.extend(slide, {direction: '', entering: false, leaving: false, active: false}); }); angular.extend(nextSlide, {direction: direction, active: true, entering: true}); angular.extend(self.currentSlide||{}, {direction: direction, leaving: true}); $scope.$currentTransition = $transition(nextSlide.$element, {}); //We have to create new pointers inside a closure since next & current will change (function(next,current) { $scope.$currentTransition.then( function(){ transitionDone(next, current); }, function(){ transitionDone(next, current); } ); }(nextSlide, self.currentSlide)); } else { transitionDone(nextSlide, self.currentSlide); } self.currentSlide = nextSlide; currentIndex = nextIndex; //every time you change slides, reset the timer restartTimer(); } function transitionDone(next, current) { angular.extend(next, {direction: '', active: true, leaving: false, entering: false}); angular.extend(current||{}, {direction: '', active: false, leaving: false, entering: false}); $scope.$currentTransition = null; } }; /* Allow outside people to call indexOf on slides array */ self.indexOfSlide = function(slide) { return slides.indexOf(slide); }; $scope.next = function() { var newIndex = (currentIndex + 1) % slides.length; //Prevent this user-triggered transition from occurring if there is already one in progress if (!$scope.$currentTransition) { return self.select(slides[newIndex], 'next'); } }; $scope.prev = function() { var newIndex = currentIndex - 1 < 0 ? slides.length - 1 : currentIndex - 1; //Prevent this user-triggered transition from occurring if there is already one in progress if (!$scope.$currentTransition) { return self.select(slides[newIndex], 'prev'); } }; $scope.select = function(slide) { self.select(slide); }; $scope.isActive = function(slide) { return self.currentSlide === slide; }; $scope.slides = function() { return slides; }; $scope.$watch('interval', restartTimer); function restartTimer() { if (currentTimeout) { $timeout.cancel(currentTimeout); } function go() { if (isPlaying) { $scope.next(); restartTimer(); } else { $scope.pause(); } } var interval = +$scope.interval; if (!isNaN(interval) && interval>=0) { currentTimeout = $timeout(go, interval); } } $scope.play = function() { if (!isPlaying) { isPlaying = true; restartTimer(); } }; $scope.pause = function() { if (!$scope.noPause) { isPlaying = false; if (currentTimeout) { $timeout.cancel(currentTimeout); } } }; self.addSlide = function(slide, element) { slide.$element = element; slides.push(slide); //if this is the first slide or the slide is set to active, select it if(slides.length === 1 || slide.active) { self.select(slides[slides.length-1]); if (slides.length == 1) { $scope.play(); } } else { slide.active = false; } }; self.removeSlide = function(slide) { //get the index of the slide inside the carousel var index = slides.indexOf(slide); slides.splice(index, 1); if (slides.length > 0 && slide.active) { if (index >= slides.length) { self.select(slides[index-1]); } else { self.select(slides[index]); } } else if (currentIndex > index) { currentIndex--; } }; }]) /** * @ngdoc directive * @name ui.bootstrap.carousel.directive:carousel * @restrict EA * * @description * Carousel is the outer container for a set of image 'slides' to showcase. * * @param {number=} interval The time, in milliseconds, that it will take the carousel to go to the next slide. * @param {boolean=} noTransition Whether to disable transitions on the carousel. * @param {boolean=} noPause Whether to disable pausing on the carousel (by default, the carousel interval pauses on hover). * * @example <example module="ui.bootstrap"> <file name="index.html"> <carousel> <slide> <img src="http://placekitten.com/150/150" style="margin:auto;"> <div class="carousel-caption"> <p>Beautiful!</p> </div> </slide> <slide> <img src="http://placekitten.com/100/150" style="margin:auto;"> <div class="carousel-caption"> <p>D'aww!</p> </div> </slide> </carousel> </file> <file name="demo.css"> .carousel-indicators { top: auto; bottom: 15px; } </file> </example> */ .directive('carousel', [function() { return { restrict: 'EA', transclude: true, replace: true, controller: 'CarouselController', require: 'carousel', templateUrl: 'template/carousel/carousel.html', scope: { interval: '=', noTransition: '=', noPause: '=' } }; }]) /** * @ngdoc directive * @name ui.bootstrap.carousel.directive:slide * @restrict EA * * @description * Creates a slide inside a {@link ui.bootstrap.carousel.directive:carousel carousel}. Must be placed as a child of a carousel element. * * @param {boolean=} active Model binding, whether or not this slide is currently active. * * @example <example module="ui.bootstrap"> <file name="index.html"> <div ng-controller="CarouselDemoCtrl"> <carousel> <slide ng-repeat="slide in slides" active="slide.active"> <img ng-src="{{slide.image}}" style="margin:auto;"> <div class="carousel-caption"> <h4>Slide {{$index}}</h4> <p>{{slide.text}}</p> </div> </slide> </carousel> <div class="row-fluid"> <div class="span6"> <ul> <li ng-repeat="slide in slides"> <button class="btn btn-mini" ng-class="{'btn-info': !slide.active, 'btn-success': slide.active}" ng-disabled="slide.active" ng-click="slide.active = true">select</button> {{$index}}: {{slide.text}} </li> </ul> <a class="btn" ng-click="addSlide()">Add Slide</a> </div> <div class="span6"> Interval, in milliseconds: <input type="number" ng-model="myInterval"> <br />Enter a negative number to stop the interval. </div> </div> </div> </file> <file name="script.js"> function CarouselDemoCtrl($scope) { $scope.myInterval = 5000; var slides = $scope.slides = []; $scope.addSlide = function() { var newWidth = 200 + ((slides.length + (25 * slides.length)) % 150); slides.push({ image: 'http://placekitten.com/' + newWidth + '/200', text: ['More','Extra','Lots of','Surplus'][slides.length % 4] + ' ' ['Cats', 'Kittys', 'Felines', 'Cutes'][slides.length % 4] }); }; for (var i=0; i<4; i++) $scope.addSlide(); } </file> <file name="demo.css"> .carousel-indicators { top: auto; bottom: 15px; } </file> </example> */ .directive('slide', ['$parse', function($parse) { return { require: '^carousel', restrict: 'EA', transclude: true, replace: true, templateUrl: 'template/carousel/slide.html', scope: { }, link: function (scope, element, attrs, carouselCtrl) { //Set up optional 'active' = binding if (attrs.active) { var getActive = $parse(attrs.active); var setActive = getActive.assign; var lastValue = scope.active = getActive(scope.$parent); scope.$watch(function parentActiveWatch() { var parentActive = getActive(scope.$parent); if (parentActive !== scope.active) { // we are out of sync and need to copy if (parentActive !== lastValue) { // parent changed and it has precedence lastValue = scope.active = parentActive; } else { // if the parent can be assigned then do so setActive(scope.$parent, parentActive = lastValue = scope.active); } } return parentActive; }); } carouselCtrl.addSlide(scope, element); //when the scope is destroyed then remove the slide from the current slides array scope.$on('$destroy', function() { carouselCtrl.removeSlide(scope); }); scope.$watch('active', function(active) { if (active) { carouselCtrl.select(scope); } }); } }; }]);