feat: handle local urls
feat: debug mode (auto-refreshes pages) fix: date ordering feat: add poor person's jQuery improvement: rename startLoading to showLoadingOverlay fix: do not load initial page twice improvement: allow arbitrary spaces between filename and date in files.txt
This commit is contained in:
parent
7fba4dbbd6
commit
b03ddcb428
@ -1 +1,2 @@
|
|||||||
readme.md 2022-03-03 Tickle
|
readme.md 2022-28-06 Tickle
|
||||||
|
examples.md 2022-28-06 Examples
|
71
index.html
71
index.html
@ -153,12 +153,47 @@
|
|||||||
<main id="Body"></main>
|
<main id="Body"></main>
|
||||||
<div id="Loading"></div>
|
<div id="Loading"></div>
|
||||||
<script type="module">
|
<script type="module">
|
||||||
|
//@ts-check
|
||||||
|
|
||||||
|
const is_debug_mode = /^localhost|127.0.0.1/.test(
|
||||||
|
window.location.hostname
|
||||||
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* markdown parser. Remove if you don't use markdown
|
* markdown parser. Remove if you don't use markdown
|
||||||
*/
|
*/
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import { micromark } from "https://esm.sh/micromark@3?bundle";
|
import { micromark } from "https://esm.sh/micromark@3?bundle";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A small utility to query elements and get back an array
|
||||||
|
*/
|
||||||
|
const $ = (parent, selector) => [
|
||||||
|
...(!selector
|
||||||
|
? document.querySelectorAll(parent)
|
||||||
|
: parent.querySelectorAll(selector)),
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assumes a provided url is external if it begins by a known protocol
|
||||||
|
* @param {string} url
|
||||||
|
*/
|
||||||
|
const isExternal = (url) =>
|
||||||
|
/^(https?|mailto|tel|ftp|ipfs|dat):/.test(url);
|
||||||
|
|
||||||
|
const rewriteLocalUrls = (container) => {
|
||||||
|
$(container, "a").forEach((a) => {
|
||||||
|
const href = a.getAttribute("href");
|
||||||
|
if (href && !isExternal(href)) {
|
||||||
|
console.log({ href });
|
||||||
|
const rewrittenHref = "#/" + href.replace(/^\.?\//, "");
|
||||||
|
a.setAttribute("href", rewrittenHref);
|
||||||
|
console.log(a);
|
||||||
|
console.log(rewrittenHref);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* useful to check for transitions while developing styles, if the loading screen disappears too fast
|
* useful to check for transitions while developing styles, if the loading screen disappears too fast
|
||||||
*
|
*
|
||||||
@ -177,10 +212,12 @@
|
|||||||
*/
|
*/
|
||||||
const mainTitle = document.title;
|
const mainTitle = document.title;
|
||||||
|
|
||||||
const startLoading = () => document.body.classList.add("is-loading");
|
const showLoadingOverlay = () =>
|
||||||
const stopLoading = () => document.body.classList.remove("is-loading");
|
document.body.classList.add("is-loading");
|
||||||
|
const hideLoadingOverlay = () =>
|
||||||
|
document.body.classList.remove("is-loading");
|
||||||
|
|
||||||
const getCurrentPage = () => {
|
const getCurrentHashUrl = () => {
|
||||||
const [path, searchStr] = (
|
const [path, searchStr] = (
|
||||||
window.location.hash[1] === "/" ? window.location.hash.slice(2) : ""
|
window.location.hash[1] === "/" ? window.location.hash.slice(2) : ""
|
||||||
).split("?");
|
).split("?");
|
||||||
@ -189,12 +226,14 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onHashChange = (evt) => {
|
const onHashChange = (evt) => {
|
||||||
const { path, params } = getCurrentPage();
|
const { path, params } = getCurrentHashUrl();
|
||||||
if (!path) {
|
if (!path) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
startLoading();
|
showLoadingOverlay();
|
||||||
return fetch(`./${path}`)
|
return fetch(
|
||||||
|
is_debug_mode ? `./${path}?rand=${Math.random()}` : `./${path}`
|
||||||
|
)
|
||||||
.then((response) => response.text())
|
.then((response) => response.text())
|
||||||
.then(wait)
|
.then(wait)
|
||||||
.then((text) => {
|
.then((text) => {
|
||||||
@ -205,8 +244,9 @@
|
|||||||
Body.innerHTML = `<pre>${text}</pre>`;
|
Body.innerHTML = `<pre>${text}</pre>`;
|
||||||
} else {
|
} else {
|
||||||
Body.innerHTML = micromark(text);
|
Body.innerHTML = micromark(text);
|
||||||
|
rewriteLocalUrls(Body);
|
||||||
}
|
}
|
||||||
stopLoading();
|
hideLoadingOverlay();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -216,7 +256,8 @@
|
|||||||
* Loads the article list, parses it, creates the menu items
|
* Loads the article list, parses it, creates the menu items
|
||||||
*/
|
*/
|
||||||
const start = () => {
|
const start = () => {
|
||||||
startLoading();
|
let hasAutoloadedFirstPage = false;
|
||||||
|
showLoadingOverlay();
|
||||||
fetch("./files.txt")
|
fetch("./files.txt")
|
||||||
.then((response) => response.text())
|
.then((response) => response.text())
|
||||||
.then((lines) => {
|
.then((lines) => {
|
||||||
@ -225,7 +266,7 @@
|
|||||||
.map((line, index) => {
|
.map((line, index) => {
|
||||||
const today = new Date().toISOString().split("T")[0];
|
const today = new Date().toISOString().split("T")[0];
|
||||||
const result = line.match(
|
const result = line.match(
|
||||||
/(?<name>.+)\.(?<ext>\w{2,3})(?:\s(?<date>[\d-]+)?(?<title>.+))?/
|
/(?<name>.+)\.(?<ext>\w{2,3})(?:\s+(?<date>[\d-]+)?(?<title>.+))?/
|
||||||
);
|
);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
console.log(`could not parse line ${index}: [${line}]`);
|
console.log(`could not parse line ${index}: [${line}]`);
|
||||||
@ -235,20 +276,22 @@
|
|||||||
groups: { name, ext, date = today, title = name },
|
groups: { name, ext, date = today, title = name },
|
||||||
} = result;
|
} = result;
|
||||||
const href = `/${name}.${ext}`;
|
const href = `/${name}.${ext}`;
|
||||||
if (!getCurrentPage().path) {
|
if (!getCurrentHashUrl().path) {
|
||||||
|
hasAutoloadedFirstPage = true;
|
||||||
window.location.hash = `#${href}`;
|
window.location.hash = `#${href}`;
|
||||||
}
|
}
|
||||||
console.log({ name, href, date, title });
|
const date_unix = new Date(date).getTime();
|
||||||
return { name, href, date, title };
|
return { name, href, date, title, date_unix };
|
||||||
})
|
})
|
||||||
.filter(Boolean)
|
.filter(Boolean)
|
||||||
.sort(({ date: a }, { date: b }) => a - b)
|
.sort(({ date_unix: a }, { date_unix: b }) => a - b)
|
||||||
.map(
|
.map(
|
||||||
({ href, title }) => `<a data-link href="#${href}">${title}</a>`
|
({ href, title }) => `<a data-link href="#${href}">${title}</a>`
|
||||||
)
|
)
|
||||||
.join(`\n`);
|
.join(`\n`);
|
||||||
|
if (!hasAutoloadedFirstPage) {
|
||||||
onHashChange();
|
onHashChange();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ We have a [neat little UI to help you do all of that](https://git.poto.cafe/yagi
|
|||||||
|
|
||||||
Here are more detailed explanations, for different knowledge levels.
|
Here are more detailed explanations, for different knowledge levels.
|
||||||
|
|
||||||
- [I do not care about tech stuff, I just want to publish](/#/tutorial-publishers.md)
|
- [I do not care about tech stuff, I just want to publish](tutorial-publishers.md)
|
||||||
- [I can write some code, give me detailed explanations](/#/tutorial-hackers.md)
|
- [I can write some code, give me detailed explanations](tutorial-hackers.md)
|
||||||
|
|
||||||
It's important to know that Tickle is an *idea*. Think of it as a specification. We have a few examples listed [here](examples.md)
|
It's important to know that Tickle is an *idea*. Think of it as a specification. We have a few examples listed [here](examples.md)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user