From 582447e02b381c98492316280b9246f5ba67b363 Mon Sep 17 00:00:00 2001
From: lqdev
Date: Tue, 22 Aug 2023 19:23:31 +0200
Subject: [PATCH] rework branches a bit to support saving
---
content/2023-08-20-under-construction.tree | 2 +-
content/about-treehouse.tree | 55 +++++++++++++------
content/about.tree | 8 +--
content/index.tree | 4 +-
crates/treehouse/src/html/tree.rs | 14 +++--
crates/treehouse/src/state.rs | 1 -
static/js/tree.js | 61 +++++++++++++++-------
template/tree.hbs | 13 +----
8 files changed, 99 insertions(+), 59 deletions(-)
diff --git a/content/2023-08-20-under-construction.tree b/content/2023-08-20-under-construction.tree
index 5fcaf6c..209f98f 100644
--- a/content/2023-08-20-under-construction.tree
+++ b/content/2023-08-20-under-construction.tree
@@ -1 +1 @@
-- section under construction. sorry! in the meantime, maybe you wanna read [my ramblings about the treehouse](#01H89RFHCQCD3E1XS5XAPW86J5)?
+- section under construction. sorry! in the meantime, maybe you wanna read [my ramblings about the treehouse][b:01H89RFHCQCD3E1XS5XAPW86J5]?
diff --git a/content/about-treehouse.tree b/content/about-treehouse.tree
index b0ce9b5..3625b33 100644
--- a/content/about-treehouse.tree
+++ b/content/about-treehouse.tree
@@ -136,8 +136,10 @@
% id = "01H89RFHCQ2GWJPTAKTRGS1QAC"
- weird poems and philosophical talk are over, it's time to focus on the tech.
+ - call this an overview, Defense of Design, or what have you
+
% id = "01H89RFHCQF4N9T05B9DVWX67K"
- - treehouse is built in the programming language that gives me the most pleasure while developing.
+ - treehouse is built in the programming language that gives me the most pleasure coding.
- no need for you to know more. :shhh:
@@ -149,10 +151,10 @@
- but being the altruist I am - don't worry, it _will_ be open source one day.
- in case you're reading this in the far future, and this is still here…
- you wouldn't mind [dropping me a line](#01H89P3CH8CD28KGX9GVRFK60E) would you?
+ you wouldn't mind [dropping me a line][b:01H89P3CH8CD28KGX9GVRFK60E] would you?
% id = "01H89RFHCQAQVXP6B2H0T8NNDS"
- - personally… the language you build a personal project in almost never matters. it's rather how you execute your ideas.
+ - personally… the language you build a personal project with almost never matters. it's rather how you execute your ideas.
+ therefore I find boasting that my project is powered by a `$LANGUAGE` or a `$FRAMEWORK` unnecessary.
@@ -162,7 +164,7 @@
- (yes, I know that website is super old, but I still find it incredibly funny :hueh:)
% id = "01H89RFHCQFWC2FWBAE9PVNC08"
- - as I alluded to [here](#01H89RFHCQ3EAP0F6PRSEK7S1T), treehouse is built to decay gracefully
+ - as I alluded to [here][b:01H89RFHCQ3EAP0F6PRSEK7S1T], treehouse is built to decay gracefully
as you take away the fancy parts.
- you will be able to read it just fine without JavaScript, just that it'll be a little
@@ -185,6 +187,14 @@
- if you have accessibility concerns about this decision, please let me know.
+ - it also saves your progress as you read. if you refresh the page, you'll notice you end up exactly where you left off!
+
+ - but, there is one very crucial piece of JavaScript that makes this website tick, and your experience **will be degraded** if you disable it. that feature is linking to branches.
+
+ - by default, if you link to an element by its id and it's contained within a ``, the `` will not expand. :ralsei_dead:
+
+ - therefore there's a bit of JS to make that work, _and_ to tie that together with lazy loading.
+
- treehouse will not work *as* fine without CSS though - the `` will look extremely
janky, but the content should still be fully readable.
@@ -193,20 +203,21 @@
- the structure of `.tree` files is extremely minimal. there are only a few syntactic features to speak of.
- here's a taste of `.tree`:
- ```
- \% id = "root"
- \- this is a branch
- \% id = "child"
- \- this is a child branch
+ - ```
+ \% id = "root"
+ \- this is a branch
- \+ this is a branch that is collapsed
+ \% id = "child"
+ \- this is a child branch
- \- and this is a child of that branch
+ \+ this is a branch that is collapsed
- \% content.link = "some-other-tree"
- \- and this branch links to another tree
- ```
+ \- and this is a child of that branch
+
+ \% content.link = "some-other-tree"
+ \- and this branch links to another tree
+ ```
- the `.tree` format is line-based. that means the `%`, `-`, and `+` tokens are only
interpreted when at the beginning of a line.
@@ -219,15 +230,15 @@
- …may or may not be expanded by default (this is the branch's _kind_) - that's what the minus `-` and plus `+` tokens do
- - …are sequenced like: optional attributes, kind, content
+ - each branch is constructed in this order: optional attributes, kind, content
- - …end when another line beginning with `%`, `-`, or `+` is found.
+ - and ends when another line beginning with `%`, `-`, or `+` is found.
- other than that, `.tree` assumes nothing about what format the branch attributes or content are encoded in.
- I chose TOML and Markdown for their ease of use and flexibility, but the parser couldn't care less.
- - …actually, that's a lie. see that code example above? Markdown code fences \`\`\` are handled specially to let you do that kind of stuff. that's all.
+ - …actually, that's a lie. see that code example above? Markdown code fences \`\`\` are handled specially to let embed `.tree` source code blocks within `.tree` files. that's all.
- you may have noticed in that code example above that almost every branch has an `id` attribute.
@@ -261,6 +272,16 @@
- which is cool because it's much denser while avoiding ambiguous characters - `0`, `O`, and `o` are all interpreted as `0` (zero).
+ - noticed how fast the treehouse restores your state? there's basically no delay.
+
+ - this is because it restores your state _as it's loading in_, by using [Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements).
+
+ - despite many people calling that API extremely low-level, I beg to differ. it's actually pretty easy and pleasant to use.
+
+ - most importantly it lets me enhance vanilla `` elements with custom behavior executed on load, which I use to restore your reading progress as the page is loading in.
+
+ - linked branches also use Web Components by the way.
+
- while not strictly a technical topic, I'd like to shout out [Recursive](https://recursive.design) for being an awesome font :ralsei_love:
- (not to be confused with Font Awesome, which I do not use here. icon designs are my own.)
diff --git a/content/about.tree b/content/about.tree
index 84fbd96..668a70d 100644
--- a/content/about.tree
+++ b/content/about.tree
@@ -97,10 +97,10 @@
- [DELTARUNE](https://deltarune.com)
% id = "01H89P3CH89TQ3SFG2Z40J29HX"
- - they're pretty great you should check them out (also check out [my games corner][page:/games]? :pleading_face:)
+ - they're pretty great you should check them out (also check out [my games corner][page:games]? :pleading_face:)
% id = "01H89P3CH8AJATQ5DJBBFXJ1NH"
- - or [music][page:/music]
+ - or [music][page:music]
% id = "01H89P3CH8XQ59YZD3RFRYQ2BM"
- various genres from electronic through jazz and even rock
@@ -153,7 +153,7 @@
- anyways you can find me on
% id = "01H89P3CH8EMM31JEMJRVRAKF4"
- + Discord - username is [this](#01H89P3CH8GAHS8DDW1HHEWA3P)
+ + Discord - username is [this][b:01H89P3CH8GAHS8DDW1HHEWA3P]
% id = "01H89P3CH89HHDVHGB9GE287TR"
- I'm most active there so you'll have the best chance of getting a reply
@@ -162,7 +162,7 @@
- you'll know it's me if you see a profile with a fluffy boy avatar
% id = "01H89P3CH8WTBKXP0GGN0HYQK2"
- + Matrix - username is [this](#01H89P3CH8943QGT52K7MRW12Q) at gacko.pl
+ + Matrix - username is [this][b:01H89P3CH8943QGT52K7MRW12Q] at gacko.pl
% id = "01H89P3CH832E4GK0NJ77KED06"
- I try to be as active there as on Discord but my availability may be a little more
diff --git a/content/index.tree b/content/index.tree
index 8c3198c..2e1aad9 100644
--- a/content/index.tree
+++ b/content/index.tree
@@ -3,11 +3,11 @@
- welcome! make yourself at home
- - this is my treehouse, the place on the Internet I like to call home.
+ ---
% id = "about"
content.link = "about"
- + ## about yourself
+ + ## about me
% id = "about-treehouse"
content.link = "about-treehouse"
diff --git a/crates/treehouse/src/html/tree.rs b/crates/treehouse/src/html/tree.rs
index c09f9d9..95a8835 100644
--- a/crates/treehouse/src/html/tree.rs
+++ b/crates/treehouse/src/html/tree.rs
@@ -31,17 +31,21 @@ pub fn branch_to_html(s: &mut String, treehouse: &mut Treehouse, file_id: FileId
);
let class = if has_children { "branch" } else { "leaf" };
+ let component = if let Content::Link(_) = attributes.content {
+ "th-b-linked"
+ } else {
+ "th-b"
+ };
+
let linked_branch = if let Content::Link(link) = &attributes.content {
- format!(
- " is=\"th-linked-branch\" data-th-link=\"{}\"",
- EscapeHtml(link)
- )
+ format!(" data-th-link=\"{}\"", EscapeHtml(link))
} else {
String::new()
};
+
write!(
s,
- "",
+ "",
EscapeAttribute(&id)
)
.unwrap();
diff --git a/crates/treehouse/src/state.rs b/crates/treehouse/src/state.rs
index 8defbea..f739862 100644
--- a/crates/treehouse/src/state.rs
+++ b/crates/treehouse/src/state.rs
@@ -6,7 +6,6 @@ use codespan_reporting::{
files::SimpleFiles,
term::termcolor::{ColorChoice, StandardStream},
};
-use log::debug;
use ulid::Ulid;
pub type Files = SimpleFiles;
diff --git a/static/js/tree.js b/static/js/tree.js
index 94f218f..68c3de8 100644
--- a/static/js/tree.js
+++ b/static/js/tree.js
@@ -1,13 +1,41 @@
-class LinkedBranch extends HTMLLIElement {
+const branchStateKey = "treehouse.openBranches";
+let branchState = JSON.parse(localStorage.getItem(branchStateKey)) || {};
+
+function saveBranchIsOpen(branchID, state) {
+ branchState[branchID] = state;
+ localStorage.setItem(branchStateKey, JSON.stringify(branchState));
+}
+
+function branchIsOpen(branchID) {
+ return branchState[branchID];
+}
+
+class Branch extends HTMLLIElement {
+ constructor() {
+ super();
+
+ this.details = this.childNodes[0];
+ this.innerUL = this.details.childNodes[1];
+
+ let isOpen = branchIsOpen(this.id);
+ if (isOpen !== undefined) {
+ this.details.open = isOpen;
+ }
+ this.details.addEventListener("toggle", _ => {
+ saveBranchIsOpen(this.id, this.details.open);
+ });
+ }
+}
+
+customElements.define("th-b", Branch, { extends: "li" });
+
+class LinkedBranch extends Branch {
constructor() {
super();
this.linkedTree = this.getAttribute("data-th-link");
- this.details = this.childNodes[0];
- this.innerUL = this.details.childNodes[1];
-
- this.state = "notloaded";
+ this.loadingState = "notloaded";
this.loadingText = document.createElement("p");
{
@@ -19,12 +47,13 @@ class LinkedBranch extends HTMLLIElement {
this.innerUL.appendChild(this.loadingText);
// This produces a warning during static generation but we still want to handle that
- // correctly. Having an expanded-by-default linked block can be useful in development.
+ // correctly, as Branch saves the state in localStorage. Having an expanded-by-default
+ // linked block can be useful in development.
if (this.details.open) {
this.loadTree();
}
- this.details.addEventListener("toggle", event => {
+ this.details.addEventListener("toggle", _ => {
if (this.details.open) {
this.loadTree();
}
@@ -32,8 +61,8 @@ class LinkedBranch extends HTMLLIElement {
}
loadTree() {
- if (this.state == "notloaded") {
- this.state = "loading";
+ if (this.loadingState == "notloaded") {
+ this.loadingState = "loading";
fetch(`/${this.linkedTree}.html`)
.then(response => {
@@ -46,26 +75,22 @@ class LinkedBranch extends HTMLLIElement {
let parser = new DOMParser();
let linkedDocument = parser.parseFromString(text, "text/html");
let main = linkedDocument.getElementsByTagName("main")[0];
- let ul /*: Element */ = main.getElementsByTagName("ul")[0];
- console.log(ul);
+ let ul = main.getElementsByTagName("ul")[0];
this.loadingText.remove();
+ this.innerUL.innerHTML = ul.innerHTML;
- for (let i = 0; i < ul.childNodes.length; ++i) {
- this.innerUL.appendChild(ul.childNodes[i]);
- }
-
- this.state = "loaded";
+ this.loadingState = "loaded";
})
.catch(error => {
this.loadingText.innerText = error.toString();
- this.state = "error";
+ this.loadingState = "error";
});
}
}
}
-customElements.define("th-linked-branch", LinkedBranch, { extends: "li" });
+customElements.define("th-b-linked", LinkedBranch, { extends: "li" });
function expandDetailsRecursively(element) {
while (element && element.tagName != "MAIN") {
diff --git a/template/tree.hbs b/template/tree.hbs
index 56f4cbb..61f24c4 100644
--- a/template/tree.hbs
+++ b/template/tree.hbs
@@ -33,18 +33,9 @@
miners.
if you don't believe me, you're free to inspect the source yourself! all the scripts are written
lovingly in vanilla JS (not minified!) by yours truly ❤️
- and if this box is annoying, feel free to zap it with uBlock Origin or something. I have no
+ and if this box is annoying, feel free to block it with uBlock Origin or something. I have no
way of remembering you closed it, and don't wanna host this site on a dynamic server.
-
- {{!--
- --}}
- {{!-- I disabled the button because I can't figure out a way to do this without storing a cookie, and I
- don't like those. I'd prefer if this website were fully static. --}}
-
+