1((document, Joomla) => { 2 "use strict"; 3 4 class Mslider { 5 /* 6 * Constructor 7 */ 8 constructor(options, id, count, source, path, itemid) { 9 this.options = options; 10 this.widgetId = parseInt(id, 10); 11 this.totalCount = parseInt(count, 10); 12 this.sourceId = source; 13 this.path = path; 14 this.itemid = itemid; 15 16 this.navigatorEnabled = parseInt(this.options.slider_navigator, 10); 17 this.parallax = parseInt(this.options.slider_parallax, 10); 18 this.mediaSlider = 19 this.options.slider_theme == "media_slider" ? true : false; 20 this.hoverbox = parseInt(this.options.slider_hb, 10); 21 this.loadMore = parseInt(this.options.slider_load_more, 10); 22 this.container = document.querySelector( 23 "#mslider_" + this.widgetId 24 ); 25 this.ignoreVideos = true; 26 this.videoSource = 27 typeof this.options.videoSource === "undefined" 28 ? false 29 : parseInt(this.options.videoSource, 10); 30 31 if (this.container == null) return; 32 33 // Initialize slider 34 this.initializeSlider(); 35 36 // Load more items 37 if (this.loadMore) { 38 this.paginationDelay = 150; 39 this.appendItems(); 40 } 41 42 // Navigator 43 if (this.navigatorEnabled) this.initializeNavigator(); 44 45 // Progress bar 46 if (parseInt(this.options.slider_progressbar, 10)) 47 this.initializeProgressBar(); 48 49 // Parallax 50 if (this.parallax) this.triggerParallax(); 51 52 // Media slider 53 if (this.mediaSlider) this.initializeMediaSlider(); 54 55 // Modal images 56 if (this.hoverbox) { 57 if (parseInt(this.options.slider_hb_zoom, 10)) 58 this.initModalMessages(); 59 } 60 61 // Check if we are inside an iframe 62 this.isIframe = window.frameElement ? true : false; 63 64 if (this.isIframe) { 65 if (document.querySelector(".mslider-description")) 66 document.querySelector( 67 ".mslider-description" 68 ).style.padding = "20px"; 69 } 70 } 71 72 initializeSlider() { 73 const self = this; 74 this.nav_container = document.querySelector( 75 "#mslider_nav_" + this.widgetId 76 ); 77 78 this.draggable = parseInt(this.options.slider_drag, 10) 79 ? ">1" 80 : false; 81 this.freeScroll = parseInt(this.options.slider_free_scroll, 10) 82 ? true 83 : false; 84 var wrapAround = 85 parseInt(this.options.slider_rewind, 10) && !this.loadMore 86 ? true 87 : false; 88 this.groupCells = parseInt(this.options.slider_group_items, 10) 89 ? true 90 : false; 91 var autoplaySpeed = parseInt( 92 this.options.slider_autoplay_speed, 93 10 94 ); 95 var autoPlay = parseInt(this.options.slider_autoplay, 10) 96 ? autoplaySpeed 97 : false; 98 var pauseAutoPlayOnHover = parseInt( 99 this.options.slider_pause_on_hover, 100 10 101 ) 102 ? true 103 : false; 104 var fullscreen = parseInt(this.options.slider_fullscreen, 10) 105 ? true 106 : false; 107 var fade = parseInt(this.options.slider_fade, 10) ? true : false; 108 var adaptiveHeight = parseInt( 109 this.options.slider_adaptive_height, 110 10 111 ) 112 ? true 113 : false; 114 var hash = parseInt(this.options.slider_hash, 10) ? true : false; 115 this.dragThreshold = parseInt( 116 this.options.slider_drag_threshold, 117 10 118 ) 119 ? parseInt(this.options.slider_drag_threshold, 10) 120 : 3; 121 this.selectedAttraction = parseFloat( 122 this.options.slider_selected_attraction 123 ) 124 ? parseFloat(this.options.slider_selected_attraction) 125 : 0.025; 126 this.friction = parseFloat(this.options.slider_friction) 127 ? parseFloat(this.options.slider_friction) 128 : 0.28; 129 this.freeScrollFriction = parseFloat( 130 this.options.slider_free_scroll_friction 131 ) 132 ? parseFloat(this.options.slider_free_scroll_friction) 133 : 0.075; 134 var lazyLoad = parseInt(this.options.slider_lazyload, 10) 135 ? true 136 : false;
137 var initialIndex = parseInt(this.options.slider_initial_index, 10) 138 ? parseInt(this.options.slider_initial_index, 10) - 1 139 : 0; 140 var cellAlign = this.options.slider_cell_align; 141 var contain = parseInt(this.options.slider_contain, 10) 142 ? true 143 : false; 144 this.rightToLeft = parseInt(this.options.slider_rtl, 10) 145 ? true 146 : false; 147 var prevNextButtons = parseInt(this.options.slider_arrows, 10) 148 ? true 149 : false; 150 var pageDots = parseInt(this.options.slider_bullets, 10) 151 ? true 152 : false; 153 154 // Show slider 155 this.container.style.display = "block"; 156 157 // Initialize Flickity 158 let update_slider = function () { 159 self.slider = new Flickity(self.container, { 160 draggable: self.draggable, 161 freeScroll: self.freeScroll, 162 wrapAround: wrapAround, 163 groupCells: self.groupCells, 164 autoPlay: autoPlay, 165 pauseAutoPlayOnHover: pauseAutoPlayOnHover, 166 fullscreen: fullscreen, 167 fade: fade, 168 adaptiveHeight: adaptiveHeight, 169 hash: hash, 170 initialIndex: !hash ? initialIndex : undefined, 171 dragThreshold: self.dragThreshold, 172 selectedAttraction: self.selectedAttraction, 173 friction: self.friction, 174 freeScrollFriction: self.freeScrollFriction, 175 imagesLoaded: true, 176 lazyLoad: lazyLoad, 177 cellSelector: ".mslider-item", 178 accessibility: true, 179 setGallerySize: true, 180 resize: true, 181 cellAlign: cellAlign, 182 contain: contain, 183 rightToLeft: self.rightToLeft, 184 percentPosition: true, 185 prevNextButtons: prevNextButtons, 186 pageDots: pageDots, 187 on: { 188 ready: function () { 189 document 190 .querySelector( 191 "#mslider_wrapper_" + self.widgetId 192 ) 193 .classList.add("flickity-ready"); 194 self.fixHeights(false); 195 }, 196 fullscreenChange: function (isFullscreen) { 197 if (self.navigatorEnabled) self.navigator.resize(); 198 199 if (isFullscreen) self.fixHeights(true); 200 else self.fixHeights(false); 201 202 self.slider.resize(); 203 }, 204 }, 205 }); 206 }; 207 208 if (self.videoSource) self.videosReady(update_slider); 209 210 if (self.ignoreVideos) update_slider(); 211 } 212 213 videosReady(callback) { 214 const self = this; 215 self.ignoreVideos = true; 216 const _videos = self.container.querySelectorAll("video"); 217 218 if (_videos.length) { 219 let videos = []; 220 221 _videos.forEach((a) => { 222 if (a.readyState == 0) videos.push(a); 223 }); 224 225 if (videos.length) { 226 self.ignoreVideos = false; 227 let states = []; 228 229 for (let i = 0; i < videos.length; i++) { 230 states.push(0); 231 } 232 233 let promise = new Promise(function (resolve) { 234 Object.keys(videos).forEach((key) => { 235 videos[key].addEventListener("loadeddata", () => { 236 states[key] = videos[key].readyState; 237 238 // If all videos ready (readyState >=3), resolve promise 239 if (states.every((v) => v >= 3)) 240 resolve(states); 241 }); 242 }); 243 }); 244 245 promise.then(function (value) { 246 callback(); 247 }); 248 } 249 } 250 } 251 252 appendItems() { 253 const self = this; 254 var ajax_request, nav_ajax_request; 255 var cells_loaded = self.slider.cells.length; 256 var new_cells_loaded, nav_cells_loaded; 257 var items_left = self.totalCount - cells_loaded; 258 var arrowsColor = self.options.slider_arrows_color; 259 var page = 2; 260 var new_page; 261 var next_button = self.container.querySelector( 262 ".flickity-button.next" 263 ); 264 265 if (items_left > 0 && next_button) { 266 var next_clone = self.container 267 .querySelector(".flickity-button.next") 268 .cloneNode(true); 269 next_clone.classList.add("cloned"); 270 self.insertAfter(next_clone, next_button); 271 next_clone.classList.add("disabled"); 272 next_clone.style.display = "none"; 273 next_clone.setAttribute("data-page", "2"); 274 next_clone.appendChild( 275 self.htmlToElement('<div class="mslider-loader"></div>') 276 ); 277 self.createSpinner(".mslider-loader", arrowsColor); 278 279 // Corner case: 1st page has 0 or 1 slides 280 if ( 281 self.slider.slides.length == 0 || 282 self.slider.slides.length == 1 283 ) { 284 self.container 285 .querySelectorAll(".flickity-button.next") 286 .forEach(function (a) { 287 a.style.display = "none"; 288 }); 289 290 next_clone.classList.remove("disabled"); 291 next_clone.removeAttribute("disabled"); 292 next_clone.style.display = "block"; 293 } 294
295 // Calculate visibility of cloned next button 296 self.slider.on("change", function (index) { 297 if (self.groupCells) 298 cells_loaded = self.slider.slides.length; 299 else cells_loaded = self.slider.cells.length; 300 301 items_left = self.totalCount - self.slider.cells.length; 302 303 if (items_left > 0) { 304 if (index == cells_loaded - 1) { 305 self.container 306 .querySelectorAll(".flickity-button.next") 307 .forEach(function (a) { 308 a.style.display = "none"; 309 }); 310 311 next_clone.classList.remove("disabled"); 312 next_clone.style.display = "block"; 313 } else { 314 self.container 315 .querySelectorAll(".flickity-button.next") 316 .forEach(function (a) { 317 a.style.display = "block"; 318 }); 319 320 next_clone.classList.add("disabled"); 321 next_clone.style.display = "none"; 322 } 323 } else { 324 self.container 325 .querySelectorAll(".flickity-button.next") 326 .forEach(function (a) { 327 a.style.display = "block"; 328 }); 329 330 next_clone.remove(); 331 } 332 }); 333 334 // Load more items 335 next_clone.addEventListener("click", function (e) { 336 e.preventDefault(); 337 338 if (this.classList.contains("disabled")) return false; 339 340 // Check if there is a pending ajax request 341 if (typeof ajax_request !== "undefined") 342 ajax_request.abort(); 343 344 if (self.groupCells) { 345 new_cells_loaded = self.slider.slides.length; 346 nav_cells_loaded = self.slider.cells.length; 347 } else { 348 new_cells_loaded = self.slider.cells.length; 349 nav_cells_loaded = self.slider.cells.length; 350 } 351 352 page = next_clone.getAttribute("data-page"); 353 page = parseInt(page, 10); 354 new_page = page + 1; 355 356 // Increment data-page 357 next_clone.setAttribute("data-page", new_page); 358 359 // Show loader 360 next_clone.classList.add("disabled"); 361 next_clone.querySelector("svg").style.display = "none"; 362 this.querySelector(".mslider-loader").style.display = 363 "block"; 364 self.container.classList.add("is-loading"); 365 366 // Ajax 367 ajax_request = Joomla.request({ 368 url: 369 self.path + 370 "index.php?option=com_minitekslider&task=slider.getContent&widget_id=" + 371 self.widgetId + 372 "&page=" + 373 page + 374 "&type=slider" + 375 "&Itemid=" + 376 self.itemid, 377 method: "GET", 378 onSuccess: (response, xhr) => { 379 if (response.length > 3) { 380 var items_array = response.split( 381 '<div class="mslider-media-db">' 382 ); 383 var dbs = items_array[1]; 384 385 if (self.mediaSlider) { 386 // Update detail box in media slider 387 var dbItems = self.htmlToElements( 388 dbs,
389 ".mslider-detail-box" 390 ); 391 392 dbItems.forEach(function (a) { 393 self.container 394 .querySelector(".mslider-media-db") 395 .appendChild(a); 396 }); 397 398 self.container 399 .querySelectorAll( 400 ".mslider-media-db .mslider-detail-box" 401 ) 402 .forEach(function (element, index) { 403 element.setAttribute( 404 "data-selectedindex", 405 index 406 ); 407 }); 408 } 409 410 // Load items 411 var sliderItems = self.htmlToElements( 412 response, 413 ".mslider-item" 414 ); 415 self.slider.append(sliderItems); 416 417 // Fix heights 418 if ( 419 self.container.classList.contains( 420 "is-fullscreen" 421 ) 422 ) { 423 if (!self.mediaSlider) 424 self.fixHeights(true); 425 } else self.fixHeights(false); 426 427 // Initialize parallax 428 if (self.parallax) self.triggerParallax(); 429 430 // Fade in items 431 self.slider.once("select", function () { 432 self.container 433 .querySelectorAll(".mslider-item") 434 .forEach(function (a) { 435 a.classList.remove( 436 "mslider-item-hidden" 437 ); 438 }); 439 440 self.slider.resize(); 441 }); 442 443 // Update Navigator 444 if (self.navigatorEnabled) { 445 nav_ajax_request = Joomla.request({ 446 url: 447 self.path + 448 "index.php?option=com_minitekslider&task=slider.getContent&widget_id=" + 449 self.widgetId + 450 "&page=" + 451 page + 452 "&type=navigator" + 453 "&Itemid=" + 454 self.itemid, 455 method: "GET", 456 onSuccess: (response, xhr) => { 457 if (response.length > 3) { 458 // Load items 459 var navItems = 460 self.htmlToElements( 461 response, 462 ".mslider-nav-item" 463 ); 464 self.navigator.append(navItems); 465 self.slider.select( 466 new_cells_loaded 467 ); 468 469 self.nav_container 470 .querySelectorAll( 471 ".mslider-nav-item" 472 ) 473 .forEach(function (a) { 474 a.classList.remove( 475 "mslider-item-hidden" 476 ); 477 }); 478 479 self.container.classList.remove( 480 "is-loading" 481 ); 482 } 483 }, 484 onError: (xhr) => { 485 console.log(xhr); 486 }, 487 }); 488 } else { 489 if (page <= 2) { 490 // Make sure selection is delayed, otherwise the items heights are not calculated correctly on 2nd page 491 setTimeout(function () { 492 self.slider.select( 493 new_cells_loaded 494 ); 495 self.container.classList.remove( 496 "is-loading" 497 ); 498 }, self.paginationDelay); 499 } else { 500 self.slider.select(new_cells_loaded); 501 self.container.classList.remove( 502 "is-loading" 503 ); 504 } 505 } 506 507 // Hide loader 508 next_clone.querySelector("svg").style.display = 509 "block"; 510 next_clone.querySelector( 511 ".mslider-loader" 512 ).style.display = "none"; 513 } else { 514 self.container 515 .querySelectorAll(".flickity-button.next") 516 .forEach(function (a) { 517 a.style.display = "block"; 518 }); 519 520 next_clone.remove(); 521 self.container.classList.remove("is-loading"); 522 } 523 }, 524 onError: (xhr) => { 525 console.log(xhr); 526 }, 527 }); 528 }); 529 } 530 } 531 532 initializeNavigator() { 533 const self = this; 534 var prevNextButtons = parseInt( 535 this.options.slider_navigator_arrows, 536 10 537 ); 538 539 // Show navigator 540 self.nav_container.style.display = "block"; 541 542 // Initialize navigator 543 self.navigator = new Flickity(self.nav_container, { 544 draggable: self.draggable, 545 freeScroll: self.freeScroll, 546 groupCells: false, 547 asNavFor: "#mslider_" + self.widgetId, 548 dragThreshold: self.dragThreshold, 549 selectedAttraction: self.selectedAttraction, 550 friction: self.friction, 551 freeScrollFriction: self.freeScrollFriction, 552 imagesLoaded: true, 553 lazyLoad: false, 554 cellSelector: ".mslider-nav-item", 555 accessibility: true, 556 setGallerySize: true, 557 resize: true, 558 contain: true, 559 rightToLeft: self.rightToLeft, 560 percentPosition: true, 561 prevNextButtons: prevNextButtons, 562 pageDots: false, 563 }); 564 } 565 566 fixHeights(fullscreen, index = false) { 567 var sliderPaddingTop = parseInt( 568 this.options.slider_cont_padding, 569 10 570 ); 571 var sliderPaddingBottom = sliderPaddingTop; 572 var sliderMarginBottom = 30; 573 var mediaDbPaddingTop = 40; 574 var maxMediaDb = 350; 575 var navBottom = 10; 576 var bullets = this.container.querySelector(".flickity-page-dots"); 577 var progressbar = document.querySelector( 578 "#mslider_progressbar_" + this.widgetId 579 ); 580 581 if (fullscreen) { 582 // Fix slider height 583 var height = 584 document.querySelector("#mslider_wrapper_" + this.widgetId) 585 .offsetHeight - sliderPaddingTop; 586 var slider_height = 0; 587 var media_db_height = 0; 588 var navigator_height = 0; 589 var viewport_height; 590 591 if (this.mediaSlider) { 592 if (index !== false) { 593 var detail_boxes = this.container.querySelectorAll(
594 ".mslider-media-db .mslider-detail-box" 595 ); 596 597 if (detail_boxes) 598 media_db_height = 599 detail_boxes[index].offsetHeight + 600 mediaDbPaddingTop; 601 } else { 602 if (this.container.querySelector(".mslider-media-db")) 603 media_db_height = 604 this.container.querySelector( 605 ".mslider-media-db" 606 ).offsetHeight + mediaDbPaddingTop; 607 } 608 609 media_db_height = 610 media_db_height > maxMediaDb 611 ? maxMediaDb 612 : media_db_height; 613 } 614 615 if (this.nav_container) { 616 navigator_height = 617 this.nav_container.offsetHeight + navBottom; 618 619 if (bullets) sliderMarginBottom = 2 * sliderMarginBottom; 620 } else { 621 if (!bullets && !progressbar) 622 height = height - sliderPaddingBottom; 623 else { 624 if (bullets && !progressbar) 625 sliderMarginBottom = 2 * sliderMarginBottom; 626 else if (!bullets && progressbar) 627 sliderMarginBottom = 10; 628 else if (bullets && progressbar) 629 sliderMarginBottom = 2 * sliderMarginBottom; 630 } 631 } 632 633 // Update calculations 634 sliderMarginBottom = 635 bullets || progressbar || this.nav_container 636 ? sliderMarginBottom 637 : 0; 638 639 // Container 640 slider_height = height - sliderMarginBottom - navigator_height; 641 this.container.style.height = slider_height + "px"; 642 643 // Viewport 644 viewport_height = slider_height - media_db_height; 645 this.container.querySelector( 646 ".flickity-viewport" 647 ).style.maxHeight = viewport_height + "px"; 648 649 // Images 650 if ( 651 this.container.querySelectorAll(".mslider-photo-link img") 652 ) { 653 var max_height = 654 this.container.querySelector( 655 ".flickity-viewport" 656 ).offsetHeight; 657 658 this.container 659 .querySelectorAll(".mslider-photo-link img") 660 .forEach(function (a) { 661 a.style.maxHeight = max_height + "px"; 662 }); 663 } 664 } else { 665 // Main 666 this.container.style.height = "auto"; 667 668 // Viewport 669 this.container.querySelector( 670 ".flickity-viewport" 671 ).style.maxHeight = "inherit"; 672 673 // Images 674 if ( 675 this.container.querySelectorAll(".mslider-photo-link img") 676 ) { 677 this.container 678 .querySelectorAll(".mslider-photo-link img") 679 .forEach(function (a) { 680 a.style.maxHeight = "inherit"; 681 }); 682 } 683 } 684 } 685 686 initializeProgressBar() { 687 var progressBar = document.querySelector( 688 "#mslider_progressbar_" + this.widgetId 689 ); 690 691 this.slider.on("scroll", function (progress) { 692 progress = Math.max(0, Math.min(1, progress)); 693 progressBar.style.width = progress * 100 + "%"; 694 }); 695 } 696 697 triggerParallax() { 698 const self = this; 699 var imgs = self.container.querySelectorAll(".mslider-item img"); 700 701 if (imgs) { 702 self.slider.on("scroll", function (progress) {
703 self.slider.slides.forEach(function (slide, i) { 704 var img = imgs[i]; 705 var x = ((slide.target + self.slider.x) * -1) / 3; 706 707 if (img) 708 img.style.transform = "translateX(" + x + "px)"; 709 }); 710 }); 711 } 712 } 713 714 initializeMediaSlider() { 715 const self = this; 716 var media_db = self.container.querySelector(".mslider-media-db"); 717 var viewport = self.container.querySelector(".flickity-viewport"); 718 self.insertAfter(media_db, viewport); 719 720 media_db 721 .querySelectorAll(".mslider-detail-box") 722 .forEach(function (element, index) { 723 element.setAttribute("data-selectedindex", index); 724 }); 725 726 media_db.querySelector( 727 '.mslider-detail-box[data-selectedindex="0"]' 728 ).style.display = "block"; 729 730 self.slider.on("select", function (index) { 731 media_db 732 .querySelectorAll(".mslider-detail-box") 733 .forEach(function (a) { 734 a.style.display = "none"; 735 }); 736 737 media_db.querySelector( 738 '.mslider-detail-box[data-selectedindex="' + index + '"]' 739 ).style.display = "block"; 740 741 // Update heights in fullscreen 742 if (self.slider.isFullscreen) self.fixHeights(true, index); 743 }); 744 } 745 746 createSpinner(divIdentifier, color) { 747 var spinner_options = { 748 lines: 9, 749 length: 4, 750 width: 3, 751 radius: 3, 752 corners: 1, 753 rotate: 0, 754 direction: 1, 755 color: color, 756 speed: 1, 757 trail: 52, 758 shadow: false, 759 hwaccel: false, 760 className: "spinner", 761 zIndex: 2e9, 762 top: "50%", 763 left: "50%", 764 }; 765 766 var target = document.querySelector(divIdentifier); 767 768 if (target) { 769 var spinner = new Spinner(spinner_options).spin(); 770 target.innerHTML = ""; 771 target.appendChild(spinner.el); 772 } 773 774 return; 775 } 776 777 insertAfter(newNode, referenceNode) { 778 referenceNode.parentNode.insertBefore( 779 newNode, 780 referenceNode.nextSibling 781 ); 782 } 783 784 htmlToElement(htmlString) { 785 var div = document.createElement("div"); 786 div.innerHTML = htmlString.trim(); 787 788 return div.firstChild; 789 } 790 791 htmlToElements(htmlString, selector) { 792 var div = document.createElement("div"); 793 div.innerHTML = htmlString.trim(); 794 795 return div.querySelectorAll(selector); 796 } 797 798 initModalMessages() { 799 var zoomSlider = document.querySelector( 800 "#zoomSlider_" + this.widgetId 801 ); 802 803 if (!zoomSlider) return; 804 805 zoomSlider.addEventListener("show.bs.modal", function (e) { 806 // Button that triggered the modal 807 var button = e.relatedTarget; 808 809 // Update the title 810 if (zoomSlider.querySelector(".modal-title")) { 811 var title = button.getAttribute("data-ms-title"); 812 zoomSlider.querySelector(".modal-title").textContent = 813 title; 814 } 815 816 // Update the image 817 var image = button.getAttribute("data-src"); 818 zoomSlider.querySelector("img").setAttribute("src", image); 819 }); 820 821 zoomSlider.addEventListener("hidden.bs.modal", function (e) { 822 zoomSlider.querySelector("img").setAttribute("src", ""); 823 }); 824 } 825 } 826 827 window.Mslider = { 828 initialise: (options, id, count, source, path, itemid) => 829 new Mslider(options, id, count, source, path, itemid), 830 }; 831})(document, Joomla);
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.