mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2025-01-03 01:16:14 +03:00
Update beta index code.
This commit is contained in:
parent
cc78cb40c5
commit
4b30a4b4bb
@ -3,17 +3,44 @@
|
||||
import { Elm } from "/main.js";
|
||||
// const pagesInit = require("../../index.js");
|
||||
|
||||
pagesInit({
|
||||
mainElmModule: Elm.Main,
|
||||
});
|
||||
let prefetchedPages;
|
||||
let initialLocationHash;
|
||||
let elmViewRendered = false;
|
||||
let headTagsAdded = false;
|
||||
|
||||
function pagesInit(config) {
|
||||
function pagesInit(
|
||||
/** @type { mainElmModule: { init: any } } */ { mainElmModule }
|
||||
) {
|
||||
prefetchedPages = [window.location.pathname];
|
||||
initialLocationHash = document.location.hash.replace(/^#/, "");
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
document.addEventListener("DOMContentLoaded", (_) => {
|
||||
new MutationObserver(function () {
|
||||
elmViewRendered = true;
|
||||
if (headTagsAdded) {
|
||||
document.dispatchEvent(new Event("prerender-trigger"));
|
||||
}
|
||||
}).observe(document.body, {
|
||||
attributes: true,
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
|
||||
loadContentAndInitializeApp(mainElmModule).then(resolve, reject);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function loadContentAndInitializeApp(
|
||||
/** @type { init: any } */ mainElmModule
|
||||
) {
|
||||
const path = window.location.pathname.replace(/(\w)$/, "$1/");
|
||||
|
||||
httpGet(`${window.location.origin}${path}content.json`).then(function (
|
||||
/** @type {JSON} */ contentJson
|
||||
) {
|
||||
const app = config.mainElmModule.init({
|
||||
return Promise.all([
|
||||
httpGet(`${window.location.origin}${path}content.json`),
|
||||
]).then(function (/** @type {[JSON]} */ [contentJson]) {
|
||||
const app = mainElmModule.init({
|
||||
flags: {
|
||||
secrets: null,
|
||||
baseUrl: document.baseURI,
|
||||
@ -23,9 +50,106 @@ function pagesInit(config) {
|
||||
contentJson,
|
||||
},
|
||||
});
|
||||
|
||||
app.ports.toJsPort.subscribe((
|
||||
/** @type { { allRoutes: string[] } } */ fromElm
|
||||
) => {
|
||||
window.allRoutes = fromElm.allRoutes.map(
|
||||
(route) => new URL(route, document.baseURI).href
|
||||
);
|
||||
|
||||
setupLinkPrefetching();
|
||||
});
|
||||
|
||||
return app;
|
||||
});
|
||||
}
|
||||
|
||||
function setupLinkPrefetching() {
|
||||
new MutationObserver(observeFirstRender).observe(document.body, {
|
||||
attributes: true,
|
||||
childList: true,
|
||||
subtree: true,
|
||||
});
|
||||
}
|
||||
|
||||
function loadNamedAnchor() {
|
||||
if (initialLocationHash !== "") {
|
||||
const namedAnchor = document.querySelector(`[name=${initialLocationHash}]`);
|
||||
namedAnchor && namedAnchor.scrollIntoView();
|
||||
}
|
||||
}
|
||||
|
||||
function observeFirstRender(
|
||||
/** @type {MutationRecord[]} */ mutationList,
|
||||
/** @type {MutationObserver} */ firstRenderObserver
|
||||
) {
|
||||
loadNamedAnchor();
|
||||
for (let mutation of mutationList) {
|
||||
if (mutation.type === "childList") {
|
||||
setupLinkPrefetchingHelp();
|
||||
}
|
||||
}
|
||||
firstRenderObserver.disconnect();
|
||||
new MutationObserver(observeUrlChanges).observe(document.body.children[0], {
|
||||
attributes: true,
|
||||
childList: false,
|
||||
subtree: false,
|
||||
});
|
||||
}
|
||||
|
||||
function observeUrlChanges(
|
||||
/** @type {MutationRecord[]} */ mutationList,
|
||||
/** @type {MutationObserver} */ _theObserver
|
||||
) {
|
||||
for (let mutation of mutationList) {
|
||||
if (
|
||||
mutation.type === "attributes" &&
|
||||
mutation.attributeName === "data-url"
|
||||
) {
|
||||
setupLinkPrefetchingHelp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setupLinkPrefetchingHelp(
|
||||
/** @type {MutationObserver} */ _mutationList,
|
||||
/** @type {MutationObserver} */ _theObserver
|
||||
) {
|
||||
const links = document.querySelectorAll("a");
|
||||
links.forEach((link) => {
|
||||
// console.log(link.pathname);
|
||||
link.addEventListener("mouseenter", function (event) {
|
||||
if (event && event.target && event.target instanceof HTMLAnchorElement) {
|
||||
prefetchIfNeeded(event.target);
|
||||
} else {
|
||||
// console.log("Couldn't prefetch with event", event);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function prefetchIfNeeded(/** @type {HTMLAnchorElement} */ target) {
|
||||
if (target.host === window.location.host) {
|
||||
if (prefetchedPages.includes(target.pathname)) {
|
||||
// console.log("Already preloaded", target.href);
|
||||
// console.log("Not a known route, skipping preload", target.pathname);
|
||||
} else if (
|
||||
!allRoutes.includes(new URL(target.pathname, document.baseURI).href)
|
||||
) {
|
||||
} else {
|
||||
prefetchedPages.push(target.pathname);
|
||||
// console.log("Preloading...", target.pathname);
|
||||
const link = document.createElement("link");
|
||||
link.setAttribute("as", "fetch");
|
||||
|
||||
link.setAttribute("rel", "prefetch");
|
||||
link.setAttribute("href", origin + target.pathname + "/content.json");
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function httpGet(/** @type string */ theUrl) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
const xmlHttp = new XMLHttpRequest();
|
||||
@ -38,3 +162,39 @@ function httpGet(/** @type string */ theUrl) {
|
||||
xmlHttp.send(null);
|
||||
});
|
||||
}
|
||||
|
||||
pagesInit({
|
||||
mainElmModule: Elm.Main,
|
||||
});
|
||||
|
||||
// function pagesInit(config) {
|
||||
// const path = window.location.pathname.replace(/(\w)$/, "$1/");
|
||||
|
||||
// httpGet(`${window.location.origin}${path}content.json`).then(function (
|
||||
// /** @type {JSON} */ contentJson
|
||||
// ) {
|
||||
// const app = config.mainElmModule.init({
|
||||
// flags: {
|
||||
// secrets: null,
|
||||
// baseUrl: document.baseURI,
|
||||
// isPrerendering: false,
|
||||
// isDevServer: false,
|
||||
// isElmDebugMode: false,
|
||||
// contentJson,
|
||||
// },
|
||||
// });
|
||||
// });
|
||||
// }
|
||||
|
||||
// function httpGet(/** @type string */ theUrl) {
|
||||
// return new Promise(function (resolve, reject) {
|
||||
// const xmlHttp = new XMLHttpRequest();
|
||||
// xmlHttp.onreadystatechange = function () {
|
||||
// if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
|
||||
// resolve(JSON.parse(xmlHttp.responseText));
|
||||
// };
|
||||
// xmlHttp.onerror = reject;
|
||||
// xmlHttp.open("GET", theUrl, true); // true for asynchronous
|
||||
// xmlHttp.send(null);
|
||||
// });
|
||||
// }
|
||||
|
Loading…
Reference in New Issue
Block a user