async function swap(url) { const res = await fetch(url); if (res.status !== 200) return; if (!res.headers.get("content-type").startsWith("text/html")) return; const text = await res.text(); const content = new DOMParser().parseFromString(text, "text/html"); const stylesheets = [...content.querySelectorAll("link[rel='stylesheet']")]; // swap title document.title = content.title; // swap body html document.body.innerHTML = content.body.innerHTML; // swap head html document.head.innerHTML = content.head.innerHTML; // swap stylesheets // const old_sheets = document.head.querySelectorAll("link[rel='stylesheet']"); // stylesheets.forEach(stylesheet => { document.head.appendChild(stylesheet) }); // old_sheets.forEach(stylesheet => { stylesheet.remove(); }); // push history window.history.pushState({}, "", url); bind(document.body); } function bind(content) { if (typeof(content) !== 'object' || content.nodeType !== Node.ELEMENT_NODE) return; content.querySelectorAll("a[href]").forEach(element => { if (element.href.includes("#")) return; if (!element.href.startsWith(window.location.origin)) return; const href = element.href.substring(window.location.origin.length); if (href.includes(".")) return; element.addEventListener("click", event => { event.preventDefault(); swap(element.href); }) }); content.querySelectorAll("[swap-url]").forEach(element => { const href = element.attributes.getNamedItem('swap-url').value; element.addEventListener("click", event => { event.preventDefault(); swap(href); }); }); } bind(document.body);