1import{LitElement,html,css,unsafeHTML,ref,createRef,map,range,paths,t,styles,classMap}from"@hh/global.js";class HHSlideshow extends LitElement{static properties={_current:{state:!0},_total:{state:!0},speed:{reflect:!0,type:Number},playing:{reflect:!0,type:Boolean},userPause:{type:Boolean},autoplay:{state:!0},slideCount:{type:Number,attribute:"slide-count"},hideArrows:{type:Boolean,attribute:"hide-arrows"},strings:{type:Object}};$next=createRef();$prev=createRef();constructor(){super(),this._total=0,this._current=1,this.playing=!1,this.userPause=!1,this.speed=0,this.highlightCompleted=!1,this.swiper=null,this._swiperEl=null,this._swiperMounted=!1,this._boundWindowKeydown=e=>this.onModalKeydown(e),this._onResize=this._onResize.bind(this)}_getWrapper(){return this.closest("[js-slideshow-wrapper]")}_getTrack(){return this._getWrapper()?.querySelector("[js-slideshow-track]")??this.querySelector("[js-slideshow-track]")}connectedCallback(){super.connectedCallback();const track=this._getTrack();this.items=Array.from(track?.querySelectorAll("[js-slide]")??[]),this._total=this.items.length,(this.slideCount==null||Number.isNaN(this.slideCount))&&(this.slideCount=this._total),this.hideArrows=this.hasAttribute("hide-arrows");const speedAttr=this.getAttribute("speed");this.speed=speedAttr?Number(speedAttr):0;const stringsAttr=this.getAttribute("strings");if(!this.strings||typeof this.strings!="object")if(stringsAttr)try{this.strings=JSON.parse(stringsAttr)}catch{this.strings={}}else this.strings={};this.reducedMotion=window.matchMedia("(prefers-reduced-motion: reduce)"),window.addEventListener("keydown",this._boundWindowKeydown),window.addEventListener("resize",this._onResize),this.addEventListener("openVideoModal",this.onVideoLinkClick)}disconnectedCallback(){super.disconnectedCallback();const video=this.items?.[this._current-1]?.querySelector?.("video");video&&(video.onended=null),clearTimeout(this.imageSlideTimeout),clearInterval(this.autoplay),this.swiper&&(this.swiper.destroy(!0,!0),this.swiper=null),window.removeEventListener("keydown",this._boundWindowKeydown),window.removeEventListener("resize",this._onResize)}async firstUpdated(){await this._applyUniformSlideHeight(),await this._initSwiper(),this.setSlideVisibility(),this._updateNavState(),!this.reducedMotion.matches&&this.hasAttribute("use-video-rotation")?this.setupVideoEndTrigger(this.items[this._current-1]):this.hasAttribute("speed")?this.setAutoplay():(this.autoplay=!1,this.userPause=!0)}_isMobileSlideshow(){return window.matchMedia("(max-width: 749px)").matches}_whenSlideImagesReady(){const pending=this.items.flatMap(item=>[...item.querySelectorAll("img")]).filter(img=>!img.complete);return pending.length?Promise.all(pending.map(img=>new Promise(resolve=>{img.addEventListener("load",resolve,{once:!0}),img.addEventListener("error",resolve,{once:!0})}))):Promise.resolve()}_getSlideMediaHeight(slide){const media=[...slide.querySelectorAll(".slide__media, .video-mobile-wrapper, .video-desktop-wrapper")].filter(element=>getComputedStyle(element).display!=="none");return media.length?Math.max(...media.map(element=>element.offsetHeight)):0}async _applyUniformSlideHeight(){const wrapper=this._getWrapper();if(!wrapper||!this.items?.length)return;if(!this._isMobileSlideshow()){wrapper.style.removeProperty("--slideshow-slide-height");return}await this._whenSlideImagesReady();let uniformHeight=0;this.items.forEach(item=>{uniformHeight=Math.max(uniformHeight,this._getSlideMediaHeight(item))}),uniformHeight>0&&wrapper.style.setProperty("--slideshow-slide-height",`${uniformHeight}px`)}_waitForSwiper(){return new Promise(resolve=>{const check=()=>{window.Swiper?resolve(window.Swiper):requestAnimationFrame(check)};check()})}_mountSwiperStructure(){if(this._swiperMounted)return null;const track=this._getTrack();if(!track)return null;this._swiperMounted=!0,this.items=Array.from(track.querySelectorAll("[js-slide]")),this._total=this.items.length,track.classList.add("swiper","slideshow-swiper"),track.setAttribute("aria-live","off");const wrapper=document.createElement("div");
1return wrapper.className="swiper-wrapper",this.items.forEach(item=>{const slide=document.createElement("div");slide.className="swiper-slide",slide.appendChild(item),wrapper.appendChild(slide)}),track.appendChild(wrapper),this._swiperEl=track,track}async _initSwiper(){const Swiper=await this._waitForSwiper(),track=this._mountSwiperStructure();!track||this.swiper||(this.swiper=new Swiper(track,{slidesPerView:1,spaceBetween:0,speed:300,allowTouchMove:this._total>1,grabCursor:this._total>1,resistanceRatio:.85,longSwipes:!0,shortSwipes:!0,preventInteractionOnTransition:!1,watchSlidesProgress:!0,observer:!0,observeParents:!0,on:{slideChange:()=>this._onSwiperSlideChange(),touchStart:()=>{this.userPause=!0,this.stopAutoplay()}}}))}_onSwiperSlideChange(){if(!this.swiper)return;const slideIndex=this.swiper.activeIndex,newCurrent=slideIndex+1;if(newCurrent===this._current&&this.swiper.initialized){this._updateNavState();return}this._current=newCurrent;const currentSlide=this.items[slideIndex];this.setSlideVisibility(),this.onSlideChange(currentSlide),this._updateNavState(),this.highlightCompleted=!1,this.requestUpdate(),currentSlide&&this.eagerLoadSlidesImages(currentSlide.querySelectorAll("img"))}async _onResize(){this.swiper&&(await this._applyUniformSlideHeight(),this.swiper.update(),this.swiper.slideTo(this._current-1,0))}updated(changedProperties){changedProperties.has("_current")&&this.setSlideVisibility()}setSlideVisibility(){if(!this.items?.length)return;this.items.forEach((item,idx)=>{const linkElements=item.querySelectorAll("hh-button");idx+1===this._current?(linkElements.forEach(button=>button.removeAttribute("tabindex")),item.setAttribute("aria-hidden","false"),item.removeAttribute("tabindex")):(linkElements.forEach(button=>button.setAttribute("tabindex","-1")),item.setAttribute("aria-hidden","true"),item.setAttribute("tabindex","-1"))});const activeSlide=this.items[this._current-1],slideIndex=activeSlide?parseInt(activeSlide.getAttribute("slide-index"),10):null;slideIndex!=null&&!Number.isNaN(slideIndex)&&this._getWrapper()?.dispatchEvent(new CustomEvent("slideshow:active-slide",{bubbles:!0,detail:{slideIndex}}))}_updateNavState(){this._current===1?this.$prev?.value?.setAttribute("disabled",!0):this.$prev?.value?.removeAttribute("disabled"),this._current===this._total?this.$next?.value?.setAttribute("disabled",!0):this.$next?.value?.removeAttribute("disabled")}onSlideChange(currentSlide){const video=currentSlide?.querySelector?.("video");if(video){if(video.ended)try{video.currentTime=0,video.play().catch(()=>{})}catch{}this.hasAttribute("use-video-rotation")&&this.setupVideoEndTrigger(currentSlide)}}move=event=>{event.preventDefault(),this.userPause=!0,this.stopAutoplay();const next=event?.currentTarget?.name==="next"?Math.min(this._current+1,this._total):Math.max(this._current-1,1);this.moveTo(next-1)};moveTo(slide,{smooth=!0}={}){slide=Number(slide),!(!this.swiper||!this.items?.[slide])&&this.swiper.slideTo(slide,smooth?300:0)}eagerLoadSlidesImages(images){images.forEach(img=>img.setAttribute("loading","eager"))}setupVideoEndTrigger(slide){if(!this.hasAttribute("use-video-rotation"))return;clearTimeout(this.imageSlideTimeout),this.playing=!0,this.userPause=!1;const videos=slide.querySelectorAll("video");if(videos.length>0)videos.forEach(video=>{video.onended=null;const updateSpeedFromVideo=()=>{const duration=video.duration||5;this.style.setProperty("--slideshow-speed",`${duration}s`)};video.addEventListener("loadedmetadata",updateSpeedFromVideo,{once:!0});try{video.currentTime=0,video.play().catch(()=>{})}catch{}video.onended=()=>{this.highlightCompleted=!0,this.requestUpdate(),this.rotateSlides()}});else{const imageDelay=Number.parseInt(this.getAttribute("speed"),10)||5e3;this.style.setProperty("--slideshow-speed",`${imageDelay/1e3}s`),this.imageSlideTimeout=setTimeout(()=>{this.highlightCompleted=!0,this.requestUpdate(),this.rotateSlides()},imageDelay)}}rotateSlides(){clearTimeout(this.imageSlideTimeout),(this.items[this._current-1]?.querySelectorAll?.("video")||[]).forEach(video=>video.onended=null);const nextIndex=this._current===this._total?0:this._current;this.moveTo(nextIndex)}play=()=>{this._swiperEl?.setAttribute("aria-live","off"),this.playing=!0};pause=()=>{this._swiperEl?.setAttribute("aria-live","polite"),this.playing=!1};setAutoplay(){!this.speed||this.hasAttribute("use-video-rotation")||(this.style.setProperty("--slideshow-s
1peed",`${this.speed/1e3}s`),clearInterval(this.autoplay),this.autoplay=setInterval(()=>this.rotateSlides(),this.speed),this.play())}stopAutoplay(){clearInterval(this.autoplay),this.pause()}toggleAutoplay=()=>{this.hasAttribute("use-video-rotation")||(this.playing?(this.userPause=!0,this.stopAutoplay()):(this.userPause=!1,this.setAutoplay()))};onPaginationClick=(e,slideIndex)=>{e.preventDefault(),this.userPause=!0,this.stopAutoplay(),this.moveTo(slideIndex)};onVideoLinkClick=e=>{e.preventDefault(),typeof scrollLock<"u"&&scrollLock.disablePageScroll(this.videoModal);const videoUrl=e.target.getAttribute("video-url"),videoPoster=e.target.getAttribute("video-poster"),youtubeId=e.target.getAttribute("youtube-id");if(this.userPause=!0,this.stopAutoplay(),videoUrl){this.videoModal.innerHTML=this.vdsTemplate(videoUrl,videoPoster);const videoHTML=this.videoModal.querySelector("video");videoHTML.addEventListener("canplay",()=>{videoHTML.play().catch(()=>{})})}else if(youtubeId){this.videoModal.innerHTML=this.youtubeTemplate(youtubeId);const youtubeHTML=this.videoModal.querySelector("iframe");youtubeHTML.addEventListener("load",()=>{youtubeHTML.contentWindow.postMessage('{"event":"command","func":"playVideo","args":""}',"*")})}};onModalClose=()=>{typeof scrollLock<"u"&&scrollLock.enablePageScroll(this.videoModal),this.videoModal&&(this.videoModal.innerHTML=""),this.userPause=!1,this.setAutoplay()};onModalClickOutside=e=>{e.target===this.hhModal&&(this.hhModal.close(e),this.onModalClose())};onModalKeydown(e){e.code.toUpperCase()==="ESCAPE"&&(this.hhModal.close(e),this.onModalClose())}get videoModal(){return this.querySelector(".js-video-modal")??null}get hhModal(){return this.querySelector("hh-modal")??null}vdsTemplate(source,poster=""){return poster?`<video controls playsinline src="${source}" poster="${poster}"></video>`:`<video controls playsinline src="${source}"></video>`}youtubeTemplate(id){return` 2 <iframe 3 src="https://www.youtube.com/embed/${id}?enablejsapi=1&playlist=${id}&disablekb=0&fs=1&iv_load_policy=1&modestbranding=1&rel=1&widgetid=1" 4 frameborder="0" 5 allow="autoplay; encrypted-media; picture-in-picture" 6 allowfullscreen 7 ></iframe> 8 `}render(){return html` 9 <div class="slideshow-ui"> 10 <div class="controls"> 11 <div 12 class="${classMap({pagination:!0,hidden:this.slideCount===1})}" 13 > 14 ${map(range(this.slideCount),idx=>html` 15 <button 16 class="pagination-button" 17 aria-label="Go to slide ${idx+1}" 18 aria-current="${this._current===idx+1}" 19 @click=${e=>this.onPaginationClick(e,idx)} 20 > 21 <span class="pagination-button-inner"> 22 <span 23 data-paginate-progress 24 class="pagination-button-progress ${classMap({animation:this._current===idx+1&&!this.userPause,pause:!this.playing,selected:this._current===idx+1&&this.userPause,completed:this.highlightCompleted&&this._current>idx+1})}" 25 ></span> 26 </span> 27 </button> 28 `)} 29 </div> 30 31 <button 32 class="${classMap({toggle:!0,hidden:!this.speed||this.slideCount===1})}" 33 @click=${this.toggleAutoplay} 34 aria-label=${this.playing?this.strings.pause:this.strings.play} 35 > 36 <span class="${classMap({hidden:this.playing})}" 37 >${unsafeHTML(paths.play)}</span 38 > 39 <span class="${classMap({hidden:!this.playing})}" 40 >${unsafeHTML(paths.pause)}</span 41 > 42 </button> 43 </div> 44 45 <div 46 class="${classMap({buttons:!0,hidden:this.slideCount===1||this.hideArrows})}" 47 > 48 <button 49 ${ref(this.$prev)} 50 @click=${this.move} 51 type="button" 52 class="button button--prev slideshow-button" 53 name="previous" 54 aria-label="${t("accessibility.previous_slide","Previous")}" 55 > 56 ${unsafeHTML(paths.caret)} 57 </button> 58 <button 59 ${ref(this.$next)} 60 @click=${this.move} 61 type="button" 62 class="button button--next slideshow-button" 63 name="next" 64 aria-label="${t("accessibility.next_slide","Next")}" 65 > 66 ${unsafeHTML(paths.caret)} 67 </button> 68 </div> 69 </div> 70 71 <slot 72 name="video-modal" 73 @modal-close=${this.onModalClose} 74 @click=${this.onModalClickOutside} 75 @keydown=${this.onModalKeydown} 76 ></slot> 77 `}static styles=[styles.visuallyHidden,css` 78 :host { 79 box-sizing: border-box; 80 position: relative; 81 overflow: hidden; 82 display: block; 83 } 84 85 *, 86 *::before, 87 *::after { 88 box-sizing: inherit; 89 } 90 91 .slideshow-ui { 92 position: absolute; 93 inset: 0; 94 z-index: 2; 95 pointer-events: none; 96 } 97 98 .controls { 99 position: absolute; 100 padding: 0 1rem; 101 bottom: 0; 102 left: 0; 103 right: 0; 104 display: flex; 105 align-items: baseline; 106 column-gap: 1rem; 107 width: calc(100% - 2rem); 108 z-index: 2; 109 pointer-events: none; 110 } 111 112 .pagination { 113 display: flex; 114 width: 100%; 115 justify-content: space-between; 116 column-gap: 1rem; 117 pointer-events: auto; 118 } 119 120 .toggle { 121 width: 2.4rem; 122 height: 2.4rem; 123 padding: 0; 124 color: var(--hh-color-background); 125 background-color: transparent; 126 border: none; 127 cursor: pointer; 128 pointer-events: auto; 129 } 130 131 .toggle svg { 132 width: 100%; 133 height: 100%; 134 } 135 136 .buttons { 137 display: none; 138 align-items: center; 139 justify-content: space-between; 140 position: absolute; 141 z-index: 2; 142 top: 50%; 143 left: 0; 144 right: 0; 145 transform: translateY(-50%); 146 padding: 0 1rem; 147 pointer-events: none; 148 } 149 150 .hidden { 151 display: none; 152 } 153 154 .button { 155 pointer-events: auto; 156 width: 36px; 157 height: 36px; 158 cursor: pointer; 159 color: var(--hh-color-night, #000); 160 border: none; 161 background: transparent; 162 border-radius: 50%; 163 display: flex; 164 align-items: center; 165 justify-content: center; 166 transition: background 0.2s ease, opacity 0.2s ease; 167 } 168 169 .button:disabled { 170 opacity: 0.4;
171 cursor: not-allowed; 172 } 173 174 .button svg { 175 width: 8px; 176 height: auto; 177 } 178 179 .button--prev { 180 transform: rotate(90deg); 181 } 182 183 .button--next { 184 transform: rotate(270deg); 185 } 186 187 @media (min-width: 749px) { 188 .buttons { 189 display: flex; 190 padding: 0 50px; 191 } 192 193 .button { 194 width: 48px; 195 height: 48px; 196 } 197 198 .button svg { 199 width: 12px; 200 } 201 } 202 203 .pagination-button { 204 width: 100%; 205 padding: 2rem 0 1rem; 206 background: transparent; 207 border: none; 208 cursor: pointer; 209 } 210 211 .pagination-button-inner { 212 position: relative; 213 display: block; 214 background: rgba(255, 255, 255, 0.7); 215 height: 0.2rem; 216 } 217 218 .pagination-button-progress { 219 position: absolute; 220 inset: 0; 221 display: block; 222 background: red; 223 height: 0.2rem; 224 width: 0; 225 } 226 227 .pagination-button-progress.animation { 228 animation: slideProgress var(--slideshow-speed) linear 1 forwards; 229 } 230 231 .pagination-button-progress.completed, 232 .pagination-button-progress.selected { 233 width: 100%; 234 } 235 236 .pagination-button-progress.pause { 237 animation-play-state: paused; 238 } 239 240 @keyframes slideProgress { 241 from { 242 width: 0; 243 } 244 to { 245 width: 100%; 246 } 247 } 248 `]}customElements.define("hh-slideshow",HHSlideshow); 249//# sourceMappingURL=/cdn/shop/t/725/assets/component-slideshow.js.map?v=83480818229015616751786477837
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.