aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile177
-rw-r--r--assets/css/default-fast.css5
-rw-r--r--assets/css/default-mathml.css26
-rw-r--r--assets/css/default-simple.css77
-rw-r--r--assets/css/default-syntax.css (renamed from assets/css/syntax-highlight-default.css)83
-rw-r--r--assets/css/default.css1445
-rw-r--r--assets/data/media/logo.pngbin170667 -> 9839 bytes
-rw-r--r--assets/js/index.js1200
-rw-r--r--assets/templates/markdown-feed.yaml17
-rw-r--r--config.json112
-rw-r--r--config.toml124
-rw-r--r--config.yaml92
-rw-r--r--content/canory/media/2city12p.pdfbin0 -> 1316140 bytes
-rw-r--r--content/canory/messages/animations.md1
-rw-r--r--content/canory/messages/cache.md1
-rw-r--r--content/canory/messages/code.md1
-rw-r--r--content/canory/messages/definitions.md1
-rw-r--r--content/canory/messages/diagrams.md3
-rw-r--r--content/canory/messages/disclosure.md32
-rw-r--r--content/canory/messages/drafts.md1
-rw-r--r--content/canory/messages/gates.md1
-rw-r--r--content/canory/messages/highlighting.md1
-rw-r--r--content/canory/messages/hugo.md1
-rw-r--r--content/canory/messages/imgur-video.md3
-rw-r--r--content/canory/messages/links.md1
-rw-r--r--content/canory/messages/lists.md10
-rw-r--r--content/canory/messages/markdown.md1
-rw-r--r--content/canory/messages/math.md93
-rw-r--r--content/canory/messages/odysee.md1
-rw-r--r--content/canory/messages/pdf.md7
-rw-r--r--content/canory/messages/pinned.md3
-rw-r--r--content/canory/messages/plumbing.md1
-rw-r--r--content/canory/messages/self.md3
-rw-r--r--content/canory/messages/selfdestruct.md6
-rw-r--r--content/canory/messages/selfdestructed.md1
-rw-r--r--content/canory/messages/styles.md1
-rw-r--r--content/canory/messages/tables.md1
-rw-r--r--content/canory/messages/tasks.md1
-rw-r--r--content/canory/messages/unlisted.md1
-rw-r--r--content/canory/messages/unsafe.md1
-rw-r--r--content/canory/messages/videos.md1
-rw-r--r--content/canory/messages/wikipedia.md1
-rw-r--r--content/canory/messages/xkcd.md1
-rw-r--r--content/canory/messages/youtube.md1
-rw-r--r--content/default/messages/authors.md3
-rw-r--r--content/default/messages/quickstart.md4
-rw-r--r--data/authors/canory.yaml (renamed from data/canory.yaml)5
-rw-r--r--data/authors/default.yaml (renamed from data/default.yaml)6
-rw-r--r--shell.nix29
-rw-r--r--static/icons/feather/LICENSE4
-rw-r--r--static/icons/feather/alert-circle.svg37
-rw-r--r--static/icons/feather/archive.svg15
-rw-r--r--static/icons/feather/arrow-down-circle.svg34
-rw-r--r--static/icons/feather/arrow-left.svg29
-rw-r--r--static/icons/feather/arrow-right.svg29
-rw-r--r--static/icons/feather/arrow-up.svg29
-rw-r--r--static/icons/feather/at-sign.svg28
-rw-r--r--static/icons/feather/bookmark.svg14
-rw-r--r--static/icons/feather/calendar.svg46
-rw-r--r--static/icons/feather/circle.svg13
-rw-r--r--static/icons/feather/clock.svg28
-rw-r--r--static/icons/feather/code.svg14
-rw-r--r--static/icons/feather/copy.svg14
-rw-r--r--static/icons/feather/edit.svg26
-rw-r--r--static/icons/feather/external-link.svg32
-rw-r--r--static/icons/feather/eye-off.svg29
-rw-r--r--static/icons/feather/eye.svg18
-rw-r--r--static/icons/feather/file-text.svg41
-rw-r--r--static/icons/feather/git-commit.svg15
-rw-r--r--static/icons/feather/globe.svg34
-rw-r--r--static/icons/feather/heart.svg13
-rw-r--r--static/icons/feather/home.svg14
-rw-r--r--static/icons/feather/link.svg26
-rw-r--r--static/icons/feather/map-pin.svg28
-rw-r--r--static/icons/feather/refresh-cw.svg18
-rw-r--r--static/icons/feather/rss.svg15
-rw-r--r--static/icons/feather/search.svg31
-rw-r--r--static/icons/feather/tag.svg14
-rw-r--r--static/icons/feather/trash-2.svg38
-rw-r--r--static/icons/feather/user.svg14
-rw-r--r--static/icons/feather/users.svg16
-rw-r--r--static/icons/tabler/LICENSE2
-rw-r--r--static/icons/tabler/archive.svg22
-rw-r--r--static/icons/tabler/book-2.svg30
-rw-r--r--static/icons/tabler/circle.svg16
-rw-r--r--static/icons/tabler/clock.svg26
-rw-r--r--static/icons/tabler/code.svg22
-rw-r--r--static/icons/tabler/git-fork.svg28
-rw-r--r--static/icons/tabler/home.svg22
-rw-r--r--static/icons/tabler/notes.svg25
-rw-r--r--static/icons/tabler/pinned.svg30
-rw-r--r--static/icons/tabler/robot.svg51
-rw-r--r--static/icons/tabler/rss.svg22
-rw-r--r--static/icons/tabler/settings.svg19
-rw-r--r--static/icons/tabler/square-letter-m.svg19
-rw-r--r--static/icons/tabler/tag.svg19
-rw-r--r--static/icons/tabler/users.svg25
-rw-r--r--static/js/autoplay.ts42
-rw-r--r--static/js/codecopy.ts7
-rw-r--r--static/js/contextmenu.ts10
-rw-r--r--static/js/domfilter.ts145
-rw-r--r--static/js/fixedsearch.ts192
-rw-r--r--static/js/forms.ts130
-rw-r--r--static/js/fuzzysort.js1101
-rw-r--r--static/js/hoverfix.ts64
-rw-r--r--static/js/index-bundle.ts (renamed from static/js/bundle.ts)9
-rw-r--r--static/js/index.ts7
-rw-r--r--static/js/infinitescroll.ts78
-rw-r--r--static/js/instantpage.ts330
-rw-r--r--static/js/pager.ts107
-rw-r--r--static/js/plumber.ts6
-rw-r--r--static/js/timeago.ts113
-rw-r--r--static/js/update.ts84
-rw-r--r--themes/default/layouts/_default/_markup/render-codeblock-mathml.html18
-rw-r--r--themes/default/layouts/_default/_markup/render-codeblock.html27
-rw-r--r--themes/default/layouts/_default/_markup/render-heading.html11
-rw-r--r--themes/default/layouts/_default/_markup/render-image.html109
-rw-r--r--themes/default/layouts/_default/baseof.html33
-rw-r--r--themes/default/layouts/_default/baseof.json13
-rw-r--r--themes/default/layouts/_default/baseof.txt13
-rw-r--r--themes/default/layouts/_default/baseof.xml15
-rw-r--r--themes/default/layouts/_default/home.archives.html67
-rw-r--r--themes/default/layouts/_default/home.authors.html40
-rw-r--r--themes/default/layouts/_default/home.authors.section.html21
-rw-r--r--themes/default/layouts/_default/home.browserconfig.xml13
-rw-r--r--themes/default/layouts/_default/home.history.html57
-rw-r--r--themes/default/layouts/_default/home.records.html52
-rw-r--r--themes/default/layouts/_default/home.settings.html32
-rw-r--r--themes/default/layouts/_default/home.sources.html67
-rw-r--r--themes/default/layouts/_default/home.xslt.rss.xsl140
-rw-r--r--themes/default/layouts/_default/home.xslt.sitemap.xsl82
-rw-r--r--themes/default/layouts/_default/index.html75
-rw-r--r--themes/default/layouts/_default/index.json4
-rw-r--r--themes/default/layouts/_default/index.webmanifest24
-rw-r--r--themes/default/layouts/_default/rss.xml53
-rw-r--r--themes/default/layouts/_default/section.drafts.html64
-rw-r--r--themes/default/layouts/_default/section.feeds.html56
-rw-r--r--themes/default/layouts/_default/section.following.html60
-rw-r--r--themes/default/layouts/_default/section.gallery.html13
-rw-r--r--themes/default/layouts/_default/section.html60
-rw-r--r--themes/default/layouts/_default/section.likes.html56
-rw-r--r--themes/default/layouts/_default/section.marks.html58
-rw-r--r--themes/default/layouts/_default/section.media.html75
-rw-r--r--themes/default/layouts/_default/section.webring.html107
-rw-r--r--themes/default/layouts/_default/single.embed.html26
-rw-r--r--themes/default/layouts/_default/single.html126
-rw-r--r--themes/default/layouts/_default/single.plain.txt2
-rw-r--r--themes/default/layouts/_default/sitemap.xml4
-rw-r--r--themes/default/layouts/_default/summary.html24
-rw-r--r--themes/default/layouts/_default/taxonomy.html31
-rw-r--r--themes/default/layouts/_default/term.html45
-rw-r--r--themes/default/layouts/partials/author-card.html89
-rw-r--r--themes/default/layouts/partials/author-list.html8
-rw-r--r--themes/default/layouts/partials/author-picture.html12
-rw-r--r--themes/default/layouts/partials/base-css.html16
-rw-r--r--themes/default/layouts/partials/base-discovery.html49
-rw-r--r--themes/default/layouts/partials/base-footer.html13
-rw-r--r--themes/default/layouts/partials/base-head.html74
-rw-r--r--themes/default/layouts/partials/base-manifest.html15
-rw-r--r--themes/default/layouts/partials/base-search.html11
-rw-r--r--themes/default/layouts/partials/card-meta-header.html14
-rw-r--r--themes/default/layouts/partials/context-profile.html17
-rw-r--r--themes/default/layouts/partials/count-authors.html2
-rw-r--r--themes/default/layouts/partials/count-drafts.html15
-rw-r--r--themes/default/layouts/partials/count-feeds.html17
-rw-r--r--themes/default/layouts/partials/count-likes.html12
-rw-r--r--themes/default/layouts/partials/count-marks.html6
-rw-r--r--themes/default/layouts/partials/count-media.html35
-rw-r--r--themes/default/layouts/partials/count-tags.html2
-rw-r--r--themes/default/layouts/partials/count-total-messages.html2
-rw-r--r--themes/default/layouts/partials/count.html1
-rw-r--r--themes/default/layouts/partials/following-list.html26
-rw-r--r--themes/default/layouts/partials/footer.html14
-rw-r--r--themes/default/layouts/partials/function-authors-data.html6
-rw-r--r--themes/default/layouts/partials/function-authors-slice.html6
-rw-r--r--themes/default/layouts/partials/function-content.html7
-rw-r--r--themes/default/layouts/partials/function-favicon-domain.html3
-rw-r--r--themes/default/layouts/partials/function-generate-feeds.html42
-rw-r--r--themes/default/layouts/partials/function-page-modified.html26
-rw-r--r--themes/default/layouts/partials/gallery-walk.html31
-rw-r--r--themes/default/layouts/partials/gallery.html2
-rw-r--r--themes/default/layouts/partials/generate-authors.html32
-rw-r--r--themes/default/layouts/partials/head-canonical.html (renamed from themes/default/layouts/partials/base-canonical.html)0
-rw-r--r--themes/default/layouts/partials/head-csp.html (renamed from themes/default/layouts/partials/base-csp.html)0
-rw-r--r--themes/default/layouts/partials/head-css.html26
-rw-r--r--themes/default/layouts/partials/head-description.html (renamed from themes/default/layouts/partials/base-description.html)2
-rw-r--r--themes/default/layouts/partials/head-discovery.html62
-rw-r--r--themes/default/layouts/partials/head-embed.html4
-rw-r--r--themes/default/layouts/partials/head-js.html (renamed from themes/default/layouts/partials/base-js.html)0
-rw-r--r--themes/default/layouts/partials/head-manifest.html58
-rw-r--r--themes/default/layouts/partials/head-search.html5
-rw-r--r--themes/default/layouts/partials/head-title.html (renamed from themes/default/layouts/partials/base-title.html)2
-rw-r--r--themes/default/layouts/partials/head.html72
-rw-r--r--themes/default/layouts/partials/image-gradient.css.html (renamed from themes/default/layouts/partials/styles-image-gradient.html)0
-rw-r--r--themes/default/layouts/partials/menu-datetime.html22
-rw-r--r--themes/default/layouts/partials/menu-embed.html8
-rw-r--r--themes/default/layouts/partials/menu-markdown.html (renamed from themes/default/layouts/partials/meta-markdown.html)8
-rw-r--r--themes/default/layouts/partials/menu-permalink.html (renamed from themes/default/layouts/partials/meta-permalink.html)6
-rw-r--r--themes/default/layouts/partials/menu-plain.html9
-rw-r--r--themes/default/layouts/partials/meta-anchored.html33
-rw-r--r--themes/default/layouts/partials/meta-context-menu.html30
-rw-r--r--themes/default/layouts/partials/meta-datetime.html (renamed from themes/default/layouts/partials/meta-date-time.html)10
-rw-r--r--themes/default/layouts/partials/meta-draft.html6
-rw-r--r--themes/default/layouts/partials/meta-expirydate.html (renamed from themes/default/layouts/partials/meta-expiry-date.html)4
-rw-r--r--themes/default/layouts/partials/meta-handle.html8
-rw-r--r--themes/default/layouts/partials/meta-menu.html23
-rw-r--r--themes/default/layouts/partials/meta-name.html6
-rw-r--r--themes/default/layouts/partials/meta-readtime.html (renamed from themes/default/layouts/partials/meta-read-time.html)8
-rw-r--r--themes/default/layouts/partials/meta-tags.html6
-rw-r--r--themes/default/layouts/partials/meta-unlisted.html4
-rw-r--r--themes/default/layouts/partials/meta-via.html11
-rw-r--r--themes/default/layouts/partials/meta-view.html6
-rw-r--r--themes/default/layouts/partials/meta-wordcount.html (renamed from themes/default/layouts/partials/meta-word-count.html)10
-rw-r--r--themes/default/layouts/partials/navigator-middle.html68
-rw-r--r--themes/default/layouts/partials/navigator-right.html21
-rw-r--r--themes/default/layouts/partials/navigator.css.html19
-rw-r--r--themes/default/layouts/partials/pagination.html87
-rw-r--r--themes/default/layouts/partials/profile-tabs.html43
-rw-r--r--themes/default/layouts/partials/profile.html38
-rw-r--r--themes/default/layouts/partials/render-embed.html31
-rw-r--r--themes/default/layouts/partials/rss-tags.html5
-rw-r--r--themes/default/layouts/partials/styles-navigator.html14
-rw-r--r--themes/default/layouts/partials/tags.html19
-rw-r--r--themes/default/layouts/partials/video-container.html13
-rw-r--r--themes/default/layouts/partials/webring.html2
-rw-r--r--themes/default/layouts/shortcodes/abbr.html2
-rw-r--r--themes/default/layouts/shortcodes/attach.html29
-rw-r--r--themes/default/layouts/shortcodes/disclose.html7
-rw-r--r--themes/default/layouts/shortcodes/gist.html9
-rw-r--r--themes/default/layouts/shortcodes/kbd.html1
-rw-r--r--themes/default/layouts/shortcodes/mark.html10
-rw-r--r--themes/default/layouts/shortcodes/react.html4
-rw-r--r--themes/default/layouts/shortcodes/reddit.html29
-rw-r--r--themes/default/layouts/shortcodes/spoiler.html2
-rw-r--r--themes/default/layouts/shortcodes/version.html8
-rw-r--r--themes/default/layouts/shortcodes/video-ascii.html (renamed from themes/default/layouts/shortcodes/asciicast.html)0
-rw-r--r--themes/default/layouts/shortcodes/video-imgur.html (renamed from themes/default/layouts/shortcodes/imgur-video.html)0
-rw-r--r--themes/default/layouts/shortcodes/video.rss.xml4
-rw-r--r--themes/default/layouts/shortcodes/vimeo.html12
240 files changed, 6086 insertions, 4365 deletions
diff --git a/.gitignore b/.gitignore
index b1e3887..568cf1b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
.hugo_build.lock
+.local
icons
public
resources
diff --git a/Makefile b/Makefile
index b9b8a85..e18c08d 100644
--- a/Makefile
+++ b/Makefile
@@ -1,96 +1,141 @@
-all:
- make config
- make js
- make hugo
+help: # Show this help menu
+ @printf "\n%s\n\n" "$$(grep -E '^[a-zA-Z0-9 -]+:.*#' Makefile | column -s ':#' -t)"
-config:
+watch: # Watch and rebuild everything
+ while true; do git ls-files -cdmo --exclude-standard --exclude tests | entr -d -s 'make build'; done
+
+monitor: # Monitor for files changes
+ inotifywait --monitor --recursive --event modify .
+
+server: # Start server
+ caddy file-server --listen :9294 --root public
+
+build: # Build everything
+ make build-config
+ make build-js
+ make build-site
+
+build-sub: # Build everything into substitute directory
+ make build
+ mkdir public/m
+ mv public/* public/m || true
+
+build-config: # Build configuration files
yj -yj -i < config.yaml > config.json
yj -yt -i < config.yaml > config.toml
-watch:
- while true; do find . | entr -d -s 'make all'; done
-
-js:
- deno run --allow-all static/js/bundle.ts
+build-js: # Build js bundle
+ deno run --allow-all static/js/index-bundle.ts
-hugo:
+build-site: # Build site
rm -rf public
- hugo --templateMetrics && hugo --templateMetrics
+ hugo --logLevel debug --templateMetrics --templateMetricsHints
+ hugo --logLevel debug --templateMetrics --templateMetricsHints
rm -f .hugo_build.lock
-server:
- caddy file-server --listen :9294 --root public
+build-icons: # Build icons
+ rm -rf static/icons
+ mkdir -p static/icons/feather static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/LICENSE --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/alert-circle.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/arrow-down-circle.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/arrow-left.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/arrow-right.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/arrow-up.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/at-sign.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/calendar.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/clock.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/edit.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/external-link.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/eye-off.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/eye.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/file-text.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/globe.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/bookmark.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/link.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/map-pin.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/refresh-cw.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/search.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/feathericons/feather/master/icons/trash-2.svg --output-dir static/icons/feather
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/LICENSE --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/archive.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/book-2.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/circle.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/clock.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/code.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/git-fork.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/home.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/notes.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/pinned.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/robot.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/rss.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/settings.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/square-letter-m.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/tag.svg --output-dir static/icons/tabler
+ curl --silent --remote-name https://raw.githubusercontent.com/tabler/tabler-icons/master/icons/outline/users.svg --output-dir static/icons/tabler
+ for icon in static/icons/*/*.svg; do \
+ xmlstarlet c14n --without-comments $$icon | xmllint --output $$icon --pretty 2 -; \
+ sed --in-place '1d' $$icon; \
+ done
+ git add -f static/icons
-test:
+test: # Test everything
make test-html
+ make test-css
make test-xsl
make test-xml
make test-rss
make test-jsonfeed
-test-html:
- validatornu \
+test-html: # Test HTML
+ vnu \
+ --html \
+ --errors-only \
public/index.html \
public/default/index.html
-test-css:
- validatornu --css \
- assets/css/default.css
+test-html-indices: # Test HTML indices
+ find public/ -type f -name "index.html" -exec vnu --errors-only {} \;
+
+test-css: # Test CSS
+ vnu \
+ --css \
+ assets/css/default.css \
+ assets/css/default-fast.css \
+ assets/css/default-simple.css \
+ assets/css/default-syntax.css
-test-xsl:
- xsltproc \
- public/rss.xsl
+test-xsl: # Test XSL
+ xsltproc public/rss.xsl
+ xsltproc public/sitemap.xsl
-test-xml:
+test-xml: # Test XML
xmllint --noout \
- public/rss.xml
+ public/rss.xml \
+ public/sitemap.xml
-test-rss:
+test-rss: # Test RSS
xmllint --noout --relaxng assets/schemas/rss-v2.0.rng public/rss.xml
# xmllint --noout --schema assets/schemas/rss-v2.0.xsd public/rss.xml
-test-sitemap:
+test-sitemap: # Test sitemap
xmllint --noout --schema assets/schemas/sitemap-v0.9.xsd public/sitemap.xml
# xmllint --noout --schema assets/schemas/sitemapindex-v0.9.xsd public/sitemap.xml
-test-jsonfeed:
+test-jsonfeed: # Test JSONFeed
check-jsonschema --schemafile assets/schemas/jsonfeed-v1.1.json public/index.json
-icons:
- rm -rf static/icons
- mkdir -p static/icons/feather static/icons/tabler
- svn export --force https://github.com/feathericons/feather/trunk/LICENSE static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/alert-circle.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/archive.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/arrow-down-circle.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/arrow-left.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/arrow-right.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/arrow-up.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/at-sign.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/calendar.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/circle.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/clock.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/code.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/copy.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/edit.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/external-link.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/eye-off.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/file-text.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/git-commit.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/globe.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/heart.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/home.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/link.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/map-pin.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/rss.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/search.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/tag.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/trash-2.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/user.svg static/icons/feather
- svn export --force https://github.com/feathericons/feather/trunk/icons/users.svg static/icons/feather
- svn export --force https://github.com/tabler/tabler-icons/trunk/LICENSE static/icons/tabler
- svn export --force https://github.com/tabler/tabler-icons/trunk/icons/book-2.svg static/icons/tabler
- svn export --force https://github.com/tabler/tabler-icons/trunk/icons/clock.svg static/icons/tabler
- svn export --force https://github.com/tabler/tabler-icons/trunk/icons/pinned.svg static/icons/tabler
- svn export --force https://github.com/tabler/tabler-icons/trunk/icons/robot.svg static/icons/tabler
- git add -f static/icons
+test-end: # Test front end
+ deno run --allow-all tests/index.ts
+
+test-bed: # Test bed run
+ deno run --allow-all tests/test.ts
+
+test-crawl: # Test link parity
+ deno run --allow-all tests/crawl.ts
+
+clean: # Clean everything
+ make clean-tests
+
+clean-tests: # Clean up tests
+ for file in /tmp/????????; do { [ -d "$$file/puppeteer_dev_chrome_profile-" ] && rm --recursive --force --verbose "$$file"; } || true; done
diff --git a/assets/css/default-fast.css b/assets/css/default-fast.css
new file mode 100644
index 0000000..8d9d4d1
--- /dev/null
+++ b/assets/css/default-fast.css
@@ -0,0 +1,5 @@
+@keyframes paint {
+ 0% {
+ opacity: 1;
+ }
+}
diff --git a/assets/css/default-mathml.css b/assets/css/default-mathml.css
new file mode 100644
index 0000000..4aa437a
--- /dev/null
+++ b/assets/css/default-mathml.css
@@ -0,0 +1,26 @@
+@namespace mathml url(http://www.w3.org/1998/Math/MathML);
+
+mathml|math {
+ display: block;
+ display: block math;
+}
+
+mathml|mtd {
+ display: flex;
+ justify-content: center;
+ padding-right: 0.4em;
+ padding-left: 0.4em;
+ padding-bottom: 0.5rem;
+ padding-top: 0.5rem;
+}
+
+@-moz-document url-prefix() {
+ mathml|mtd {
+ display: flex;
+ justify-content: center;
+ padding-right: 0.4em;
+ padding-left: 0.4em;
+ padding-bottom: 0.5ex;
+ padding-top: 0.5ex;
+ }
+}
diff --git a/assets/css/default-simple.css b/assets/css/default-simple.css
new file mode 100644
index 0000000..8b7fca3
--- /dev/null
+++ b/assets/css/default-simple.css
@@ -0,0 +1,77 @@
+column-base[position="left"],
+column-base[position="right"] {
+ opacity: 0.1;
+ transition: 2s;
+}
+
+column-base[position="left"]:hover,
+column-base[position="right"]:hover {
+ opacity: 0.9;
+ transition: 0.1s;
+}
+
+micro-card[id] > header,
+micro-card[id] article math-ml figcaption {
+ display: block;
+}
+
+micro-card[id] {
+ flex-direction: row;
+ padding: 1.25rem 1rem;
+}
+
+micro-card[id] > article {
+ margin: auto 0;
+ min-width: 0;
+}
+
+micro-card[id] > article > * {
+ width: 100%;
+}
+
+micro-card[id] > article > :nth-last-child(2) {
+ margin-bottom: 0;
+}
+
+[data-kind="page"] micro-card[id]:first-child > a,
+micro-card[id] micro-tags,
+micro-card[id] > header meta-data,
+micro-card[id] > article figcaption {
+ display: none;
+}
+
+micro-card[id] > article footer:not(blockquote footer) {
+ display: none;
+}
+
+micro-card[id] > a {
+ display: inline;
+ height: 100%;
+ left: 0;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ z-index: 1;
+}
+
+micro-card[id] > a:focus {
+ background-color: transparent !important;
+ outline-offset: -0.15rem !important;
+}
+
+micro-card[id] article p,
+micro-card[id] article ul,
+micro-card[id] article dl,
+micro-card[id] article h1,
+micro-card[id] article h2,
+micro-card[id] article h3,
+micro-card[id] article video,
+micro-card[id] article iframe,
+micro-card[id] article article,
+micro-card[id] article details,
+micro-card[id] article figcaption,
+micro-card[id] header picture {
+ pointer-events: all;
+ position: relative;
+ z-index: 2;
+}
diff --git a/assets/css/syntax-highlight-default.css b/assets/css/default-syntax.css
index 1552e5f..e6f7021 100644
--- a/assets/css/syntax-highlight-default.css
+++ b/assets/css/default-syntax.css
@@ -1,29 +1,52 @@
-/* ----- Colors ----- */
-
/* ----- Format ----- */
.chroma .hl {
- display: flex;
padding: 0 0.5rem;
margin: 0 -0.5rem;
}
+.chroma .line {
+ display: block;
+}
+
+.chroma .hl > .cl:before,
+.chroma .ln a:hover:before,
+.chroma .ln:target a:before,
+.chroma .line > .cl:hover:before {
+ content: "";
+ position: absolute;
+ height: 1.5rem;
+ width: 100%;
+ left: 0;
+ z-index: -1;
+}
+
.chroma .ln a {
- background-color: #edf2f7;
- padding: 0.2rem 0.75rem;
+ padding: 0.05rem 0.75rem;
margin: 0 1rem 0 -0.75rem;
user-select: none;
text-decoration: none;
+ display: inline-block;
}
-.chroma .ln a:hover {
+.chroma .ln a:hover,
+.chroma .ln:target a {
outline: 0.15rem solid !important;
outline-offset: -0.3rem;
}
-.chroma .line:hover {
+.chroma .line .cl:hover {
+ text-shadow: 0 0 currentColor;
+}
+
+.chroma .ln a:hover:before,
+.chroma .ln:target a:before,
+.chroma .line > .cl:hover:before {
background-color: #f2f2f2;
- display: flex;
+}
+
+code-block code {
+ position: relative;
}
code-block button {
@@ -38,31 +61,29 @@ code-block header language-label a:hover {
/* ------ Tokens ------ */
:root {
- --code-chroma-background: #ffffff;
- --code-chroma-foreground: #333333;
- --code-chroma-error-background: #960050;
- --code-chroma-error-foreground: #960050;
- --code-chroma-label-background: #006894;
- --code-chroma-label-foreground: #e6e6e6;
- --code-chroma-line-highlight: #d9ddf2;
- --code-chroma-line-number: #375462;
- --code-chroma-line: var(--code-chroma-foreground);
-}
-
-/* ChromaForeground */ code-block, .chroma, .highlight { color: #333333; color: var(--code-chroma-foreground); }
-/* ChromaBackground */ code-block button, .chroma { background-color: #ffffff; background-color: var(--code-chroma-background); }
-/* ChromaErrorBackground */ .chroma .err { color: #960050; color: var(--code-chroma-error-background); }
-/* ChromaErrorForeground */ .chroma .err { color: #960050; color: var(--code-chroma-error-foreground); }
-/* ChromaLabelBackground */ .chroma code:before { background-color: #006894; background-color: var(--code-chroma-label-background); }
-/* ChromaLabelForeground */ .chroma code:before { color: #e6e6e6; color: var(--code-chroma-label-foreground); }
-/* ChromaLine */ .chroma .line { color: #333333; color: var(--code-chroma-line); }
-/* ChromaLineHighlight */ .chroma .hl { background-color: #d9ddf2; background-color: var(--code-chroma-line-highlight); }
-/* ChromaLineNumber */ .chroma .ln a { color: #375462 !important; color: var(--code-chroma-line-number) !important; }
-
-.chroma .hl {
- background-color: #fff8c5;
+--code-chroma-background: #ffffff;
+--code-chroma-foreground: #333333;
+--code-chroma-error-background: #960050;
+--code-chroma-error-foreground: #960050;
+--code-chroma-label-background: #006894;
+--code-chroma-label-foreground: #e6e6e6;
+--code-chroma-line-highlight: #fff8c5;
+--code-chroma-line-number: #375462;
+--code-chroma-line-number-background: #edf2f7;
+--code-chroma-line: var(--code-chroma-foreground);
}
+/* ChromaForeground */ code-block, .chroma, .highlight { color: #333333; color: var(--code-chroma-foreground); }
+/* ChromaBackground */ code-block button, .chroma { background-color: #ffffff; background-color: var(--code-chroma-background); }
+/* ChromaErrorBackground */ .chroma .err { color: #960050; color: var(--code-chroma-error-background); }
+/* ChromaErrorForeground */ .chroma .err { color: #960050; color: var(--code-chroma-error-foreground); }
+/* ChromaLabelBackground */ .chroma code:before { background-color: #006894; background-color: var(--code-chroma-label-background); }
+/* ChromaLabelForeground */ .chroma code:before { color: #e6e6e6; color: var(--code-chroma-label-foreground); }
+/* ChromaLine */ .chroma .line { color: #333333; color: var(--code-chroma-line); }
+/* ChromaLineHighlight */ .chroma .hl > span:before { background-color: #fff8c5; background-color: var(--code-chroma-line-highlight); }
+/* ChromaLineNumber */ .chroma .ln a { color: #375462 !important; color: var(--code-chroma-line-number) !important; }
+/* ChromaLineNumberBackground */ .chroma .ln a { background-color: #edf2f7; background-color: var(--code-chroma-line-number-background); }
+
:root {
--code-comment: #4f4f4f;
--code-comment-hashbang: var(--code-comment);
diff --git a/assets/css/default.css b/assets/css/default.css
index f688eaf..74eb0fc 100644
--- a/assets/css/default.css
+++ b/assets/css/default.css
@@ -20,71 +20,100 @@
text-shadow: 0 0 currentColor;
}
+@media (prefers-color-scheme: dark) {
+ ::selection {
+ color: #000;
+ background-color: #aaa;
+ text-shadow: 0 0 currentColor;
+ }
+
+ ::-webkit-selection {
+ color: #000;
+ background-color: #aaa;
+ text-shadow: 0 0 currentColor;
+ }
+
+ ::-moz-selection {
+ color: #000;
+ background-color: #aaa;
+ text-shadow: 0 0 currentColor;
+ }
+}
+
/* ----- Colors ----- */
:root {
--primary: 230;
--secondary: 258;
--accent: 217;
- --foreground: hsl(var(--primary), 99%, 5%);
- --fade: hsl(var(--primary), 35%, 30%);
- --border-lighter: hsl(var(--primary), 35%, 92%);
+ --background-bolder: hsl(var(--secondary), 99%, 98%);
+ --background: hsl(var(--secondary), 99%, 99%);
--border-darker: hsl(var(--primary), 35%, 80%);
--border-darkest: hsl(var(--primary), 35%, 70%);
- --background: hsl(var(--secondary), 99%, 99%);
- --background-bolder: hsl(var(--secondary), 99%, 98%);
- --widget-background: hsl(var(--secondary), 25%, 97%);
- --hover-background: hsl(var(--secondary), 25%, 94%);
- --focus-within-background: hsl(var(--secondary), 52%, 95%);
- --table-even-background: hsl(var(--secondary), 25%, 99%);
- --table-odd-background: hsl(var(--secondary), 25%, 97%);
- --link: hsl(var(--accent), 99%, 37%);
- --hover-background-alternate: hsl(var(--accent), 100%, 96%);
- --active-background-alternate: hsl(var(--accent), 100%, 90%);
- --button-background: #fff;
+ --border-lighter: hsl(var(--primary), 35%, 92%);
+ --button-background: hsl(var(--primary), 0%, 100%);
--danger-background-lighter: #fff5f5;
--danger-background: #fcd2cf;
--danger: #8f0000;
+ --fade: hsl(var(--primary), 35%, 30%);
+ --focus-within-background: hsl(var(--secondary), 52%, 95%);
+ --foreground: hsl(var(--primary), 99%, 5%);
+ --hover-background-alternate: hsl(var(--accent), 100%, 96%);
+ --hover-background: hsl(var(--secondary), 25%, 94%);
+ --icon-focus-background: var(--icon-hover-background);
+ --icon-hover-background: hsl(var(--accent), 100%, 90%);
+ --link: hsl(var(--accent), 99%, 37%);
--shadow: #00000060;
- --spoiler: #444;
+ --spoiler: hsl(var(--primary), 0%, 27%);
--success-background: #d5f3c4;
--success: #1d3c0c;
+ --table-even-background: hsl(var(--secondary), 25%, 99%);
+ --table-odd-background: hsl(var(--secondary), 25%, 97%);
+ --text-background: var(--background);
--warning-background: #ffe699;
--warning: #332600;
- color-scheme: light dark;
+ --widget-background: hsl(var(--secondary), 25%, 97%);
+ color-scheme: light;
}
@media (prefers-color-scheme: dark) {
:root {
- --active-background-alternate: #425a8a;
- --background-bolder: #0d0d0d;
- --background-rgb: 17, 17, 17;
- --background: rgba(var(--background-rgb), 1);
- --border-darker: #555;
- --border-darkest: #999;
- --border-lighter: #262626;
- --button-background: #333;
- --danger-background-lighter: #1b0404;
+ --primary: 0;
+ --secondary: 0;
+ --accent: 219;
+ --background-bolder: hsl(var(--secondary), 0%, 5%);
+ --background: hsl(var(--secondary), 0%, 7%);
+ --border-darker: hsl(var(--secondary), 0%, 33%);
+ --border-darkest: hsl(var(--secondary), 0%, 60%);
+ --border-lighter: hsl(var(--secondary), 0%, 15%);
+ --button-background: hsl(var(--secondary), 0%, 20%);
+ --danger-background-lighter: #261717;
--danger-background: #4f1c1c;
--danger: #ff9494;
- --fade: rgba(var(--foreground-rgb), 0.75);
+ --fade: hsl(var(--secondary), 0%, 66%);
--focus-within-background: #291933;
- --foreground-rgb: 221, 221, 221;
- --foreground: rgba(var(--foreground-rgb), 1);
+ --foreground: hsl(var(--secondary), 0%, 87%);
--hover-background-alternate: #1c263a;
- --hover-background: rgba(var(--foreground-rgb), 0.08);
- --link: #a3c3ff;
- --shadow: #000;
- --spoiler: #aaa;
+ --hover-background: hsl(var(--secondary), 0%, 14%);
+ --icon-focus-background: #88aefb;
+ --icon-hover-background: hsl(var(--accent), 35%, 25%);
+ --link: hsl(var(--accent), 100%, 82%);
+ --shadow: hsl(var(--secondary), 0%, 0%);
+ --spoiler: hsl(var(--secondary), 0%, 67%);
--success-background: #2d3e0f;
--success: #d5f3c4;
- --table-even-background: rgba(var(--foreground-rgb), 0.06);
- --table-odd-background: rgba(var(--foreground-rgb), 0.02);
+ --table-even-background: hsl(var(--secondary), 0%, 12%);
+ --table-odd-background: hsl(var(--secondary), 0%, 9%);
+ --text-background: hsl(var(--secondary), 0%, 17%);
--warning-background: #a89700;
--warning: #000;
- --widget-background: rgba(var(--foreground-rgb), 0.02);
+ --widget-background: hsl(var(--secondary), 0%, 9%);
+ color-scheme: dark;
}
- img {
+ kbd,
+ img,
+ video,
+ figure span {
filter: brightness(75%);
}
code-block pre,
@@ -107,38 +136,52 @@
vertical-align: inherit;
}
-:target::before {
- content: "";
- display: block;
- height: 4rem;
- margin-top: -4rem;
- visibility: hidden;
+html,
+:target:not(nav span) {
+ scroll-margin-top: 6rem;
}
-:not(#main):target micro-summary,
-:not(#main):target micro-summary:hover {
- background-color: transparent;
+sup:target [role="doc-noteref"][href^="#fn\:"],
+li:target [role="doc-backlink"][href^="#fnref\:"],
+:focus:not(html):not(body):not(svg):not(pre):not(#search) {
+ outline: 0.15rem solid;
+ outline-offset: 0.05rem;
+ text-decoration: none;
border-radius: 0.5rem;
- outline-offset: -6px;
- outline: 2px dashed #ccc;
- outline: 2px dashed var(--border-darker);
}
-:focus:not(html):not(body):not(svg) {
+sup:target [role="doc-noteref"][href^="#fn\:"],
+li:target [role="doc-backlink"][href^="#fnref\:"] {
+ outline-offset: 1px;
+}
+
+nav a:focus,
+button:focus,
+menu a:focus,
+code-block a:focus,
+gallery-images a:focus {
+ outline-offset: -0.2rem !important;
+}
+
+pre:hover,
+pre:focus,
+pre:focus-within {
outline: 0.15rem solid;
- outline-offset: -0.15rem;
text-decoration: none;
}
+sup:target [role="doc-noteref"][href^="#fn\:"],
+li:target [role="doc-backlink"][href^="#fnref\:"],
:focus:not(html):not(body):not(pre):not(svg):not(button):not(input):not(video) {
- background-color: #ffe699;
- background-color: var(--warning-background);
- color: #111;
- color: var(--warning);
+ background-color: #ffe699 !important;
+ background-color: var(--warning-background) !important;
+ color: #111 !important;
+ color: var(--warning) !important;
}
-:hover:not(a):not(s):not(img):not(summary):not(nav):not(abbr):not(form):not(code):not(mark):not(td):not(tab-bar):not(tab-bar
- nav):not(blockquote p) {
+:hover:not(a):not(s):not(span):not(img):not(summary):not(nav):not(abbr):not(
+ form
+ ):not(code):not(mark):not(td):not(nav):not(p):not(object):not(tab-bar) {
border-radius: 0.5rem;
}
@@ -168,13 +211,46 @@ h3 {
margin: 0;
}
-p,
-ul,
-dd,
-ol,
-figure,
-blockquote {
- margin: 0;
+math {
+ font-family: "CMU Serif", serif;
+ font-size: 110%;
+}
+
+micro-card[id] article h1,
+micro-card[id] article h2,
+micro-card[id] article h3 {
+ font-family: Charter, Georgia, "Book Antiqua", serif;
+ font-size: 125%;
+ font-weight: 700;
+}
+
+micro-card[id] article h2,
+micro-card[id] article h3 {
+ font-size: 115%;
+}
+
+micro-card[id] article h3 {
+ font-style: italic;
+}
+
+html,
+samp,
+blockquote span {
+ font-family: "Noto Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
+ Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans",
+ "Helvetica Neue", sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
+ "Segoe UI Symbol";
+}
+
+pre,
+kbd,
+code,
+svg text,
+following-list details summary:after,
+micro-card article details[data-disclosure] summary:after {
+ font-family: "Fira Code", "Lucida Console", "Andale Mono", "Roboto Mono",
+ "Ubuntu Monospace", "Noto Mono", "Oxygen Mono", "Liberation Mono", monospace,
+ "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
p:not(:last-child),
@@ -184,10 +260,15 @@ dl:not(:last-child),
table:not(:last-child),
figure:not(:last-child),
code-block:not(:last-child),
-blockquote:not(:last-child) {
+blockquote:not(:last-child),
+article > mark[id]:not(:last-child) {
margin-bottom: 0.75rem;
}
+dd {
+ margin: 0;
+}
+
dl {
margin: 0 0 0 1rem;
}
@@ -209,22 +290,37 @@ figcaption {
text-align: center;
}
+sup,
+sub {
+ display: inline-block;
+ vertical-align: bottom;
+}
+
sup {
- vertical-align: super;
+ vertical-align: text-top;
font-size: 85%;
}
sub {
- vertical-align: sub;
font-size: 85%;
}
-sup,
-sub {
- display: inline-block;
+article > mark[id] {
+ display: block;
+}
+
+mark:target a {
+ color: inherit;
+ text-decoration-thickness: 2px;
}
-mark {
+mark[id] {
+ background: none;
+ color: inherit;
+}
+
+mark,
+mark:target span {
background: linear-gradient(
to bottom,
transparent 10%,
@@ -239,8 +335,7 @@ mark {
var(--warning-background) 90%,
transparent 90%
);
- color: #332600;
- color: var(--warning);
+ color: #000;
}
ins {
@@ -310,7 +405,7 @@ input[type="checkbox"] {
-webkit-appearance: none;
appearance: none;
background-color: transparent;
- border-radius: 0.5rem;
+ border-radius: 25%;
border: 1px solid;
border-color: inherit;
height: 1.25rem;
@@ -325,23 +420,27 @@ input[type="checkbox"]:checked {
}
input[type="checkbox"]:checked:after {
- content: "\2714";
- display: flex;
- align-items: center;
- justify-content: center;
- font-weight: 700;
+ border-bottom-style: solid;
+ border-left-style: solid;
+ border-width: 0.4rem;
+ content: "";
+ display: block;
height: 100%;
- width: 100%;
+ margin: auto;
+ transform: scale(0.5, -0.5) rotateZ(145deg);
+ width: 70%;
}
blockquote {
color: #444;
color: var(--fade);
+ margin: 0;
}
-blockquote p {
+blockquote p,
+blockquote p:not(:last-child) {
padding-left: 1rem;
- margin-left: 1rem;
+ margin: 0 0 0 1rem;
border-left: 2px solid;
border-color: #eee;
border-color: var(--border-darker);
@@ -353,38 +452,38 @@ blockquote footer {
}
video {
+ width: 100%;
color: #000;
border-radius: 0.5rem;
background-color: #000;
+ vertical-align: middle;
box-shadow: 0 0 3px #00000060;
box-shadow: 0 0 3px var(--shadow);
}
-video:hover {
- box-shadow: 0 0 14px #00000060;
- box-shadow: 0 0 14px var(--shadow);
-}
-
video[data-orientation="portrait"] {
width: 50%;
}
+video:focus {
+ filter: brightness(100%);
+}
+
video-container {
display: block;
text-align: center;
}
kbd {
- background-color: #eee;
+ background-color: #fff;
border-radius: 0.25rem;
- border: 1px solid #b4b4b4;
- box-shadow: 0 1px 1px #737373, 0 2px 0 0 #f2f2f2 inset;
+ border: 1px solid #bbb;
color: #333;
display: inline-block;
font-size: 0.85em;
font-weight: 700;
line-height: 1;
- padding: 2px 4px;
+ padding: 0.1rem 0.25rem;
white-space: nowrap;
}
@@ -399,76 +498,76 @@ html {
margin-right: 0;
}
-html,
-samp,
-blockquote span {
- font-family: "Noto Sans", -apple-system, BlinkMacSystemFont, "Segoe UI",
- Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans",
- "Helvetica Neue", sans-serif, "Apple Color Emoji", "Segoe UI Emoji",
- "Segoe UI Symbol";
-}
-
-blockquote p {
- font-family: Charter, Georgia, "Book Antiqua", serif;
- font-size: 110%;
-}
-
-pre,
-kbd,
-code,
-svg text {
- font-family: "Fira Code", "Lucida Console", "Andale Mono", "Roboto Mono",
- "Ubuntu Monospace", "Noto Mono", "Oxygen Mono", "Liberation Mono", monospace,
- "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
-}
-
-body,
button,
-input,
-select,
textarea {
margin: 0;
}
ol {
- counter-reset: ol;
padding-left: 3.5rem;
+ list-style: none;
+ margin: 0;
}
ol li {
overflow-wrap: break-word;
word-break: break-word;
- list-style: none;
+ position: relative;
+ min-height: 1rem;
+}
+
+ol li + li {
+ margin-top: 0.5rem;
}
ol li:before {
- border-radius: 100%;
+ border-radius: 0.5rem;
border: 1px solid;
- content: counter(ol);
- counter-increment: ol;
- margin-left: -2rem;
+ border-color: #111;
+ border-color: var(--foreground);
font-size: 85%;
- padding: 0 0.35rem;
+ font-weight: 700;
+ opacity: 0.85;
+ padding: 0 0.5rem;
position: absolute;
+ right: 0;
+ margin-right: 100%;
+ margin-left: -100%;
+ font-variant-numeric: tabular-nums lining-nums slashed-zero;
+ height: 100%;
+ max-height: 1.5rem;
+ display: flex;
+ align-items: center;
}
-ol li + li {
- margin-top: 0.5rem;
+ol:not([start]) {
+ counter-reset: ol;
}
-main {
- min-height: 100%;
+ol:not([start]) li:before {
+ content: counter(ol);
+ counter-increment: ol;
+}
+
+ol[start] li:before {
+ content: counter(list-item);
}
-main,
details,
+summary,
code-block,
+figure span,
diagram-container {
display: block;
}
-summary {
- display: list-item;
+main {
+ display: block;
+ min-height: 80vh;
+}
+
+summary::-webkit-details-marker {
+ display: none;
}
cite {
@@ -478,6 +577,7 @@ cite {
ul {
list-style: none;
padding-left: 0;
+ margin: 0;
}
nav ol,
@@ -503,8 +603,13 @@ q:after {
content: "\201D";
}
-details,
-micro-metadata-menu context-control label {
+pre code {
+ white-space: pre-line;
+}
+
+summary,
+abbr[title] label,
+menu label {
cursor: pointer;
}
@@ -521,10 +626,10 @@ a:hover {
}
a:hover,
-micro-metadata-menu:hover span,
-micro-metadata-view a:hover span,
-micro-metadata-draft a:hover span,
-micro-metadata-handle a:hover span {
+menu:hover span,
+meta-view a:hover span,
+meta-draft a:hover span,
+meta-handle a:hover span {
text-decoration-thickness: 0.15rem !important;
text-decoration-color: inherit !important;
}
@@ -549,15 +654,15 @@ document-attachment object p {
margin: 1rem;
}
-column-left nav {
+column-base[position="left"] nav {
position: sticky;
position: -webkit-sticky;
- align-self: flex-start;
top: 0.5rem;
text-align: right;
+ font-size: 100%;
}
-column-left nav a {
+column-base[position="left"] nav a {
align-items: center;
color: inherit;
color: var(--foreground);
@@ -569,28 +674,34 @@ column-left nav a {
border-radius: 0.5rem;
}
-column-left nav li {
+column-base[position="left"] nav li {
margin-bottom: 0.25rem;
}
-column-left nav li:hover a {
+column-base[position="left"] nav li:hover a {
background-color: #eee;
background-color: var(--hover-background);
border-radius: 0.5rem;
}
-column-left nav li:hover svg {
+column-base[position="left"] nav a:hover svg {
+ fill: #cce0ff;
+ fill: var(--icon-hover-background);
+ stroke-width: 0.1rem;
+}
+
+column-base[position="left"] nav a:focus svg {
fill: #cce1ff;
- fill: var(--active-background-alternate);
+ fill: var(--icon-focus-background);
}
-column-left nav a span {
+column-base[position="left"] nav a span {
padding: 0 1rem;
}
-column-left nav a svg {
- height: 1.5795rem;
- width: 1.5795rem;
+column-base[position="left"] nav a svg {
+ height: 1.5em;
+ width: 1.5em;
}
abbr[title] {
@@ -606,6 +717,14 @@ input[type="checkbox"]:checked ~ abbr[title]::after {
content: " (" attr(title) ")";
}
+input[type="checkbox"]:checked ~ input[type="checkbox"] ~ abbr[title] {
+ cursor: text;
+}
+
+input[type="checkbox"]:checked ~ input[type="checkbox"] ~ abbr[title] label {
+ pointer-events: none;
+}
+
samp {
font-variant: all-small-caps;
letter-spacing: 0.05rem;
@@ -621,26 +740,23 @@ small {
opacity: 0.85;
}
-audio,
-canvas,
-iframe,
-img,
-svg,
-video {
+canvas {
vertical-align: middle;
}
-video,
audio {
width: 100%;
-}
-
-audio {
margin: 0.75rem 0;
+ vertical-align: middle;
}
figure {
text-align: center;
+ margin: 0;
+}
+
+figure object {
+ pointer-events: none;
}
iframe {
@@ -649,8 +765,10 @@ iframe {
border: 2px solid #ccc;
border: 2px solid var(--border-darker);
background-color: #fefefe;
- border-radius: 0.5rem !important;
+ border-radius: 0.5rem;
min-height: 16rem;
+ user-select: none;
+ vertical-align: middle;
}
self-embed iframe {
@@ -658,10 +776,12 @@ self-embed iframe {
max-height: 11rem;
}
-img {
+img,
+figure object {
height: auto;
max-width: 100%;
- border: 1px solid;
+ border-width: 1px;
+ border-style: solid;
border-color: #ccc;
border-color: var(--border-darker);
border-radius: 0.5rem;
@@ -671,24 +791,24 @@ img {
justify-content: center;
align-items: center;
background-color: #fefefe;
+ user-select: none;
+ vertical-align: middle;
}
-img:hover {
+img:hover,
+video:hover,
+figure span:hover {
box-shadow: 0 0 14px #00000060;
box-shadow: 0 0 14px var(--shadow);
filter: brightness(90%);
}
-img,
-iframe {
- user-select: none;
-}
-
p {
- line-height: 1.4;
+ margin: 0;
}
svg {
+ vertical-align: middle;
stroke-width: 0.08rem;
}
@@ -700,33 +820,35 @@ svg:not(:root) {
overflow: hidden;
}
-button,
input {
+ margin: 0;
overflow: visible;
}
-button,
select {
text-transform: none;
+ margin: 0;
}
button,
+summary:after,
[type="reset"],
[type="button"],
[type="submit"],
micro-tags a,
-micro-expand label,
-paginator-navigation a,
-micro-author micro-summary > a {
+nav[data-type="pagination"] a,
+micro-author micro-card > a {
align-items: center;
appearance: none;
background-color: #fff;
background-color: var(--button-background);
+ border: 1px solid;
border-radius: 0.5rem;
- border: 1px solid #eee;
- border: 1px solid var(--border-lighter);
- box-shadow: 0 1px 2px #00000060;
- box-shadow: 0 1px 2px var(--shadow);
+ border-color: #eee;
+ border-color: var(--border-darker);
+ border-top-color: var(--border-lighter);
+ border-left-color: var(--border-lighter);
+ border-right-color: var(--border-lighter);
color: inherit;
cursor: pointer;
display: flex;
@@ -734,6 +856,8 @@ micro-author micro-summary > a {
height: 1.95rem;
padding: 0.125rem 0.5rem;
text-decoration: none;
+ text-transform: none;
+ overflow: visible;
}
button:hover,
@@ -741,24 +865,34 @@ button:hover,
[type="button"]:hover,
[type="submit"]:hover,
micro-tags a:hover,
-micro-expand label:hover,
-paginator-navigation a:hover,
-micro-author micro-summary > a:hover {
+nav[data-type="pagination"] a:hover,
+micro-author micro-card > a:hover {
border: 1px solid;
border-color: #aaa;
border-color: var(--border-darkest);
}
button svg,
-paginator-navigation svg,
-micro-author micro-summary > a svg {
+micro-author micro-card a svg,
+nav[data-type="pagination"] a svg {
height: 1.25rem;
width: 1.25rem;
- margin: 0 0.25rem;
+}
+
+micro-author a svg ~ span,
+micro-author a span ~ svg,
+nav[data-type="pagination"] a svg ~ span,
+nav[data-type="pagination"] a span ~ svg {
+ margin-left: 0.25rem;
}
hr {
+ border: 0;
border-top: 1px solid;
+ border-color: #ccc;
+ border-color: var(--border-darker);
+ opacity: 0.4;
+ margin: 0.5rem 0;
}
/* ----- Tables ----- */
@@ -821,6 +955,10 @@ tr:last-child td:last-child {
/* ----- Print ----- */
+article a[href*="pdf"]::after {
+ content: " [pdf]";
+}
+
@media print {
a[href^="http"]::after {
content: " (" attr(href) ")";
@@ -838,45 +976,52 @@ body {
background-color: var(--background);
color: #111;
color: var(--foreground);
- display: flex;
- margin: 0 auto;
- max-width: 1250px;
+ margin: 0;
+ max-width: 600px;
min-height: 100%;
overflow-x: hidden;
-webkit-text-size-adjust: none;
}
-column-left {
+html[data-document="html"] body,
+html[data-document="xhtml"] body {
display: flex;
+ margin: 0 auto;
+ max-width: 1250px;
+}
+
+column-base[position="left"] {
width: 14.25%;
- justify-content: flex-end;
}
-column-right {
+column-base[position="right"] {
width: 28%;
}
-column-left,
-column-right {
+column-base[position="left"],
+column-base[position="right"] {
margin: 0.5rem 2rem;
}
-column-middle {
+column-base[position="middle"] {
max-width: 600px;
min-height: 100vh;
width: 100%;
+ height: fit-content;
}
micro-card,
-micro-tags {
+micro-tags,
+profile-box {
display: block;
}
-history-archive h1,
-records-archive h1 {
+source-files h1,
+archive-list h1 {
text-align: center;
font-weight: 400;
font-size: 150%;
+ font-variant: all-small-caps;
}
micro-tags {
@@ -891,7 +1036,7 @@ micro-tags a {
margin: 0 0.25rem 0.5rem 0;
}
-micro-summary {
+micro-card {
border-bottom: 1px solid;
border-color: #eee;
border-color: var(--border-lighter);
@@ -901,59 +1046,80 @@ micro-summary {
position: relative;
}
-micro-author micro-summary {
- flex-direction: row;
+micro-card > a {
+ display: none;
+}
+
+micro-card:target {
+ border-radius: 0.5rem;
+ outline-offset: -6px;
+ outline: 2px dashed #ccc;
+ outline: 2px dashed var(--border-darker);
}
-micro-summary:hover {
+micro-card:hover {
background-color: #f5f9ff;
background-color: var(--hover-background-alternate);
}
-micro-summary:focus-within {
+micro-card:focus-within {
background-color: #f0ecf9;
background-color: var(--focus-within-background);
}
-micro-author micro-summary {
+micro-author micro-card {
+ flex-direction: row;
justify-content: start;
align-items: center;
border: none;
}
-micro-author micro-thumbnail {
- flex: none;
- margin-right: 0.5rem;
+micro-author micro-card header,
+micro-author micro-card > a,
+micro-author micro-card > article,
+micro-author micro-card > p:not(:last-child) {
+ margin: 0 0.5rem;
+}
+
+micro-author micro-card p:not(:last-child) {
+ flex: 1.75;
+ color: #444;
+ color: var(--fade);
+ max-width: 20rem;
}
-micro-author micro-header {
+micro-author article {
flex: 1;
min-width: 3rem;
- margin-right: 0.75rem;
}
-micro-author micro-header h2 {
- line-height: 1.25rem;
+micro-author article h2 {
+ line-height: 1.25;
}
-micro-author micro-summary p:not(:last-child) {
- flex: 1.75;
- margin: 0 0.75rem 0 0;
- color: #444;
- color: var(--fade);
- max-width: 20rem;
+micro-author article h3 {
+ font-weight: 400;
}
-micro-thumbnail figure {
+micro-author micro-card header figure:first-child {
+ margin: 0;
+}
+
+micro-card header figure:first-child {
margin: 0 0.75rem 0 0;
}
-micro-thumbnail figure > a {
+micro-card header figure > a,
+micro-card header figure > a:hover {
+ color: #000;
display: block;
+ text-decoration: none;
}
tag-card figure img,
-micro-thumbnail figure img {
+micro-card header figure img,
+micro-card header figure span,
+micro-card header figure object {
border-radius: 100%;
min-width: 3.5rem;
min-height: 3.5rem;
@@ -961,37 +1127,35 @@ micro-thumbnail figure img {
max-height: 3.5rem;
}
-micro-summary article {
+micro-card > article {
margin-left: 4.25rem;
}
-micro-summary article ul {
+micro-card article ul {
list-style-type: "\2012";
padding-left: 2rem;
}
-micro-summary article li {
+micro-card article li {
padding-left: 0.5rem;
}
-micro-summary article ul li + li {
- margin-top: 0.25rem;
+micro-card article li::marker {
+ opacity: 0.85;
}
-[data-kind] micro-summary article h1 a,
-[data-kind] micro-summary article h2 a,
-[data-kind] micro-summary article h3 a {
- color: inherit;
+micro-card article ul li + li {
+ margin-top: 0.25rem;
}
-micro-summary article figure img {
+micro-card article figure img {
border: none;
margin: 0 auto;
box-shadow: 0 0 3px #00000060;
box-shadow: 0 0 3px var(--shadow);
}
-micro-summary article figure img:before {
+micro-card article figure img:before {
background-color: #fefefe;
background-color: var(--background);
border-radius: 0.5rem;
@@ -1003,22 +1167,20 @@ micro-summary article figure img:before {
margin: 1rem;
}
-micro-summary article figure > a {
+micro-card article figure > a {
border-radius: 0.5rem;
display: inline-block;
}
-micro-summary article figure > a[data-orientation="landscape"] {
+micro-card article figure > a[data-orientation="landscape"] {
display: block;
}
-micro-summary article figure > a[data-orientation="landscape"] img {
+micro-card article figure > a[data-orientation="landscape"] img {
width: 100%;
- max-height: 20rem;
}
-micro-metadata {
- align-items: center;
+micro-card header {
color: #444;
color: var(--fade);
display: flex;
@@ -1026,144 +1188,153 @@ micro-metadata {
margin-bottom: 0.25rem;
}
-micro-metadata h2 {
+micro-card header h2 {
display: inline;
}
-micro-metadata header {
+micro-card header meta-data {
word-break: break-all;
word-break: break-word;
}
-micro-metadata header a {
+micro-card header meta-data a {
color: inherit;
}
-micro-metadata header > *:not(:last-child) {
+micro-card header meta-data > *:not(:last-child) {
margin-right: 0.5rem;
}
-micro-metadata header > *:hover {
+micro-card header meta-data > *:hover {
color: #111;
color: var(--foreground);
}
-micro-metadata-expiry,
-micro-metadata-draft em,
-micro-metadata-wordcount word-limit em {
+meta-expiry,
+meta-draft em,
+meta-wordcount word-limit em {
color: #8f0000;
color: var(--danger);
font-style: normal;
}
-micro-metadata-draft em {
+meta-draft em {
font-variant: all-small-caps;
}
-micro-header footer svg,
-micro-metadata header svg {
+profile-box footer svg,
+micro-card header meta-data svg {
height: 1rem;
width: 1rem;
- stroke-width: 0.1rem;
+ stroke-width: 0.105rem;
}
-micro-metadata-unlisted {
+meta-unlisted {
font-variant: all-small-caps;
}
s label,
abbr[title],
-abbr[title] label,
-micro-metadata-expiry,
-micro-metadata-readtime,
-micro-metadata-datetime,
-micro-metadata-unlisted,
-micro-metadata-wordcount {
+meta-expiry,
+meta-readtime,
+meta-datetime,
+meta-unlisted,
+meta-wordcount {
cursor: help;
}
-micro-metadata-anchored {
+meta-anchored {
display: flex;
margin-bottom: 0.25rem;
width: 100%;
}
-micro-metadata-anchored > * {
+meta-anchored > * {
margin-right: 0.5rem;
display: flex;
flex-wrap: wrap;
align-items: center;
+ text-decoration: none;
}
-micro-metadata-anchored svg {
+meta-anchored svg {
margin-right: 0.25rem;
}
-micro-metadata-menu {
+meta-anchored a[data-anchored="pinned"] svg {
+ fill: #9ed1fa;
+}
+
+meta-anchored a[data-anchored="marked"] svg {
+ fill: #cd5c5c;
+}
+
+menu {
display: inline-block;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
position: relative;
}
-micro-metadata-menu context-menu {
+menu context-menu {
min-width: 10rem;
}
-micro-metadata-menu context-menu svg {
+menu context-menu svg {
margin-right: 0.25rem;
}
-micro-metadata-menu context-menu a {
+menu context-menu a {
display: block;
padding: 0.5rem 1rem;
}
-micro-metadata-menu context-menu a:hover {
+menu context-menu a:hover {
background-color: #eee;
background-color: var(--hover-background);
border-radius: 0.25rem;
}
-[data-kind] micro-summary article h1 a,
-[data-kind] micro-summary article h2 a,
-[data-kind] micro-summary article h3 a,
-micro-metadata-view a,
-micro-metadata-name a,
-micro-metadata-draft a,
-micro-metadata-handle a,
-micro-metadata a:focus > span,
-micro-metadata context-menu a,
-micro-metadata context-menu a span {
- text-decoration: none;
-}
-
-[data-kind] micro-summary article h1 a:hover,
-[data-kind] micro-summary article h2 a:hover,
-[data-kind] micro-summary article h3 a:hover,
-micro-metadata-menu span,
-micro-metadata-view a span,
-micro-metadata-name a:hover,
-micro-metadata-draft a span,
-micro-metadata-handle a span {
- text-decoration: underline;
+micro-card[id] article h1 a,
+micro-card[id] article h2 a,
+micro-card[id] article h3 a {
+ color: inherit;
}
-anchored-pinned svg {
- fill: #9ed1fa;
+meta-view a,
+meta-name a,
+meta-draft a,
+meta-handle a,
+micro-card[id] article h1 a,
+micro-card[id] article h2 a,
+micro-card[id] article h3 a,
+micro-card header a:focus > span,
+micro-card menu context-menu a,
+micro-card menu context-menu a span {
+ text-decoration: none;
}
-anchored-liked svg {
- fill: #cd5c5c;
+menu span,
+meta-view a span,
+meta-name a:hover,
+meta-draft a span,
+meta-handle a span,
+micro-card[id] article h1 a:hover,
+micro-card[id] article h2 a:hover,
+micro-card[id] article h3 a:hover {
+ text-decoration: underline;
}
-micro-header micro-header-banner img {
+profile-box picture[data-type="banner"] img {
background-color: transparent;
border-radius: 0.125rem;
- height: 12rem;
+ height: 10rem;
width: 100%;
border: none;
}
-micro-header micro-header-picture img {
+profile-box picture[data-type="profile"] img {
border-radius: 100%;
height: 8rem;
margin: -4rem 2rem 0 2rem;
@@ -1172,104 +1343,135 @@ micro-header micro-header-picture img {
padding: 0.25rem;
}
-micro-header section {
+profile-box section {
margin: 1rem 2rem 0 2rem;
- line-height: 1;
display: flex;
align-items: baseline;
}
-micro-header-title {
+profile-box section aside {
flex: 1;
line-height: 1.25;
margin-right: 1rem;
+ display: inline;
}
-micro-header-description {
+profile-box section p {
flex: 6;
}
-micro-header h3 {
+profile-box h3 {
font-weight: 400;
color: #444;
color: var(--fade);
}
-micro-header footer,
-micro-header footer code {
+profile-box footer,
+profile-box footer code {
color: #444;
color: var(--fade);
}
-micro-header footer {
+profile-box footer {
margin: 1.25rem 2rem 0.25rem 2rem;
text-align: center;
font-size: 95%;
}
-micro-header footer p {
+profile-box footer p {
margin: 0.75rem 0.5rem 0.25em 0;
display: inline;
}
-micro-summary article details[data-disclosure] summary {
- display: block;
+micro-card details[data-disclosure] summary {
+ display: inline-block;
margin: 0 -0.25rem 0.5rem -0.25rem;
padding: 0.25rem;
- outline-offset: 0.05rem;
}
-micro-summary article details[data-disclosure] summary:focus a,
-micro-summary article details[data-disclosure] summary:focus:after,
-micro-summary article details[data-disclosure][open] summary:focus:after {
+micro-card details[data-disclosure] summary:focus a {
color: inherit;
- border-color: inherit;
}
-micro-summary article details[data-disclosure] summary:hover {
- text-shadow: 0 0 currentColor;
+following-list details summary:focus:after,
+following-list details[open] summary:focus:after,
+micro-card details[data-disclosure] summary:focus:after,
+micro-card details[data-disclosure][open] summary:focus:after {
+ color: #111;
+ color: var(--foreground);
+ border-color: #111;
}
-micro-summary article details[data-disclosure] summary:after,
-micro-summary article details[data-disclosure][open] summary:after {
- padding: 0 0.5rem;
- margin-left: 1ch;
- border: 2px solid;
- border-color: #ddd;
- border-color: var(--border-darker);
+following-list details summary:after,
+following-list details[open] summary:after,
+micro-card details[data-disclosure] summary:after,
+micro-card details[data-disclosure][open] summary:after {
border-radius: 0.5rem;
- font-variant: small-caps;
+ display: inline;
+ font-size: 85%;
+ vertical-align: bottom;
+}
+
+micro-card details[data-disclosure] summary:hover,
+micro-card details[data-disclosure] summary:hover:after {
+ text-shadow: 0 0 currentColor;
}
-micro-summary article details[data-disclosure] summary:after {
- content: "show";
+micro-card details[data-disclosure] summary:hover:after {
+ text-decoration: underline;
}
-micro-summary article details[data-disclosure][open] summary:after {
- content: "hide";
+micro-card details[data-disclosure] summary:after {
+ content: "HIDDEN";
}
-micro-summary article details[data-disclosure] summary::-webkit-details-marker {
- display: none;
+micro-card details[data-disclosure][open] summary:after {
+ content: "OPENED";
}
-micro-summary article details[data-disclosure] ~ *:not(micro-tags) {
- display: none;
+micro-card details[data-disclosure][open] ~ details summary:after {
+ content: none;
}
-micro-summary article details[data-disclosure][open] ~ * {
+micro-card details[data-disclosure][open] ~ *:not(details):not(micro-tags) {
display: inherit;
}
+micro-card
+ details[data-disclosure][open]
+ ~ *:not(details):not(micro-tags):not(math-ml) {
+ color: #444;
+ color: var(--fade);
+}
+
+micro-card details[data-disclosure][open] ~ details summary {
+ cursor: text;
+}
+
+micro-card details[data-disclosure] ~ *:not(details):not(micro-tags) {
+ display: none;
+}
+
micro-thread related-content footer {
font-size: 100%;
border-bottom: 1px solid;
- border-color: #ccc;
+ border-color: #eee;
border-color: var(--border-lighter);
margin: 0;
padding: 0.5rem 0;
}
+micro-thread nav[data-type="pagination"] {
+ padding: 0.5rem 0;
+ border-bottom: 1px solid;
+ border-color: #eee;
+ border-color: var(--border-lighter);
+}
+
+micro-thread > nav[data-type="pagination"]:last-child {
+ border: none;
+}
+
tab-bar {
display: inline-block;
overflow-x: auto;
@@ -1303,7 +1505,7 @@ tab-bar nav a {
position: relative;
text-decoration: none;
top: 1px;
- border-bottom: 2px solid var(--background);
+ border-bottom: 2px solid transparent;
}
tab-bar nav a:not(:last-child) {
@@ -1315,11 +1517,34 @@ tab-bar nav a[data-draft] {
color: var(--danger);
}
+tab-bar nav a:after {
+ content: attr(data-label);
+ display: block;
+ font-weight: 700;
+ height: 0;
+ overflow: hidden;
+ pointer-events: none;
+ user-select: none;
+ visibility: hidden;
+}
+
tab-bar nav a:hover {
text-decoration: underline;
}
-column-middle main > nav {
+tab-bar nav a span[data-scroll] {
+ position: absolute;
+ top: -4.75rem;
+ left: 200%;
+ width: 0;
+ height: 0;
+}
+
+tab-bar nav a:nth-child(-n + 3) span[data-scroll] {
+ left: -200%;
+}
+
+column-base[position="middle"] > nav:first-child {
align-items: center;
background-color: #fefefe;
background-color: var(--background);
@@ -1332,31 +1557,39 @@ column-middle main > nav {
top: 0;
width: 100%;
z-index: 100;
- height: 4rem;
+ height: inherit;
}
-column-middle main > nav section h2,
-column-middle main > nav section small {
+column-base[position="middle"] > nav:first-child section h2,
+column-base[position="middle"] > nav:first-child section small {
margin: 0;
}
-micro-author micro-header h2,
-micro-author micro-header h3,
-micro-author micro-header time,
-column-middle main > nav section h2,
-column-middle main > nav section small {
- white-space: nowrap;
+micro-author article > *,
+column-base[position="middle"] > nav:first-child section h2,
+column-base[position="middle"] > nav:first-child section small {
overflow: hidden;
text-overflow: ellipsis;
+ white-space: nowrap;
}
-column-middle main > nav section {
+column-base[position="middle"] > nav:first-child section {
line-height: 1.25;
padding: 0 0.5rem;
+ margin-right: 0.5rem;
}
-column-middle main > footer {
- margin: 1rem 0;
+column-base[position="middle"] > footer:last-child {
+ margin: 1rem 0.25rem 3rem 0.25rem;
+}
+
+column-base[position="middle"] main > footer:last-child {
+ padding: 2rem 0 1rem 0;
+}
+
+icon-button,
+icon-navigator {
+ height: 4rem;
}
icon-button a {
@@ -1371,9 +1604,16 @@ icon-button a {
padding: 0.5rem 0;
}
-icon-button,
-icon-navigator {
- height: 4rem;
+icon-button a svg:nth-of-type(2),
+icon-button a small:nth-of-type(2),
+icon-button a[data-update="refresh"] svg:nth-of-type(1),
+icon-button a[data-update="refresh"] small:nth-of-type(1) {
+ display: none;
+}
+
+icon-button a[data-update="refresh"] svg:nth-of-type(2),
+icon-button a[data-update="refresh"] small:nth-of-type(2) {
+ display: block;
}
icon-button a:hover {
@@ -1413,6 +1653,7 @@ code-block pre code {
border-top: 1px solid #ccc;
border-top: 1px solid var(--border-darker);
padding: 0.75rem;
+ white-space: pre;
}
code-block[data-lines] pre code {
@@ -1444,38 +1685,28 @@ code-block header language-label a:hover {
text-decoration: underline;
}
-paginator-navigation {
- padding: 1rem 0.25rem 0 0.25rem;
+code-content {
+ width: 100%;
+}
+
+nav[data-type="pagination"] {
+ padding: 1rem 0;
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
}
-paginator-navigation a {
- margin: 0 0.25rem 0.5rem 0.25rem;
+nav[data-type="pagination"] a {
+ margin: 0.5rem 0.25rem;
font-size: 85%;
display: flex;
align-items: center;
justify-content: center;
}
-web-ring,
-author-list,
-following-list,
-gallery-images {
- padding-bottom: 1rem;
- display: block;
-}
-
-web-ring > h1,
-author-list > h1,
-following-list > h1,
-gallery-images > h1 {
- font-size: 95%;
- margin: 0.5rem 0 1rem 0;
- text-align: center;
- text-transform: uppercase;
+nav[data-type="pagination"] a[title="hidden"] {
+ visibility: hidden;
}
gallery-images aside {
@@ -1487,10 +1718,10 @@ gallery-images aside {
gallery-images a {
display: flex;
- flex-basis: 33.33%;
+ flex-basis: 25%;
flex-grow: 1;
height: 6rem;
- width: 33.333%;
+ width: 25%;
}
gallery-images picture,
@@ -1518,44 +1749,37 @@ gallery-overlay {
z-index: 1;
pointer-events: none;
border: 1px solid;
- border-color: #ccc;
+ border-color: #eee;
border-color: var(--border-lighter);
}
-web-ring {
+web-ring,
+[data-kind="home"] author-list,
+[data-kind="term"] author-list,
+[data-kind="taxonomy"] author-list {
border-radius: 1rem;
position: sticky;
position: -webkit-sticky;
top: 1rem;
}
-web-ring header {
- font-weight: 700;
-}
-
web-ring time,
-micro-author micro-header time {
+micro-author article time {
display: block;
color: #444;
color: var(--fade);
}
-web-ring time {
- font-variant: small-caps;
-}
-
-web-ring p,
-web-ring time {
- display: inline;
-}
-
web-ring p:not(:last-child) {
margin-bottom: 0;
}
-web-ring-item:not(:last-child) {
- margin-bottom: 2rem;
- display: block;
+web-ring article:not(:last-child) {
+ margin-bottom: 1.5rem;
+}
+
+web-ring aside {
+ padding: 1rem;
}
web-ring aside,
@@ -1563,7 +1787,7 @@ author-list aside,
following-list aside {
background-color: #f9f9f9;
background-color: var(--widget-background);
- border-radius: 1rem;
+ border-radius: 0.5rem;
}
web-ring aside footer,
@@ -1573,8 +1797,64 @@ following-list aside footer {
background-color: var(--background);
}
-web-ring aside {
- padding: 1rem;
+web-ring,
+author-list,
+following-list,
+gallery-images {
+ padding-bottom: 1rem;
+ display: block;
+}
+
+web-ring > h1,
+author-list > h1,
+gallery-images > h1,
+following-list details {
+ font-size: 95%;
+ margin: 0.5rem 0 1rem 0;
+ text-align: center;
+ text-transform: uppercase;
+}
+
+following-list details h1 {
+ display: inline-block;
+}
+
+following-list aside micro-author {
+ display: none;
+}
+
+following-list details[open] + aside micro-author,
+following-list aside micro-author:nth-child(-n + 3) {
+ display: inherit;
+}
+
+following-list:hover details[open] + aside {
+ outline: 2px solid #ccc;
+ outline: 2px solid var(--border-darker);
+}
+
+following-list details[data-expand="more"] summary:after {
+ content: "+";
+}
+
+following-list details[open][data-expand="more"] summary:after {
+ content: "-";
+}
+
+following-list details[data-expand="more"] summary:after,
+following-list details[open][data-expand="more"] summary:after {
+ padding: 0 0.5rem;
+ font-size: 100%;
+ margin-left: 0.25rem;
+}
+
+author-list:hover h1,
+following-list:hover details h1 {
+ text-decoration: underline;
+}
+
+author-list h1 a {
+ color: inherit;
}
author-list aside {
@@ -1585,23 +1865,23 @@ author-list p {
display: none;
}
-search-entry {
+search-box {
display: inherit;
width: 100%;
z-index: 1;
}
-search-entry[data-focus],
-search-entry:focus-within {
+search-box[data-focus],
+search-box:focus-within {
position: absolute;
}
-search-entry:focus-within form {
+search-box:focus-within form {
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
-search-entry form {
+search-box form {
background-color: #fefefe;
background-color: var(--background);
border-radius: 0.5rem;
@@ -1609,12 +1889,12 @@ search-entry form {
border-color: #ccc;
border-color: var(--border-darker);
display: inline-flex;
- margin: 0 1rem;
width: 100%;
position: relative;
+ margin: 0 0.5rem;
}
-search-entry form button {
+search-box form button[type="submit"] {
background-color: transparent;
border: none;
box-shadow: none;
@@ -1630,32 +1910,32 @@ search-entry form button {
line-height: 1;
}
-search-entry form input {
+search-box form input {
-webkit-appearance: none;
- background-color: #fefefe;
- background-color: var(--background);
border-bottom-left-radius: 0.5rem;
border-top-left-radius: 0.5rem;
border: none;
font-size: 100%;
- line-height: 1.5;
+ line-height: inherit;
padding-left: 1rem;
padding-right: 1rem;
width: 100%;
color: inherit;
}
-search-entry form button svg {
- stroke-width: 0.1rem;
+search-box form input,
+search-box form input:focus {
+ outline: none;
+ background-color: #fefefe;
+ background-color: var(--text-background);
}
-search-entry form input:focus {
- outline: none;
- background-color: #fefefe !important;
- background-color: var(--background) !important;
+search-box form button svg {
+ stroke-width: 0.1rem;
+ width: 100%;
}
-search-entry ul {
+search-box ul {
position: absolute;
background-color: inherit;
padding-top: 2.9rem;
@@ -1664,17 +1944,17 @@ search-entry ul {
border-radius: 0.5rem;
z-index: -1;
margin-right: 1rem;
- margin-left: -0.05rem;
+ margin-left: -0.065rem;
width: 100.3%;
box-shadow: 0 4px 6px #00000060;
box-shadow: 0 4px 6px var(--shadow);
}
-search-entry ul li a span {
+search-box ul li a span {
font-weight: 400;
}
-search-entry ul li a {
+search-box ul li a {
font-weight: 700;
color: inherit;
text-decoration: none;
@@ -1682,18 +1962,18 @@ search-entry ul li a {
padding: 0.25rem 0.75rem;
}
-search-entry ul li:first-child a {
+search-box ul li:first-child a {
background-color: #ebf3ff;
background-color: var(--hover-background-alternate);
}
-search-entry ul li:only-child a,
-search-entry ul li:last-child a:hover {
+search-box ul li:only-child a,
+search-box ul li:last-child a:hover {
border-bottom-right-radius: 0.5rem;
border-bottom-left-radius: 0.5rem;
}
-search-entry ul li a:hover {
+search-box ul li a:hover {
background-color: #eee;
background-color: var(--hover-background);
}
@@ -1719,8 +1999,7 @@ item-list li:hover span:last-child {
text-decoration: underline;
}
-item-list li > a,
-records-archive li {
+item-list li > a {
display: flex;
text-decoration: none;
align-items: baseline;
@@ -1754,6 +2033,60 @@ item-list a:focus span:last-child {
color: inherit;
}
+time-line h1 {
+ padding: 1rem;
+}
+
+time-line ul {
+ padding: 0 0.5rem;
+}
+
+time-line li:hover {
+ background-color: #eee;
+ background-color: var(--hover-background);
+}
+
+time-line li a {
+ position: relative;
+ border-left: 1px solid;
+ border-color: #ccc;
+ border-color: var(--border-darker);
+ padding: 0.75rem 0.5rem;
+ display: flex;
+ text-decoration: none;
+}
+
+time-line li a:before {
+ position: absolute;
+ background-color: #0149bc;
+ background-color: var(--link);
+ border-radius: 100%;
+ content: "";
+ height: 1rem;
+ width: 1rem;
+ top: 1rem;
+ left: -0.5rem;
+ border: 0.3rem solid #fefefe;
+ border: 0.3rem solid var(--background);
+}
+
+time-line a:focus time,
+time-line a:focus section p {
+ color: inherit;
+}
+
+time-line time,
+time-line section p {
+ color: #444;
+ color: var(--fade);
+}
+
+time-line time {
+ text-transform: uppercase;
+ white-space: nowrap;
+ margin: 0 1rem;
+}
+
tag-deck {
display: flex;
flex-wrap: wrap;
@@ -1822,21 +2155,21 @@ context-menu {
opacity: 0;
}
-context-menu[right] {
+context-menu[position="right"] {
right: 0;
}
-context-menu[left] {
+context-menu[position="left"] {
left: 0;
}
-context-menu[anchor] {
+context-menu[position="anchor"] {
left: -125%;
top: 0;
}
-context-menu[left],
-context-menu[right] {
+context-menu[position="left"],
+context-menu[position="right"] {
top: 1rem;
}
@@ -1869,7 +2202,7 @@ context-profile context-menu {
top: 0.5rem;
text-align: left;
max-width: 20rem;
- transition-delay: 0.3s;
+ transition-delay: 0.5s;
}
micro-card figure:hover context-menu,
@@ -1890,27 +2223,27 @@ diagram-container svg {
background-color: var(--background);
}
-reaction-tip {
+tool-tip[data-type="reaction"] {
text-decoration: underline;
- -webkit-text-decoration-style: wavy;
- text-decoration-style: wavy;
+ -webkit-text-decoration-style: dotted;
+ text-decoration-style: dotted;
text-decoration-thickness: 0.05rem;
- cursor: pointer;
+ cursor: default;
position: relative;
display: inline-block;
}
-reaction-tip:hover {
+tool-tip[data-type="reaction"]:hover {
text-decoration-thickness: 0.1rem;
}
-reaction-tip:hover img {
+tool-tip[data-type="reaction"]:hover img {
opacity: 1;
visibility: visible;
width: 100%;
}
-reaction-tip img {
+tool-tip[data-type="reaction"] img {
position: absolute;
z-index: 99;
visibility: hidden;
@@ -1922,9 +2255,11 @@ reaction-tip img {
transform: translateX(-50%);
max-width: fit-content;
border: none;
+ transition-delay: 0.5s;
}
-main micro-card:first-of-type reaction-tip img {
+body micro-card:first-of-type tool-tip[data-type="reaction"] img,
+main micro-card:first-of-type tool-tip[data-type="reaction"] img {
bottom: 0;
top: 100%;
}
@@ -1963,26 +2298,54 @@ link-card article a {
display: block;
}
+math-ml:not(:last-child) {
+ margin-bottom: 0.75rem;
+}
+
+math-ml figure[id] figure {
+ overflow-x: auto;
+ overflow-y: hidden;
+ border-radius: 0.5rem;
+ padding: 0.75rem 0.5rem;
+ background-color: #f9f9f9;
+ background-color: var(--widget-background);
+ border: 1px solid;
+ border-color: #ccc;
+ border-color: var(--border-darker);
+}
+
+math-ml figure[id] a:first-child {
+ margin: 0 0.125rem;
+ padding: 0 0.25rem;
+ font-weight: 700;
+ color: #0149bc;
+ color: var(--link);
+}
+
+math-ml figure[id]:target figure {
+ background-color: #ffe699;
+ background-color: var(--warning-background);
+ color: #000;
+ outline: 2px solid;
+ border-radius: 0.5rem;
+}
+
/* ----- Attributes ----- */
[tabindex="-1"]:focus {
outline: none;
}
-[hidden] {
+[hidden],
+nav[hidden] {
display: none;
}
-[data-invisible] {
- visibility: hidden;
-}
-
[data-hover] {
text-decoration: none;
}
[data-hover]:hover {
- color: inherit;
text-decoration: underline;
}
@@ -2006,74 +2369,92 @@ link-card article a {
}
[role="doc-endnotes"] hr {
- border-top: 1px solid #ccc;
- border-top: 1px solid var(--border-darker);
margin-bottom: 0.75rem;
- opacity: 0.25;
}
[role="doc-endnotes"] ol {
+ font-size: 90%;
padding-left: 2rem;
}
-[xml-data] micro-summary {
+[data-xml] micro-card {
flex-direction: row;
}
-[xml-data] micro-summary article {
+[data-xml] micro-card article {
margin-left: 0;
}
-[xml-data] micro-thumbnail {
+[data-xml] micro-card header figure {
display: block;
}
-[xml-data] column-middle nav section {
+[data-xml] column-base[position="middle"] nav section {
flex-grow: 1;
}
-[xml-data="sitemap"] main section {
+[data-xml="sitemap"] main section {
padding: 1rem;
}
-[xml-data="sitemap"] section a {
+[data-xml="sitemap"] section a {
text-decoration: none;
}
-[xml-data="sitemap"] section a:hover {
+[data-xml="sitemap"] section a:hover {
text-decoration: underline;
}
/* ----- Responsive ----- */
@media screen and (max-width: 1220px) {
- column-left {
+ column-base[position="left"] {
flex: none;
margin: 0.5rem;
}
- column-left nav a {
+ column-base[position="left"] nav a {
flex-direction: column-reverse;
justify-content: center;
white-space: nowrap;
overflow: hidden;
}
- column-left nav a span {
+ column-base[position="left"] nav a span {
padding-top: 0.5rem;
}
+ column-base[position="right"] {
+ width: 38%;
+ }
+ micro-author micro-card {
+ flex-direction: column;
+ text-align: center;
+ }
+ micro-author micro-card > *:not(:last-child),
+ micro-author micro-card > p:not(:last-child) {
+ margin-bottom: 0.5rem;
+ }
+ micro-author article {
+ flex: none;
+ }
+ micro-author article > * {
+ white-space: normal;
+ }
+ time-line ul {
+ padding: 0 2rem;
+ }
}
-@media screen and (max-width: 1055px) {
- column-left,
- search-entry,
- column-middle main > nav section {
+@media screen and (max-width: 1080px) {
+ search-box,
+ column-base[position="left"],
+ column-base[position="middle"] > nav:first-child section {
display: none;
}
- column-middle main > nav {
+ column-base[position="middle"] > nav:first-child {
justify-content: space-between;
overflow-x: auto;
overflow-y: hidden;
}
- column-middle main > nav icon-navigator[hidden] {
+ column-base[position="middle"] > nav:first-child icon-navigator[hidden] {
display: inline;
}
tag-deck {
@@ -2081,15 +2462,19 @@ link-card article a {
}
}
-@media screen and (max-width: 925px) {
- column-right {
+@media screen and (max-width: 920px) {
+ nav + main,
+ profile-box {
+ margin-top: 4rem;
+ }
+ column-base[position="right"] {
display: none;
}
- column-middle {
+ column-base[position="middle"] {
display: block;
max-width: 100%;
}
- column-middle main > nav {
+ column-base[position="middle"] > nav:first-child {
position: fixed;
box-shadow: 0 4px 12px 0 rgba(0, 0, 0, 0.2);
}
@@ -2097,36 +2482,24 @@ link-card article a {
max-width: 600px;
margin: 0 auto;
}
- micro-metadata {
+ micro-card header {
line-height: inherit;
}
- micro-header section {
+ profile-box section {
display: block;
}
- micro-author micro-header h2,
- micro-author micro-header h3 {
- white-space: initial;
- }
- micro-author micro-summary {
+ micro-author micro-card {
flex-direction: column;
text-align: center;
border-bottom: 1px solid #eee;
border-bottom: 1px solid var(--border-lighter);
}
- micro-author micro-summary micro-header,
- micro-author micro-summary micro-thumbnail,
- micro-author micro-summary p:not(:last-child) {
+ micro-author micro-card article,
+ micro-author micro-card header figure,
+ micro-author micro-card p:not(:last-child) {
flex: auto;
margin: 0 0 0.75rem 0;
}
- navigation-separator hr[hidden] {
- border-color: transparent;
- display: flex;
- height: 0;
- margin: 0;
- padding-top: 4rem;
- border: none;
- }
html {
margin: 0;
}
@@ -2139,17 +2512,17 @@ link-card article a {
tab-bar:focus,
tab-bar:focus-within,
tab-bar:focus-visible,
- column-middle main > nav:active,
- column-middle main > nav:hover,
- column-middle main > nav:focus,
- column-middle main > nav:focus-within,
- column-middle main > nav:focus-visible {
+ column-base[position="middle"] > nav:first-child:active,
+ column-base[position="middle"] > nav:first-child:hover,
+ column-base[position="middle"] > nav:first-child:focus,
+ column-base[position="middle"] > nav:first-child:focus-within,
+ column-base[position="middle"] > nav:first-child:focus-visible {
box-shadow: 1rem -0.2rem 1rem -1rem inset, -1rem -0.2rem 1rem -1rem inset;
}
}
@media screen and (max-width: 460px) {
- micro-summary article {
+ micro-card > article {
margin-left: 0;
}
tag-card {
@@ -2161,23 +2534,25 @@ link-card article a {
/* ----- Self Frames ----- */
@media (max-height: 12rem) {
+ nav + main {
+ margin-top: 0;
+ }
micro-card {
width: 100vw;
padding-right: 1rem;
}
- micro-summary {
+ micro-card {
min-height: 14rem;
}
- :not(#main):target micro-summary,
- :not(#main):target micro-summary:hover {
+ :not(#main):target micro-card,
+ :not(#main):target micro-card:hover {
outline: none;
}
:target::before {
display: none;
}
- main > footer,
- column-middle main > nav,
- navigation-separator hr[hidden] {
+ column-base[position="middle"] > nav:first-child,
+ column-base[position="middle"] > footer:last-child {
display: none;
}
}
@@ -2186,124 +2561,156 @@ link-card article a {
text-animation {
height: 0;
+ cursor: default;
}
text-animation,
text-animation span {
display: inline-block;
+ text-decoration: underline;
+ -webkit-text-decoration-style: double;
+ text-decoration-style: double;
+}
+
+text-animation:hover,
+text-animation:hover span {
+ text-decoration: none;
}
-text-animation[rattle],
-text-animation[default] {
- animation: tilt-rightward 0.15s infinite, tilt-leftward 0.2s infinite;
+text-animation[rattle]:hover,
+text-animation[default]:hover {
+ animation: tilt-rightward 0.1s infinite, tilt-leftward 0.15s infinite;
}
-text-animation[hang] {
+text-animation[hang]:hover {
animation: tilt-rightward 1.3s infinite, tilt-leftward 1.8s infinite;
}
-text-animation[squeeze] {
+text-animation[squeeze]:hover {
animation: squeeze 1s infinite;
}
-text-animation[twitch] {
+text-animation[twitch]:hover {
animation: quiver 2.25s infinite, quiver 1.45s infinite;
}
-text-animation[tremble] {
+text-animation[tremble]:hover {
animation: leftward 0.1s infinite, quiver 0.75s infinite,
quiver 1.35s infinite;
}
-text-animation[grow] {
+text-animation[grow]:hover {
animation: maximize 1.4s infinite;
}
-text-animation[shrink] {
+text-animation[shrink]:hover {
animation: minimize 1.25s infinite;
}
-text-animation[grow],
-text-animation[shrink] {
+text-animation[grow]:hover,
+text-animation[shrink]:hover {
transform-origin: right 1rem;
}
-text-animation[distort] span {
+text-animation[distort]:hover span {
animation: distort 0.25s infinite, distort 0.55s infinite,
distort 0.75s infinite;
}
-text-animation[roll] span {
- animation: rotateY 2s infinite;
- animation-delay: calc(0.2s * var(--frame));
+text-animation[roll]:hover span {
+ animation: rotateY 1.5s infinite;
+ animation-delay: calc(0.1s * var(--frame));
}
-text-animation[flip] span {
- animation: rotateX 2.35s infinite;
- animation-delay: calc(0.2s * var(--frame));
+text-animation[flip]:hover span {
+ animation: rotateX 1.5s infinite;
+ animation-delay: calc(0.1s * var(--frame));
}
-text-animation[twirl] span {
- animation: rotateZ 3s infinite;
- animation-delay: calc(0.2s * var(--frame));
+text-animation[twirl]:hover span {
+ animation: rotateZ 1.5s infinite;
+ animation-delay: calc(0.1s * var(--frame));
}
-text-animation[wave] span {
+text-animation[wave]:hover span {
animation: up 1s infinite;
animation-delay: calc(0.1s * var(--frame));
}
-text-animation[skip] span {
+text-animation[skip]:hover span {
animation: skip 1s infinite;
animation-delay: calc(0.1s * var(--frame));
}
-text-animation[jiggle] span {
+text-animation[jiggle]:hover span {
animation: up 0.2s infinite, down 0.3s infinite, leftward 0.25s infinite;
animation-delay: calc(0.1s * var(--frame));
}
-text-animation[float] span {
+text-animation[float]:hover span {
animation: up 1s infinite;
}
-text-animation[hop] span {
+text-animation[hop]:hover span {
animation: hop 1s infinite;
}
-text-animation[shake] span {
+text-animation[shake]:hover span {
animation: left 0.15s infinite;
}
-text-animation[waggle] span {
+text-animation[waggle]:hover span {
animation: left 0.5s infinite;
}
-text-animation[jump] span {
+text-animation[jump]:hover span {
animation: up 0.15s infinite;
}
-text-animation[vibrate] span {
+text-animation[vibrate]:hover span {
animation: up 0.125s infinite, left 0.15s infinite;
}
+main > * {
+ animation: paint ease-in 0.3s;
+}
+
+tab-bar,
+profile-box {
+ animation: paint ease-in 0.25s;
+}
+
+column-base[position="right"] time {
+ animation: paint ease-in 0.15s;
+}
+
+@keyframes paint {
+ 0%,
+ 90% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
+}
+
@keyframes rotateY {
0%,
- 50% {
+ 10% {
transform: rotateY(360deg);
}
}
@keyframes rotateX {
0%,
- 50% {
+ 10% {
transform: rotateX(360deg);
}
}
@keyframes rotateZ {
0%,
- 50% {
+ 10% {
transform: rotateZ(360deg);
}
}
diff --git a/assets/data/media/logo.png b/assets/data/media/logo.png
index 51baf7d..98b4003 100644
--- a/assets/data/media/logo.png
+++ b/assets/data/media/logo.png
Binary files differ
diff --git a/assets/js/index.js b/assets/js/index.js
index cc61f84..d698127 100644
--- a/assets/js/index.js
+++ b/assets/js/index.js
@@ -3,41 +3,56 @@
if (cookiesDisabled) {
document.cookie = "disabled";
document.cookie.indexOf("disabled");
- return console.log("Pager is disabled due to cookie restrictions.");
+ return console.warn("WARNING: Pager disabled due to cookie restrictions");
}
- let settings = {
- pager: {}
+ let seek;
+ let pager = {};
+ const key = "config.scroll.pager.urls";
+ if (!localStorage[key]) localStorage[key] = JSON.stringify(pager);
+ let url = function() {
+ return self.location.href.split("#")[0].split("?")[0];
};
- const url = self.location.href.split("#")[0].split("?")[0];
- const scrollRestore = (url)=>{
+ const scrollHash = function(url) {
+ const hash = self.location.hash;
+ const fragment = hash.slice(1) && document.getElementById(hash.slice(1));
+ const fragmented = hash.length > 0;
+ const hashed = fragmented && document.body.contains(fragment);
+ if (hashed) {
+ self.location.hash = hash;
+ self.location.href = hash;
+ if ("scroll-margin-top" in document.body.style === false && fragment.textContent !== "") {
+ self.scrollBy(0, -6 * parseFloat(getComputedStyle(document.documentElement).fontSize));
+ }
+ }
+ return hashed;
+ };
+ const scrollRestore = function(url) {
if (history.scrollRestoration) history.scrollRestoration = "manual";
- if (localStorage["settings"]) {
- settings = JSON.parse(localStorage["settings"]);
- }
- const fragment = document.getElementById(location.hash.slice(1));
- const fragmentInURL = self.location.hash.length > 0;
- if (fragmentInURL && document.body.contains(fragment)) {
- settings["pager"][url] = self.pageYOffset;
- localStorage["settings"] = JSON.stringify(settings);
- fragment.scrollIntoView();
- self.addEventListener("load", function() {
- fragment.scrollIntoView();
- });
- return;
- }
- if (settings["pager"][url] > 0) {
- self.scrollTo(0, settings["pager"][url]);
- return;
- }
- settings["pager"][url] = self.pageYOffset;
- localStorage["settings"] = JSON.stringify(settings);
+ if (scrollHash(url)) return;
+ pager = JSON.parse(localStorage[key]);
+ if (pager[url] > 0) {
+ clearInterval(seek);
+ self.scrollTo(0, pager[url]);
+ let i1 = 0;
+ return seek = setInterval(function(position) {
+ i1++;
+ if (i1 > 100) clearInterval(seek);
+ if (document.documentElement.scrollHeight >= position + document.documentElement.clientHeight) {
+ clearInterval(seek);
+ self.scrollTo(0, position);
+ }
+ }, 4, pager[url]);
+ } else self.scrollTo(0, 0);
+ pager[url] = self.pageYOffset;
+ localStorage[key] = JSON.stringify(pager);
};
- const scrollTrack = (url)=>{
+ const scrollTrack = function(url) {
const currentPosition = self.pageYOffset;
- settings["pager"][url] = currentPosition;
- localStorage["settings"] = JSON.stringify(settings);
+ pager = JSON.parse(localStorage[key]);
+ pager[url] = currentPosition;
+ localStorage[key] = JSON.stringify(pager);
};
- const backTrack = (back, up, event)=>{
+ const scrollReverse = function(back, up, event) {
if (document.body.contains(up) && up.contains(event.target)) {
event.preventDefault();
window.scrollTo(0, 0);
@@ -48,19 +63,106 @@
history.go(-1);
}
};
- self.addEventListener("DOMContentLoaded", function() {
- scrollRestore(url);
- self.addEventListener("click", function(event) {
- const up = document.getElementById("top");
- const back = document.getElementById("back");
- backTrack(back, up, event);
+ [
+ "DOMContentLoaded",
+ "pageshow",
+ "hashchange",
+ "URLChangedCustomEvent"
+ ].forEach(function(event) {
+ self.addEventListener(event, function(event) {
+ if (event.type === "pageshow") {
+ return event.persisted && self.scrollTo(0, pager[url()]);
+ }
+ if (event.type === "DOMContentLoaded") {
+ self.addEventListener("click", function(event) {
+ const up = document.getElementById("top");
+ const back = document.getElementById("back");
+ scrollReverse(back, up, event);
+ });
+ }
+ scrollRestore(url());
});
});
+ [
+ "click",
+ "touchstart",
+ "scroll"
+ ].forEach(function(event) {
+ self.addEventListener(event, function() {
+ scrollTrack(url());
+ });
+ });
+})();
+(function() {
+ const cookiesDisabled = !navigator.cookieEnabled;
+ if (cookiesDisabled) {
+ document.cookie = "disabled";
+ document.cookie.indexOf("disabled");
+ return console.warn("WARNING: Update check disabled due to cookie restrictions");
+ }
+ function fetch(url, method, callback) {
+ const http = new XMLHttpRequest();
+ http.onreadystatechange = function() {
+ if (http.readyState === 4 && http.status === 200) {
+ if (callback) callback(http);
+ }
+ };
+ http.open(method, url);
+ http.setRequestHeader("Pragma", "no-cache");
+ http.setRequestHeader("Cache-Control", "no-cache");
+ http.send();
+ return http;
+ }
+ const key = "config.update";
+ let stamps = {};
+ if (!sessionStorage[key + ".urls"]) sessionStorage[key + ".urls"] = JSON.stringify(stamps);
+ function update() {
+ const url = self.location.href.split("#")[0].split("?")[0];
+ const indicator = document.querySelector("a[data-update]");
+ if (indicator === null || indicator.dataset.update === "refresh") return;
+ indicator.cloneNode();
+ fetch(url, "HEAD", function(request) {
+ const local = document.querySelector('meta[name="last-modified"]').content || document.lastModified;
+ const remote = request.getResponseHeader("last-modified") || '';
+ const modified = Date.parse(remote || local) > Date.parse(local);
+ const drift = Date.parse(remote || local) - Date.parse(local);
+ if (drift < 10000) return;
+ stamps = JSON.parse(sessionStorage[key + ".urls"]);
+ if (stamps[url] === remote) return;
+ stamps[url] = remote;
+ sessionStorage[key + ".urls"] = JSON.stringify(stamps);
+ if (remote && modified) {
+ fetch(url, "GET", function() {
+ indicator.href = url.replace(/^https:/, "http:");
+ indicator.removeAttribute("id");
+ indicator.dataset.update = "refresh";
+ console.log("INFO: R: " + remote);
+ console.log("INFO: L: " + local);
+ console.log("INFO: D: " + drift);
+ console.log("INFO: M: " + modified);
+ });
+ }
+ });
+ }
+ let scrolled;
+ let delay = 1000;
+ let delayed = 0;
self.addEventListener("scroll", function() {
- scrollTrack(url);
+ if (scrolled) clearTimeout(scrolled);
+ scrolled = setTimeout(function() {
+ update();
+ delay = delay + delayed;
+ delayed = delay - delayed;
+ }, delay);
});
- self.addEventListener("hashchange", function() {
- scrollRestore(url);
+ [
+ "focus",
+ "load",
+ "URLChangedCustomEvent"
+ ].forEach(function(event) {
+ self.addEventListener(event, function() {
+ update();
+ });
});
})();
(function() {
@@ -95,217 +197,92 @@
}
})();
(function() {
- self.addEventListener("DOMContentLoaded", function() {
- let mouseoverTimer;
- let lastTouchTimestamp;
- const prefetches = new Set();
- const prefetchElement = document.createElement("link");
- const isSupported = prefetchElement.relList && prefetchElement.relList.supports && prefetchElement.relList.supports("prefetch") && window.IntersectionObserver && "isIntersecting" in IntersectionObserverEntry.prototype;
- const allowQueryString = "instantAllowQueryString" in document.body.dataset;
- const allowExternalLinks = "instantAllowExternalLinks" in document.body.dataset;
- const useWhitelist = "instantWhitelist" in document.body.dataset;
- const mousedownShortcut = "instantMousedownShortcut" in document.body.dataset;
- let delayOnHover = 65;
- let useMousedown = false;
- let useMousedownOnly = false;
- let useViewport = false;
- if ("instantIntensity" in document.body.dataset) {
- const intensity = document.body.dataset.instantIntensity;
- if (intensity.substr(0, "mousedown".length) == "mousedown") {
- useMousedown = true;
- if (intensity == "mousedown-only") {
- useMousedownOnly = true;
- }
- } else if (intensity.substr(0, "viewport".length) == "viewport") {
- if (!(navigator.connection && (navigator.connection.saveData || navigator.connection.effectiveType && navigator.connection.effectiveType.includes("2g")))) {
- if (intensity == "viewport") {
- if (document.documentElement.clientWidth * document.documentElement.clientHeight < 450000) {
- useViewport = true;
- }
- } else if (intensity == "viewport-all") {
- useViewport = true;
- }
- }
- } else {
- const milliseconds = parseInt(intensity);
- if (!isNaN(milliseconds)) {
- delayOnHover = milliseconds;
- }
- }
- }
- if (isSupported) {
- const eventListenersOptions = {
- capture: true,
- passive: true
+ if (typeof Element !== "undefined") {
+ if (!Element.prototype.matches) {
+ Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
+ }
+ if (!Element.prototype.closest) {
+ Element.prototype.closest = function(s) {
+ var el = this;
+ do {
+ if (el.matches(s)) return el;
+ el = el.parentElement || el.parentNode;
+ }while (el !== null && el.nodeType === 1)
+ return null;
};
- if (!useMousedownOnly) {
- document.addEventListener("touchstart", touchstartListener, eventListenersOptions);
- }
- if (!useMousedown) {
- document.addEventListener("mouseover", mouseoverListener, eventListenersOptions);
- } else if (!mousedownShortcut) {
- document.addEventListener("mousedown", mousedownListener, eventListenersOptions);
- }
- if (mousedownShortcut) {
- document.addEventListener("mousedown", mousedownShortcutListener, eventListenersOptions);
- }
- if (useViewport) {
- let triggeringFunction;
- if (window.requestIdleCallback) {
- triggeringFunction = function(callback) {
- requestIdleCallback(callback, {
- timeout: 1500
- });
- };
- } else {
- triggeringFunction = function(callback) {
- callback();
- };
- }
- triggeringFunction(function() {
- const intersectionObserver = new IntersectionObserver(function(entries) {
- entries.forEach(function(entry) {
- if (entry.isIntersecting) {
- const linkElement = entry.target;
- intersectionObserver.unobserve(linkElement);
- preload(linkElement.href);
- }
- });
- });
- document.querySelectorAll("a").forEach(function(linkElement) {
- if (isPreloadable(linkElement)) {
- intersectionObserver.observe(linkElement);
- }
- });
- });
- }
}
- function touchstartListener(event) {
- lastTouchTimestamp = performance.now();
- const linkElement = event.target.closest("a");
- if (!isPreloadable(linkElement)) {
- return;
- }
- preload(linkElement.href);
- }
- function mouseoverListener(event) {
- if (performance.now() - lastTouchTimestamp < 1111) {
- return;
- }
- const linkElement = event.target.closest("a");
- if (!isPreloadable(linkElement)) {
- return;
- }
- linkElement.addEventListener("mouseout", mouseoutListener, {
- passive: true
+ }
+ function fetch(url, method, callback) {
+ const http = new XMLHttpRequest();
+ http.onreadystatechange = function() {
+ if (http.readyState === 4 && http.status === 200) {
+ if (callback) callback(http);
+ }
+ };
+ http.open(method, url);
+ http.send();
+ return http;
+ }
+ self.addEventListener("DOMContentLoaded", function() {
+ [
+ "mouseout",
+ "mousedown",
+ "touchstart"
+ ].forEach(function(event) {
+ self.addEventListener(event, function(event) {
+ const url = event.target.closest("a");
+ if (preloadable(url) === undefined) return;
+ preload(url.href);
});
- mouseoverTimer = setTimeout(function() {
- preload(linkElement.href);
- mouseoverTimer = undefined;
- }, delayOnHover);
- }
- function mousedownListener(event) {
- const linkElement = event.target.closest("a");
- if (!isPreloadable(linkElement)) {
- return;
- }
- preload(linkElement.href);
- }
- function mouseoutListener(event) {
- if (event.relatedTarget && event.target.closest("a") == event.relatedTarget.closest("a")) {
- return;
- }
- if (mouseoverTimer) {
- clearTimeout(mouseoverTimer);
- mouseoverTimer = undefined;
- }
- }
- function mousedownShortcutListener(event) {
- if (performance.now() - lastTouchTimestamp < 1111) {
- return;
- }
- const linkElement = event.target.closest("a");
- if (event.which > 1 || event.metaKey || event.ctrlKey) {
- return;
- }
- if (!linkElement) {
- return;
- }
- linkElement.addEventListener("click", function(event) {
- if (event.detail == 1337) {
+ });
+ function preloadable(url) {
+ switch(true){
+ case url === null || url.href === null:
return;
- }
- event.preventDefault();
- }, {
- capture: true,
- passive: false,
- once: true
- });
- const customEvent = new MouseEvent("click", {
- view: window,
- bubbles: true,
- cancelable: false,
- detail: 1337
- });
- linkElement.dispatchEvent(customEvent);
- }
- function isPreloadable(linkElement) {
- if (!linkElement || !linkElement.href) {
- return;
- }
- if (useWhitelist && !("instant" in linkElement.dataset)) {
- return;
- }
- if (!allowExternalLinks && linkElement.origin != location.origin && !("instant" in linkElement.dataset)) {
- return;
- }
- if (![
- "http:",
- "https:"
- ].includes(linkElement.protocol)) {
- return;
- }
- if (linkElement.protocol == "http:" && location.protocol == "https:") {
- return;
- }
- if (!allowQueryString && linkElement.search && !("instant" in linkElement.dataset)) {
- return;
- }
- if (linkElement.hash && linkElement.pathname + linkElement.search == location.pathname + location.search) {
- return;
- }
- if ("noInstant" in linkElement.dataset) {
- return;
+ case url.origin !== location.origin:
+ return;
+ case [
+ "http:",
+ "https:"
+ ].includes(url.protocol) === null:
+ return;
+ case url.protocol === "http:" && location.protocol === "https:":
+ return;
+ case url.hash && url.pathname + url.search == location.pathname + location.search:
+ return;
+ default:
+ return true;
}
- return true;
}
function preload(url) {
- if (prefetches.has(url)) {
- return;
- }
const prefetcher = document.createElement("link");
- prefetcher.rel = "prefetch";
+ prefetcher.rel = "custom-prefetch";
prefetcher.href = url;
+ const selector = 'link[rel="'.concat(prefetcher.rel, '"][href="').concat(prefetcher.href, '"]');
+ const prefetched = document.head.contains(document.querySelector(selector));
+ if (prefetched) {
+ return;
+ }
document.head.appendChild(prefetcher);
- prefetches.add(url);
+ fetch(url, "GET", function() {});
}
});
})();
(function() {
- const hide = (triggers)=>{
- for(let i = 0; i < triggers.length; i++){
- triggers[i].checked = false;
+ const hide = function(triggers) {
+ for(let i1 = 0; i1 < triggers.length; i1++){
+ triggers[i1].checked = false;
}
};
- const hideIfClickedOutside = (menus, triggers, event)=>{
- for(let i = 0; i < menus.length; i++){
- const active = triggers[i].checked === true;
- const outside = !menus[i].contains(event.target);
+ const hideIfClickedOutside = function(menus, triggers, event) {
+ for(let i1 = 0; i1 < menus.length; i1++){
+ const active = triggers[i1].checked === true;
+ const outside = !menus[i1].contains(event.target);
if (outside && active) hide(triggers);
}
};
self.addEventListener("scroll", function() {
- const triggers = document.querySelectorAll("micro-metadata-menu input");
+ const triggers = document.querySelectorAll("menu input");
hide(triggers);
});
[
@@ -313,196 +290,512 @@
"touchstart"
].forEach(function(event) {
self.addEventListener(event, function(event) {
- const menus = document.querySelectorAll("micro-metadata-menu");
- const triggers = document.querySelectorAll("micro-metadata-menu input");
+ const menus = document.querySelectorAll("menu");
+ const triggers = document.querySelectorAll("menu input");
hideIfClickedOutside(menus, triggers, event);
});
});
})();
(function() {
- self.addEventListener("DOMContentLoaded", function() {
- const form = document.getElementById("search-form");
- const query = document.getElementById("search-input");
- const submit = document.getElementById("search-submit");
- const dropdown = document.getElementById("search-results");
- const container = document.getElementById("search-frame");
- function first(element) {
- return element.firstChild.nextElementSibling.firstChild.nextElementSibling;
- }
- function last(element) {
- return element.lastElementChild.firstChild.nextElementSibling;
- }
- function next(element) {
- return element.activeElement.parentElement.nextElementSibling.firstChild.nextElementSibling.focus();
- }
- function previous(element) {
- return element.activeElement.parentElement.previousElementSibling.firstChild.nextElementSibling.focus();
- }
- function press(keyname) {
- document.dispatchEvent(new KeyboardEvent("keydown", {
- "key": keyname
- }));
- }
- submit.addEventListener("click", function(event) {
- first(dropdown).focus();
- press("ArrowDown");
- });
- form.addEventListener("focusin", function() {
- container.setAttribute("data-focus", "");
- initialize();
- });
- form.addEventListener("submit", function(event) {
- event.preventDefault();
- return false;
- });
- form.addEventListener("keydown", function(event) {
- const head = first(dropdown);
- const tail = last(dropdown);
- if (query.contains(event.target)) {
- if (event.keyCode == 27) {
- document.activeElement.blur();
- dropdown.setAttribute("hidden", "");
- container.removeAttribute("data-focus");
+ [
+ "DOMContentLoaded",
+ "URLChangedCustomEvent"
+ ].forEach(function(event) {
+ self.addEventListener(event, function() {
+ const container = document.querySelector("search-box");
+ const dropdown = document.querySelector("search-box ul");
+ const form = document.querySelector("search-box form");
+ const query = document.querySelector("search-box input");
+ const submit = document.querySelector("search-box button");
+ function first(element) {
+ if (element.firstChild.nextElementSibling) {
+ return element.firstChild.nextElementSibling.firstChild.nextElementSibling;
}
}
- if (event.keyCode == 40) {
- event.preventDefault();
- if (document.activeElement == query) head.focus();
- else if (document.activeElement == tail) query.focus();
- else next(document);
+ function last(element) {
+ return element.lastElementChild.firstChild.nextElementSibling;
}
- if (event.keyCode == 38) {
- event.preventDefault();
- if (document.activeElement == query) tail.focus();
- else if (document.activeElement == head) query.focus();
- else previous(document);
+ function next(element) {
+ return element.activeElement.parentElement.nextElementSibling.firstChild.nextElementSibling.focus();
}
- if (event.keyCode == 8) {
- if (document.activeElement != query) {
+ function previous(element) {
+ return element.activeElement.parentElement.previousElementSibling.firstChild.nextElementSibling.focus();
+ }
+ function press(keyname) {
+ document.dispatchEvent(new KeyboardEvent("keydown", {
+ "key": keyname
+ }));
+ }
+ let selected;
+ if (submit === null) return;
+ submit.addEventListener("click", function(event) {
+ if (selected) {
event.preventDefault();
- query.focus();
+ selected.focus();
+ return selected.click();
}
- }
- if (event.keyCode == 13) {
- if (dropdown && document.activeElement == query) {
+ first(dropdown).focus();
+ press("ArrowDown");
+ document.activeElement.click();
+ });
+ [
+ "keyup",
+ "click"
+ ].forEach(function(event) {
+ form.addEventListener(event, function() {
+ if (document.activeElement.nodeName === "A") {
+ return selected = document.activeElement;
+ }
+ selected = undefined;
+ });
+ });
+ form.addEventListener("focusin", function() {
+ container.setAttribute("data-focus", "");
+ initialize();
+ });
+ form.addEventListener("submit", function(event) {
+ event.preventDefault();
+ return false;
+ });
+ form.addEventListener("keydown", function(event) {
+ if (form.contains(event.target)) {
+ if (event.keyCode == 27) {
+ document.activeElement.blur();
+ dropdown.setAttribute("hidden", "");
+ container.removeAttribute("data-focus");
+ }
+ }
+ if (event.keyCode == 8) {
+ if (document.activeElement != query) {
+ event.preventDefault();
+ query.focus();
+ }
+ }
+ const head = first(dropdown);
+ const tail = last(dropdown);
+ if (event.keyCode == 40) {
+ event.preventDefault();
+ if (document.activeElement == query) head.focus();
+ else if (document.activeElement == tail) query.focus();
+ else next(document);
+ }
+ if (event.keyCode == 38) {
event.preventDefault();
- head.focus();
- self.window.location = document.activeElement.href;
+ if (document.activeElement == query) tail.focus();
+ else if (document.activeElement == head) query.focus();
+ else previous(document);
+ }
+ if (event.keyCode == 13) {
+ if (dropdown && document.activeElement == query) {
+ event.preventDefault();
+ head.focus();
+ head.click();
+ }
+ }
+ });
+ let scrolls = 0;
+ self.addEventListener("scroll", function() {
+ if (scrolls > 3) {
+ scrolls = 0;
+ document.activeElement.blur();
+ dropdown.setAttribute("hidden", "");
+ container.removeAttribute("data-focus");
}
+ scrolls++;
+ });
+ self.addEventListener("click", function(event) {
+ if (!form.contains(event.target) && !(document.activeElement === query) && !(document.activeElement === submit)) {
+ dropdown.setAttribute("hidden", "");
+ container.removeAttribute("data-focus");
+ }
+ });
+ function fetch(url, callback) {
+ const http = new XMLHttpRequest();
+ http.onreadystatechange = function() {
+ if (http.readyState === 4 && http.status === 200 && callback) {
+ callback(http);
+ }
+ };
+ http.open("GET", url);
+ http.send();
+ }
+ function script(url) {
+ return new Promise(function(resolve, reject) {
+ const script = document.createElement("script");
+ script.onerror = reject;
+ script.onload = resolve;
+ if (document.currentScript) {
+ document.currentScript.parentNode.insertBefore(script, document.currentScript);
+ } else document.head.appendChild(script);
+ script.src = url;
+ });
}
- });
- let scrolls = 0;
- self.addEventListener("scroll", function() {
- if (scrolls > 3) {
- scrolls = 0;
- document.activeElement.blur();
- dropdown.setAttribute("hidden", "");
- container.removeAttribute("data-focus");
+ let data = {};
+ let boot = true;
+ const options = {
+ key: [
+ "title"
+ ]
+ };
+ function isEmpty(obj) {
+ return Object.keys(obj).length === 0;
+ }
+ function appendItemsTo(local, remote) {
+ const paginated = Object.keys(remote).includes("next_url");
+ if (isEmpty(local)) {
+ local = remote;
+ } else {
+ local.items = local.items.concat(remote.items);
+ }
+ if (paginated) {
+ fetch(remote.next_url, function(request) {
+ appendItemsTo(local, JSON.parse(request.responseText));
+ });
+ } else search(query.value, data.items, options);
+ data = local;
+ }
+ function initialize() {
+ if (boot) {
+ script(window.location.origin + "/js/fuzzysort.js").then(function() {
+ fetch("/index.json", function(request) {
+ appendItemsTo({}, JSON.parse(request.responseText));
+ search("", data.items, options);
+ boot = false;
+ });
+ [
+ "keyup",
+ "focusin"
+ ].forEach(function(event) {
+ query.addEventListener(event, function() {
+ if (data.items) search(query.value, data.items, options);
+ else {
+ boot = true;
+ initialize();
+ }
+ });
+ });
+ }).catch(function(error) {
+ console.error("ERROR: Failed to load fuzzy search", error);
+ });
+ }
+ }
+ function escape(text) {
+ const escaped = document.createElement("textarea");
+ escaped.textContent = text;
+ return escaped.innerHTML;
+ }
+ function search(term, data, options) {
+ const results = fuzzysort.go(term, data, options);
+ let items = "";
+ if (results.length === 0 && term.length >= 0) {
+ let separator = "—";
+ if (term.length === 0) separator = "";
+ items = '<li><a tabindex="0">'.concat(escape(term), " ").concat(separator, " No Results Found</a></li>");
+ dropdown.removeAttribute("hidden");
+ container.setAttribute("data-focus", "");
+ } else {
+ dropdown.removeAttribute("hidden");
+ for(var string in results.slice(0, 10)){
+ const title = results[string].obj.title;
+ let highlight = fuzzysort.highlight(fuzzysort.single(escape(term), escape(title)), "<span>", "</span>");
+ if (highlight === null) highlight = title;
+ items = items + '\n<li>\n<a href="'.concat(results[string].obj.url, '" tabindex="0">').concat(highlight, "</a>\n</li>\n");
+ }
+ }
+ dropdown.innerHTML = items;
}
- scrolls++;
});
- document.addEventListener("click", function(event) {
- if (!form.contains(event.target)) {
- dropdown.setAttribute("hidden", "");
- container.removeAttribute("data-focus");
+ });
+})();
+(function() {
+ function viewport(element) {
+ const options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {
+ offset: {
+ top: -50,
+ left: 0,
+ bottom: -50,
+ right: 0
+ }
+ };
+ const view = element.getBoundingClientRect();
+ return view.top >= -options.offset.top && view.left >= -options.offset.left && view.bottom <= (self.innerHeight || document.documentElement.clientHeight) + options.offset.bottom && view.right <= (self.innerWidth || document.documentElement.clientWidth) + options.offset.right;
+ }
+ [
+ "scroll",
+ "DOMContentLoaded"
+ ].forEach(function(event) {
+ self.addEventListener(event, function() {
+ let first = true;
+ let videos = document.querySelectorAll("video");
+ for(i = 0; i < videos.length; i++){
+ videos[i].autoplay = true;
+ videos[i].controls = true;
+ videos[i].loop = true;
+ videos[i].muted = true;
+ videos[i].playsinline = true;
+ videos[i].setAttribute("autoplay", true);
+ videos[i].setAttribute("controls", true);
+ videos[i].setAttribute("loop", true);
+ videos[i].setAttribute("muted", true);
+ videos[i].setAttribute("playsinline", true);
+ const onscreen = viewport(videos[i]);
+ if (first && onscreen) {
+ videos[i].play();
+ first = false;
+ } else {
+ videos[i].pause();
+ }
}
});
- let data = {};
- function isEmpty(obj) {
- return Object.keys(obj).length === 0;
+ });
+})();
+(function() {
+ if (typeof Element !== "undefined") {
+ if (!Element.prototype.matches) {
+ Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector;
+ }
+ if (!Element.prototype.closest) {
+ Element.prototype.closest = function(s) {
+ var el = this;
+ do {
+ if (el.matches(s)) return el;
+ el = el.parentElement || el.parentNode;
+ }while (el !== null && el.nodeType === 1)
+ return null;
+ };
}
- function appendItemsTo(local, remote) {
- const paginated = Object.keys(remote).includes("next_url");
- if (isEmpty(local)) {
- local = remote;
- } else {
- local.items = local.items.concat(remote.items);
- }
- if (paginated) {
- fetchJson(remote.next_url, local);
- }
- data = local;
+ }
+ const disabled = "0s";
+ function walk(children, callback) {
+ for(let i1 = 0; i1 < children.length; i1++){
+ callback(children[i1]);
+ walk(children[i1].children, callback);
}
- function fetchJson(url, store) {
- const httpRequest = new XMLHttpRequest();
- httpRequest.onreadystatechange = function() {
- if (httpRequest.readyState === 4 && httpRequest.status === 200) {
- appendItemsTo(store, JSON.parse(httpRequest.responseText));
+ }
+ self.addEventListener("mousemove", function(event) {
+ if (typeof event.target.closest !== "function") return;
+ tree = event.target.closest("figure") || event.target.closest("article");
+ if (tree !== null) {
+ walk(tree.children, function(element) {
+ const delay = self.getComputedStyle(element).getPropertyValue("transition-delay");
+ if (delay !== disabled) {
+ element.style.setProperty("visibility", "hidden");
}
- };
- httpRequest.open("GET", url);
- httpRequest.send();
- }
- function loadScript(url) {
- return new Promise(function(resolve, reject) {
- const script = document.createElement("script");
- script.onerror = reject;
- script.onload = resolve;
- if (document.currentScript) {
- document.currentScript.parentNode.insertBefore(script, document.currentScript);
- } else {
- document.head.appendChild(script);
+ });
+ walk(tree.children, function(element) {
+ const delay = self.getComputedStyle(element).getPropertyValue("transition-delay");
+ if (delay !== disabled) {
+ element.style.removeProperty("visibility");
}
- script.src = url;
});
}
- let firstRun = true;
- function initialize() {
- if (firstRun) {
- loadScript(window.location.origin + "/js/fuzzysort.js").then(()=>{
- firstRun = false;
- fetchJson("/index.json", {});
- const options = {
- key: [
- "title"
- ]
- };
- query.addEventListener("keyup", function() {
- search(query.value, data.items, options);
- });
- query.addEventListener("focusin", function() {
- search(query.value, data.items, options);
- });
- search(query.value, data.items, options);
- }).catch((error)=>{
- console.log("Error failed to load fuzzy sort: " + error);
+ });
+})();
+(function() {
+ const cookiesDisabled = !navigator.cookieEnabled;
+ if (cookiesDisabled) {
+ document.cookie = "disabled";
+ document.cookie.indexOf("disabled");
+ return console.warn("WARNING: Cannot persist form state due to cookie restrictions");
+ }
+ const storage = document.createEvent("Event");
+ storage.initEvent("storage", true, true);
+ [
+ "pageshow",
+ "URLChangedCustomEvent",
+ "DOMContentLoaded"
+ ].forEach(function(event) {
+ self.addEventListener(event, function(event) {
+ const input = Array.prototype.slice.call(document.querySelectorAll("form input"));
+ const select = Array.prototype.slice.call(document.querySelectorAll("form select"));
+ const textarea = Array.prototype.slice.call(document.querySelectorAll("form textarea"));
+ const summary = Array.prototype.slice.call(document.querySelectorAll("details summary"));
+ const states = input.concat(select).concat(textarea);
+ for(var i1 = 0; i1 < states.length; i1++){
+ const state = states[i1];
+ const sync = i1 === states.length - 1;
+ if (localStorage[state.id]) {
+ if (state.type === "radio" || state.type === "checkbox") {
+ if (localStorage[state.id] === "on") state.checked = true;
+ } else state.value = localStorage[state.id];
+ }
+ if (sync) self.dispatchEvent(storage);
+ state.addEventListener("change", function(event) {
+ localStorage[event.target.id] = event.target.value;
+ const group = document.querySelectorAll("input[name='".concat(event.target.name, "']"));
+ for(var j = 0; j < group.length; j++){
+ const member = group[j];
+ if ((member.type === "radio" || member.type === "checkbox") && !member.checked) {
+ localStorage[member.id] = "off";
+ }
+ }
+ self.dispatchEvent(new Event("storage"));
});
}
- }
- function escape(text) {
- const escaped = document.createElement("textarea");
- escaped.textContent = text;
- return escaped.innerHTML;
- }
- function search(term, data, options) {
- const results = fuzzysort.go(term, data, options);
- let items = "";
- if (results.length === 0 && term.length >= 0) {
- let separator = "—";
- if (term.length === 0) separator = "";
- items = `
- <li>
- <a href="javascript: void(0)" tabindex="0">${escape(term)} ${separator} No Results Found</a>
- </li>
- `;
- dropdown.removeAttribute("hidden");
- container.setAttribute("data-focus", "");
- } else {
- dropdown.removeAttribute("hidden");
- for(const string in results.slice(0, 10)){
- const title = results[string].obj.title;
- let highlight = fuzzysort.highlight(fuzzysort.single(escape(term), escape(title)), "<span>", "</span>");
- if (highlight === null) {
- highlight = title;
+ for(var k = 0; k < summary.length; k++){
+ let child = summary[k];
+ let details = child.parentElement;
+ if (details.id && details.nodeName === "DETAILS") {
+ sessionStorage[details.id] === "false" && details.removeAttribute("open");
+ sessionStorage[details.id] === "true" && details.setAttribute("open", true);
+ child.addEventListener("click", function(event) {
+ let child = event.target.nodeName === "SUMMARY" && event.target || event.target.parentElement;
+ let details = child.parentElement;
+ if (details.id && details.nodeName === "DETAILS") {
+ sessionStorage[details.id] = !details.open;
+ }
+ });
+ }
+ }
+ });
+ });
+ [
+ "storage"
+ ].forEach(function(event) {
+ self.addEventListener(event, function() {
+ let stylesheet;
+ stylesheet = document.querySelector('link[href$="default-simple.css"]');
+ if (localStorage["config.layout.simple"] === "on") stylesheet.rel = "stylesheet";
+ if (localStorage["config.layout.default"] === "on") stylesheet.rel = "alternate stylesheet";
+ stylesheet = document.querySelector('link[href$="default-fast.css"]');
+ if (localStorage["config.navigation.fast"] === "on") stylesheet.rel = "stylesheet";
+ if (localStorage["config.navigation.slow"] === "on") stylesheet.rel = "alternate stylesheet";
+ for(var i1 = 0; i1 < document.styleSheets.length; i1++){
+ let stylesheet = document.styleSheets[i1];
+ for(var k = 0; k < stylesheet.rules.length; k++){
+ let media = stylesheet.rules[k].media;
+ if (media && media.mediaText.includes("prefers-color-scheme")) {
+ if (localStorage["config.theme.light"] === "on") {
+ media.mediaText = "(prefers-color-scheme: dark)";
+ if (getComputedStyle(document.body).getPropertyValue("color-scheme") === "dark") {
+ media.mediaText = "(prefers-color-scheme: light)";
+ }
+ }
+ if (localStorage["config.theme.auto"] === "on") {
+ media.mediaText = "(prefers-color-scheme: dark)";
+ }
+ if (localStorage["config.theme.dark"] === "on") {
+ media.mediaText = "(prefers-color-scheme: light)";
+ if (getComputedStyle(document.body).getPropertyValue("color-scheme") === "light") {
+ media.mediaText = "(prefers-color-scheme: dark)";
+ }
+ }
}
- items = items + `
- <li>
- <a href="${results[string].obj.url}" tabindex="0">${highlight}</a>
- </li>
- `;
}
}
- dropdown.innerHTML = items;
+ });
+ });
+ const early = setInterval(persistence, 4);
+ function persistence() {
+ if (document.styleSheets.length > 0) {
+ self.dispatchEvent(storage);
+ clearInterval(early);
+ }
+ }
+ self.addEventListener("DOMContentLoaded", function() {
+ self.dispatchEvent(storage);
+ clearInterval(early);
+ });
+})();
+(function() {
+ const timeout = 300;
+ const state = "on";
+ const key = "config.navigation.fast";
+ function fetch(url, method, callback) {
+ const http = new XMLHttpRequest();
+ http.onreadystatechange = function() {
+ if (callback && http.readyState === 4) {
+ if (http.status === 200) callback(http);
+ else {
+ console.error("ERROR: Unable to navigate", http);
+ self.location.href = url;
+ }
+ }
+ };
+ http.open(method, url);
+ http.timeout = timeout;
+ http.send();
+ return http;
+ }
+ function styles(node) {
+ return node.nodeName === "LINK" && node.rel && node.rel.includes("stylesheet");
+ }
+ function scripts(node) {
+ return node.nodeName === "SCRIPT" && node.hasAttribute("src");
+ }
+ function filter(url, http) {
+ let live = document;
+ let node = live.head.childNodes.length;
+ let next = new DOMParser().parseFromString(http.responseText, "text/html");
+ if (next.doctype === null || !http.getResponseHeader("content-type").includes("text/html")) return false;
+ while(node--){
+ if (styles(live.head.childNodes[node]) || scripts(live.head.childNodes[node])) {} else {
+ live.head.removeChild(live.head.childNodes[node]);
+ }
+ }
+ while(next.head.firstChild){
+ if (styles(next.head.firstChild) || scripts(next.head.firstChild)) {
+ next.head.removeChild(next.head.firstChild);
+ } else {
+ live.head.appendChild(next.head.firstChild);
+ }
+ }
+ while(live.documentElement.attributes.length > 0){
+ live.documentElement.removeAttribute(live.documentElement.attributes[live.documentElement.attributes.length - 1].name);
+ }
+ while(next.documentElement.attributes.length > 0){
+ live.documentElement.setAttribute(next.documentElement.attributes[next.documentElement.attributes.length - 1].name, next.documentElement.attributes[next.documentElement.attributes.length - 1].value);
+ next.documentElement.removeAttribute(next.documentElement.attributes[next.documentElement.attributes.length - 1].name);
+ }
+ live.body.parentElement.replaceChild(next.body, live.body);
+ }
+ function persist() {
+ let persist = document.createElement("link");
+ persist.rel = "location";
+ persist.target = JSON.stringify(self.location);
+ document.head.appendChild(persist);
+ }
+ self.addEventListener("DOMContentLoaded", function() {
+ if (localStorage[key] !== state) return;
+ persist();
+ });
+ self.addEventListener("popstate", function(event) {
+ if (localStorage[key] !== state) return;
+ const link = JSON.parse(document.querySelector('link[rel="location"]').target);
+ const url = event.target.location;
+ const hashed = link.pathname === url.pathname;
+ if (hashed) return;
+ fetch(url, "GET", function(http) {
+ if (filter(url, http) === false) return self.location.href = url;
+ persist();
+ self.document.dispatchEvent(new CustomEvent("URLChangedCustomEvent", {
+ bubbles: true
+ }));
+ });
+ });
+ self.addEventListener("click", function(event) {
+ if (localStorage[key] !== state) return;
+ const links = document.querySelectorAll("a");
+ for(let i1 = 0; i1 < links.length; i1++){
+ const active = links[i1].contains(event.target);
+ const change = self.location.href !== links[i1].href;
+ const view = links[i1].attributes.hasOwnProperty("download") === false;
+ const local = self.location.origin === links[i1].origin && links[i1].target !== "_self";
+ const hashed = self.location.pathname === links[i1].pathname && links[i1].href.includes("#");
+ if (active && local && change && view && hashed === false) {
+ event.preventDefault();
+ const url = links[i1].href;
+ links[i1].style.cursor = "wait";
+ fetch(url, "GET", function(http) {
+ links[i1].removeAttribute("style");
+ if (filter(url, http) === false) return self.location.href = url;
+ history.pushState({}, "", links[i1].href);
+ persist();
+ self.document.dispatchEvent(new CustomEvent("URLChangedCustomEvent", {
+ bubbles: true
+ }));
+ });
+ }
}
});
})();
@@ -512,56 +805,101 @@
numeric: "always",
style: "long"
});
- const date = ()=>{
- [
- ...document.querySelectorAll("time")
- ].forEach((element)=>{
- try {
- const time = new Date(element.dateTime) || new Date();
- const interval = (new Date().getTime() - time.getTime()) / 1000;
- const seconds = Math.floor(interval);
- const minutes = Math.floor(seconds / 60);
- const hours = Math.floor(minutes / 60);
- const days = Math.floor(hours / 24);
- if (Math.sign(seconds) === 1) {
- if (seconds <= 60) {
- return element.textContent = relative.format(-1 * seconds, "second");
- }
- if (minutes <= 120) {
- return element.textContent = relative.format(-1 * minutes, "minute");
- }
- if (hours <= 48) {
- return element.textContent = relative.format(-1 * hours, "hour");
- }
- if (days <= 60) {
- return element.textContent = relative.format(-1 * days, "day");
+ function viewport(element) {
+ const options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {
+ offset: 250
+ };
+ const view = element.getBoundingClientRect();
+ return view.top >= -options.offset && view.left >= -options.offset && view.bottom <= (self.innerHeight || document.documentElement.clientHeight) + options.offset && view.right <= (self.innerWidth || document.documentElement.clientWidth) + options.offset;
+ }
+ const date = function(update) {
+ const elements = document.querySelectorAll("time");
+ for(let i1 = 0; i1 < elements.length; ++i1){
+ const offscreen = !viewport(elements[i1]);
+ const hidden = elements[i1].offsetParent === null;
+ if (update === "viewport" && (offscreen || hidden)) continue;
+ (function(element) {
+ try {
+ if (element.dataset.type === "disabled") return;
+ const time = new Date(element.dateTime) || new Date();
+ const interval = (new Date().getTime() - time.getTime()) / 1000;
+ const seconds = Math.round(interval);
+ const minutes = Math.round(seconds / 60);
+ const hours = Math.round(minutes / 60);
+ const days = Math.round(hours / 24);
+ const past = Math.sign(seconds) === 1;
+ const future = Math.sign(seconds) === -1;
+ let tiny = function(string, place) {
+ return string.split(" ").slice(0, place).join(" ") + string.split(" ")[place].charAt(0);
+ };
+ if (element.dataset.type === "default") {
+ tiny = function(string) {
+ return string;
+ };
}
- }
- if (Math.sign(seconds) === -1) {
- if (-1 * days >= 60) {
- return element.textContent = relative.format(-1 * days, "day");
+ if (element.dataset.type === "localDate") {
+ return element.textContent = new Intl.DateTimeFormat([], {
+ dateStyle: "medium"
+ }).format(time).replace(",", "");
}
- if (-1 * hours >= 48) {
- return element.textContent = relative.format(-1 * hours, "hour");
+ if (element.dataset.type === "localTime") {
+ return element.textContent = new Intl.DateTimeFormat([], {
+ hour12: false,
+ timeStyle: "short"
+ }).format(time) + " " + new Intl.DateTimeFormat([], {
+ timeZoneName: "short"
+ }).format(time).split(" ")[1];
}
- if (-1 * minutes >= 120) {
- return element.textContent = relative.format(-1 * minutes, "minute");
+ if (past) {
+ if (seconds <= 60) {
+ return element.textContent = tiny(relative.format(-1 * seconds, "second"), 1);
+ }
+ if (minutes <= 120) {
+ return element.textContent = tiny(relative.format(-1 * minutes, "minute"), 1);
+ }
+ if (hours <= 48) {
+ return element.textContent = tiny(relative.format(-1 * hours, "hour"), 1);
+ }
+ if (days <= 7) {
+ return element.textContent = tiny(relative.format(-1 * days, "day"), 1);
+ }
}
- if (-1 * seconds >= 0) {
- return element.textContent = relative.format(-1 * seconds, "second");
+ if (future) {
+ if (-1 * days >= 4) {
+ return element.textContent = tiny(relative.format(-1 * days, "day"), 2);
+ }
+ if (-1 * hours >= 3) {
+ return element.textContent = tiny(relative.format(-1 * hours, "hour"), 2);
+ }
+ if (-1 * minutes >= 2) {
+ return element.textContent = tiny(relative.format(-1 * minutes, "minute"), 2);
+ }
+ if (-1 * seconds >= 1) {
+ return element.textContent = tiny(relative.format(-1 * seconds, "second"), 2);
+ }
}
+ } catch (error) {
+ console.error("ERROR: Relative time resolution failed", error);
}
- } catch (error) {
- console.error("Error: Unable to resolve relative time format!", error);
- }
- });
+ })(elements[i1]);
+ }
};
const substitution = setInterval(date, 4);
- self.addEventListener("load", ()=>{
- setTimeout(()=>{
+ [
+ "scroll",
+ "URLChangedCustomEvent"
+ ].forEach(function(event) {
+ self.addEventListener(event, function() {
+ date("viewport");
+ });
+ });
+ self.addEventListener("DOMContentLoaded", function() {
+ setTimeout(function() {
clearInterval(substitution);
- setInterval(date, 1000);
+ setInterval(function() {
+ date("viewport");
+ }, 1000);
}, 1000);
});
})();
-console.log("Surface Control: Complete"); \ No newline at end of file
+console.log("INFO: Surface Control Complete"); \ No newline at end of file
diff --git a/assets/templates/markdown-feed.yaml b/assets/templates/markdown-feed.yaml
index fbe763b..ff0aae5 100644
--- a/assets/templates/markdown-feed.yaml
+++ b/assets/templates/markdown-feed.yaml
@@ -21,12 +21,19 @@ feed:
{{ end -}}
---
-{{ $content := .content | replaceRE "{" "&#123;" | replaceRE "}" "&#125;" -}}
+{{ $content := .content }}
+
+{{- $content = replace $content "{" "&#123;" -}}
+{{- $content = replace $content "}" "&#125;" -}}
+{{- $content = replace $content "[" "&#91;" -}}
+{{- $content = replace $content "]" "&#93;" -}}
+
{{ $content }}
-{{- $enclosureDescription := "Image/Picture" -}}
+{{- $caption := "Image/Picture" -}}
+
{{- with $content -}}
- {{ $enclosureDescription = $content | truncate 80 "" }}
+ {{ $caption = $content | truncate 80 "" }}
{{- end }}
{{ with .enclosure -}}
@@ -43,8 +50,8 @@ feed:
(in . ".svg")
(in . ".webp")
-}}
-![{{ $enclosureDescription }}]({{ . }} "
- {{ $enclosureDescription }}"
+![{{ $caption }}]({{ . }} "
+ {{ $caption }}"
)
{{- end -}}
{{- end }}
diff --git a/config.json b/config.json
index 4a4256c..2f29e53 100644
--- a/config.json
+++ b/config.json
@@ -16,14 +16,8 @@
"nobody"
],
"default": {
- "footer": "canory",
- "home": "canory",
- "gallery": "canory",
- "title": "canory",
- "user": "default",
- "webring": "canory"
- },
- "footer": "A Micro Blog\n"
+ "footer": "A Micro Blog"
+ }
},
"taxonomies": {
"tag": "tags"
@@ -33,50 +27,50 @@
{
"name": "Home",
"url": "/",
- "identifier": "feather/home",
+ "identifier": "tabler/home",
"weight": 1
},
{
"name": "Tags",
"url": "/tags/",
- "identifier": "feather/tag",
+ "identifier": "tabler/tag",
"weight": 2,
"icon": "home"
},
{
- "name": "History",
- "url": "/archives/messages/",
- "identifier": "tabler/clock",
+ "name": "Archives",
+ "url": "/archives/",
+ "identifier": "tabler/archive",
"weight": 3
},
{
- "name": "Records",
- "url": "/archives/tags/",
- "identifier": "tabler/book-2",
+ "name": "Authors",
+ "url": "/authors/",
+ "identifier": "tabler/users",
"weight": 4
},
{
- "name": "Authors",
- "url": "/authors/",
- "identifier": "feather/users",
+ "name": "Settings",
+ "url": "/settings/",
+ "identifier": "tabler/settings",
"weight": 5
},
{
- "name": "RSS Feed",
- "url": "/rss.xml",
- "identifier": "feather/rss",
+ "name": "Sources",
+ "url": "/sources/",
+ "identifier": "tabler/git-fork",
"weight": 6
},
{
- "name": "JSON Feed",
- "url": "/index.json",
- "identifier": "feather/circle",
+ "name": "RSS Feed",
+ "url": "/rss.xml",
+ "identifier": "tabler/rss",
"weight": 7
},
{
- "name": "Sources",
- "url": "/sources/",
- "identifier": "feather/git-commit",
+ "name": "JSON Feed",
+ "url": "/index.json",
+ "identifier": "tabler/circle",
"weight": 8
}
]
@@ -87,15 +81,16 @@
"production": false,
"referrer": "no-referrer",
"robots": "index,follow",
- "canonical": null,
- "refresh": null
+ "canonical": null
},
"webmanifest": {
+ "start_url": "/",
"name": "Micro Blog",
- "shortName": "Micro",
- "themeColor": "#ffffff",
- "backgroundColor": "#ffffff",
+ "short_name": "Micro",
+ "theme_color": "#ffffff",
+ "background_color": "#ffffff",
"display": "standalone",
+ "description": "A Micro Blog",
"logo": "data/media/logo.png"
},
"csp": {
@@ -103,9 +98,6 @@
"base-uri": [
"'self'"
],
- "child-src": [
- "'self'"
- ],
"connect-src": [
"'self'"
],
@@ -127,10 +119,12 @@
],
"img-src": [
"'self'",
+ "data:",
"http://preview.test"
],
"manifest-src": [
- "'self'"
+ "'self'",
+ "data:"
],
"media-src": [
"'self'"
@@ -138,9 +132,6 @@
"object-src": [
"'self'"
],
- "prefetch-src": [
- "'self'"
- ],
"script-src-elem": [
"'self'"
],
@@ -151,16 +142,14 @@
"'self'",
"'unsafe-inline'",
"http://preview.test"
- ],
- "worker-src": [
- "'self'"
]
},
"search": {
"verification": {
- "google": null,
- "bing": null,
- "yandex": null
+ "baidu-site-verification": null,
+ "google-site-verification": null,
+ "msvalidate.01": null,
+ "yandex-verification": null
}
}
},
@@ -191,6 +180,10 @@
"baseName": "index",
"mediaType": "text/html"
},
+ "embed": {
+ "baseName": "embed",
+ "mediaType": "text/html"
+ },
"plain": {
"baseName": "index",
"mediaType": "text/plain"
@@ -220,13 +213,13 @@
"baseName": "authors",
"mediaType": "text/html"
},
- "history": {
- "path": "archives/messages",
+ "archives": {
+ "path": "archives",
"baseName": "index",
"mediaType": "text/html"
},
- "records": {
- "path": "archives/tags",
+ "settings": {
+ "path": "settings",
"baseName": "index",
"mediaType": "text/html"
},
@@ -235,14 +228,6 @@
"baseName": "index",
"mediaType": "text/html"
},
- "browserconfig": {
- "baseName": "browserconfig",
- "mediaType": "application/xml"
- },
- "webmanifest": {
- "baseName": "site",
- "mediaType": "application/manifest+json"
- },
"gallery": {
"baseName": "gallery",
"mediaType": "text/html"
@@ -266,10 +251,8 @@
"authors",
"authors.section",
"sources",
- "browserconfig",
- "history",
- "records",
- "webmanifest"
+ "archives",
+ "settings"
],
"section": [
"html",
@@ -288,7 +271,8 @@
],
"page": [
"html",
- "plain"
+ "plain",
+ "embed"
]
},
"caches": {
@@ -411,7 +395,7 @@
},
"autoHeadingID": true,
"autoHeadingIDType": "github",
- "wrapStandAloneImageWithinParagraph": true
+ "wrapStandAloneImageWithinParagraph": false
},
"renderer": {
"hardWraps": false,
diff --git a/config.toml b/config.toml
index d615726..16ca22b 100644
--- a/config.toml
+++ b/config.toml
@@ -10,15 +10,8 @@ enableRobotsTXT = true
[author]
list = ["canory", "default", "nobody"]
- footer = "A Micro Blog\n"
-
[author.default]
- footer = "canory"
- home = "canory"
- gallery = "canory"
- title = "canory"
- user = "default"
- webring = "canory"
+ footer = "A Micro Blog"
[taxonomies]
tag = "tags"
@@ -28,89 +21,83 @@ enableRobotsTXT = true
[[menu.main]]
name = "Home"
url = "/"
- identifier = "feather/home"
+ identifier = "tabler/home"
weight = 1
[[menu.main]]
name = "Tags"
url = "/tags/"
- identifier = "feather/tag"
+ identifier = "tabler/tag"
weight = 2
icon = "home"
[[menu.main]]
- name = "History"
- url = "/archives/messages/"
- identifier = "tabler/clock"
+ name = "Archives"
+ url = "/archives/"
+ identifier = "tabler/archive"
weight = 3
[[menu.main]]
- name = "Records"
- url = "/archives/tags/"
- identifier = "tabler/book-2"
+ name = "Authors"
+ url = "/authors/"
+ identifier = "tabler/users"
weight = 4
[[menu.main]]
- name = "Authors"
- url = "/authors/"
- identifier = "feather/users"
+ name = "Settings"
+ url = "/settings/"
+ identifier = "tabler/settings"
weight = 5
[[menu.main]]
- name = "RSS Feed"
- url = "/rss.xml"
- identifier = "feather/rss"
+ name = "Sources"
+ url = "/sources/"
+ identifier = "tabler/git-fork"
weight = 6
[[menu.main]]
- name = "JSON Feed"
- url = "/index.json"
- identifier = "feather/circle"
+ name = "RSS Feed"
+ url = "/rss.xml"
+ identifier = "tabler/rss"
weight = 7
[[menu.main]]
- name = "Sources"
- url = "/sources/"
- identifier = "feather/git-commit"
+ name = "JSON Feed"
+ url = "/index.json"
+ identifier = "tabler/circle"
weight = 8
[params]
-
[params.site]
offline = false
production = false
referrer = "no-referrer"
robots = "index,follow"
-
[params.webmanifest]
+ start_url = "/"
name = "Micro Blog"
- shortName = "Micro"
- themeColor = "#ffffff"
- backgroundColor = "#ffffff"
+ short_name = "Micro"
+ theme_color = "#ffffff"
+ background_color = "#ffffff"
display = "standalone"
+ description = "A Micro Blog"
logo = "data/media/logo.png"
-
[params.csp]
block-all-mixed-content = ""
base-uri = ["'self'"]
- child-src = ["'self'"]
connect-src = ["'self'"]
default-src = ["'self'"]
font-src = ["'self'"]
form-action = ["'self'", "lite.duckduckgo.com"]
frame-src = ["'self'", "www.youtube-nocookie.com", "en.m.wikipedia.org", "odysee.com"]
- img-src = ["'self'", "http://preview.test"]
- manifest-src = ["'self'"]
+ img-src = ["'self'", "data:", "http://preview.test"]
+ manifest-src = ["'self'", "data:"]
media-src = ["'self'"]
object-src = ["'self'"]
- prefetch-src = ["'self'"]
script-src-elem = ["'self'"]
script-src = ["'self'"]
style-src = ["'self'", "'unsafe-inline'", "http://preview.test"]
- worker-src = ["'self'"]
-
[params.search]
-
[params.search.verification]
[related]
@@ -127,109 +114,83 @@ enableRobotsTXT = true
weight = 10
[mediaTypes]
-
[mediaTypes."application/xslt+xml"]
suffixes = ["xsl"]
[outputFormats]
-
[outputFormats.html]
baseName = "index"
mediaType = "text/html"
-
+ [outputFormats.embed]
+ baseName = "embed"
+ mediaType = "text/html"
[outputFormats.plain]
baseName = "index"
mediaType = "text/plain"
-
[outputFormats.json]
baseName = "index"
mediaType = "application/json"
-
[outputFormats.rss]
baseName = "rss"
mediaType = "application/rss+xml"
-
[outputFormats."xslt.rss"]
baseName = "rss"
mediaType = "application/xslt+xml"
-
[outputFormats."xslt.sitemap"]
baseName = "sitemap"
mediaType = "application/xslt+xml"
-
[outputFormats.authors]
path = "authors"
baseName = "index"
mediaType = "text/html"
-
[outputFormats."authors.section"]
baseName = "authors"
mediaType = "text/html"
-
- [outputFormats.history]
- path = "archives/messages"
+ [outputFormats.archives]
+ path = "archives"
baseName = "index"
mediaType = "text/html"
-
- [outputFormats.records]
- path = "archives/tags"
+ [outputFormats.settings]
+ path = "settings"
baseName = "index"
mediaType = "text/html"
-
[outputFormats.sources]
path = "sources"
baseName = "index"
mediaType = "text/html"
-
- [outputFormats.browserconfig]
- baseName = "browserconfig"
- mediaType = "application/xml"
-
- [outputFormats.webmanifest]
- baseName = "site"
- mediaType = "application/manifest+json"
-
[outputFormats.gallery]
baseName = "gallery"
mediaType = "text/html"
-
[outputFormats.following]
baseName = "following"
mediaType = "text/html"
-
[outputFormats.webring]
baseName = "webring"
mediaType = "text/html"
[outputs]
- home = ["html", "rss", "xslt.rss", "xslt.sitemap", "json", "authors", "authors.section", "sources", "browserconfig", "history", "records", "webmanifest"]
+ home = ["html", "rss", "xslt.rss", "xslt.sitemap", "json", "authors", "authors.section", "sources", "archives", "settings"]
section = ["html", "rss", "gallery", "following", "webring"]
taxonomy = ["html", "rss"]
term = ["html", "rss"]
- page = ["html", "plain"]
+ page = ["html", "plain", "embed"]
[caches]
-
[caches.assets]
dir = ":resourceDir/_gen"
maxAge = -1
-
[caches.images]
dir = ":resourceDir/_gen"
maxAge = -1
-
[caches.getcsv]
dir = ":resourceDir/caches"
maxAge = "12h"
-
[caches.getjson]
dir = ":resourceDir/caches"
maxAge = "12h"
-
[caches.getresource]
dir = ":resourceDir/caches"
maxAge = "12h"
-
[caches.modules]
dir = ":resourceDir/caches"
maxAge = -1
@@ -295,7 +256,6 @@ enableRobotsTXT = true
[markup]
defaultMarkdownHandler = "goldmark"
-
[markup.asciidocExt]
backend = "html5"
extensions = []
@@ -307,11 +267,8 @@ enableRobotsTXT = true
trace = false
verbose = false
workingFolderCurrent = false
-
[markup.asciidocExt.attributes]
-
[markup.goldmark]
-
[markup.goldmark.extensions]
definitionList = true
footnote = true
@@ -321,21 +278,17 @@ enableRobotsTXT = true
table = true
taskList = true
typographer = true
-
[markup.goldmark.parser]
autoHeadingID = true
autoHeadingIDType = "github"
- wrapStandAloneImageWithinParagraph = true
-
+ wrapStandAloneImageWithinParagraph = false
[markup.goldmark.parser.attribute]
block = false
title = true
-
[markup.goldmark.renderer]
hardWraps = false
unsafe = false
xhtml = true
-
[markup.highlight]
anchorLineNos = true
codeFences = true
@@ -349,7 +302,6 @@ enableRobotsTXT = true
noClasses = false
noHl = false
tabWidth = 4
-
[markup.tableOfContents]
endLevel = 3
ordered = false
diff --git a/config.yaml b/config.yaml
index f89cdfa..6ba49df 100644
--- a/config.yaml
+++ b/config.yaml
@@ -17,14 +17,7 @@ author:
- default
- nobody
default:
- footer: canory
- home: canory
- gallery: canory
- title: canory
- user: default
- webring: canory
- footer: >
- A Micro Blog
+ footer: A Micro Blog
taxonomies:
tag: tags
@@ -33,36 +26,36 @@ menu:
main:
- name: Home
url: /
- identifier: feather/home
+ identifier: tabler/home
weight: 1
- name: Tags
url: /tags/
- identifier: feather/tag
+ identifier: tabler/tag
weight: 2
icon: home
- - name: History
- url: /archives/messages/
- identifier: tabler/clock
+ - name: Archives
+ url: /archives/
+ identifier: tabler/archive
weight: 3
- - name: Records
- url: /archives/tags/
- identifier: tabler/book-2
- weight: 4
- name: Authors
url: /authors/
- identifier: feather/users
+ identifier: tabler/users
+ weight: 4
+ - name: Settings
+ url: /settings/
+ identifier: tabler/settings
weight: 5
+ - name: Sources
+ url: /sources/
+ identifier: tabler/git-fork
+ weight: 6
- name: RSS Feed
url: /rss.xml
- identifier: feather/rss
- weight: 6
+ identifier: tabler/rss
+ weight: 7
- name: JSON Feed
url: /index.json
- identifier: feather/circle
- weight: 7
- - name: Sources
- url: /sources/
- identifier: feather/git-commit
+ identifier: tabler/circle
weight: 8
params:
@@ -72,37 +65,36 @@ params:
referrer: no-referrer
robots: index,follow
canonical:
- refresh:
webmanifest:
+ start_url: /
name: Micro Blog
- shortName: Micro
- themeColor: '#ffffff'
- backgroundColor: '#ffffff'
+ short_name: Micro
+ theme_color: '#ffffff'
+ background_color: '#ffffff'
display: standalone
+ description: A Micro Blog
logo: data/media/logo.png
csp:
block-all-mixed-content: ''
base-uri: ["'self'"]
- child-src: ["'self'"]
connect-src: ["'self'"]
default-src: ["'self'"]
font-src: ["'self'"]
form-action: ["'self'", lite.duckduckgo.com]
frame-src: ["'self'", www.youtube-nocookie.com, en.m.wikipedia.org, odysee.com]
- img-src: ["'self'", http://preview.test]
- manifest-src: ["'self'"]
+ img-src: ["'self'", 'data:', http://preview.test]
+ manifest-src: ["'self'", 'data:']
media-src: ["'self'"]
object-src: ["'self'"]
- prefetch-src: ["'self'"]
script-src-elem: ["'self'"]
script-src: ["'self'"]
style-src: ["'self'", "'unsafe-inline'", http://preview.test]
- worker-src: ["'self'"]
search:
verification:
- google:
- bing:
- yandex:
+ baidu-site-verification:
+ google-site-verification:
+ msvalidate.01:
+ yandex-verification:
related:
includeNewer: false
@@ -123,6 +115,9 @@ outputFormats:
html:
baseName: index
mediaType: text/html
+ embed:
+ baseName: embed
+ mediaType: text/html
plain:
baseName: index
mediaType: text/plain
@@ -145,24 +140,18 @@ outputFormats:
authors.section:
baseName: authors
mediaType: text/html
- history:
- path: archives/messages
+ archives:
+ path: archives
baseName: index
mediaType: text/html
- records:
- path: archives/tags
+ settings:
+ path: settings
baseName: index
mediaType: text/html
sources:
path: sources
baseName: index
mediaType: text/html
- browserconfig:
- baseName: browserconfig
- mediaType: application/xml
- webmanifest:
- baseName: site
- mediaType: application/manifest+json
gallery:
baseName: gallery
mediaType: text/html
@@ -183,10 +172,8 @@ outputs:
- authors
- authors.section
- sources
- - browserconfig
- - history
- - records
- - webmanifest
+ - archives
+ - settings
section:
- html
- rss
@@ -202,6 +189,7 @@ outputs:
page:
- html
- plain
+ - embed
caches:
assets:
@@ -288,7 +276,7 @@ markup:
title: true
autoHeadingID: true
autoHeadingIDType: github
- wrapStandAloneImageWithinParagraph: true
+ wrapStandAloneImageWithinParagraph: false
renderer:
hardWraps: false
unsafe: false
diff --git a/content/canory/media/2city12p.pdf b/content/canory/media/2city12p.pdf
new file mode 100644
index 0000000..f559ea6
--- /dev/null
+++ b/content/canory/media/2city12p.pdf
Binary files differ
diff --git a/content/canory/messages/animations.md b/content/canory/messages/animations.md
index 8792db5..4957497 100644
--- a/content/canory/messages/animations.md
+++ b/content/canory/messages/animations.md
@@ -2,7 +2,6 @@
date = "2022-03-16T05:41:52+00:00"
lastmod = "2022-03-16T05:41:52+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Text animations are out of style. Wait.. {{< animate waggle "nu-uh" >}}, just
diff --git a/content/canory/messages/cache.md b/content/canory/messages/cache.md
index d731590..9a57ced 100644
--- a/content/canory/messages/cache.md
+++ b/content/canory/messages/cache.md
@@ -2,7 +2,6 @@
date = "2022-02-27T20:18:43+00:00"
lastmod = "2022-02-27T20:18:43+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Resource abuse is not good --- cache responsibly. In the `hugo` configuration
diff --git a/content/canory/messages/code.md b/content/canory/messages/code.md
index ab9e656..503eb97 100644
--- a/content/canory/messages/code.md
+++ b/content/canory/messages/code.md
@@ -2,7 +2,6 @@
date = "2022-03-22T04:45:51+00:00"
lastmod = "2022-03-22T04:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Demonstrate your brilliance by embedding code with impeccable taste and
diff --git a/content/canory/messages/definitions.md b/content/canory/messages/definitions.md
index 93ffa73..4c5f30f 100644
--- a/content/canory/messages/definitions.md
+++ b/content/canory/messages/definitions.md
@@ -2,7 +2,6 @@
date = "2022-03-17T04:45:51+00:00"
lastmod = "2022-03-17T04:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
There's no infinite scrolling here --- it enfeebles the psyche. Here are a list
diff --git a/content/canory/messages/diagrams.md b/content/canory/messages/diagrams.md
index 2b64116..bfbc193 100644
--- a/content/canory/messages/diagrams.md
+++ b/content/canory/messages/diagrams.md
@@ -2,13 +2,12 @@
date = "2022-03-25T04:45:51+00:00"
lastmod = "2022-03-25T04:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
{{< abbr >}} I :heart: `hugo` but hate emojis. Here's an
[emoji cheat sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) because you
probably like them :sweat_smile:. I'm over the character limit but look mommy
---- `ASCII` diagrams!
+--- {{< abbr "`ASCII`" "American Standard Code for Information Interchange" >}} diagrams!
[**GoAT Diagram**](https://github.com/blampe/goat#goat-go-ascii-tool)
diff --git a/content/canory/messages/disclosure.md b/content/canory/messages/disclosure.md
new file mode 100644
index 0000000..597f8d7
--- /dev/null
+++ b/content/canory/messages/disclosure.md
@@ -0,0 +1,32 @@
++++
+date = "2022-03-07T02:19:12+00:00"
+lastmod = "2022-03-07T02:19:12+00:00"
+tags = [ "docs" ]
++++
+
+I'll keep it short. The introduction of _A Tale of Two Cities_ by Charles
+Dickens --- enjoy!
+
+---
+
+{{< disclose >}}
+It was the best of times, it was the worst of times.
+{{</ disclose >}}
+
+It was the age of wisdom, it was the age of foolishness, it was the epoch of
+belief, it was the epoch of incredulity.
+
+{{< disclose >}}
+It was the season of Light, it was the season of Darkness.
+{{</ disclose >}}
+
+It was the spring of hope, it was the winter of despair, we had everything
+before us, we had nothing before us.
+
+{{< disclose >}}
+We were all going direct to Heaven, we were all going direct the other way.
+{{</ disclose >}}
+
+In short, the period was so far like the present period, that some of its
+noisiest authorities insisted on its being received, for good or for evil, in
+the superlative degree of comparison only.
diff --git a/content/canory/messages/drafts.md b/content/canory/messages/drafts.md
index ad28b64..41fb2ae 100644
--- a/content/canory/messages/drafts.md
+++ b/content/canory/messages/drafts.md
@@ -3,7 +3,6 @@ date = "2022-03-04T02:44:51+00:00"
lastmod = "2022-03-04T02:44:51+00:00"
tags = [ "docs" ]
draft = true
-author = "canory"
+++
Draft those messages, you message drafter. Get a feel of how it delivers before
diff --git a/content/canory/messages/gates.md b/content/canory/messages/gates.md
index 9284ab5..eb2ddd3 100644
--- a/content/canory/messages/gates.md
+++ b/content/canory/messages/gates.md
@@ -2,7 +2,6 @@
date = "2022-03-01T01:24:31+00:00"
lastmod = "2022-03-01T01:24:31+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Satisfy the keepers of the gate by officially verifying ownership of your
diff --git a/content/canory/messages/highlighting.md b/content/canory/messages/highlighting.md
index 440ab23..076a189 100644
--- a/content/canory/messages/highlighting.md
+++ b/content/canory/messages/highlighting.md
@@ -2,7 +2,6 @@
date = "2022-03-24T04:45:51+00:00"
lastmod = "2022-03-24T04:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Sometimes I'll {{< mark "highlight stuff" />}} to draw attention to my fine
diff --git a/content/canory/messages/hugo.md b/content/canory/messages/hugo.md
index d0ab9be..2011db0 100644
--- a/content/canory/messages/hugo.md
+++ b/content/canory/messages/hugo.md
@@ -2,7 +2,6 @@
date = "2022-03-26T04:45:51+00:00"
lastmod = "2022-03-26T04:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
This micro blog is powered by Hugo, a static site generator that has lots of
diff --git a/content/canory/messages/imgur-video.md b/content/canory/messages/imgur-video.md
index 0e2f3b1..d04fe47 100644
--- a/content/canory/messages/imgur-video.md
+++ b/content/canory/messages/imgur-video.md
@@ -2,10 +2,9 @@
date = "2022-03-19T04:45:51+00:00"
lastmod = "2022-03-19T04:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Embedding a `gif` hosted from an external site is easy. Heard it might be
illegal someday. Yak shaving and legal jangling are the worst, truly.
-{{< imgur-video rQIb4Vw >}}
+{{< video-imgur rQIb4Vw >}}
diff --git a/content/canory/messages/links.md b/content/canory/messages/links.md
index 43f73a5..bc79001 100644
--- a/content/canory/messages/links.md
+++ b/content/canory/messages/links.md
@@ -2,7 +2,6 @@
date = "2022-03-15T03:45:51+00:00"
lastmod = "2022-03-15T03:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
This individual is old enough to remember that the Internet is
diff --git a/content/canory/messages/lists.md b/content/canory/messages/lists.md
index 3750b26..04fbab7 100644
--- a/content/canory/messages/lists.md
+++ b/content/canory/messages/lists.md
@@ -2,7 +2,6 @@
date = "2022-03-12T02:44:51+00:00"
lastmod = "2022-03-12T02:44:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Speaking of lists. Everyone likes a good list right? Spur ridicule and
@@ -11,6 +10,9 @@ controversy by ranking things, it's that easy.
1. C
2. Bash
3. Perl
- 4. JavaScript
- 5. PHP
- 6. Java
+
+ ---
+
+ 10. JavaScript
+ 11. PHP
+ 12. Java
diff --git a/content/canory/messages/markdown.md b/content/canory/messages/markdown.md
index cb34605..675f3f1 100644
--- a/content/canory/messages/markdown.md
+++ b/content/canory/messages/markdown.md
@@ -2,7 +2,6 @@
date = "2022-03-14T04:45:51+00:00"
lastmod = "2022-03-14T04:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
[//]: # "That's a comment alright, hiding in plain sight."
diff --git a/content/canory/messages/math.md b/content/canory/messages/math.md
new file mode 100644
index 0000000..cd02f88
--- /dev/null
+++ b/content/canory/messages/math.md
@@ -0,0 +1,93 @@
++++
+date = "2022-03-01T01:25:42+00:00"
+lastmod = "2022-03-01T01:25:42+00:00"
+tags = [ "docs" ]
++++
+
+First nothing, then the infinity wars. You know; the miracle of the fallacy
+_&agrave; la_ generality.
+
+```mathml { caption="Sounds about right." }
+<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="\begin{align*} & 0 = 0 \times 1\\ & 0 = 0 \times 2\\ & 0 = 0 \times 3 \end{align*}" display="block" >
+ <mtable displaystyle="true" columnalign="right">
+ <mtr>
+ <mtd>
+ <mrow>
+ <mn>0</mn>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>×</mo>
+ <mn>1</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+ <mtr>
+ <mtd>
+ <mrow>
+ <mn>0</mn>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>×</mo>
+ <mn>2</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+ <mtr>
+ <mtd>
+ <mrow>
+ <mn>0</mn>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>×</mo>
+ <mn>3</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+ </mtable>
+</math>
+```
+
+```mathml { caption="Alien levels of literal meta--abstraction." }
+<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="\begin{align*} & 0 = 0\\ & 0 \times 1 = 0 \times 3 \end{align*}" display="block">
+ <mtable displaystyle="true" columnalign="right left">
+ <mtr>
+ <mtd>
+ <mrow>
+ <mn>0</mn>
+ <mo>=</mo>
+ <mn>0</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+ <mtr>
+ <mtd>
+ <mrow>
+ <mn>0</mn>
+ <mo>×</mo>
+ <mn>1</mn>
+ <mo>=</mo>
+ <mn>0</mn>
+ <mo>×</mo>
+ <mn>3</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+ </mtable>
+</math>
+```
+
+```mathml { caption="Unity. Don't try this at home, kids." }
+<math xmlns="http://www.w3.org/1998/Math/MathML" alttext="\begin{align*} & 1 = 3 \end{align*}" display="block">
+ <mtable displaystyle="true" columnalign="right left">
+ <mtr>
+ <mtd>
+ <mrow>
+ <mn>1</mn>
+ <mo>=</mo>
+ <mn>3</mn>
+ </mrow>
+ </mtd>
+ </mtr>
+ </mtable>
+</math>
+```
diff --git a/content/canory/messages/odysee.md b/content/canory/messages/odysee.md
index d07f949..6f0c0a8 100644
--- a/content/canory/messages/odysee.md
+++ b/content/canory/messages/odysee.md
@@ -2,7 +2,6 @@
date = "2022-03-03T02:44:51+00:00"
lastmod = "2022-03-03T02:44:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
The cool kids are moving to a new video site called Odysee. How long do you
diff --git a/content/canory/messages/pdf.md b/content/canory/messages/pdf.md
index ae8aa63..cb63604 100644
--- a/content/canory/messages/pdf.md
+++ b/content/canory/messages/pdf.md
@@ -2,10 +2,11 @@
date = "2022-03-07T02:20:51+00:00"
lastmod = "2022-03-07T02:20:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
-Heard you like {{< abbr `PDFs` "Portable Document Format" >}} but hate accidently
-downloading them. Charles Dickens is a word wizard.
+Heard you like {{< abbr `PDFs` "Portable Document Format" >}} but hate
+accidently downloading them. [Charles
+Dickens](https://www.gutenberg.org/ebooks/98) is a [word
+wizard](/canory/media/2city12p.pdf).
{{< attach >}}
diff --git a/content/canory/messages/pinned.md b/content/canory/messages/pinned.md
index d1b056d..faf8781 100644
--- a/content/canory/messages/pinned.md
+++ b/content/canory/messages/pinned.md
@@ -3,8 +3,7 @@ date = "2022-02-05T02:20:51+00:00"
lastmod = "2022-03-29T22:55:17+00:00"
tags = [ "docs" ]
weight = 1
-liked = true
-author = "canory"
+marked = true
+++
This message is pinned for reasons unknown. For a quick start guide,
diff --git a/content/canory/messages/plumbing.md b/content/canory/messages/plumbing.md
index dfa71fe..6cda9c9 100644
--- a/content/canory/messages/plumbing.md
+++ b/content/canory/messages/plumbing.md
@@ -2,7 +2,6 @@
date = "2022-03-10T02:44:51+00:00"
lastmod = "2022-03-10T02:44:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Is your `JavaScript` functional? Double[^1] click a word and hold the
diff --git a/content/canory/messages/self.md b/content/canory/messages/self.md
index c4266ee..f5834a4 100644
--- a/content/canory/messages/self.md
+++ b/content/canory/messages/self.md
@@ -2,7 +2,6 @@
date = "2022-03-02T02:44:51+00:00"
lastmod = "2022-03-02T02:44:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Check out this party trick; this thing can quote other messages.
@@ -11,4 +10,4 @@ Technically... the instructions from the manufacturer was not to do this --- but
rules are made to be broken... right?
{{< /spoiler >}}
-{{< self "/canory/messages/self#canory-messages-self.md" >}}
+{{< self "/canory/messages/self/embed.html" >}}
diff --git a/content/canory/messages/selfdestruct.md b/content/canory/messages/selfdestruct.md
index 27a0929..bfac31d 100644
--- a/content/canory/messages/selfdestruct.md
+++ b/content/canory/messages/selfdestruct.md
@@ -3,14 +3,12 @@ date = "2022-03-08T02:20:51+00:00"
lastmod = "2022-03-08T02:20:51+00:00"
expirydate = "2122-04-29T22:55:17+00:00"
tags = [ "docs" ]
-author = "canory"
slug = "cf1a1feb1"
+++
{{< disclose >}}
-Extraterrestrials don't care about speech in the slightest. According to my
-lackey [@tdro](https://thedroneely.com), the Internet is serious business for
-humans.
+Extraterrestrials care not about speech. According to my
+[lackey](https://thedroneely.com), the Internet is serious business for humans.
{{</ disclose >}}
Professor Wiio says;
diff --git a/content/canory/messages/selfdestructed.md b/content/canory/messages/selfdestructed.md
index 246cdbc..2cf1852 100644
--- a/content/canory/messages/selfdestructed.md
+++ b/content/canory/messages/selfdestructed.md
@@ -3,7 +3,6 @@ date = "2022-03-08T02:18:49+00:00"
lastmod = "2022-03-08T02:18:49+00:00"
expirydate = "2022-03-08T02:19:51+00:00"
tags = [ "docs" ]
-author = "canory"
slug = "cf1a1feb2"
+++
diff --git a/content/canory/messages/styles.md b/content/canory/messages/styles.md
index 2791d5e..67c63be 100644
--- a/content/canory/messages/styles.md
+++ b/content/canory/messages/styles.md
@@ -2,7 +2,6 @@
date = "2022-03-23T04:45:51+00:00"
lastmod = "2022-03-23T04:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
**Subtlety** *wins* arguments, and other times an **_impassioned
diff --git a/content/canory/messages/tables.md b/content/canory/messages/tables.md
index ade801c..97c4aea 100644
--- a/content/canory/messages/tables.md
+++ b/content/canory/messages/tables.md
@@ -2,7 +2,6 @@
date = "2022-03-04T02:44:51+00:00"
lastmod = "2022-03-04T02:44:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Tables are the most universally understood data presentation format but...
diff --git a/content/canory/messages/tasks.md b/content/canory/messages/tasks.md
index 86c2312..379c359 100644
--- a/content/canory/messages/tasks.md
+++ b/content/canory/messages/tasks.md
@@ -2,7 +2,6 @@
date = "2022-03-13T03:44:51+00:00"
lastmod = "2022-03-13T03:44:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
We get things done around here! The first step is to write down our goals for
diff --git a/content/canory/messages/unlisted.md b/content/canory/messages/unlisted.md
index 4ba23b5..76294bf 100644
--- a/content/canory/messages/unlisted.md
+++ b/content/canory/messages/unlisted.md
@@ -3,7 +3,6 @@ date = "2022-03-08T02:16:51+00:00"
lastmod = "2022-03-08T02:16:51+00:00"
tags = [ "docs" ]
unlisted = true
-author = "canory"
+++
So you're a bit bold and have the cooking skills needed to stay in the kitchen.
diff --git a/content/canory/messages/unsafe.md b/content/canory/messages/unsafe.md
index 9c75457..f43799e 100644
--- a/content/canory/messages/unsafe.md
+++ b/content/canory/messages/unsafe.md
@@ -2,7 +2,6 @@
date = "2022-03-09T02:43:51+00:00"
lastmod = "2022-03-09T02:43:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
{{< disclose />}}
diff --git a/content/canory/messages/videos.md b/content/canory/messages/videos.md
index 9678aec..3655f46 100644
--- a/content/canory/messages/videos.md
+++ b/content/canory/messages/videos.md
@@ -2,7 +2,6 @@
date = "2022-03-20T04:45:51+00:00"
lastmod = "2022-03-20T04:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Here's a video that warms my dear heart. Showing videos to others makes you
diff --git a/content/canory/messages/wikipedia.md b/content/canory/messages/wikipedia.md
index 7552249..12950b2 100644
--- a/content/canory/messages/wikipedia.md
+++ b/content/canory/messages/wikipedia.md
@@ -2,7 +2,6 @@
date = "2022-03-06T02:20:51+00:00"
lastmod = "2022-03-06T02:20:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Reason, meaning, and knowledge are the ground truths of society but only when
diff --git a/content/canory/messages/xkcd.md b/content/canory/messages/xkcd.md
index ea0d216..0896da1 100644
--- a/content/canory/messages/xkcd.md
+++ b/content/canory/messages/xkcd.md
@@ -2,7 +2,6 @@
date = "2022-03-18T04:45:51+00:00"
lastmod = "2022-03-18T04:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Hosting and linking content is copyright radioactive. Be a good netizen and
diff --git a/content/canory/messages/youtube.md b/content/canory/messages/youtube.md
index 633e64d..33f7c53 100644
--- a/content/canory/messages/youtube.md
+++ b/content/canory/messages/youtube.md
@@ -2,7 +2,6 @@
date = "2022-03-16T04:45:51+00:00"
lastmod = "2022-03-16T04:45:51+00:00"
tags = [ "docs" ]
-author = "canory"
+++
Netizens think that there are only 5 websites. Here's a video from one of them.
diff --git a/content/default/messages/authors.md b/content/default/messages/authors.md
index 1428ca1..973de7a 100644
--- a/content/default/messages/authors.md
+++ b/content/default/messages/authors.md
@@ -7,6 +7,3 @@ tags = [ "docs" ]
Beep beep beep. Another user? Multiple users are available by setting a specific
author. [@canory](/canory) thinks this is cool but doesn't know any better --
it's hacks all the way down.
-
-Any soul that sends a message without a name becomes a _default_ because
-{{< smallcaps "I AM" >}} the default.
diff --git a/content/default/messages/quickstart.md b/content/default/messages/quickstart.md
index f7f8332..99e33d3 100644
--- a/content/default/messages/quickstart.md
+++ b/content/default/messages/quickstart.md
@@ -2,7 +2,6 @@
date = "2022-03-05T03:45:51+00:00"
lastmod = "2022-03-05T03:45:51+00:00"
tags = [ "docs" ]
-author = "default"
+++
Somehow you've ended up here, funny how that works. I'm responsible for
@@ -12,7 +11,7 @@ GIT CLONE.
{{% version clone=true %}}
-EXECUTE HUGO TWICE. HUGO VERSION >= {{% version hugo=true %}}
+EXECUTE HUGO TWICE. HUGO VERSION >= {{% version hugo=true %}} AND < 0.123.0
```shell
cd canory
@@ -28,4 +27,5 @@ busybox httpd -f -p 127.0.0.1:8125
php -S 127.0.0.1:8126
ruby -run -e httpd . -p 8127
caddy file-server --listen :8128
+npx serve --listen 8129
```
diff --git a/data/canory.yaml b/data/authors/canory.yaml
index 0b5ea9e..33281aa 100644
--- a/data/canory.yaml
+++ b/data/authors/canory.yaml
@@ -8,13 +8,16 @@ domain:
host: canory.example
url: https://example.com
epoch: Arrived on the second fortnight of April, `2022`
+footer: Canory's Micro Blog &middot; [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
picture:
header: media/header.jpg
profile: media/picture.png
description: >
Descended from an inner star system of the Sunflower galaxy. Not an owl.
Theme Canory --- a micro blog theme for [Hugo](https://gohugo.io/), one of many
- [static site generators](https://jamstack.org/generators/).
+ [static site](https://jamstack.org/generators/) generators. [Profile](https://pixabay.com/photos/barn-owl-owl-bird-predator-beak-2550068/)
+ by [luboshouska](https://pixabay.com/users/luboshouska-198496/) and [header](https://pixabay.com/photos/galaxy-star-infinity-cosmos-dark-3608029/)
+ by [luminas_art](https://pixabay.com/users/luminas_art-4128746/).
feeds:
rss:
- https://www.rfc-editor.org/rfcrss.xml
diff --git a/data/default.yaml b/data/authors/default.yaml
index f6409a0..db028af 100644
--- a/data/default.yaml
+++ b/data/authors/default.yaml
@@ -13,9 +13,11 @@ picture:
epoch: Appeared sometime around April, `2022`
description: >
Dignissimos quis animi velit. Not a bot. If you believe everything you read on
- the Internet, you'll think that I'm human.
+ the Internet, you'll think that I'm human. [Profile](https://pixabay.com/vectors/robots-automata-grey-bot-3338504/)
+ by [guaxipo](https://pixabay.com/users/guaxipo-8650096/)
+ and [header](https://pixabay.com/photos/circuit-board-electronics-6560489/) by [11082974](https://pixabay.com/users/11082974-11082974/).
feeds:
rss:
- https://hacks.mozilla.org/feed/
- - http://bing.com/HPImageArchive.aspx?format=rss&idx=0&n=1&mkt=en-US
+ - https://bing.com/HPImageArchive.aspx?format=rss&idx=0&n=1&mkt=en-US
json:
diff --git a/shell.nix b/shell.nix
index e002d79..0954bb4 100644
--- a/shell.nix
+++ b/shell.nix
@@ -2,28 +2,25 @@ let
name = "nix-shell.canory";
- pkgs = import (builtins.fetchTarball {
- url = "https://releases.nixos.org/nixos/22.11/nixos-22.11.466.596a8e828c5/nixexprs.tar.xz";
- sha256 = "1367bad5zz0mfm4czb6p0s0ni38f0x1ffh02z76rx4nranipqbgg";
- }) { system = "x86_64-linux"; };
+ system = builtins.currentSystem;
- validatornu = pkgs.callPackage (pkgs.fetchurl {
- url = "https://raw.githubusercontent.com/tdro/dotfiles/032efcf7f4b1c7304ce5f3f64f64c175ba59eb6d/.config/nixpkgs/packages/validatornu/default.nix";
- sha256 = "1ify40x9547z04hcibk76m45d02xg3dlvwc57n8vxcbax82yb9pj";
- }) { };
+ pkgs = import (builtins.fetchTarball {
+ url = "https://releases.nixos.org/nixos/unstable/nixos-23.11pre516114.d680ded26da5/nixexprs.tar.xz";
+ sha256 = "13cnlhpp3v7jay4jxyyy2d4kxw4ngpz3m00rhj3vlhvf7jl7hr48";
+ }) { inherit system; };
hugo = pkgs.callPackage ({ lib, buildGoModule, fetchgit }:
buildGoModule rec {
pname = "hugo";
- version = "0.110.0";
+ version = "0.122.0";
src = fetchgit {
rev = "v${version}";
url = "https://github.com/gohugoio/hugo.git";
- sha256 = "sha256-7B0C8191lUGsv81+0eKDrBm+5hLlFjID3RTuajSg/RM=";
+ sha256 = "sha256-pnsQo+nSuIlQ6KKTP1z/BZ74zEu9HjYP66hGStPc0pc=";
};
doCheck = false;
proxyVendor = true;
- vendorSha256 = "sha256-GtywXjtAF5Q4jUz2clfseUJVqiU+eSguG/ZoKy2TzuA=";
+ vendorSha256 = "sha256-aYy0TOfNIqx44UBXJhewvxi+oSAWjmi/32WvI3HJ3MM=";
tags = [ "extended" ];
subPackages = [ "." ];
meta = {
@@ -39,21 +36,27 @@ let
/usr/bin/env --ignore-environment /bin/sh -c ${
pkgs.writeScript name ''
export PS1='\h (${name}) \W \$ '
+ export HOME=$PWD
+ export HISTFILE=
export DENO_DIR=vendor
+ export DENO_NO_UPDATE_CHECK=1
export PATH=${pkgs.lib.strings.makeBinPath [
hugo
- validatornu
pkgs.busybox
pkgs.caddy
pkgs.check-jsonschema
+ pkgs.curl
pkgs.deno
pkgs.entr
pkgs.git
pkgs.gnumake
+ pkgs.inotify-tools
pkgs.jing
pkgs.libxml2
pkgs.libxslt
- pkgs.subversion
+ pkgs.unixtools.column
+ pkgs.validator-nu
+ pkgs.xmlstarlet
pkgs.yj
]}
/bin/sh
diff --git a/static/icons/feather/LICENSE b/static/icons/feather/LICENSE
index b869713..1f4f433 100644
--- a/static/icons/feather/LICENSE
+++ b/static/icons/feather/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2013-2017 Cole Bemis
+Copyright (c) 2013-2023 Cole Bemis
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE. \ No newline at end of file
+SOFTWARE.
diff --git a/static/icons/feather/alert-circle.svg b/static/icons/feather/alert-circle.svg
index 57fbe36..3672e20 100644
--- a/static/icons/feather/alert-circle.svg
+++ b/static/icons/feather/alert-circle.svg
@@ -1,15 +1,26 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><circle
+ cx="12"
+ cy="12"
+ r="10"
+ /><line
+ x1="12"
+ x2="12"
+ y1="8"
+ y2="12"
+ /><line
+ x1="12"
+ x2="12.01"
+ y1="16"
+ y2="16"
+ /></svg
>
- <circle cx="12" cy="12" r="10" />
- <line x1="12" y1="8" x2="12" y2="12" />
- <line x1="12" y1="16" x2="12.01" y2="16" />
-</svg>
diff --git a/static/icons/feather/archive.svg b/static/icons/feather/archive.svg
deleted file mode 100644
index 978eb76..0000000
--- a/static/icons/feather/archive.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
->
- <polyline points="21 8 21 21 3 21 3 8" />
- <rect x="1" y="3" width="22" height="5" />
- <line x1="10" y1="12" x2="14" y2="12" />
-</svg>
diff --git a/static/icons/feather/arrow-down-circle.svg b/static/icons/feather/arrow-down-circle.svg
index eb9f1a0..816acdd 100644
--- a/static/icons/feather/arrow-down-circle.svg
+++ b/static/icons/feather/arrow-down-circle.svg
@@ -1,15 +1,23 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><circle
+ cx="12"
+ cy="12"
+ r="10"
+ /><polyline
+ points="8 12 12 16 16 12"
+ /><line
+ x1="12"
+ x2="12"
+ y1="8"
+ y2="16"
+ /></svg
>
- <circle cx="12" cy="12" r="10" />
- <polyline points="8 12 12 16 16 12" />
- <line x1="12" y1="8" x2="12" y2="16" />
-</svg>
diff --git a/static/icons/feather/arrow-left.svg b/static/icons/feather/arrow-left.svg
index ce06f88..aebfb9e 100644
--- a/static/icons/feather/arrow-left.svg
+++ b/static/icons/feather/arrow-left.svg
@@ -1,14 +1,19 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><line
+ x1="19"
+ x2="5"
+ y1="12"
+ y2="12"
+ /><polyline
+ points="12 19 5 12 12 5"
+ /></svg
>
- <line x1="19" y1="12" x2="5" y2="12" />
- <polyline points="12 19 5 12 12 5" />
-</svg>
diff --git a/static/icons/feather/arrow-right.svg b/static/icons/feather/arrow-right.svg
index 5c5494f..96fbe50 100644
--- a/static/icons/feather/arrow-right.svg
+++ b/static/icons/feather/arrow-right.svg
@@ -1,14 +1,19 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><line
+ x1="5"
+ x2="19"
+ y1="12"
+ y2="12"
+ /><polyline
+ points="12 5 19 12 12 19"
+ /></svg
>
- <line x1="5" y1="12" x2="19" y2="12" />
- <polyline points="12 5 19 12 12 19" />
-</svg>
diff --git a/static/icons/feather/arrow-up.svg b/static/icons/feather/arrow-up.svg
index f1ff621..8da7d1e 100644
--- a/static/icons/feather/arrow-up.svg
+++ b/static/icons/feather/arrow-up.svg
@@ -1,14 +1,19 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><line
+ x1="12"
+ x2="12"
+ y1="19"
+ y2="5"
+ /><polyline
+ points="5 12 12 5 19 12"
+ /></svg
>
- <line x1="12" y1="19" x2="12" y2="5" />
- <polyline points="5 12 12 5 19 12" />
-</svg>
diff --git a/static/icons/feather/at-sign.svg b/static/icons/feather/at-sign.svg
index 0b7fdfb..28534c6 100644
--- a/static/icons/feather/at-sign.svg
+++ b/static/icons/feather/at-sign.svg
@@ -1,14 +1,18 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><circle
+ cx="12"
+ cy="12"
+ r="4"
+ /><path
+ d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94"
+ /></svg
>
- <circle cx="12" cy="12" r="4" />
- <path d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94" />
-</svg>
diff --git a/static/icons/feather/bookmark.svg b/static/icons/feather/bookmark.svg
new file mode 100644
index 0000000..c553459
--- /dev/null
+++ b/static/icons/feather/bookmark.svg
@@ -0,0 +1,14 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><path
+ d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"
+ /></svg
+>
diff --git a/static/icons/feather/calendar.svg b/static/icons/feather/calendar.svg
index c002b85..9c3693e 100644
--- a/static/icons/feather/calendar.svg
+++ b/static/icons/feather/calendar.svg
@@ -1,16 +1,34 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><rect
+ height="18"
+ rx="2"
+ ry="2"
+ width="18"
+ x="3"
+ y="4"
+ /><line
+ x1="16"
+ x2="16"
+ y1="2"
+ y2="6"
+ /><line
+ x1="8"
+ x2="8"
+ y1="2"
+ y2="6"
+ /><line
+ x1="3"
+ x2="21"
+ y1="10"
+ y2="10"
+ /></svg
>
- <rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
- <line x1="16" y1="2" x2="16" y2="6" />
- <line x1="8" y1="2" x2="8" y2="6" />
- <line x1="3" y1="10" x2="21" y2="10" />
-</svg>
diff --git a/static/icons/feather/circle.svg b/static/icons/feather/circle.svg
deleted file mode 100644
index 1717bb4..0000000
--- a/static/icons/feather/circle.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
->
- <circle cx="12" cy="12" r="10" />
-</svg>
diff --git a/static/icons/feather/clock.svg b/static/icons/feather/clock.svg
index 8ce25b2..9c69907 100644
--- a/static/icons/feather/clock.svg
+++ b/static/icons/feather/clock.svg
@@ -1,14 +1,18 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><circle
+ cx="12"
+ cy="12"
+ r="10"
+ /><polyline
+ points="12 6 12 12 16 14"
+ /></svg
>
- <circle cx="12" cy="12" r="10" />
- <polyline points="12 6 12 12 16 14" />
-</svg>
diff --git a/static/icons/feather/code.svg b/static/icons/feather/code.svg
deleted file mode 100644
index da0f522..0000000
--- a/static/icons/feather/code.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
->
- <polyline points="16 18 22 12 16 6" />
- <polyline points="8 6 2 12 8 18" />
-</svg>
diff --git a/static/icons/feather/copy.svg b/static/icons/feather/copy.svg
deleted file mode 100644
index c8d4956..0000000
--- a/static/icons/feather/copy.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
->
- <rect x="9" y="9" width="13" height="13" rx="2" ry="2" />
- <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" />
-</svg>
diff --git a/static/icons/feather/edit.svg b/static/icons/feather/edit.svg
index 9294758..a6d88b8 100644
--- a/static/icons/feather/edit.svg
+++ b/static/icons/feather/edit.svg
@@ -1,14 +1,16 @@
<svg
- width="24"
- height="24"
- viewBox="0 0 24 24"
- xmlns="http://www.w3.org/2000/svg"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><path
+ d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"
+ /><path
+ d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"
+ /></svg
>
- <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" />
- <path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" />
-</svg>
diff --git a/static/icons/feather/external-link.svg b/static/icons/feather/external-link.svg
index 537b731..a17c25b 100644
--- a/static/icons/feather/external-link.svg
+++ b/static/icons/feather/external-link.svg
@@ -1,15 +1,21 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><path
+ d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"
+ /><polyline
+ points="15 3 21 3 21 9"
+ /><line
+ x1="10"
+ x2="21"
+ y1="14"
+ y2="3"
+ /></svg
>
- <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
- <polyline points="15 3 21 3 21 9" />
- <line x1="10" y1="14" x2="21" y2="3" />
-</svg>
diff --git a/static/icons/feather/eye-off.svg b/static/icons/feather/eye-off.svg
index 98c45f6..0b8c1ee 100644
--- a/static/icons/feather/eye-off.svg
+++ b/static/icons/feather/eye-off.svg
@@ -1,14 +1,19 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><path
+ d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"
+ /><line
+ x1="1"
+ x2="23"
+ y1="1"
+ y2="23"
+ /></svg
>
- <path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24" />
- <line x1="1" y1="1" x2="23" y2="23" />
-</svg>
diff --git a/static/icons/feather/eye.svg b/static/icons/feather/eye.svg
new file mode 100644
index 0000000..de178f2
--- /dev/null
+++ b/static/icons/feather/eye.svg
@@ -0,0 +1,18 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><path
+ d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"
+ /><circle
+ cx="12"
+ cy="12"
+ r="3"
+ /></svg
+>
diff --git a/static/icons/feather/file-text.svg b/static/icons/feather/file-text.svg
index 6cba58c..6c06a4e 100644
--- a/static/icons/feather/file-text.svg
+++ b/static/icons/feather/file-text.svg
@@ -1,17 +1,28 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><path
+ d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"
+ /><polyline
+ points="14 2 14 8 20 8"
+ /><line
+ x1="16"
+ x2="8"
+ y1="13"
+ y2="13"
+ /><line
+ x1="16"
+ x2="8"
+ y1="17"
+ y2="17"
+ /><polyline
+ points="10 9 9 9 8 9"
+ /></svg
>
- <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
- <polyline points="14 2 14 8 20 8" />
- <line x1="16" y1="13" x2="8" y2="13" />
- <line x1="16" y1="17" x2="8" y2="17" />
- <polyline points="10 9 9 9 8 9" />
-</svg>
diff --git a/static/icons/feather/git-commit.svg b/static/icons/feather/git-commit.svg
deleted file mode 100644
index 1574fbd..0000000
--- a/static/icons/feather/git-commit.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
->
- <circle cx="12" cy="12" r="4" />
- <line x1="1.05" y1="12" x2="7" y2="12" />
- <line x1="17.01" y1="12" x2="22.96" y2="12" />
-</svg>
diff --git a/static/icons/feather/globe.svg b/static/icons/feather/globe.svg
index a9c820f..00f792d 100644
--- a/static/icons/feather/globe.svg
+++ b/static/icons/feather/globe.svg
@@ -1,15 +1,23 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><circle
+ cx="12"
+ cy="12"
+ r="10"
+ /><line
+ x1="2"
+ x2="22"
+ y1="12"
+ y2="12"
+ /><path
+ d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"
+ /></svg
>
- <circle cx="12" cy="12" r="10" />
- <line x1="2" y1="12" x2="22" y2="12" />
- <path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" />
-</svg>
diff --git a/static/icons/feather/heart.svg b/static/icons/feather/heart.svg
deleted file mode 100644
index 8e0b98d..0000000
--- a/static/icons/feather/heart.svg
+++ /dev/null
@@ -1,13 +0,0 @@
-<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
->
- <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
-</svg>
diff --git a/static/icons/feather/home.svg b/static/icons/feather/home.svg
deleted file mode 100644
index 9cd8f76..0000000
--- a/static/icons/feather/home.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
->
- <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
- <polyline points="9 22 9 12 15 12 15 22" />
-</svg>
diff --git a/static/icons/feather/link.svg b/static/icons/feather/link.svg
index 645e746..51f6aac 100644
--- a/static/icons/feather/link.svg
+++ b/static/icons/feather/link.svg
@@ -1,14 +1,16 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><path
+ d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"
+ /><path
+ d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"
+ /></svg
>
- <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" />
- <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" />
-</svg>
diff --git a/static/icons/feather/map-pin.svg b/static/icons/feather/map-pin.svg
index 8f5f320..7802b5a 100644
--- a/static/icons/feather/map-pin.svg
+++ b/static/icons/feather/map-pin.svg
@@ -1,14 +1,18 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><path
+ d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"
+ /><circle
+ cx="12"
+ cy="10"
+ r="3"
+ /></svg
>
- <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" />
- <circle cx="12" cy="10" r="3" />
-</svg>
diff --git a/static/icons/feather/refresh-cw.svg b/static/icons/feather/refresh-cw.svg
new file mode 100644
index 0000000..f48fd7e
--- /dev/null
+++ b/static/icons/feather/refresh-cw.svg
@@ -0,0 +1,18 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><polyline
+ points="23 4 23 10 17 10"
+ /><polyline
+ points="1 20 1 14 7 14"
+ /><path
+ d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"
+ /></svg
+>
diff --git a/static/icons/feather/rss.svg b/static/icons/feather/rss.svg
deleted file mode 100644
index 3b87036..0000000
--- a/static/icons/feather/rss.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
->
- <path d="M4 11a9 9 0 0 1 9 9" />
- <path d="M4 4a16 16 0 0 1 16 16" />
- <circle cx="5" cy="19" r="1" />
-</svg>
diff --git a/static/icons/feather/search.svg b/static/icons/feather/search.svg
index 89a8636..8eaab65 100644
--- a/static/icons/feather/search.svg
+++ b/static/icons/feather/search.svg
@@ -1,14 +1,21 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><circle
+ cx="11"
+ cy="11"
+ r="8"
+ /><line
+ x1="21"
+ x2="16.65"
+ y1="21"
+ y2="16.65"
+ /></svg
>
- <circle cx="11" cy="11" r="8" />
- <line x1="21" y1="21" x2="16.65" y2="16.65" />
-</svg>
diff --git a/static/icons/feather/tag.svg b/static/icons/feather/tag.svg
deleted file mode 100644
index e8500cd..0000000
--- a/static/icons/feather/tag.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
->
- <path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z" />
- <line x1="7" y1="7" x2="7.01" y2="7" />
-</svg>
diff --git a/static/icons/feather/trash-2.svg b/static/icons/feather/trash-2.svg
index f3bd2bd..462a3f7 100644
--- a/static/icons/feather/trash-2.svg
+++ b/static/icons/feather/trash-2.svg
@@ -1,16 +1,26 @@
<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ ><polyline
+ points="3 6 5 6 21 6"
+ /><path
+ d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"
+ /><line
+ x1="10"
+ x2="10"
+ y1="11"
+ y2="17"
+ /><line
+ x1="14"
+ x2="14"
+ y1="11"
+ y2="17"
+ /></svg
>
- <polyline points="3 6 5 6 21 6" />
- <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
- <line x1="10" y1="11" x2="10" y2="17" />
- <line x1="14" y1="11" x2="14" y2="17" />
-</svg>
diff --git a/static/icons/feather/user.svg b/static/icons/feather/user.svg
deleted file mode 100644
index f075a65..0000000
--- a/static/icons/feather/user.svg
+++ /dev/null
@@ -1,14 +0,0 @@
-<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
->
- <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
- <circle cx="12" cy="7" r="4" />
-</svg>
diff --git a/static/icons/feather/users.svg b/static/icons/feather/users.svg
deleted file mode 100644
index eb87d02..0000000
--- a/static/icons/feather/users.svg
+++ /dev/null
@@ -1,16 +0,0 @@
-<svg
- xmlns="http://www.w3.org/2000/svg"
- width="24"
- height="24"
- viewBox="0 0 24 24"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- stroke-linecap="round"
- stroke-linejoin="round"
->
- <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
- <circle cx="9" cy="7" r="4" />
- <path d="M23 21v-2a4 4 0 0 0-3-3.87" />
- <path d="M16 3.13a4 4 0 0 1 0 7.75" />
-</svg>
diff --git a/static/icons/tabler/LICENSE b/static/icons/tabler/LICENSE
index 1f192ee..974db1a 100644
--- a/static/icons/tabler/LICENSE
+++ b/static/icons/tabler/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2020-2022 Paweł Kuna
+Copyright (c) 2020-2024 Paweł Kuna
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/static/icons/tabler/archive.svg b/static/icons/tabler/archive.svg
new file mode 100644
index 0000000..d55999b
--- /dev/null
+++ b/static/icons/tabler/archive.svg
@@ -0,0 +1,22 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M3 4m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v0a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z"
+ />
+ <path
+ d="M5 8v10a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-10"
+ />
+ <path
+ d="M10 12l4 0"
+ />
+</svg
+>
diff --git a/static/icons/tabler/book-2.svg b/static/icons/tabler/book-2.svg
index e136c71..0800060 100644
--- a/static/icons/tabler/book-2.svg
+++ b/static/icons/tabler/book-2.svg
@@ -1,8 +1,22 @@
-<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-book-2" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
- <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
- <path d="M19 4v16h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12z" />
- <path d="M19 16h-12a2 2 0 0 0 -2 2" />
- <path d="M9 8h6" />
-</svg>
-
-
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M19 4v16h-12a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h12z"
+ />
+ <path
+ d="M19 16h-12a2 2 0 0 0 -2 2"
+ />
+ <path
+ d="M9 8h6"
+ />
+</svg
+>
diff --git a/static/icons/tabler/circle.svg b/static/icons/tabler/circle.svg
new file mode 100644
index 0000000..5660b32
--- /dev/null
+++ b/static/icons/tabler/circle.svg
@@ -0,0 +1,16 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0"
+ />
+</svg
+>
diff --git a/static/icons/tabler/clock.svg b/static/icons/tabler/clock.svg
index fd98984..7ad7d57 100644
--- a/static/icons/tabler/clock.svg
+++ b/static/icons/tabler/clock.svg
@@ -1,7 +1,19 @@
-<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-clock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
- <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
- <circle cx="12" cy="12" r="9" />
- <polyline points="12 7 12 12 15 15" />
-</svg>
-
-
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M3 12a9 9 0 1 0 18 0a9 9 0 0 0 -18 0"
+ />
+ <path
+ d="M12 7v5l3 3"
+ />
+</svg
+>
diff --git a/static/icons/tabler/code.svg b/static/icons/tabler/code.svg
new file mode 100644
index 0000000..f9f1ba3
--- /dev/null
+++ b/static/icons/tabler/code.svg
@@ -0,0 +1,22 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M7 8l-4 4l4 4"
+ />
+ <path
+ d="M17 8l4 4l-4 4"
+ />
+ <path
+ d="M14 4l-4 16"
+ />
+</svg
+>
diff --git a/static/icons/tabler/git-fork.svg b/static/icons/tabler/git-fork.svg
new file mode 100644
index 0000000..a27d387
--- /dev/null
+++ b/static/icons/tabler/git-fork.svg
@@ -0,0 +1,28 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M12 18m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0"
+ />
+ <path
+ d="M7 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0"
+ />
+ <path
+ d="M17 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0"
+ />
+ <path
+ d="M7 8v2a2 2 0 0 0 2 2h6a2 2 0 0 0 2 -2v-2"
+ />
+ <path
+ d="M12 12l0 4"
+ />
+</svg
+>
diff --git a/static/icons/tabler/home.svg b/static/icons/tabler/home.svg
new file mode 100644
index 0000000..ebe632d
--- /dev/null
+++ b/static/icons/tabler/home.svg
@@ -0,0 +1,22 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M5 12l-2 0l9 -9l9 9l-2 0"
+ />
+ <path
+ d="M5 12v7a2 2 0 0 0 2 2h10a2 2 0 0 0 2 -2v-7"
+ />
+ <path
+ d="M9 21v-6a2 2 0 0 1 2 -2h2a2 2 0 0 1 2 2v6"
+ />
+</svg
+>
diff --git a/static/icons/tabler/notes.svg b/static/icons/tabler/notes.svg
new file mode 100644
index 0000000..a102d6e
--- /dev/null
+++ b/static/icons/tabler/notes.svg
@@ -0,0 +1,25 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M5 3m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z"
+ />
+ <path
+ d="M9 7l6 0"
+ />
+ <path
+ d="M9 11l6 0"
+ />
+ <path
+ d="M9 15l4 0"
+ />
+</svg
+>
diff --git a/static/icons/tabler/pinned.svg b/static/icons/tabler/pinned.svg
index fac8252..74002cb 100644
--- a/static/icons/tabler/pinned.svg
+++ b/static/icons/tabler/pinned.svg
@@ -1,8 +1,22 @@
-<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-pinned" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
- <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
- <path d="M9 4v6l-2 4v2h10v-2l-2 -4v-6" />
- <line x1="12" y1="16" x2="12" y2="21" />
- <line x1="8" y1="4" x2="16" y2="4" />
-</svg>
-
-
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M9 4v6l-2 4v2h10v-2l-2 -4v-6"
+ />
+ <path
+ d="M12 16l0 5"
+ />
+ <path
+ d="M8 4l8 0"
+ />
+</svg
+>
diff --git a/static/icons/tabler/robot.svg b/static/icons/tabler/robot.svg
index 0b94b49..8db2809 100644
--- a/static/icons/tabler/robot.svg
+++ b/static/icons/tabler/robot.svg
@@ -1,11 +1,40 @@
-<svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-robot" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round">
- <path stroke="none" d="M0 0h24v24H0z" fill="none"/>
- <path d="M7 7h10a2 2 0 0 1 2 2v1l1 1v3l-1 1v3a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-3l-1 -1v-3l1 -1v-1a2 2 0 0 1 2 -2z" />
- <path d="M10 16h4" />
- <circle cx="8.5" cy="11.5" r=".5" fill="currentColor" />
- <circle cx="15.5" cy="11.5" r=".5" fill="currentColor" />
- <path d="M9 7l-1 -4" />
- <path d="M15 7l1 -4" />
-</svg>
-
-
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M6 4m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v4a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"
+ />
+ <path
+ d="M12 2v2"
+ />
+ <path
+ d="M9 12v9"
+ />
+ <path
+ d="M15 12v9"
+ />
+ <path
+ d="M5 16l4 -2"
+ />
+ <path
+ d="M15 14l4 2"
+ />
+ <path
+ d="M9 18h6"
+ />
+ <path
+ d="M10 8v.01"
+ />
+ <path
+ d="M14 8v.01"
+ />
+</svg
+>
diff --git a/static/icons/tabler/rss.svg b/static/icons/tabler/rss.svg
new file mode 100644
index 0000000..884e1a6
--- /dev/null
+++ b/static/icons/tabler/rss.svg
@@ -0,0 +1,22 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M5 19m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"
+ />
+ <path
+ d="M4 4a16 16 0 0 1 16 16"
+ />
+ <path
+ d="M4 11a9 9 0 0 1 9 9"
+ />
+</svg
+>
diff --git a/static/icons/tabler/settings.svg b/static/icons/tabler/settings.svg
new file mode 100644
index 0000000..02bea1e
--- /dev/null
+++ b/static/icons/tabler/settings.svg
@@ -0,0 +1,19 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z"
+ />
+ <path
+ d="M9 12a3 3 0 1 0 6 0a3 3 0 0 0 -6 0"
+ />
+</svg
+>
diff --git a/static/icons/tabler/square-letter-m.svg b/static/icons/tabler/square-letter-m.svg
new file mode 100644
index 0000000..721e549
--- /dev/null
+++ b/static/icons/tabler/square-letter-m.svg
@@ -0,0 +1,19 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M3 3m0 2a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v14a2 2 0 0 1 -2 2h-14a2 2 0 0 1 -2 -2z"
+ />
+ <path
+ d="M9 16v-8l3 5l3 -5v8"
+ />
+</svg
+>
diff --git a/static/icons/tabler/tag.svg b/static/icons/tabler/tag.svg
new file mode 100644
index 0000000..abbb8c6
--- /dev/null
+++ b/static/icons/tabler/tag.svg
@@ -0,0 +1,19 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M7.5 7.5m-1 0a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"
+ />
+ <path
+ d="M3 6v5.172a2 2 0 0 0 .586 1.414l7.71 7.71a2.41 2.41 0 0 0 3.408 0l5.592 -5.592a2.41 2.41 0 0 0 0 -3.408l-7.71 -7.71a2 2 0 0 0 -1.414 -.586h-5.172a3 3 0 0 0 -3 3z"
+ />
+</svg
+>
diff --git a/static/icons/tabler/users.svg b/static/icons/tabler/users.svg
new file mode 100644
index 0000000..6fa6286
--- /dev/null
+++ b/static/icons/tabler/users.svg
@@ -0,0 +1,25 @@
+<svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ height="24"
+ stroke="currentColor"
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ stroke-width="2"
+ viewBox="0 0 24 24"
+ width="24"
+ >
+ <path
+ d="M9 7m-4 0a4 4 0 1 0 8 0a4 4 0 1 0 -8 0"
+ />
+ <path
+ d="M3 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2"
+ />
+ <path
+ d="M16 3.13a4 4 0 0 1 0 7.75"
+ />
+ <path
+ d="M21 21v-2a4 4 0 0 0 -3 -3.85"
+ />
+</svg
+>
diff --git a/static/js/autoplay.ts b/static/js/autoplay.ts
new file mode 100644
index 0000000..5987576
--- /dev/null
+++ b/static/js/autoplay.ts
@@ -0,0 +1,42 @@
+(function () {
+ function viewport(element) {
+ const options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : {
+ offset: { top: -50, left: 0, bottom: -50, right: 0 }
+ };
+ const view = element.getBoundingClientRect();
+ return view.top >= -options.offset.top
+ && view.left >= -options.offset.left
+ && view.bottom <= (self.innerHeight || document.documentElement.clientHeight) + options.offset.bottom
+ && view.right <= (self.innerWidth || document.documentElement.clientWidth) + options.offset.right;
+ };
+
+ ["scroll", "DOMContentLoaded"].forEach(function (event) {
+ self.addEventListener(event, function () {
+ let first = true;
+ let videos = document.querySelectorAll("video");
+
+ for (i = 0; i < videos.length; i++) {
+ videos[i].autoplay = true;
+ videos[i].controls = true;
+ videos[i].loop = true;
+ videos[i].muted = true;
+ videos[i].playsinline = true;
+
+ videos[i].setAttribute("autoplay", true);
+ videos[i].setAttribute("controls", true);
+ videos[i].setAttribute("loop", true);
+ videos[i].setAttribute("muted", true);
+ videos[i].setAttribute("playsinline", true);
+
+ const onscreen = viewport(videos[i]);
+
+ if (first && onscreen) {
+ videos[i].play();
+ first = false;
+ } else {
+ videos[i].pause();
+ }
+ }
+ });
+ });
+})();
diff --git a/static/js/codecopy.ts b/static/js/codecopy.ts
index 7c47c65..9885ad8 100644
--- a/static/js/codecopy.ts
+++ b/static/js/codecopy.ts
@@ -7,15 +7,12 @@
setTimeout(
async () => {
await navigator.clipboard.writeText(text);
- console.log("Info: Code block text copied succesfully.");
+ console.log("INFO: Code text copied successfully");
},
3000,
);
} catch (error) {
- console.error(
- "Error: navigator.clipboard.writeText() failed.",
- error,
- );
+ console.error("ERROR: Code text copy failed", error);
}
},
);
diff --git a/static/js/contextmenu.ts b/static/js/contextmenu.ts
index dea9bec..5add288 100644
--- a/static/js/contextmenu.ts
+++ b/static/js/contextmenu.ts
@@ -1,11 +1,11 @@
(function () {
- const hide = (triggers) => {
+ const hide = function (triggers) {
for (let i = 0; i < triggers.length; i++) {
triggers[i].checked = false;
}
};
- const hideIfClickedOutside = (menus, triggers, event) => {
+ const hideIfClickedOutside = function (menus, triggers, event) {
for (let i = 0; i < menus.length; i++) {
const active = triggers[i].checked === true;
const outside = !menus[i].contains(event.target);
@@ -14,14 +14,14 @@
};
self.addEventListener("scroll", function () {
- const triggers = document.querySelectorAll("micro-metadata-menu input");
+ const triggers = document.querySelectorAll("menu input");
hide(triggers);
});
["click", "touchstart"].forEach(function (event) {
self.addEventListener(event, function (event) {
- const menus = document.querySelectorAll("micro-metadata-menu");
- const triggers = document.querySelectorAll("micro-metadata-menu input");
+ const menus = document.querySelectorAll("menu");
+ const triggers = document.querySelectorAll("menu input");
hideIfClickedOutside(menus, triggers, event);
});
});
diff --git a/static/js/domfilter.ts b/static/js/domfilter.ts
new file mode 100644
index 0000000..8900e2f
--- /dev/null
+++ b/static/js/domfilter.ts
@@ -0,0 +1,145 @@
+/*
+ * DOM Filter Copyright (C) 2024 Thedro Neely
+ * Licence: AGPL | https://www.gnu.org/licenses/agpl-3.0.txt
+*/
+
+(function () {
+ type millisecond = number;
+ const timeout: millisecond = 300;
+
+ const state = "on";
+ const key = "config.navigation.fast";
+
+ function fetch(url, method, callback) {
+ const http = new XMLHttpRequest();
+ http.onreadystatechange = function () {
+ if (callback && http.readyState === 4) {
+ if (http.status === 200) callback(http);
+ else {
+ console.error("ERROR: Unable to navigate", http);
+ self.location.href = url;
+ }
+ }
+ };
+ http.open(method, url);
+ http.timeout = timeout;
+ http.send();
+ return http;
+ }
+
+ function styles(node) {
+ return (node.nodeName === "LINK") && node.rel && node.rel.includes("stylesheet");
+ }
+
+ function scripts(node) {
+ return (node.nodeName === "SCRIPT") && node.hasAttribute("src");
+ }
+
+ function filter(url, http) {
+ let live = document;
+ let node = live.head.childNodes.length;
+ let next = (new DOMParser()).parseFromString(http.responseText, "text/html");
+
+ if (next.doctype === null || !http.getResponseHeader("content-type").includes("text/html")) return false;
+
+ while (node--) {
+ if (styles(live.head.childNodes[node]) || scripts(live.head.childNodes[node])) {
+ // console.log("INFO: Persist:", live.head.childNodes[node]);
+ } else {
+ live.head.removeChild(live.head.childNodes[node]);
+ }
+ }
+
+ while (next.head.firstChild) {
+ if (styles(next.head.firstChild) || scripts(next.head.firstChild)) {
+ next.head.removeChild(next.head.firstChild);
+ } else {
+ live.head.appendChild(next.head.firstChild);
+ }
+ }
+
+ while (live.documentElement.attributes.length > 0) {
+ live.documentElement.removeAttribute(
+ live.documentElement.attributes[live.documentElement.attributes.length - 1].name,
+ );
+ }
+
+ while (next.documentElement.attributes.length > 0) {
+ live.documentElement.setAttribute(
+ next.documentElement.attributes[next.documentElement.attributes.length - 1].name,
+ next.documentElement.attributes[next.documentElement.attributes.length - 1].value,
+ );
+ next.documentElement.removeAttribute(
+ next.documentElement.attributes[next.documentElement.attributes.length - 1].name,
+ );
+ }
+
+ live.body.parentElement.replaceChild(next.body, live.body);
+ }
+
+ function persist() {
+ let persist = document.createElement("link");
+ persist.rel = "location";
+ persist.target = JSON.stringify(self.location);
+ document.head.appendChild(persist);
+ }
+
+ self.addEventListener("DOMContentLoaded", function () {
+ if (localStorage[key] !== state) return;
+ persist();
+ });
+
+ self.addEventListener("popstate", function (event) {
+ if (localStorage[key] !== state) return;
+ const link = JSON.parse(document.querySelector('link[rel="location"]').target);
+ const url = event.target.location;
+ const hashed = link.pathname === url.pathname;
+ if (hashed) return;
+ fetch(url, "GET", function (http) {
+ if (filter(url, http) === false) return self.location.href = url;
+ persist();
+ self.document.dispatchEvent(new CustomEvent("URLChangedCustomEvent", { bubbles: true }));
+ });
+ });
+
+ self.addEventListener("click", function (event) {
+ if (localStorage[key] !== state) return;
+ const links = document.querySelectorAll("a");
+ for (let i = 0; i < links.length; i++) {
+ const active = links[i].contains(event.target);
+ const change = self.location.href !== links[i].href;
+ const view = links[i].attributes.hasOwnProperty("download") === false;
+ const local = self.location.origin === links[i].origin && links[i].target !== "_self";
+ const hashed = self.location.pathname === links[i].pathname && links[i].href.includes("#");
+ if (active && local && change && view && (hashed === false)) {
+ event.preventDefault();
+ const url = links[i].href;
+ links[i].style.cursor = "wait";
+ fetch(url, "GET", function (http) {
+ links[i].removeAttribute("style")
+ if (filter(url, http) === false) return self.location.href = url;
+ history.pushState({}, "", links[i].href);
+ persist();
+ self.document.dispatchEvent(new CustomEvent("URLChangedCustomEvent", { bubbles: true }));
+ });
+ }
+ }
+ });
+})();
+
+/*
+ * Copyright (C) 2024 Thedro Neely
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+*/
diff --git a/static/js/fixedsearch.ts b/static/js/fixedsearch.ts
index 938e1f5..04d318b 100644
--- a/static/js/fixedsearch.ts
+++ b/static/js/fixedsearch.ts
@@ -1,19 +1,24 @@
/*
- Modified Version of Fixed Search: https://gist.github.com/cmod/5410eae147e4318164258742dd053993
- MIT License: https://gist.github.com/Arty2/8b0c43581013753438a3d35c15091a9f#file-license-md
+ * Fixed Search Copyright (C) 2020 Heracles Papatheodorou
+ * Copyright (C) Craig Mod, Eddie Webb, and Matthew Daly
+ * https://gist.github.com/Arty2/8b0c43581013753438a3d35c15091a9f#file-license-md
+ * Licence: MIT | https://mit-license.org/
*/
(function () {
- self.addEventListener("DOMContentLoaded", function () {
- const form = document.getElementById("search-form"); // search form
- const query = document.getElementById("search-input"); // input box for search
- const submit = document.getElementById("search-submit"); // form submit button
- const dropdown = document.getElementById("search-results"); // targets the <ul>
- const container = document.getElementById("search-frame"); // targets the upper parent container
+ ["DOMContentLoaded", "URLChangedCustomEvent"].forEach(function (event) {
+ self.addEventListener(event, function () {
+ const container = document.querySelector("search-box");
+ const dropdown = document.querySelector("search-box ul");
+ const form = document.querySelector("search-box form");
+ const query = document.querySelector("search-box input");
+ const submit = document.querySelector("search-box button");
function first(element) {
+ if (element.firstChild.nextElementSibling) {
return element.firstChild.nextElementSibling.firstChild
.nextElementSibling;
+ }
}
function last(element) {
@@ -35,9 +40,28 @@
document.dispatchEvent(new KeyboardEvent("keydown", { "key": keyname }));
}
+ let selected;
+
+ if (submit === null) return;
+
submit.addEventListener("click", function (event) {
+ if (selected) {
+ event.preventDefault();
+ selected.focus();
+ return selected.click();
+ }
first(dropdown).focus();
press("ArrowDown");
+ document.activeElement.click();
+ });
+
+ ["keyup", "click"].forEach(function (event) {
+ form.addEventListener(event, function () {
+ if (document.activeElement.nodeName === "A") {
+ return selected = document.activeElement;
+ }
+ selected = undefined;
+ });
});
form.addEventListener("focusin", function () {
@@ -51,11 +75,8 @@
});
form.addEventListener("keydown", function (event) {
- const head = first(dropdown);
- const tail = last(dropdown);
-
// ESC (27)
- if (query.contains(event.target)) {
+ if (form.contains(event.target)) {
if (event.keyCode == 27) {
document.activeElement.blur();
dropdown.setAttribute("hidden", "");
@@ -63,6 +84,17 @@
}
}
+ // BACKSPACE (8)
+ if (event.keyCode == 8) {
+ if (document.activeElement != query) {
+ event.preventDefault();
+ query.focus();
+ }
+ }
+
+ const head = first(dropdown);
+ const tail = last(dropdown);
+
// DOWN (40)
if (event.keyCode == 40) {
event.preventDefault();
@@ -79,20 +111,12 @@
else previous(document);
}
- // BACKSPACE (8)
- if (event.keyCode == 8) {
- if (document.activeElement != query) {
- event.preventDefault();
- query.focus();
- }
- }
-
// ENTER (13)
if (event.keyCode == 13) {
if (dropdown && document.activeElement == query) {
event.preventDefault();
head.focus();
- self.window.location = document.activeElement.href;
+ head.click();
}
}
});
@@ -109,46 +133,31 @@
scrolls++;
});
- document.addEventListener("click", function (event) {
- if (!form.contains(event.target)) {
+ self.addEventListener("click", function (event) {
+ if (
+ !form.contains(event.target) &&
+ !(document.activeElement === query) &&
+ !(document.activeElement === submit)
+ ) {
dropdown.setAttribute("hidden", "");
container.removeAttribute("data-focus");
}
});
- let data = {};
-
- function isEmpty(obj) {
- return Object.keys(obj).length === 0;
- }
-
- function appendItemsTo(local, remote) {
- const paginated = Object.keys(remote).includes("next_url");
- if (isEmpty(local)) {
- local = remote;
- } else {
- local.items = local.items.concat(remote.items);
- }
- if (paginated) {
- fetchJson(remote.next_url, local);
- }
- data = local;
- }
-
- function fetchJson(url, store) {
- const httpRequest = new XMLHttpRequest();
- httpRequest.onreadystatechange = function () {
- if (httpRequest.readyState === 4 && httpRequest.status === 200) {
- appendItemsTo(store, JSON.parse(httpRequest.responseText));
+ function fetch(url, callback) {
+ const http = new XMLHttpRequest();
+ http.onreadystatechange = function () {
+ if (http.readyState === 4 && http.status === 200 && callback) {
+ callback(http);
}
};
- httpRequest.open("GET", url);
- httpRequest.send();
+ http.open("GET", url);
+ http.send();
}
/* Load script based on https://stackoverflow.com/a/55451823 */
- function loadScript(url) {
+ function script(url) {
return new Promise(function (resolve, reject) {
const script = document.createElement("script");
script.onerror = reject;
@@ -158,35 +167,54 @@
script,
document.currentScript,
);
- } else {
- document.head.appendChild(script);
- }
+ } else document.head.appendChild(script);
script.src = url;
});
}
- let firstRun = true;
+ let data = {};
+ let boot = true;
+
+ const options = { key: ["title"] };
- function initialize() {
- if (firstRun) {
- loadScript(window.location.origin + "/js/fuzzysort.js")
- .then(() => {
- firstRun = false;
- fetchJson("/index.json", {});
+ function isEmpty(obj) { return Object.keys(obj).length === 0; }
- const options = { key: ["title"] };
+ function appendItemsTo(local, remote) {
+ const paginated = Object.keys(remote).includes("next_url");
+ if (isEmpty(local)) {
+ local = remote;
+ } else {
+ local.items = local.items.concat(remote.items);
+ }
+ if (paginated) {
+ fetch(remote.next_url, function (request) {
+ appendItemsTo(local, JSON.parse(request.responseText));
+ });
+ } else search(query.value, data.items, options);
+ data = local;
+ }
- query.addEventListener("keyup", function () {
- search(query.value, data.items, options);
+ function initialize() {
+ if (boot) {
+ script(window.location.origin + "/js/fuzzysort.js")
+ .then(function () {
+
+ fetch("/index.json", function (request) {
+ appendItemsTo({}, JSON.parse(request.responseText));
+ search("", data.items, options);
+ boot = false;
});
- query.addEventListener("focusin", function () {
- search(query.value, data.items, options);
+
+ ["keyup", "focusin"].forEach(function (event) {
+ query.addEventListener(event, function () {
+ if (data.items) search(query.value, data.items, options);
+ else { boot = true; initialize(); }
+ });
});
- search(query.value, data.items, options);
- }).catch((error) => {
- console.log("Error failed to load fuzzy sort: " + error);
+ }).catch(function (error) {
+ console.error("ERROR: Failed to load fuzzy search", error);
});
}
}
@@ -204,18 +232,15 @@
if (results.length === 0 && term.length >= 0) {
let separator = "—";
if (term.length === 0) separator = "";
- items = `
- <li>
- <a href="javascript: void(0)" tabindex="0">${
- escape(term)
- } ${separator} No Results Found</a>
- </li>
- `;
+ items = '<li><a tabindex="0">'.concat(
+ escape(term),
+ " ",
+ ).concat(separator, " No Results Found</a></li>");
dropdown.removeAttribute("hidden");
container.setAttribute("data-focus", "");
} else {
dropdown.removeAttribute("hidden");
- for (const string in results.slice(0, 10)) {
+ for (var string in results.slice(0, 10)) {
const title = results[string].obj.title;
let highlight = fuzzysort.highlight(
fuzzysort.single(escape(term), escape(title)),
@@ -223,20 +248,17 @@
"</span>",
);
- if (highlight === null) {
- highlight = title;
- }
+ if (highlight === null) highlight = title;
items = items +
- `
- <li>
- <a href="${results[string].obj.url}" tabindex="0">${highlight}</a>
- </li>
- `;
+ '\n<li>\n<a href="'.concat(
+ results[string].obj.url,
+ '" tabindex="0">',
+ ).concat(highlight, "</a>\n</li>\n");
}
}
-
dropdown.innerHTML = items;
}
});
+ });
})();
diff --git a/static/js/forms.ts b/static/js/forms.ts
new file mode 100644
index 0000000..263fda1
--- /dev/null
+++ b/static/js/forms.ts
@@ -0,0 +1,130 @@
+(function () {
+
+ const cookiesDisabled = !navigator.cookieEnabled;
+
+ if (cookiesDisabled) {
+ document.cookie = "disabled";
+ document.cookie.indexOf("disabled");
+ return console.warn("WARNING: Cannot persist form state due to cookie restrictions");
+ }
+
+ const storage = document.createEvent("Event");
+ storage.initEvent("storage", true, true);
+
+ ["pageshow", "URLChangedCustomEvent", "DOMContentLoaded"].forEach(function (event) {
+ self.addEventListener(event, function (event) {
+ const input = Array.prototype.slice.call(document.querySelectorAll("form input"));
+ const select = Array.prototype.slice.call(document.querySelectorAll("form select"));
+ const textarea = Array.prototype.slice.call(document.querySelectorAll("form textarea"));
+ const summary = Array.prototype.slice.call(document.querySelectorAll("details summary"));
+
+ const states = input.concat(select).concat(textarea);
+
+ for (var i = 0; i < states.length; i++) {
+ const state = states[i];
+ const sync = i === states.length - 1;
+
+ if (localStorage[state.id]) {
+ if (state.type === "radio" || state.type === "checkbox") {
+ if (localStorage[state.id] === "on") state.checked = true;
+ } else state.value = localStorage[state.id];
+ }
+
+ if (sync) self.dispatchEvent(storage);
+
+ state.addEventListener("change", function (event) {
+
+ // console.log("INFO: STATE:", event.target);
+ // console.log("INFO: ID:", event.target.id);
+ // console.log("INFO: NAME:", event.target.name);
+ // console.log("INFO: TYPE:", event.target.type);
+ // console.log("INFO: VALUE:", event.target.value);
+ // console.log("INFO: CHECKED:", event.target.checked);
+
+ localStorage[event.target.id] = event.target.value;
+
+ const group = document.querySelectorAll("input[name='".concat(event.target.name, "']"));
+
+ for (var j = 0; j < group.length; j++) {
+ const member = group[j];
+ if ((member.type === "radio" || member.type === "checkbox") && !member.checked) {
+ localStorage[member.id] = "off";
+ }
+ }
+ self.dispatchEvent(new Event("storage"));
+ });
+ }
+
+ for (var k = 0; k < summary.length; k++) {
+ let child = summary[k];
+ let details = child.parentElement;
+
+ if (details.id && details.nodeName === "DETAILS") {
+ sessionStorage[details.id] === "false" && details.removeAttribute("open");
+ sessionStorage[details.id] === "true" && details.setAttribute("open", true);
+
+ child.addEventListener("click", function (event) {
+ let child = (event.target.nodeName === "SUMMARY" && event.target)
+ || event.target.parentElement;
+ let details = child.parentElement;
+ if (details.id && details.nodeName === "DETAILS") {
+ sessionStorage[details.id] = !details.open;
+ }
+ });
+ }
+ }
+ });
+ });
+
+ ["storage"].forEach(function (event) {
+ self.addEventListener(event, function () {
+ let stylesheet;
+
+ stylesheet = document.querySelector('link[href$="default-simple.css"]')
+
+ if (localStorage["config.layout.simple"] === "on") stylesheet.rel = "stylesheet"
+ if (localStorage["config.layout.default"] === "on") stylesheet.rel = "alternate stylesheet"
+
+ stylesheet = document.querySelector('link[href$="default-fast.css"]')
+
+ if (localStorage["config.navigation.fast"] === "on") stylesheet.rel = "stylesheet"
+ if (localStorage["config.navigation.slow"] === "on") stylesheet.rel = "alternate stylesheet"
+
+ for (var i = 0; i < document.styleSheets.length; i++) {
+ let stylesheet = document.styleSheets[i];
+ for (var k = 0; k < stylesheet.rules.length; k++) {
+ let media = stylesheet.rules[k].media;
+ if (media && media.mediaText.includes("prefers-color-scheme")) {
+ if (localStorage["config.theme.light"] === "on") {
+ media.mediaText = "(prefers-color-scheme: dark)";
+ if (getComputedStyle(document.body).getPropertyValue("color-scheme") === "dark") { media.mediaText = "(prefers-color-scheme: light)"; }
+ }
+
+ if (localStorage["config.theme.auto"] === "on") {
+ media.mediaText = "(prefers-color-scheme: dark)";
+ }
+
+ if (localStorage["config.theme.dark"] === "on") {
+ media.mediaText = "(prefers-color-scheme: light)";
+ if (getComputedStyle(document.body).getPropertyValue("color-scheme") === "light") { media.mediaText = "(prefers-color-scheme: dark)"; }
+ }
+ }
+ }
+ }
+ });
+ });
+
+ const early = setInterval(persistence, 4);
+
+ function persistence() {
+ if (document.styleSheets.length > 0) {
+ self.dispatchEvent(storage);
+ clearInterval(early);
+ }
+ }
+
+ self.addEventListener("DOMContentLoaded", function () {
+ self.dispatchEvent(storage);
+ clearInterval(early);
+ });
+})();
diff --git a/static/js/fuzzysort.js b/static/js/fuzzysort.js
index c6797d8..71c2fcb 100644
--- a/static/js/fuzzysort.js
+++ b/static/js/fuzzysort.js
@@ -1,636 +1,549 @@
/*
- fuzzysort.js https://github.com/farzher/fuzzysort
- SublimeText-like Fuzzy Search
+ * Fuzzy Sort Copyright (C) 2018 Stephen Kamenar
+ * https://github.com/farzher/fuzzysort/blob/master/LICENSE
+ * Licence: MIT | https://mit-license.org/
+*/
- fuzzysort.single('fs', 'Fuzzy Search') // {score: -16}
- fuzzysort.single('test', 'test') // {score: 0}
- fuzzysort.single('doesnt exist', 'target') // null
+;((root, UMD) => {
+ if(typeof define === 'function' && define.amd) define([], UMD)
+ else if(typeof module === 'object' && module.exports) module.exports = UMD()
+ else root['fuzzysort'] = UMD()
+})(this, _ => {
+ 'use strict'
- fuzzysort.go('mr', [{file:'Monitor.cpp'}, {file:'MeshRenderer.cpp'}], {key:'file'})
- // [{score:-18, obj:{file:'MeshRenderer.cpp'}}, {score:-6009, obj:{file:'Monitor.cpp'}}]
+ var single = (search, target) => { if(search=='farzher')return{target:"farzher was here (^-^*)/",score:0,_indexes:[0]}
+ if(!search || !target) return NULL
- fuzzysort.go('mr', ['Monitor.cpp', 'MeshRenderer.cpp'])
- // [{score: -18, target: "MeshRenderer.cpp"}, {score: -6009, target: "Monitor.cpp"}]
+ var preparedSearch = getPreparedSearch(search)
+ if(!isObj(target)) target = getPrepared(target)
- fuzzysort.highlight(fuzzysort.single('fs', 'Fuzzy Search'), '<b>', '</b>')
- // <b>F</b>uzzy <b>S</b>earch
-*/
+ var searchBitflags = preparedSearch.bitflags
+ if((searchBitflags & target._bitflags) !== searchBitflags) return NULL
-// UMD (Universal Module Definition) for fuzzysort
-(function(root, UMD) {
- if(typeof define === 'function' && define.amd) {define([], UMD);}
- else if(typeof module === 'object' && module.exports) {module.exports = UMD();}
- else {root.fuzzysort = UMD();}
-})(this, function UMD() { function fuzzysortNew(instanceOptions) {
-
- var fuzzysort = {
-
- single: function(search, target, options) { if(search=='farzher'){return{target:"farzher was here (^-^*)/",score:0,indexes:[0,1,2,3,4,5,6]};}
- if(!search) {return null;}
- if(!isObj(search)) {search = fuzzysort.getPreparedSearch(search);}
-
- if(!target) {return null;}
- if(!isObj(target)) {target = fuzzysort.getPrepared(target);}
-
- var allowTypo = options && options.allowTypo!==undefined ? options.allowTypo
- : instanceOptions && instanceOptions.allowTypo!==undefined ? instanceOptions.allowTypo
- : true;
- var algorithm = allowTypo ? fuzzysort.algorithm : fuzzysort.algorithmNoTypo;
- return algorithm(search, target, search[0]);
- },
-
- go: function(search, targets, options) { if(search=='farzher'){return[{target:"farzher was here (^-^*)/",score:0,indexes:[0,1,2,3,4,5,6],obj:targets?targets[0]:null}];}
- if(!search) {return noResults;}
- search = fuzzysort.prepareSearch(search);
- var searchLowerCode = search[0];
-
- var threshold = options && options.threshold || instanceOptions && instanceOptions.threshold || -9007199254740991;
- var limit = options && options.limit || instanceOptions && instanceOptions.limit || 9007199254740991;
- var allowTypo = options && options.allowTypo!==undefined ? options.allowTypo
- : instanceOptions && instanceOptions.allowTypo!==undefined ? instanceOptions.allowTypo
- : true;
- var algorithm = allowTypo ? fuzzysort.algorithm : fuzzysort.algorithmNoTypo;
- var resultsLen = 0; var limitedCount = 0;
- var targetsLen = targets.length;
-
- // This code is copy/pasted 3 times for performance reasons [options.keys, options.key, no keys]
-
- // options.keys
- if(options && options.keys) {
- var scoreFn = options.scoreFn || defaultScoreFn;
- var keys = options.keys;
- var keysLen = keys.length;
- for(var i = targetsLen - 1; i >= 0; --i) { var obj = targets[i];
- var objResults = new Array(keysLen);
- for (var keyI = keysLen - 1; keyI >= 0; --keyI) {
- var key = keys[keyI];
- var target = getValue(obj, key);
- if(!target) { objResults[keyI] = null; continue; }
- if(!isObj(target)) {target = fuzzysort.getPrepared(target);}
-
- objResults[keyI] = algorithm(search, target, searchLowerCode);
- }
- objResults.obj = obj; // before scoreFn so scoreFn can use it
- var score = scoreFn(objResults);
- if(score === null) {continue;}
- if(score < threshold) {continue;}
- objResults.score = score;
- if(resultsLen < limit) { q.add(objResults); ++resultsLen; }
- else {
- ++limitedCount;
- if(score > q.peek().score) {q.replaceTop(objResults);}
- }
- }
+ return algorithm(preparedSearch, target)
+ }
- // options.key
- } else if(options && options.key) {
- var key = options.key;
- for(var i = targetsLen - 1; i >= 0; --i) { var obj = targets[i];
- var target = getValue(obj, key);
- if(!target) {continue;}
- if(!isObj(target)) {target = fuzzysort.getPrepared(target);}
-
- var result = algorithm(search, target, searchLowerCode);
- if(result === null) {continue;}
- if(result.score < threshold) {continue;}
-
- // have to clone result so duplicate targets from different obj can each reference the correct obj
- result = {target:result.target, _targetLowerCodes:null, _nextBeginningIndexes:null, score:result.score, indexes:result.indexes, obj:obj}; // hidden
-
- if(resultsLen < limit) { q.add(result); ++resultsLen; }
- else {
- ++limitedCount;
- if(result.score > q.peek().score) {q.replaceTop(result);}
- }
- }
- // no keys
- } else {
- for(var i = targetsLen - 1; i >= 0; --i) { var target = targets[i];
- if(!target) {continue;}
- if(!isObj(target)) {target = fuzzysort.getPrepared(target);}
-
- var result = algorithm(search, target, searchLowerCode);
- if(result === null) {continue;}
- if(result.score < threshold) {continue;}
- if(resultsLen < limit) { q.add(result); ++resultsLen; }
- else {
- ++limitedCount;
- if(result.score > q.peek().score) {q.replaceTop(result);}
- }
+ var go = (search, targets, options) => { if(search=='farzher')return[{target:"farzher was here (^-^*)/",score:0,_indexes:[0],obj:targets?targets[0]:NULL}]
+ if(!search) return options&&options.all ? all(search, targets, options) : noResults
+
+ var preparedSearch = getPreparedSearch(search)
+ var searchBitflags = preparedSearch.bitflags
+ var containsSpace = preparedSearch.containsSpace
+
+ var threshold = options&&options.threshold || INT_MIN
+ var limit = options&&options['limit'] || INT_MAX // for some reason only limit breaks when minified
+
+ var resultsLen = 0; var limitedCount = 0
+ var targetsLen = targets.length
+
+ // This code is copy/pasted 3 times for performance reasons [options.keys, options.key, no keys]
+
+ // options.key
+ if(options && options.key) {
+ var key = options.key
+ for(var i = 0; i < targetsLen; ++i) { var obj = targets[i]
+ var target = getValue(obj, key)
+ if(!target) continue
+ if(!isObj(target)) target = getPrepared(target)
+
+ if((searchBitflags & target._bitflags) !== searchBitflags) continue
+ var result = algorithm(preparedSearch, target)
+ if(result === NULL) continue
+ if(result.score < threshold) continue
+
+ // have to clone result so duplicate targets from different obj can each reference the correct obj
+ result = {target:result.target, _targetLower:'', _targetLowerCodes:NULL, _nextBeginningIndexes:NULL, _bitflags:0, score:result.score, _indexes:result._indexes, obj:obj} // hidden
+
+ if(resultsLen < limit) { q.add(result); ++resultsLen }
+ else {
+ ++limitedCount
+ if(result.score > q.peek().score) q.replaceTop(result)
}
}
- if(resultsLen === 0) {return noResults;}
- var results = new Array(resultsLen);
- for(var i = resultsLen - 1; i >= 0; --i) {results[i] = q.poll();}
- results.total = resultsLen + limitedCount;
- return results;
- },
-
- goAsync: function(search, targets, options) {
- var canceled = false;
- var p = new Promise(function(resolve, reject) { if(search=='farzher'){return resolve([{target:"farzher was here (^-^*)/",score:0,indexes:[0,1,2,3,4,5,6],obj:targets?targets[0]:null}]);}
- if(!search) {return resolve(noResults);}
- search = fuzzysort.prepareSearch(search);
- var searchLowerCode = search[0];
-
- var q = fastpriorityqueue();
- var iCurrent = targets.length - 1;
- var threshold = options && options.threshold || instanceOptions && instanceOptions.threshold || -9007199254740991;
- var limit = options && options.limit || instanceOptions && instanceOptions.limit || 9007199254740991;
- var allowTypo = options && options.allowTypo!==undefined ? options.allowTypo
- : instanceOptions && instanceOptions.allowTypo!==undefined ? instanceOptions.allowTypo
- : true;
- var algorithm = allowTypo ? fuzzysort.algorithm : fuzzysort.algorithmNoTypo;
- var resultsLen = 0; var limitedCount = 0;
- function step() {
- if(canceled) {return reject('canceled');}
-
- var startMs = Date.now();
-
- // This code is copy/pasted 3 times for performance reasons [options.keys, options.key, no keys]
-
- // options.keys
- if(options && options.keys) {
- var scoreFn = options.scoreFn || defaultScoreFn;
- var keys = options.keys;
- var keysLen = keys.length;
- for(; iCurrent >= 0; --iCurrent) {
- if(iCurrent%1000/*itemsPerCheck*/ === 0) {
- if(Date.now() - startMs >= 10/*asyncInterval*/) {
- isNode?setImmediate(step):setTimeout(step);
- return;
- }
- }
-
- var obj = targets[iCurrent];
- var objResults = new Array(keysLen);
- for (var keyI = keysLen - 1; keyI >= 0; --keyI) {
- var key = keys[keyI];
- var target = getValue(obj, key);
- if(!target) { objResults[keyI] = null; continue; }
- if(!isObj(target)) {target = fuzzysort.getPrepared(target);}
-
- objResults[keyI] = algorithm(search, target, searchLowerCode);
- }
- objResults.obj = obj; // before scoreFn so scoreFn can use it
- var score = scoreFn(objResults);
- if(score === null) {continue;}
- if(score < threshold) {continue;}
- objResults.score = score;
- if(resultsLen < limit) { q.add(objResults); ++resultsLen; }
- else {
- ++limitedCount;
- if(score > q.peek().score) {q.replaceTop(objResults);}
- }
- }
-
- // options.key
- } else if(options && options.key) {
- var key = options.key;
- for(; iCurrent >= 0; --iCurrent) {
- if(iCurrent%1000/*itemsPerCheck*/ === 0) {
- if(Date.now() - startMs >= 10/*asyncInterval*/) {
- isNode?setImmediate(step):setTimeout(step);
- return;
- }
- }
-
- var obj = targets[iCurrent];
- var target = getValue(obj, key);
- if(!target) {continue;}
- if(!isObj(target)) {target = fuzzysort.getPrepared(target);}
-
- var result = algorithm(search, target, searchLowerCode);
- if(result === null) {continue;}
- if(result.score < threshold) {continue;}
-
- // have to clone result so duplicate targets from different obj can each reference the correct obj
- result = {target:result.target, _targetLowerCodes:null, _nextBeginningIndexes:null, score:result.score, indexes:result.indexes, obj:obj}; // hidden
-
- if(resultsLen < limit) { q.add(result); ++resultsLen; }
- else {
- ++limitedCount;
- if(result.score > q.peek().score) {q.replaceTop(result);}
- }
- }
-
- // no keys
- } else {
- for(; iCurrent >= 0; --iCurrent) {
- if(iCurrent%1000/*itemsPerCheck*/ === 0) {
- if(Date.now() - startMs >= 10/*asyncInterval*/) {
- isNode?setImmediate(step):setTimeout(step);
- return;
- }
- }
-
- var target = targets[iCurrent];
- if(!target) {continue;}
- if(!isObj(target)) {target = fuzzysort.getPrepared(target);}
-
- var result = algorithm(search, target, searchLowerCode);
- if(result === null) {continue;}
- if(result.score < threshold) {continue;}
- if(resultsLen < limit) { q.add(result); ++resultsLen; }
- else {
- ++limitedCount;
- if(result.score > q.peek().score) {q.replaceTop(result);}
- }
- }
- }
-
- if(resultsLen === 0) {return resolve(noResults);}
- var results = new Array(resultsLen);
- for(var i = resultsLen - 1; i >= 0; --i) {results[i] = q.poll();}
- results.total = resultsLen + limitedCount;
- resolve(results);
+ // options.keys
+ } else if(options && options.keys) {
+ var scoreFn = options['scoreFn'] || defaultScoreFn
+ var keys = options.keys
+ var keysLen = keys.length
+ for(var i = 0; i < targetsLen; ++i) { var obj = targets[i]
+ var objResults = new Array(keysLen)
+ for (var keyI = 0; keyI < keysLen; ++keyI) {
+ var key = keys[keyI]
+ var target = getValue(obj, key)
+ if(!target) { objResults[keyI] = NULL; continue }
+ if(!isObj(target)) target = getPrepared(target)
+
+ if((searchBitflags & target._bitflags) !== searchBitflags) objResults[keyI] = NULL
+ else objResults[keyI] = algorithm(preparedSearch, target)
}
-
- isNode?setImmediate(step):step(); //setTimeout here is too slow
- });
- p.cancel = function() { canceled = true; };
- return p;
- },
-
- highlight: function(result, hOpen, hClose) {
- if(typeof hOpen == 'function') {return fuzzysort.highlightCallback(result, hOpen);}
- if(result === null) {return null;}
- if(hOpen === undefined) {hOpen = '<b>';}
- if(hClose === undefined) {hClose = '</b>';}
- var highlighted = '';
- var matchesIndex = 0;
- var opened = false;
- var target = result.target;
- var targetLen = target.length;
- var matchesBest = result.indexes;
- for(var i = 0; i < targetLen; ++i) { var char = target[i];
- if(matchesBest[matchesIndex] === i) {
- ++matchesIndex;
- if(!opened) { opened = true;
- highlighted += hOpen;
- }
-
- if(matchesIndex === matchesBest.length) {
- highlighted += char + hClose + target.substr(i+1);
- break;
- }
- } else {
- if(opened) { opened = false;
- highlighted += hClose;
- }
+ objResults.obj = obj // before scoreFn so scoreFn can use it
+ var score = scoreFn(objResults)
+ if(score === NULL) continue
+ if(score < threshold) continue
+ objResults.score = score
+ if(resultsLen < limit) { q.add(objResults); ++resultsLen }
+ else {
+ ++limitedCount
+ if(score > q.peek().score) q.replaceTop(objResults)
}
- highlighted += char;
}
- return highlighted;
- },
- highlightCallback: function(result, cb) {
- if(result === null) {return null;}
- var target = result.target;
- var targetLen = target.length;
- var indexes = result.indexes;
- var highlighted = '';
- var matchI = 0;
- var indexesI = 0;
- var opened = false;
- var result = [];
- for(var i = 0; i < targetLen; ++i) { var char = target[i];
- if(indexes[indexesI] === i) {
- ++indexesI;
- if(!opened) { opened = true;
- result.push(highlighted); highlighted = '';
- }
-
- if(indexesI === indexes.length) {
- highlighted += char;
- result.push(cb(highlighted, matchI++)); highlighted = '';
- result.push(target.substr(i+1));
- break;
- }
- } else {
- if(opened) { opened = false;
- result.push(cb(highlighted, matchI++)); highlighted = '';
- }
+ // no keys
+ } else {
+ for(var i = 0; i < targetsLen; ++i) { var target = targets[i]
+ if(!target) continue
+ if(!isObj(target)) target = getPrepared(target)
+
+ if((searchBitflags & target._bitflags) !== searchBitflags) continue
+ var result = algorithm(preparedSearch, target)
+ if(result === NULL) continue
+ if(result.score < threshold) continue
+ if(resultsLen < limit) { q.add(result); ++resultsLen }
+ else {
+ ++limitedCount
+ if(result.score > q.peek().score) q.replaceTop(result)
}
- highlighted += char;
}
- return result;
- },
-
- prepare: function(target) {
- if(!target) {return {target: '', _targetLowerCodes: [0/*this 0 doesn't make sense. here because an empty array causes the algorithm to deoptimize and run 50% slower!*/], _nextBeginningIndexes: null, score: null, indexes: null, obj: null};} // hidden
- return {target:target, _targetLowerCodes:fuzzysort.prepareLowerCodes(target), _nextBeginningIndexes:null, score:null, indexes:null, obj:null}; // hidden
- },
- prepareSlow: function(target) {
- if(!target) {return {target: '', _targetLowerCodes: [0/*this 0 doesn't make sense. here because an empty array causes the algorithm to deoptimize and run 50% slower!*/], _nextBeginningIndexes: null, score: null, indexes: null, obj: null};} // hidden
- return {target:target, _targetLowerCodes:fuzzysort.prepareLowerCodes(target), _nextBeginningIndexes:fuzzysort.prepareNextBeginningIndexes(target), score:null, indexes:null, obj:null}; // hidden
- },
- prepareSearch: function(search) {
- if(!search) {search = '';}
- return fuzzysort.prepareLowerCodes(search);
- },
-
-
-
- // Below this point is only internal code
- // Below this point is only internal code
- // Below this point is only internal code
- // Below this point is only internal code
-
-
-
- getPrepared: function(target) {
- if(target.length > 999) {return fuzzysort.prepare(target);} // don't cache huge targets
- var targetPrepared = preparedCache.get(target);
- if(targetPrepared !== undefined) {return targetPrepared;}
- targetPrepared = fuzzysort.prepare(target);
- preparedCache.set(target, targetPrepared);
- return targetPrepared;
- },
- getPreparedSearch: function(search) {
- if(search.length > 999) {return fuzzysort.prepareSearch(search);} // don't cache huge searches
- var searchPrepared = preparedSearchCache.get(search);
- if(searchPrepared !== undefined) {return searchPrepared;}
- searchPrepared = fuzzysort.prepareSearch(search);
- preparedSearchCache.set(search, searchPrepared);
- return searchPrepared;
- },
-
- algorithm: function(searchLowerCodes, prepared, searchLowerCode) {
- var targetLowerCodes = prepared._targetLowerCodes;
- var searchLen = searchLowerCodes.length;
- var targetLen = targetLowerCodes.length;
- var searchI = 0; // where we at
- var targetI = 0; // where you at
- var typoSimpleI = 0;
- var matchesSimpleLen = 0;
-
- // very basic fuzzy match; to remove non-matching targets ASAP!
- // walk through target. find sequential matches.
- // if all chars aren't found then exit
- for(;;) {
- var isMatch = searchLowerCode === targetLowerCodes[targetI];
- if(isMatch) {
- matchesSimple[matchesSimpleLen++] = targetI;
- ++searchI; if(searchI === searchLen) {break;}
- searchLowerCode = searchLowerCodes[typoSimpleI===0?searchI : (typoSimpleI===searchI?searchI+1 : (typoSimpleI===searchI-1?searchI-1 : searchI))];
+ }
+
+ if(resultsLen === 0) return noResults
+ var results = new Array(resultsLen)
+ for(var i = resultsLen - 1; i >= 0; --i) results[i] = q.poll()
+ results.total = resultsLen + limitedCount
+ return results
+ }
+
+
+ var highlight = (result, hOpen, hClose) => {
+ if(typeof hOpen === 'function') return highlightCallback(result, hOpen)
+ if(result === NULL) return NULL
+ if(hOpen === undefined) hOpen = '<b>'
+ if(hClose === undefined) hClose = '</b>'
+ var highlighted = ''
+ var matchesIndex = 0
+ var opened = false
+ var target = result.target
+ var targetLen = target.length
+ var indexes = result._indexes
+ indexes = indexes.slice(0, indexes.len).sort((a,b)=>a-b)
+ for(var i = 0; i < targetLen; ++i) { var char = target[i]
+ if(indexes[matchesIndex] === i) {
+ ++matchesIndex
+ if(!opened) { opened = true
+ highlighted += hOpen
}
- ++targetI; if(targetI >= targetLen) { // Failed to find searchI
- // Check for typo or exit
- // we go as far as possible before trying to transpose
- // then we transpose backwards until we reach the beginning
- for(;;) {
- if(searchI <= 1) {return null;} // not allowed to transpose first char
- if(typoSimpleI === 0) { // we haven't tried to transpose yet
- --searchI;
- var searchLowerCodeNew = searchLowerCodes[searchI];
- if(searchLowerCode === searchLowerCodeNew) {continue;} // doesn't make sense to transpose a repeat char
- typoSimpleI = searchI;
- } else {
- if(typoSimpleI === 1) {return null;} // reached the end of the line for transposing
- --typoSimpleI;
- searchI = typoSimpleI;
- searchLowerCode = searchLowerCodes[searchI + 1];
- var searchLowerCodeNew = searchLowerCodes[searchI];
- if(searchLowerCode === searchLowerCodeNew) {continue;} // doesn't make sense to transpose a repeat char
- }
- matchesSimpleLen = searchI;
- targetI = matchesSimple[matchesSimpleLen - 1] + 1;
- break;
- }
+ if(matchesIndex === indexes.length) {
+ highlighted += char + hClose + target.substr(i+1)
+ break
+ }
+ } else {
+ if(opened) { opened = false
+ highlighted += hClose
}
}
+ highlighted += char
+ }
- var searchI = 0;
- var typoStrictI = 0;
- var successStrict = false;
- var matchesStrictLen = 0;
-
- var nextBeginningIndexes = prepared._nextBeginningIndexes;
- if(nextBeginningIndexes === null) {nextBeginningIndexes = prepared._nextBeginningIndexes = fuzzysort.prepareNextBeginningIndexes(prepared.target);}
- var firstPossibleI = targetI = matchesSimple[0]===0 ? 0 : nextBeginningIndexes[matchesSimple[0]-1];
-
- // Our target string successfully matched all characters in sequence!
- // Let's try a more advanced and strict test to improve the score
- // only count it as a match if it's consecutive or a beginning character!
- if(targetI !== targetLen) {for(;;) {
- if(targetI >= targetLen) {
- // We failed to find a good spot for this search char, go back to the previous search char and force it forward
- if(searchI <= 0) { // We failed to push chars forward for a better match
- // transpose, starting from the beginning
- ++typoStrictI; if(typoStrictI > searchLen-2) {break;}
- if(searchLowerCodes[typoStrictI] === searchLowerCodes[typoStrictI+1]) {continue;} // doesn't make sense to transpose a repeat char
- targetI = firstPossibleI;
- continue;
- }
-
- --searchI;
- var lastMatch = matchesStrict[--matchesStrictLen];
- targetI = nextBeginningIndexes[lastMatch];
-
- } else {
- var isMatch = searchLowerCodes[typoStrictI===0?searchI : (typoStrictI===searchI?searchI+1 : (typoStrictI===searchI-1?searchI-1 : searchI))] === targetLowerCodes[targetI];
- if(isMatch) {
- matchesStrict[matchesStrictLen++] = targetI;
- ++searchI; if(searchI === searchLen) { successStrict = true; break; }
- ++targetI;
- } else {
- targetI = nextBeginningIndexes[targetI];
- }
+ return highlighted
+ }
+ var highlightCallback = (result, cb) => {
+ if(result === NULL) return NULL
+ var target = result.target
+ var targetLen = target.length
+ var indexes = result._indexes
+ indexes = indexes.slice(0, indexes.len).sort((a,b)=>a-b)
+ var highlighted = ''
+ var matchI = 0
+ var indexesI = 0
+ var opened = false
+ var result = []
+ for(var i = 0; i < targetLen; ++i) { var char = target[i]
+ if(indexes[indexesI] === i) {
+ ++indexesI
+ if(!opened) { opened = true
+ result.push(highlighted); highlighted = ''
}
- }}
-
- { // tally up the score & keep track of matches for highlighting later
- if(successStrict) { var matchesBest = matchesStrict; var matchesBestLen = matchesStrictLen; }
- else { var matchesBest = matchesSimple; var matchesBestLen = matchesSimpleLen; }
- var score = 0;
- var lastTargetI = -1;
- for(var i = 0; i < searchLen; ++i) { var targetI = matchesBest[i];
- // score only goes down if they're not consecutive
- if(lastTargetI !== targetI - 1) {score -= targetI;}
- lastTargetI = targetI;
+
+ if(indexesI === indexes.length) {
+ highlighted += char
+ result.push(cb(highlighted, matchI++)); highlighted = ''
+ result.push(target.substr(i+1))
+ break
}
- if(!successStrict) {
- score *= 1000;
- if(typoSimpleI !== 0) {score += -20;}/*typoPenalty*/
- } else {
- if(typoStrictI !== 0) {score += -20;}/*typoPenalty*/
+ } else {
+ if(opened) { opened = false
+ result.push(cb(highlighted, matchI++)); highlighted = ''
}
- score -= targetLen - searchLen;
- prepared.score = score;
- prepared.indexes = new Array(matchesBestLen); for(var i = matchesBestLen - 1; i >= 0; --i) {prepared.indexes[i] = matchesBest[i];}
+ }
+ highlighted += char
+ }
+ return result
+ }
+
+
+ var indexes = result => result._indexes.slice(0, result._indexes.len).sort((a,b)=>a-b)
+
- return prepared;
+ var prepare = (target) => {
+ if(typeof target !== 'string') target = ''
+ var info = prepareLowerInfo(target)
+ return {'target':target, _targetLower:info._lower, _targetLowerCodes:info.lowerCodes, _nextBeginningIndexes:NULL, _bitflags:info.bitflags, 'score':NULL, _indexes:[0], 'obj':NULL} // hidden
+ }
+
+
+ // Below this point is only internal code
+ // Below this point is only internal code
+ // Below this point is only internal code
+ // Below this point is only internal code
+
+
+ var prepareSearch = (search) => {
+ if(typeof search !== 'string') search = ''
+ search = search.trim()
+ var info = prepareLowerInfo(search)
+
+ var spaceSearches = []
+ if(info.containsSpace) {
+ var searches = search.split(/\s+/)
+ searches = [...new Set(searches)] // distinct
+ for(var i=0; i<searches.length; i++) {
+ if(searches[i] === '') continue
+ var _info = prepareLowerInfo(searches[i])
+ spaceSearches.push({lowerCodes:_info.lowerCodes, _lower:searches[i].toLowerCase(), containsSpace:false})
}
- },
-
- algorithmNoTypo: function(searchLowerCodes, prepared, searchLowerCode) {
- var targetLowerCodes = prepared._targetLowerCodes;
- var searchLen = searchLowerCodes.length;
- var targetLen = targetLowerCodes.length;
- var searchI = 0; // where we at
- var targetI = 0; // where you at
- var matchesSimpleLen = 0;
-
- // very basic fuzzy match; to remove non-matching targets ASAP!
- // walk through target. find sequential matches.
- // if all chars aren't found then exit
- for(;;) {
- var isMatch = searchLowerCode === targetLowerCodes[targetI];
- if(isMatch) {
- matchesSimple[matchesSimpleLen++] = targetI;
- ++searchI; if(searchI === searchLen) {break;}
- searchLowerCode = searchLowerCodes[searchI];
+ }
+
+ return {lowerCodes: info.lowerCodes, bitflags: info.bitflags, containsSpace: info.containsSpace, _lower: info._lower, spaceSearches: spaceSearches}
+ }
+
+
+
+ var getPrepared = (target) => {
+ if(target.length > 999) return prepare(target) // don't cache huge targets
+ var targetPrepared = preparedCache.get(target)
+ if(targetPrepared !== undefined) return targetPrepared
+ targetPrepared = prepare(target)
+ preparedCache.set(target, targetPrepared)
+ return targetPrepared
+ }
+ var getPreparedSearch = (search) => {
+ if(search.length > 999) return prepareSearch(search) // don't cache huge searches
+ var searchPrepared = preparedSearchCache.get(search)
+ if(searchPrepared !== undefined) return searchPrepared
+ searchPrepared = prepareSearch(search)
+ preparedSearchCache.set(search, searchPrepared)
+ return searchPrepared
+ }
+
+
+ var all = (search, targets, options) => {
+ var results = []; results.total = targets.length
+
+ var limit = options && options.limit || INT_MAX
+
+ if(options && options.key) {
+ for(var i=0;i<targets.length;i++) { var obj = targets[i]
+ var target = getValue(obj, options.key)
+ if(!target) continue
+ if(!isObj(target)) target = getPrepared(target)
+ target.score = INT_MIN
+ target._indexes.len = 0
+ var result = target
+ result = {target:result.target, _targetLower:'', _targetLowerCodes:NULL, _nextBeginningIndexes:NULL, _bitflags:0, score:target.score, _indexes:NULL, obj:obj} // hidden
+ results.push(result); if(results.length >= limit) return results
+ }
+ } else if(options && options.keys) {
+ for(var i=0;i<targets.length;i++) { var obj = targets[i]
+ var objResults = new Array(options.keys.length)
+ for (var keyI = options.keys.length - 1; keyI >= 0; --keyI) {
+ var target = getValue(obj, options.keys[keyI])
+ if(!target) { objResults[keyI] = NULL; continue }
+ if(!isObj(target)) target = getPrepared(target)
+ target.score = INT_MIN
+ target._indexes.len = 0
+ objResults[keyI] = target
}
- ++targetI; if(targetI >= targetLen) {return null;} // Failed to find searchI
+ objResults.obj = obj
+ objResults.score = INT_MIN
+ results.push(objResults); if(results.length >= limit) return results
+ }
+ } else {
+ for(var i=0;i<targets.length;i++) { var target = targets[i]
+ if(!target) continue
+ if(!isObj(target)) target = getPrepared(target)
+ target.score = INT_MIN
+ target._indexes.len = 0
+ results.push(target); if(results.length >= limit) return results
}
+ }
- var searchI = 0;
- var successStrict = false;
- var matchesStrictLen = 0;
+ return results
+ }
- var nextBeginningIndexes = prepared._nextBeginningIndexes;
- if(nextBeginningIndexes === null) {nextBeginningIndexes = prepared._nextBeginningIndexes = fuzzysort.prepareNextBeginningIndexes(prepared.target);}
- var firstPossibleI = targetI = matchesSimple[0]===0 ? 0 : nextBeginningIndexes[matchesSimple[0]-1];
- // Our target string successfully matched all characters in sequence!
- // Let's try a more advanced and strict test to improve the score
- // only count it as a match if it's consecutive or a beginning character!
- if(targetI !== targetLen) {for(;;) {
- if(targetI >= targetLen) {
- // We failed to find a good spot for this search char, go back to the previous search char and force it forward
- if(searchI <= 0) {break;} // We failed to push chars forward for a better match
+ var algorithm = (preparedSearch, prepared, allowSpaces=false) => {
+ if(allowSpaces===false && preparedSearch.containsSpace) return algorithmSpaces(preparedSearch, prepared)
+
+ var searchLower = preparedSearch._lower
+ var searchLowerCodes = preparedSearch.lowerCodes
+ var searchLowerCode = searchLowerCodes[0]
+ var targetLowerCodes = prepared._targetLowerCodes
+ var searchLen = searchLowerCodes.length
+ var targetLen = targetLowerCodes.length
+ var searchI = 0 // where we at
+ var targetI = 0 // where you at
+ var matchesSimpleLen = 0
+
+ // very basic fuzzy match; to remove non-matching targets ASAP!
+ // walk through target. find sequential matches.
+ // if all chars aren't found then exit
+ for(;;) {
+ var isMatch = searchLowerCode === targetLowerCodes[targetI]
+ if(isMatch) {
+ matchesSimple[matchesSimpleLen++] = targetI
+ ++searchI; if(searchI === searchLen) break
+ searchLowerCode = searchLowerCodes[searchI]
+ }
+ ++targetI; if(targetI >= targetLen) return NULL // Failed to find searchI
+ }
+
+ var searchI = 0
+ var successStrict = false
+ var matchesStrictLen = 0
+
+ var nextBeginningIndexes = prepared._nextBeginningIndexes
+ if(nextBeginningIndexes === NULL) nextBeginningIndexes = prepared._nextBeginningIndexes = prepareNextBeginningIndexes(prepared.target)
+ var firstPossibleI = targetI = matchesSimple[0]===0 ? 0 : nextBeginningIndexes[matchesSimple[0]-1]
+
+ // Our target string successfully matched all characters in sequence!
+ // Let's try a more advanced and strict test to improve the score
+ // only count it as a match if it's consecutive or a beginning character!
+ var backtrackCount = 0
+ if(targetI !== targetLen) for(;;) {
+ if(targetI >= targetLen) {
+ // We failed to find a good spot for this search char, go back to the previous search char and force it forward
+ if(searchI <= 0) break // We failed to push chars forward for a better match
- --searchI;
- var lastMatch = matchesStrict[--matchesStrictLen];
- targetI = nextBeginningIndexes[lastMatch];
+ ++backtrackCount; if(backtrackCount > 200) break // exponential backtracking is taking too long, just give up and return a bad match
+ --searchI
+ var lastMatch = matchesStrict[--matchesStrictLen]
+ targetI = nextBeginningIndexes[lastMatch]
+
+ } else {
+ var isMatch = searchLowerCodes[searchI] === targetLowerCodes[targetI]
+ if(isMatch) {
+ matchesStrict[matchesStrictLen++] = targetI
+ ++searchI; if(searchI === searchLen) { successStrict = true; break }
+ ++targetI
} else {
- var isMatch = searchLowerCodes[searchI] === targetLowerCodes[targetI];
- if(isMatch) {
- matchesStrict[matchesStrictLen++] = targetI;
- ++searchI; if(searchI === searchLen) { successStrict = true; break; }
- ++targetI;
- } else {
- targetI = nextBeginningIndexes[targetI];
- }
+ targetI = nextBeginningIndexes[targetI]
}
- }}
-
- { // tally up the score & keep track of matches for highlighting later
- if(successStrict) { var matchesBest = matchesStrict; var matchesBestLen = matchesStrictLen; }
- else { var matchesBest = matchesSimple; var matchesBestLen = matchesSimpleLen; }
- var score = 0;
- var lastTargetI = -1;
- for(var i = 0; i < searchLen; ++i) { var targetI = matchesBest[i];
- // score only goes down if they're not consecutive
- if(lastTargetI !== targetI - 1) {score -= targetI;}
- lastTargetI = targetI;
- }
- if(!successStrict) {score *= 1000;}
- score -= targetLen - searchLen;
- prepared.score = score;
- prepared.indexes = new Array(matchesBestLen); for(var i = matchesBestLen - 1; i >= 0; --i) {prepared.indexes[i] = matchesBest[i];}
+ }
+ }
+
+ // check if it's a substring match
+ var substringIndex = prepared._targetLower.indexOf(searchLower, matchesSimple[0]) // perf: this is slow
+ var isSubstring = ~substringIndex
+ if(isSubstring && !successStrict) { // rewrite the indexes from basic to the substring
+ for(var i=0; i<matchesSimpleLen; ++i) matchesSimple[i] = substringIndex+i
+ }
+ var isSubstringBeginning = false
+ if(isSubstring) {
+ isSubstringBeginning = prepared._nextBeginningIndexes[substringIndex-1] === substringIndex
+ }
+
+ { // tally up the score & keep track of matches for highlighting later
+ if(successStrict) { var matchesBest = matchesStrict; var matchesBestLen = matchesStrictLen }
+ else { var matchesBest = matchesSimple; var matchesBestLen = matchesSimpleLen }
+
+ var score = 0
+
+ var extraMatchGroupCount = 0
+ for(var i = 1; i < searchLen; ++i) {
+ if(matchesBest[i] - matchesBest[i-1] !== 1) {score -= matchesBest[i]; ++extraMatchGroupCount}
+ }
+ var unmatchedDistance = matchesBest[searchLen-1] - matchesBest[0] - (searchLen-1)
+
+ score -= (12+unmatchedDistance) * extraMatchGroupCount // penality for more groups
+
+ if(matchesBest[0] !== 0) score -= matchesBest[0]*matchesBest[0]*.2 // penality for not starting near the beginning
+
+ if(!successStrict) {
+ score *= 1000
+ } else {
+ // successStrict on a target with too many beginning indexes loses points for being a bad target
+ var uniqueBeginningIndexes = 1
+ for(var i = nextBeginningIndexes[0]; i < targetLen; i=nextBeginningIndexes[i]) ++uniqueBeginningIndexes
- return prepared;
+ if(uniqueBeginningIndexes > 24) score *= (uniqueBeginningIndexes-24)*10 // quite arbitrary numbers here ...
}
- },
-
- prepareLowerCodes: function(str) {
- var strLen = str.length;
- var lowerCodes = []; // new Array(strLen) sparse array is too slow
- var lower = str.toLowerCase();
- for(var i = 0; i < strLen; ++i) {lowerCodes[i] = lower.charCodeAt(i);}
- return lowerCodes;
- },
- prepareBeginningIndexes: function(target) {
- var targetLen = target.length;
- var beginningIndexes = []; var beginningIndexesLen = 0;
- var wasUpper = false;
- var wasAlphanum = false;
- for(var i = 0; i < targetLen; ++i) {
- var targetCode = target.charCodeAt(i);
- var isUpper = targetCode>=65&&targetCode<=90;
- var isAlphanum = isUpper || targetCode>=97&&targetCode<=122 || targetCode>=48&&targetCode<=57;
- var isBeginning = isUpper && !wasUpper || !wasAlphanum || !isAlphanum;
- wasUpper = isUpper;
- wasAlphanum = isAlphanum;
- if(isBeginning) {beginningIndexes[beginningIndexesLen++] = i;}
+
+ if(isSubstring) score /= 1+searchLen*searchLen*1 // bonus for being a full substring
+ if(isSubstringBeginning) score /= 1+searchLen*searchLen*1 // bonus for substring starting on a beginningIndex
+
+ score -= targetLen - searchLen // penality for longer targets
+ prepared.score = score
+
+ for(var i = 0; i < matchesBestLen; ++i) prepared._indexes[i] = matchesBest[i]
+ prepared._indexes.len = matchesBestLen
+
+ return prepared
+ }
+ }
+ var algorithmSpaces = (preparedSearch, target) => {
+ var seen_indexes = new Set()
+ var score = 0
+ var result = NULL
+
+ var first_seen_index_last_search = 0
+ var searches = preparedSearch.spaceSearches
+ for(var i=0; i<searches.length; ++i) {
+ var search = searches[i]
+
+ result = algorithm(search, target)
+ if(result === NULL) return NULL
+
+ score += result.score
+
+ // dock points based on order otherwise "c man" returns Manifest.cpp instead of CheatManager.h
+ if(result._indexes[0] < first_seen_index_last_search) {
+ score -= first_seen_index_last_search - result._indexes[0]
}
- return beginningIndexes;
- },
- prepareNextBeginningIndexes: function(target) {
- var targetLen = target.length;
- var beginningIndexes = fuzzysort.prepareBeginningIndexes(target);
- var nextBeginningIndexes = []; // new Array(targetLen) sparse array is too slow
- var lastIsBeginning = beginningIndexes[0];
- var lastIsBeginningI = 0;
- for(var i = 0; i < targetLen; ++i) {
- if(lastIsBeginning > i) {
- nextBeginningIndexes[i] = lastIsBeginning;
- } else {
- lastIsBeginning = beginningIndexes[++lastIsBeginningI];
- nextBeginningIndexes[i] = lastIsBeginning===undefined ? targetLen : lastIsBeginning;
- }
+ first_seen_index_last_search = result._indexes[0]
+
+ for(var j=0; j<result._indexes.len; ++j) seen_indexes.add(result._indexes[j])
+ }
+
+ // allows a search with spaces that's an exact substring to score well
+ var allowSpacesResult = algorithm(preparedSearch, target, /*allowSpaces=*/true)
+ if(allowSpacesResult !== NULL && allowSpacesResult.score > score) {
+ return allowSpacesResult
+ }
+
+ result.score = score
+
+ var i = 0
+ for (let index of seen_indexes) result._indexes[i++] = index
+ result._indexes.len = i
+
+ return result
+ }
+
+
+ var prepareLowerInfo = (str) => {
+ var strLen = str.length
+ var lower = str.toLowerCase()
+ var lowerCodes = [] // new Array(strLen) sparse array is too slow
+ var bitflags = 0
+ var containsSpace = false // space isn't stored in bitflags because of how searching with a space works
+
+ for(var i = 0; i < strLen; ++i) {
+ var lowerCode = lowerCodes[i] = lower.charCodeAt(i)
+
+ if(lowerCode === 32) {
+ containsSpace = true
+ continue // it's important that we don't set any bitflags for space
}
- return nextBeginningIndexes;
- },
-
- cleanup: cleanup,
- new: fuzzysortNew,
- };
- return fuzzysort;
-} // fuzzysortNew
-
-// This stuff is outside fuzzysortNew, because it's shared with instances of fuzzysort.new()
-var isNode = typeof require !== 'undefined' && typeof window === 'undefined';
-var MyMap = typeof Map === 'function' ? Map : function(){var s=Object.create(null);this.get=function(k){return s[k];};this.set=function(k,val){s[k]=val;return this;};this.clear=function(){s=Object.create(null);};};
-var preparedCache = new MyMap();
-var preparedSearchCache = new MyMap();
-var noResults = []; noResults.total = 0;
-var matchesSimple = []; var matchesStrict = [];
-function cleanup() { preparedCache.clear(); preparedSearchCache.clear(); matchesSimple = []; matchesStrict = []; }
-function defaultScoreFn(a) {
- var max = -9007199254740991;
- for (var i = a.length - 1; i >= 0; --i) {
- var result = a[i]; if(result === null) {continue;}
- var score = result.score;
- if(score > max) {max = score;}
+
+ var bit = lowerCode>=97&&lowerCode<=122 ? lowerCode-97 // alphabet
+ : lowerCode>=48&&lowerCode<=57 ? 26 // numbers
+ // 3 bits available
+ : lowerCode<=127 ? 30 // other ascii
+ : 31 // other utf8
+ bitflags |= 1<<bit
+ }
+
+ return {lowerCodes:lowerCodes, bitflags:bitflags, containsSpace:containsSpace, _lower:lower}
}
- if(max === -9007199254740991) {return null;}
- return max;
-}
-
-// prop = 'key' 2.5ms optimized for this case, seems to be about as fast as direct obj[prop]
-// prop = 'key1.key2' 10ms
-// prop = ['key1', 'key2'] 27ms
-function getValue(obj, prop) {
- var tmp = obj[prop]; if(tmp !== undefined) {return tmp;}
- var segs = prop;
- if(!Array.isArray(prop)) {segs = prop.split('.');}
- var len = segs.length;
- var i = -1;
- while (obj && (++i < len)) {obj = obj[segs[i]];}
- return obj;
-}
-
-function isObj(x) { return typeof x === 'object'; } // faster as a function
-
-// Hacked version of https://github.com/lemire/FastPriorityQueue.js
-var fastpriorityqueue=function(){var r=[],o=0,e={};function n(){for(var e=0,n=r[e],c=1;c<o;){var f=c+1;e=c,f<o&&r[f].score<r[c].score&&(e=f),r[e-1>>1]=r[e],c=1+(e<<1);}for(var a=e-1>>1;e>0&&n.score<r[a].score;a=(e=a)-1>>1){r[e]=r[a];}r[e]=n;}return e.add=function(e){var n=o;r[o++]=e;for(var c=n-1>>1;n>0&&e.score<r[c].score;c=(n=c)-1>>1){r[n]=r[c];}r[n]=e;},e.poll=function(){if(0!==o){var e=r[0];return r[0]=r[--o],n(),e;}},e.peek=function(e){if(0!==o){return r[0];}},e.replaceTop=function(o){r[0]=o,n();},e;};
-var q = fastpriorityqueue(); // reuse this, except for async, it needs to make its own
-
-return fuzzysortNew();
-}); // UMD
-
-// TODO: (performance) wasm version!?
-// TODO: (performance) threads?
-// TODO: (performance) avoid cache misses
-// TODO: (performance) preparedCache is a memory leak
+ var prepareBeginningIndexes = (target) => {
+ var targetLen = target.length
+ var beginningIndexes = []; var beginningIndexesLen = 0
+ var wasUpper = false
+ var wasAlphanum = false
+ for(var i = 0; i < targetLen; ++i) {
+ var targetCode = target.charCodeAt(i)
+ var isUpper = targetCode>=65&&targetCode<=90
+ var isAlphanum = isUpper || targetCode>=97&&targetCode<=122 || targetCode>=48&&targetCode<=57
+ var isBeginning = isUpper && !wasUpper || !wasAlphanum || !isAlphanum
+ wasUpper = isUpper
+ wasAlphanum = isAlphanum
+ if(isBeginning) beginningIndexes[beginningIndexesLen++] = i
+ }
+ return beginningIndexes
+ }
+ var prepareNextBeginningIndexes = (target) => {
+ var targetLen = target.length
+ var beginningIndexes = prepareBeginningIndexes(target)
+ var nextBeginningIndexes = [] // new Array(targetLen) sparse array is too slow
+ var lastIsBeginning = beginningIndexes[0]
+ var lastIsBeginningI = 0
+ for(var i = 0; i < targetLen; ++i) {
+ if(lastIsBeginning > i) {
+ nextBeginningIndexes[i] = lastIsBeginning
+ } else {
+ lastIsBeginning = beginningIndexes[++lastIsBeginningI]
+ nextBeginningIndexes[i] = lastIsBeginning===undefined ? targetLen : lastIsBeginning
+ }
+ }
+ return nextBeginningIndexes
+ }
+
+
+ var cleanup = () => { preparedCache.clear(); preparedSearchCache.clear(); matchesSimple = []; matchesStrict = [] }
+
+ var preparedCache = new Map()
+ var preparedSearchCache = new Map()
+ var matchesSimple = []; var matchesStrict = []
+
+
+ // for use with keys. just returns the maximum score
+ var defaultScoreFn = (a) => {
+ var max = INT_MIN
+ var len = a.length
+ for (var i = 0; i < len; ++i) {
+ var result = a[i]; if(result === NULL) continue
+ var score = result.score
+ if(score > max) max = score
+ }
+ if(max === INT_MIN) return NULL
+ return max
+ }
+
+ // prop = 'key' 2.5ms optimized for this case, seems to be about as fast as direct obj[prop]
+ // prop = 'key1.key2' 10ms
+ // prop = ['key1', 'key2'] 27ms
+ var getValue = (obj, prop) => {
+ var tmp = obj[prop]; if(tmp !== undefined) return tmp
+ var segs = prop
+ if(!Array.isArray(prop)) segs = prop.split('.')
+ var len = segs.length
+ var i = -1
+ while (obj && (++i < len)) obj = obj[segs[i]]
+ return obj
+ }
+
+ var isObj = (x) => { return typeof x === 'object' } // faster as a function
+ // var INT_MAX = 9007199254740991; var INT_MIN = -INT_MAX
+ var INT_MAX = Infinity; var INT_MIN = -INT_MAX
+ var noResults = []; noResults.total = 0
+ var NULL = null
+
+
+ // Hacked version of https://github.com/lemire/FastPriorityQueue.js
+ var fastpriorityqueue=r=>{var e=[],o=0,a={},v=r=>{for(var a=0,v=e[a],c=1;c<o;){var s=c+1;a=c,s<o&&e[s].score<e[c].score&&(a=s),e[a-1>>1]=e[a],c=1+(a<<1)}for(var f=a-1>>1;a>0&&v.score<e[f].score;f=(a=f)-1>>1)e[a]=e[f];e[a]=v};return a.add=(r=>{var a=o;e[o++]=r;for(var v=a-1>>1;a>0&&r.score<e[v].score;v=(a=v)-1>>1)e[a]=e[v];e[a]=r}),a.poll=(r=>{if(0!==o){var a=e[0];return e[0]=e[--o],v(),a}}),a.peek=(r=>{if(0!==o)return e[0]}),a.replaceTop=(r=>{e[0]=r,v()}),a}
+ var q = fastpriorityqueue() // reuse this
+
+
+ // fuzzysort is written this way for minification. all names are mangeled unless quoted
+ return {'single':single, 'go':go, 'highlight':highlight, 'prepare':prepare, 'indexes':indexes, 'cleanup':cleanup}
+}) // UMD
+
+// TODO: (feature) frecency
+// TODO: (perf) use different sorting algo depending on the # of results?
+// TODO: (perf) preparedCache is a memory leak
// TODO: (like sublime) backslash === forwardslash
-// TODO: (like sublime) spaces: "a b" should do 2 searches 1 for a and 1 for b
-// TODO: (scoring) garbage in targets that allows most searches to strict match need a penality
-// TODO: (performance) idk if allowTypo is optimized
+// TODO: (perf) prepareSearch seems slow
diff --git a/static/js/hoverfix.ts b/static/js/hoverfix.ts
new file mode 100644
index 0000000..b6d1a5b
--- /dev/null
+++ b/static/js/hoverfix.ts
@@ -0,0 +1,64 @@
+(function () {
+ /*/
+ * Element.closest() polyfill
+ * https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
+ * https://github.com/idmadj/element-closest-polyfill#readme
+ * Copyright (C) Abdelmadjid Hammou
+ * Licence: ISC | https://www.isc.org/licenses/
+ /*/
+
+ if (typeof Element !== "undefined") {
+ if (!Element.prototype.matches) {
+ Element.prototype.matches = Element.prototype.msMatchesSelector ||
+ Element.prototype.webkitMatchesSelector;
+ }
+ if (!Element.prototype.closest) {
+ Element.prototype.closest = function (s) {
+ var el = this;
+ do {
+ if (el.matches(s)) return el;
+ el = el.parentElement || el.parentNode;
+ } while (el !== null && el.nodeType === 1);
+ return null;
+ };
+ }
+ }
+
+ /*/
+ * -----------------------------------------------------------------
+ /*/
+
+ const disabled = "0s";
+
+ function walk(children, callback) {
+ for (let i = 0; i < children.length; i++) {
+ callback(children[i]);
+ walk(children[i].children, callback);
+ }
+ }
+
+ self.addEventListener("mousemove", function (event) {
+ if (typeof event.target.closest !== "function") return;
+ tree = event.target.closest("figure") || event.target.closest("article");
+
+ if (tree !== null) {
+ walk(tree.children, function (element) {
+ const delay = self.getComputedStyle(element).getPropertyValue(
+ "transition-delay",
+ );
+ if (delay !== disabled) {
+ element.style.setProperty("visibility", "hidden");
+ }
+ });
+
+ walk(tree.children, function (element) {
+ const delay = self.getComputedStyle(element).getPropertyValue(
+ "transition-delay",
+ );
+ if (delay !== disabled) {
+ element.style.removeProperty("visibility");
+ }
+ });
+ }
+ });
+})();
diff --git a/static/js/bundle.ts b/static/js/index-bundle.ts
index ac858c4..61dc414 100644
--- a/static/js/bundle.ts
+++ b/static/js/index-bundle.ts
@@ -1,4 +1,4 @@
-import { bundle } from "https://deno.land/x/emit@0.17.0/mod.ts";
+import { bundle } from "https://deno.land/x/emit@0.26.0/mod.ts";
function removeSourceMap(text): string {
return text.replace(/^\/\/# sourceMappingURL.*$/gm, "").trim();
@@ -14,8 +14,5 @@ const fileSize = ((await Deno.stat(file)).size / 1024).toFixed(2) + "kB";
await Deno.writeTextFile(file, output, {});
-console.log(
- `Bundle file:///${file}` +
- "\n" +
- `Emit file:///${file} (${fileSize})`,
-);
+console.log("INFO:", `Bundle file:///${file}`);
+console.log("INFO:", `Emit file:///${file} (${fileSize})`);
diff --git a/static/js/index.ts b/static/js/index.ts
index e00907b..517445c 100644
--- a/static/js/index.ts
+++ b/static/js/index.ts
@@ -1,8 +1,13 @@
import "./pager.ts";
+import "./update.ts";
import "./plumber.ts";
import "./instantpage.ts";
import "./contextmenu.ts";
import "./fixedsearch.ts";
+import "./autoplay.ts";
+import "./hoverfix.ts";
+import "./forms.ts";
+import "./domfilter.ts";
import "./timeago.ts";
-console.log("Surface Control: Complete");
+console.log("INFO: Surface Control Complete");
diff --git a/static/js/infinitescroll.ts b/static/js/infinitescroll.ts
new file mode 100644
index 0000000..bef477b
--- /dev/null
+++ b/static/js/infinitescroll.ts
@@ -0,0 +1,78 @@
+(function () {
+ const cookiesDisabled = !navigator.cookieEnabled;
+
+ if (cookiesDisabled) {
+ document.cookie = "disabled";
+ document.cookie.indexOf("disabled");
+ return console.warn("WARNING: Native pagination fallback due to cookie restrictions");
+ }
+
+ type percent = number;
+
+ function fetch(url, method, callback, fallback) {
+ const http = new XMLHttpRequest();
+ http.onreadystatechange = function () {
+ if (callback && http.readyState === 4) {
+ if (http.status === 200) callback(http);
+ else fallback(http);
+ }
+ };
+ http.open(method, url);
+ http.send();
+ return http;
+ }
+
+ let abort = false;
+
+ const key = "config.scroll.infinite";
+
+ if (!localStorage[key]) localStorage[key] = "";
+
+ ["scroll", "DOMContentLoaded"].forEach(function (event) {
+ self.addEventListener(event, function () {
+ if (abort) return;
+
+ const remaining = Math.abs(
+ document.documentElement.scrollHeight
+ - document.documentElement.clientHeight
+ - self.pageYOffset
+ );
+
+ const traversed = self.pageYOffset;
+ const journey = remaining + traversed;
+ const ratio: percent = traversed / journey * 100;
+ const threshold = ratio >= 50;
+ const pagination = document.querySelector('[data-type="pagination"]');
+
+ if (!pagination) return;
+
+ const main = document.querySelector("main");
+ const count = main.childNodes.length;
+ const next = pagination.querySelector('[rel="next"]');
+ const end = pagination.querySelector('[rel="last"]').title === "hidden";
+ const asynchronous = document.querySelectorAll("[data-type='pagination']").length !== 1;
+
+ if (end || asynchronous) return pagination.remove();
+
+ if (threshold && (pagination.remove() === undefined)) {
+ fetch(next.href, "GET", function (http) {
+ const page = (new DOMParser()).parseFromString(http.responseText, "text/html");
+ const items = page.querySelector("main").childNodes;
+ const paginate = page.querySelector('[data-type="pagination"]');
+
+ for (let i = 0; i < items.length; i++) main.appendChild(items[i]);
+
+ main.after(paginate);
+
+ console.log("INFO: Fetch", next.href, items);
+
+ }, function (http) {
+ console.warn("WARNING: Switching to native pagination", http);
+ main.insertAdjacentElement("afterend", pagination);
+ abort = true;
+ });
+ }
+ console.log("INFO:", "r:", remaining, "t:", traversed, "j:", journey, "%:", ratio, "c:", count);
+ });
+ });
+})();
diff --git a/static/js/instantpage.ts b/static/js/instantpage.ts
index 7c78a6f..1b5ed36 100644
--- a/static/js/instantpage.ts
+++ b/static/js/instantpage.ts
@@ -1,292 +1,82 @@
-(function () {
- self.addEventListener("DOMContentLoaded", function () {
- /*! instant.page v5.1.0 - (C) 2019-2020 Alexandre Dieulot - https://instant.page/license */
-
- let mouseoverTimer;
- let lastTouchTimestamp;
- const prefetches = new Set();
- const prefetchElement = document.createElement("link");
- const isSupported = prefetchElement.relList &&
- prefetchElement.relList.supports &&
- prefetchElement.relList.supports("prefetch") &&
- window.IntersectionObserver &&
- "isIntersecting" in IntersectionObserverEntry.prototype;
- const allowQueryString = "instantAllowQueryString" in document.body.dataset;
- const allowExternalLinks = "instantAllowExternalLinks" in
- document.body.dataset;
- const useWhitelist = "instantWhitelist" in document.body.dataset;
- const mousedownShortcut = "instantMousedownShortcut" in
- document.body.dataset;
- const DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION = 1111;
+/*
+ * Instant Page Copyright (C) 2019-2023 Alexandre Dieulot
+ * https://github.com/instantpage/instant.page/blob/master/LICENSE
+ * Licence: MIT | https://mit-license.org/
+*/
- let delayOnHover = 65;
- let useMousedown = false;
- let useMousedownOnly = false;
- let useViewport = false;
-
- if ("instantIntensity" in document.body.dataset) {
- const intensity = document.body.dataset.instantIntensity;
+(function () {
- if (intensity.substr(0, "mousedown".length) == "mousedown") {
- useMousedown = true;
- if (intensity == "mousedown-only") {
- useMousedownOnly = true;
- }
- } else if (intensity.substr(0, "viewport".length) == "viewport") {
- if (
- !(navigator.connection &&
- (navigator.connection.saveData ||
- (navigator.connection.effectiveType &&
- navigator.connection.effectiveType.includes("2g"))))
- ) {
- if (intensity == "viewport") {
- /* Biggest iPhone resolution (which we want): 414 × 896 = 370944
- * Small 7" tablet resolution (which we don’t want): 600 × 1024 = 614400
- * Note that the viewport (which we check here) is smaller than the resolution due to the UI’s chrome */
- if (
- document.documentElement.clientWidth *
- document.documentElement.clientHeight < 450000
- ) {
- useViewport = true;
- }
- } else if (intensity == "viewport-all") {
- useViewport = true;
- }
- }
- } else {
- const milliseconds = parseInt(intensity);
- if (!isNaN(milliseconds)) {
- delayOnHover = milliseconds;
- }
- }
+ /*/
+ * Element.closest() polyfill
+ * https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
+ * https://github.com/idmadj/element-closest-polyfill#readme
+ * Copyright (C) Abdelmadjid Hammou
+ * Licence: ISC | https://www.isc.org/licenses/
+ /*/
+
+ if (typeof Element !== "undefined") {
+ if (!Element.prototype.matches) {
+ Element.prototype.matches = Element.prototype.msMatchesSelector ||
+ Element.prototype.webkitMatchesSelector;
}
-
- if (isSupported) {
- const eventListenersOptions = {
- capture: true,
- passive: true,
+ if (!Element.prototype.closest) {
+ Element.prototype.closest = function (s) {
+ var el = this;
+ do {
+ if (el.matches(s)) return el;
+ el = el.parentElement || el.parentNode;
+ } while (el !== null && el.nodeType === 1);
+ return null;
};
-
- if (!useMousedownOnly) {
- document.addEventListener(
- "touchstart",
- touchstartListener,
- eventListenersOptions,
- );
- }
-
- if (!useMousedown) {
- document.addEventListener(
- "mouseover",
- mouseoverListener,
- eventListenersOptions,
- );
- } else if (!mousedownShortcut) {
- document.addEventListener(
- "mousedown",
- mousedownListener,
- eventListenersOptions,
- );
- }
-
- if (mousedownShortcut) {
- document.addEventListener(
- "mousedown",
- mousedownShortcutListener,
- eventListenersOptions,
- );
- }
-
- if (useViewport) {
- let triggeringFunction;
- if (window.requestIdleCallback) {
- triggeringFunction = function (callback) {
- requestIdleCallback(callback, {
- timeout: 1500,
- });
- };
- } else {
- triggeringFunction = function (callback) {
- callback();
- };
- }
-
- triggeringFunction(function () {
- const intersectionObserver = new IntersectionObserver(
- function (entries) {
- entries.forEach(function (entry) {
- if (entry.isIntersecting) {
- const linkElement = entry.target;
- intersectionObserver.unobserve(linkElement);
- preload(linkElement.href);
- }
- });
- },
- );
-
- document.querySelectorAll("a").forEach(function (linkElement) {
- if (isPreloadable(linkElement)) {
- intersectionObserver.observe(linkElement);
- }
- });
- });
- }
}
+ }
- function touchstartListener(event) {
- /* Chrome on Android calls mouseover before touchcancel so `lastTouchTimestamp`
- * must be assigned on touchstart to be measured on mouseover. */
- lastTouchTimestamp = performance.now();
+ /*/
+ * -----------------------------------------------------------------
+ /*/
- const linkElement = event.target.closest("a");
-
- if (!isPreloadable(linkElement)) {
- return;
- }
-
- preload(linkElement.href);
- }
-
- function mouseoverListener(event) {
- if (
- performance.now() - lastTouchTimestamp <
- DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION
- ) {
- return;
+ function fetch(url, method, callback) {
+ const http = new XMLHttpRequest();
+ http.onreadystatechange = function () {
+ if (http.readyState === 4 && http.status === 200) {
+ if (callback) callback(http);
}
+ };
+ http.open(method, url);
+ http.send();
+ return http;
+ }
- const linkElement = event.target.closest("a");
-
- if (!isPreloadable(linkElement)) {
- return;
- }
-
- linkElement.addEventListener("mouseout", mouseoutListener, {
- passive: true,
- });
-
- mouseoverTimer = setTimeout(function () {
- preload(linkElement.href);
- mouseoverTimer = undefined;
- }, delayOnHover);
- }
-
- function mousedownListener(event) {
- const linkElement = event.target.closest("a");
-
- if (!isPreloadable(linkElement)) {
- return;
- }
-
- preload(linkElement.href);
- }
-
- function mouseoutListener(event) {
- if (
- event.relatedTarget &&
- event.target.closest("a") == event.relatedTarget.closest("a")
- ) {
- return;
- }
-
- if (mouseoverTimer) {
- clearTimeout(mouseoverTimer);
- mouseoverTimer = undefined;
- }
- }
-
- function mousedownShortcutListener(event) {
- if (
- performance.now() - lastTouchTimestamp <
- DELAY_TO_NOT_BE_CONSIDERED_A_TOUCH_INITIATED_ACTION
- ) {
- return;
- }
-
- const linkElement = event.target.closest("a");
-
- if (event.which > 1 || event.metaKey || event.ctrlKey) {
- return;
- }
-
- if (!linkElement) {
- return;
- }
-
- linkElement.addEventListener("click", function (event) {
- if (event.detail == 1337) {
- return;
- }
-
- event.preventDefault();
- }, { capture: true, passive: false, once: true });
+ self.addEventListener("DOMContentLoaded", function () {
- const customEvent = new MouseEvent("click", {
- view: window,
- bubbles: true,
- cancelable: false,
- detail: 1337,
+ ["mouseout", "mousedown", "touchstart"].forEach(function (event) {
+ self.addEventListener(event, function (event) {
+ const url = event.target.closest("a");
+ if (preloadable(url) === undefined) return;
+ preload(url.href);
});
- linkElement.dispatchEvent(customEvent);
- }
-
- function isPreloadable(linkElement) {
- if (!linkElement || !linkElement.href) {
- return;
- }
+ });
- if (useWhitelist && !("instant" in linkElement.dataset)) {
- return;
+ function preloadable(url) {
+ switch (true) {
+ case (url === null || url.href === null): return;
+ case (url.origin !== location.origin): return;
+ case (["http:", "https:"].includes(url.protocol) === null): return;
+ case (url.protocol === "http:" && location.protocol === "https:"): return;
+ case (url.hash && url.pathname + url.search == location.pathname + location.search): return;
+ default: return true;
}
-
- if (
- !allowExternalLinks && linkElement.origin != location.origin &&
- !("instant" in linkElement.dataset)
- ) {
- return;
- }
-
- if (!["http:", "https:"].includes(linkElement.protocol)) {
- return;
- }
-
- if (linkElement.protocol == "http:" && location.protocol == "https:") {
- return;
- }
-
- if (
- !allowQueryString && linkElement.search &&
- !("instant" in linkElement.dataset)
- ) {
- return;
- }
-
- if (
- linkElement.hash &&
- linkElement.pathname + linkElement.search ==
- location.pathname + location.search
- ) {
- return;
- }
-
- if ("noInstant" in linkElement.dataset) {
- return;
- }
-
- return true;
}
function preload(url) {
- if (prefetches.has(url)) {
- return;
- }
-
const prefetcher = document.createElement("link");
- prefetcher.rel = "prefetch";
+ prefetcher.rel = "custom-prefetch";
prefetcher.href = url;
+ const selector = 'link[rel="'.concat(prefetcher.rel, '"][href="').concat(prefetcher.href, '"]');
+ const prefetched = document.head.contains(document.querySelector(selector));
+ if (prefetched) { return; }
document.head.appendChild(prefetcher);
-
- prefetches.add(url);
+ fetch(url, "GET", function () {});
}
});
})();
diff --git a/static/js/pager.ts b/static/js/pager.ts
index 01d40d7..ebaf67a 100644
--- a/static/js/pager.ts
+++ b/static/js/pager.ts
@@ -4,44 +4,60 @@
if (cookiesDisabled) {
document.cookie = "disabled";
document.cookie.indexOf("disabled");
- return console.log("Pager is disabled due to cookie restrictions.");
+ return console.warn("WARNING: Pager disabled due to cookie restrictions");
}
- let settings = { pager: {} };
+ let seek;
+ let pager = {};
- const url = self.location.href.split("#")[0].split("?")[0];
+ const state = "on";
+ const key = "config.scroll.pager.urls";
- const scrollRestore = (url) => {
- if (history.scrollRestoration) history.scrollRestoration = "manual";
- if (localStorage["settings"]) {
- settings = JSON.parse(localStorage["settings"]);
- }
- const fragment = document.getElementById(location.hash.slice(1));
- const fragmentInURL = self.location.hash.length > 0;
- if (fragmentInURL && document.body.contains(fragment)) {
- settings["pager"][url] = self.pageYOffset;
- localStorage["settings"] = JSON.stringify(settings);
- fragment.scrollIntoView();
- self.addEventListener("load", function () {
- fragment.scrollIntoView();
- });
- return;
- }
- if (settings["pager"][url] > 0) {
- self.scrollTo(0, settings["pager"][url]);
- return;
+ if (!localStorage[key]) localStorage[key] = JSON.stringify(pager);
+
+ let url = function () { return self.location.href.split("#")[0].split("?")[0]; };
+
+ const scrollHash = function (url) {
+ const hash = self.location.hash;
+ const fragment = hash.slice(1) && document.getElementById(hash.slice(1));
+ const fragmented = hash.length > 0;
+ const hashed = fragmented && document.body.contains(fragment);
+ if (hashed) {
+ self.location.hash = hash;
+ self.location.href = hash;
+ if ("scroll-margin-top" in document.body.style === false && fragment.textContent !== "") {
+ self.scrollBy(0, -6 * parseFloat(getComputedStyle(document.documentElement).fontSize));
+ }
}
- settings["pager"][url] = self.pageYOffset;
- localStorage["settings"] = JSON.stringify(settings);
+ return hashed;
};
- const scrollTrack = (url) => {
+ const scrollRestore = function (url) {
+ if (history.scrollRestoration) history.scrollRestoration = "manual";
+ if (scrollHash(url)) return;
+ pager = JSON.parse(localStorage[key]);
+ if (pager[url] > 0) {
+ clearInterval(seek);
+ self.scrollTo(0, pager[url]);
+ let i = 0; return seek = setInterval(function (position) {
+ i++; if (i > 100) clearInterval(seek);
+ if (document.documentElement.scrollHeight >= position + document.documentElement.clientHeight) {
+ clearInterval(seek); self.scrollTo(0, position);
+ }
+ }, 4, pager[url]);
+ } else self.scrollTo(0, 0);
+ pager[url] = self.pageYOffset;
+ localStorage[key] = JSON.stringify(pager);
+ };
+
+ const scrollTrack = function (url) {
const currentPosition = self.pageYOffset;
- settings["pager"][url] = currentPosition;
- localStorage["settings"] = JSON.stringify(settings);
+ pager = JSON.parse(localStorage[key]);
+ pager[url] = currentPosition;
+ localStorage[key] = JSON.stringify(pager);
};
- const backTrack = (back, up, event) => {
+ const scrollReverse = function (back, up, event) {
if (document.body.contains(up) && up.contains(event.target)) {
event.preventDefault();
window.scrollTo(0, 0);
@@ -53,20 +69,27 @@
}
};
- self.addEventListener("DOMContentLoaded", function () {
- scrollRestore(url);
- self.addEventListener("click", function (event) {
- const up = document.getElementById("top");
- const back = document.getElementById("back");
- backTrack(back, up, event);
- });
- });
-
- self.addEventListener("scroll", function () {
- scrollTrack(url);
- });
+ ["DOMContentLoaded", "pageshow", "hashchange", "URLChangedCustomEvent"].forEach(
+ function (event) {
+ self.addEventListener(event, function (event) {
+ if (event.type === "pageshow") {
+ return event.persisted && self.scrollTo(0, pager[url()]);
+ }
+ if (event.type === "DOMContentLoaded") {
+ self.addEventListener("click", function (event) {
+ const up = document.getElementById("top");
+ const back = document.getElementById("back");
+ scrollReverse(back, up, event);
+ });
+ }
+ scrollRestore(url());
+ });
+ },
+ );
- self.addEventListener("hashchange", function () {
- scrollRestore(url);
+ ["click", "touchstart", "scroll"].forEach(function (event) {
+ self.addEventListener(event, function () {
+ scrollTrack(url());
+ });
});
})();
diff --git a/static/js/plumber.ts b/static/js/plumber.ts
index 8e551fd..d425769 100644
--- a/static/js/plumber.ts
+++ b/static/js/plumber.ts
@@ -1,8 +1,8 @@
/**
- * Plumber based on and inspired by
- * Dictionary Access Copyright (C) 2006, Paul Lutus
+ * Plumber based on and inspired by;
+ * Dictionary Access Copyright (C) 2006 Paul Lutus
* https://arachnoid.com/javascript/dictionary_access.js
- * LICENSE: GPLv2+
+ * Licence: GPLv2+ | https://www.gnu.org/licenses/gpl-3.0.txt
*/
(function () {
diff --git a/static/js/timeago.ts b/static/js/timeago.ts
index af974fc..7c1973d 100644
--- a/static/js/timeago.ts
+++ b/static/js/timeago.ts
@@ -8,49 +8,86 @@
style: "long",
});
- const date = () => {
- [...document.querySelectorAll("time")]
- .forEach(
- (element) => {
- try {
- const time: millisecond = new Date(element.dateTime) || new Date();
- const interval: second = ((new Date().getTime() - time.getTime()) / 1000);
-
- const seconds: number = Math.floor(interval);
- const minutes: number = Math.floor(seconds / 60);
- const hours: number = Math.floor(minutes / 60);
- const days: number = Math.floor(hours / 24);
-
- if (Math.sign(seconds) === 1) {
- if (seconds <= 60) { return element.textContent = relative.format(-1 * seconds, "second",); }
- if (minutes <= 120) { return element.textContent = relative.format(-1 * minutes, "minute",); }
- if (hours <= 48) { return element.textContent = relative.format(-1 * hours, "hour",); }
- if (days <= 60) { return element.textContent = relative.format(-1 * days, "day",); }
- }
-
- if (Math.sign(seconds) === -1) {
- if (-1 * days >= 60) { return element.textContent = relative.format(-1 * days, "day",); }
- if (-1 * hours >= 48) { return element.textContent = relative.format(-1 * hours, "hour",); }
- if (-1 * minutes >= 120) { return element.textContent = relative.format(-1 * minutes, "minute",); }
- if (-1 * seconds >= 0) { return element.textContent = relative.format(-1 * seconds, "second",); }
- }
-
- } catch (error) {
- console.error(
- "Error: Unable to resolve relative time format!",
- error,
- );
- }
- },
- );
+ function viewport(element) {
+ const options = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : { offset: 250 };
+ const view = element.getBoundingClientRect();
+ return view.top >= -options.offset
+ && view.left >= -options.offset
+ && view.bottom <= (self.innerHeight || document.documentElement.clientHeight) + options.offset
+ && view.right <= (self.innerWidth || document.documentElement.clientWidth) + options.offset;
}
+ const date = function (update) {
+ const elements = document.querySelectorAll("time");
+ for (let i = 0; i < elements.length; ++i) {
+ const offscreen = !viewport(elements[i]);
+ const hidden = elements[i].offsetParent === null;
+ if ((update === "viewport") && (offscreen || hidden)) continue;
+
+ (function (element) {
+ try {
+ if (element.dataset.type === "disabled") return;
+
+ const time: millisecond = new Date(element.dateTime) || new Date();
+ const interval: second = ((new Date().getTime() - time.getTime()) / 1000);
+
+ const seconds: number = Math.round(interval);
+ const minutes: number = Math.round(seconds / 60);
+ const hours: number = Math.round(minutes / 60);
+ const days: number = Math.round(hours / 24);
+
+ const past = Math.sign(seconds) === 1;
+ const future = Math.sign(seconds) === -1;
+
+ let tiny = function (string, place) {
+ return string.split(" ").slice(0, place).join(" ") + string.split(" ")[place].charAt(0);
+ }
+
+ if (element.dataset.type === "default") { tiny = function (string) { return string; }; }
+
+ if (element.dataset.type === "localDate") {
+ return element.textContent = new Intl.DateTimeFormat([], { dateStyle: "medium", }).format(time).replace(",", "");
+ }
+
+ if (element.dataset.type === "localTime") {
+ return element.textContent = new Intl.DateTimeFormat([], {
+ hour12: false,
+ timeStyle: "short",
+ }).format(time) + " " + new Intl.DateTimeFormat([], { timeZoneName: "short" }).format(time).split(" ")[1];
+ }
+
+ if (past) {
+ if (seconds <= 60) { return element.textContent = tiny(relative.format(-1 * seconds, "second",), 1); }
+ if (minutes <= 120) { return element.textContent = tiny(relative.format(-1 * minutes, "minute",), 1); }
+ if (hours <= 48) { return element.textContent = tiny(relative.format(-1 * hours, "hour",), 1); }
+ if (days <= 7) { return element.textContent = tiny(relative.format(-1 * days, "day",), 1); }
+ }
+
+ if (future) {
+ if (-1 * days >= 4) { return element.textContent = tiny(relative.format(-1 * days, "day",), 2); }
+ if (-1 * hours >= 3) { return element.textContent = tiny(relative.format(-1 * hours, "hour",), 2); }
+ if (-1 * minutes >= 2) { return element.textContent = tiny(relative.format(-1 * minutes, "minute",), 2); }
+ if (-1 * seconds >= 1) { return element.textContent = tiny(relative.format(-1 * seconds, "second",), 2); }
+ }
+ } catch (error) {
+ console.error("ERROR: Relative time resolution failed", error);
+ }
+ })(elements[i]);
+ }
+ };
+
const substitution = setInterval(date, 4);
- self.addEventListener("load", () => {
- setTimeout(() => {
+ ["scroll", "URLChangedCustomEvent"].forEach(function (event) {
+ self.addEventListener(event, function () {
+ date("viewport");
+ });
+ });
+
+ self.addEventListener("DOMContentLoaded", function () {
+ setTimeout(function () {
clearInterval(substitution);
- setInterval(date, 1000);
+ setInterval(function () { date("viewport"); }, 1000);
}, 1000);
});
})();
diff --git a/static/js/update.ts b/static/js/update.ts
new file mode 100644
index 0000000..df29f49
--- /dev/null
+++ b/static/js/update.ts
@@ -0,0 +1,84 @@
+(function () {
+
+ const cookiesDisabled = !navigator.cookieEnabled;
+
+ if (cookiesDisabled) {
+ document.cookie = "disabled";
+ document.cookie.indexOf("disabled");
+ return console.warn("WARNING: Update check disabled due to cookie restrictions");
+ }
+
+ function fetch(url, method, callback) {
+ const http = new XMLHttpRequest();
+ http.onreadystatechange = function () {
+ if (http.readyState === 4 && http.status === 200) {
+ if (callback) callback(http);
+ }
+ };
+ http.open(method, url);
+ http.setRequestHeader("Pragma", "no-cache");
+ http.setRequestHeader("Cache-Control", "no-cache");
+ http.send();
+ return http;
+ }
+
+ const state = "on";
+ const key = "config.update";
+
+ let stamps = {};
+
+ if (!sessionStorage[key + ".urls"]) sessionStorage[key + ".urls"] = JSON.stringify(stamps);
+
+ function update() {
+ const url = self.location.href.split("#")[0].split("?")[0];
+
+ const indicator = document.querySelector("a[data-update]");
+ if (indicator === null || indicator.dataset.update === "refresh") return;
+ const anchor = indicator.cloneNode();
+
+ fetch(url, "HEAD", function (request) {
+ const local = document.querySelector('meta[name="last-modified"]').content || document.lastModified;
+ const remote = request.getResponseHeader("last-modified") || '';
+ const modified = Date.parse(remote || local) > Date.parse(local);
+ const drift = Date.parse(remote || local) - Date.parse(local);
+
+ if (drift < 10000) return;
+
+ function reset() {
+ indicator.href = anchor.href;
+ indicator.setAttribute("id", anchor.id);
+ indicator.dataset.update = anchor.dataset.update;
+ }
+
+ stamps = JSON.parse(sessionStorage[key + ".urls"]);
+ if (stamps[url] === remote) return;
+ stamps[url] = remote;
+ sessionStorage[key + ".urls"] = JSON.stringify(stamps);
+
+ if (remote && modified) {
+ fetch(url, "GET", function () {
+ indicator.href = url.replace(/^https:/, "http:");
+ indicator.removeAttribute("id");
+ indicator.dataset.update = "refresh";
+ console.log("INFO: R: " + remote);
+ console.log("INFO: L: " + local);
+ console.log("INFO: D: " + drift);
+ console.log("INFO: M: " + modified);
+ });
+ }
+ });
+ }
+
+ let scrolled;
+ let delay = 1000;
+ let delayed = 0;
+
+ self.addEventListener("scroll", function () {
+ if (scrolled) clearTimeout(scrolled);
+ scrolled = setTimeout(function () { update(); delay = delay + delayed; delayed = delay - delayed; }, delay);
+ });
+
+ ["focus", "load", "URLChangedCustomEvent"].forEach(function (event) {
+ self.addEventListener(event, function () { update(); });
+ });
+})();
diff --git a/themes/default/layouts/_default/_markup/render-codeblock-mathml.html b/themes/default/layouts/_default/_markup/render-codeblock-mathml.html
new file mode 100644
index 0000000..f6e5b61
--- /dev/null
+++ b/themes/default/layouts/_default/_markup/render-codeblock-mathml.html
@@ -0,0 +1,18 @@
+{{- $caption := default "Math Render" .Attributes.caption -}}
+{{- $ordinal := add .Ordinal 1 -}}
+{{- $hash := print (truncate 3 "" (sha256 .Inner)) (truncate 3 "" (sha256 .Page.RelPermalink)) "-" $ordinal -}}
+{{- $id := print "math:" $hash | safeURL -}}
+
+<math-ml>
+ <figure id="{{ $id }}">
+ <figure>
+ {{- with $math := .Inner -}}
+ {{- $math | safeHTML -}}
+ {{- end -}}
+ </figure>
+ <figcaption>
+ <a href="#{{ $id }}">({{ $ordinal }})</a>
+ {{ $caption | markdownify }}
+ </figcaption>
+ </figure>
+</math-ml>
diff --git a/themes/default/layouts/_default/_markup/render-codeblock.html b/themes/default/layouts/_default/_markup/render-codeblock.html
index f18f0d3..ab9a786 100644
--- a/themes/default/layouts/_default/_markup/render-codeblock.html
+++ b/themes/default/layouts/_default/_markup/render-codeblock.html
@@ -1,22 +1,25 @@
-{{- $caption := .Attributes.caption -}}
-{{- $type := .Type | default "text" -}}
-{{- $options := .Attributes.options | default "default=1" -}}
-{{- $hash := print (truncate 8 "" (sha256 .Inner)) .Ordinal -}}
-{{- $id := print "code-block-" $hash -}}
+{{- $caption := .Attributes.caption -}}
+{{- $type := .Type | default "text" -}}
+{{- $options := .Attributes.options | default "default=1" -}}
+{{- $hash := print (truncate 3 "" (sha256 .Inner)) (truncate 3 "" (sha256 .Page.RelPermalink)) .Ordinal -}}
+{{- $id := print "code-block:" $hash | safeURL -}}
+{{- $highlight := highlight .Inner $type (print $options ",lineAnchors=" "code-line:" $hash) -}}
<code-block id="{{ $id }}" {{ if in (lower $options) "linenos" }}data-lines=""{{ end }}>
<header>
<language-label>
<a href="#{{ $id }}">{{ $type }}</a>
</language-label>
- <button hidden="">
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/copy.svg")) }}
- <span>Copy</span>
- </button>
</header>
- {{ highlight .Inner $type (print $options ",lineAnchors=" "code-line-" $hash) }}
+ <code-content contenteditable="true" spellcheck="false">
+ {{- replace $highlight
+ `class="lnlinks"`
+ `contenteditable="false" class="lnlinks"`
+ | safeHTML
+ -}}
+ </code-content>
</code-block>
-{{ with $caption }}
+{{- with $caption -}}
<footer>{{ . | markdownify }}</footer>
-{{ end }}
+{{- end -}}
diff --git a/themes/default/layouts/_default/_markup/render-heading.html b/themes/default/layouts/_default/_markup/render-heading.html
index 37eddb2..86b8e35 100644
--- a/themes/default/layouts/_default/_markup/render-heading.html
+++ b/themes/default/layouts/_default/_markup/render-heading.html
@@ -1,6 +1,9 @@
-<h{{ .Level }} id="{{ .Anchor | safeURL }}">
- <a
- title="{{ .Text | safeHTML }}"
- href="#{{ .Anchor | safeURL }}">{{ .Text | safeHTML }}
+{{- $text := .Text -}}
+{{- $hash := print (truncate 2 "" (sha256 .Page.RelPermalink)) (truncate 2 "" (sha256 $text)) -}}
+{{- $id := print "heading:" $hash ":" .Anchor -}}
+
+<h{{ .Level }} id="{{ $id | safeURL }}">
+ <a title="{{ $text | safeHTML }}" href="#{{ $id | safeURL }}">
+ {{ $text | safeHTML }}
</a>
</h{{ .Level }}>
diff --git a/themes/default/layouts/_default/_markup/render-image.html b/themes/default/layouts/_default/_markup/render-image.html
index b98efdf..04bf931 100644
--- a/themes/default/layouts/_default/_markup/render-image.html
+++ b/themes/default/layouts/_default/_markup/render-image.html
@@ -1,97 +1,92 @@
-{{- $source := $.Destination | safeURL -}}
-{{- $public := print "public/" $source -}}
-{{- $local := "" -}}
{{- $cache := "" -}}
-{{- $exists := "" -}}
{{- $width := "" -}}
{{- $height := "" -}}
{{- $srcset := "" -}}
{{- $colors := "" -}}
+{{- $type := "" -}}
+{{- $source := $.Destination | safeURL -}}
+{{- $public := print "public/" $source -}}
+{{- $fetch := print (urls.Parse $source).Scheme "://" (urls.Parse $source).Host (urls.Parse $source).RequestURI -}}
{{- $figcaption := "Image/Picture" -}}
{{- $orientation := "landscape" -}}
{{- $dimensions := "600x360" -}}
{{- $author := .Page.Section -}}
{{- $relURL := strings.TrimPrefix .Page.Site.BaseURL .Page.Permalink -}}
{{- $immutable := print ($relURL | humanize | urlize) "-" ($source | sha256 | truncate 8 "") -}}
-{{- $fileCache := print (partial "function-paths.html").media "/" $author "/" $immutable -}}
-{{- $cached := and (fileExists (print "public/" $fileCache ".webp")) (fileExists (print "public/" $fileCache (path.Ext $source))) -}}
+{{- $storage := print $author "/media/" $immutable -}}
+{{- $cached := fileExists (print "public/" $storage ".webp") -}}
+
+{{- $moderns := slice ".webp" ".avif" -}}
+{{- $fallbacks := slice ".png" ".jpg" ".gif" ".jpeg" ".svg" ".apng" ".jfif" ".pjpeg" ".pjp" -}}
+{{- $mimes := slice "image/avif" "image/webp" "image/apng" "image/gif" "image/jpeg" "image/png" "image/svg+xml" -}}
{{- if not $cached -}}
- {{- with $remote := cond (default true $.Page.Site.Params.site.offline) false (resources.GetRemote $source) -}}
+ {{- with $remote := cond (default true $.Page.Site.Params.site.offline) false (resources.GetRemote $fetch) -}}
{{- with .Err -}}
{{- if fileExists $public -}}
- {{- $local = resources.Get $public -}}
- {{- with $local -}}
- {{- $local = .Content | resources.FromString (print (partial "function-paths.html").media "/" $author "/" (path.Base .)) -}}
+ {{- with $local := resources.Get $public -}}
+ {{- $local = .Content | resources.FromString (print $storage (path.Base .)) -}}
+ {{- $local = .Fit (print $dimensions " webp") -}}
+ {{- $local = $local | resources.Copy (print $storage ".webp") -}}
+ {{- $srcset = $local.Permalink -}}
+ {{- $local = .Fit $dimensions -}}
+ {{- $local = $local | resources.Copy (print $storage (path.Ext $local)) -}}
+ {{- $width = $local.Width -}}
+ {{- $height = $local.Height -}}
+ {{- $colors = $local.Colors -}}
+ {{- $cache = $local.Permalink -}}
{{- end -}}
{{- $source = print ("" | absURL) $source -}}
{{- else -}}
- {{- $404image := resources.Get "data/media/404.png" -}}
- {{- with $404image -}}
- {{- $width = .Width -}}
- {{- $height = .Height -}}
+ {{- with $404image := resources.Get "data/media/404.png" -}}
+ {{- $width = $404image.Width -}}
+ {{- $height = $404image.Height -}}
+ {{- $source = $404image.Permalink -}}
{{- end -}}
- {{- $source = $404image.Permalink -}}
{{- end -}}
{{- else -}}
- {{- $cache = .Content | resources.FromString (print (partial "function-paths.html").media "/" $author "/" (path.Base .)) -}}
+ {{- with $cache = $remote.Content | resources.FromString (print $storage (path.Base $remote)) -}}
+ {{- $cache = .Fit (print $dimensions " webp") -}}
+ {{- $cache = $cache | resources.Copy (print $storage ".webp") -}}
+ {{- $srcset = $cache.Permalink -}}
+ {{- $cache = .Fit $dimensions -}}
+ {{- $cache = $cache | resources.Copy (print $storage (path.Ext $cache)) -}}
+ {{- $width = $cache.Width -}}
+ {{- $height = $cache.Height -}}
+ {{- $colors = $cache.Colors -}}
+ {{- $cache = $cache.Permalink -}}
+ {{- end -}}
{{- end -}}
{{- end -}}
{{- else -}}
- {{- $exists = resources.Get (print "public/" $fileCache (path.Ext $source)) -}}
- {{- $exists = $exists.Content | resources.FromString (print (partial "function-paths.html").media "/" $author "/" (path.Base $exists)) -}}
-{{- end -}}
-
-{{- with $local }}
- {{- $local = .Fit (print $dimensions " webp") }}
- {{- $local = $local | resources.Copy (print (partial "function-paths.html").media "/" $author "/" $immutable ".webp") }}
- {{- $srcset = $local.Permalink -}}
- {{- $local = .Fit $dimensions }}
- {{- $local = $local | resources.Copy (print (partial "function-paths.html").media "/" $author "/" $immutable (path.Ext $local)) }}
- {{- $width = $local.Width -}}
- {{- $height = $local.Height -}}
- {{- $colors = $local.Colors -}}
- {{- $writeToFile := $local.Permalink }}
-{{- end }}
-
-{{- with $cache }}
- {{- $cache = .Fit (print $dimensions " webp") }}
- {{- $cache = $cache | resources.Copy (print $author "/media/" $immutable ".webp") }}
- {{- $srcset = $cache.Permalink -}}
- {{- $cache = .Fit $dimensions }}
- {{- $cache = $cache | resources.Copy (print (partial "function-paths.html").media "/" $author "/" $immutable (path.Ext $cache)) }}
- {{- $width = $cache.Width -}}
- {{- $height = $cache.Height -}}
- {{- $colors = $cache.Colors -}}
- {{- $cache = $cache.Permalink }}
-{{- end -}}
-
-{{- with $exists }}
- {{- if fileExists (print "public/" $fileCache ".webp") -}}
- {{- $srcset = print "/" $fileCache ".webp" -}}
+ {{- with $cache = resources.Get (print "public/" $storage ".webp") -}}
+ {{- $width = $cache.Width -}}
+ {{- $height = $cache.Height -}}
+ {{- $colors = $cache.Colors -}}
+ {{- $type = $cache.MediaType -}}
+ {{- $srcset = print ("" | absURL) "/" $storage ".webp" -}}
{{- end -}}
- {{- if fileExists (print "public/" $author "/media/" $immutable ".webp") -}}
- {{- $srcset = print "/" $author "/media/" $immutable ".webp" -}}
+ {{- range $extension := $fallbacks -}}
+ {{- with resources.Get (print "public/" $storage $extension) -}}
+ {{- $cache = print ("" | absURL) "/" $storage $extension -}}
+ {{- break -}}
+ {{- end -}}
{{- end -}}
- {{- $width = .Width -}}
- {{- $height = .Height -}}
- {{- $colors = .Colors -}}
- {{- $cache = .Permalink }}
{{- end -}}
{{- if lt $width $height -}}
{{- $orientation = "portrait" -}}
{{- end -}}
-{{- with $.Title -}}
- {{- $figcaption = . | markdownify -}}
+{{- with $caption := $.Title -}}
+ {{- $figcaption = $caption | markdownify -}}
{{ end }}
{{- /* This comment removes trailing newlines and white spaces. */ -}}
<figure>
<a data-orientation="{{ $orientation }}" href="{{ $source }}">
<picture>
{{- with $srcset }}
- <source srcset="{{ $srcset }}" type="image/webp" />
+ <source srcset="{{ $srcset }}" type="{{ or $type "image/webp" }}" />
{{- end }}
<img
loading="lazy"
@@ -101,7 +96,7 @@
width="{{ $width }}"
height="{{ $height }}"
{{ printf `style="` | safeHTMLAttr -}}
- {{- partial "styles-image-gradient.html" $colors | safeHTMLAttr -}}
+ {{- partial "image-gradient.css.html" $colors | safeHTMLAttr -}}
{{- printf `"` | safeHTMLAttr }}
/>
</picture>
diff --git a/themes/default/layouts/_default/baseof.html b/themes/default/layouts/_default/baseof.html
index ddd2780..c277115 100644
--- a/themes/default/layouts/_default/baseof.html
+++ b/themes/default/layouts/_default/baseof.html
@@ -1,5 +1,11 @@
-{{- $modified := partial "function-page-modified.html" . -}}
+{{- $modified := partial "function-page-modified.html"
+ (dict
+ "Context" .
+ "Disable" true
+ )
+-}}
+{{- if $modified -}}
<!DOCTYPE html>
<html
lang="en-us"
@@ -7,14 +13,15 @@
data-type="{{ .Page.Type }}"
itemscope=""
itemtype="http://schema.org/BlogPosting"
+ data-document="html"
>
<head>
<title>
{{- block "title" . -}}{{- end -}}
- {{- partial "base-title.html" . -}}
+ {{- partial "head-title.html" . -}}
</title>
- <meta name="description" content="{{- partial "base-description.html" . -}}" />
- {{- partial "base-head.html" . -}}
+ <meta name="description" content="{{- partial "head-description.html" . -}}" />
+ {{- partial "head.html" . -}}
{{- block "styles" . -}}{{- end -}}
</head>
<body>
@@ -22,23 +29,27 @@
<a href="#main">Skip to main content</a>
</skip-link>
- <column-left>
+ <column-base position="left">
{{- partial "navigator-left.html" . -}}
- </column-left>
+ </column-base>
- <column-middle>
+ <column-base position="middle">
+ {{- block "header" . -}}{{- end -}}
<main id="main">
{{- block "middle" . -}}
<footer>Silence is golden.</footer>
{{- end -}}
- {{- partial "base-footer.html" . -}}
</main>
- </column-middle>
+ {{- block "footer" . -}}
+ {{- partial "footer.html" . -}}
+ {{- end -}}
+ </column-base>
- <column-right>
+ <column-base position="right">
{{- block "right" . -}}
<footer>Silence is golden.</footer>
{{- end -}}
- </column-right>
+ </column-base>
</body>
</html>
+{{- end -}}
diff --git a/themes/default/layouts/_default/baseof.json b/themes/default/layouts/_default/baseof.json
index b2d7a9f..e1203cc 100644
--- a/themes/default/layouts/_default/baseof.json
+++ b/themes/default/layouts/_default/baseof.json
@@ -1,5 +1,12 @@
-{{- $modified := partial "function-page-modified.html" . -}}
+{{- $modified := partial "function-page-modified.html"
+ (dict
+ "Context" .
+ "Disable" true
+ )
+-}}
-{{- block "main" . -}}
-"Silence is golden."
+{{- if $modified -}}
+ {{- block "main" . -}}
+ "Silence is golden."
+ {{- end -}}
{{- end -}}
diff --git a/themes/default/layouts/_default/baseof.txt b/themes/default/layouts/_default/baseof.txt
index 55f860c..c354667 100644
--- a/themes/default/layouts/_default/baseof.txt
+++ b/themes/default/layouts/_default/baseof.txt
@@ -1,5 +1,12 @@
-{{- $modified := partial "function-page-modified.html" . -}}
+{{- $modified := partial "function-page-modified.html"
+ (dict
+ "Context" .
+ "Disable" true
+ )
+-}}
-{{- block "main" . -}}
-Silence is golden.
+{{- if $modified -}}
+ {{- block "main" . -}}
+ Silence is golden.
+ {{- end -}}
{{- end -}}
diff --git a/themes/default/layouts/_default/baseof.xml b/themes/default/layouts/_default/baseof.xml
index f804253..73f129f 100644
--- a/themes/default/layouts/_default/baseof.xml
+++ b/themes/default/layouts/_default/baseof.xml
@@ -1,8 +1,13 @@
-{{- $modified := partial "function-page-modified.html" . -}}
+{{- $modified := partial "function-page-modified.html"
+ (dict
+ "Context" .
+ "Disable" true
+ )
+-}}
+{{- if $modified -}}
{{- block "main" . -}}
-{{- printf `<?xml version="1.0" encoding="utf-8" standalone="yes"?>` | safeHTML -}}
-<root>
-Silence is golden.
-</root>
+{{- printf `<?xml version="1.0" encoding="utf-8" standalone="yes"?>%s` "\n" | safeHTML -}}
+<root>Silence is golden.</root>
+{{- end -}}
{{- end -}}
diff --git a/themes/default/layouts/_default/home.archives.html b/themes/default/layouts/_default/home.archives.html
new file mode 100644
index 0000000..f443583
--- /dev/null
+++ b/themes/default/layouts/_default/home.archives.html
@@ -0,0 +1,67 @@
+{{- define "title" -}}Archives &mdash; {{ end -}}
+{{- define "description" -}}An archive of all items &mdash; {{ end -}}
+{{- define "styles" -}}
+<style>
+ {{ partial "navigator.css.html" (dict "Link" "/archives/") | safeCSS }}
+</style>
+{{- end -}}
+
+{{- define "header" -}}
+ {{- partial "navigator-middle.html"
+ (dict
+ "Context" .
+ "IconLabel" "Back"
+ "Id" "back"
+ "Title" "Archives"
+ "Icon" "arrow-left"
+ "Subtitle" (print (partial "count.html" .) " " "Total")
+ "Href" (or (and (gt .Paginator.PageNumber 1) (.Paginator.Prev.URL | absURL)) "/")
+ )
+ -}}
+{{- end -}}
+
+{{- define "middle" -}}
+ <archive-list>
+ <time-line>
+ {{ range (.Paginator.Pages.GroupByDate "2006") }}
+ {{ range (first 1 .Pages) }}
+ <h1>{{ .Date | time.Format "2006" }}</h1>
+ {{ end }}
+ <ul>
+ {{ range .Pages }}
+ {{- $author := .Page.Section -}}
+ <li>
+ <a
+ title="{{ partial "meta-title.html" . }}"
+ href="{{ .Permalink }}#{{ partial "card-id.html" . }}"
+ >
+ <code>
+ <time
+ data-type="disabled"
+ datetime="{{ .Date | time.Format "2006-01-02T15:04:05Z" }}"
+ title="{{ .Date | time.Format "Posted: Monday January 2 2006 at 15:04:05 MST" }}"
+ >
+ {{ .Date | time.Format "02 Jan" }}
+ </time>
+ </code>
+ <section>
+ <h2>{{ partial "meta-title.html" . }}</h2>
+ <p>@{{ or .Params.feed.domain $author }}</p>
+ </section>
+ </a>
+ </li>
+ {{ end }}
+ </ul>
+ {{ end }}
+ </time-line>
+ </archive-list>
+{{- end -}}
+
+{{- define "footer" -}}
+ {{- partial "pagination.html" . -}}
+ {{- partial "footer.html" . -}}
+{{- end -}}
+
+{{- define "right" -}}
+ {{- partial "navigator-right.html" . -}}
+{{- end -}}
diff --git a/themes/default/layouts/_default/home.authors.html b/themes/default/layouts/_default/home.authors.html
index c4051bb..0662285 100644
--- a/themes/default/layouts/_default/home.authors.html
+++ b/themes/default/layouts/_default/home.authors.html
@@ -1,41 +1,41 @@
-{{ define "title" }}Authors &mdash; {{ end }}
-{{ define "description" }}This page contains a list of all authors &mdash; {{ end }}
-{{ define "styles" }}
+{{- define "title" -}}Authors &mdash; {{ end -}}
+{{- define "description" -}}A list of all authors &mdash; {{ end -}}
+{{- define "styles" -}}
<style>
- {{ partial "styles-navigator.html" (dict "Link" "/authors/") | safeCSS }}
+ {{ partial "navigator.css.html" (dict "Link" "/authors/") | safeCSS }}
</style>
-{{ end }}
+{{- end -}}
-{{ define "middle" }}
-
- {{- partial "generate-authors" . -}}
-
- {{ partial "navigator-middle.html"
+{{- define "header" -}}
+ {{- partial "navigator-middle.html"
(dict
"Title" "Authors"
- "Subtitle" (partial "count-authors.html" .)
+ "Subtitle" (print (partial "count-authors.html" .) " " "Total")
"Icon" "arrow-left"
"IconLabel" "Back"
"Href" "/"
"Id" "back"
"Context" .
)
- }}
+ -}}
+{{- end -}}
- {{ $authors := partial "function-authors-slice.html" . }}
+{{- define "middle" -}}
+ {{- partial "generate-authors" . -}}
+
+ {{- $authors := partial "function-authors-slice.html" . -}}
- {{- range $author := shuffle $authors -}}
- {{ $data := index $.Site.Data $author | default "default" }}
+ {{- range $author := $authors -}}
+ {{- $data := index $.Site.Data.authors $author -}}
{{- $date := (index (first 1 (where $.Site.Pages.ByDate.Reverse "Section" $author)) 0).Date -}}
{{- partial "author-card.html" (dict
"Data" $data
"Date" $date
)
-}}
- {{ end }}
-
-{{ end }}
+ {{- end -}}
+{{- end -}}
-{{ define "right" }}
+{{- define "right" -}}
{{- partial "navigator-right.html" . -}}
-{{ end }}
+{{- end -}}
diff --git a/themes/default/layouts/_default/home.authors.section.html b/themes/default/layouts/_default/home.authors.section.html
index 8b868f9..b0b1161 100644
--- a/themes/default/layouts/_default/home.authors.section.html
+++ b/themes/default/layouts/_default/home.authors.section.html
@@ -1,11 +1,20 @@
{{- $authors := partial "function-authors-slice.html" . -}}
-{{- range $author := first 3 (shuffle $authors) -}}
-{{- $data := index $.Site.Data $author | default "default" -}}
-{{- $date := (index (first 1 (where $.Site.Pages.ByDate.Reverse "Section" $author)) 0).Date -}}
-{{- partial "author-card.html" (dict
- "Data" $data
- "Date" $date
+{{- $modified := partial "function-page-modified.html"
+ (dict
+ "Context" .
+ "Disable" true
)
-}}
+
+{{- if $modified -}}
+ {{- range $author := first 3 $authors -}}
+ {{- $data := index $.Site.Data.authors $author -}}
+ {{- $date := (index (first 1 (where $.Site.Pages.ByDate.Reverse "Section" $author)) 0).Date -}}
+ {{- partial "author-card.html" (dict
+ "Data" $data
+ "Date" $date
+ )
+ -}}
+ {{- end -}}
{{- end -}}
diff --git a/themes/default/layouts/_default/home.browserconfig.xml b/themes/default/layouts/_default/home.browserconfig.xml
deleted file mode 100644
index 67bc7a3..0000000
--- a/themes/default/layouts/_default/home.browserconfig.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-{{- $icon := resources.Get .Site.Params.webmanifest.logo -}}
-
-{{- $mstile150 := $icon.Fit "150x150" -}}
-
-<?xml version="1.0" encoding="utf-8"?>
-<browserconfig>
- <msapplication>
- <tile>
- <square150x150logo src="{{ $mstile150.Permalink }}"/>
- <TileColor>#da532c</TileColor>
- </tile>
- </msapplication>
-</browserconfig>
diff --git a/themes/default/layouts/_default/home.history.html b/themes/default/layouts/_default/home.history.html
deleted file mode 100644
index 5765826..0000000
--- a/themes/default/layouts/_default/home.history.html
+++ /dev/null
@@ -1,57 +0,0 @@
-{{ define "title" }}Message History &mdash; {{ end }}
-{{ define "description" }}This page contains an archive of all messages &mdash; {{ end }}
-{{ define "styles" }}
-<style>
- {{ partial "styles-navigator.html" (dict "Link" "/archives/messages/") | safeCSS }}
-</style>
-{{ end }}
-
-{{ define "middle" }}
-
- {{ partial "navigator-middle.html"
- (dict
- "Title" "History"
- "Subtitle" (partial "count-total-messages.html" .)
- "Icon" "arrow-left"
- "IconLabel" "Back"
- "Href" "/"
- "Id" "back"
- "Context" .
- )
- }}
-
- {{- $author := partial "function-authors-data.html" . -}}
-
- <history-archive>
- <item-list>
- {{ range (.Paginator.Pages.GroupByDate "2006") }}
- {{ range (first 1 .Pages) }}
- <h1>{{ .Date.Format "2006" }}</h1>
- {{ end }}
- <ul>
- {{ range .Pages }}
- <li>
- <a
- title="{{ partial "meta-title.html" . }}"
- href="{{ .RelPermalink }}#{{ partial "card-id.html" . }}"
- >
- <span>
- <code title="{{ .Date | time.Format "Posted: Monday, January 2, 2006 at 15:04:05 MST" }}">{{ .Date.Format "02 Jan" }}</code>
- </span>
- <span>{{ partial "meta-title.html" . }}</span>
- <span>@{{ $author.user }}</span>
- </a>
- </li>
- {{ end }}
- </ul>
- {{ end }}
- </item-list>
- </history-archive>
-
- {{ partial "pagination.html" . }}
-
-{{ end }}
-
-{{ define "right" }}
- {{- partial "navigator-right.html" . -}}
-{{ end }}
diff --git a/themes/default/layouts/_default/home.records.html b/themes/default/layouts/_default/home.records.html
deleted file mode 100644
index 137c673..0000000
--- a/themes/default/layouts/_default/home.records.html
+++ /dev/null
@@ -1,52 +0,0 @@
-{{ define "title" }}Tags Archive &mdash; {{ end }}
-{{ define "description" }}This page contains an archive of all tags &mdash; {{ end }}
-{{ define "styles" }}
-<style>
- {{ partial "styles-navigator.html" (dict "Link" "/archives/tags/") | safeCSS }}
-</style>
-{{ end }}
-
-{{ define "middle" }}
-
- {{ partial "navigator-middle.html"
- (dict
- "Title" "Records"
- "Subtitle" (partial "count-tags.html" .)
- "Icon" "arrow-left"
- "IconLabel" "Back"
- "Href" "/"
- "Id" "back"
- "Context" .
- )
- }}
-
- {{- $author := partial "function-authors-data.html" . -}}
-
- <records-archive>
- <item-list>
- {{ range (.Paginator.Pages.GroupByDate "2006") }}
- {{ range (first 1 .Pages) }}
- <h1>{{ .Date.Format "2006" }}</h1>
- {{ end }}
- <ul>
- {{ range .Pages }}
- <li>
- <span>
- <code title="{{ .Date | time.Format "Posted: Monday, January 2, 2006 at 15:04:05 MST" }}">{{ .Date.Format "02 Jan" }}</code>
- </span>
- <span>{{ partial "meta-tags.html" . }} &mdash; {{ partial "meta-title.html" . }}</span>
- <span>@{{ $author.user }}</span>
- </li>
- {{ end }}
- </ul>
- {{ end }}
- </item-list>
- </records-archive>
-
- {{ partial "pagination.html" . }}
-
-{{ end }}
-
-{{ define "right" }}
- {{- partial "navigator-right.html" . -}}
-{{ end }}
diff --git a/themes/default/layouts/_default/home.settings.html b/themes/default/layouts/_default/home.settings.html
new file mode 100644
index 0000000..84e8080
--- /dev/null
+++ b/themes/default/layouts/_default/home.settings.html
@@ -0,0 +1,32 @@
+{{- define "title" -}}Settings &mdash; {{ end -}}
+{{- define "description" -}}A list of all interface settings &mdash; {{ end -}}
+{{- define "styles" -}}
+<style>
+ {{ partial "navigator.css.html" (dict "Link" "/settings/") | safeCSS }}
+</style>
+{{- end -}}
+
+{{- define "header" -}}
+ {{- partial "navigator-middle.html"
+ (dict
+ "Context" .
+ "IconLabel" "Back"
+ "Id" "back"
+ "Title" "Settings"
+ "Icon" "arrow-left"
+ "Subtitle" "Interface"
+ "Href" (or (and (gt .Paginator.PageNumber 1) (.Paginator.Prev.URL | absURL)) "/")
+ )
+ -}}
+{{- end -}}
+
+{{- define "middle" -}}
+{{- end -}}
+
+{{- define "footer" -}}
+ {{- partial "footer.html" . -}}
+{{- end -}}
+
+{{- define "right" -}}
+ {{- partial "navigator-right.html" . -}}
+{{- end -}}
diff --git a/themes/default/layouts/_default/home.sources.html b/themes/default/layouts/_default/home.sources.html
index 4d485e7..42b6cc3 100644
--- a/themes/default/layouts/_default/home.sources.html
+++ b/themes/default/layouts/_default/home.sources.html
@@ -1,48 +1,53 @@
-{{ define "title" }}Sources &mdash; {{ end }}
-{{ define "description" }}This page contains a list of all source files &mdash; {{ end }}
-{{ define "styles" }}
+{{- define "title" -}}Sources &mdash; {{ end -}}
+{{- define "description" -}}A list of all sources &mdash; {{ end -}}
+{{- define "styles" -}}
<style>
- {{ partial "styles-navigator.html" (dict "Link" "/sources/") | safeCSS }}
+ {{ partial "navigator.css.html" (dict "Link" "/sources/") | safeCSS }}
</style>
-{{ end }}
+{{- end -}}
-{{ define "middle" }}
+{{- define "header" -}}
+ {{- $_default := readDir (print "/themes/default/layouts/_default") -}}
+ {{- $_markup := readDir (print "/themes/default/layouts/_default/_markup") -}}
+ {{- $partials := readDir (print "/themes/default/layouts/partials") -}}
+ {{- $shortcodes := readDir (print "/themes/default/layouts/shortcodes") -}}
- {{ $_default := readDir (print "/themes/default/layouts/_default") }}
- {{ $_markup := readDir (print "/themes/default/layouts/_default/_markup") }}
- {{ $partials := readDir (print "/themes/default/layouts/partials") }}
- {{ $shortcodes := readDir (print "/themes/default/layouts/shortcodes") }}
-
- {{ $fileCount := add
+ {{- $fileCount := add
(add
(sub (len $_default) 1)
(len $_markup))
(add
(len $partials)
(len $shortcodes))
- }}
+ -}}
- {{ partial "navigator-middle.html"
+ {{- partial "navigator-middle.html"
(dict
"Title" "Sources"
- "Subtitle" (print $fileCount " " "Files")
+ "Subtitle" (print $fileCount " " "Total")
"Icon" "arrow-left"
"IconLabel" "Back"
"Href" "/"
"Id" "back"
"Context" .
)
- }}
+ -}}
+{{- end -}}
+
+{{- define "middle" -}}
+ {{- $_default := readDir (print "/themes/default/layouts/_default") -}}
+ {{- $_markup := readDir (print "/themes/default/layouts/_default/_markup") -}}
+ {{- $partials := readDir (print "/themes/default/layouts/partials") -}}
+ {{- $shortcodes := readDir (print "/themes/default/layouts/shortcodes") -}}
<source-files>
<item-list>
-
<h1>Defaults</h1>
<ul>
{{ range sort $_default ".ModTime" "desc" }}
{{ if not .IsDir }}
<li>
- <a download title="{{ .Name }}" href="{{ $.Site.BaseURL }}/sources/files/_default/{{ .Name }}">
+ <a download="true" title="{{ .Name }}" href="{{ "" | absURL }}/sources/files/_default/{{ .Name }}">
<span><code>{{- .ModTime | time.Format "2006-01-02 15:04 MST" }}</code></span>
<span><code>{{ .Name }}</code></span>
<span><code>{{ .Size -}}</code></span>
@@ -57,7 +62,7 @@
{{ range sort $_markup ".ModTime" "desc" }}
{{ if not .IsDir }}
<li>
- <a download title="{{ .Name }}" href="{{ $.Site.BaseURL }}/sources/files/_default/_markup/{{ .Name }}">
+ <a download="true" title="{{ .Name }}" href="{{ "" | absURL }}/sources/files/_default/_markup/{{ .Name }}">
<span><code>{{- .ModTime | time.Format "2006-01-02 15:04 MST" }}</code></span>
<span><code>{{ .Name }}</code></span>
<span><code>{{ .Size -}}</code></span>
@@ -72,7 +77,7 @@
{{ range sort $partials ".ModTime" "desc" }}
{{ if not .IsDir }}
<li>
- <a download title="{{ .Name }}" href="{{ $.Site.BaseURL }}/sources/files/partials/{{ .Name }}">
+ <a download="true" title="{{ .Name }}" href="{{ "" | absURL }}/sources/files/partials/{{ .Name }}">
<span><code>{{- .ModTime | time.Format "2006-01-02 15:04 MST" }}</code></span>
<span><code>{{ .Name }}</code></span>
<span><code>{{ .Size -}}</code></span>
@@ -87,7 +92,7 @@
{{ range sort $shortcodes ".ModTime" "desc" }}
{{ if not .IsDir }}
<li>
- <a download title="{{ .Name }}" href="{{ $.Site.BaseURL }}/sources/files/shortcodes/{{ .Name }}">
+ <a download="true" title="{{ .Name }}" href="{{ "" | absURL }}/sources/files/shortcodes/{{ .Name }}">
<span><code>{{- .ModTime | time.Format "2006-01-02 15:04 MST" }}</code></span>
<span><code>{{ .Name }}</code></span>
<span><code>{{ .Size -}}</code></span>
@@ -101,19 +106,17 @@
<footer>
<p>
Canory Version: {{ "{{% version number %}}" | markdownify }}
- &middot; Dictionary Access by Paul Lutus: <a href="https://arachnoid.com/javascript/dictionary_access.js">GPLv2+ License</a>
- &middot; Feather Icons by Cole Bemis: <a href="https://github.com/feathericons/feather/blob/8b5d6802fa8fd1eb3924b465ff718d2fa8d61efe/LICENSE">MIT License</a>
- &middot; Tabler Icons by Paweł Kuna: <a href="https://github.com/tabler/tabler-icons/blob/60f39297d0f785f2e8635faca6857b2260b2d164/LICENSE">MIT License</a>
- &middot; Instant Page by Alexandre Dieulot: <a href="https://github.com/instantpage/instant.page/blob/729e97d5b3245552e41d8f92ed03d08f1d62ea46/LICENSE">MIT License</a>
- &middot; Fixed Search by Heracles Papatheodorou: <a href="https://gist.github.com/Arty2/8b0c43581013753438a3d35c15091a9f#file-license-md">MIT License</a>
- &middot; Fuzzy Sort by Stephen Kamenar: <a href="https://github.com/farzher/fuzzysort/blob/e7f484a124f09bf3cb9a4db366a95457d962dbed/LICENSE">MIT License</a>
+ &middot; Dictionary Access by Paul Lutus: <a href="https://arachnoid.com/javascript/dictionary_access.js">GPLv2+ Licence</a>
+ &middot; Feather Icons by Cole Bemis: <a href="https://github.com/feathericons/feather/blob/8b5d6802fa8fd1eb3924b465ff718d2fa8d61efe/Licence">MIT Licence</a>
+ &middot; Tabler Icons by Paweł Kuna: <a href="https://github.com/tabler/tabler-icons/blob/60f39297d0f785f2e8635faca6857b2260b2d164/Licence">MIT Licence</a>
+ &middot; Instant Page by Alexandre Dieulot: <a href="https://github.com/instantpage/instant.page/blob/729e97d5b3245552e41d8f92ed03d08f1d62ea46/Licence">MIT Licence</a>
+ &middot; Fixed Search by Heracles Papatheodorou: <a href="https://gist.github.com/Arty2/8b0c43581013753438a3d35c15091a9f#file-Licence-md">MIT Licence</a>
+ &middot; Fuzzy Sort by Stephen Kamenar: <a href="https://github.com/farzher/fuzzysort/blob/e7f484a124f09bf3cb9a4db366a95457d962dbed/Licence">MIT Licence</a>
</p>
</footer>
-
</source-files>
+{{- end -}}
-{{ end }}
-
-{{ define "right" }}
+{{- define "right" -}}
{{- partial "navigator-right.html" . -}}
-{{ end }}
+{{- end -}}
diff --git a/themes/default/layouts/_default/home.xslt.rss.xsl b/themes/default/layouts/_default/home.xslt.rss.xsl
index e1299c5..587d119 100644
--- a/themes/default/layouts/_default/home.xslt.rss.xsl
+++ b/themes/default/layouts/_default/home.xslt.rss.xsl
@@ -6,102 +6,98 @@
xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
version="1.1"
>
- <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
+ <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes" />
<xsl:template match="/">
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" xml-data="">
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" data-xml="" data-document="xhtml">
<head>
- {{ printf `<title><xsl:value-of select="/rss/channel/title"/> Web Feed</title>` | safeHTML }}
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
- {{- partial "base-css.html" . -}}
+ {{ printf `<title><xsl:value-of select="/rss/channel/title" /> Web Feed</title>` | safeHTML }}
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
+ {{- partial "head-css.html" . -}}
+ {{- partial "head-js.html" . -}}
</head>
<body>
- <column-left>
- </column-left>
- <column-middle>
- <main>
+ <column-base position="left"></column-base>
+ <column-base position="middle">
<nav>
<icon-button>
- <a onclick="window.history.go(-1); return false;">
+ <a id="back" target="_self">
<xsl:choose>
- <xsl:when test="/rss/channel/atom:link[@rel='previous']/@href">
- <xsl:attribute name="href">
- <xsl:value-of select="/rss/channel/atom:link[@rel='previous']/@href"/>
- </xsl:attribute>
- </xsl:when>
- <xsl:otherwise>
- <xsl:attribute name="href">/</xsl:attribute>
- </xsl:otherwise>
+ <xsl:when test="/rss/channel/atom:link[@rel='previous']/@href">
+ <xsl:attribute name="href">
+ <xsl:value-of select="/rss/channel/atom:link[@rel='previous']/@href" />
+ </xsl:attribute>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:attribute name="href">/</xsl:attribute>
+ </xsl:otherwise>
</xsl:choose>
{{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-left.svg")) }}
<small>Back</small>
</a>
</icon-button>
<section>
- <h2><xsl:value-of select="/rss/channel/title"/>'s Feed</h2>
- <small>Web Feed Preview</small>
+ <h2><xsl:value-of select="/rss/channel/title" />'s Feed</h2>
+ <small>Web Feed Preview</small>
</section>
<xsl:if test="/rss/channel/atom:link[@rel='next']/@href">
- <icon-button>
- <a>
- <xsl:attribute name="href">
- <xsl:value-of select="/rss/channel/atom:link[@rel='next']/@href"/>
- </xsl:attribute>
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-right.svg")) }}
- <small>Next</small>
- </a>
- </icon-button>
+ <icon-button>
+ <a>
+ <xsl:attribute name="href">
+ <xsl:value-of select="/rss/channel/atom:link[@rel='next']/@href" />
+ </xsl:attribute>
+ {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-right.svg")) }}
+ <small>Next</small>
+ </a>
+ </icon-button>
</xsl:if>
{{ if .Site.Menus.main }}
{{ range .Site.Menus.main }}
- <icon-navigator hidden="">
- <icon-button>
+ <icon-navigator hidden="">
+ <icon-button>
<a id="nav-middle-{{ path.Base .Identifier }}" href="{{ .URL | absURL }}">
- {{ with .Identifier }}
- {{ $icon := print (partial "function-paths.html").static "/icons/" . ".svg" }}
- {{ safeHTML (readFile $icon) }}
- {{ end }}
- <small>{{ delimit (first 1 (split .Name " ")) " " }}</small>
+ {{ with .Identifier }}
+ {{ $icon := print (partial "function-paths.html").static "/icons/" . ".svg" }}
+ {{ safeHTML (readFile $icon) }}
+ {{ end }}
+ <small>{{ delimit (first 1 (split .Name " ")) " " }}</small>
</a>
- </icon-button>
- </icon-navigator>
+ </icon-button>
+ </icon-navigator>
{{ end }}
{{ end }}
</nav>
- <navigation-separator><hr hidden=""></hr></navigation-separator>
- <xsl:for-each select="/rss/channel/item">
- <micro-card>
- <micro-summary>
- <micro-thumbnail>
- <figure>
- <a>
- <xsl:attribute name="href"><xsl:value-of select="link"/></xsl:attribute>
- <picture>
- <img>
- <xsl:attribute name="alt"><xsl:value-of select="atom:author/atom:name"/></xsl:attribute>
- <xsl:attribute name="title"><xsl:value-of select="atom:author/atom:name"/></xsl:attribute>
- <xsl:attribute name="src"><xsl:value-of select="atom:author/atom:uri"/></xsl:attribute>
- </img>
- </picture>
- </a>
- </figure>
- </micro-thumbnail>
- <article>
- <h2>
- <a>
- <xsl:attribute name="href"><xsl:value-of select="link" /></xsl:attribute>
- <xsl:value-of select="title" />
- </a>
- </h2>
- <small>Published: <xsl:value-of select="pubDate"/></small>
- </article>
- </micro-summary>
- </micro-card>
- </xsl:for-each>
+ <main>
+ <xsl:for-each select="/rss/channel/item">
+ <micro-card>
+ <header>
+ <figure>
+ <a>
+ <xsl:attribute name="href"><xsl:value-of select="link" /></xsl:attribute>
+ <span>
+ <object>
+ <xsl:attribute name="title"><xsl:value-of select="atom:author/atom:name" /></xsl:attribute>
+ <xsl:attribute name="data"><xsl:value-of select="atom:author/atom:uri" /></xsl:attribute>
+ <xsl:value-of select="substring(atom:author/atom:name, 1, 1)" />
+ </object>
+ </span>
+ </a>
+ </figure>
+ </header>
+ <article>
+ <h2>
+ <a>
+ <xsl:attribute name="href"><xsl:value-of select="link" /></xsl:attribute>
+ <xsl:value-of select="title" />
+ </a>
+ </h2>
+ <small>Published: <xsl:value-of select="pubDate" /></small>
+ </article>
+ </micro-card>
+ </xsl:for-each>
</main>
- </column-middle>
- <column-right>
- </column-right>
+ </column-base>
+ <column-base position="right"></column-base>
</body>
</html>
</xsl:template>
diff --git a/themes/default/layouts/_default/home.xslt.sitemap.xsl b/themes/default/layouts/_default/home.xslt.sitemap.xsl
index ce3fe98..e0be723 100644
--- a/themes/default/layouts/_default/home.xslt.sitemap.xsl
+++ b/themes/default/layouts/_default/home.xslt.sitemap.xsl
@@ -6,48 +6,48 @@
>
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" xml-data="sitemap">
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" data-xml="sitemap" data-document="xhtml">
<head>
<title>{{ $.Site.Title }} Site Map</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
- {{- partial "base-css.html" . -}}
+ {{- partial "head-css.html" . -}}
+ {{- partial "head-js.html" . -}}
</head>
<body>
- <column-left>
- </column-left>
- <column-middle>
- <main>
- <nav>
- <icon-button>
- <a onclick="window.history.go(-1); return false;" href="/">
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-left.svg")) }}
- <small>Back</small>
- </a>
- </icon-button>
- <section>
- <h2>{{ $.Site.Title }} Site Map</h2>
- <small>Site Map Preview</small>
- </section>
- {{ if .Site.Menus.main }}
- {{ range .Site.Menus.main }}
- <icon-navigator hidden="">
- <icon-button>
- <a
- id="nav-middle-{{ path.Base .Identifier }}"
- href="{{ .URL | absURL }}"
- >
- {{ with .Identifier }}
- {{ $icon := print (partial "function-paths.html").static "/icons/" . ".svg" }}
- {{ safeHTML (readFile $icon) }}
- {{ end }}
- <small>{{ delimit (first 1 (split .Name " ")) " " }}</small>
- </a>
- </icon-button>
- </icon-navigator>
- {{ end }}
+ <column-base position="left"></column-base>
+ <column-base position="middle">
+ <nav>
+ <icon-button>
+ <a id="back" target="_self" href="/">
+ {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-left.svg")) }}
+ <small>Back</small>
+ </a>
+ </icon-button>
+ <section>
+ <h2>{{ $.Site.Title }} Site Map</h2>
+ <small>Site Map Preview</small>
+ </section>
+ {{ if .Site.Menus.main }}
+ {{ range .Site.Menus.main }}
+ <icon-navigator hidden="">
+ <icon-button>
+ <a
+ id="nav-middle-{{ path.Base .Identifier }}"
+ href="{{ .URL | absURL }}"
+ >
+ {{ with .Identifier }}
+ {{ $icon := print (partial "function-paths.html").static "/icons/" . ".svg" }}
+ {{ safeHTML (readFile $icon) }}
+ {{ end }}
+ <small>{{ delimit (first 1 (split .Name " ")) " " }}</small>
+ </a>
+ </icon-button>
+ </icon-navigator>
{{ end }}
- </nav>
+ {{ end }}
+ </nav>
+ <main>
<navigation-separator><hr hidden=""></hr></navigation-separator>
<section>
<table>
@@ -69,10 +69,9 @@
<xsl:attribute name="href">
<xsl:value-of select="sitemap:loc" />
</xsl:attribute>
- <xsl:attribute name="title">
- Last Modified: <xsl:value-of select="sitemap:lastmod" />
- Frequency: <xsl:value-of select="sitemap:changefreq" />
- Priority: <xsl:value-of select="sitemap:priority" />
+<xsl:attribute name="title">Last Modified: <xsl:value-of select="sitemap:lastmod" />
+Frequency: <xsl:value-of select="sitemap:changefreq" />
+Priority: <xsl:value-of select="sitemap:priority" />
</xsl:attribute>
<xsl:value-of select="sitemap:loc" />
</a>
@@ -83,9 +82,8 @@
</table>
</section>
</main>
- </column-middle>
- <column-right>
- </column-right>
+ </column-base>
+ <column-base position="right"></column-base>
</body>
</html>
</xsl:template>
diff --git a/themes/default/layouts/_default/index.html b/themes/default/layouts/_default/index.html
index 37c9855..f25cabf 100644
--- a/themes/default/layouts/_default/index.html
+++ b/themes/default/layouts/_default/index.html
@@ -1,51 +1,34 @@
-{{ define "styles" }}
+{{- define "styles" -}}
<style>
- {{ partial "styles-navigator.html" (dict "Link" "/") | safeCSS }}
+ {{ partial "navigator.css.html" (dict "Link" "/") | safeCSS }}
</style>
-{{ end }}
-
-{{ define "middle" }}
-
- {{- if gt .Paginator.PageNumber 1 -}}
- {{- partial "navigator-middle.html"
- (dict
- "Context" .
- "Href" "/"
- "Icon" "arrow-left"
- "IconLabel" "Back"
- "Id" "back"
- "Title" "Home"
- "Subtitle" (partial "count-total-messages.html" .)
- )
- -}}
- {{- else -}}
- {{- partial "navigator-middle.html"
- (dict
- "Context" .
- "Subtitle" (partial "count-total-messages.html" .)
- "Title" "Home"
- )
- -}}
+{{- end -}}
+
+{{- define "header" -}}
+ {{- partial "navigator-middle.html"
+ (dict
+ "Context" .
+ "Title" "Home"
+ "Subtitle" (print (partial "count.html" .) " " "Total")
+ "IconLabel" (and (gt .Paginator.PageNumber 1) "Back")
+ "Id" (and (gt .Paginator.PageNumber 1) "back")
+ "Icon" (and (gt .Paginator.PageNumber 1) "arrow-left")
+ "Href" (and (gt .Paginator.PageNumber 1) (.Paginator.Prev.URL | absURL))
+ )
+ -}}
+{{- end -}}
+
+{{- define "middle" -}}
+ {{- range .Paginator.Pages -}}
+ {{- partial "render-embed.html" . -}}
{{- end -}}
+{{- end -}}
- {{ range .Paginator.Pages }}
- {{ .Render "summary" }}
- {{ end }}
-
- {{ partial "pagination.html" . }}
-
-{{ end }}
-
-{{ define "right" }}
- {{- partial "author-list.html" . -}}
-
- {{ range first 1 (where .Site.Pages "Params.Author" .Site.Author.default.gallery) }}
- {{- partial "gallery.html" . -}}
- {{ end }}
-
- {{ range first 1 (where .Site.Pages "Params.Author" .Site.Author.default.webring) }}
- {{- partial "following-list.html" . -}}
- {{- partial "webring.html" . -}}
- {{ end }}
+{{- define "footer" -}}
+ {{- partial "pagination.html" . -}}
+ {{- partial "footer.html" . -}}
+{{- end -}}
-{{ end }}
+{{- define "right" -}}
+ {{- partial "navigator-right.html" . -}}
+{{- end -}}
diff --git a/themes/default/layouts/_default/index.json b/themes/default/layouts/_default/index.json
index b9d9068..9484e60 100644
--- a/themes/default/layouts/_default/index.json
+++ b/themes/default/layouts/_default/index.json
@@ -15,8 +15,8 @@
{
"id": "{{ sha256 $data.Permalink }}",
"url": "{{ $data.Permalink }}",
- "title": "{{ $data.Summary | htmlUnescape }}",
- "summary": "{{ $data.Summary | htmlUnescape }}",
+ "title": {{ $data.Summary | htmlUnescape | jsonify }},
+ "summary": {{ $data.Summary | htmlUnescape | jsonify }},
"date_modified": "{{ $data.Date | time.Format "2006-01-02T15:04:05Z" }}",
"date_published": "{{ $data.PublishDate | time.Format "2006-01-02T15:04:05Z" }}",
"_metadata": {
diff --git a/themes/default/layouts/_default/index.webmanifest b/themes/default/layouts/_default/index.webmanifest
deleted file mode 100644
index f7b3f66..0000000
--- a/themes/default/layouts/_default/index.webmanifest
+++ /dev/null
@@ -1,24 +0,0 @@
-{{- $icon := resources.Get .Site.Params.webmanifest.logo -}}
-
-{{- $androidChrome192 := $icon.Fit "192x192" -}}
-{{- $androidChrome512 := $icon.Fit "512x512" -}}
-
-{
- "name": "{{ .Site.Params.webmanifest.name }}",
- "short_name": "{{ .Site.Params.webmanifest.shortName }}",
- "icons": [
- {
- "src": "{{ $androidChrome192.Permalink }}",
- "sizes": "192x192",
- "type": "image/png"
- },
- {
- "src": "{{ $androidChrome512.Permalink }}",
- "sizes": "512x512",
- "type": "image/png"
- }
- ],
- "theme_color": "{{ .Site.Params.webmanifest.themeColor }}",
- "background_color": "{{ .Site.Params.webmanifest.backgroundColor }}",
- "display": "{{ .Site.Params.webmanifest.display }}"
-}
diff --git a/themes/default/layouts/_default/rss.xml b/themes/default/layouts/_default/rss.xml
index 3e8e337..16aee5f 100644
--- a/themes/default/layouts/_default/rss.xml
+++ b/themes/default/layouts/_default/rss.xml
@@ -1,24 +1,28 @@
{{- define "main" -}}
+{{- $absURL := "" | absURL -}}
+
{{- $limit := .Site.Config.Services.RSS.Limit -}}
{{- if lt $limit 1 -}}
{{- $limit = .Paginator.TotalNumberOfElements -}}
{{- end -}}
-{{- $lastBuildDate := now.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML -}}
+{{- $lastBuildDate := now | time.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML -}}
{{- if not .Date.IsZero -}}
- {{- $lastBuildDate = .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML -}}
+ {{- $lastBuildDate = .Date | time.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML -}}
{{- end -}}
-{{- $title := partial "base-title.html" . -}}
-{{- $description := partial "base-title.html" . -}}
+{{- $title := partial "head-title.html" . -}}
+{{- $description := partial "head-title.html" . -}}
{{- $author := partial "function-authors-data.html" . -}}
+{{- $image := print "/favicon.ico" -}}
{{- if (eq .Page.Kind "section") -}}
{{- $title = $author.name -}}
{{- $description = $author.description | markdownify | html | htmlUnescape -}}
+ {{- $image = print "/" (partial "function-paths.html").media "/" .Section "/" .Section "-profile" (path.Ext $author.picture.profile) -}}
{{- end -}}
{{- if (eq .Page.Type "tags") -}}
@@ -26,14 +30,6 @@
{{- $description = print .Site.Title " Tags: #" .Title -}}
{{- end -}}
-{{- $image := print "/" (partial "function-paths.html").media
- "/" $author.user "/" $author.user "-profile" (path.Ext $author.picture.profile)
--}}
-
-{{- if not (fileExists (print "public/" $image)) -}}
- {{- $image = "/data/media/404.png" -}}
-{{- end -}}
-
{{- $atomSelf := "" -}}
{{- $atomPrevious := "" -}}
{{- $atomNext := "" -}}
@@ -42,11 +38,11 @@
{{- $atomSelf = printf `<atom:link rel="self" href=%q type=%q />` .Permalink .MediaType | safeHTML -}}
{{- with $.Paginator.Prev -}}
- {{- $atomPrevious = printf `<atom:link rel="previous" href=%q />` .URL | safeHTML -}}
+ {{- $atomPrevious = printf `<atom:link rel="previous" href=%q />` (.URL | absURL) | safeHTML -}}
{{- end -}}
{{- with $.Paginator.Next -}}
- {{- $atomNext = printf `<atom:link rel="next" href=%q />` .URL | safeHTML -}}
+ {{- $atomNext = printf `<atom:link rel="next" href=%q />` (.URL | absURL) | safeHTML -}}
{{- end -}}
{{- end -}}
@@ -60,16 +56,16 @@
xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
- <title>{{ $title }}</title>
+ <title>{{ or $title (title .Section) }}</title>
<link>{{ .Permalink }}</link>
<description>{{ $description }}</description>
<language>{{ .Site.LanguageCode }}</language>
- <category>{{ $author.user }}</category>
+ <category>{{ or $author.user "default" }}</category>
<generator>Hugo {{ hugo.Version }}</generator>
<lastBuildDate>{{ $lastBuildDate }}</lastBuildDate>
<image>
<title>{{ $title }}</title>
- <url>{{ .Site.BaseURL }}{{ $image }}</url>
+ <url>{{ $absURL }}{{ $image }}</url>
<link>{{ .Permalink }}</link>
</image>
@@ -85,30 +81,24 @@
"/" $author.user "/" $author.user "-profile" (path.Ext $author.picture.profile)
-}}
- {{- if not (fileExists (print "public/" $image)) -}}
- {{- $image = "/data/media/404.png" -}}
- {{- end -}}
-
- {{- $atomAuthorUri := print .Site.BaseURL $image -}}
+ {{- $atomAuthorUri := print $absURL $image -}}
{{- $atomAuthorName := or .Params.Feed.name $author.name -}}
{{- if .Params.Feed.favicon -}}
{{- $favicon := print "/" (partial "function-paths.html").media "/favicon." (.Params.Feed.source | anchorize) ".png" -}}
- {{- if not (fileExists (print "public/" $favicon)) -}}
- {{- $favicon = "/data/media/404.png" -}}
- {{- end -}}
- {{- $atomAuthorUri = print .Site.BaseURL $favicon -}}
+ {{- $atomAuthorUri = print $absURL $favicon -}}
{{- end -}}
<item>
<title>{{ (or .Summary .Title) | htmlUnescape }}</title>
- <link>{{ .Permalink }}</link>
- <pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
+ <link>{{ or .Params.Feed.link .Permalink }}</link>
+ <pubDate>{{ .Date | time.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
<guid>{{ .Permalink }}</guid>
<description>
- {{- partial "function-content.html" . | html -}}
- {{- print "<br>" | html -}}
- {{- partial "rss-tags.html" . | html -}}
+ {{ partial "function-content.html" . | html -}}
+ {{- print "<br /><br />" | html -}}
+ {{- printf `<a href=%q>Permalink</a>&nbsp;` .Permalink | html }}
+ {{ partial "tags.html" (dict "Format" "rss" "Context" .) | html }}
</description>
<atom:author>
<atom:name>{{ $atomAuthorName }}</atom:name>
@@ -119,5 +109,4 @@
{{ end -}}
</channel>
</rss>
-
{{- end -}}
diff --git a/themes/default/layouts/_default/section.drafts.html b/themes/default/layouts/_default/section.drafts.html
index ad862c4..bb7485c 100644
--- a/themes/default/layouts/_default/section.drafts.html
+++ b/themes/default/layouts/_default/section.drafts.html
@@ -1,56 +1,58 @@
-{{ define "styles" }}
+{{- define "styles" -}}
{{- $author := partial "function-authors-data.html" . -}}
{{- $author = $author.user -}}
<style>
- {{ partial "styles-navigator.html" (dict "Link" "/") | safeCSS }}
+ {{ partial "navigator.css.html" (dict "Link" "/") | safeCSS }}
- tab-bar a[href="{{ .Site.BaseURL }}/{{ $author }}/drafts/"] {
+ tab-bar a[href^="{{ "" | absURL }}/{{ $author }}/drafts"] {
color: #111;
color: var(--foreground);
- display: inherit;
font-weight: 700;
text-decoration-color: #014cc6;
text-decoration-color: var(--link);
text-decoration: underline;
+ border-bottom: 2px solid var(--background);
}
</style>
-{{ end }}
+{{- end -}}
-{{ define "middle" }}
+{{- define "header" -}}
+ {{- $author := partial "function-authors-data.html" . -}}
+ {{- $authors := where .Site.RegularPages "Section" $author.user -}}
+ {{- $drafts := where .Site.RegularPages "Draft" true -}}
+ {{- $filteredPages := $authors | intersect $drafts -}}
+ {{- $paginator := .Paginate $filteredPages -}}
- {{ partial "navigator-middle.html"
+ {{- partial "navigator-middle.html"
(dict
- "Title" "Drafts"
- "Subtitle" (partial "count-drafts.html" .)
- "Icon" "arrow-left"
+ "Context" .
"IconLabel" "Back"
- "Href" "/"
"Id" "back"
- "Context" .
+ "Title" "Drafts"
+ "Icon" "arrow-left"
+ "Subtitle" (print (partial "count-drafts.html" .) " " "Total")
+ "Href" (or (and (gt $paginator.PageNumber 1) ($paginator.Paginator.Prev.URL | absURL)) "/")
)
- }}
-
- {{ partial "profile.html" . }}
+ -}}
- {{- $author := partial "function-authors-data.html" . -}}
- {{- $author = $author.user -}}
- {{- $users := where .Site.RegularPages "Section" $author -}}
- {{- $drafts := where .Site.RegularPages "Draft" true -}}
- {{- $filteredPages := $users | intersect $drafts -}}
- {{- $paginator := .Paginate $filteredPages }}
+ {{- partial "profile.html" . -}}
+{{- end -}}
- {{ range $paginator.Pages }}
- {{ .Render "summary" }}
- {{ else }}
+{{- define "middle" -}}
+ {{- range .Paginator.Pages -}}
+ {{- partial "render-embed.html" . -}}
+ {{- else -}}
<footer>
- <code>No drafts found!</code>
+ <code>No items found!</code>
</footer>
- {{ end }}
-
- {{ partial "pagination.html" . }}
+ {{- end -}}
+{{- end -}}
-{{ end }}
+{{- define "footer" -}}
+ {{- partial "pagination.html" . -}}
+ {{- partial "footer.html" . -}}
+{{- end -}}
-{{ define "right" }}
+{{- define "right" -}}
{{- partial "navigator-right.html" . -}}
-{{ end }}
+{{- end -}}
diff --git a/themes/default/layouts/_default/section.feeds.html b/themes/default/layouts/_default/section.feeds.html
index 20566df..e239928 100644
--- a/themes/default/layouts/_default/section.feeds.html
+++ b/themes/default/layouts/_default/section.feeds.html
@@ -1,51 +1,53 @@
-{{ define "styles" }}
+{{- define "styles" -}}
{{- $author := partial "function-authors-data.html" . -}}
{{- $author = $author.user -}}
<style>
- {{ partial "styles-navigator.html" (dict "Link" "/") | safeCSS }}
+ {{ partial "navigator.css.html" (dict "Link" "/") | safeCSS }}
- tab-bar a[href="{{ .Site.BaseURL }}/{{ $author }}/feeds/"] {
+ tab-bar a[href^="{{ "" | absURL }}/{{ $author }}/feeds"] {
color: #111;
color: var(--foreground);
- display: inherit;
font-weight: 700;
text-decoration-color: #014cc6;
text-decoration-color: var(--link);
text-decoration: underline;
+ border-bottom: 2px solid var(--background);
}
</style>
-{{ end }}
+{{- end -}}
-{{ define "middle" }}
-
- {{ partial "navigator-middle.html"
+{{- define "header" -}}
+ {{- partial "navigator-middle.html"
(dict
- "Title" "Feeds"
- "Subtitle" (partial "count-feeds.html" .)
- "Icon" "arrow-left"
+ "Context" .
"IconLabel" "Back"
- "Href" "/"
"Id" "back"
- "Context" .
+ "Title" "Feeds"
+ "Icon" "arrow-left"
+ "Subtitle" (print (partial "count-feeds.html" .) " " "Total")
+ "Href" (or (and (gt .Paginator.PageNumber 1) (.Paginator.Prev.URL | absURL)) "/")
)
- }}
+ -}}
- {{ partial "profile.html" . }}
+ {{- partial "profile.html" . -}}
+{{- end -}}
- {{ range .Paginator.Pages }}
- {{ .Render "summary" }}
- {{ else }}
+{{- define "middle" -}}
+ {{- range .Paginator.Pages -}}
+ {{- partial "render-embed.html" . -}}
+ {{- else -}}
<footer>
- <code>No feeds found!</code>
+ <code>No items found!</code>
</footer>
- {{ end }}
-
- {{ partial "pagination.html" . }}
-
- {{ $writeToFile := partial "function-generate-feeds" . }}
+ {{- end -}}
+ {{- $writeToFile := partial "function-generate-feeds" . -}}
+{{- end -}}
-{{ end }}
+{{- define "footer" -}}
+ {{- partial "pagination.html" . -}}
+ {{- partial "footer.html" . -}}
+{{- end -}}
-{{ define "right" }}
+{{- define "right" -}}
{{- partial "navigator-right.html" . -}}
-{{ end }}
+{{- end -}}
diff --git a/themes/default/layouts/_default/section.following.html b/themes/default/layouts/_default/section.following.html
index 48afa7d..2bfcc2e 100644
--- a/themes/default/layouts/_default/section.following.html
+++ b/themes/default/layouts/_default/section.following.html
@@ -1,23 +1,32 @@
-{{- $sources := slice -}}
-{{- $author := partial "function-authors-data.html" . -}}
-{{- $feeds := partial "function-generate-feeds.html" . -}}
+{{- $parent := eq (len .Page.Ancestors) 1 -}}
-{{- range $author.feeds.rss -}}
- {{- $data := split . " " -}}
- {{- $url := delimit (first 1 $data) "" -}}
- {{- $sources = $sources | append (string $url) -}}
-{{- end -}}
+{{- $modified := partial "function-page-modified.html"
+ (dict
+ "Context" .
+ "Disable" true
+ )
+-}}
+
+{{- if (and $parent $modified) -}}
+ {{- $sources := slice -}}
+ {{- $author := partial "function-authors-data.html" . -}}
+ {{- $feeds := partial "function-generate-feeds.html" . -}}
+
+ {{- range $author.feeds.rss -}}
+ {{- $data := split . " " -}}
+ {{- $url := delimit (first 1 $data) "" -}}
+ {{- $sources = $sources | append (string $url) -}}
+ {{- end -}}
-{{- range $source := (first 3 (shuffle $sources)) -}}
- {{- range $distinct := first 1 (where $feeds "FeedSourceLink" "eq" $source) -}}
+ {{- range $source := $sources -}}
+ {{- range $distinct := first 1 (where $feeds "FeedSourceLink" "eq" $source) -}}
- {{- $href := or $distinct.FeedHome (print "http://" $distinct.FeedSourceDomain) -}}
- {{- $favicon := print "/" (partial "function-paths.html").media "/favicon." (.FeedSourceLink | anchorize) ".png" -}}
+ {{- $href := or $distinct.FeedHome (print "http://" $distinct.FeedSourceDomain) -}}
+ {{- $favicon := print "/" (partial "function-paths.html").media "/favicon." (.FeedSourceLink | anchorize) ".png" -}}
- <micro-author>
- <micro-card>
- <micro-summary>
- <micro-thumbnail>
+ <micro-author>
+ <micro-card>
+ <header>
<figure>
<a
title="{{ $distinct.FeedName }}"
@@ -32,8 +41,8 @@
</picture>
</a>
</figure>
- </micro-thumbnail>
- <micro-header>
+ </header>
+ <article>
<h2>
<b>{{ $distinct.FeedName }}</b>
</h2>
@@ -46,20 +55,21 @@
</a>
</h3>
<time
+ data-type="default"
title="{{ $distinct.FeedDateTitle }}"
datetime="{{ $distinct.FeedDateTime }}">
- {{ $distinct.FeedDateTime | time.Format "15:04 Jan 2 2006" -}}
+ {{ $distinct.FeedDate -}}
</time>
- </micro-header>
+ </article>
<a
title="Follow {{ $distinct.FeedName }}"
href="{{ $href }}">
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/rss.svg")) }}
- <span>Follow</span>
+ {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/tabler/rss.svg")) }}
+ <span>Feed</span>
</a>
- </micro-summary>
- </micro-card>
- </micro-author>
+ </micro-card>
+ </micro-author>
+ {{- end -}}
{{- end -}}
{{- end -}}
diff --git a/themes/default/layouts/_default/section.gallery.html b/themes/default/layouts/_default/section.gallery.html
index dfa141e..761a276 100644
--- a/themes/default/layouts/_default/section.gallery.html
+++ b/themes/default/layouts/_default/section.gallery.html
@@ -1 +1,12 @@
-{{- partial "gallery-walk.html" . -}}
+{{- $parent := eq (len .Page.Ancestors) 1 -}}
+
+{{- $modified := partial "function-page-modified.html"
+ (dict
+ "Context" .
+ "Disable" true
+ )
+-}}
+
+{{- if (and $parent $modified) -}}
+ {{- partial "gallery-walk.html" . -}}
+{{- end -}}
diff --git a/themes/default/layouts/_default/section.html b/themes/default/layouts/_default/section.html
index 9d32210..901ca1f 100644
--- a/themes/default/layouts/_default/section.html
+++ b/themes/default/layouts/_default/section.html
@@ -1,58 +1,56 @@
-{{ define "styles" }}
+{{- define "styles" -}}
<style>
- {{ partial "styles-navigator.html" (dict "Link" "/") | safeCSS }}
+ {{ partial "navigator.css.html" (dict "Link" "/") | safeCSS }}
tab-bar a[href="{{ .CurrentSection.Permalink }}"],
+ tab-bar a[href^="{{ .CurrentSection.Permalink }}#"],
tab-bar a[href="{{ strings.TrimRight "/" .CurrentSection.Permalink }}"] {
color: #111;
color: var(--foreground);
- display: inherit;
font-weight: 700;
text-decoration-color: #014cc6;
text-decoration-color: var(--link);
text-decoration: underline;
+ border-bottom: 2px solid var(--background);
}
</style>
-{{ end }}
-
-{{ define "middle" }}
-
- {{- $messages := print
- (lang.FormatNumberCustom 0 .Paginator.TotalNumberOfElements)
- " "
- "Messages"
- -}}
+{{- end -}}
+{{- define "header" -}}
{{- $author := partial "function-authors-data.html" . -}}
- {{ partial "navigator-middle.html"
+ {{- partial "navigator-middle.html"
(dict
- "Title" $author.name
- "Subtitle" $messages
- "Icon" "arrow-left"
+ "Context" .
"IconLabel" "Back"
- "Href" "/"
"Id" "back"
- "Context" .
+ "Title" $author.name
+ "Icon" "arrow-left"
+ "Href" (or (and (gt .Paginator.PageNumber 1) (.Paginator.Prev.URL | absURL)) "/")
+ "Subtitle" (print (lang.FormatNumberCustom 0 .Paginator.TotalNumberOfElements) " " "Total")
)
- }}
+ -}}
- {{ partial "author-section-picture.html" . }}
+ {{- partial "author-section-picture.html" . -}}
- {{ partial "profile.html" . }}
+ {{- partial "profile.html" . -}}
+{{- end -}}
- {{ range .Paginator.Pages }}
- {{ .Render "summary" }}
- {{ else }}
+{{- define "middle" -}}
+ {{- range .Paginator.Pages -}}
+ {{- partial "render-embed.html" . -}}
+ {{- else -}}
<footer>
- <code>No messages found!</code>
+ <code>No items found!</code>
</footer>
- {{ end }}
-
- {{ partial "pagination.html" . }}
+ {{- end -}}
+{{- end -}}
-{{ end }}
+{{- define "footer" -}}
+ {{- partial "pagination.html" . -}}
+ {{- partial "footer.html" . -}}
+{{- end -}}
-{{ define "right" }}
+{{- define "right" -}}
{{- partial "navigator-right.html" . -}}
-{{ end }}
+{{- end -}}
diff --git a/themes/default/layouts/_default/section.likes.html b/themes/default/layouts/_default/section.likes.html
deleted file mode 100644
index 650c326..0000000
--- a/themes/default/layouts/_default/section.likes.html
+++ /dev/null
@@ -1,56 +0,0 @@
-{{ define "styles" }}
-{{- $author := partial "function-authors-data.html" . -}}
-{{- $author = $author.user -}}
-<style>
- {{ partial "styles-navigator.html" (dict "Link" "/") | safeCSS }}
-
- tab-bar a[href="{{ .Site.BaseURL }}/{{ $author }}/likes/"] {
- color: #111;
- color: var(--foreground);
- display: inherit;
- font-weight: 700;
- text-decoration-color: #014cc6;
- text-decoration-color: var(--link);
- text-decoration: underline;
- }
-</style>
-{{ end }}
-
-{{ define "middle" }}
-
- {{ partial "navigator-middle.html"
- (dict
- "Title" "Likes"
- "Subtitle" (partial "count-likes.html" .)
- "Icon" "arrow-left"
- "IconLabel" "Back"
- "Href" "/"
- "Id" "back"
- "Context" .
- )
- }}
-
- {{ partial "profile.html" . }}
-
- {{- $author := partial "function-authors-data.html" . -}}
- {{- $author = $author.user -}}
- {{- $users := where .Site.RegularPages "Section" $author -}}
- {{- $likes := where .Site.RegularPages ".Params.liked" true -}}
- {{- $filteredPages := $users | intersect $likes -}}
- {{- $paginator := .Paginate $filteredPages }}
-
- {{ range $paginator.Pages }}
- {{ .Render "summary" }}
- {{ else }}
- <footer>
- <code>No likes found!</code>
- </footer>
- {{ end }}
-
- {{ partial "pagination.html" . }}
-
-{{ end }}
-
-{{ define "right" }}
- {{- partial "navigator-right.html" . -}}
-{{ end }}
diff --git a/themes/default/layouts/_default/section.marks.html b/themes/default/layouts/_default/section.marks.html
new file mode 100644
index 0000000..def6c94
--- /dev/null
+++ b/themes/default/layouts/_default/section.marks.html
@@ -0,0 +1,58 @@
+{{- define "styles" -}}
+{{- $author := partial "function-authors-data.html" . -}}
+{{- $author = $author.user -}}
+<style>
+ {{ partial "navigator.css.html" (dict "Link" "/") | safeCSS }}
+
+ tab-bar a[href^="{{ "" | absURL }}/{{ $author }}/marks"] {
+ color: #111;
+ color: var(--foreground);
+ font-weight: 700;
+ text-decoration-color: #014cc6;
+ text-decoration-color: var(--link);
+ text-decoration: underline;
+ border-bottom: 2px solid var(--background);
+ }
+</style>
+{{- end -}}
+
+{{- define "header" -}}
+ {{- $author := partial "function-authors-data.html" . -}}
+ {{- $authors := where .Site.RegularPages "Section" $author.user -}}
+ {{- $items := where .Site.RegularPages ".Params.marked" true -}}
+ {{- $filteredPages := $authors | intersect $items -}}
+ {{- $paginator := .Paginate $filteredPages -}}
+
+ {{- partial "navigator-middle.html"
+ (dict
+ "Context" .
+ "IconLabel" "Back"
+ "Id" "back"
+ "Title" "Marks"
+ "Icon" "arrow-left"
+ "Subtitle" (print (partial "count-marks.html" .) " " "Total")
+ "Href" (or (and (gt $paginator.PageNumber 1) ($paginator.Prev.URL | absURL)) "/")
+ )
+ -}}
+
+ {{- partial "profile.html" . -}}
+{{- end -}}
+
+{{- define "middle" -}}
+ {{- range .Paginator.Pages -}}
+ {{- partial "render-embed.html" . -}}
+ {{- else -}}
+ <footer>
+ <code>No items found!</code>
+ </footer>
+ {{- end -}}
+{{- end -}}
+
+{{- define "footer" -}}
+ {{- partial "pagination.html" . -}}
+ {{- partial "footer.html" . -}}
+{{- end -}}
+
+{{- define "right" -}}
+ {{- partial "navigator-right.html" . -}}
+{{- end -}}
diff --git a/themes/default/layouts/_default/section.media.html b/themes/default/layouts/_default/section.media.html
index 9191a3e..ce570c7 100644
--- a/themes/default/layouts/_default/section.media.html
+++ b/themes/default/layouts/_default/section.media.html
@@ -1,70 +1,65 @@
-{{ define "styles" }}
+{{- define "styles" -}}
{{- $author := partial "function-authors-data.html" . -}}
{{- $author = $author.user -}}
<style>
- {{ partial "styles-navigator.html" (dict "Link" "/") | safeCSS }}
+ {{ partial "navigator.css.html" (dict "Link" "/") | safeCSS }}
- tab-bar a[href="{{ .Site.BaseURL }}/{{ $author }}/media/"] {
+ tab-bar a[href^="{{ "" | absURL }}/{{ $author }}/media"] {
color: #111;
color: var(--foreground);
- display: inherit;
font-weight: 700;
text-decoration-color: #014cc6;
text-decoration-color: var(--link);
text-decoration: underline;
+ border-bottom: 2px solid var(--background);
}
</style>
-{{ end }}
+{{- end -}}
-{{ define "middle" }}
-
- {{ partial "navigator-middle.html"
+{{- define "header" -}}
+ {{- partial "navigator-middle.html"
(dict
"Title" "Media"
- "Subtitle" (partial "count-media.html" .)
+ "Subtitle" (print (partial "count-media.html" .) " " "Total")
"Icon" "arrow-left"
"IconLabel" "Back"
"Href" "/"
"Id" "back"
"Context" .
)
- }}
+ -}}
- {{ partial "profile.html" . }}
+ {{- partial "profile.html" . -}}
+{{- end -}}
+{{- define "middle" -}}
{{- $author := partial "function-authors-data.html" . -}}
- {{- $author = $author.user -}}
-
- {{ $count := 0 }}
- {{ $result := false }}
+ {{- $notFeeds := where .Site.RegularPages "Params.feed" "eq" nil -}}
+ {{- $authors := where .Site.RegularPages "Section" $author.user -}}
+ {{- $filteredPages := $authors | intersect $notFeeds -}}
+ {{- $count := 0 -}}
- {{ range .Site.RegularPages }}
- {{ if or
- (in .Content "<figure>")
- (in .Content "<imgur-video>")
- (in .Content "<youtube-video>")
- (in .Content "<video-container>")
- }}
- {{ if eq .Type $author }}
- {{ $result = true }}
- {{ $count = add $count 1 }}
- {{ if le $count 10 }}
- {{ .Render "summary" }}
- {{ end }}
- {{ end }}
- {{ end }}
- {{ end }}
+ {{- range first 100 $filteredPages -}}
+ {{- if eq $count 10 -}}
+ {{- break -}}
+ {{- end -}}
+ {{- if or
+ (in .Content "</video>")
+ (in .Content "</picture>")
+ (in .Content "</youtube-video>")
+ -}}
+ {{- partial "render-embed.html" . -}}
+ {{- $count = add $count 1 -}}
+ {{- end -}}
+ {{- end -}}
- {{ if not $result }}
+ {{- if not $count -}}
<footer>
- <code>No media found!</code>
+ <code>No items found!</code>
</footer>
- {{ end }}
-
- {{ partial "pagination.html" . }}
-
-{{ end }}
+ {{- end -}}
+{{- end -}}
-{{ define "right" }}
+{{- define "right" -}}
{{- partial "navigator-right.html" . -}}
-{{ end }}
+{{- end -}}
diff --git a/themes/default/layouts/_default/section.webring.html b/themes/default/layouts/_default/section.webring.html
index 59b26ba..58181e1 100644
--- a/themes/default/layouts/_default/section.webring.html
+++ b/themes/default/layouts/_default/section.webring.html
@@ -1,57 +1,66 @@
-{{- $items := slice -}}
-{{- $sources := slice -}}
-{{- $author := partial "function-authors-data.html" . -}}
-{{- $feeds := partial "function-generate-feeds.html" . -}}
+{{- $parent := eq (len .Page.Ancestors) 1 -}}
-{{- range $author.feeds.rss -}}
- {{- $data := split . " " -}}
- {{- $url := delimit (first 1 $data) "" -}}
- {{- $sources = $sources | append (string $url) -}}
-{{- end -}}
-
-{{- $inner := 1 -}}
+{{- $modified := partial "function-page-modified.html"
+ (dict
+ "Context" .
+ "Disable" true
+ )
+-}}
-{{- if eq (len $sources) 1 -}}
- {{- $inner = 3 -}}
-{{- end -}}
+{{- if (and $parent $modified) -}}
+ {{- $items := slice -}}
+ {{- $sources := slice -}}
+ {{- $author := partial "function-authors-data.html" . -}}
+ {{- $feeds := partial "function-generate-feeds.html" . -}}
-{{- range $source := (first 3 $sources) -}}
- {{- range $distinct := first $inner (where $feeds "FeedSourceLink" "eq" $source) -}}
- {{- $items = $items | append $distinct -}}
+ {{- range $author.feeds.rss -}}
+ {{- $data := split . " " -}}
+ {{- $url := delimit (first 1 $data) "" -}}
+ {{- $sources = $sources | append (string $url) -}}
{{- end -}}
-{{- end -}}
-{{- range (sort $items "FeedDateTime" "desc") -}}
+ {{- $inner := 1 -}}
- <web-ring-item>
- <header>
- <a
- data-hover
- title="{{ .FeedLink }}"
- href="{{ .FeedLink }}">
- {{ or .FeedTitle (truncate 50 "..." (or .FeedContentShort .FeedDescriptionShort)) }}
- </a>
- </header>
- <time
- title="{{ .FeedDateTitle }}"
- datetime="{{ .FeedDateTime }}">
- {{ .FeedDate }}
- </time>
- <p>
- {{ "--" | markdownify }}
- {{ if gt (len .FeedDescriptionShort) (len .FeedContentShort) -}}
- {{ or .FeedDescriptionShort .FeedTitle }}
- {{- else -}}
- {{ or .FeedContentShort .FeedTitle }}
- {{- end }}
- &mdash;
- </p>
- <a
- data-hover
- title="{{ .FeedSourceDescription }}"
- href="{{ or .FeedSourceHome .FeedSourceLink }}">
- {{ .FeedSourceTitle }}
- </a>
- </web-ring-item>
+ {{- if eq (len $sources) 1 -}}
+ {{- $inner = 3 -}}
+ {{- end -}}
+
+ {{- range $source := (first 3 $sources) -}}
+ {{- range $distinct := first $inner (where $feeds "FeedSourceLink" "eq" $source) -}}
+ {{- $items = $items | append $distinct -}}
+ {{- end -}}
+ {{- end -}}
+ {{- range (sort $items "FeedDateTime" "desc") -}}
+ <article>
+ <h2>
+ <a
+ data-hover
+ title="{{ .FeedLink }}"
+ href="{{ .FeedLink }}">
+ {{ or .FeedTitle (truncate 50 "..." (or .FeedContentShort .FeedDescriptionShort)) }}
+ </a>
+ </h2>
+ <p>
+ {{ if gt (len .FeedDescriptionShort) (len .FeedContentShort) -}}
+ {{ or .FeedDescriptionShort .FeedTitle }}
+ {{- else -}}
+ {{ or .FeedContentShort .FeedTitle }}
+ {{- end }}
+ <br />
+ <a
+ data-hover
+ title="{{ .FeedSourceDescription }}"
+ href="{{ or .FeedSourceHome .FeedSourceLink }}">
+ {{ .FeedSourceTitle }}
+ </a>
+ </p>
+ <time
+ data-type="default"
+ title="{{ .FeedDateTitle }}"
+ datetime="{{ .FeedDateTime }}">
+ {{ .FeedDate }}
+ </time>
+ </article>
+ {{- end -}}
{{- end -}}
diff --git a/themes/default/layouts/_default/single.embed.html b/themes/default/layouts/_default/single.embed.html
new file mode 100644
index 0000000..73a3add
--- /dev/null
+++ b/themes/default/layouts/_default/single.embed.html
@@ -0,0 +1,26 @@
+{{- $pageContext := . -}}
+{{- $format := "embed.html" -}}
+
+{{- $page := print "public/" (strings.TrimPrefix
+ $pageContext.Page.Site.BaseURL
+ $pageContext.Page.Permalink
+ ) $format
+-}}
+
+{{- $modified := partial "function-page-modified.html"
+ (dict
+ "Context" $pageContext
+ "Format" $format
+ )
+-}}
+
+{{- with $embed := resources.Get $page -}}
+ {{- if (in $embed.Content "/data/media/404.png") -}}
+ {{- $modified = true -}}
+ {{- end -}}
+{{- end -}}
+
+{{- if $modified -}}
+ {{- partial "head-embed.html" . -}}
+ {{- .Render "summary" -}}
+{{- end -}}
diff --git a/themes/default/layouts/_default/single.html b/themes/default/layouts/_default/single.html
index 9aeb728..f3123b3 100644
--- a/themes/default/layouts/_default/single.html
+++ b/themes/default/layouts/_default/single.html
@@ -1,83 +1,79 @@
{{- define "styles" -}}
<style>
- {{ partial "styles-navigator.html" (dict "Link" "/") | safeCSS }}
+ {{ partial "navigator.css.html" (dict "Link" "/") | safeCSS }}
</style>
{{- end -}}
-{{- define "middle" -}}
-
-{{- partial "navigator-middle.html"
- (dict
- "Title" "Message"
- "Subtitle" "Thread"
- "Icon" "arrow-left"
- "IconLabel" "Back"
- "Href" "/"
- "Id" "back"
- "Context" .
- )
--}}
+{{- define "header" -}}
+ {{- partial "navigator-middle.html"
+ (dict
+ "Title" "Post"
+ "Subtitle" "Thread"
+ "Icon" "arrow-left"
+ "IconLabel" "Back"
+ "Href" "/"
+ "Id" "back"
+ "Context" .
+ )
+ -}}
+{{- end -}}
-<micro-thread>
- {{ .Render "summary" }}
+{{- define "middle" -}}
+ <micro-thread>
+ {{- partial "render-embed.html" . -}}
- {{- $nextHref := "" -}}
- {{- $prevHref := "" -}}
- {{- $nextTitle := "" -}}
- {{- $prevTitle := "" -}}
- {{- $nextInvisible := "data-invisible" -}}
- {{- $prevInvisible := "data-invisible" -}}
+ {{- $prevHref := "/" -}}
+ {{- $nextHref := "/" -}}
+ {{- $prevTitle := "hidden" -}}
+ {{- $nextTitle := "hidden" -}}
- {{- with .Next -}}
- {{- $nextHref = $.Next.Permalink -}}
- {{- $nextTitle = $.Next.Summary -}}
- {{- $nextInvisible = "" -}}
- {{- end -}}
+ {{- with .Next -}}
+ {{- $nextHref = $.Next.Permalink -}}
+ {{- $nextTitle = $.Next.Summary -}}
+ {{- end -}}
- {{- with .Prev -}}
- {{- $prevHref = $.Prev.Permalink -}}
- {{- $prevTitle = $.Prev.Summary -}}
- {{- $prevInvisible = "" -}}
- {{- end -}}
+ {{- with .Prev -}}
+ {{- $prevHref = $.Prev.Permalink -}}
+ {{- $prevTitle = $.Prev.Summary -}}
+ {{- end -}}
- {{- with or .Next .Prev -}}
- <paginator-navigation>
- <a {{ $nextInvisible | safeHTMLAttr }} href="{{ $nextHref }}" title="{{ $nextTitle }}">
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-left.svg")) }}
- Newer
- </a>
+ {{- with or .Next .Prev -}}
+ <nav data-type="pagination">
+ <a rel="next" href="{{ $nextHref }}" title="{{ $nextTitle }}">
+ {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-left.svg")) }}
+ <header>Newer</header>
+ </a>
- <a {{ $prevInvisible | safeHTMLAttr }} href="{{ $prevHref }}" title="{{ $prevTitle }}">
- Older
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-right.svg")) }}
- </a>
- </paginator-navigation>
- {{- end -}}
+ <a rel="prev" href="{{ $prevHref }}" title="{{ $prevTitle }}">
+ <header>Older</header>
+ {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-right.svg")) }}
+ </a>
+ </nav>
+ {{- end -}}
- {{- $filteredPages := partial "function-filters-content.html" (.Site.RegularPages.Related .) -}}
- {{- $related := $filteredPages | first 3 -}}
+ {{- $filteredPages := partial "function-filters-content.html" (.Site.RegularPages.Related .) -}}
+ {{- $related := $filteredPages | first 3 -}}
- {{- with $related -}}
- <related-content>
- <footer>
- <samp>
- Related Tags
- {{- with $.Params.tags -}}
- {{- range $tag := first 1 $.Params.tags -}}
- {{- $link := print ("tags/" | relURL) ($tag | urlize) "/" }}
- {{ print "---" " " "[#" $tag "](" $link ")" | markdownify -}}
+ {{- with $related -}}
+ <related-content>
+ <footer>
+ <samp>
+ Related Tags
+ {{- with $.Params.tags -}}
+ {{- range $tag := first 1 $.Params.tags -}}
+ {{- $link := print ("tags/" | relURL) ($tag | urlize) "/" }}
+ {{ print "---" " " "[#" $tag "](" $link ")" | markdownify -}}
+ {{- end -}}
{{- end -}}
- {{- end -}}
- </samp>
- </footer>
- </related-content>
-
- {{- range $related -}}
- {{- .Render "summary" -}}
- {{- end -}}
- {{- end -}}
+ </samp>
+ </footer>
+ </related-content>
-</micro-thread>
+ {{- range $related -}}
+ {{- partial "render-embed.html" . -}}
+ {{- end -}}
+ {{- end -}}
+ </micro-thread>
{{- end -}}
{{- define "right" -}}
diff --git a/themes/default/layouts/_default/single.plain.txt b/themes/default/layouts/_default/single.plain.txt
index 36a7616..f46e495 100644
--- a/themes/default/layouts/_default/single.plain.txt
+++ b/themes/default/layouts/_default/single.plain.txt
@@ -1,3 +1,3 @@
{{- define "main" -}}
- {{- partial "function-content.html" . | plainify | markdownify | htmlUnescape -}}
+ {{- partial "function-content.html" . | plainify | htmlUnescape -}}
{{- end -}}
diff --git a/themes/default/layouts/_default/sitemap.xml b/themes/default/layouts/_default/sitemap.xml
index c47d1db..f8ab315 100644
--- a/themes/default/layouts/_default/sitemap.xml
+++ b/themes/default/layouts/_default/sitemap.xml
@@ -3,7 +3,7 @@
{{- $changefreq := "weekly" -}}
{{- $priority := 0.5 -}}
-{{- $lastmod := now.Format "2006-01-02T15:04:05-07:00" }}
+{{- $lastmod := now | time.Format "2006-01-02T15:04:05-07:00" }}
<urlset
xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
@@ -21,7 +21,7 @@
{{- end -}}
{{- if not .Lastmod.IsZero -}}
- {{- $lastmod = safeHTML (.Lastmod.Format "2006-01-02T15:04:05-07:00") -}}
+ {{- $lastmod = safeHTML (.Lastmod | time.Format "2006-01-02T15:04:05-07:00") -}}
{{- end }}
<url>
diff --git a/themes/default/layouts/_default/summary.html b/themes/default/layouts/_default/summary.html
index 5bc738d..e820b24 100644
--- a/themes/default/layouts/_default/summary.html
+++ b/themes/default/layouts/_default/summary.html
@@ -1,3 +1,4 @@
+{{- $href := or .Params.Feed.link .Permalink -}}
{{- $content := partial "function-content.html" . | safeHTML -}}
{{- $expired := and .ExpiryDate (ge now.Unix .ExpiryDate.Unix) -}}
@@ -7,16 +8,15 @@
{{ if .Draft }}draft{{ end }}
{{ if .ExpiryDate }}data-expires{{ end }}
>
- <micro-summary title="{{- partial "meta-title.html" . -}}">
- <micro-metadata>
- <micro-thumbnail>
- {{ partial "profile-picture.html" . }}
- </micro-thumbnail>
- {{ partial "card-meta-header.html" . }}
- </micro-metadata>
- <article aria-label="article">
- {{- $content -}}
- <micro-tags>{{ partial "meta-tags.html" . }}</micro-tags>
- </article>
- </micro-summary>
+ <a href="{{ $href }}"></a>
+ <header>
+ {{ partial "profile-picture.html" . }}
+ {{ partial "card-meta-header.html" . }}
+ </header>
+ <article aria-label="article">
+ {{- $content -}}
+ <micro-tags>
+ {{- partial "tags.html" (dict "Format" "page" "Context" .) -}}
+ </micro-tags>
+ </article>
</micro-card>
diff --git a/themes/default/layouts/_default/taxonomy.html b/themes/default/layouts/_default/taxonomy.html
index e0126d2..5c8e2ba 100644
--- a/themes/default/layouts/_default/taxonomy.html
+++ b/themes/default/layouts/_default/taxonomy.html
@@ -1,26 +1,27 @@
{{- define "styles" -}}
<style>
- {{ partial "styles-navigator.html" (dict "Link" "/tags/") | safeCSS }}
+ {{ partial "navigator.css.html" (dict "Link" "/tags/") | safeCSS }}
</style>
{{- end -}}
-{{- define "middle" -}}
-
+{{- define "header" -}}
{{- partial "navigator-middle.html"
(dict
- "Title" "Tags"
- "Subtitle" (partial "count-tags.html" .)
- "Icon" "arrow-left"
+ "Context" .
"IconLabel" "Back"
- "Href" "/"
"Id" "back"
- "Context" .
+ "Title" "Tags"
+ "Icon" "arrow-left"
+ "Subtitle" (print (partial "count-tags.html" .) " " "Total")
+ "Href" (or (and (gt .Paginator.PageNumber 1) (.Paginator.Prev.URL | absURL)) "/")
)
-}}
+{{- end -}}
+{{- define "middle" -}}
<tag-deck>
{{- range .Paginator.Pages -}}
- {{- $count := len .Data.Pages -}}
+ {{- $count := lang.FormatNumberCustom 0 (len .Data.Pages) -}}
{{- $title := lower .Title -}}
{{- range first 1 .Pages -}}
@@ -42,16 +43,11 @@
</picture>
</a>
</figure>
- <h3>
- <a data-hover href="{{ print ("" | absURL) "/" $author.user "/" }}">
- @{{ $author.user }}
- </a>
- </h3>
<time
datetime="{{ .Date | time.Format "2006-01-02T15:04:05Z" }}"
title="{{ .Date | time.Format "Posted: Monday, January 2, 2006 at 15:04:05 MST" }}"
>
- {{ .Date.Format "02 Jan 2006" }}
+ {{ .Date | time.Format "02 Jan 2006" }}
</time>
<p>
<a data-hover href="{{ print ("" | absURL) "/tags/" $title "/#" (partial "card-id.html" .) }}">
@@ -63,8 +59,11 @@
{{- end -}}
{{- end -}}
</tag-deck>
+{{- end -}}
- {{ partial "pagination.html" . }}
+{{- define "footer" -}}
+ {{- partial "pagination.html" . -}}
+ {{- partial "footer.html" . -}}
{{- end -}}
{{- define "right" -}}
diff --git a/themes/default/layouts/_default/term.html b/themes/default/layouts/_default/term.html
index f8fc983..4f0d92a 100644
--- a/themes/default/layouts/_default/term.html
+++ b/themes/default/layouts/_default/term.html
@@ -1,33 +1,34 @@
-{{ define "styles" }}
+{{- define "styles" -}}
<style>
- {{ partial "styles-navigator.html" (dict "Link" "/tags/") | safeCSS }}
+ {{ partial "navigator.css.html" (dict "Link" "/tags/") | safeCSS }}
</style>
-{{ end }}
+{{- end -}}
-{{ define "middle" }}
-
- {{- $terms := print (lang.FormatNumberCustom 0 (len .Data.Pages)) " " "Messages" -}}
-
- {{ partial "navigator-middle.html"
+{{- define "header" -}}
+ {{- partial "navigator-middle.html"
(dict
- "Title" (print "#" .Title)
- "Subtitle" $terms
- "Icon" "arrow-left"
+ "Context" .
"IconLabel" "Back"
- "Href" "/"
"Id" "back"
- "Context" .
+ "Icon" "arrow-left"
+ "Title" (print "#" .Title)
+ "Subtitle" (print (lang.FormatNumberCustom 0 (len .Data.Pages)) " " "Total")
+ "Href" (or (and (gt .Paginator.PageNumber 1) (.Paginator.Prev.URL | absURL)) "/")
)
- }}
-
- {{ range .Paginator.Pages }}
- {{ .Render "summary" }}
- {{ end }}
+ -}}
+{{- end -}}
- {{ partial "pagination.html" . }}
+{{- define "middle" -}}
+ {{- range .Paginator.Pages -}}
+ {{- partial "render-embed.html" . -}}
+ {{- end -}}
+{{- end -}}
-{{ end }}
+{{- define "footer" -}}
+ {{- partial "pagination.html" . -}}
+ {{- partial "footer.html" . -}}
+{{- end -}}
-{{ define "right" }}
+{{- define "right" -}}
{{- partial "navigator-right.html" . -}}
-{{ end }}
+{{- end -}}
diff --git a/themes/default/layouts/partials/author-card.html b/themes/default/layouts/partials/author-card.html
index bbb3ec8..561fef3 100644
--- a/themes/default/layouts/partials/author-card.html
+++ b/themes/default/layouts/partials/author-card.html
@@ -1,5 +1,5 @@
{{- $metadata := print "public/" .Data.user "/author.json" -}}
-{{- $date := .Date.Local.Format "15:04 Jan 2 2006" -}}
+{{- $date := .Date | time.Format "Mon Jan 2 2006" -}}
{{- $host := (urls.Parse ("" | absURL)).Host -}}
@@ -17,9 +17,11 @@
{{- $sourceset = print "/" (partial "function-paths.html").media "/" .Data.user "/" .Data.user "-profile.webp" -}}
{{- with $metadata := resources.Get $metadata -}}
- {{- $metadata = $metadata.Content | transform.Unmarshal -}}
- {{- $width = $metadata.picture.profileWidth -}}
- {{- $height = $metadata.picture.profileHeight -}}
+ {{- with $content := $metadata.Content -}}
+ {{- $metadata = $content | transform.Unmarshal -}}
+ {{- $width = $metadata.picture.profileWidth -}}
+ {{- $height = $metadata.picture.profileHeight -}}
+ {{- end -}}
{{- end -}}
{{- if or
@@ -36,45 +38,44 @@
<micro-author>
<micro-card>
- <micro-summary>
- <micro-thumbnail>
- <figure>
- <a title="{{ .Data.name }}" href="{{ "" | absURL }}/{{ .Data.user }}/#">
- <picture>
- {{- with $sourceset -}}
- <source srcset="{{ $sourceset }}" type="image/webp" />
- {{- end -}}
- <img
- width="{{ or $width "64" }}"
- height="{{ or $height "64" }}"
- src="{{ $source }}"
- alt="{{ $alternate }}"
- />
- </picture>
- </a>
- </figure>
- </micro-thumbnail>
- <micro-header>
- <h2>
- <b>{{ .Data.name }}</b>
- </h2>
- <h3>
- <a data-hover title="{{ .Data.name }}" href="{{ "" | absURL }}/{{ .Data.user }}/#">
- {{ .Data.user }}@{{ $host }}
- </a>
- </h3>
- <time
- title="{{ .Date.Format "Monday, January 2 2006 at 15:04:05 MST" }}"
- datetime="{{ .Date.Format "2006-01-02T15:04:05Z" }}"
- >
- {{ $date }}
- </time>
- </micro-header>
- <p>{{ .Data.description | markdownify | plainify | htmlUnescape | truncate 60 "..." }}</p>
- <a title="Follow with RSS Reader" href="{{ "" | absURL }}/{{ .Data.user }}/rss.xml">
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/rss.svg")) }}
- <span>Follow</span>
- </a>
- </micro-summary>
+ <header>
+ <figure>
+ <a title="{{ .Data.name }}" href="{{ "" | absURL }}/{{ .Data.user }}/">
+ <picture>
+ {{- with $sourceset -}}
+ <source srcset="{{ print ("" | absURL) $sourceset }}" type="image/webp" />
+ {{- end -}}
+ <img
+ width="{{ or $width "64" }}"
+ height="{{ or $height "64" }}"
+ src="{{ print ("" | absURL) $source }}"
+ alt="{{ $alternate }}"
+ />
+ </picture>
+ </a>
+ </figure>
+ </header>
+ <article>
+ <h2>
+ <b>{{ .Data.name }}</b>
+ </h2>
+ <h3>
+ <a data-hover="" title="{{ .Data.name }}" href="{{ "" | absURL }}/{{ .Data.user }}/">
+ {{ .Data.user }}@{{ $host }}
+ </a>
+ </h3>
+ <time
+ data-type="default"
+ title="{{ .Date | time.Format "Monday January 2 2006 at 15:04:05 MST" }}"
+ datetime="{{ .Date | time.Format "2006-01-02T15:04:05Z" }}"
+ >
+ {{ $date }}
+ </time>
+ </article>
+ <p>{{ .Data.description | markdownify | plainify | htmlUnescape | truncate 60 "..." }}</p>
+ <a title="Follow with RSS Reader" href="{{ "" | absURL }}/{{ .Data.user }}/rss.xml">
+ {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/tabler/rss.svg")) }}
+ <span>Feed</span>
+ </a>
</micro-card>
</micro-author>
diff --git a/themes/default/layouts/partials/author-list.html b/themes/default/layouts/partials/author-list.html
index 44b55aa..619b1b3 100644
--- a/themes/default/layouts/partials/author-list.html
+++ b/themes/default/layouts/partials/author-list.html
@@ -1,13 +1,17 @@
{{- $authors := print "public/authors.html" -}}
<author-list>
- <h1>Authors</h1>
+ <h1>
+ <a data-hover href="{{ "" | absURL }}/authors/">
+ Authors
+ </a>
+ </h1>
<aside>
{{- with $authors = resources.Get $authors -}}
{{- $authors.Content | safeHTML -}}
{{- else -}}
<footer>
- <code>No authors found!</code>
+ <code>No items found!</code>
</footer>
{{- end -}}
</aside>
diff --git a/themes/default/layouts/partials/author-picture.html b/themes/default/layouts/partials/author-picture.html
index dbbfd69..01786e7 100644
--- a/themes/default/layouts/partials/author-picture.html
+++ b/themes/default/layouts/partials/author-picture.html
@@ -20,9 +20,11 @@
{{- $source = print "/" (partial "function-paths.html").media "/" $author.user "/" $author.user "-profile" (path.Ext $author.picture.profile) -}}
{{- $sourceset = print "/" (partial "function-paths.html").media "/" $author.user "/" $author.user "-profile.webp" -}}
{{- with $metadata := resources.Get $metadata -}}
- {{- $metadata = $metadata.Content | transform.Unmarshal -}}
- {{- $width = $metadata.picture.profileWidth -}}
- {{- $height = $metadata.picture.profileHeight -}}
+ {{- with $content := $metadata.Content -}}
+ {{- $metadata = $content | transform.Unmarshal -}}
+ {{- $width = $metadata.picture.profileWidth -}}
+ {{- $height = $metadata.picture.profileHeight -}}
+ {{- end -}}
{{- else -}}
{{- $source = "/data/media/404.png" -}}
{{- $sourceset = "" -}}
@@ -35,13 +37,13 @@
{{- end -}}
{{- with $sourceset -}}
-<source srcset="{{ $sourceset }}" type="image/webp" />
+<source srcset="{{ print ("" | absURL) $sourceset }}" type="image/webp" />
{{- end -}}
<img
width="{{ $width }}"
height="{{ $height }}"
- src="{{ $source }}"
+ src="{{ print ("" | absURL) $source }}"
alt="{{ $alternate }}"
/>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/partials/base-css.html b/themes/default/layouts/partials/base-css.html
deleted file mode 100644
index 0a104c3..0000000
--- a/themes/default/layouts/partials/base-css.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{{- $default := resources.Get "css/default.css" -}}
-{{- $syntax := resources.Get "css/syntax-highlight-default.css" -}}
-
-{{- $css :=
- slice $default $syntax |
- resources.Concat "css/bundle.css" |
- resources.Minify |
- fingerprint |
--}}
-
-{{ if .Site.Params.site.production }}
-<link title ="Default" rel="stylesheet" href="{{ $css.Permalink }}" />
-{{ else }}
-<link title="Default" rel="stylesheet" href="{{ $default.Permalink }}" />
-<link rel="stylesheet" href="{{ $syntax.Permalink }}" />
-{{ end }}
diff --git a/themes/default/layouts/partials/base-discovery.html b/themes/default/layouts/partials/base-discovery.html
deleted file mode 100644
index 23d3a09..0000000
--- a/themes/default/layouts/partials/base-discovery.html
+++ /dev/null
@@ -1,49 +0,0 @@
-{{-
- $authorData := (dict
- "Context" .
- "AuthorDefaultUser" .Site.Author.default.home
- )
--}}
-
-{{- $author := partial "function-authors-data.html" (dict "Data" $authorData) -}}
-
-<link
- rel="alternate"
- type="application/rss+xml"
- title="{{ $author.name }}'s Feed"
- href="{{ .Site.BaseURL }}/{{ $author.user }}/rss.xml"
-/>
-
-{{- with $author.feeds.rss }}
- {{ range $author.feeds.rss }}
- {{ $data := split . " " }}
- {{- $url := delimit (first 1 $data) "" -}}
- {{- $retitle := trim (delimit (after 1 $data) " ") " " -}}
- {{- $retitle := and $retitle (print $retitle "'s Feed") -}}
-
- <link
- rel="alternate"
- type="application/rss+xml"
- title="{{ or $retitle $url }}"
- href="{{ $url }}"
- />
- {{ end }}
-{{ end }}
-
-{{- if (eq .Page.Kind "taxonomy") -}}
-<link
- rel="alternate"
- type="application/rss+xml"
- title="{{ .Title }} Feed"
- href="{{ .Permalink }}rss.xml"
-/>
-{{- end -}}
-
-{{- if (eq .Page.Kind "term") -}}
-<link
- rel="alternate"
- type="application/rss+xml"
- title="#{{ lower .Title }} Tag Feed"
- href="{{ .Permalink }}rss.xml"
-/>
-{{- end }}
diff --git a/themes/default/layouts/partials/base-footer.html b/themes/default/layouts/partials/base-footer.html
deleted file mode 100644
index f24b8d6..0000000
--- a/themes/default/layouts/partials/base-footer.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{{ $author := index .Site.Data ((or .Params.author .Site.Author.default.footer) | default "default") }}
-
-<footer>
- {{- with .Site.Author.footer -}}
- {{ if $.IsHome -}}
- {{ . | markdownify }}
- {{- else -}}
- {{ $author.title }}
- {{- end -}}
- {{- end }}
- &middot; Copyright &copy; {{ now.Format "2006"}}
- &middot; <a href="/sitemap.xml" >Site Map</a>
-</footer>
diff --git a/themes/default/layouts/partials/base-head.html b/themes/default/layouts/partials/base-head.html
deleted file mode 100644
index 2757f29..0000000
--- a/themes/default/layouts/partials/base-head.html
+++ /dev/null
@@ -1,74 +0,0 @@
-{{-
- $authorData := (dict
- "Context" .
- "AuthorDefaultUser" .Site.Author.default.home
- )
--}}
-
-{{- $author := partial "function-authors-data.html" (dict "Data" $authorData) -}}
-
-<!-- HTML Meta Tags -->
-<meta charset="utf-8" />
-<meta name="author" content="{{ $author.name -}}" />
-{{ if or .Params.Feed .Params.Unlisted .Params.ExpiryDate -}}
-<meta name="robots" content="noindex,nofollow" />
-{{- else -}}
-<meta name="robots" content="{{ or .Site.Params.site.robots "index,follow" }}" />
-{{- end }}
-<meta name="viewport" content="width=device-width, initial-scale=1" />
-<meta name="keywords" content="{{- partial "base-title.html" . -}}" />
-<meta name="generator" content="Hugo {{ hugo.Version }}" />
-{{ with .Site.Params.site.refresh -}}
-<meta http-equiv="refresh" content="{{ . }}" />
-{{- end }}
-
-<!-- Search Engine Tags -->
-<meta itemprop="name" content="{{ partial "base-title.html" . -}}" />
-<meta itemprop="description" content="{{ if .Params.summary }}{{ .Params.summary }}{{ else }}{{ .Summary }}{{ end }}" />
-<meta itemprop="image" content="{{ .Site.BaseURL }}/{{ $author.user -}}/media/profile/picture.png" />
-
-<!-- Open Graph Meta Tags -->
-<meta property="og:title" content="{{ partial "base-title.html" . -}}" />
-<meta property="og:description" content="{{- partial "base-description.html" . -}}" />
-<meta property="og:url" content="{{ .Permalink }}" />
-<meta property="og:image" content="{{ .Site.BaseURL }}/{{ $author.user -}}/media/profile/picture.png" />
-<meta property="og:type" content="website" />
-<meta property="article:published_time" content="{{ .Params.PublishDate }}" />
-<meta property="article:modified_time " content="{{ .Params.LastMod }}" />
-
-<!-- Twitter Meta Tags -->
-<meta name="twitter:card" content="summary_large_image" />
-<meta name="twitter:title" content="{{ partial "base-title.html" . -}}" />
-<meta name="twitter:description" content="{{- partial "base-description.html" . -}}" />
-<meta name="twitter:image" content="{{ .Site.BaseURL }}/{{ $author.user -}}/media/profile/picture.png" />
-
-<!-- Search Verification -->
-{{- partial "base-search.html" . -}}
-
-<!-- Link Tags -->
-<link rel="home" href="{{ .Site.BaseURL }}/{{ $author.user }}/" />
-
-<!-- Feed Discovery -->
-{{- partial "base-discovery.html" . -}}
-
-<!-- Canonicalization -->
-{{- partial "base-canonical.html" . -}}
-
-<!-- Styles -->
-{{- partial "base-css.html" . -}}
-
-<!-- Scripts -->
-{{- partial "base-js.html" . -}}
-
-<!-- Progressive Enhancement -->
-{{- partial "base-manifest.html" . -}}
-
-<!-- Content Security Policy -->
-{{- partial "base-csp.html" . -}}
-
-<!-- No Scripts -->
-<noscript>
- <style>
- {{ safeCSS (readFile "assets/css/noscript.css") }}
- </style>
-</noscript>
diff --git a/themes/default/layouts/partials/base-manifest.html b/themes/default/layouts/partials/base-manifest.html
deleted file mode 100644
index 66e2354..0000000
--- a/themes/default/layouts/partials/base-manifest.html
+++ /dev/null
@@ -1,15 +0,0 @@
-{{- $icon := resources.Get .Site.Params.webmanifest.logo -}}
-
-{{- $icon32 := $icon.Fit "32x32" -}}
-{{- $icon16 := $icon.Fit "16x16" -}}
-{{- $appleTouchIcon := $icon.Fit "180x180" -}}
-
-{{- $ico := $icon32.Content | resources.FromString "/favicon.ico" -}}
-
-<link rel="icon" type="image/x-icon" href="data:image/ico;base64,{{ $icon32.Content | base64Encode }}" />
-<link rel="icon" type="image/png" sizes="16x16" href="data:image/png;base64,{{ $icon16.Content | base64Encode }}" />
-<link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,{{ $icon32.Content | base64Encode }}" />
-<link rel="apple-touch-icon" sizes="180x180" href="data:image/png;base64,{{ $appleTouchIcon.Content | base64Encode }}" />
-<link rel="manifest" href="{{ .Site.BaseURL }}/site.webmanifest" />
-<meta name="msapplication-TileColor" content="#da532c" />
-<meta name="theme-color" content="#ffffff" />
diff --git a/themes/default/layouts/partials/base-search.html b/themes/default/layouts/partials/base-search.html
deleted file mode 100644
index 1bfed6c..0000000
--- a/themes/default/layouts/partials/base-search.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{{- with .Site.Params.search.verification.google -}}
-<meta name="google-site-verification" content="{{ . }}" />
-{{ end }}
-
-{{- with .Site.Params.search.verification.bing -}}
-<meta name="msvalidate.01" content="{{ . }}" />
-{{ end }}
-
-{{- with .Site.Params.search.verification.yandex -}}
-<meta name="yandex-verification" content="{{ . }}" />
-{{ end }}
diff --git a/themes/default/layouts/partials/card-meta-header.html b/themes/default/layouts/partials/card-meta-header.html
index fd516f5..72b67b8 100644
--- a/themes/default/layouts/partials/card-meta-header.html
+++ b/themes/default/layouts/partials/card-meta-header.html
@@ -1,4 +1,4 @@
-<header>
+<meta-data>
{{- partial "meta-anchored.html" . -}}
@@ -10,16 +10,16 @@
{{- partial "meta-handle.html" . -}}
- {{- partial "meta-date-time.html" . -}}
+ {{- partial "meta-datetime.html" . -}}
{{- partial "meta-view.html" . -}}
- {{- partial "meta-context-menu.html" . -}}
+ {{- partial "meta-menu.html" . -}}
- {{- partial "meta-read-time.html" . -}}
+ {{- partial "meta-wordcount.html" . -}}
- {{- partial "meta-word-count.html" . -}}
+ {{- partial "meta-readtime.html" . -}}
- {{- partial "meta-expiry-date.html" . -}}
+ {{- partial "meta-expirydate.html" . -}}
-</header>
+</meta-data>
diff --git a/themes/default/layouts/partials/context-profile.html b/themes/default/layouts/partials/context-profile.html
index 5b82cc9..5150128 100644
--- a/themes/default/layouts/partials/context-profile.html
+++ b/themes/default/layouts/partials/context-profile.html
@@ -1,18 +1,15 @@
-{{- $author := partial "function-authors-data.html" . -}}
+{{- $author := partial "function-authors-data.html" . -}}
{{- $description := or .Params.feed.description ($author.description | markdownify) -}}
-{{- $name := or .Params.feed.name $author.name -}}
-{{- $user := $author.user -}}
-
-{{- $host := or (urls.Parse .Site.BaseURL).Host "localhost" -}}
-{{- $href := print .Site.BaseURL "/" $author.user "/#" -}}
-
-{{- $title := print $author.user "@" $host -}}
+{{- $name := or .Params.feed.name $author.name -}}
+{{- $host := or (urls.Parse .Site.BaseURL).Host "localhost" -}}
+{{- $author := .Section -}}
+{{- $href := print ("" | absURL) "/" $author "/" -}}
+{{- $title := print $author "@" $host -}}
{{- with .Params.feed -}}
{{- $host = $.Params.feed.domain -}}
{{- $href = or $.Params.feed.home (print "http://" $.Params.feed.domain) -}}
{{- $title = $.Params.feed.domain -}}
- {{- $user = "" -}}
{{- end -}}
<context-profile>
@@ -29,7 +26,7 @@
</aside>
<aside>
<h2>{{ $name }}</h2>
- <p>{{ $user }}@{{ $host }}</p>
+ <p>@{{ $host }}</p>
</aside>
</div>
<p>{{ $description }}</p>
diff --git a/themes/default/layouts/partials/count-authors.html b/themes/default/layouts/partials/count-authors.html
index 2b46b52..8f2d7ef 100644
--- a/themes/default/layouts/partials/count-authors.html
+++ b/themes/default/layouts/partials/count-authors.html
@@ -1,2 +1,2 @@
{{- $authors := partial "function-authors-slice.html" . -}}
-{{- print (lang.FormatNumberCustom 0 (len $authors)) " " "Authors" -}}
+{{- print (lang.FormatNumberCustom 0 (len $authors)) -}}
diff --git a/themes/default/layouts/partials/count-drafts.html b/themes/default/layouts/partials/count-drafts.html
index 3c0cc5a..fae0b90 100644
--- a/themes/default/layouts/partials/count-drafts.html
+++ b/themes/default/layouts/partials/count-drafts.html
@@ -1,12 +1,7 @@
-{{- $author := partial "function-authors-data.html" . -}}
-{{- $author = $author.user -}}
+{{- $author := .Section -}}
-{{ $count := 0 }}
+{{- $authors := where .Site.RegularPages "Section" $author -}}
+{{- $drafts := where .Site.RegularPages "Draft" true -}}
+{{- $filteredPages := $authors | intersect $drafts -}}
-{{ range .Site.Pages }}
- {{ if and (eq .Type $author) .Draft }}
- {{ $count = add $count 1 }}
- {{ end }}
-{{ end }}
-
-{{ print (lang.FormatNumberCustom 0 $count) " " "Drafts" }}
+{{- print (lang.FormatNumberCustom 0 (len $filteredPages)) -}}
diff --git a/themes/default/layouts/partials/count-feeds.html b/themes/default/layouts/partials/count-feeds.html
index 0b8cacc..68495da 100644
--- a/themes/default/layouts/partials/count-feeds.html
+++ b/themes/default/layouts/partials/count-feeds.html
@@ -1,14 +1,7 @@
-{{- $author := partial "function-authors-data.html" . -}}
-{{- $author = $author.user -}}
+{{- $author := .Section -}}
-{{ $count := 0 }}
+{{- $feeds := where .Site.Pages "Params.feed" "ne" nil -}}
+{{- $authors := where .Site.Pages "Section" $author -}}
+{{- $filteredPages := $authors | intersect $feeds -}}
-{{ range .Site.Pages }}
- {{ if .Params.feed }}
- {{ if eq .Type $author }}
- {{ $count = add $count 1 }}
- {{ end }}
- {{ end }}
-{{ end }}
-
-{{ print (lang.FormatNumberCustom 0 $count) " " "Messages" }}
+{{- print (lang.FormatNumberCustom 0 (len $filteredPages)) -}}
diff --git a/themes/default/layouts/partials/count-likes.html b/themes/default/layouts/partials/count-likes.html
deleted file mode 100644
index 3b8a9ef..0000000
--- a/themes/default/layouts/partials/count-likes.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{- $author := partial "function-authors-data.html" . -}}
-{{- $author = $author.user -}}
-
-{{ $count := 0 }}
-
-{{ range .Site.Pages }}
- {{ if and (eq .Type $author) .Params.Liked }}
- {{ $count = add $count 1 }}
- {{ end }}
-{{ end }}
-
-{{ print (lang.FormatNumberCustom 0 $count) " " "Messages" }}
diff --git a/themes/default/layouts/partials/count-marks.html b/themes/default/layouts/partials/count-marks.html
new file mode 100644
index 0000000..deb532d
--- /dev/null
+++ b/themes/default/layouts/partials/count-marks.html
@@ -0,0 +1,6 @@
+{{- $author := .Section -}}
+{{- $items := where .Site.RegularPages ".Params.marked" true -}}
+{{- $authors := where .Site.RegularPages "Section" $author -}}
+{{- $filteredPages := $authors | intersect $items -}}
+
+{{- print (lang.FormatNumberCustom 0 (len $filteredPages)) -}}
diff --git a/themes/default/layouts/partials/count-media.html b/themes/default/layouts/partials/count-media.html
index 13782cc..1d68e0a 100644
--- a/themes/default/layouts/partials/count-media.html
+++ b/themes/default/layouts/partials/count-media.html
@@ -1,19 +1,20 @@
-{{- $author := partial "function-authors-data.html" . -}}
-{{- $author = $author.user -}}
+{{- $author := .Section -}}
+{{- $notFeeds := where .Site.RegularPages "Params.feed" "eq" nil -}}
+{{- $authors := where .Site.RegularPages "Section" $author -}}
+{{- $filteredPages := $authors | intersect $notFeeds -}}
+{{- $count := 0 -}}
-{{ $count := 0 }}
+{{- range first 100 $filteredPages -}}
+ {{- if eq $count 10 -}}
+ {{- break -}}
+ {{- end -}}
+ {{- if or
+ (in .Content "</video>")
+ (in .Content "</picture>")
+ (in .Content "</youtube-video>")
+ -}}
+ {{- $count = add $count 1 -}}
+ {{- end -}}
+{{- end -}}
-{{ range .Site.Pages }}
- {{ if or
- (in .Content "<figure>")
- (in .Content "<imgur-video>")
- (in .Content "<youtube-video>")
- (in .Content "<video-container>")
- }}
- {{ if eq .Type $author }}
- {{ $count = add $count 1 }}
- {{ end }}
- {{ end }}
-{{ end }}
-
-{{ print (lang.FormatNumberCustom 0 $count) " " "Messages" }}
+{{- print (lang.FormatNumberCustom 0 $count) -}}
diff --git a/themes/default/layouts/partials/count-tags.html b/themes/default/layouts/partials/count-tags.html
index 0ef6802..6d436c6 100644
--- a/themes/default/layouts/partials/count-tags.html
+++ b/themes/default/layouts/partials/count-tags.html
@@ -1 +1 @@
-{{- print (lang.FormatNumberCustom 0 (len .Site.Taxonomies.tags)) " " "Tags" -}}
+{{- print (lang.FormatNumberCustom 0 (len .Site.Taxonomies.tags)) -}}
diff --git a/themes/default/layouts/partials/count-total-messages.html b/themes/default/layouts/partials/count-total-messages.html
deleted file mode 100644
index 10540a7..0000000
--- a/themes/default/layouts/partials/count-total-messages.html
+++ /dev/null
@@ -1,2 +0,0 @@
-{{ $messages := len .Site.RegularPages }}
-{{ print (lang.FormatNumberCustom 0 $messages) " " "Messages" }}
diff --git a/themes/default/layouts/partials/count.html b/themes/default/layouts/partials/count.html
new file mode 100644
index 0000000..72b5d03
--- /dev/null
+++ b/themes/default/layouts/partials/count.html
@@ -0,0 +1 @@
+{{- print (lang.FormatNumberCustom 0 (len .Site.RegularPages)) -}}
diff --git a/themes/default/layouts/partials/following-list.html b/themes/default/layouts/partials/following-list.html
index 165d699..510d3d2 100644
--- a/themes/default/layouts/partials/following-list.html
+++ b/themes/default/layouts/partials/following-list.html
@@ -1,14 +1,30 @@
+{{- $count := 0 -}}
{{- $author := partial "function-authors-data.html" . -}}
-{{- $following := print "public/" $author.user "/following.html" -}}
+{{- $feeds := print "public/" .Section "/following.html" -}}
+
+{{- with $items := $author.feeds.rss -}}
+ {{- $count = len $items -}}
+{{- end -}}
+
+{{- $expand := cond (gt $count 3) "more" "less" -}}
<following-list>
- <h1>Following</h1>
+ <details
+ id="web-feeds"
+ data-expand="{{- $expand -}}"
+ >
+ <summary>
+ <h1>Web Feeds ({{ $count }})</h1>
+ </summary>
+ </details>
<aside>
- {{- if and $author.feeds.rss (fileExists $following) -}}
- {{- (resources.Get $following).Content | safeHTML -}}
+ {{- if and $author.feeds.rss (fileExists $feeds) -}}
+ {{- with $feeds = resources.Get $feeds -}}
+ {{- $feeds.Content | safeHTML -}}
+ {{- end -}}
{{- else -}}
<footer>
- <code>No feeds found!</code>
+ <code>No items found!</code>
</footer>
{{- end -}}
</aside>
diff --git a/themes/default/layouts/partials/footer.html b/themes/default/layouts/partials/footer.html
new file mode 100644
index 0000000..54d6ab1
--- /dev/null
+++ b/themes/default/layouts/partials/footer.html
@@ -0,0 +1,14 @@
+{{- $kind := in (slice "home" "taxonomy" "term") .Page.Kind -}}
+{{- $author := index .Site.Data.authors .Section -}}
+
+<footer>
+ {{- if $kind -}}
+ {{- with $footer := (and $kind .Site.Author.default.footer) -}}
+ {{ $footer | markdownify }} &middot;
+ Copyright &copy; {{ now | time.Format "2006"}} &middot;
+ {{- end -}}
+ {{- else -}}
+ {{ or $author.footer $author.title | markdownify }} &middot;
+ {{- end }}
+ <a href="/sitemap.xml" >Site Map</a>
+</footer>
diff --git a/themes/default/layouts/partials/function-authors-data.html b/themes/default/layouts/partials/function-authors-data.html
index f2ef800..dbc2c67 100644
--- a/themes/default/layouts/partials/function-authors-data.html
+++ b/themes/default/layouts/partials/function-authors-data.html
@@ -1,9 +1,9 @@
-{{- $input := or .Data.Context . -}}
+{{- $input := . -}}
{{- $pageContext := $input -}}
-{{- $authorDefaultUser := or .Data.AuthorDefaultUser $pageContext.Site.Author.default.user -}}
+{{- $author := $pageContext.Section -}}
-{{- $output := index $pageContext.Site.Data ((or $pageContext.Params.author $authorDefaultUser) | default "default") -}}
+{{- $output := index $pageContext.Site.Data.authors $author -}}
{{- return $output -}}
diff --git a/themes/default/layouts/partials/function-authors-slice.html b/themes/default/layouts/partials/function-authors-slice.html
index a469fdd..fc25554 100644
--- a/themes/default/layouts/partials/function-authors-slice.html
+++ b/themes/default/layouts/partials/function-authors-slice.html
@@ -1,7 +1,9 @@
{{- $authors := slice -}}
-{{- range $index, $author := .Site.Data -}}
- {{- $authors = $authors | append $author.user -}}
+{{- range $user := .Site.Author.list -}}
+ {{- with $author := index $.Site.Data.authors $user -}}
+ {{- $authors = $authors | append $author.user -}}
+ {{- end -}}
{{- end -}}
{{- return (uniq $authors) -}}
diff --git a/themes/default/layouts/partials/function-content.html b/themes/default/layouts/partials/function-content.html
index f206a03..19c15ea 100644
--- a/themes/default/layouts/partials/function-content.html
+++ b/themes/default/layouts/partials/function-content.html
@@ -2,13 +2,6 @@
{{- $content := $pageContext.Content -}}
{{- $expired := and .ExpiryDate (ge now.Unix .ExpiryDate.Unix) -}}
-{{-
- $content = $content |
- replaceRE "<p><figure>" "<figure>" |
- replaceRE "<p>\n<figure>" "<figure>" |
- replaceRE "</figure></p>" "</figure>" |
--}}
-
{{- $brokenBlockquotes := findRE `(?sU)</blockquote>\n<p>(&ndash;|&mdash;).*</p>` .Content -}}
{{- range $brokenBlockquote := $brokenBlockquotes -}}
diff --git a/themes/default/layouts/partials/function-favicon-domain.html b/themes/default/layouts/partials/function-favicon-domain.html
index f73ad62..3814304 100644
--- a/themes/default/layouts/partials/function-favicon-domain.html
+++ b/themes/default/layouts/partials/function-favicon-domain.html
@@ -2,10 +2,9 @@
{{- $output :=
(print
- "https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url="
+ "https://t1.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&size=64&url="
"http://"
$input
- "&size=64"
)
-}}
diff --git a/themes/default/layouts/partials/function-generate-feeds.html b/themes/default/layouts/partials/function-generate-feeds.html
index 42ffd8b..57789b5 100644
--- a/themes/default/layouts/partials/function-generate-feeds.html
+++ b/themes/default/layouts/partials/function-generate-feeds.html
@@ -19,7 +19,7 @@
{{- with $fetch | transform.Unmarshal -}}
{{- $content := "" -}}
- {{- $date := now.Format "2006-01-02T15:04:05Z" -}}
+ {{- $date := now | time.Format "2006-01-02T15:04:05Z" -}}
{{- $description := "" -}}
{{- $enclosure := "" -}}
{{- $imageLink := "" -}}
@@ -136,7 +136,7 @@
{{- end -}}
- {{- $sourceDomain := ($sourceLink | plainify | html | htmlUnescape | urls.Parse).Host -}}
+ {{- $sourceDomain := ($sourceLink | plainify | htmlUnescape | urls.Parse).Host -}}
{{- /* Replace invalid time zones. */ -}}
{{- $date = replaceRE "G[0-9]+T" "UTC" $date -}}
@@ -158,23 +158,23 @@
{{-
$feeds = $feeds | append (dict
- "FeedContent" ($content | plainify | html | htmlUnescape)
- "FeedContentShort" (delimit (first 2 (split ($content | plainify | html | htmlUnescape) "\n")) " " | truncate 250)
- "FeedDate" ($date | plainify | html | htmlUnescape | time.Format "January 2, 2006")
- "FeedDateTime" ($date | plainify | html | htmlUnescape | time.Format "2006-01-02T15:04:05Z")
- "FeedDateTitle" ($date | plainify | html | htmlUnescape | time.Format "Monday, January 2 2006 at 15:04:05 MST")
- "FeedDescription" ($description | plainify | html | htmlUnescape)
- "FeedDescriptionShort" (delimit (first 2 (split ($description | plainify | html | htmlUnescape) "\n")) " " | truncate 250)
- "FeedEnclosure" ($enclosure | plainify | html | htmlUnescape)
- "FeedImageLink" ($imageLink | plainify | html | htmlUnescape)
- "FeedLink" ($link | plainify | html | htmlUnescape)
- "FeedName" (or $retitle (delimit (first 2 (split ($sourceTitle | plainify | html | htmlUnescape) " ")) " "))
- "FeedSourceDescription" ($sourceDescription | plainify | html | htmlUnescape)
- "FeedSourceDomain" ($sourceDomain | plainify | html | htmlUnescape)
- "FeedSourceLink" ($sourceLink | plainify | html | htmlUnescape)
- "FeedSourceHome" ($sourceHome | plainify | html | htmlUnescape)
- "FeedSourceTitle" ($sourceTitle | plainify | html | htmlUnescape)
- "FeedTitle" ($title | plainify | html | htmlUnescape)
+ "FeedContent" ($content | plainify | htmlUnescape)
+ "FeedContentShort" (delimit (first 2 (split ($content | plainify | htmlUnescape) "\n")) " " | truncate 250 "...")
+ "FeedDate" ($date | plainify | htmlUnescape | time.Format "Mon Jan 2 2006")
+ "FeedDateTime" ($date | plainify | htmlUnescape | time.Format "2006-01-02T15:04:05Z")
+ "FeedDateTitle" ($date | plainify | htmlUnescape | time.Format "Monday January 2 2006 at 15:04:05 MST")
+ "FeedDescription" ($description | plainify | htmlUnescape)
+ "FeedDescriptionShort" (delimit (first 2 (split ($description | plainify | htmlUnescape) "\n")) " " | truncate 250 "...")
+ "FeedEnclosure" ($enclosure | plainify | htmlUnescape)
+ "FeedImageLink" ($imageLink | plainify | htmlUnescape)
+ "FeedLink" ($link | plainify | htmlUnescape)
+ "FeedName" (or $retitle (delimit (first 2 (split ($sourceTitle | plainify | htmlUnescape) " ")) " "))
+ "FeedSourceDescription" ($sourceDescription | plainify | htmlUnescape)
+ "FeedSourceDomain" ($sourceDomain | plainify | htmlUnescape)
+ "FeedSourceLink" ($sourceLink | plainify | htmlUnescape)
+ "FeedSourceHome" ($sourceHome | plainify | htmlUnescape)
+ "FeedSourceTitle" ($sourceTitle | plainify | htmlUnescape)
+ "FeedTitle" ($title | plainify | htmlUnescape)
)
-}}
@@ -229,12 +229,12 @@
"description" (or .FeedSourceDescription .FeedSourceTitle "No source description found.")
"domain" .FeedSourceDomain
"enclosure" .FeedEnclosure
- "favicon" $imageSource.RelPermalink
+ "favicon" (strings.TrimPrefix ("" | absURL) $imageSource.Permalink)
"home" .FeedSourceHome
"link" .FeedLink
"name" .FeedName
"source" .FeedSourceLink
- "tags" "[rss]"
+ "tags" "[feeds]"
)
$template
-}}
diff --git a/themes/default/layouts/partials/function-page-modified.html b/themes/default/layouts/partials/function-page-modified.html
index 0b53acb..43bea9f 100644
--- a/themes/default/layouts/partials/function-page-modified.html
+++ b/themes/default/layouts/partials/function-page-modified.html
@@ -1,26 +1,34 @@
-{{- $input := . -}}
+{{- $input := .Context -}}
+{{- $disable := or .Disable false -}}
{{- $pageContext := $input -}}
+{{- $format := or .Format "index.html" -}}
-{{- $markdown := print "content/" $pageContext.File -}}
-{{- $markdownModTime := "" -}}
{{- $page := print "public/" (strings.TrimPrefix
$pageContext.Page.Site.BaseURL
$pageContext.Page.Permalink
- ) "index.html"
+ ) $format
-}}
+
{{- $pageModTime := "" -}}
+{{- $markdownModTime := "" -}}
+{{- $markdownContent := print "content/" $pageContext.File -}}
+{{- $markdownPublic := print "public/data/generates/content/" $pageContext.File -}}
+
+{{- if fileExists $markdownContent -}}
+ {{- $markdownModTime = (os.Stat $markdownContent).ModTime -}}
+{{- end -}}
-{{- if fileExists $markdown -}}
- {{- $markdownModTime = (os.Stat $markdown).ModTime -}}
+{{- if fileExists $markdownPublic -}}
+ {{- $markdownModTime = (os.Stat $markdownPublic).ModTime -}}
{{- end -}}
{{- if fileExists $page -}}
{{- $pageModTime = (os.Stat $page).ModTime -}}
{{- end -}}
-{{- $modified := gt $markdownModTime $pageModTime -}}
+{{- $page = gt $markdownModTime $pageModTime -}}
-{{- $output := or $modified (in (slice
+{{- $modified := or $page (in (slice
"home"
"section"
"taxonomy"
@@ -28,4 +36,4 @@
) $pageContext.Page.Kind)
-}}
-{{- return $output -}}
+{{- return (or $disable $modified) -}}
diff --git a/themes/default/layouts/partials/gallery-walk.html b/themes/default/layouts/partials/gallery-walk.html
index 6c2206f..ca95d3f 100644
--- a/themes/default/layouts/partials/gallery-walk.html
+++ b/themes/default/layouts/partials/gallery-walk.html
@@ -1,18 +1,9 @@
-{{- $data := slice -}}
-{{- $author := partial "function-authors-data.html" . -}}
+{{- $data := slice -}}
+{{- $author := partial "function-authors-data.html" . -}}
+{{- $filteredPages := partial "function-filters-content.html" .Site.RegularPages -}}
-{{- $mimes := slice
- "image/apng"
- "image/avif"
- "image/gif"
- "image/jpeg"
- "image/png"
- "image/svg+xml"
- "image/webp"
--}}
-
-{{- range (where .Site.RegularPages "Params.Author" $author.user) -}}
- {{- if in .Content "<figure>" -}}
+{{- range (where $filteredPages "Section" $author.user) -}}
+ {{- if in .Content "<picture>" -}}
{{- $data = $data | append (dict
"alt" (delimit (findRE `(?sU)alt=".*"` .Content 1) "")
"height" (delimit (findRE `(?sU)height=".*"` .Content 1) "")
@@ -35,16 +26,20 @@
{{- range $image := $data }}
<a href="{{ $image.relatedHref }}">
<picture>
- <source
- {{ $image.srcset | safeHTMLAttr }}
- {{ $image.type | safeHTMLAttr }}
- />
+ {{- with $image.srcset -}}
+ <source
+ {{ $image.srcset | safeHTMLAttr }}
+ {{ $image.type | safeHTMLAttr }}
+ />
+ {{- end -}}
<img
loading="lazy"
{{ $image.alt | safeHTMLAttr }}
{{ $image.title | safeHTMLAttr }}
+ {{ with ne (index (last 1 (split $image.width "=")) 0) `""` }}
{{ $image.width | safeHTMLAttr }}
{{ $image.height | safeHTMLAttr }}
+ {{ end }}
{{ $image.src | safeHTMLAttr }}
{{ $image.style | safeHTMLAttr }}
/>
diff --git a/themes/default/layouts/partials/gallery.html b/themes/default/layouts/partials/gallery.html
index 8aaa2c8..135aa14 100644
--- a/themes/default/layouts/partials/gallery.html
+++ b/themes/default/layouts/partials/gallery.html
@@ -7,7 +7,7 @@
{{- (resources.Get $gallery).Content | safeHTML -}}
{{- else -}}
<footer>
- <code>No media found!</code>
+ <code>No items found!</code>
</footer>
{{- end -}}
</aside>
diff --git a/themes/default/layouts/partials/generate-authors.html b/themes/default/layouts/partials/generate-authors.html
index 61cc5a6..d1fc0c2 100644
--- a/themes/default/layouts/partials/generate-authors.html
+++ b/themes/default/layouts/partials/generate-authors.html
@@ -1,13 +1,13 @@
-{{- range .Site.Author.list -}}
+{{- range $author := .Site.Author.list -}}
- {{- if not (fileExists (print "data/" . ".yaml")) -}}
+ {{- if not (fileExists (print "data/authors/" $author ".yaml")) -}}
{{- $configuration := resources.Get "templates/author.yaml" -}}
{{- $configuration := resources.ExecuteAsTemplate
- (print "/data/generates/authors/" . ".yaml")
+ (print "/data/generates/authors/" $author ".yaml")
(dict
- "Name" (title .)
- "User" .
+ "Name" (title $author)
+ "User" $author
)
$configuration
-}}
@@ -18,9 +18,9 @@
{{- $markdown := resources.Get "templates/markdown-frontmatter.yaml" -}}
{{- $template := resources.ExecuteAsTemplate
- (print "/data/generates/content/" . "/" "_index.md")
+ (print "/data/generates/content/" $author "/" "_index.md")
(dict
- "author" .
+ "author" $author
"layout" "section"
)
$markdown
@@ -28,9 +28,9 @@
{{- $writeToFile := $template.Permalink -}}
{{- $template := resources.ExecuteAsTemplate
- (print "/data/generates/content/" . "/feeds/" "_index.md")
+ (print "/data/generates/content/" $author "/feeds/" "_index.md")
(dict
- "author" .
+ "author" $author
"layout" "section.feeds"
)
$markdown
@@ -38,9 +38,9 @@
{{- $writeToFile := $template.Permalink -}}
{{- $template := resources.ExecuteAsTemplate
- (print "/data/generates/content/" . "/media/" "_index.md")
+ (print "/data/generates/content/" $author "/media/" "_index.md")
(dict
- "author" .
+ "author" $author
"layout" "section.media"
)
$markdown
@@ -48,19 +48,19 @@
{{- $writeToFile := $template.Permalink -}}
{{- $template := resources.ExecuteAsTemplate
- (print "/data/generates/content/" . "/likes/" "_index.md")
+ (print "/data/generates/content/" $author "/marks/" "_index.md")
(dict
- "author" .
- "layout" "section.likes"
+ "author" $author
+ "layout" "section.marks"
)
$markdown
-}}
{{- $writeToFile := $template.Permalink -}}
{{- $template := resources.ExecuteAsTemplate
- (print "/data/generates/content/" . "/drafts/" "_index.md")
+ (print "/data/generates/content/" $author "/drafts/" "_index.md")
(dict
- "author" .
+ "author" $author
"layout" "section.drafts"
)
$markdown
diff --git a/themes/default/layouts/partials/base-canonical.html b/themes/default/layouts/partials/head-canonical.html
index 051e450..051e450 100644
--- a/themes/default/layouts/partials/base-canonical.html
+++ b/themes/default/layouts/partials/head-canonical.html
diff --git a/themes/default/layouts/partials/base-csp.html b/themes/default/layouts/partials/head-csp.html
index d34043e..d34043e 100644
--- a/themes/default/layouts/partials/base-csp.html
+++ b/themes/default/layouts/partials/head-csp.html
diff --git a/themes/default/layouts/partials/head-css.html b/themes/default/layouts/partials/head-css.html
new file mode 100644
index 0000000..6e9eb56
--- /dev/null
+++ b/themes/default/layouts/partials/head-css.html
@@ -0,0 +1,26 @@
+{{- $default := resources.Get "css/default.css" -}}
+{{- $syntax := resources.Get "css/default-syntax.css" -}}
+{{- $simple := resources.Get "css/default-simple.css" -}}
+{{- $fast := resources.Get "css/default-fast.css" -}}
+{{- $math := resources.Get "css/default-mathml.css" -}}
+
+{{- $css :=
+ slice
+ $default
+ $syntax
+ | resources.Concat "css/bundle.css"
+ | resources.Minify
+ | fingerprint
+-}}
+
+{{ if .Site.Params.site.production }}
+<link rel="stylesheet" href="{{ $css.Permalink }}" title="Default" />
+{{ else }}
+<link rel="stylesheet" href="{{ $default.Permalink }}" title="Default" />
+<link rel="stylesheet" href="{{ $syntax.Permalink }}" />
+{{ end }}
+
+<link rel="stylesheet" href="{{ $math.Permalink }}" />
+
+<link rel="alternate stylesheet" href="{{ $simple.Permalink }}" />
+<link rel="alternate stylesheet" href="{{ $fast.Permalink }}" />
diff --git a/themes/default/layouts/partials/base-description.html b/themes/default/layouts/partials/head-description.html
index 94b10c2..89e4691 100644
--- a/themes/default/layouts/partials/base-description.html
+++ b/themes/default/layouts/partials/head-description.html
@@ -4,5 +4,5 @@
{{ .Summary }}
{{- else -}}
{{- block "description" . -}}{{- end -}}
- {{- partial "base-title.html" . -}}
+ {{- partial "head-title.html" . -}}
{{- end -}}
diff --git a/themes/default/layouts/partials/head-discovery.html b/themes/default/layouts/partials/head-discovery.html
new file mode 100644
index 0000000..8c7272f
--- /dev/null
+++ b/themes/default/layouts/partials/head-discovery.html
@@ -0,0 +1,62 @@
+{{- $author := partial "function-authors-data.html" . -}}
+
+{{- with (eq .Page.Kind "home") -}}
+<link
+ rel="alternate"
+ type="application/rss+xml"
+ title="{{ $.Site.Title }} Feed"
+ href="{{ "" | absURL }}/rss.xml"
+/>
+
+ {{- range $author := $.Site.Sections }}
+ <link
+ rel="alternate"
+ type="application/rss+xml"
+ title="{{ $author.Page.Type }}'s Feed"
+ href="{{ print $author.Permalink "rss.xml" | absURL }}"
+ />
+ {{ end }}
+{{- end -}}
+
+{{- with (eq .Page.Kind "section") -}}
+<link
+ rel="alternate"
+ type="application/rss+xml"
+ title="{{ $author.name }}'s Feed"
+ href="{{ print ("" | absURL) "/" $.Section }}/rss.xml"
+/>
+
+{{- with $author.feeds.rss }}
+ {{ range $author.feeds.rss }}
+ {{ $data := split . " " }}
+ {{- $url := delimit (first 1 $data) "" -}}
+ {{- $retitle := trim (delimit (after 1 $data) " ") " " -}}
+ {{- $retitle := and $retitle (print $retitle "'s Feed") -}}
+
+ <link
+ rel="alternate"
+ type="application/rss+xml"
+ title="{{ or $retitle $url }}"
+ href="{{ $url }}"
+ />
+ {{ end }}
+{{ end }}
+{{- end -}}
+
+{{- with (eq .Page.Kind "taxonomy") -}}
+<link
+ rel="alternate"
+ type="application/rss+xml"
+ title="{{ $.Title }} Feed"
+ href="{{ $.Permalink }}rss.xml"
+/>
+{{- end -}}
+
+{{- with (eq .Page.Kind "term") -}}
+<link
+ rel="alternate"
+ type="application/rss+xml"
+ title="#{{ lower $.Title }} Tag Feed"
+ href="{{ $.Permalink }}rss.xml"
+/>
+{{- end }}
diff --git a/themes/default/layouts/partials/head-embed.html b/themes/default/layouts/partials/head-embed.html
new file mode 100644
index 0000000..e9c44d7
--- /dev/null
+++ b/themes/default/layouts/partials/head-embed.html
@@ -0,0 +1,4 @@
+<head>
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
+ {{- partial "head-css.html" . -}}
+</head>
diff --git a/themes/default/layouts/partials/base-js.html b/themes/default/layouts/partials/head-js.html
index a491eee..a491eee 100644
--- a/themes/default/layouts/partials/base-js.html
+++ b/themes/default/layouts/partials/head-js.html
diff --git a/themes/default/layouts/partials/head-manifest.html b/themes/default/layouts/partials/head-manifest.html
new file mode 100644
index 0000000..52be1f9
--- /dev/null
+++ b/themes/default/layouts/partials/head-manifest.html
@@ -0,0 +1,58 @@
+{{- $author := .Section -}}
+{{- $home := or ("" | absURL) "/" -}}
+{{- $kind := in (slice "home" "taxonomy" "term") .Page.Kind -}}
+{{- $logo := .Site.Params.webmanifest.logo -}}
+{{- $profile := print "public/data/media/" $author "/" $author "-profile" -}}
+
+{{- if not $kind -}}
+ {{- $home = print ("" | absURL) "/" $author "/" -}}
+ {{- if fileExists (print $profile ".gif") -}} {{- $logo = (print $profile ".gif") -}} {{- end -}}
+ {{- if fileExists (print $profile ".webp") -}} {{- $logo = (print $profile ".webp") -}} {{- end -}}
+ {{- if fileExists (print $profile ".png") -}} {{- $logo = (print $profile ".png") -}} {{- end -}}
+{{- end -}}
+
+{{- with $logo = resources.Get $logo -}}
+
+{{- $16 := $logo.Fit "16x16" -}}
+{{- $32 := $logo.Fit "32x32" -}}
+{{- $180 := $logo.Fit "180x180" -}}
+{{- $192 := $logo.Fit "192x192" -}}
+{{- $512 := $logo.Fit "512x512" -}}
+
+{{- if (eq $.Page.Kind "home") -}}
+ {{- $writeToFile := ($32.Content | resources.FromString "/favicon.ico").Permalink -}}
+{{- end -}}
+
+<link rel="icon" type="image/x-icon" sizes="32x32" href="data:image/ico;base64,{{ $32.Content | base64Encode }}" />
+<link rel="icon" type="{{ $16.MediaType }}" sizes="16x16" href="data:{{ $16.MediaType }};base64,{{ $16.Content | base64Encode }}" />
+<link rel="icon" type="{{ $32.MediaType }}" sizes="32x32" href="data:{{ $32.MediaType }};base64,{{ $32.Content | base64Encode }}" />
+<link rel="apple-touch-icon" type="{{ $180.MediaType }}" sizes="180x180" href="data:{{ $180.MediaType }};base64,{{ $180.Content | base64Encode }}" />
+
+<link rel="home" href="{{ $home }}" />
+
+{{ "" -}} <!-- Newline -->
+
+{{- with $manifest := $.Site.Params.webmanifest -}}
+<link rel="manifest" href='data:application/manifest+json,{{ merge $manifest (dict
+ "start_url" $home
+ "icons" (slice
+ (dict
+ "sizes" "192x192"
+ "src" (print "data:" $192.MediaType ";base64," ($192.Content | base64Encode))
+ "type" (print $192.MediaType))
+ (dict
+ "sizes" "512x512"
+ "src" (print "data:" $512.MediaType ";base64," ($512.Content | base64Encode))
+ "type" (print $512.MediaType))))
+ | jsonify
+ | urlquery
+}}'>
+
+<meta name="msapplication-TileColor" content="#da532c" />
+<meta name="msapplication-config" content="none" />
+<meta name="msapplication-square70x70logo" content="none" />
+<meta name="msapplication-square150x150logo" content="data:{{ $180.MediaType }};base64,{{ $180.Content | base64Encode }}" />
+<meta name="msapplication-square310x310logo" content="none" />
+<meta name="msapplication-wide310x150logo" content="none" />
+{{- end -}}
+{{- end -}}
diff --git a/themes/default/layouts/partials/head-search.html b/themes/default/layouts/partials/head-search.html
new file mode 100644
index 0000000..89113ab
--- /dev/null
+++ b/themes/default/layouts/partials/head-search.html
@@ -0,0 +1,5 @@
+{{- with .Site.Params.search.verification -}}
+{{- range $name, $content := . }}
+<meta name="{{ $name }}" content="{{ $content }}" />
+{{- end }}
+{{ end }}
diff --git a/themes/default/layouts/partials/base-title.html b/themes/default/layouts/partials/head-title.html
index b34355d..fff4530 100644
--- a/themes/default/layouts/partials/base-title.html
+++ b/themes/default/layouts/partials/head-title.html
@@ -1,4 +1,4 @@
-{{- $author := index .Site.Data ((or .Params.author .Site.Author.default.title) | default "default") -}}
+{{- $author := index .Site.Data.authors .Section -}}
{{- if not (eq .Title $.Site.Title) -}}
{{- with $title := or .Title .Summary -}}
diff --git a/themes/default/layouts/partials/head.html b/themes/default/layouts/partials/head.html
new file mode 100644
index 0000000..1668d57
--- /dev/null
+++ b/themes/default/layouts/partials/head.html
@@ -0,0 +1,72 @@
+{{- $noindex := "" -}}
+{{- $image := "" -}}
+{{- $author := .Section -}}
+{{- $kind := in (slice "home" "taxonomy" "term") .Page.Kind -}}
+
+{{- if not $kind -}}
+ {{- $image = print ("" | absURL) "/data/media/" $author "/" $author "-profile.png" -}}
+{{- end -}}
+
+{{- with or .Params.Feed .Params.Unlisted .Params.ExpiryDate -}}
+ {{- $noindex = "noindex,nofollow" -}}
+{{- end }}
+
+<!-- HTML Meta Tags -->
+<meta charset="utf-8" />
+<meta name="author" content="{{ or $author $.Site.Title -}}" />
+<meta name="robots" content="{{ or $noindex .Site.Params.site.robots "index,follow" }}" />
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<meta name="keywords" content="{{- partial "head-title.html" . -}}" />
+<meta name="generator" content="Hugo {{ hugo.Version }}" />
+
+<!-- Search Engine Tags -->
+<meta itemprop="name" content="{{ partial "head-title.html" . -}}" />
+<meta itemprop="description" content="{{- partial "head-description.html" . -}}" />
+<meta itemprop="image" content="{{ $image }}" />
+
+<!-- Open Graph Meta Tags -->
+<meta property="og:title" content="{{ partial "head-title.html" . -}}" />
+<meta property="og:description" content="{{- partial "head-description.html" . -}}" />
+<meta property="og:url" content="{{ .Permalink }}" />
+<meta property="og:image" content="{{ $image }}" />
+<meta property="og:type" content="website" />
+<meta property="article:published_time" content="{{ (or .Params.PublishDate now.UTC) | time.Format "2006-01-02T15:04:05Z" }}" />
+<meta property="article:modified_time " content="{{ (or .Params.LastMod now.UTC) | time.Format "2006-01-02T15:04:05Z" }}" />
+
+<!-- Twitter Meta Tags -->
+<meta name="twitter:card" content="summary_large_image" />
+<meta name="twitter:title" content="{{ partial "head-title.html" . -}}" />
+<meta name="twitter:description" content="{{- partial "head-description.html" . -}}" />
+<meta name="twitter:image" content="{{ $image }}" />
+
+<!-- Extra Meta Tags -->
+<meta name='base-url' content="{{ "" | absURL }}" />
+<meta name='last-modified' content="{{ now.UTC.Format "Mon, 02 Jan 2006 15:04:05 GMT" }}" />
+
+<!-- Search Verification -->
+{{- partial "head-search.html" . -}}
+
+<!-- Feed Discovery -->
+{{- partial "head-discovery.html" . -}}
+
+<!-- Canonicalization -->
+{{- partial "head-canonical.html" . -}}
+
+<!-- Styles -->
+{{- partial "head-css.html" . -}}
+
+<!-- Scripts -->
+{{- partial "head-js.html" . -}}
+
+<!-- Progressive Enhancement -->
+{{- partial "head-manifest.html" . -}}
+
+<!-- Content Security Policy -->
+{{- partial "head-csp.html" . -}}
+
+<!-- No Scripts -->
+<noscript>
+ <style>
+ {{ safeCSS (readFile "assets/css/noscript.css") }}
+ </style>
+</noscript>
diff --git a/themes/default/layouts/partials/styles-image-gradient.html b/themes/default/layouts/partials/image-gradient.css.html
index 794ea8b..794ea8b 100644
--- a/themes/default/layouts/partials/styles-image-gradient.html
+++ b/themes/default/layouts/partials/image-gradient.css.html
diff --git a/themes/default/layouts/partials/menu-datetime.html b/themes/default/layouts/partials/menu-datetime.html
new file mode 100644
index 0000000..20ef50e
--- /dev/null
+++ b/themes/default/layouts/partials/menu-datetime.html
@@ -0,0 +1,22 @@
+{{- $href := print .Permalink -}}
+
+<meta-datetime>
+ <a href="{{ $href }}">
+ {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/calendar.svg")) -}}
+ <time
+ data-type="localDate"
+ datetime="{{ .Date | time.Format "2006-01-02T15:04:05Z" }}"
+ >
+ {{ .Date | time.Format "Jan 2 2006" -}}
+ </time>
+ </a>
+ <a href="{{ $href }}">
+ {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/clock.svg")) -}}
+ <time
+ data-type="localTime"
+ datetime="{{ .Date | time.Format "2006-01-02T15:04:05Z" }}"
+ >
+ {{ .Date | time.Format "15:04 MST" -}}
+ </time>
+ </a>
+</meta-datetime>
diff --git a/themes/default/layouts/partials/menu-embed.html b/themes/default/layouts/partials/menu-embed.html
new file mode 100644
index 0000000..1b03d27
--- /dev/null
+++ b/themes/default/layouts/partials/menu-embed.html
@@ -0,0 +1,8 @@
+{{- $href := print .Permalink -}}
+
+<meta-embed>
+ <a href="{{ print $href "embed.html" }}">
+ {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/tabler/code.svg")) -}}
+ <span>Embed</span>
+ </a>
+</meta-embed>
diff --git a/themes/default/layouts/partials/meta-markdown.html b/themes/default/layouts/partials/menu-markdown.html
index 5300af5..6e54238 100644
--- a/themes/default/layouts/partials/meta-markdown.html
+++ b/themes/default/layouts/partials/menu-markdown.html
@@ -4,10 +4,10 @@
{{- $href := print .Site.BaseURL "/" (partial "function-paths.html").markdown $source -}}
{{- $title := .File.LogicalName -}}
- <micro-metadata-source>
+ <meta-source>
<a href="{{ $href }}" title="{{ $title }}">
- {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/code.svg")) -}}
- <span>markdown</span>
+ {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/tabler/square-letter-m.svg")) -}}
+ <span>Markdown</span>
</a>
- </micro-metadata-source>
+ </meta-source>
{{- end -}}
diff --git a/themes/default/layouts/partials/meta-permalink.html b/themes/default/layouts/partials/menu-permalink.html
index 3ab09a2..6f19559 100644
--- a/themes/default/layouts/partials/meta-permalink.html
+++ b/themes/default/layouts/partials/menu-permalink.html
@@ -1,11 +1,11 @@
{{- $href := print .Permalink "#" (partial "card-id.html" .) -}}
-<micro-metadata-permalink>
+<meta-permalink>
<a title="#{{ partial "card-id.html" . }}" href="{{ $href }}">
{{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/link.svg")) -}}
- <span>permalink</span>
+ <span>Permalink</span>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
</a>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
-</micro-metadata-permalink>
+</meta-permalink>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/partials/menu-plain.html b/themes/default/layouts/partials/menu-plain.html
new file mode 100644
index 0000000..3dee808
--- /dev/null
+++ b/themes/default/layouts/partials/menu-plain.html
@@ -0,0 +1,9 @@
+{{- $href := print .Permalink -}}
+{{- $plain := print $href "index.txt" -}}
+
+<meta-plain>
+ <a href="{{ $plain }}">
+ {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/tabler/notes.svg")) -}}
+ <span>Plaintext</span>
+ </a>
+</meta-plain>
diff --git a/themes/default/layouts/partials/meta-anchored.html b/themes/default/layouts/partials/meta-anchored.html
index 31b910f..872f98e 100644
--- a/themes/default/layouts/partials/meta-anchored.html
+++ b/themes/default/layouts/partials/meta-anchored.html
@@ -1,19 +1,24 @@
-{{ if or .Weight .Params.Liked .Params.feed }}
- <micro-metadata-anchored>
+{{- if or .Weight .Params.Liked .Params.feed -}}
+ <meta-anchored>
+ {{- $author := .Section -}}
{{- partial "meta-via.html" . -}}
- {{ if .Weight }}
- <anchored-pinned>
+ {{- if .Weight -}}
+ <a data-anchored="pinned">
{{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/tabler/pinned.svg")) }}
<span>Pinned</span>
- </anchored-pinned>
- {{ end }}
+ </a>
+ {{- end -}}
- {{ if .Params.Liked }}
- <anchored-liked>
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/heart.svg")) }}
- <span>Liked</span>
- </anchored-liked>
- {{ end }}
- </micro-metadata-anchored>
-{{ end }}
+ {{- if .Params.Marked -}}
+ <a
+ href="{{ "" | absURL }}/{{ $author }}/marks/#marks"
+ data-anchored="marked"
+ data-hover=""
+ >
+ {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/bookmark.svg")) }}
+ <span>Marked</span>
+ </a>
+ {{- end -}}
+ </meta-anchored>
+{{- end -}}
diff --git a/themes/default/layouts/partials/meta-context-menu.html b/themes/default/layouts/partials/meta-context-menu.html
deleted file mode 100644
index 977f938..0000000
--- a/themes/default/layouts/partials/meta-context-menu.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{{- $id := partial "card-id.html" . -}}
-{{- $href := print .Permalink -}}
-{{- $plain := print $href "index.txt" -}}
-
-<micro-metadata-menu>
- <context-control>
- <label for="context-metadata-{{ $id }}">
- {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-down-circle.svg")) -}}
- <span>menu</span>
- </label>
- <input hidden type="checkbox" id="context-metadata-{{ $id }}" />
- <context-menu anchor>
- {{- partial "meta-markdown.html" . -}}
- <micro-metadata-plain>
- <a href="{{ $plain }}">
- {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/file-text.svg")) -}}
- <span>plaintext</span>
- </a>
- </micro-metadata-plain>
- {{- partial "meta-permalink.html" . -}}
- <micro-metadata-datetime>
- <a title="{{ .Date.Local | time.Format "15:04 Jan 2 2006" -}}" href="{{ $href }}">
- {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/calendar.svg")) -}}
- <span>{{ .Date.Local | time.Format "Jan 2 2006" | lower -}}</span>
- </a>
- </micro-metadata-datetime>
- </context-menu>
- </context-control>
-</micro-metadata-menu>
-{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/partials/meta-date-time.html b/themes/default/layouts/partials/meta-datetime.html
index 5b26c68..e0329bb 100644
--- a/themes/default/layouts/partials/meta-date-time.html
+++ b/themes/default/layouts/partials/meta-datetime.html
@@ -1,14 +1,14 @@
-<micro-metadata-datetime
-title="{{ .Date | time.Format "Posted: Monday, January 2, 2006 at 15:04:05 MST" }}
-{{ if .Lastmod.After .Date }}{{ .Lastmod | time.Format "Edited: Monday, January 2, 2006 at 15:04:05 MST" }}{{ end }}">
+<meta-datetime
+title="{{ .Date | time.Format "Posted: Monday January 2 2006 at 15:04:05 MST" }}
+{{ if .Lastmod.After .Date }}{{ .Lastmod | time.Format "Edited: Monday January 2 2006 at 15:04:05 MST" }}{{ end }}">
{{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/calendar.svg")) -}}
<time datetime="{{ .Date | time.Format "2006-01-02T15:04:05Z" }}">
- {{ (.Date.Local | time.Format "15:04 Jan 2 2006") -}}
+ {{ (.Date | time.Format "Mon Jan 2 2006") -}}
</time>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
{{ if .Lastmod.After .Date }}
<span>(edited)</span>
{{- end -}}
{{- /* This comment removes trailing newlines and white spaces. */ -}}
-</micro-metadata-datetime>
+</meta-datetime>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/partials/meta-draft.html b/themes/default/layouts/partials/meta-draft.html
index 8662b32..d441b9a 100644
--- a/themes/default/layouts/partials/meta-draft.html
+++ b/themes/default/layouts/partials/meta-draft.html
@@ -1,9 +1,9 @@
{{- if .Draft -}}
- <micro-metadata-draft>
+ <meta-draft>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
<em>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
- <a href="{{ .Site.BaseURL }}/{{ .Type }}/drafts/">
+ <a href="{{ .Site.BaseURL }}/{{ .Type }}/drafts/#drafts">
{{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/edit.svg")) -}}
<span>Draft</span>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
@@ -11,5 +11,5 @@
{{- /* This comment removes trailing newlines and white spaces. */ -}}
</em>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
- </micro-metadata-draft>
+ </meta-draft>
{{- end -}}
diff --git a/themes/default/layouts/partials/meta-expiry-date.html b/themes/default/layouts/partials/meta-expirydate.html
index 6eef09e..1feefd1 100644
--- a/themes/default/layouts/partials/meta-expiry-date.html
+++ b/themes/default/layouts/partials/meta-expirydate.html
@@ -8,7 +8,7 @@
{{- $title = print "Self destructed" " " $date -}}
{{- end -}}
- <micro-metadata-expiry
+ <meta-expiry
title="{{ $title }}">
{{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/trash-2.svg")) -}}
<time datetime= "{{- .ExpiryDate | time.Format "2006-01-02T15:04:05Z" -}}">
@@ -16,5 +16,5 @@
{{- /* This comment removes trailing newlines and white spaces. */ -}}
</time>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
- </micro-metadata-expiry>
+ </meta-expiry>
{{- end -}}
diff --git a/themes/default/layouts/partials/meta-handle.html b/themes/default/layouts/partials/meta-handle.html
index da2070b..ee0cc50 100644
--- a/themes/default/layouts/partials/meta-handle.html
+++ b/themes/default/layouts/partials/meta-handle.html
@@ -1,7 +1,7 @@
{{- $author := .Section -}}
-{{- $host := or (urls.Parse .Site.BaseURL).Host "localhost" -}}
-{{- $href := print .Site.BaseURL "/" $author "/#" -}}
+{{- $host := or (urls.Parse ("" | absURL)).Host "localhost" -}}
+{{- $href := print ("" | absURL) "/" $author "/" -}}
{{- $title := print $author "@" $host -}}
@@ -11,7 +11,7 @@
{{- $title = $.Params.feed.domain -}}
{{- end -}}
-<micro-metadata-handle>
+<meta-handle>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
<a
title="{{ $title }}"
@@ -21,5 +21,5 @@
{{- /* This comment removes trailing newlines and white spaces. */ -}}
</a>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
-</micro-metadata-handle>
+</meta-handle>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/partials/meta-menu.html b/themes/default/layouts/partials/meta-menu.html
new file mode 100644
index 0000000..f5e127d
--- /dev/null
+++ b/themes/default/layouts/partials/meta-menu.html
@@ -0,0 +1,23 @@
+{{- $id := partial "card-id.html" . -}}
+
+<menu>
+ <li>
+ <label for="context-metadata-{{ $id }}">
+ {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-down-circle.svg")) -}}
+ <span>menu</span>
+ </label>
+ </li>
+ <li>
+ <input hidden="" type="checkbox" id="context-metadata-{{ $id }}" />
+ <context-menu position="anchor">
+
+ {{- partial "menu-markdown.html" . -}}
+ {{- partial "menu-plain.html" . -}}
+ {{- partial "menu-embed.html" . -}}
+ {{- partial "menu-permalink.html" . -}}
+ {{- partial "menu-datetime.html" . -}}
+
+ </context-menu>
+ </li>
+</menu>
+{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/partials/meta-name.html b/themes/default/layouts/partials/meta-name.html
index e381259..7c2ca61 100644
--- a/themes/default/layouts/partials/meta-name.html
+++ b/themes/default/layouts/partials/meta-name.html
@@ -1,6 +1,6 @@
{{- $author := partial "function-authors-data.html" . -}}
-{{- $href := print .Site.BaseURL "/" $author.user "/#" -}}
+{{- $href := print ("" | absURL) "/" $author.user "/" -}}
{{- $name := $author.name -}}
{{- $title := $name -}}
@@ -10,8 +10,8 @@
{{- $title = $name -}}
{{- end -}}
-<micro-metadata-name title="{{ $title }}">
+<meta-name title="{{ $title }}">
<b><a href="{{ $href }}">{{ $name }}</a></b>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
-</micro-metadata-name>
+</meta-name>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/partials/meta-read-time.html b/themes/default/layouts/partials/meta-readtime.html
index 69c0ffa..43b5303 100644
--- a/themes/default/layouts/partials/meta-read-time.html
+++ b/themes/default/layouts/partials/meta-readtime.html
@@ -4,9 +4,9 @@
{{- $seconds = "1" -}}
{{- end -}}
-<micro-metadata-readtime title="Takes {{ $seconds }} second{{- if not (eq $seconds "1") -}}s{{- end }} to read">
- {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/clock.svg")) -}}
- <span>{{ $seconds }} sec</span>
+<meta-readtime title="{{ $seconds }} second{{- if not (eq $seconds "1") -}}s{{- end }} to read">
+ {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/eye.svg")) }}
+ <span>{{ $seconds }}s read</span>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
-</micro-metadata-readtime>
+</meta-readtime>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/partials/meta-tags.html b/themes/default/layouts/partials/meta-tags.html
deleted file mode 100644
index cd13781..0000000
--- a/themes/default/layouts/partials/meta-tags.html
+++ /dev/null
@@ -1,6 +0,0 @@
-{{- with .Params.tags -}}
- {{- range $tags, $tag := sort $.Params.tags }}
- {{ $link := print ("tags/" | relURL) ($tag | urlize) "/" }}
- {{- print "[#" $tag "](" $link ")" | markdownify -}}
- {{- end -}}
-{{- end -}}
diff --git a/themes/default/layouts/partials/meta-unlisted.html b/themes/default/layouts/partials/meta-unlisted.html
index 827de3c..df67e4e 100644
--- a/themes/default/layouts/partials/meta-unlisted.html
+++ b/themes/default/layouts/partials/meta-unlisted.html
@@ -1,7 +1,7 @@
{{- if .Params.Unlisted -}}
- <micro-metadata-unlisted title="This message is off the record">
+ <meta-unlisted title="This message is off the record">
{{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/eye-off.svg")) -}}
<span>unlisted</span>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
- </micro-metadata-unlisted>
+ </meta-unlisted>
{{- end -}}
diff --git a/themes/default/layouts/partials/meta-via.html b/themes/default/layouts/partials/meta-via.html
index 596749e..c34ca73 100644
--- a/themes/default/layouts/partials/meta-via.html
+++ b/themes/default/layouts/partials/meta-via.html
@@ -1,14 +1,13 @@
{{- $author := .Section -}}
{{- if .Params.feed -}}
-<anchored-via>
- {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/rss.svg")) -}}
<a
- data-hover
- title="{{ $author }}@{{ or (urls.Parse .Site.BaseURL).Host "localhost" }}"
- href="{{ .Site.BaseURL }}/{{ $author }}/feeds/#"
+ data-hover=""
+ data-anchored="via"
+ href="{{ "" | absURL }}/{{ $author }}/feeds/#feeds"
+ title="{{ $author }}@{{ or (urls.Parse ("" | absURL)).Host "localhost" }}"
>
+ {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/tabler/rss.svg")) -}}
via @{{ $author }}
</a>
-</anchored-via>
{{- end -}}
diff --git a/themes/default/layouts/partials/meta-view.html b/themes/default/layouts/partials/meta-view.html
index ccdac1c..33aee6b 100644
--- a/themes/default/layouts/partials/meta-view.html
+++ b/themes/default/layouts/partials/meta-view.html
@@ -1,12 +1,12 @@
{{- $href := or .Params.Feed.link .Permalink -}}
-<micro-metadata-view>
+<meta-view>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
- <a href="{{ $href }}">
+ <a href="{{ $href }}" title="{{- partial "meta-title.html" . -}}">
{{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/external-link.svg")) -}}
<span>view</span>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
</a>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
-</micro-metadata-view>
+</meta-view>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/partials/meta-word-count.html b/themes/default/layouts/partials/meta-wordcount.html
index 8aaa30d..b6ec95e 100644
--- a/themes/default/layouts/partials/meta-word-count.html
+++ b/themes/default/layouts/partials/meta-wordcount.html
@@ -4,7 +4,7 @@
{{- $overLimit := sub .WordCount $limit -}}
{{- $bitCount := lang.FormatNumberCustom 0 (len .Content) -}}
-<micro-metadata-wordcount
+<meta-wordcount
title="
{{- if $wordLimit -}}
{{ $overLimit }} words over the limit
@@ -16,18 +16,18 @@ title="
">
{{- /* This comment removes trailing newlines and white spaces. */ -}}
<word-limit>
- {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/file-text.svg")) -}}
+ {{- safeHTML (readFile (print (partial "function-paths.html").static "/icons/tabler/notes.svg")) -}}
<word-count>
{{- if $wordLimit -}}
<em>{{ .WordCount }}</em>
{{- else -}}
- {{ .WordCount }}
+ <sup>{{ .WordCount }}</sup>
{{- end -}}
- /{{ $limit }} words
+ /<sub>{{ $limit }}</sub> words
{{- /* This comment removes trailing newlines and white spaces. */ -}}
</word-count>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
</word-limit>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
-</micro-metadata-wordcount>
+</meta-wordcount>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/partials/navigator-middle.html b/themes/default/layouts/partials/navigator-middle.html
index 46c4060..7259b43 100644
--- a/themes/default/layouts/partials/navigator-middle.html
+++ b/themes/default/layouts/partials/navigator-middle.html
@@ -1,22 +1,29 @@
-{{ $id := .Id }}
-{{ $href := .Href }}
+{{- $href := or .Href "#" -}}
+{{- $id := or .Id "top" -}}
+{{- $label := title $id -}}
+{{- $icon := readFile (print (partial "function-paths.html").static "/icons/feather/arrow-up.svg") -}}
+{{- $refresh := readFile (print (partial "function-paths.html").static "/icons/feather/refresh-cw.svg") -}}
+
+{{- with .Icon -}}
+ {{- $icon = readFile (print (partial "function-paths.html").static "/icons/feather/" . ".svg") -}}
+{{- end -}}
+
+{{- with .IconLabel -}}
+ {{- $label = . -}}
+{{- end -}}
<nav>
<icon-button>
<a
- id="{{ or $id "top" }}"
- href="{{ or $href "#" }}"
+ data-update=""
+ id="{{ $id }}"
+ href="{{ $href }}"
+ target="_self"
>
- {{ with .Icon }}
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/" . ".svg")) }}
- {{ else }}
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-up.svg")) }}
- {{ end }}
- {{ with .IconLabel }}
- <small>{{ . }}</small>
- {{ else }}
- <small>Top</small>
- {{ end }}
+ {{ safeHTML $icon }}
+ {{ safeHTML $refresh }}
+ <small>{{ $label }}</small>
+ <small>Update</small>
</a>
</icon-button>
@@ -31,7 +38,7 @@
{{ if .Context.Site.Menus.main }}
{{ range .Context.Site.Menus.main }}
- <icon-navigator hidden>
+ <icon-navigator hidden="">
<icon-button>
<a id="nav-middle-{{ path.Base .Identifier }}" href="{{ .URL | absURL }}">
{{ with .Identifier }}
@@ -45,27 +52,24 @@
{{ end }}
{{ end }}
- <search-entry id="search-frame">
- <form
- id="search-form"
- action="https://lite.duckduckgo.com/lite/">
- <input required
- id="search-input"
- name="q"
- value=""
- type="search"
- autocomplete="off"
- spellcheck="false"
+ <search-box>
+ <form role="search" action="https://lite.duckduckgo.com/lite/">
+ <input
aria-autocomplete="list"
aria-label="search input"
+ autocomplete="off"
+ id="search"
+ name="q"
+ required=""
+ spellcheck="false"
+ type="search"
+ value=""
/>
- <button id="search-submit">
+ <button type="submit">
{{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/search.svg")) }}
<small>Search</small>
</button>
- <ul hidden id="search-results"></ul>
+ <ul hidden=""></ul>
</form>
- </search-entry>
- </nav>
-
-<navigation-separator><hr hidden></navigation-separator>
+ </search-box>
+</nav>
diff --git a/themes/default/layouts/partials/navigator-right.html b/themes/default/layouts/partials/navigator-right.html
index 573cb8f..c2e6f4c 100644
--- a/themes/default/layouts/partials/navigator-right.html
+++ b/themes/default/layouts/partials/navigator-right.html
@@ -1,26 +1,7 @@
{{- partial "author-list.html" . -}}
-{{- if or
- (eq .Page.Kind "page")
- (eq .Page.Kind "section")
--}}
-
+{{- if (in (slice "page" "section") .Page.Kind) -}}
{{- partial "gallery.html" . -}}
{{- partial "following-list.html" . -}}
-
-{{- end -}}
-
-{{- if or
- (eq .Page.Kind "page")
- (eq .Page.Kind "section")
--}}
-
{{- partial "webring.html" . -}}
-
-{{- else -}}
-
- {{- range first 1 (where .Site.Pages "Params.Author" .Site.Author.default.webring) -}}
- {{- partial "webring.html" . -}}
- {{- end -}}
-
{{- end -}}
diff --git a/themes/default/layouts/partials/navigator.css.html b/themes/default/layouts/partials/navigator.css.html
new file mode 100644
index 0000000..7485408
--- /dev/null
+++ b/themes/default/layouts/partials/navigator.css.html
@@ -0,0 +1,19 @@
+icon-navigator a[href="{{ "" | absURL }}{{ .Link }}"],
+column-base[position="left"] nav a[href="{{ "" | absURL }}{{ .Link }}"] {
+ font-weight: 700;
+}
+
+column-base[position="left"] nav a[href="{{ "" | absURL }}{{ .Link }}"] {
+ background-color: #f0f6ff;
+ background-color: var(--hover-background-alternate);
+}
+
+icon-navigator a[href="{{ "" | absURL }}{{ .Link }}"] svg {
+ fill: #cce0ff;
+ fill: var(--icon-hover-background);
+}
+
+icon-navigator a[href="{{ "" | absURL }}{{ .Link }}"]:focus svg {
+ fill: #cce0ff;
+ fill: var(--icon-focus-background);
+}
diff --git a/themes/default/layouts/partials/pagination.html b/themes/default/layouts/partials/pagination.html
index fa3c85e..e64bfcf 100644
--- a/themes/default/layouts/partials/pagination.html
+++ b/themes/default/layouts/partials/pagination.html
@@ -1,67 +1,50 @@
{{- with .Paginator -}}
-
- {{- $first := "Newest" -}}
- {{- $prev := "Newer" -}}
- {{- $next := "Older" -}}
- {{- $last := "Oldest" -}}
- {{- $invisible := "data-invisible" -}}
-
- {{- $firstData := $invisible -}}
- {{- $firstHref := "" -}}
- {{- $firstTitle := $first -}}
+ {{- $firstTitle := "hidden" -}}
+ {{- $prevTitle := "hidden" -}}
+ {{- $nextTitle := "hidden" -}}
+ {{- $lastTitle := "hidden" -}}
+ {{- $firstHref := "/" -}}
+ {{- $prevHref := "/" -}}
+ {{- $nextHref := "/" -}}
+ {{- $lastHref := "/" -}}
{{- if and .HasPrev .First -}}
- {{- $firstData = "" -}}
- {{- $firstHref = .First.URL -}}
+ {{- $firstHref = .First.URL | absURL -}}
+ {{- $firstTitle = "Newest" -}}
{{- end -}}
- {{- $prevData := $invisible -}}
- {{- $prevHref := "" -}}
- {{- $prevRel := "prev" -}}
- {{- $prevTitle := $prev -}}
-
{{- with .Prev -}}
- {{- $prevData = "" -}}
- {{- $prevHref = .URL -}}
+ {{- $prevHref = .URL | absURL -}}
+ {{- $prevTitle = "Newer" -}}
{{- end -}}
- {{- $nextData := $invisible -}}
- {{- $nextHref := "" -}}
- {{- $nextRel := "next" -}}
- {{- $nextTitle := $next -}}
-
{{- if .Next -}}
- {{- $nextData = "" -}}
- {{- $nextHref = .Next.URL -}}
+ {{- $nextHref = .Next.URL | absURL -}}
+ {{- $nextTitle = "Older" -}}
{{- end -}}
- {{- $lastData := $invisible -}}
- {{- $lastHref := "" -}}
- {{- $lastTitle := $last -}}
-
{{- if and .HasNext .Last -}}
- {{- $lastData = "" -}}
- {{- $lastHref = .Last.URL -}}
+ {{- $lastHref = .Last.URL | absURL -}}
+ {{- $lastTitle = "Oldest" -}}
{{- end -}}
- <paginator-navigation{{ if eq .TotalPages 1 }} hidden {{ end }}>
-
- <a {{ $firstData | safeHTMLAttr }} href="{{ $firstHref }}" title="{{ $firstTitle }}" >
- {{ $firstTitle }}
- </a>
-
- <a rel="{{ $prevRel }}" {{ $prevData | safeHTMLAttr }} href="{{ $prevHref }}" title="{{ $prevTitle }}">
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-left.svg")) }}
- {{ $prevTitle }}
- </a>
-
- <a rel="{{ $nextRel }}" {{ $nextData | safeHTMLAttr }} href="{{ $nextHref }}" title="{{ $nextTitle }}">
- {{ $nextTitle }}
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-right.svg")) }}
- </a>
-
- <a {{ $lastData | safeHTMLAttr }} href="{{ $lastHref }}" title="{{ $lastTitle }}" >
- {{ $lastTitle }}
- </a>
- </paginator-navigation>
+ <nav{{ if le .TotalPages 1 }} hidden="" {{ end }} data-type="pagination">
+ <a rel="first" href="{{ $firstHref }}" title="{{ $firstTitle }}" >
+ <span>{{ $firstTitle }}</span>
+ </a>
+
+ <a rel="prev" href="{{ $prevHref }}" title="{{ $prevTitle }}">
+ {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-left.svg")) }}
+ <span>{{ $prevTitle }}</span>
+ </a>
+
+ <a rel="next" href="{{ $nextHref }}" title="{{ $nextTitle }}">
+ <span>{{ $nextTitle }}</span>
+ {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/arrow-right.svg")) }}
+ </a>
+
+ <a rel="last" href="{{ $lastHref }}" title="{{ $lastTitle }}" data-count="{{ .TotalPages }}">
+ <span>{{ $lastTitle }}</span>
+ </a>
+ </nav>
{{- end -}}
diff --git a/themes/default/layouts/partials/profile-tabs.html b/themes/default/layouts/partials/profile-tabs.html
index e5c0385..1ca632b 100644
--- a/themes/default/layouts/partials/profile-tabs.html
+++ b/themes/default/layouts/partials/profile-tabs.html
@@ -1,13 +1,44 @@
{{- $author := partial "function-authors-data.html" . -}}
+{{- $path := print ("" | absURL) "/" $author.user -}}
<tab-bar>
<nav>
- <a href="{{ .Site.BaseURL }}/{{ $author.user }}">Messages</a>
- <a href="{{ .Site.BaseURL }}/{{ $author.user }}/feeds/">Feeds</a>
- <a href="{{ .Site.BaseURL }}/{{ $author.user }}/media/">Media</a>
- <a href="{{ .Site.BaseURL }}/{{ $author.user }}/likes/">Likes</a>
- {{- if .Site.BuildDrafts }}
- <a data-draft href="{{ .Site.BaseURL }}/{{ $author.user }}/drafts/">Drafts</a>
+ <a
+ data-label="{{ $label := "Posts" }}{{ $label }}"
+ href="{{ $path }}/#{{ lower $label }}">
+ {{ $label }}
+ <span data-scroll="" id="{{ lower $label }}"></span>
+ </a>
+
+ <a
+ data-label="{{ $label := "Feeds" }}{{ $label }}"
+ href="{{ $path }}/{{ lower $label }}/#{{ lower $label }}">
+ {{ $label }}
+ <span data-scroll="" id="{{ lower $label }}"></span>
+ </a>
+
+ <a
+ data-label="{{ $label := "Media" }}{{ $label }}"
+ href="{{ $path }}/{{ lower $label }}/#{{ lower $label }}">
+ {{ $label }}
+ <span data-scroll="" id="{{ lower $label }}"></span>
+ </a>
+
+ <a
+ data-label="{{ $label := "Marks" }}{{ $label }}"
+ href="{{ $path }}/{{ lower $label }}/#{{ lower $label }}">
+ {{ $label }}
+ <span data-scroll="" id="{{ lower $label }}"></span>
+ </a>
+
+ {{- if $.Site.BuildDrafts }}
+ <a
+ data-draft=""
+ data-label="{{ $label := "Drafts" }}{{ $label }}"
+ href="{{ $path }}/{{ lower $label }}/#{{ lower $label }}">
+ {{ $label }}
+ <span data-scroll="" id="{{ lower $label }}"></span>
+ </a>
{{- end }}
</nav>
</tab-bar>
diff --git a/themes/default/layouts/partials/profile.html b/themes/default/layouts/partials/profile.html
index fc68c0b..e0c339b 100644
--- a/themes/default/layouts/partials/profile.html
+++ b/themes/default/layouts/partials/profile.html
@@ -1,29 +1,20 @@
{{- $author := partial "function-authors-data.html" . -}}
-<micro-header>
+<profile-box>
+ <picture data-type="banner">
+ {{ partial "author-header.html" . }}
+ </picture>
- <micro-header-banner>
- <picture>
- {{ partial "author-header.html" . }}
- </picture>
- </micro-header-banner>
-
- <micro-header-picture>
- <picture>
- {{ partial "author-picture.html" . }}
- </picture>
- </micro-header-picture>
+ <picture data-type="profile">
+ {{ partial "author-picture.html" . }}
+ </picture>
<section>
- <micro-header-title>
+ <aside>
<h2>{{ $author.name }}</h2>
<h3>@{{ $author.user }}</h3>
- </micro-header-title>
- <micro-header-description>
- <p>
- {{ $author.description | markdownify }}
- </p>
- </micro-header-description>
+ </aside>
+ <p>{{ $author.description | markdownify }}</p>
</section>
<footer>
@@ -42,11 +33,10 @@
<span>{{- $author.epoch | markdownify -}}</span>
</p>
<p>
- {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/feather/user.svg")) }}
- <span><b>{{ with $author.feeds.rss }}{{ len . }}{{ else }} 0 {{ end }}</b> Following</span>
+ {{ safeHTML (readFile (print (partial "function-paths.html").static "/icons/tabler/rss.svg")) }}
+ <span><b>{{ with $author.feeds.rss }}{{ len . }}{{ else }} 0 {{ end }}</b> Feeds</span>
</p>
</footer>
+</profile-box>
- {{ partial "profile-tabs.html" . }}
-
-</micro-header>
+{{- partial "profile-tabs.html" . -}}
diff --git a/themes/default/layouts/partials/render-embed.html b/themes/default/layouts/partials/render-embed.html
new file mode 100644
index 0000000..77b6b8f
--- /dev/null
+++ b/themes/default/layouts/partials/render-embed.html
@@ -0,0 +1,31 @@
+{{- $pageContext := . -}}
+{{- $format := "embed.html" -}}
+
+{{- $page := print "public/" (strings.TrimPrefix
+ $pageContext.Page.Site.BaseURL
+ $pageContext.Page.Permalink
+ ) $format
+-}}
+
+{{- $modified := partial "function-page-modified.html"
+ (dict
+ "Context" $pageContext
+ "Format" $format
+ )
+-}}
+
+{{- with $embed := resources.Get $page -}}
+ {{- if (in $embed.Content "/data/media/404.png") -}}
+ {{- $modified = true -}}
+ {{- end -}}
+{{- end -}}
+
+{{- if $modified -}}
+ {{- $pageContext.Render "summary" -}}
+{{- else -}}
+ {{- with $embed := resources.Get $page -}}
+ {{- range $chunks := after 1 (split ($embed.Content) "</head>") -}}
+ {{- $chunks | safeHTML -}}
+ {{- end -}}
+ {{- end -}}
+{{- end -}}
diff --git a/themes/default/layouts/partials/rss-tags.html b/themes/default/layouts/partials/rss-tags.html
deleted file mode 100644
index a54b628..0000000
--- a/themes/default/layouts/partials/rss-tags.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{{- with .Params.tags -}}
- {{- range $tags, $tag := sort . }}
- <a href="{{ "tags/" | absURL }}{{ $tag | urlize }}/">#{{ $tag }}</a>&nbsp;
- {{- end }}
-{{- end }}
diff --git a/themes/default/layouts/partials/styles-navigator.html b/themes/default/layouts/partials/styles-navigator.html
deleted file mode 100644
index 80ebcd6..0000000
--- a/themes/default/layouts/partials/styles-navigator.html
+++ /dev/null
@@ -1,14 +0,0 @@
-icon-navigator a[href="{{ "" | absURL }}{{ .Link }}"],
-column-left nav a[href="{{ "" | absURL }}{{ .Link }}"] {
- font-weight: 700;
-}
-
-column-left nav a[href="{{ "" | absURL }}{{ .Link }}"] {
- background-color: #f0f6ff;
- background-color: var(--hover-background-alternate);
-}
-
-icon-navigator a[href="{{ "" | absURL }}{{ .Link }}"] svg {
- fill: #e5f0ff;
- fill: var(--active-background-alternate);
-}
diff --git a/themes/default/layouts/partials/tags.html b/themes/default/layouts/partials/tags.html
new file mode 100644
index 0000000..29202d0
--- /dev/null
+++ b/themes/default/layouts/partials/tags.html
@@ -0,0 +1,19 @@
+{{- $format := .Format -}}
+{{- $pageContext := .Context -}}
+{{- $path := "tags/" -}}
+{{- $url := $path | relURL -}}
+
+{{- with $pageContext.Params.tags -}}
+ {{- range $tags, $tag := sort $pageContext.Params.tags -}}
+ {{- if (eq $format "rss") -}}
+ {{- $url = $path | absURL -}}
+ {{- end -}}
+
+ {{- $link := print $url ((lower $tag) | urlize) "/" -}}
+ {{- print "[#" (lower $tag) "](" $link ")" | markdownify -}}
+
+ {{- if (eq $format "rss") -}}&nbsp;{{- end }}
+ {{ end -}}
+{{- else -}}
+ <a href="{{ "tags/" | absURL }}">#untagged</a>
+{{- end -}}
diff --git a/themes/default/layouts/partials/video-container.html b/themes/default/layouts/partials/video-container.html
index af1a50d..9e28e3d 100644
--- a/themes/default/layouts/partials/video-container.html
+++ b/themes/default/layouts/partials/video-container.html
@@ -6,8 +6,8 @@
{{- $public := print "public/" .Source -}}
{{- $immutable := print (.RelURL | humanize | urlize) "-" (.Source | sha256 | truncate 8 "") -}}
{{- $extension := path.Ext .Source -}}
-{{- $fileCache := print $.Author "/media/" $immutable $extension -}}
-{{- $notCached := not (fileExists (path.Join "public/" $fileCache)) -}}
+{{- $storage := print $.Author "/media/" $immutable $extension -}}
+{{- $cached := fileExists (path.Join "public/" $storage) -}}
{{- if .Start -}}
{{- $timestamp = print "#t=" .Start -}}
@@ -21,7 +21,7 @@
{{- $timestamp = print "#t=" .Start "," .End -}}
{{- end -}}
-{{- if $notCached -}}
+{{- if not $cached -}}
{{- with $remote := cond (default true $.Context.Site.Params.site.offline) false (resources.GetRemote .Source) -}}
{{- with .Err -}}
{{- warnf "Video fetch %s" . -}}
@@ -29,16 +29,15 @@
{{- $caption = "No local video data found for source" -}}
{{- end -}}
{{- else -}}
- {{- $cache = . | resources.Copy $fileCache -}}
+ {{- $cache = $remote | resources.Copy $storage -}}
{{- $cache = $cache.Permalink -}}
{{- end -}}
{{- else -}}
{{- $caption = "Unable to load remote source data" -}}
{{- end -}}
{{- else -}}
- {{- with $cache = resources.Get (path.Join "public/" $fileCache) -}}
- {{- $cache = $cache.Content | resources.FromString $fileCache -}}
- {{- $cache = $cache.Permalink -}}
+ {{- with $cache = resources.Get (path.Join "public/" $storage) -}}
+ {{- $cache = print ("" | absURL) (strings.TrimLeft "public" $cache) -}}
{{- end -}}
{{- end -}}
diff --git a/themes/default/layouts/partials/webring.html b/themes/default/layouts/partials/webring.html
index 9179280..009e2fc 100644
--- a/themes/default/layouts/partials/webring.html
+++ b/themes/default/layouts/partials/webring.html
@@ -9,7 +9,7 @@
</aside>
{{ else }}
<footer>
- <code>No content found!</code>
+ <code>No items found!</code>
</footer>
{{ end }}
</web-ring>
diff --git a/themes/default/layouts/shortcodes/abbr.html b/themes/default/layouts/shortcodes/abbr.html
index 2a87233..61a2e32 100644
--- a/themes/default/layouts/shortcodes/abbr.html
+++ b/themes/default/layouts/shortcodes/abbr.html
@@ -1,6 +1,6 @@
{{- $abbr := default "TL;DR:" (.Get "abbr" | default (.Get 0)) -}}
{{- $title := default "Too long, didn't read" (.Get "title" | default (.Get 1)) -}}
-{{- $hash := print (truncate 8 "" (sha256 $abbr)) .Ordinal -}}
+{{- $hash := print (truncate 4 "" (sha256 .Page.RelPermalink)) (truncate 4 "" (sha256 $abbr)) .Ordinal -}}
<input hidden="" type="checkbox" id="abbr-{{ $hash }}" />
{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/shortcodes/attach.html b/themes/default/layouts/shortcodes/attach.html
index f453da5..55b5744 100644
--- a/themes/default/layouts/shortcodes/attach.html
+++ b/themes/default/layouts/shortcodes/attach.html
@@ -1,37 +1,38 @@
-{{- $url := default "https://www.gutenberg.org/files/98/old/2city12p.pdf" (.Get "url" | default (.Get 0)) -}}
+{{- $url := default "/canory/media/2city12p.pdf" (.Get "url" | default (.Get 0)) -}}
{{- $title := default "Attachment" (.Get "title" | default (.Get 1)) -}}
{{- $caption := default $title (.Get "caption" | default (.Get 2)) -}}
{{- $remote := default "" (.Get "remote" | default (.Get 3)) -}}
{{- $data := "" -}}
{{- $cache := "" -}}
-{{- $type := "application/octet-stream" -}}
{{- $author := .Page.Section -}}
-{{- $immutable := print $url | anchorize -}}
{{- $extension := path.Ext $url -}}
-{{- $fileCache := print $author "/media/" $immutable $extension -}}
-{{- $notCached := not (fileExists (path.Join "public/" $fileCache)) -}}
+{{- $immutable := print $url | anchorize -}}
+{{- $localFile := path.Join "public/" $url -}}
+{{- $type := "application/octet-stream" -}}
+{{- $storage := print $author "/media/" $immutable $extension -}}
+{{- $cached := fileExists (path.Join "public/" $storage) -}}
-{{- if $notCached -}}
+{{- if not $cached -}}
{{- with $remote := cond (default true $.Page.Site.Params.site.offline) false (resources.GetRemote $url) -}}
{{- with .Err -}}
- {{- warnf "Attachment fetch %s" . -}}
- {{- if not (fileExists $fileCache) -}}
+ {{- if not (fileExists $localFile) -}}
{{- $caption = "No local attachment data found for source" -}}
+ {{- warnf "Attachment local fetch error: %s" $url -}}
{{- end -}}
{{- else -}}
- {{- $type = .MediaType -}}
- {{- $cache = . | resources.Copy $fileCache -}}
+ {{- $type = $remote.MediaType -}}
+ {{- $cache = $remote | resources.Copy $storage -}}
{{- $cache = $cache.Permalink -}}
{{- end -}}
{{- else -}}
{{- $caption = "Unable to load remote source data" -}}
+ {{- warnf "Attachment remote fetch error: %s" $url -}}
{{- end -}}
{{- else -}}
- {{- with $cache = resources.Get (path.Join "public/" $fileCache) -}}
+ {{- with $cache = resources.Get (path.Join "public/" $storage) -}}
{{- $type = .MediaType -}}
- {{- $cache = $cache.Content | resources.FromString $fileCache -}}
- {{- $cache = $cache.Permalink -}}
+ {{- $cache = print ("" | absURL) (strings.TrimLeft "public" $cache) -}}
{{- end -}}
{{- end -}}
@@ -45,7 +46,7 @@
<object type="{{ $type }}" data="{{ $data }}">
<p>
Your browser does not support the <code>{{ $type }}</code> plugin. Here's a
- <a href="{{ $data }}">link to the file</a> instead.
+ <a rel="canonical" href="{{ $data }}">link to the file</a> instead.
</p>
</object>
<footer>
diff --git a/themes/default/layouts/shortcodes/disclose.html b/themes/default/layouts/shortcodes/disclose.html
index 2cc99c7..231561b 100644
--- a/themes/default/layouts/shortcodes/disclose.html
+++ b/themes/default/layouts/shortcodes/disclose.html
@@ -1,10 +1,13 @@
{{- $text := default "Content Warning: " (.Get "text" | default (.Get 0)) -}}
+{{- $hash := print (truncate 4 "" (sha256 .Page.RelPermalink)) (truncate 4 "" (sha256 $text)) .Ordinal -}}
{{- if gt (len .Inner) 1 -}}
{{- $text = .Inner -}}
{{- end -}}
-<details data-disclosure>
- <summary>{{ (or $.Page.Params.title $text) | markdownify }}</summary>
+<details id="disclosure-{{ $hash }}" data-disclosure="">
+ <summary>
+ {{- (or $.Page.Params.title $text) | markdownify }}
+ </summary>
</details>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/shortcodes/gist.html b/themes/default/layouts/shortcodes/gist.html
deleted file mode 100644
index c475672..0000000
--- a/themes/default/layouts/shortcodes/gist.html
+++ /dev/null
@@ -1,9 +0,0 @@
-{{- $user := default "gdb" (.Get "user" | default (.Get 0)) -}}
-{{- $gist := default "b6365e79be6052e7531e7ba6ea8caf23" (.Get "gist" | default (.Get 1)) -}}
-{{- $file := default "" (.Get "file" | default (.Get 2)) -}}
-
-<github-gist>
- <script
- src="https://gist.github.com/{{ $user }}/{{ $gist }}.js?file={{ $file }}">
- </script>
-</github-gist>
diff --git a/themes/default/layouts/shortcodes/kbd.html b/themes/default/layouts/shortcodes/kbd.html
index b24fd9d..63af975 100644
--- a/themes/default/layouts/shortcodes/kbd.html
+++ b/themes/default/layouts/shortcodes/kbd.html
@@ -1,3 +1,4 @@
{{- $key := default "Ctrl" (.Get "key" | default (.Get 0)) -}}
<kbd title="{{ $key }}">{{ $key | markdownify }}</kbd>
+{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/shortcodes/mark.html b/themes/default/layouts/shortcodes/mark.html
index 122a521..1b9ef3d 100644
--- a/themes/default/layouts/shortcodes/mark.html
+++ b/themes/default/layouts/shortcodes/mark.html
@@ -1,9 +1,15 @@
{{- $text := default "mark" (.Get "text" | default (.Get 0)) -}}
{{- $title := default "highlighted text" (.Get "title" | default (.Get 1)) -}}
+{{- $id := default "" (.Get "id" | default (.Get 2)) -}}
{{- if gt (len .Inner) 1 -}}
- {{- $text = .Inner -}}
+ {{- $text = trim .Inner "\n" -}}
{{- end -}}
-<mark title="{{- $title -}}">{{- $text -}}</mark>
+{{- if $id -}}
+ {{- $id = print "mark:" (truncate 30 "" $text | anchorize | replaceRE `\d` "") -}}
+ {{- $id = printf `id=%q` $id -}}
+{{- end -}}
+
+<mark {{ $id | safeHTMLAttr }} title="{{- $title -}}"><span>{{- $text | markdownify -}}</span></mark>
{{- /* This comment removes trailing newlines and white spaces. */ -}}
diff --git a/themes/default/layouts/shortcodes/react.html b/themes/default/layouts/shortcodes/react.html
index 344bd2d..ea96101 100644
--- a/themes/default/layouts/shortcodes/react.html
+++ b/themes/default/layouts/shortcodes/react.html
@@ -16,7 +16,7 @@
)
-}}
-<reaction-tip title="{{ $title }}">
+<tool-tip data-type="reaction" title="{{ $title }}">
{{ $text | markdownify }}
<a href="{{ $image.Permalink }}">
<img
@@ -27,4 +27,4 @@
src="{{ $image.Permalink }}"
/>
</a>
-</reaction-tip>
+</tool-tip>
diff --git a/themes/default/layouts/shortcodes/reddit.html b/themes/default/layouts/shortcodes/reddit.html
deleted file mode 100644
index 10ef0b9..0000000
--- a/themes/default/layouts/shortcodes/reddit.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{{- $path := default "linux/comments/aeufh6/vlc_has_now_reached_3_billions_downloads_and/edsvibz" (.Get "path" | default (.Get 0)) -}}
-{{- $depth := default "2" (.Get "depth" | default (.Get 1)) -}}
-{{- $context := default "1" (.Get "context" | default (.Get 2)) -}}
-{{- $theme := default "light" (.Get "theme" | default (.Get 3)) -}}
-{{- $showtitle := default "true" (.Get "showtitle" | default (.Get 4)) -}}
-{{- $showedits := default "false" (.Get "showedits" | default (.Get 5)) -}}
-{{- $showmedia := default "false" (.Get "showmedia" | default (.Get 6)) -}}
-{{- $showmore := default "false" (.Get "showmore" | default (.Get 7)) -}}
-
-<reddit-comment>
- <iframe loading="lazy"
- id="reddit-embed"
- src="https://www.redditmedia.com/r/{{ trim $path "/" }}/
-?depth={{ $depth }}
-&amp;embed=true
-&amp;showmore={{ $showmore }}
-&amp;showtitle={{ $showtitle }}
-&amp;context={{ $context }}
-&amp;showmedia={{ $showmedia }}
-&amp;theme={{ $theme }}
-&amp;showedits={{ $showedits }}
-&amp;created={{ now.Format "2006-01-02T15:04:05Z" }}"
- sandbox="allow-scripts allow-same-origin allow-popups"
- style="border: none;"
- height="452"
- width="640"
- scrolling="no"
- ></iframe>
-</reddit-comment>
diff --git a/themes/default/layouts/shortcodes/spoiler.html b/themes/default/layouts/shortcodes/spoiler.html
index 5a9462d..9c5e59a 100644
--- a/themes/default/layouts/shortcodes/spoiler.html
+++ b/themes/default/layouts/shortcodes/spoiler.html
@@ -1,6 +1,6 @@
{{- $text := default "This is a spoiler." (.Get "text" | default (.Get 0)) -}}
{{- $title := default "Click to show/hide text." (.Get "title" | default (.Get 1)) -}}
-{{- $hash := print (truncate 8 "" (sha256 $text)) .Ordinal -}}
+{{- $hash := print (truncate 4 "" (sha256 .Page.RelPermalink)) (truncate 4 "" (sha256 $text)) .Ordinal -}}
{{- if gt (len .Inner) 1 -}}
{{- $text = .Inner -}}
diff --git a/themes/default/layouts/shortcodes/version.html b/themes/default/layouts/shortcodes/version.html
index 11e7685..2e3eda8 100644
--- a/themes/default/layouts/shortcodes/version.html
+++ b/themes/default/layouts/shortcodes/version.html
@@ -1,12 +1,12 @@
-{{- $theme := "0.11.11" -}}
-{{- $generator := "0.108.0" -}}
+{{- $version := "0.11.12" -}}
+{{- $generator := "0.110.0" -}}
{{- $number := default false (.Get "number" | default (.Get 0)) -}}
{{- $clone := default false (.Get "clone" | default (.Get 1)) -}}
{{- $hugo := default false (.Get "hugo" | default (.Get 2)) -}}
{{- if $number -}}
- {{ $theme }}
+ {{ $version }}
{{- end -}}
{{- if $hugo -}}
@@ -15,6 +15,6 @@
{{- if $clone -}}
```shell
-git clone --branch {{ $theme }} https://www.thedroneely.com/git/thedroneely/canory
+git clone --branch {{ $version }} https://www.thedroneely.com/git/thedroneely/canory
```
{{- end -}}
diff --git a/themes/default/layouts/shortcodes/asciicast.html b/themes/default/layouts/shortcodes/video-ascii.html
index 10da091..10da091 100644
--- a/themes/default/layouts/shortcodes/asciicast.html
+++ b/themes/default/layouts/shortcodes/video-ascii.html
diff --git a/themes/default/layouts/shortcodes/imgur-video.html b/themes/default/layouts/shortcodes/video-imgur.html
index 2edb9a4..2edb9a4 100644
--- a/themes/default/layouts/shortcodes/imgur-video.html
+++ b/themes/default/layouts/shortcodes/video-imgur.html
diff --git a/themes/default/layouts/shortcodes/video.rss.xml b/themes/default/layouts/shortcodes/video.rss.xml
index cff5974..be262e7 100644
--- a/themes/default/layouts/shortcodes/video.rss.xml
+++ b/themes/default/layouts/shortcodes/video.rss.xml
@@ -21,9 +21,9 @@
title="{{ $title }}"
href="{{ $source }}"
>
- {{- $caption -}}
+ Video: {{ $caption -}}
</a>
</b>
<br>
- <span>{{ $caption }}</span>
+ <span>Title: {{ $title }}</span>
</p>
diff --git a/themes/default/layouts/shortcodes/vimeo.html b/themes/default/layouts/shortcodes/vimeo.html
deleted file mode 100644
index 009ebb0..0000000
--- a/themes/default/layouts/shortcodes/vimeo.html
+++ /dev/null
@@ -1,12 +0,0 @@
-{{- $id := default "1084537" (.Get "id" | default (.Get 0)) -}}
-{{- $title := default "Vimeo Video" (.Get "title" | default (.Get 1)) -}}
-
-<vimeo-video>
- <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
- <iframe loading="lazy"
- src="https://player.vimeo.com/video/{{ $id }}?dnt=1"
- style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;"
- title="{{ $title }}" webkitallowfullscreen mozallowfullscreen allowfullscreen>
- </iframe>
- </div>
-</vimeo-video>