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:
		| @@ -1 +1,2 @@ | |||||||
| readme.md 2022-03-03 Tickle | readme.md   2022-28-06 Tickle | ||||||
|  | examples.md 2022-28-06 Examples | ||||||
							
								
								
									
										73
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										73
									
								
								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) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user