@geekity/cms 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (278) hide show
  1. package/README.md +188 -9
  2. package/admin/pages/account/login.njk +3 -0
  3. package/admin/pages/documents/editor.njk +20 -0
  4. package/admin/pages/indieauth/consent.njk +51 -0
  5. package/admin/pages/indieauth/refused.njk +11 -0
  6. package/admin/pages/settings/general.njk +12 -2
  7. package/admin/pages/settings/reading.njk +93 -0
  8. package/admin/pages/users/apps.njk +74 -0
  9. package/admin/pages/users/edit.njk +12 -0
  10. package/admin/static/admin.css +27 -0
  11. package/dist/admin/accounts.d.ts +3 -0
  12. package/dist/admin/accounts.d.ts.map +1 -1
  13. package/dist/admin/accounts.js +5 -0
  14. package/dist/admin/accounts.js.map +1 -1
  15. package/dist/admin/documents.d.ts +4 -0
  16. package/dist/admin/documents.d.ts.map +1 -1
  17. package/dist/admin/documents.js +45 -5
  18. package/dist/admin/documents.js.map +1 -1
  19. package/dist/admin/federation.js +2 -2
  20. package/dist/admin/federation.js.map +1 -1
  21. package/dist/admin/headers.d.ts +9 -2
  22. package/dist/admin/headers.d.ts.map +1 -1
  23. package/dist/admin/headers.js +16 -7
  24. package/dist/admin/headers.js.map +1 -1
  25. package/dist/admin/menu.d.ts.map +1 -1
  26. package/dist/admin/menu.js +2 -1
  27. package/dist/admin/menu.js.map +1 -1
  28. package/dist/admin/routes.d.ts.map +1 -1
  29. package/dist/admin/routes.js +48 -5
  30. package/dist/admin/routes.js.map +1 -1
  31. package/dist/admin/settings-general.d.ts.map +1 -1
  32. package/dist/admin/settings-general.js +28 -3
  33. package/dist/admin/settings-general.js.map +1 -1
  34. package/dist/admin/settings-reading.d.ts.map +1 -1
  35. package/dist/admin/settings-reading.js +15 -1
  36. package/dist/admin/settings-reading.js.map +1 -1
  37. package/dist/admin/settings.d.ts +83 -4
  38. package/dist/admin/settings.d.ts.map +1 -1
  39. package/dist/admin/settings.js +166 -4
  40. package/dist/admin/settings.js.map +1 -1
  41. package/dist/admin/templates.d.ts +3 -0
  42. package/dist/admin/templates.d.ts.map +1 -1
  43. package/dist/admin/templates.js +3 -0
  44. package/dist/admin/templates.js.map +1 -1
  45. package/dist/admin/users.d.ts +8 -0
  46. package/dist/admin/users.d.ts.map +1 -1
  47. package/dist/admin/users.js +9 -0
  48. package/dist/admin/users.js.map +1 -1
  49. package/dist/config.d.ts +34 -0
  50. package/dist/config.d.ts.map +1 -1
  51. package/dist/config.js +1 -0
  52. package/dist/config.js.map +1 -1
  53. package/dist/content/pinned.d.ts +26 -0
  54. package/dist/content/pinned.d.ts.map +1 -0
  55. package/dist/content/pinned.js +42 -0
  56. package/dist/content/pinned.js.map +1 -0
  57. package/dist/content/store.d.ts +7 -0
  58. package/dist/content/store.d.ts.map +1 -1
  59. package/dist/content/store.js +20 -0
  60. package/dist/content/store.js.map +1 -1
  61. package/dist/env.d.ts +21 -0
  62. package/dist/env.d.ts.map +1 -1
  63. package/dist/federation/actor.d.ts +15 -0
  64. package/dist/federation/actor.d.ts.map +1 -1
  65. package/dist/federation/actor.js +94 -3
  66. package/dist/federation/actor.js.map +1 -1
  67. package/dist/federation/article.d.ts +13 -1
  68. package/dist/federation/article.d.ts.map +1 -1
  69. package/dist/federation/article.js +45 -6
  70. package/dist/federation/article.js.map +1 -1
  71. package/dist/federation/delivery.d.ts.map +1 -1
  72. package/dist/federation/delivery.js +36 -4
  73. package/dist/federation/delivery.js.map +1 -1
  74. package/dist/federation/federation.d.ts.map +1 -1
  75. package/dist/federation/federation.js +24 -2
  76. package/dist/federation/federation.js.map +1 -1
  77. package/dist/federation/mount.js +2 -2
  78. package/dist/federation/mount.js.map +1 -1
  79. package/dist/federation/paths.d.ts +30 -0
  80. package/dist/federation/paths.d.ts.map +1 -1
  81. package/dist/federation/paths.js +36 -0
  82. package/dist/federation/paths.js.map +1 -1
  83. package/dist/images/icons.d.ts +44 -25
  84. package/dist/images/icons.d.ts.map +1 -1
  85. package/dist/images/icons.js +205 -60
  86. package/dist/images/icons.js.map +1 -1
  87. package/dist/images/index.d.ts +2 -2
  88. package/dist/images/index.d.ts.map +1 -1
  89. package/dist/images/index.js +1 -1
  90. package/dist/images/index.js.map +1 -1
  91. package/dist/images/markup.d.ts +14 -0
  92. package/dist/images/markup.d.ts.map +1 -1
  93. package/dist/images/markup.js +16 -11
  94. package/dist/images/markup.js.map +1 -1
  95. package/dist/images/variants.d.ts +11 -0
  96. package/dist/images/variants.d.ts.map +1 -1
  97. package/dist/images/variants.js +24 -4
  98. package/dist/images/variants.js.map +1 -1
  99. package/dist/index.d.ts +15 -5
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +33 -2
  102. package/dist/index.js.map +1 -1
  103. package/dist/indexnow.d.ts +34 -0
  104. package/dist/indexnow.d.ts.map +1 -0
  105. package/dist/indexnow.js +141 -0
  106. package/dist/indexnow.js.map +1 -0
  107. package/dist/indieauth/bearer.d.ts +39 -0
  108. package/dist/indieauth/bearer.d.ts.map +1 -0
  109. package/dist/indieauth/bearer.js +63 -0
  110. package/dist/indieauth/bearer.js.map +1 -0
  111. package/dist/indieauth/client.d.ts +61 -0
  112. package/dist/indieauth/client.d.ts.map +1 -0
  113. package/dist/indieauth/client.js +139 -0
  114. package/dist/indieauth/client.js.map +1 -0
  115. package/dist/indieauth/connected-apps.d.ts +23 -0
  116. package/dist/indieauth/connected-apps.d.ts.map +1 -0
  117. package/dist/indieauth/connected-apps.js +73 -0
  118. package/dist/indieauth/connected-apps.js.map +1 -0
  119. package/dist/indieauth/consent.d.ts +28 -0
  120. package/dist/indieauth/consent.d.ts.map +1 -0
  121. package/dist/indieauth/consent.js +185 -0
  122. package/dist/indieauth/consent.js.map +1 -0
  123. package/dist/indieauth/discovery.d.ts +87 -0
  124. package/dist/indieauth/discovery.d.ts.map +1 -0
  125. package/dist/indieauth/discovery.js +127 -0
  126. package/dist/indieauth/discovery.js.map +1 -0
  127. package/dist/indieauth/grants.d.ts +57 -0
  128. package/dist/indieauth/grants.d.ts.map +1 -0
  129. package/dist/indieauth/grants.js +35 -0
  130. package/dist/indieauth/grants.js.map +1 -0
  131. package/dist/indieauth/identity.d.ts +36 -0
  132. package/dist/indieauth/identity.d.ts.map +1 -0
  133. package/dist/indieauth/identity.js +77 -0
  134. package/dist/indieauth/identity.js.map +1 -0
  135. package/dist/indieauth/redeem.d.ts +47 -0
  136. package/dist/indieauth/redeem.d.ts.map +1 -0
  137. package/dist/indieauth/redeem.js +69 -0
  138. package/dist/indieauth/redeem.js.map +1 -0
  139. package/dist/indieauth/request.d.ts +47 -0
  140. package/dist/indieauth/request.d.ts.map +1 -0
  141. package/dist/indieauth/request.js +104 -0
  142. package/dist/indieauth/request.js.map +1 -0
  143. package/dist/indieauth/token.d.ts +19 -0
  144. package/dist/indieauth/token.d.ts.map +1 -0
  145. package/dist/indieauth/token.js +110 -0
  146. package/dist/indieauth/token.js.map +1 -0
  147. package/dist/indieauth/tokens.d.ts +131 -0
  148. package/dist/indieauth/tokens.d.ts.map +1 -0
  149. package/dist/indieauth/tokens.js +205 -0
  150. package/dist/indieauth/tokens.js.map +1 -0
  151. package/dist/web/admin-bar.d.ts +3 -1
  152. package/dist/web/admin-bar.d.ts.map +1 -1
  153. package/dist/web/admin-bar.js +5 -1
  154. package/dist/web/admin-bar.js.map +1 -1
  155. package/dist/web/archive.d.ts +1 -1
  156. package/dist/web/archive.d.ts.map +1 -1
  157. package/dist/web/archive.js +3 -2
  158. package/dist/web/archive.js.map +1 -1
  159. package/dist/web/authors.d.ts +19 -0
  160. package/dist/web/authors.d.ts.map +1 -1
  161. package/dist/web/authors.js +25 -0
  162. package/dist/web/authors.js.map +1 -1
  163. package/dist/web/context.d.ts +25 -0
  164. package/dist/web/context.d.ts.map +1 -1
  165. package/dist/web/context.js +18 -0
  166. package/dist/web/context.js.map +1 -1
  167. package/dist/web/feed-atom.d.ts.map +1 -1
  168. package/dist/web/feed-atom.js +5 -2
  169. package/dist/web/feed-atom.js.map +1 -1
  170. package/dist/web/feed-item.d.ts +24 -6
  171. package/dist/web/feed-item.d.ts.map +1 -1
  172. package/dist/web/feed-item.js +16 -8
  173. package/dist/web/feed-item.js.map +1 -1
  174. package/dist/web/feed-json.d.ts +6 -2
  175. package/dist/web/feed-json.d.ts.map +1 -1
  176. package/dist/web/feed-json.js +6 -2
  177. package/dist/web/feed-json.js.map +1 -1
  178. package/dist/web/feed-rss.d.ts.map +1 -1
  179. package/dist/web/feed-rss.js +17 -4
  180. package/dist/web/feed-rss.js.map +1 -1
  181. package/dist/web/feed-source.d.ts +31 -0
  182. package/dist/web/feed-source.d.ts.map +1 -1
  183. package/dist/web/feed-source.js +31 -0
  184. package/dist/web/feed-source.js.map +1 -1
  185. package/dist/web/feed-xml.d.ts +2 -0
  186. package/dist/web/feed-xml.d.ts.map +1 -1
  187. package/dist/web/feed-xml.js +2 -0
  188. package/dist/web/feed-xml.js.map +1 -1
  189. package/dist/web/feeds.d.ts.map +1 -1
  190. package/dist/web/feeds.js +15 -3
  191. package/dist/web/feeds.js.map +1 -1
  192. package/dist/web/index.d.ts +4 -2
  193. package/dist/web/index.d.ts.map +1 -1
  194. package/dist/web/index.js +3 -2
  195. package/dist/web/index.js.map +1 -1
  196. package/dist/web/indexnow.d.ts +9 -0
  197. package/dist/web/indexnow.d.ts.map +1 -0
  198. package/dist/web/indexnow.js +27 -0
  199. package/dist/web/indexnow.js.map +1 -0
  200. package/dist/web/llms.d.ts +58 -0
  201. package/dist/web/llms.d.ts.map +1 -0
  202. package/dist/web/llms.js +91 -0
  203. package/dist/web/llms.js.map +1 -0
  204. package/dist/web/locale.d.ts +41 -0
  205. package/dist/web/locale.d.ts.map +1 -0
  206. package/dist/web/locale.js +56 -0
  207. package/dist/web/locale.js.map +1 -0
  208. package/dist/web/manifest.d.ts +50 -0
  209. package/dist/web/manifest.d.ts.map +1 -0
  210. package/dist/web/manifest.js +56 -0
  211. package/dist/web/manifest.js.map +1 -0
  212. package/dist/web/negotiate.d.ts.map +1 -1
  213. package/dist/web/negotiate.js +6 -0
  214. package/dist/web/negotiate.js.map +1 -1
  215. package/dist/web/oembed.d.ts +104 -0
  216. package/dist/web/oembed.d.ts.map +1 -0
  217. package/dist/web/oembed.js +290 -0
  218. package/dist/web/oembed.js.map +1 -0
  219. package/dist/web/opensearch.d.ts +35 -0
  220. package/dist/web/opensearch.d.ts.map +1 -0
  221. package/dist/web/opensearch.js +65 -0
  222. package/dist/web/opensearch.js.map +1 -0
  223. package/dist/web/render.d.ts +6 -1
  224. package/dist/web/render.d.ts.map +1 -1
  225. package/dist/web/render.js +40 -10
  226. package/dist/web/render.js.map +1 -1
  227. package/dist/web/robots.d.ts +89 -0
  228. package/dist/web/robots.d.ts.map +1 -0
  229. package/dist/web/robots.js +259 -0
  230. package/dist/web/robots.js.map +1 -0
  231. package/dist/web/routes.d.ts.map +1 -1
  232. package/dist/web/routes.js +179 -8
  233. package/dist/web/routes.js.map +1 -1
  234. package/dist/web/share-image.d.ts +51 -0
  235. package/dist/web/share-image.d.ts.map +1 -0
  236. package/dist/web/share-image.js +43 -0
  237. package/dist/web/share-image.js.map +1 -0
  238. package/dist/web/sitemap.d.ts +0 -26
  239. package/dist/web/sitemap.d.ts.map +1 -1
  240. package/dist/web/sitemap.js +0 -44
  241. package/dist/web/sitemap.js.map +1 -1
  242. package/dist/web/templates.d.ts +16 -9
  243. package/dist/web/templates.d.ts.map +1 -1
  244. package/dist/web/templates.js +88 -55
  245. package/dist/web/templates.js.map +1 -1
  246. package/dist/web/themes.d.ts +33 -0
  247. package/dist/web/themes.d.ts.map +1 -1
  248. package/dist/web/themes.js +57 -0
  249. package/dist/web/themes.js.map +1 -1
  250. package/dist/webmention/discovery.d.ts +4 -2
  251. package/dist/webmention/discovery.d.ts.map +1 -1
  252. package/dist/webmention/discovery.js +14 -8
  253. package/dist/webmention/discovery.js.map +1 -1
  254. package/dist/webmention/fetch-public.d.ts +2 -0
  255. package/dist/webmention/fetch-public.d.ts.map +1 -1
  256. package/dist/webmention/fetch-public.js +1 -1
  257. package/dist/webmention/fetch-public.js.map +1 -1
  258. package/package.json +2 -1
  259. package/templates/site/content/_data/site.json +0 -1
  260. package/themes/default/README.md +174 -43
  261. package/themes/default/layouts/base.njk +116 -17
  262. package/themes/default/layouts/front-page.njk +7 -1
  263. package/themes/default/layouts/home.njk +11 -0
  264. package/themes/default/layouts/page.njk +4 -3
  265. package/themes/default/layouts/post.njk +5 -4
  266. package/themes/default/layouts/search.njk +4 -5
  267. package/themes/default/partials/archive.njk +3 -1
  268. package/themes/default/partials/bio.njk +16 -2
  269. package/themes/default/partials/breadcrumbs.njk +20 -0
  270. package/themes/default/partials/conversation.njk +4 -1
  271. package/themes/default/partials/jsonld.njk +49 -9
  272. package/themes/default/partials/kicker.njk +6 -4
  273. package/themes/default/partials/lang.njk +7 -0
  274. package/themes/default/partials/post-list.njk +5 -3
  275. package/themes/default/partials/reply-context.njk +4 -2
  276. package/themes/default/src/style.css +14 -0
  277. package/themes/default/static/style.css +57 -0
  278. package/themes/default/theme.json +2 -0
