From 4cf095cf40353c14ecdfd715d88ae56a6cd961b2 Mon Sep 17 00:00:00 2001 From: Chunkybanana Date: Thu, 19 Dec 2024 21:39:16 +1300 Subject: [PATCH] _now_ it should actually work --- events.js | 72 ++++++++++++------------ helper.js | 79 +++++++++++++-------------- index.html | 158 +++++++++++++++++++++++++++++------------------------ 3 files changed, 162 insertions(+), 147 deletions(-) diff --git a/events.js b/events.js index d88a17b..1a7dcc1 100644 --- a/events.js +++ b/events.js @@ -1,6 +1,6 @@ -var worker = {"postMessage": function(a) {}}; -var page, q = "", res = []; -window.addEventListener("scroll", function(e) { +var worker = { postMessage() { } }; +var page, res = []; +window.addEventListener("scroll", function (e) { if (window.innerHeight + window.scrollY >= document.body.scrollHeight - 100) { page++; load(res, page); @@ -13,45 +13,47 @@ function checkLength() { } } function clearRes() { + res = null; [`res`, `len`, `bottom`].forEach(x => $(x).innerHTML = ""); } -function redirect() { - var v = "?"; - if (q) v += "&q=" + encodeURIComponent(q); - v = v.replace(/\?&/g, "?").replace(/[?&]+$/, ""); - window.history.pushState(null, null, window.location.href.split("?")[0] + v); + +function navigate(q, push_state = true, is_search = false) { + clearRes(); + if (!is_search) $`search`.value = q; + + if (q == '') { + page = 0; + return + } + + let newLink = window.location.href.split("?")[0] + (q ? "?q=" + encodeURIComponent(q) : '') + if (push_state) { + window.history.pushState('', '', newLink) + } else { + window.history.replaceState('', '', newLink) + } + + $`bottom`.innerHTML = "chum lao jí pó jóaıse" + worker.postMessage({ q }) } -var timer; -$`search`.addEventListener("input", function() { + +let timer; +$`search`.addEventListener("input", function () { clearTimeout(timer); - q = $`search`.value.trim(); - res = null; clearRes(); - redirect(); - $`bottom`.innerHTML = "chum lao jí pó jóaıse" - timer = setTimeout(function() { - if (q.length) { - worker.postMessage({"q": q}) - } else { - res = null; - clearRes(); - page = 0; - } - }, 100); + timer = setTimeout(() => { + navigate(this.value.trim(), false, true); + }, 100) }); -$`clear`.addEventListener("click", function() { - $`search`.value = ""; +$`clear`.addEventListener("click", function () { $`search`.focus(); - dispatchSearch(); + navigate("", false); }); -$`english`.addEventListener("click", function() { - $`search`.value = - $`search`.value.split(" ") - .filter(t => !/^([!-]|not:)*(\$|scope:)/.test(t)) - .concat(["$en"]).join(" ").trim(); +$`english`.addEventListener("click", function () { + let newQuery = + $`search`.value.split(" ") + .filter(t => !/^([!-]|not:)*(\$|scope:)/.test(t)) + .concat(["$en"]).join(" ").trim(); $`search`.focus(); - dispatchSearch(); + navigate(newQuery, false); }); -function dispatchSearch() { - $`search`.dispatchEvent(new Event("input", {"bubbles": true})); -} diff --git a/helper.js b/helper.js index 402ac07..4376458 100644 --- a/helper.js +++ b/helper.js @@ -10,74 +10,73 @@ function mkel(tag, props, children) { } return element; } + function htmlify(json) { - const entry = - mkel("div", {"className": "entry"}, [ + return mkel("div", { "className": "entry" }, [ mkel("dt", {}, [ json.warn ? mkel("span", {}, "⚠\ufe0f ") : null, mkel("a", { "className": "toa", - "href": "?q=" + encodeURIComponent(json.head) + onclick() { navigate(json.head) } }, [json.head]), " • ", mkel("a", { "className": "scope", - "href": "?q=" + encodeURIComponent("scope:" + json.scope) + onclick() { navigate("scope:" + json.scope) } }, [json.scope]), " ", - mkel("a", {"href": "?q=" + encodeURIComponent("@" + json.user)}, [json.user]), + mkel("a", { onclick() { navigate("@" + json.user) } }, [json.user]), " ", - mkel("span", {"className": "score"}, [ + mkel("span", { "className": "score" }, [ ("" + json.score).replace(/^0$/, "±").replace(/^(\d)/, "+$1") ]), " • ", - mkel("a", {"href": "?q=" + encodeURIComponent("#" + json.id)}, [json.date.slice(0, 10)]), + mkel("a", { onclick() { navigate("#" + json.id) } }, [json.date.slice(0, 10)]), " ", - mkel("a", {"href": "https://toadua.uakci.space/#" + encodeURIComponent("#" + json.id)}, ["↗"]), + mkel("a", { "href": "https://toadua.uakci.space/#" + encodeURIComponent("#" + json.id) }, ["↗"]), ]), mkel("dd", {}, replaceLinks(json.body)), - mkel("div", {"className": "notes indent"}, json.notes.map(note => [ - mkel("span", {"className": "score"}, [ - mkel("a", {"href": "?q=" + encodeURIComponent("@" + note.user)}, [note.user]), + mkel("div", { "className": "notes indent" }, json.notes.flatMap(note => [ + mkel("span", { "className": "score" }, [ + mkel("a", { onclick() { navigate("@" + note.user) } }, [note.user]), ": " ]), mkel("span", {}, replaceLinks(note.content)), " ", - mkel("span", {"className": "scope"}, [/^\d/.test(note.date) ? note.date.slice(0, 10) : new Date(note.date).toISOString().slice(0, 10)]), + mkel("span", { "className": "scope" }, [/^\d/.test(note.date) ? note.date.slice(0, 10) : new Date(note.date).toISOString().slice(0, 10)]), mkel("br", {}, []) - ]).flat(Infinity)) + ])) ]); - return entry; } +/* + - replace **word** with a link to said word + - replace https://example.com with a link to said URL + - replace #ID with a link to said ID + - replace with a link to the query stuff [???] + */ +// just me trying to figure out how this works +// i'll probably replace this with a more descriptive one once things work again + function replaceLinks(str) { // ugh why isn't /u a default regex flag - var bits = str - .replace(/\*\*/g, "📦") - .replace(/https?:\/\/([a-z0-9./#%?=&_:()'-]+)/giu, "🌐$1🌐") - .replace(/(?]+(?(?!.+<\/\1>)/giu, "📎$1📎") - .split(/(?=[📦🆔🌐📎])/u); - for (var i = 0; i < bits.length; i++) { - if (i == 0) continue; - if ([...bits[i]][0] === [...bits[i - 1]][0] && "📦🆔🌐📎".includes([...bits[i]][0])) { - bits[i] = bits[i].replace(/^[📦🆔🌐📎]/u, ""); - var hrefprefix = bits[i - 1].startsWith("📦") ? "?q=%3D" : bits[i - 1].startsWith("🆔") ? "?q=%23" : bits[i - 1].startsWith("📎") ? "?q=" : "https://"; - var textprefix = bits[i - 1].startsWith("📦") || bits[i - 1].startsWith("📎") ? "" : bits[i - 1].startsWith("🆔") ? "#" : "https://"; - if (i >= 2 && bits[i - 1].startsWith("🌐") && bits[i - 1].endsWith(")") && bits[i - 2].endsWith("(")) { - bits[i - 1] = bits[i - 1].replace(/\)$/, ""); - bits[i] = ")" + bits[i]; - } - var href = bits[i - 1].replace(/^[📦🆔🌐📎]/u, ""); - if (bits[i - 1].startsWith("📦")) { - href = href.replace(/ /g, "|"); - } - bits[i - 1] = mkel("a", { - "href": hrefprefix + (hrefprefix != "https://" ? encodeURIComponent : (x) => x)(href) - }, [bits[i - 1].replace(/^[📦🆔🌐📎]/u, textprefix)]) + let parts = str + .replace(/\*\*/g, "📦") + .replace(/https?:\/\/([a-z0-9./#%?=&_:'-]+)/giu, "🌐$1🌐") + .replace(/(?]+(?(?!.+<\/\1>)/giu, "📎$1📎") + .match(/([📦🆔🌐📎]).*?\1|[^📦🆔🌐📎]+/ug); + + return parts.map(part => { + part = [...part]; + let head = part[0], body = part.slice(1, -1).join("") + if (!"📦🆔🌐📎".includes(head)) return part.join("") + if (head === "🌐") { + return mkel("a", { href: body }, [body]); } - } - return bits; + let search = head === '📦' ? '=' + body.replace(/ /g, '|') : body; + return mkel("a", { onclick() { navigate(search) } }, [body]); + }) } function load(res, page) { @@ -91,4 +90,4 @@ function load(res, page) { } } $`res`.append(...nodes); -} \ No newline at end of file +} diff --git a/index.html b/index.html index 33e348e..7e1f866 100644 --- a/index.html +++ b/index.html @@ -1,82 +1,96 @@ - - mí soakue - - - - - - - - -

mí soakue / 󱛘󱚰󱛊󱚹󱛛󱛓󱚺󱛃󱛍󱚺󱛄󱚲󱛍󱚴󱛓󱛙

-

github

- - - - - - -
-
-
-

about

-

this updates every day. it used to update every 6 hours, but github actions scheduling is not very precise.

-

the fonts here are mostly in Noto, except the font for Tangut (which is by BabelStone) and the Deranı one (Iosevka modified by Laqme+Kıa).

-

kuaq kıe jí mí Sofıa lä soa muoja já ka :3

-

operators

-

= head searches just the words themselves. there are a couple fancy things you can do with this:

-

+ + + mí soakue + + + + + + + + + +

mí soakue / 󱛘󱚰󱛊󱚹󱛛󱛓󱚺󱛃󱛍󱚺󱛄󱚲󱛍󱚴󱛓󱛙

+

github

+ + + + + + +
+
+
+

about

+

this updates every day. it used to update every 6 hours, but github actions scheduling is not very precise. +

+

the fonts here are mostly in Noto, except the font for Tangut (which is by BabelStone) and the Deranı one + (Iosevka modified by Laqme+Kıa).

+

kuaq kıe jí mí Sofıa lä soa muoja já ka :3

+

operators

+

= head searches just the words themselves. there are a couple fancy things you can do with this: +

+
+

* matches anything (or nothing, i.e. it's /.*/)
? matches any single letter, /[aeıoumpbfntdczsrljꝡqkg'h]|[ncs]h/i
- CVFQ match their refgram definitions (note that VV ⊋ F)
+ CVFQ match their refgram definitions (note + that VV ⊋ F)
R matches a raku
_ matches a space
- ()[]| work like in regex -

-

+ ()[]| work like in regex +

+
+
+

iı, vw, x'
.◌̣
1234◌̀◌́◌̈◌̂ -

-

~ is similar but will also match word-internally: ~◌ = =*◌*

-

@ user searches word authors

-

# id finds the word with id x

-

/ arity finds definitions with x slots

-

$ scope shows words defined under a particular language code

-

! - not negate a query, e.g. -@official

-

^ score finds definitions with at least +x votes. you can do !^ for less than x, and ^= for exactly x.

-

things you can't do here

-

anything that requires logging in

+

- - - - - - +

~ is similar but will also match word-internally: ~◌ = =*◌*

+

@ user searches word authors

+

# id finds the word with id x

+

/ arity finds definitions with x slots

+

$ scope shows words defined under a particular language code

+

! - not negate a query, e.g. -@official

+

^ score finds definitions with at least +x votes. you can do !^ for less + than x, and ^= for exactly x.

+

things you can't do here

+

anything that requires logging in

+
+ + + + + + + \ No newline at end of file