1(() => { 2 'use strict'; 3 const root = document.querySelector('.sst-qo'); 4 if (!root) return; 5 const tabs = [...root.querySelectorAll('[data-qo-family-tab]')]; 6 const protectedTabs = new Set(['top', 'sale', 'all']); 7 const endpoint = root.dataset.qoTabAvailabilityUrl; 8 if (!endpoint) return; 9 let busy = false, lastAttempt = 0; 10 function restoreSelection() { 11 const selected = tabs.find(tab => tab.getAttribute('aria-pressed') === 'true'); 12 if (!selected || selected.dataset.qoUnavailable !== '1') return; 13 const fallback = ['top', 'sale', 'all'].map(id => tabs.find(tab => tab.dataset.qoFamilyTab === id && !tab.hidden)).find(Boolean); 14 fallback?.click(); 15 } 16 function apply(map) { 17 tabs.forEach(tab => { 18 const id = tab.dataset.qoFamilyTab; 19 if (protectedTabs.has(id) || typeof map[id] !== 'boolean') return; 20 tab.hidden = !map[id]; 21 if (map[id]) delete tab.dataset.qoUnavailable; 22 else tab.dataset.qoUnavailable = '1'; 23 }); 24 restoreSelection(); 25 } 26 async function refresh() { 27 if (busy || document.hidden || Date.now() - lastAttempt < 45000) return; 28 busy = true; lastAttempt = Date.now(); 29 const controller = new AbortController(); 30 const timeout = setTimeout(() => controller.abort(), 15000); 31 try { 32 const response = await fetch(endpoint, {credentials:'same-origin', cache:'no-store', signal:controller.signal}); 33 if (!response.ok) return; 34 const payload = await response.json(); 35 if (payload.success && payload.data?.tabs) apply(payload.data.tabs); 36 } catch (_) { 37 // Keep the last known tab state when the network is unavailable. 38 } finally { clearTimeout(timeout); busy = false; } 39 } 40 const strip = root.querySelector('[data-qo-family-tabs]'); 41 if (strip) new MutationObserver(restoreSelection).observe(strip, {subtree:true, attributes:true, attributeFilter:['aria-pressed']}); 42 restoreSelection(); 43 refresh(); 44 setInterval(refresh, 60000); 45 document.addEventListener('visibilitychange', refresh); 46})();
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.