@@ -1,4 +1,3 @@
1
- import { ADMIN_PREFIX } from '../admin/session.js';
2
1
  import { escapeXml } from './feeds.js';
3
2
  import { absoluteUrl, contentEtag, isNotModified } from './negotiate.js';
4
3
  /**
@@ -17,8 +16,6 @@ import { absoluteUrl, contentEtag, isNotModified } from './negotiate.js';
17
16
  */
18
17
  /** The sitemap's URL. Fixed: it is the one a `robots.txt` names. */
19
18
  export const SITEMAP_PATH = '/sitemap.xml';
20
- /** The robots file's URL. Fixed by the standard; nothing else is looked at. */
21
- export const ROBOTS_PATH = '/robots.txt';
22
19
  /** The namespace both a `<urlset>` and a `<sitemapindex>` are written in. */
23
20
  export const SITEMAP_NAMESPACE = 'http://www.sitemaps.org/schemas/sitemap/0.9';
24
21
  /**
@@ -84,8 +81,6 @@ function document(root, entries, baseUrl, entryName) {
84
81
  }
85
82
  /** What a sitemap is served as. */
86
83
  export const SITEMAP_CONTENT_TYPE = 'application/xml; charset=utf-8';
87
- /** What a robots file is served as. */
88
- export const ROBOTS_CONTENT_TYPE = 'text/plain; charset=utf-8';
89
84
  /**
90
85
  * One sitemap as an HTTP response, or `undefined` when the URL names a child
91
86
  * that does not exist and the caller owes a 404.
@@ -157,43 +152,4 @@ function fingerprint(entries, baseUrl, page) {
157
152
  ...entries.map((entry) => `${entry.loc} ${entry.lastmod?.toISOString() ?? ''}`),
158
153
  ].join('\n');
159
154
  }
160
- /**
161
- * The robots file: everything public is crawlable, the admin is not, and the
162
- * sitemap is named absolutely because that is the only spelling the standard
163
- * allows for a `Sitemap:` line.
164
- *
165
- * Nothing else is disallowed. The ActivityPub routes under `/ap/` are left
166
- * open deliberately: an actor and an object are documents meant to be
167
- * fetched, they carry the same content as the pages that link to them, and a
168
- * crawler that follows one gets JSON it will ignore. Hiding them would only
169
- * make the fediverse's own view of the site depend on a file written for
170
- * search engines.
171
- */
172
- export function robotsTxt(baseUrl) {
173
- return [
174
- 'User-agent: *',
175
- `Disallow: ${ADMIN_PREFIX}/`,
176
- '',
177
- `Sitemap: ${absoluteUrl(SITEMAP_PATH, baseUrl)}`,
178
- '',
179
- ].join('\n');
180
- }
181
- /**
182
- * The robots file as an HTTP response.
183
- *
184
- * It has a validator but no `Last-Modified`: nothing dates it. Its body is a
185
- * function of the site's origin alone, so the ETag moves when that does and
186
- * never otherwise, which is exactly what a crawler's `If-None-Match` should
187
- * be told.
188
- */
189
- export function robotsResponse(baseUrl, conditional) {
190
- const body = robotsTxt(baseUrl);
191
- const etag = contentEtag('robots', body);
192
- const headers = new Headers({ etag, 'cache-control': 'no-cache' });
193
- if (isNotModified(conditional, etag, undefined)) {
194
- return new Response(null, { status: 304, headers });
195
- }
196
- headers.set('content-type', ROBOTS_CONTENT_TYPE);
197
- return new Response(body, { headers });
198
- }
199
155
  //# sourceMappingURL=sitemap.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sitemap.js","sourceRoot":"","sources":["../../src/web/sitemap.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sitemap.js","sourceRoot":"","sources":["../../src/web/sitemap.ts"],"names":[],"mappings":"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"}
