1// Redirect the whole page when the user picks a different sport from header dropdown. 2// Always lands on /{sport}/workbench rather than preserving the current 3// subpath. Sport-specific sections (research-hub/pitchers, weather, 4// home-runs) don't necessarily exist on the other sports, so swapping 5// just the sport prefix would land on a 404 / cover-page in some cases. 6// Workbench is the universal entry point that exists for every sport. 7function pbSportDest(sport) { 8 const sportLc = String(sport || "").toLowerCase(); 9 if (!sportLc) return null; 10 const dest = `/${sportLc}/workbench`; 11 // No-op when already on this sport's workbench. Other paths within 12 // the same sport still re-route to /workbench so the experience is 13 // predictable regardless of where the user starts. 14 if (location.pathname === dest || location.pathname === `${dest}/`) return null; 15 return dest; 16} 17 18document.getElementById("sport-dropdown")?.addEventListener("click", evt => { 19 const li = evt.target.closest(".sport-item"); 20 if (!li) return; 21 if (li.classList.contains("sport-disabled")) return; // offseason â handled by coverPage.js 22 const dest = pbSportDest(li.dataset.sport); 23 if (dest) { li.style.opacity = "0.55"; location.href = dest; } 24}); 25// Hand-off from the inline early switcher in index.html: it navigates for 26// taps that land before this script evaluates, and stands down once this 27// flag is set.
28window.__pbSportNavReady = true; 29 30// Segmented switcher, beside the logo. Since 2026-09-08 it is the displayed 31// control from 601px up, the phone included; the dropdown wired above is 32// still the affordance below that. Same destination rules either way. 33const pbSegments = document.querySelector(".sport-segments"); 34 35function pbHideOffseasonToast() { 36 const toast = document.querySelector(".offseason-toast"); 37 if (!toast) return; 38 clearTimeout(toast._tid); 39 toast.classList.remove("show"); 40} 41 42pbSegments?.addEventListener("click", evt => { 43 const btn = evt.target.closest(".sport-seg"); 44 if (!btn) return; 45 // .sport-segments lives INSIDE .landing-nav .nav-left, and coverPage.js 46 // binds handleLogoClick to that whole block â click the brand, go to the 47 // workbench. Without this the pill click bubbles there and the offseason 48 // pill, which deliberately does NOT navigate, navigated anyway: tapping the 49 // greyed NBA crest showed "See you next season!" AND yanked the user to the 50 // current sport's workbench. This is why the segments handler must stop the 51 // event for EVERY .sport-seg, including the disabled one below. 52 evt.stopPropagation(); 53 // Offseason sports announce themselves instead of silently doing nothing â 54 // same "See you next season!" toast the dropdown shows, exported by 55 // coverPage.js (which runs on app pages too, not just the cover). 56 if (btn.classList.contains("sport-disabled")) { 57 window.PBShowOffseasonToast?.(btn); 58 return; 59 } 60 const dest = pbSportDest(btn.dataset.sport); 61 if (dest) { btn.style.opacity = "0.55"; location.href = dest; } 62}); 63 64// Hover preview of the same toast. Gated on a real hover pointer so a tap on 65// a touchscreen does not fire the synthetic mouseover AND the click handler. 66// mouseover/mouseout are used (they bubble, unlike mouseenter/mouseleave) with 67// a relatedTarget containment check so moving between a segment's icon and 68// label does not re-trigger. contains(null) is false, so leaving the button 69// entirely still hides. 70if (pbSegments && window.matchMedia?.("(hover: hover)").matches) { 71 pbSegments.addEventListener("mouseover", evt => { 72 const btn = evt.target.closest(".sport-seg.sport-disabled"); 73 if (!btn || btn.contains(evt.relatedTarget)) return; 74 window.PBShowOffseasonToast?.(btn); 75 // Cancel the helper's 2.5s auto-hide: while the cursor stays on the 76 // segment the toast should stay up, and mouseout is what dismisses it. 77 const toast = document.querySelector(".offseason-toast"); 78 if (toast) clearTimeout(toast._tid); 79 }); 80 pbSegments.addEventListener("mouseout", evt => { 81 const btn = evt.target.closest(".sport-seg.sport-disabled"); 82 if (!btn || btn.contains(evt.relatedTarget)) return; 83 pbHideOffseasonToast(); 84 }); 85} 86// Note: Hero sport toggle navigation is handled in coverPage.js
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.