diff options
Diffstat (limited to 'src/assets')
-rw-r--r-- | src/assets/assets.11tydata.js | 8 | ||||
-rw-r--r-- | src/assets/atom.njk | 26 | ||||
-rw-r--r-- | src/assets/error.md | 11 | ||||
-rw-r--r-- | src/assets/index.css | 126 | ||||
-rw-r--r-- | src/assets/index.mjs | 12 | ||||
-rw-r--r-- | src/assets/json.njk | 30 | ||||
-rw-r--r-- | src/assets/manifest.njk | 30 | ||||
-rw-r--r-- | src/assets/prism.css | 162 | ||||
-rw-r--r-- | src/assets/robot.njk | 6 | ||||
-rw-r--r-- | src/assets/sitemap.njk | 14 | ||||
-rw-r--r-- | src/assets/sw.mjs | 59 |
11 files changed, 484 insertions, 0 deletions
diff --git a/src/assets/assets.11tydata.js b/src/assets/assets.11tydata.js new file mode 100644 index 0000000..6704307 --- /dev/null +++ b/src/assets/assets.11tydata.js @@ -0,0 +1,8 @@ +const path = require("path") + +module.exports = { + eleventyExcludeFromCollections: true, + eleventyComputed: { + permalink: data => data.permalink || `/${path.relative("/assets", data.page.filePathStem)}.${data.page.outputFileExtension}` + } +}
\ No newline at end of file diff --git a/src/assets/atom.njk b/src/assets/atom.njk new file mode 100644 index 0000000..4e517ca --- /dev/null +++ b/src/assets/atom.njk @@ -0,0 +1,26 @@ +--- +permalink: /feed.xml +--- +<?xml version="1.0" encoding="utf-8"?> +<feed xmlns="http://www.w3.org/2005/Atom"> + <title>{{ metadata.title }}</title> + <subtitle>{{ metadata.description }}</subtitle> + <link href="{{ permalink | url | absoluteUrl(metadata.url) }}" rel="self"/> + <link href="{{ "/" | url | absoluteUrl(metadata.url) }}"/> + <updated>{{ collections.posts | getNewestCollectionItemDate | dateToRfc3339 }}</updated> + <id>{{ metadata.url }}</id> + <author> + <name>{{ metadata.author.name }}</name> + <email>{{ metadata.author.email }}</email> + </author> + {% for post in collections.posts %} + {% set absolutePostUrl %}{{ post.url | url | absoluteUrl(metadata.url) }}{% endset %} + <entry> + <title>{{ post.data.title }}</title> + <link href="{{ absolutePostUrl }}"/> + <updated>{{ post.date | dateToRfc3339 }}</updated> + <id>{{ '/' | url | absoluteUrl(metadata.url) }}</id> + <content type="html"><![CDATA[{{ post.templateContent | htmlToAbsoluteUrls( absolutePostUrl ) }}]]></content> + </entry> + {% endfor %} +</feed> diff --git a/src/assets/error.md b/src/assets/error.md new file mode 100644 index 0000000..65655f3 --- /dev/null +++ b/src/assets/error.md @@ -0,0 +1,11 @@ +--- +layout: base.njk +pagination: + data: err + size: 1 + alias: error +permalink: "/{{ error.code }}.html" +--- +# ERROR: {{ error.code }} {.err} + +{{ error.msg }} diff --git a/src/assets/index.css b/src/assets/index.css new file mode 100644 index 0000000..db51dc8 --- /dev/null +++ b/src/assets/index.css @@ -0,0 +1,126 @@ +:root { + --fg: rgb(0 0 0); + --bg: rgb(255 255 255); + --brand: rgb(139 0 0); + + @media screen and (prefers-color-scheme: dark) { + --bg: rgb(0 0 0); + --fg: rgb(255 255 255); + --brand: rgb(255 0 0); + } +} + +body { + font-family: serif; + background-color: var(--bg); + color: var(--fg); + + @media screen { + max-width: 920px; + min-height: calc(100vh - 1rem); + margin: 0.5rem auto; + display: grid; + grid-template: "head" auto "main" auto "footer" 1fr / auto; + + & > header { + background-color: var(--brand); + font-weight: bold; + color: rgb(255 255 255); + padding: 1rem; + grid-area: head; + + & *:any-link { + text-decoration: none; + } + } + + & > footer { + background-color: var(--brand); + color: rgb(255 255 255); + padding: 0.5rem; + align-self: end; + grid-area: footer; + + & *:any-link { + text-decoration: none; + } + + & > main { + grid-area: main; + } + } + } +} + +* :any-link { + color: inherit; + text-decoration: underline; + + @media screen { + &:is(:hover, :active) { + font-style: italic; + } + } +} + +a[href^="mailto:"]::after { + content: "📧"; +} + +.err { + color: var(--brand); +} + +aside { + width: 40%; + padding: 0.5rem; + margin-left: 0.5rem; + float: right; + background-color: var(--brand); + color: rgb(255 255 255); +} + +img { + max-width: 100%; + max-height: 100%; + + &.side { + width: 40%; + float: right; + + @media screen and (max-width: 450px) { + width: 100%; + float: none; + } + } +} + +@media screen { + nav > a { + margin-right: 1rem; + padding-left: 0; + padding-right: 0; + + @media (max-width: 450px) { + display: block; + margin: auto; + text-align: center; + padding: 16px; + + .navlinks { + display: none; + + .navopen { + display: block; + } + } + } + } +} + +@media print { + header, + footer { + display: none; + } +} diff --git a/src/assets/index.mjs b/src/assets/index.mjs new file mode 100644 index 0000000..4d7c2b0 --- /dev/null +++ b/src/assets/index.mjs @@ -0,0 +1,12 @@ +document.getElementById("nav-toogle").addEventListener("click", async() => { + const navlinks = Array.from(document.getElementsByClassName("navlinks")) + for (const navlink of navlinks) { + navlink.classList.toggle("navopen") + } + return false +}) +window.addEventListener('load', async() => { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.register('/sw.js') + } +})
\ No newline at end of file diff --git a/src/assets/json.njk b/src/assets/json.njk new file mode 100644 index 0000000..6d8c7ec --- /dev/null +++ b/src/assets/json.njk @@ -0,0 +1,30 @@ +--- +permalink: /feed.json +--- +{ + "version": "https://jsonfeed.org/version/1.1", + "title": "{{ metadata.title }}", + "language": "{{ metadata.language }}", + "home_page_url": "{{ "/" | url | absoluteUrl(metadata.url) }}", + "feed_url": "{{ permalink | url | absoluteUrl(metadata.url) }}", + "description": "{{ metadata.description }}", + "author": { + "name": "{{ metadata.author.name }}" + }, + "items": [ + {%- for post in collections.posts | reverse %} + {%- set absolutePostUrl %}{{ post.url | url | absoluteUrl(metadata.url) }}{% endset -%} + { + "id": "{{ absolutePostUrl }}", + "url": "{{ absolutePostUrl }}", + "title": "{{ post.data.title }}", + "content_html": {% if post.templateContent %}{{ post.templateContent | htmlToAbsoluteUrls(absolutePostUrl) | dump | safe }} + {% else %}""{% endif %}, + "date_published": "{{ post.date | rssDate }}" + } + {%- if not loop.last -%} + , + {%- endif -%} +{%- endfor %} +] +} diff --git a/src/assets/manifest.njk b/src/assets/manifest.njk new file mode 100644 index 0000000..cbdefea --- /dev/null +++ b/src/assets/manifest.njk @@ -0,0 +1,30 @@ +--- +permalink: /app.webmanifest +--- +{ + "$schema": "https://json.schemastore.org/web-manifest-combined.json", + "name": "{{ metadata.title }}", + + "lang": "en-GB", + "start_url": "{{ '/' | url }}", + "id": "{{ '/' | url }}", + "scope": "{{ '/' | url }}", + "display": "minimal-ui", + "background_color": "#8b0000", + "theme_color": "#8b0000", + "description": "{{ metadata.description }}", + "icons": [ + { + "src": "{{ '/favicon/192.png' | url }}", + "type": "image/png", + "sizes": "192x192", + "purpose": "any" + }, + { + "src": "{{ '/favicon/512.png' | url }}", + "type": "image/png", + "sizes": "512x512", + "purpose": "any" + } + ] +} diff --git a/src/assets/prism.css b/src/assets/prism.css new file mode 100644 index 0000000..110c6be --- /dev/null +++ b/src/assets/prism.css @@ -0,0 +1,162 @@ +code[class*="language-"], +pre[class*="language-"] { + color: rgb(248 248 242); + background: none; + text-shadow: 0 1px rgb(0 0 0 / 30%); + font-family: monospace; + font-size: 1em; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + tab-size: 4; + hyphens: none; + + @media screen and (prefers-color-scheme: dark) { + code[class*="language-"], + pre[class*="language-"] { + color: #000; + text-shadow: 0 1px #fff; + } + } +} + +/* Code blocks */ + +pre[class*="language-"] { + padding: 1em; + margin: 0.5em 0; + overflow: auto; + border-radius: 0.3em; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: rgb(39 40 34); + + @media screen and (prefers-color-scheme: dark) { + background: rgb(245 242 240); + } +} + +/* Inline code */ + +:not(pre) > code[class*="language-"] { + padding: 0.1em; + border-radius: 0.3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: rgb(130 146 162); + + @media screen and (prefers-color-scheme: dark) { + color: rgb(112 128 144); + } +} + +.token.punctuation { + color: rgb(248 248 242); + + @media screen and (prefers-color-scheme: dark) { + color: rgb(153 0 85); + } +} + +.token.namespace { + opacity: 0.7; +} + +.token.property, +.token.tag, +.token.constant, +.token.symbol, +.token.deleted { + color: rgb(249 38 114); + + @media screen and (prefers-color-scheme: dark) { + color: rgb(153 0 85); + } +} + +.token.boolean, +.token.number { + color: rgb(174 129 255); + + @media screen and (prefers-color-scheme: dark) { + color: rgb(153 0 85); + } +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: rgb(166 226 46); + + @media screen and (prefers-color-scheme: dark) { + color: rgb(102 153 0); + } +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string, +.token.variable { + color: rgb(248 248 242); + + @media screen and (prefers-color-scheme: dark) { + color: rgb(154 110 58); + background: rgb(255 255 255 / 50%); + } +} + +.token.atrule, +.token.attr-value, +.token.function, +.token.class-name { + color: rgb(230 219 116); + + @media screen and (prefers-color-scheme: dark) { + color: rgb(0 118 168); + } +} + +.token.keyword { + color: rgb(102 217 239); + + @media screen and (prefers-color-scheme: dark) { + color: rgb(221 75 104); + } +} + +.token.regex, +.token.important { + color: rgb(253 151 31); + + @media screen (prefers-color-scheme: dark) { + color: rgb(238 153 0); + } +} + +.token.important, +.token.bold { + font-weight: bold; +} + +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} diff --git a/src/assets/robot.njk b/src/assets/robot.njk new file mode 100644 index 0000000..dcaa728 --- /dev/null +++ b/src/assets/robot.njk @@ -0,0 +1,6 @@ +--- +permalink: /robot.txt +--- +User-agent: * +Allow: / +Sitemap: {{ "/"| url | absoluteUrl(metadata.url) }}/sitemap.xml
\ No newline at end of file diff --git a/src/assets/sitemap.njk b/src/assets/sitemap.njk new file mode 100644 index 0000000..910b238 --- /dev/null +++ b/src/assets/sitemap.njk @@ -0,0 +1,14 @@ +--- +permalink: /sitemap.xml +--- +<?xml version="1.0" encoding="utf-8"?> +<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> +{%- for page in collections.all %} + {% set absoluteUrl %}{{ page.url | url | absoluteUrl(metadata.url) }}{% endset %} + <url> + <loc>{{ absoluteUrl }}</loc> + <lastmod>{{ page.date | datefmt }}</lastmod> + </url> +{%- endfor %} +</urlset> + diff --git a/src/assets/sw.mjs b/src/assets/sw.mjs new file mode 100644 index 0000000..78d659a --- /dev/null +++ b/src/assets/sw.mjs @@ -0,0 +1,59 @@ +const sw_cache = { + offline: "/offline.html", + default: [ + "/index.css", + "/prism.css", + "/index.js", + "/favicon/icon.svg", + "/offline.html", + "/" + ], + // eslint-disable-next-line no-undef + store: VERSION, +} + +self.addEventListener('install', event => { + self.skipWaiting() + event.waitUntil((async() => { + const cache = await self.caches.open(sw_cache.store) + return cache.addAll(sw_cache.default) + })()) +}) + +self.addEventListener('activate', event => { + event.waitUntil((async() => { + const keys = await self.caches.keys() + Promise.all(keys.map(key => { + if (key !== sw_cache.store) { + return self.caches.delete(key) + } + })) + })()) +}) + +self.addEventListener('fetch', event => { + event.respondWith((async() => { + if (event.request.method != 'GET') { + return fetch(event.request) + } + + const req_url = new URL(event.request.url) + if (req_url.origin != self.location.origin) { + return fetch(event.request) + } + + const cacheres = await self.caches.match(event.request) + return cacheres || (async() => { + try { + const response = await self.fetch(event.request) + const cache = await self.caches.open(sw_cache.store) + cache.put(event.request, response.clone()) + return response + } catch { + return self.caches.match(sw_cache.offline) + } + })() + })()) + + +})
\ No newline at end of file |