1; (function ($, window) { 2 3 var debug = false; 4 var diag = function (message) { 5 if (debug && window.console) { 6 console.log('[CarouselWidget] - ' + message); 7 } 8 }; 9 10 var constants = 11 { 12 Fade: 'fade', 13 Slide: 'slide', 14 Automatic: 'automatically', 15 Manual: 'manual' 16 } 17 18 // Defaults 19 var defaults = { 20 transition: constants.Fade, //[fade or slide] 21 transitionTiming: 1, 22 groupAdvance: constants.Automatic, //[automatically or manual] 23 groupTiming: 5, 24 showArrows: true, 25 showPaging: true, 26 showDots: true, 27 sliderSelector: 'div.widgetCarousel-slider', 28 groupSelector: 'div.widgetCarousel-group', 29 itemsSelector: 'div.widgetCarousel-item', 30 forceHeight: false 31 }; 32 33 var pageMarkup = '<li><a href="#slide" onclick="return false;" class="pagingItems" data-index="{0}">{0}</a></li>'; 34 var separatorMarkup = '<li><span>...</span></li>'; 35 var maxPageNumbers = 10; 36 37 //Constructor 38 window.CarouselWidget = function (options, element) { 39 var self = this; 40 41 //private vars/methods 42 self.element = element; 43 self.$carousel = $(self.element); 44 self.$prev = self.$carousel.find('.arrow.prev'); 45 self.$next = self.$carousel.find('.arrow.next'); 46 self.$pager = self.$carousel.find('.semanticList.pager'); 47 self.$arrowSpans = self.$next.children('svg').add(self.$prev.children('svg')); 48 self.autoTransition = null; 49 50 self.initPaging = function () { 51 var appendPage = function (number) { 52 var $li = $(pageMarkup.replace(/\{0\}/g, number)); 53 $li.children('a').unbind('click').click(function (e) { 54 e.preventDefault(); 55 if (!$(this).parent().hasClass('disabled')) { 56 self.stopTransition(); 57 self.show($(this).data('index')); 58 } 59 }); 60 self.$pager.append($li); 61 }; 62 var appendSeparator = function () { 63 var $li = $(separatorMarkup); 64 self.$pager.append($li); 65 }; 66 var appendRange = function (start, end) { 67 for (var number = start; number <= end; number++) { 68 appendPage(number); 69 } 70 }; 71 72 self.$pager.empty(); 73 if (self.settings.showDots || self.$slides.length <= maxPageNumbers) { 74 for (var i = 0; i < self.$slides.length; i++) { 75 appendPage(i + 1); 76 } 77 diag('Paging initialized with ' + (self.settings.showDots ? 'dots' : 'numbers')); 78 } else { 79 if (self.currentSlide <= 3) { 80 appendRange(1, 4); 81 appendSeparator(); 82 appendPage(self.$slides.length); 83 } else if (self.$slides.length - self.currentSlide < 3) { 84 appendPage(1); 85 appendSeparator(); 86 appendRange(self.$slides.length - 3, self.$slides.length); 87 } else { 88 appendPage(1); 89 appendSeparator(); 90 appendRange(self.currentSlide - 1, self.currentSlide + 1); 91 appendSeparator(); 92 appendPage(self.$slides.length); 93 } 94 diag('Paging initialized with optimized numbers'); 95 } 96 self.$pager.show(); 97 }; 98 99 self.updatePaging = function () { 100 if (self.$pager.is(':visible')) { 101 if (!self.settings.showDots && self.$slides.length > maxPageNumbers) { 102 self.initPaging(); 103 } 104 self.$pager.find('.active').removeClass('active'); 105 self.$pager.find('[data-index=' + self.currentSlide + '].pagingItems').parent().addClass('active'); 106 } 107 self.updateArrowsHeight(); 108 }; 109 110 self.updateGraphicLinksWidgetClasses = function () { 111 var liveEditEnabled = getCookieValue("enableLiveEdit") === "true"; 112 if (liveEditEnabled) { 113 return; 114 } 115 116 var isCarouselWide = self.$carousel.hasClass('wide'); 117 var addClass = isCarouselWide ? 'wide' : 'narrow'; 118 var removeClass = isCarouselWide ? 'narrow' : 'wide'; 119 120 var $graphicLinksWidgets = self.$carousel.find('.widget.widgetGraphicLinks'); 121 122 $graphicLinksWidgets.each(function () { 123 var $widget = $(this); 124 125 if ($widget.closest('.widgetCarousel')[0] !== self.$carousel[0]) { 126 return; 127 } 128 129 $widget.addClass(addClass).removeClass(removeClass); 130 131 $widget.find('.widgetGraphicLinksNav .row').addClass(addClass).removeClass(removeClass); 132 }); 133 }; 134 135 self.updateArrowsHeight = function () { 136 if (self.settings.showArrows) { 137 var slide = self.currentSlide > self.$slides.length 138 ? 1
139 : (self.currentSlide < 1 140 ? self.$slides.length 141 : self.currentSlide); 142 var top = $(self.$slides[slide - 1]).height() / 2; 143 if (top < 15) top = 15; 144 var centerCss = 'translateY(' + top + 'px)'; 145 self.$arrowSpans.css({ 146 '-webkit-transform': centerCss, 147 '-ms-transform': centerCss, 148 '-o-transform': centerCss, 149 'transform': centerCss 150 }); 151 } 152 }; 153 154 self.initArrows = function () { 155 self.$prev.unbind('click').click(function (e) { 156 e.preventDefault(); 157 if (!$(this).hasClass('disabled')) { 158 self.$prev.addClass('disabled'); 159 if (!self.$next.hasClass('disabled')) { 160 self.$next.addClass('disabled'); 161 setTimeout(function() { 162 self.$next.removeClass('disabled'); 163 }, self.settings.transitionTiming * 1000); 164 } 165 self.stopTransition(); 166 self.movePrev(); 167 if (document.activeElement !== document.body) document.activeElement.blur(); 168 setTimeout(function() { 169 self.$prev.removeClass('disabled'); 170 }, self.settings.transitionTiming * 1000); 171 } 172 }); 173 self.$next.unbind('click').click(function (e) { 174 e.preventDefault(); 175 if (!$(this).hasClass('disabled')) { 176 self.stopTransition(); 177 self.moveNext(); 178 if (document.activeElement !== document.body) document.activeElement.blur(); 179 } 180 }); 181 //Disabled arrows only if there is one slide. Otherwise, carousel is always circular 182 self.$prev.show()[(self.$slides.length <= 1) ? 'addClass' : 'removeClass']("disabled"); 183 self.$next.show()[(self.$slides.length <= 1) ? 'addClass' : 'removeClass']("disabled"); 184 }; 185 186 self.startTransition = function () { 187 self.stopTransition(); 188 var loopTransition = function (force) { 189 force = force || false; 190 if (force || self.autoTransition != null) { 191 self.autoTransition = window.setTimeout(function () { 192 self.moveNext(loopTransition); 193 }, self.settings.groupTiming * 1000); 194 } 195 }; 196 loopTransition(true); 197 }; 198 199 self.stopTransition = function () { 200 if (self.autoTransition != null) { 201 window.clearTimeout(self.autoTransition); 202 self.autoTransition = null; 203 } 204 }; 205 206 self.setupTransition = function () { 207 var i, 208 m = self.$groups.length, 209 n = self.$items.length; 210 if (!self.slideByItems) { 211 //by groups => wide view 212 diag('Setup transition by groups. m=' + m + ', effect=' + self.settings.transition); 213 if (self.settings.transition === constants.Slide) { 214 self.$slider.css('left', '0'); 215 self.$slider.css("margin-left", "100%").css("margin-right", "100%"); 216 217 //adjust internally new groups 218 self.$groups = self.$carousel.find(self.settings.groupSelector); 219 m = self.$groups.length; 220 221 if (m > 1) { 222 self.$slider.css("transition", "left " + self.settings.transitionTiming + "s ease"); 223 } 224 225 } else { 226 for (i = 0; i < m; i++) { 227 $(self.$groups[i]).css('left', (i * 100 * -1 / m) + '%').css('z-index', 1); 228 } 229 } 230 self.$slider.css('width', (m * 100) + '%'); 231 self.$groups.css('width', (100 * 1 / m) + '%'); 232 } else { 233 //by items => narrow view 234 diag('Setup transition by items. m=' + m + ', n=' + n + ', effect=' + self.settings.transition); 235 var $groupItems; 236 var j; 237 if (self.settings.transition === constants.Slide) { 238 self.$slider.css('left', '0'); 239 self.$items.css('opacity', 1); 240 self.$slider.css("margin-left", "100%").css("margin-right", "100%"); 241 242 //adjust internally new groups and items 243 self.$groups = self.$carousel.find(self.settings.groupSelector); 244 self.$items = self.$carousel.find(self.settings.itemsSelector); 245 m = self.$groups.length; 246 n = self.$items.length; 247 248 if (n > 1) { 249 self.$slider.css("transition", "left " + self.settings.transitionTiming + "s ease"); 250 } 251 252 for (i = 0; i < m; i++) { 253 $groupItems = $(self.$groups[i]).find(self.settings.itemsSelector); 254 $(self.$groups[i]) 255 .css('width', (100 * $groupItems.length / n) + '%'); 256 for (j = 0; j < $groupItems.length; j++) { 257 $($groupItems[j]).css('width', (1 / $groupItems.length) * 100 + '%'); 258 } 259 } 260 } else { 261 for (i = 0; i < m; i++) { 262 var itemsLeft = 0; 263 $groupItems = $(self.$groups[i]).find(self.settings.itemsSelector); 264 if (i > 0) { 265 for (j = 0; j < i; j++) { 266 itemsLeft += $(self.$groups[j]).find(self.settings.itemsSelector).length; 267 } 268 } 269 $(self.$groups[i]) 270 .css('width', (100 * $groupItems.length / n) + '%') 271 .css('left', (-100 * itemsLeft / n) + '%').css('z-index', 1); 272 for (j = 0; j < $groupItems.length; j++) { 273 $($groupItems[j]).css('width', (1 / $groupItems.length) * 100 + '%') 274 .css('left', -j / $groupItems.length * 100 + '%'); 275 } 276 } 277 } 278 279 self.$slider.css('width', (n * 100) + '%'); 280 } 281 }; 282 283 self.init(options); 284 285 //Adding global onresize handlers 286 var onResize = function () { 287 self.onResize(); 288 }; 289 290 window.Pages.onResizeHandlers = window.Pages.onResizeHandlers || []; 291 window.Pages.onResizeHandlers.push(onResize); 292 }; 293 294 //public methods 295 window.CarouselWidget.prototype = { 296 init: function (options) { 297 var self = this; 298 299 self.settings = $.extend({}, defaults, options); 300 self.$slider = self.$carousel.find(self.settings.sliderSelector); 301 self.$groups = self.$carousel.find(self.settings.groupSelector); 302 self.$items = self.$carousel.find(self.settings.itemsSelector); 303 self.slideByItems = self.settings.itemsSelector != null && self.settings.itemsSelector.length > 0;
304 self.$slides = self.slideByItems ? self.$items : self.$groups; 305 self.currentSlide = 1; 306 307 diag('Initing carouselId: ' + self.$carousel.attr('id')); 308 diag('# of slides: ' + self.$slides.length); 309 310 //Display and init arrows/paging if needed 311 self.$pager.hide(); 312 self.$prev.hide(); 313 self.$next.hide(); 314 self.settings.showPaging && self.initPaging(); 315 self.settings.showArrows && self.initArrows(); 316 317 // Find play and pause buttons and attach event handlers 318 self.$pause = self.$carousel.find('.pause-btn'); 319 self.$play = self.$carousel.find('.play-btn'); 320 321 // Initially display pause button and hide play button 322 if (self.$play.length>0) 323 self.$play.hide(); 324 325 if (self.$pause.length > 0) { 326 self.$pause.click(function () { 327 self.stopTransition(); 328 $(this).hide(); 329 self.$play.show(); 330 }); 331 } 332 333 if (self.$play.length > 0) { 334 self.$play.click(function () { 335 self.startTransition(); 336 $(this).hide(); 337 self.$pause.show(); 338 }); 339 } 340 341 self.setupTransition(); 342 343 //Adjust height and show only first slide. 344 self.adjustHeight(); 345 self.show(1); 346 self.updateGraphicLinksWidgetClasses(); 347 348 // Set the z-index so group 1 is front 349 if (self.slideByItems && self.settings.transition === constants.Fade) { 350 $(self.$slides[0]).parent().css('z-index', 2); 351 $(self.$slides[0]).parent().siblings().css('z-index', 1); 352 } 353 354 if (self.settings.groupAdvance === constants.Automatic && self.$slides.length > 1) 355 self.startTransition(); 356 }, 357 show: function (slide, callback) { 358 var self = this; 359 if (slide >= 1 && slide <= self.$slides.length) { 360 diag('Moving to slide #: ' + slide); 361 var originalSlide = self.currentSlide; 362 self.currentSlide = slide; 363 //Hide previous and display new one using transitions 364 switch (self.settings.transition) { 365 case constants.Fade: 366 if (originalSlide === self.currentSlide) { 367 //Hide all and display slide no effect. 368 self.$slides.css('opacity', 0).css('z-index', 1); 369 $(self.$slides[self.currentSlide - 1]).css('opacity', 1).css('z-index', 2); 370 } else { 371 // If slide by items, use to change the z-index of groups 372 if (self.slideByItems) { 373 $(self.$slides[self.currentSlide - 1]).parent().css('z-index',2); 374 $(self.$slides[self.currentSlide - 1]).parent().siblings().css('z-index', 1); 375 } 376 //Fade effect 377 $(self.$slides[originalSlide - 1]).animate({ opacity: 0 }, self.settings.transitionTiming * 1000, function () { 378 $(this).css('z-index', 1); 379 });
380 $(self.$slides[self.currentSlide - 1]).animate({ opacity: 1 }, self.settings.transitionTiming * 1000, function () { 381 $(this).css('z-index', 2); 382 if (typeof callback === 'function') { 383 callback(); 384 } 385 }); 386 } 387 break; 388 case constants.Slide: 389 if (originalSlide === self.currentSlide) { 390 //display slide no effect. 391 $(self.$slider.css('left', ((self.currentSlide) * -100) + '%')); 392 } else { 393 //slide effect 394 self.$slider.css("left", ((self.currentSlide) * -100) + '%'); 395 setTimeout(function() { 396 if (typeof callback === 'function') { 397 callback(); 398 } 399 }, self.settings.transitionTiming * 1000); 400 } 401 break; 402 } 403 //https://civicplus.tpondemand.com/entity/55058-pages-carousel-widget-does-not-show 404 window.setTimeout(function () { 405 self.updatePaging(); 406 }, 500); 407 } else { 408 diag('Cannot move to slide #: ' + slide); 409 } 410 }, 411 moveNext: function (callback) { 412 var self = this; 413 if (!self.$next.hasClass('disabled')) { 414 self.$next.addClass('disabled'); 415 setTimeout(function() { 416 self.$next.removeClass('disabled'); 417 }, self.settings.transitionTiming * 1000 + 50); 418 } 419 if (!self.$prev.hasClass('disabled')) { 420 self.$prev.addClass('disabled'); 421 setTimeout(function() { 422 self.$prev.removeClass('disabled'); 423 }, self.settings.transitionTiming * 1000 + 50); 424 } 425 var next = self.currentSlide === self.$slides.length ? 1 : self.currentSlide + 1; 426 if (next === 1 && self.settings.transition === constants.Slide) { 427 //Slide from Last to First 428 self.currentSlide = next; 429 var leftOffset = ((self.$slides.length + 1) * -100); //Last to phantom Last and then to actual First slide 430 self.$slider.css("left", leftOffset + '%'); 431 self.$slides.first().css("transform","translateX(" + self.$slides.length * 100 + "%)"); 432 setTimeout(function() { 433 self.$slider.css("transition", "none"); 434 self.$slider.css('left', ((self.currentSlide) * -100) + '%'); 435 setTimeout(function() { self.$slider.css("transition", "left " + self.settings.transitionTiming + "s ease"); }, 50); 436 self.$slides.first().css("transform","none"); 437 if (typeof callback === 'function') { 438 callback(); 439 } 440 }, self.settings.transitionTiming * 1000); 441 self.updatePaging(); 442 } else 443 self.show(next, callback); 444 }, 445 movePrev: function () { 446 var self = this; 447 if (!self.$next.hasClass('disabled')) { 448 self.$next.addClass('disabled'); 449 setTimeout(function() { 450 self.$next.removeClass('disabled'); 451 }, self.settings.transitionTiming * 1000 + 50); 452 } 453 if (!self.$prev.hasClass('disabled')) { 454 self.$prev.addClass('disabled'); 455 setTimeout(function() { 456 self.$prev.removeClass('disabled'); 457 }, self.settings.transitionTiming * 1000 + 50); 458 } 459 var prev = self.currentSlide === 1 ? self.$slides.length : self.currentSlide - 1; 460 if (prev === self.$slides.length && self.settings.transition === constants.Slide) { 461 //Slide from First to Last 462 self.currentSlide = prev; 463 var leftOffset = 0; //First to phantom First and then to actual Last slide 464 self.$slider.css("left", leftOffset + '%'); 465 self.$slides.last().css("transform","translateX(-" + self.$slides.length * 100 + "%)"); 466 setTimeout(function() { 467 self.$slider.css("transition", "none"); 468 self.$slider.css('left', ((self.currentSlide) * -100) + '%'); 469 setTimeout(function() { self.$slider.css("transition", "left " + self.settings.transitionTiming + "s ease"); }, 50); 470 self.$slides.last().css("transform","none"); 471 if (typeof callback === 'function') { 472 callback(); 473 } 474 }, self.settings.transitionTiming * 1000); 475 self.updatePaging(); 476 } else 477 self.show(prev); 478 }, 479 480 onResize: function () { 481 var self = this; 482 self.adjustHeight(); 483 self.updateGraphicLinksWidgetClasses(); 484 }, 485 adjustHeight: function () { 486 var self = this; 487 if (self.settings.forceHeight) { 488 var maxHeight = 0; 489 for (var i = 0; i < self.$slides.length; i++) { 490 var slideHeight = $(self.$slides[i]).outerHeight(true); 491 if (slideHeight > maxHeight) 492 maxHeight = slideHeight; 493 } 494 if (self.settings.showPaging) 495 maxHeight += self.$pager.outerHeight(true); 496 self.$carousel.css('height', maxHeight + 'px'); 497 diag('height adjusted to ' + maxHeight + 'px'); 498 } 499 }, 500 destroy: function () { 501 var self = this; 502 self.$pager.empty().hide(); 503 self.$prev.unbind('click').hide(); 504 self.$next.unbind('click').hide(); 505 self.stopTransition(); 506 self.$carousel.css('height', ''); 507 self.$slider.css('width', '').css('left', ''); 508 self.$groups.css('width', '').css('left', '').css('z-index', '').css('opacity', ''); 509 self.$items.css('width', '').css('left', '').css('z-index', '').css('opacity', ''); 510 } 511 } 512 513 /* jQuery Plugin Support */ 514 $.fn.carouselWidget = function (options) { 515 if (typeof options === 'string') { 516 var args = Array.prototype.slice.call(arguments, 1); 517 this.each(function () { 518 var instance = $.data(this, 'carouselWidget'); 519 if (!instance) { 520 diag("cannot call methods on carouselWidget prior to initialization; " + 521 "attempted to call method '" + options + "'"); 522 return; 523 } 524 if (!$.isFunction(instance[options]) || options.charAt(0) === "_") { 525 diag("no such method '" + options + "' for carouselWidget instance"); 526 return; 527 } 528 instance[options].apply(instance, args); 529 }); 530 } 531 else { 532 this.each(function () { 533 var instance = $.data(this, 'carouselWidget'); 534 if (instance) { 535 instance.init(options); 536 } 537 else { 538 $.data(this, 'carouselWidget', new window.CarouselWidget(options, this)); 539 } 540 }); 541 } 542 543 return this; 544 }; 545 546})(jQuery, window);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.