From 786c28ef0157a7e52e8c8424d2a906acec5566e6 Mon Sep 17 00:00:00 2001 From: Dakota Blair Date: Wed, 22 Jun 2022 20:14:26 -0400 Subject: [PATCH] Added title page. --- tilde.js | 22 ++++++++++---------- title.html | 45 ++++++++++++++++++++++++++++++++++++++++ title.js | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 title.html create mode 100644 title.js diff --git a/tilde.js b/tilde.js index cae0710..0aded5d 100644 --- a/tilde.js +++ b/tilde.js @@ -1,8 +1,8 @@ (() => { /* DOM */ - const ascii = document.getElementById('pref-ascii'); - const force = document.getElementById('pref-force'); - const themeRadios = document.getElementsByName('pref-theme'); + const ascii = document.getElementById("pref-ascii"); + const force = document.getElementById("pref-force"); + const themeRadios = document.getElementsByName("pref-theme"); const bodyClass = document.body.classList; /* localStorage management */ @@ -10,16 +10,16 @@ const getPref = (pref) => localStorage.getItem(lsn + pref); const setPref = (pref, value) => localStorage.setItem(lsn + pref, value); const getPrefs = () => ({ - prefASCII: getPref('ascii') === 'true', - prefForce: getPref('force') === 'true', - prefTheme: getPref('theme') || 'dark', + prefASCII: getPref("ascii") === "true", + prefForce: getPref("force") === "true", + prefTheme: getPref("theme") || "dark", }); /* Update the state of the document based on client preferences. */ const renderPreferences = () => { const { prefASCII, prefForce, prefTheme } = getPrefs(); if(prefASCII) { - bodyClass.add('ascii'); + bodyClass.add("ascii"); ascii.checked = "checked"; } if(prefForce) { @@ -37,8 +37,8 @@ /* ASCII aesthetic intensifies */ ascii.onchange = (evt) => { const { prefASCII } = getPrefs(); - bodyClass.toggle('ascii'); - setPref('ascii', (!prefASCII).toString()); + bodyClass.toggle("ascii"); + setPref("ascii", (!prefASCII).toString()); }; /* Manage theme forcing behavior */ @@ -50,13 +50,13 @@ if (nextForce) { bodyClass.add(prefTheme); } - setPref('force', nextForce.toString()) + setPref("force", nextForce.toString()) }; /* Manage theme selection */ themeRadios.forEach(radio => radio.onchange = () => { const { prefForce } = getPrefs(); - setPref('theme', radio.value); + setPref("theme", radio.value); if(prefForce) { themes.forEach(theme => bodyClass.remove(theme)); bodyClass.add(radio.value); diff --git a/title.html b/title.html new file mode 100644 index 0000000..2d6d088 --- /dev/null +++ b/title.html @@ -0,0 +1,45 @@ + + + + + + + + title + + +

title

+ + + diff --git a/title.js b/title.js new file mode 100644 index 0000000..5230511 --- /dev/null +++ b/title.js @@ -0,0 +1,61 @@ +(() => { + /* DOM */ + const bodyClass = document.body.classList + const entry = document.getElementsByTagName("textarea")[0] + const titleDOM = document.getElementsByTagName("h1")[0] + + /* localStorage management */ + const lsn = "~ddb:" // localStorage namespace + const getPref = (pref) => localStorage.getItem(lsn + pref) + const getPrefs = () => ({ + prefForce: getPref("force") === "true", + prefTheme: getPref("theme") || "dark", + }) + + /* Update the state of the document based on client preferences. */ + const renderPreferences = () => { + const { prefForce, prefTheme } = getPrefs() + if(prefForce) { + bodyClass.add(prefTheme) + } + } + renderPreferences() + + /* Display the title. */ + const setTitle = (title) => { + if(title) { + titleDOM.childNodes.forEach(child => child.remove()) + titleDOM.append(document.createTextNode(title)) + document.title = title + } + } + + /* Update title based on the document fragment. */ + const hashchangeHandler = () => { + const here = new URL(window.location.href) + const title = decodeURI(here.hash.slice(1)) + const updated = setTitle(title) + entry.value = title + } + + /* Update the title on page load */ + hashchangeHandler() + /* and any time the hash changes, eg. when using the back button. */ + addEventListener("hashchange", hashchangeHandler) + + /* Add a way to easily edit the title. */ + const checkKey = (evt) => { + const code = evt.code + if(code === "Escape") { + entry.classList.toggle("hidden") + const title = entry.value + setTitle(title) + if(entry.classList.contains("hidden")) { + const here = new URL(window.location.href) + here.hash = `#${encodeURI(title)}` + history.pushState({}, "", here) + } + } + } + document.addEventListener("keyup", checkKey) +})()