5 body{ Display: Grid; Box-Sizing: Border-Box; Margin: Auto; Padding-Inline:
1REM; Min-Block-Size:
100VH; Inline-Size:
100%; Max-Inline-Size:
45REM; Align-Content: Center; Justify-Content: Stretch; Font-Family: Sans-Serif }
6 article{ Font-Size: Larger }
7 summary{ Padding-Block:
1REM; Font-Weight: Bold }
8 details[open]
>summary{ Border-Block-End: Thin Solid }
9 footer{ Border-Block-Start: Thin Solid; Padding-Block:
1REM; Text-Align: End }
10 footer p{ Margin-Block:
0 .5REM }
11 footer time:Not([datetime]),
12 footer small{ Font-Size: Inherit; Font-Style: Italic }
16 const parser = new DOMParser
17 fetch(`${new URL(
".", location).toString().slice(
0, -
1)}.jsonld`)
20 const { items } = meta
21 const n = items.findIndex($ =
> new URL($[
"@id"]).pathname === location.pathname)
22 const status = items[n]
23 const src = status.content
24 const { documentElement: article } = parser.parseFromString(src,
"application/xhtml+xml")
25 const { creator, created, title } = status
26 document.title = creator
27 ? `Status by ${creator.name} @ ${status.created}`
28 : `Status @ ${created}`
29 const footer = document.createElement(
"footer")
30 const authorshipP = footer.appendChild(document.createElement(
"p"))
32 const authorLink = authorshipP.appendChild(document.createElement(
"a"))
33 authorLink.href = creator[
"@id"]
34 authorLink.textContent = creator.name
35 authorshipP.appendChild(document.createTextNode(
" @ ")) }
36 authorshipP.appendChild(document.createElement(
"time")).textContent = created
38 .appendChild(document.createElement(
"p"))
39 .appendChild(document.createElement(
"small"))
40 .textContent = status.identifier
41 const nav = footer.appendChild(document.createElement(
"nav"))
42 nav.appendChild(document.createTextNode(
"Up: "))
43 const upLink = nav.appendChild(document.createElement(
"a"))
44 upLink.href = meta[
"@id"]
45 upLink.textContent = meta.subject || meta[
"@id"].split(
"/").pop()
47 nav.appendChild(document.createTextNode(
"; Previous: "))
48 const prevLink = nav.appendChild(document.createElement(
"a"))
49 prevLink.href = items[n -
1][
"@id"]
50 const prevText = (() =
> {
52 const prevD = parser.parseFromString(items[n -
1].content,
"application/xhtml+xml")
53 const div = document.createElement(
"div")
54 div.appendChild(document.importNode(prevD.documentElement, true))
55 Object.assign(div.style,
56 { position:
"absolute"
60 , overflow:
"hidden" })
61 document.body.appendChild(div)
62 const text = div.innerText
63 document.body.removeChild(div)
65 catch { } })() ?? items[n +
1].created;
66 const prevChars = Array.from(prevText.trim().replaceAll(/\s+/gu,
" "))
67 prevLink.textContent = prevChars.length
> 28
68 ?
"".concat(...prevChars.slice(
0,
27),
"…")
70 if (n < items.length -
1) {
71 nav.appendChild(document.createTextNode(
"; Next: "))
72 const nextLink = nav.appendChild(document.createElement(
"a"))
73 nextLink.href = items[n +
1][
"@id"]
74 const nextText = (() =
> {
76 const nextD = parser.parseFromString(items[n +
1].content,
"application/xhtml+xml")
77 const div = document.createElement(
"div")
78 div.appendChild(document.importNode(nextD.documentElement, true))
79 Object.assign(div.style,
80 { position:
"absolute"
84 , overflow:
"hidden" })
85 document.body.appendChild(div)
86 const text = div.innerText
87 document.body.removeChild(div)
89 catch { } })() ?? items[n +
1].created;
90 const nextChars = Array.from(nextText.trim().replaceAll(/\s+/gu,
" "))
91 nextLink.textContent = nextChars.length
> 28
92 ?
"".concat(...nextChars.slice(
0,
27),
"…")
94 nav.appendChild(document.createTextNode(
"."))
96 const wrapper = document.createElement(
"article")
97 const details = wrapper.appendChild(document.createElement(
"details"))
98 details.setAttribute(
"open",
"")
99 const summary = details.appendChild(document.createElement(
"summary"))
100 summary.textContent = title
101 details.append(...document.importNode(article, true).childNodes)
102 document.body.replaceChildren(wrapper, footer) }
103 else document.body.replaceChildren(document.importNode(article, true), footer) })