1(function () { 2 'use strict'; 3 4 var CACHE_KEY = 'cached_footer_pages_v1'; 5 6 function pageTitle(page) { 7 return String((page && (page.title || page.placeholder_title || page.slug)) || '').trim(); 8 } 9 10 function pagePath(page) { 11 return String((page && page.path) || '').trim() || '/'; 12 } 13 14 function validPages(value) { 15 return (Array.isArray(value) ? value : []).filter(function (page) { 16 return page && pageTitle(page) && pagePath(page); 17 }); 18 } 19 20 function renderFooterPages(pages) { 21 var nav = document.getElementById('footer-pages'); 22 if (!nav) { 23 return; 24 } 25 var rows = validPages(pages); 26 if (!rows.length) { 27 nav.innerHTML = ''; 28 nav.hidden = true; 29 return; 30 } 31 nav.innerHTML = rows.map(function (page) { 32 var a = document.createElement('a'); 33 a.className = 'footer-page-link'; 34 a.href = pagePath(page); 35 a.textContent = pageTitle(page); 36 return a.outerHTML; 37 }).join(''); 38 nav.hidden = false; 39 } 40 41 function bootstrapPages() { 42 if (window.__wizardrySiteBootstrap && Array.isArray(window.__wizardrySiteBootstrap.footer_pages)) { 43 return window.__wizardrySiteBootstrap.footer_pages; 44 } 45 try { 46 return JSON.parse(localStorage.getItem(CACHE_KEY) || '[]'); 47 } catch (_err) { 48 return []; 49 } 50 } 51 52 function cachePages(pages) { 53 try { 54 localStorage.setItem(CACHE_KEY, JSON.stringify(validPages(pages))); 55 } catch (_err) { 56 // Ignore cache write failures. 57 } 58 } 59 60 function refreshFromStatic() { 61 fetch('/static/footer-pages.json', { cache: 'no-store' }) 62 .then(function (res) { 63 if (!res.ok) { 64 throw new Error('footer pages unavailable'); 65 } 66 return res.json(); 67 }) 68 .then(function (data) { 69 var pages = validPages(data && data.pages); 70 cachePages(pages); 71 renderFooterPages(pages); 72 }) 73 .catch(function () { 74 // Keep the bootstrapped/cached footer rather than flashing empty. 75 }); 76 } 77 78 renderFooterPages(bootstrapPages()); 79 if (document.readyState === 'loading') { 80 document.addEventListener('DOMContentLoaded', function () { 81 renderFooterPages(bootstrapPages()); 82 refreshFromStatic(); 83 }, { once: true }); 84 } else { 85 refreshFromStatic(); 86 } 87 window.addEventListener('wizardry-footer-refresh-request', function (event) { 88 var pages = event && event.detail && Array.isArray(event.detail.pages) ? event.detail.pages : []; 89 cachePages(pages); 90 renderFooterPages(pages); 91 }); 92})();
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.