@@ -53,20 +53,27 @@ export declare function createTemplateEnvironment(options: CreateTemplateEnviron
53
53
  */
54
54
  export declare function useThemeDirs(environment: Environment, dirs: readonly string[]): void;
55
55
  /** How `date` renders a value. */
56
- export type DateFormat = 'readable' | 'iso' | 'html' | 'year' | 'month';
56
+ export type DateFormat = 'readable' | 'full' | 'long' | 'medium' | 'short' | 'iso' | 'html' | 'year' | 'month';
57
57
  /**
58
- * `date` filter. An unparseable value renders as the empty string.
58
+ * `date` filter. An unparseable value renders as the empty string, and so
59
+ * does a zone Intl does not know.
59
60
  *
60
61
  * `iso` is the instant, always in UTC, because that is what a `<time
61
- * datetime>` and a feed want and it must not move when a setting does. The
62
- * other four are the calendar the reader in `timezone` is on, which is what
63
- * makes a post published at half past midnight in Berlin say 1 October rather
64
- * than the 30 September UTC was still on.
62
+ * datetime>` and a feed want and it must not move when a setting does. `html`
63
+ * is the ISO calendar day in `timezone`, for the same attribute. The rest are
64
+ * that calendar day written in `locale` by Intl, which is what makes a post
65
+ * published at half past midnight in Berlin say 1 October rather than the 30
66
+ * September UTC was still on, and a French site say `1 octobre`.
65
67
  *
66
68
  * `month` is the month that calendar day falls in, "September 2026", which is
67
69
  * what heads a group of an archive page (TASK-85). It is a format rather than
68
- * something the archive works out for itself so that the month names are in
69
- * one table and a theme can head a group of its own the same way.
70
+ * something the archive works out for itself so that a theme can head a group
71
+ * of its own the same way.
72
+ *
73
+ * Bare `en` is written the way `en-GB` writes it, day before month, because
74
+ * that is what the CMS printed before it had locales and `en` names a language
75
+ * rather than a convention. A site that wants `September 2, 2026` says
76
+ * `en-US`.
70
77
  */
71
- export declare function formatDate(value: unknown, format: string, timezone?: string): string;
78
+ export declare function formatDate(value: unknown, format: string, timezone?: string, locale?: string): string;
72
79
  //# sourceMappingURL=templates.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/web/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,UAAU,CAAC;AAMzD,0EAA0E;AAC1E,MAAM,WAAW,gCAAgC;IAC/C;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAC1C,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gCAAgC,GAAG,WAAW,CAahG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAiBpF;AAED,kCAAkC;AAClC,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAmFxE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAyB,GAClC,MAAM,CAqBR"}
1
+ {"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/web/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,UAAU,CAAC;AAUzD,0EAA0E;AAC1E,MAAM,WAAW,gCAAgC;IAC/C;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAC1C,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gCAAgC,GAAG,WAAW,CAahG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAiBpF;AAED,kCAAkC;AAClC,MAAM,MAAM,UAAU,GACpB,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAuHxF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,MAAyB,EACnC,MAAM,GAAE,MAAuB,GAC9B,MAAM,CAwBR"}
@@ -1,6 +1,9 @@
1
1
  import { Environment, FileSystemLoader } from 'nunjucks';
2
2
  import { calendarDayIn, DEFAULT_TIMEZONE } from '../content/time.js';
3
+ import { accountOf } from '../federation/paths.js';
3
4
  import { themeAssetUrl } from './assets.js';
5
+ import { siteLocale, siteTimezone } from './context.js';
6
+ import { canonicalLocale, DEFAULT_LOCALE, pluralForm } from './locale.js';
4
7
  import { themeSearchPath } from './themes.js';
5
8
  /**
6
9
  * A Nunjucks environment whose loader searches the theme directories in the
@@ -57,20 +60,34 @@ export function useThemeDirs(environment, dirs) {
57
60
  * are written against it.
58
61
  *
59
62
  * Per decision-11 a date in a file is a UTC instant and the site's `timezone`
60
- * setting is the lens it is read through, so `readable`, `html`, `year` and
61
- * `month` are rendered in the site's zone and `iso` stays the instant. The
62
- * zone comes from
63
- * the `site` global of the render in hand — Nunjucks calls a filter with the
64
- * template context as `this`, so nothing has to be threaded through every
65
- * template — which is what lets the setting change what every page shows
66
- * without a file changing. An Eleventy build of the same content applies the
67
- * same lens with Luxon and `zone` read from `site.json`.
63
+ * setting is the lens it is read through, so every format but `iso` is
64
+ * rendered in the site's zone and `iso` stays the instant; the words are the
65
+ * site's locale (TASK-153), unless a template passes a locale of its own
66
+ * after the zone, as the default theme does for a date inside an article
67
+ * written in another language (TASK-189). Both come from the `site` global of the render in
68
+ * hand — Nunjucks calls a filter with the template context as `this`, so
69
+ * nothing has to be threaded through every template — which is what lets a
70
+ * setting change what every page shows without a file changing. An Eleventy
71
+ * build of the same content applies the same lens and locale with Intl, both
72
+ * read from `site.json` (`docs/eleventy.config.example.js`).
68
73
  */
69
74
  function addFilters(environment, baseUrl, loader) {
70
75
  const base = new URL(baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`);
71
76
  const basePath = base.pathname === '/' ? '' : base.pathname.replace(/\/$/, '');
72
- environment.addFilter('date', function (value, format = 'readable', timezone) {
73
- return formatDate(value, typeof format === 'string' ? format : 'readable', typeof timezone === 'string' && timezone !== '' ? timezone : siteTimezone(this));
77
+ environment.addFilter('date', function (value, format = 'readable', timezone, locale) {
78
+ const site = renderSite(this);
79
+ return formatDate(value, typeof format === 'string' ? format : 'readable', typeof timezone === 'string' && timezone !== '' ? timezone : siteTimezone(site), (typeof locale === 'string' ? canonicalLocale(locale) : undefined) ?? siteLocale(site));
80
+ });
81
+ // `{{ count | plural({ one: "# reply", other: "# replies" }) }}`: the form
82
+ // for the count's plural category in the site's locale (TASK-153). A theme
83
+ // whose strings are in one language names it, so their grammar is that
84
+ // language's whatever the site's locale.
85
+ environment.addFilter('plural', function (count, forms, locale) {
86
+ if (typeof forms !== 'object' || forms === null)
87
+ return '';
88
+ const tag = (typeof locale === 'string' ? canonicalLocale(locale) : undefined) ??
89
+ siteLocale(renderSite(this));
90
+ return pluralForm(Number(count), forms, tag);
74
91
  });
75
92
  // Eleventy's `url` filter: make a site-root path absolute against the base
76
93
  // path, so a site served from a subdirectory links correctly.
@@ -97,77 +114,93 @@ function addFilters(environment, baseUrl, loader) {
97
114
  return pathname;
98
115
  }
99
116
  });
117
+ // `{{ siteAuthor.username | fediverseHandle }}`: a user's own account on
118
+ // this site, `@ada@example.com`, exactly as WebFinger answers for it
119
+ // (TASK-202), so a theme never spells the host.
120
+ environment.addFilter('fediverseHandle', (value) => typeof value === 'string' && value !== '' ? `@${accountOf(value, baseUrl)}` : '');
100
121
  return environment;
101
122
  }
102
- const MONTHS = [
103
- 'January',
104
- 'February',
105
- 'March',
106
- 'April',
107
- 'May',
108
- 'June',
109
- 'July',
110
- 'August',
111
- 'September',
112
- 'October',
113
- 'November',
114
- 'December',
115
- ];
116
123
  /**
117
- * `date` filter. An unparseable value renders as the empty string.
124
+ * What Intl is asked for, by format. `full`, `long`, `medium` and `short` are
125
+ * Intl's own date styles, so a theme picks how much it wants said and the
126
+ * locale decides how to say it; `readable` is `long` under the name it had
127
+ * before there were styles.
128
+ */
129
+ const INTL_FORMATS = {
130
+ full: { dateStyle: 'full' },
131
+ long: { dateStyle: 'long' },
132
+ medium: { dateStyle: 'medium' },
133
+ short: { dateStyle: 'short' },
134
+ readable: { dateStyle: 'long' },
135
+ month: { year: 'numeric', month: 'long' },
136
+ year: { year: 'numeric' },
137
+ };
138
+ /** One formatter per locale, zone and format, since a page prints dozens. */
139
+ const formatters = new Map();
140
+ /**
141
+ * `date` filter. An unparseable value renders as the empty string, and so
142
+ * does a zone Intl does not know.
118
143
  *
119
144
  * `iso` is the instant, always in UTC, because that is what a `<time
120
- * datetime>` and a feed want and it must not move when a setting does. The
121
- * other four are the calendar the reader in `timezone` is on, which is what
122
- * makes a post published at half past midnight in Berlin say 1 October rather
123
- * than the 30 September UTC was still on.
145
+ * datetime>` and a feed want and it must not move when a setting does. `html`
146
+ * is the ISO calendar day in `timezone`, for the same attribute. The rest are
147
+ * that calendar day written in `locale` by Intl, which is what makes a post
148
+ * published at half past midnight in Berlin say 1 October rather than the 30
149
+ * September UTC was still on, and a French site say `1 octobre`.
124
150
  *
125
151
  * `month` is the month that calendar day falls in, "September 2026", which is
126
152
  * what heads a group of an archive page (TASK-85). It is a format rather than
127
- * something the archive works out for itself so that the month names are in
128
- * one table and a theme can head a group of its own the same way.
153
+ * something the archive works out for itself so that a theme can head a group
154
+ * of its own the same way.
155
+ *
156
+ * Bare `en` is written the way `en-GB` writes it, day before month, because
157
+ * that is what the CMS printed before it had locales and `en` names a language
158
+ * rather than a convention. A site that wants `September 2, 2026` says
159
+ * `en-US`.
129
160
  */
130
- export function formatDate(value, format, timezone = DEFAULT_TIMEZONE) {
161
+ export function formatDate(value, format, timezone = DEFAULT_TIMEZONE, locale = DEFAULT_LOCALE) {
131
162
  const date = toDate(value);
132
163
  if (date === undefined)
133
164
  return '';
134
165
  if (format === 'iso')
135
166
  return date.toISOString();
136
- const day = calendarDayIn(date, timezone);
137
- if (day === undefined)
138
- return '';
139
- const [year = '', month = '', dayOfMonth = ''] = day.split('-');
140
- switch (format) {
141
- case 'html':
142
- return day;
143
- case 'year':
144
- return year;
145
- case 'month':
146
- return `${MONTHS[Number(month) - 1] ?? ''} ${year}`;
147
- case 'readable':
148
- default:
149
- return `${String(Number(dayOfMonth))} ${MONTHS[Number(month) - 1] ?? ''} ${year}`;
167
+ if (format === 'html')
168
+ return calendarDayIn(date, timezone) ?? '';
169
+ const options = INTL_FORMATS[format] ?? INTL_FORMATS['long'];
170
+ const tag = canonicalLocale(locale) ?? DEFAULT_LOCALE;
171
+ const key = `${tag}|${timezone}|${format}`;
172
+ let formatter = formatters.get(key);
173
+ if (formatter === undefined) {
174
+ try {
175
+ formatter = new Intl.DateTimeFormat(tag === 'en' ? 'en-GB' : tag, {
176
+ ...options,
177
+ timeZone: timezone,
178
+ });
179
+ }
180
+ catch {
181
+ return '';
182
+ }
183
+ formatters.set(key, formatter);
150
184
  }
185
+ return formatter.format(date);
151
186
  }
152
187
  /**
153
- * The zone the render in hand is in: the `timezone` of its `site` global.
188
+ * The `site` global of the render in hand.
154
189
  *
155
190
  * Nunjucks calls a filter with the template context as `this`, so the filter
156
191
  * can read a per-render value without the environment holding any state of its
157
192
  * own — which matters, because one environment serves every request and a zone
158
- * stored on it would be a race between two of them.
193
+ * or a locale stored on it would be a race between two of them.
159
194
  */
160
- function siteTimezone(context) {
195
+ function renderSite(context) {
196
+ const none = {};
161
197
  if (typeof context !== 'object' || context === null)
162
- return DEFAULT_TIMEZONE;
198
+ return none;
163
199
  const lookup = context.lookup;
164
200
  if (typeof lookup !== 'function')
165
- return DEFAULT_TIMEZONE;
201
+ return none;
166
202
  const site = lookup.call(context, 'site');
167
- if (typeof site !== 'object' || site === null)
168
- return DEFAULT_TIMEZONE;
169
- const timezone = site['timezone'];
170
- return typeof timezone === 'string' && timezone !== '' ? timezone : DEFAULT_TIMEZONE;
203
+ return typeof site === 'object' && site !== null ? site : none;
171
204
  }
172
205
  /**
173
206
  * A value as an instant, or `undefined` when it is not one.
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/web/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AA+B9C;;;;;;;GAOG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAyC;IACjF,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,eAAe,EAAE,CAAC,CAAC,EAAE;QACjF,OAAO,EAAE,OAAO,CAAC,OAAO,KAAK,IAAI;KAClC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC,MAAM,EAAE;QAC1C,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,IAAI;QACtC,gBAAgB,EAAE,KAAK;QACvB,UAAU,EAAE,IAAI;QAChB,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;AAC1D,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,YAAY,CAAC,WAAwB,EAAE,IAAuB;IAC5E,4EAA4E;IAC5E,4EAA4E;IAC5E,6CAA6C;IAC7C,MAAM,SAAS,GAAG,WAGjB,CAAC;IAEF,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC;QACjC,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC;YAAE,SAAS;QAE/F,MAAM,CAAC,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QAC/B,SAAS,CAAC,eAAe,EAAE,CAAC;IAC9B,CAAC;AACH,CAAC;AAKD;;;;;;;;;;;;;GAaG;AACH,SAAS,UAAU,CACjB,WAAwB,EACxB,OAAe,EACf,MAAwB;IAExB,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC;IACtE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAE/E,WAAW,CAAC,SAAS,CACnB,MAAM,EACN,UAAyB,KAAc,EAAE,MAAM,GAAY,UAAU,EAAE,QAAkB;QACvF,OAAO,UAAU,CACf,KAAK,EACL,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,EAChD,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAChF,CAAC;IACJ,CAAC,CACF,CAAC;IAEF,2EAA2E;IAC3E,8DAA8D;IAC9D,MAAM,YAAY,GAAG,CAAC,KAAc,EAAU,EAAE;QAC9C,MAAM,QAAQ,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACxD,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IACxE,CAAC,CAAC;IAEF,WAAW,CAAC,SAAS,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC;IAE3C,6EAA6E;IAC7E,yEAAyE;IACzE,yEAAyE;IACzE,kEAAkE;IAClE,MAAM,WAAW,GAAG,MAA8C,CAAC;IACnE,WAAW,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,KAAc,EAAE,EAAE,CAChD,YAAY,CAAC,aAAa,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC,CAC7F,CAAC;IAEF,yEAAyE;IACzE,4EAA4E;IAC5E,yDAAyD;IACzD,WAAW,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,KAAc,EAAE,EAAE;QACtD,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC;YACH,OAAO,IAAI,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,MAAM,GAAG;IACb,SAAS;IACT,UAAU;IACV,OAAO;IACP,OAAO;IACP,KAAK;IACL,MAAM;IACN,MAAM;IACN,QAAQ;IACR,WAAW;IACX,SAAS;IACT,UAAU;IACV,UAAU;CACF,CAAC;AAEX;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,UAAU,CACxB,KAAc,EACd,MAAc,EACd,QAAQ,GAAW,gBAAgB;IAEnC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAClC,IAAI,MAAM,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;IAEhD,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC1C,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAEjC,MAAM,CAAC,IAAI,GAAG,EAAE,EAAE,KAAK,GAAG,EAAE,EAAE,UAAU,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAEhE,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,MAAM;YACT,OAAO,GAAG,CAAC;QACb,KAAK,MAAM;YACT,OAAO,IAAI,CAAC;QACd,KAAK,OAAO;YACV,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QACtD,KAAK,UAAU,CAAC;QAChB;YACE,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;IACtF,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,OAAgB;IACpC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,gBAAgB,CAAC;IAE7E,MAAM,MAAM,GAAI,OAAgC,CAAC,MAAM,CAAC;IACxD,IAAI,OAAO,MAAM,KAAK,UAAU;QAAE,OAAO,gBAAgB,CAAC;IAE1D,MAAM,IAAI,GAAY,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACnD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,gBAAgB,CAAC;IAEvE,MAAM,QAAQ,GAAI,IAAgC,CAAC,UAAU,CAAC,CAAC;IAC/D,OAAO,OAAO,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC;AACvF,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,MAAM,CAAC,KAAc;IAC5B,IAAI,KAAK,YAAY,IAAI;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;IACpF,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO,IAAI,IAAI,EAAE,CAAC;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC3D,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IAC7D,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/web/templates.ts"],"names":[],"mappings":"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"}
@@ -47,6 +47,35 @@ export interface ThemeArea {
47
47
  /** What the Navigation screen calls this place, for a person to read. */
48
48
  readonly label: string;
49
49
  }
50
+ /**
51
+ * What the `color-scheme` meta may say (TASK-146): the schemes a theme draws,
52
+ * the one it prefers first. `only dark` is not among them because the HTML
53
+ * standard does not allow it.
54
+ */
55
+ export declare const COLOR_SCHEMES: readonly ['normal', 'light', 'dark', 'light dark', 'dark light', 'only light'];
56
+ /** One of {@link COLOR_SCHEMES}. */
57
+ export type ColorScheme = (typeof COLOR_SCHEMES)[number];
58
+ /**
59
+ * The colours a theme declares for the browser to use before its stylesheet
60
+ * has loaded, as its `theme.json` writes them:
61
+ *
62
+ * "colorScheme": "light dark",
63
+ * "themeColor": { "light": "#faf7f2", "dark": "#171412" }
64
+ *
65
+ * `colorScheme` is the `<meta name="color-scheme">`, which keeps a dark-mode
66
+ * reader from a white flash while the stylesheet is on its way. `themeColor`
67
+ * is the browser chrome around the page, one colour per scheme, and should be
68
+ * the page's own background so the two meet without a seam. A theme colour is
69
+ * a six- or three-digit hex colour, without an alpha channel, which a browser
70
+ * would ignore.
71
+ */
72
+ export interface ThemeColors {
73
+ readonly colorScheme?: ColorScheme | undefined;
74
+ readonly themeColor: {
75
+ readonly light?: string | undefined;
76
+ readonly dark?: string | undefined;
77
+ };
78
+ }
50
79
  /** One theme directory, read and validated. */
51
80
  export interface Theme {
52
81
  /** The directory name, which is the theme's id and what a site.json names. */
@@ -65,6 +94,8 @@ export interface Theme {
65
94
  * areas existed and every theme that renders no menu at all.
66
95
  */
67
96
  readonly areas: readonly ThemeArea[];
97
+ /** The colours the manifest declares, each one absent when it declares none. */
98
+ readonly colors: ThemeColors;
68
99
  }
69
100
  /** A theme, or the reason the directory is not one. */
70
101
  export type ThemeRead = {
@@ -157,6 +188,8 @@ export interface ChosenTheme {
157
188
  * packaged theme on purpose and for one whose choice is working.
158
189
  */
159
190
  readonly problem: string | undefined;
191
+ /** The colours the page declares: {@link ThemeColors}, the packaged theme's where this one is silent. */
192
+ readonly colors: ThemeColors;
160
193
  }
161
194
  /**
162
195
  * The theme one site has chosen, resolved against its themes directory.
@@ -1 +1 @@
1
- {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/web/themes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"themes.d.ts","sourceRoot":"","sources":["../../src/web/themes.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,19 @@ export const THEME_MANIFEST_FILE = 'theme.json';
33
33
  * loaded as a site theme by accident.
34
34
  */
35
35
  export const SITE_THEME_KIND = 'site';
36
+ /**
37
+ * What the `color-scheme` meta may say (TASK-146): the schemes a theme draws,
38
+ * the one it prefers first. `only dark` is not among them because the HTML
39
+ * standard does not allow it.
40
+ */
41
+ export const COLOR_SCHEMES = [
42
+ 'normal',
43
+ 'light',
44
+ 'dark',
45
+ 'light dark',
46
+ 'dark light',
47
+ 'only light',
48
+ ];
36
49
  /**
37
50
  * Read one directory as a theme.
38
51
  *
@@ -90,9 +103,49 @@ export function readTheme(dir) {
90
103
  ? { description: description.trim() }
91
104
  : {}),
92
105
  areas: themeAreasOf(manifest['areas']),
106
+ colors: themeColorsOf(manifest['colorScheme'], manifest['themeColor']),
93
107
  },
94
108
  };
95
109
  }
110
+ const HEX_COLOR = /^#(?:[0-9a-f]{3}|[0-9a-f]{6})$/i;
111
+ /**
112
+ * The colours a manifest declares, leaving out any it got wrong.
113
+ *
114
+ * Tolerant for the reason {@link themeAreasOf} is: a colour a browser would
115
+ * not take costs the site a tinted address bar, not its pages.
116
+ */
117
+ function themeColorsOf(scheme, color) {
118
+ const declared = typeof color === 'object' && color !== null ? color : {};
119
+ const hex = (value) => typeof value === 'string' && HEX_COLOR.test(value) ? value : undefined;
120
+ const light = hex(declared['light']);
121
+ const dark = hex(declared['dark']);
122
+ return {
123
+ ...(COLOR_SCHEMES.includes(scheme)
124
+ ? { colorScheme: scheme }
125
+ : {}),
126
+ themeColor: {
127
+ ...(light === undefined ? {} : { light }),
128
+ ...(dark === undefined ? {} : { dark }),
129
+ },
130
+ };
131
+ }
132
+ /**
133
+ * A chosen theme's colours, each one it leaves out taken from the packaged
134
+ * theme: a site theme is laid over the packaged one a file at a time, and it
135
+ * keeps the packaged stylesheet until it ships its own, so it keeps the
136
+ * packaged colours until it declares its own.
137
+ */
138
+ function resolvedColors(theme) {
139
+ const packaged = readTheme(PACKAGED_THEME_DIR);
140
+ const base = packaged.ok ? packaged.theme.colors : { themeColor: {} };
141
+ if (theme === undefined)
142
+ return base;
143
+ const scheme = theme.colors.colorScheme ?? base.colorScheme;
144
+ return {
145
+ ...(scheme === undefined ? {} : { colorScheme: scheme }),
146
+ themeColor: { ...base.themeColor, ...theme.colors.themeColor },
147
+ };
148
+ }
96
149
  /**
97
150
  * An `areas` value as the areas it declares, ignoring anything that is not
98
151
  * one.
@@ -213,6 +266,10 @@ export function themeNameProblem(name) {
213
266
  * a site that 500s on every page because of a directory rename.
214
267
  */
215
268
  export function chooseTheme(options) {
269
+ const chosen = chooseThemeDirs(options);
270
+ return { ...chosen, colors: resolvedColors(chosen.theme) };
271
+ }
272
+ function chooseThemeDirs(options) {
216
273
  const name = options.name.trim();
217
274
  if (name === '')
218
275
  return { theme: undefined, dirs: themeSearchPath(), problem: undefined };
@@ -1 +1 @@
1
- {"version":3,"file":"themes.js","sourceRoot":"","sources":["../../src/web/themes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"themes.js","sourceRoot":"","sources":["../../src/web/themes.ts"],"names":[],"mappings":"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"}
@@ -23,15 +23,17 @@ export declare const WEBMENTION_USER_AGENT = "Geekity/1.0 (+https://github.com/a
23
23
  * the caller records that rather than stopping.
24
24
  */
25
25
  export declare function discoverEndpoint(target: string): Promise<string | undefined>;
26
+ /** The endpoint one or more `Link` headers name, or `undefined`. */
27
+ export declare function endpointInHeader(header: string | null, base: string): string | undefined;
26
28
  /**
27
- * The endpoint one or more `Link` headers name, or `undefined`.
29
+ * Every target a `Link` header names for `rel`, in order and unresolved.
28
30
  *
29
31
  * A header may carry several links separated by commas and each may name
30
32
  * several relations, so both are split. Splitting on commas that are not
31
33
  * inside angle brackets or quotes is what keeps a URL holding a comma — which
32
34
  * is legal — from being torn in half.
33
35
  */
34
- export declare function endpointInHeader(header: string | null, base: string): string | undefined;
36
+ export declare function linkTargets(header: string | null, rel: string): string[];
35
37
  /**
36
38
  * The endpoint a page's markup names, or `undefined`.
37
39
  *
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/webmention/discovery.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAE3C,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,UAAY,CAAC;AAE7C,gCAAgC;AAChC,eAAO,MAAM,qBAAqB,0DAA0D,CAAC;AAE7F;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkClF;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAexF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAW7E;AAsCD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BpE"}
1
+ {"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../src/webmention/discovery.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAE3C,wEAAwE;AACxE,eAAO,MAAM,mBAAmB,UAAY,CAAC;AAE7C,gCAAgC;AAChC,eAAO,MAAM,qBAAqB,0DAA0D,CAAC;AAE7F;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkClF;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGxF;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAgBxE;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAW7E;AAsCD;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BpE"}
@@ -55,28 +55,34 @@ export async function discoverEndpoint(target) {
55
55
  }
56
56
  return endpointInHtml(await readCapped(response), arrivedAt);
57
57
  }
58
+ /** The endpoint one or more `Link` headers name, or `undefined`. */
59
+ export function endpointInHeader(header, base) {
60
+ const [target] = linkTargets(header, 'webmention');
61
+ return target === undefined ? undefined : resolve(target, base);
62
+ }
58
63
  /**
59
- * The endpoint one or more `Link` headers name, or `undefined`.
64
+ * Every target a `Link` header names for `rel`, in order and unresolved.
60
65
  *
61
66
  * A header may carry several links separated by commas and each may name
62
67
  * several relations, so both are split. Splitting on commas that are not
63
68
  * inside angle brackets or quotes is what keeps a URL holding a comma — which
64
69
  * is legal — from being torn in half.
65
70
  */
66
- export function endpointInHeader(header, base) {
71
+ export function linkTargets(header, rel) {
67
72
  if (header === null)
68
- return undefined;
73
+ return [];
74
+ const targets = [];
69
75
  for (const value of splitLinkHeader(header)) {
70
76
  const match = /^\s*<([^>]*)>\s*(.*)$/.exec(value);
71
77
  if (match === null)
72
78
  continue;
73
79
  const relations = /(?:^|;)\s*rel\s*=\s*("([^"]*)"|'([^']*)'|([^;\s]*))/i.exec(match[2] ?? '');
74
- const rel = relations?.[2] ?? relations?.[3] ?? relations?.[4] ?? '';
75
- if (!rel.split(/\s+/).some((token) => token.toLowerCase() === 'webmention'))
76
- continue;
77
- return resolve(match[1] ?? '', base);
80
+ const names = relations?.[2] ?? relations?.[3] ?? relations?.[4] ?? '';
81
+ if (names.split(/\s+/).some((token) => token.toLowerCase() === rel)) {
82
+ targets.push(match[1] ?? '');
83
+ }
78
84
  }
79
- return undefined;
85
+ return targets;
80
86
  }
81
87
  /**
82
88
  * The endpoint a page's markup names, or `undefined`.