1(function () { 2 const VALID_TYPES = ["do", "stay", "shop", "taste"]; 3 let hasScrolled = false; 4 5 function hasPacHash() { 6 const hash = window.location.hash || ""; 7 const match = /^#pac_dtm_child_\d+/.test(hash); 8 console.log("[tabs-scroll] hasPacHash:", match, "hash:", hash); 9 return match; 10 } 11 12 function isValidListingsPath() { 13 const segments = window.location.pathname.split("/").filter(Boolean); 14 const type = segments[0] || ""; 15 const slug = segments[1] || ""; 16 const ok = VALID_TYPES.includes(type) && slug === type + "-listings"; 17 console.log("[tabs-scroll] isValidListingsPath:", ok, "segments:", segments); 18 return ok; 19 } 20 21 function shouldRun() { 22 const hashOk = hasPacHash(); 23 const pathOk = isValidListingsPath(); 24 const ok = hashOk && pathOk; 25 console.log("[tabs-scroll] shouldRun:", ok); 26 return ok; 27 } 28 29 // Find the nearest scrollable ancestor, or fall back to window 30 function getScrollContainer(el) { 31 let node = el.parentElement; 32 33 while (node && node !== document.body) { 34 const style = window.getComputedStyle(node); 35 const overflowY = style.overflowY; 36 const overflow = style.overflow; 37 38 if (/(auto|scroll)/.test(overflowY) || /(auto|scroll)/.test(overflow)) { 39 console.log("[tabs-scroll] Using scroll container element"); 40 return node; 41 } 42 43 node = node.parentElement; 44 } 45 46 console.log("[tabs-scroll] Using window as scroll container"); 47 return window; 48 } 49 50 function getOffsetWithinContainer(target, container) { 51 if (container === window) { 52 const rect = target.getBoundingClientRect(); 53 return rect.top + window.pageYOffset; 54 } 55 56 let offset = 0; 57 let node = target; 58 59 while (node && node !== container && node !== document.body) { 60 offset += node.offsetTop; 61 node = node.offsetParent; 62 } 63 64 return offset; 65 } 66 67 function killAnimations() { 68 if (document.getElementById("tabs-scroll-kill-anims")) { 69 return; 70 } 71 72 console.log("[tabs-scroll] Killing animations/transitions"); 73 74 const style = document.createElement("style"); 75 style.id = "tabs-scroll-kill-anims"; 76 style.textContent = ` 77 * { 78 animation: none !important; 79 transition: none !important; 80 } 81 html, body { 82 scroll-behavior: auto !important; 83 } 84 `; 85 document.head.appendChild(style); 86 } 87 88 function bullyScrollToTabs() { 89 if (hasScrolled) { 90 console.log("[tabs-scroll] bullyScrollToTabs: already ran, skipping"); 91 return; 92 } 93 hasScrolled = true; 94 95 const target = document.getElementById("tabs"); 96 if (!target) { 97 console.warn("[tabs-scroll] #tabs not found."); 98 return; 99 } 100 101 killAnimations(); 102 103 const container = getScrollContainer(target); 104 let attempts = 0; 105 const maxAttempts = 10; 106 const delay = 400; 107 108 function scrollOnce() { 109 attempts++; 110 const scrollTopTarget = getOffsetWithinContainer(target, container); 111 console.log("[tabs-scroll] attempt", attempts, "scrollTopTarget:", scrollTopTarget); 112 113 if (container === window) { 114 window.scrollTo(0, scrollTopTarget); 115 console.log("[tabs-scroll] window.scrollY:", window.scrollY); 116 } else { 117 container.scrollTop = scrollTopTarget; 118 console.log("[tabs-scroll] container.scrollTop:", container.scrollTop); 119 } 120 121 if (attempts < maxAttempts) { 122 setTimeout(scrollOnce, delay); 123 } 124 } 125 126 // small delay after load to let layout/plugins settle 127 setTimeout(scrollOnce, 400); 128 } 129 130 // Main wiring 131 window.addEventListener("load", function () { 132 console.log("[tabs-scroll] window.load fired"); 133 if (shouldRun()) { 134 console.log("[tabs-scroll] running bullyScrollToTabs from load"); 135 bullyScrollToTabs(); 136 } 137 }); 138 139 // Fallback: in case load timing is weird, re-check after a bit 140 setTimeout(function () { 141 console.log("[tabs-scroll] timeout fallback fired"); 142 if (shouldRun()) { 143 console.log("[tabs-scroll] running bullyScrollToTabs from fallback"); 144 bullyScrollToTabs(); 145 } 146 }, 6000); 147})();
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.