PageSourceSearch

https://saboskirt.com/cdn/shop/t/503/assets/product-hotspot.js?v=11389525148121045061790725531

js saboskirt.com collected 2026-10-03 21:25:46 UTC 7,108 bytes, 2 lines download raw bytes

1import{Component}from"@theme/component";import"@theme/quick-add";import{isClickedOutside,isMobileBreakpoint,isTouchDevice,mediaQueryLarge}from"@theme/utilities";export class ProductHotspotComponent extends Component{requiredRefs=["trigger","dialog"];#pointerenterHandler=null;timer=null;connectedCallback(){super.connectedCallback(),this.#handleBreakpointChange(),mediaQueryLarge.addEventListener("change",this.#handleBreakpointChange)}disconnectedCallback(){super.disconnectedCallback(),this.#removeDesktopListeners(),mediaQueryLarge.removeEventListener("change",this.#handleBreakpointChange)}#openQuickAddModal(){const quickAddComponent=this.querySelector("quick-add-component");quickAddComponent&&quickAddComponent.handleClick(new MouseEvent("click",{bubbles:!0,cancelable:!0}))}#setupDesktopListeners(){const{trigger,dialog}=this.refs,pointerenterHandler=()=>{dialog.open||(this.timer=setTimeout(()=>{this.showDialog()},120),trigger.addEventListener("pointerleave",this.#handlePointerLeave))};this.#pointerenterHandler=pointerenterHandler,trigger.addEventListener("pointerenter",pointerenterHandler)}#removeDesktopListeners(){const{trigger}=this.refs;this.#pointerenterHandler&&(trigger.removeEventListener("pointerenter",this.#pointerenterHandler),trigger.removeEventListener("pointerleave",this.#handlePointerLeave),this.#pointerenterHandler=null),this.timer&&(clearTimeout(this.timer),this.timer=null)}#handleBreakpointChange=()=>{this.#removeDesktopListeners(),isMobileBreakpoint()||this.#setupDesktopListeners()};#calculateDialogPlacement(){const{trigger,dialog}=this.refs,hotspotsContainer=this.parentElement;if(!hotspotsContainer)return;const BUTTON_GAP=10,CONTAINER_GAP=10,VIEWPORT_GAP=16,TOTAL_GAP=BUTTON_GAP+CONTAINER_GAP,containerRect=hotspotsContainer?.getBoundingClientRect(),triggerRect=trigger.getBoundingClientRect(),viewportH=window.innerHeight;dialog.style.visibility="hidden",dialog.style.display="block",dialog.style.transform="none",dialog.removeAttribute("data-placement");const{width:dialogWidth,height:dialogHeight}=dialog.getBoundingClientRect();dialog.style.removeProperty("display"),dialog.style.removeProperty("visibility"),dialog.style.removeProperty("transform");const buttonLeft=triggerRect.left-containerRect.left,buttonRight=triggerRect.right-containerRect.left,buttonTop=triggerRect.top-containerRect.top,buttonBottom=triggerRect.bottom-containerRect.top,spaceRight=containerRect.width-buttonRight-CONTAINER_GAP,spaceLeft=buttonLeft-CONTAINER_GAP;let x="right";spaceRight>=dialogWidth+BUTTON_GAP?x="right":spaceLeft>=dialogWidth+BUTTON_GAP?x="left":x="center";let y="bottom",verticalOffset=0;if(x!=="center"){let dialogStartY=buttonTop,dialogEndY=buttonTop+dialogHeight;dialogEndY>containerRect.height-CONTAINER_GAP?(dialogStartY=buttonBottom-dialogHeight,dialogEndY=buttonBottom,y="top",dialogStartY<CONTAINER_GAP?verticalOffset=CONTAINER_GAP-dialogStartY:dialogEndY>containerRect.height-CONTAINER_GAP&&(verticalOffset=-(dialogEndY-(containerRect.height-CONTAINER_GAP)))):dialogStartY<CONTAINER_GAP&&(dialogStartY<CONTAINER_GAP&&(verticalOffset=CONTAINER_GAP-dialogStartY),y="bottom");const dialogTopViewport=containerRect.top+window.scrollY+dialogStartY+verticalOffset-window.scrollY,dialogBottomViewport=dialogTopViewport+dialogHeight;dialogTopViewport<VIEWPORT_GAP?verticalOffset+=VIEWPORT_GAP-dialogTopViewport:dialogBottomViewport>viewportH-VIEWPORT_GAP&&(verticalOffset-=dialogBottomViewport-(viewportH-VIEWPORT_GAP))}else containerRect.height-buttonBottom>=dialogHeight+TOTAL_GAP?y="bottom":buttonTop>=dialogHeight+TOTAL_GAP?y="top":y=buttonTop<containerRect.height/2?"bottom":"top";return dialog.dataset.placement=`${x},${y}`,verticalOffset!==0?dialog.style.setProperty("--dialog-vertical-offset",`${verticalOffset}px`):dialog.style.removeProperty("--dialog-vertical-offset"),new Promise(resolve=>setTimeout(resolve,100))}#handlePointerLeave=e=>{const{dialog,trigger}=this.refs;if(this.timer&&(clearTimeout(this.timer),this.timer=null),!dialog.open)return;const isLeavingTrigger=e.target===trigger,isLeavingDialog=e.target===dialog,isGoingToDialog=e.relatedTarget===dialog||e.relatedTarget instanceof Element&&e.relatedTarget.closest("dialog")===dialog,isGoingToTrigger=e.relatedTarget===trigger;(isLeavingTrigger&&!isGoingToDialog||isLeavingDialog&&!isGoingToTrigger)&&this.closeDialog()};getHotspotProductLink(){return this.refs.productLink||null}#isEarlyAccess(){return this.dataset.moodHotspotEarlyAccess==="true"}handleHotspotClick=e=>{isMobileBreakpoint()||isTouchDevice()?(e.preventDefault(),e.stopPropagation(),this.#isEarlyAccess()?this.showMobileSheet():this.#openQuickAddModal()):this.showDialog()};showDialog=async()=>{const{dialog}=this.refs;await this.#calculateDialogPlacement(),dialog.dataset.showing="true",dialog.show(),document.body.addEventListener("click",this.lightDismissMouse),document.body.addEventListener("keydown",this.lightDismissKeyboard),document.body.addEventListener("keyup",this.lightDismissKeyboard),dialog.addEventListener("pointerleave",this.#handlePointerLeave),window.addEventListener("resize",this.#handleViewportChange,{passive:!0})};#handleViewportChange=()=>{const{dialog}=this.refs;dialog.open&&this.#calculateDialogPlacement()};showMobileSheet=()=>{const{dialog}=this.refs;dialog.open||(dialog.setAttribute("data-mood-mobile-sheet","true"),dialog.dataset.showing="true",typeof dialog.showModal=="function"?dialog.showModal():dialog.show(),dialog.addEventListener("click",this.#handleSheetBackdropClick),dialog.addEventListener("cancel",this.#handleSheetCancel))};#handleSheetBackdropClick=event=>{const{dialog}=this.refs;event.target===dialog&&this.closeDialog()};#handleSheetCancel=event=>{event.preventDefault(),this.closeDialog()};closeDialog=async()=>{const{dialog,trigger}=this.refs;dialog.dataset.closing="true",dialog.close(),document.body.removeEventListener("click",this.lightDismissMouse),document.body.removeEventListener("keydown",this.lightDismissKeyboard),document.body.removeEventListener("keyup",this.lightDismissKeyboard),dialog.removeEventListener("pointerleave",this.#handlePointerLeave),dialog.removeEventListener("click",this.#handleSheetBackdropClick),dialog.removeEventListener("cancel",this.#handleSheetCancel),trigger.removeEventListener("pointerleave",this.#handlePointerLeave),window.removeEventListener("resize",this.#handleViewportChange);const animations=dialog.getAnimations({subtree:!0});await Promise.allSettled(animations.map(a=>a.finished)),dialog.open||(delete dialog.dataset.showing,delete dialog.dataset.closing,delete dialog.dataset.placement,dialog.removeAttribute("data-mood-mobile-sheet"))};lightDismissMouse=event=>{const{dialog}=this.refs;isClickedOutside(event,dialog)&&this.closeDialog()};lightDismissKeyboard=event=>{const{dialog}=this.refs;
1(event.type==="keydown"&&event.key==="Escape"||event.type==="keyup"&&!dialog.matches(":is(:focus, :focus-visible, :focus-within)"))&&this.closeDialog()}}customElements.define("product-hotspot-component",ProductHotspotComponent);
2//# sourceMappingURL=/cdn/shop/t/503/assets/product-hotspot.js.map?v=11389525148121045061790725531

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.