@geekity/cms 0.18.0 → 0.20.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 (182) hide show
  1. package/README.md +29 -25
  2. package/admin/components/admin-bar.njk +4 -3
  3. package/admin/components/public-admin-bar.njk +3 -1
  4. package/admin/layouts/shell.njk +1 -0
  5. package/admin/pages/documents/editor.njk +291 -192
  6. package/admin/static/admin.css +123 -13
  7. package/admin/static/location.js +38 -0
  8. package/dist/admin/documents.d.ts +18 -3
  9. package/dist/admin/documents.d.ts.map +1 -1
  10. package/dist/admin/documents.js +150 -21
  11. package/dist/admin/documents.js.map +1 -1
  12. package/dist/admin/editor-layout.d.ts +13 -0
  13. package/dist/admin/editor-layout.d.ts.map +1 -0
  14. package/dist/admin/editor-layout.js +62 -0
  15. package/dist/admin/editor-layout.js.map +1 -0
  16. package/dist/admin/enclosure-field.d.ts +2 -3
  17. package/dist/admin/enclosure-field.d.ts.map +1 -1
  18. package/dist/admin/enclosure-field.js +27 -7
  19. package/dist/admin/enclosure-field.js.map +1 -1
  20. package/dist/admin/headers.d.ts +1 -0
  21. package/dist/admin/headers.d.ts.map +1 -1
  22. package/dist/admin/headers.js +3 -0
  23. package/dist/admin/headers.js.map +1 -1
  24. package/dist/admin/location-field.d.ts +4 -3
  25. package/dist/admin/location-field.d.ts.map +1 -1
  26. package/dist/admin/location-field.js +10 -2
  27. package/dist/admin/location-field.js.map +1 -1
  28. package/dist/admin/media.d.ts.map +1 -1
  29. package/dist/admin/media.js +3 -0
  30. package/dist/admin/media.js.map +1 -1
  31. package/dist/admin/photo-field.d.ts +2 -3
  32. package/dist/admin/photo-field.d.ts.map +1 -1
  33. package/dist/admin/photo-field.js +4 -2
  34. package/dist/admin/photo-field.js.map +1 -1
  35. package/dist/admin/read-field.d.ts +2 -3
  36. package/dist/admin/read-field.d.ts.map +1 -1
  37. package/dist/admin/read-field.js +12 -4
  38. package/dist/admin/read-field.js.map +1 -1
  39. package/dist/config.d.ts +2 -0
  40. package/dist/config.d.ts.map +1 -1
  41. package/dist/config.js.map +1 -1
  42. package/dist/content/citation.d.ts +5 -0
  43. package/dist/content/citation.d.ts.map +1 -1
  44. package/dist/content/citation.js +17 -0
  45. package/dist/content/citation.js.map +1 -1
  46. package/dist/content/kept-properties.d.ts +5 -0
  47. package/dist/content/kept-properties.d.ts.map +1 -0
  48. package/dist/content/kept-properties.js +12 -0
  49. package/dist/content/kept-properties.js.map +1 -0
  50. package/dist/content/location.d.ts +4 -0
  51. package/dist/content/location.d.ts.map +1 -1
  52. package/dist/content/location.js +35 -3
  53. package/dist/content/location.js.map +1 -1
  54. package/dist/content/locations.d.ts +2 -5
  55. package/dist/content/locations.d.ts.map +1 -1
  56. package/dist/content/locations.js +2 -77
  57. package/dist/content/locations.js.map +1 -1
  58. package/dist/content/markdown.d.ts +9 -0
  59. package/dist/content/markdown.d.ts.map +1 -1
  60. package/dist/content/markdown.js +37 -1
  61. package/dist/content/markdown.js.map +1 -1
  62. package/dist/content/permalink-file.d.ts +7 -0
  63. package/dist/content/permalink-file.d.ts.map +1 -0
  64. package/dist/content/permalink-file.js +77 -0
  65. package/dist/content/permalink-file.js.map +1 -0
  66. package/dist/content/post-type.d.ts +1 -6
  67. package/dist/content/post-type.d.ts.map +1 -1
  68. package/dist/content/post-type.js +13 -14
  69. package/dist/content/post-type.js.map +1 -1
  70. package/dist/content/slug.d.ts +2 -1
  71. package/dist/content/slug.d.ts.map +1 -1
  72. package/dist/content/slug.js +3 -1
  73. package/dist/content/slug.js.map +1 -1
  74. package/dist/env.d.ts +6 -0
  75. package/dist/env.d.ts.map +1 -1
  76. package/dist/federation/article.d.ts +8 -7
  77. package/dist/federation/article.d.ts.map +1 -1
  78. package/dist/federation/article.js +37 -18
  79. package/dist/federation/article.js.map +1 -1
  80. package/dist/federation/citations.d.ts +7 -6
  81. package/dist/federation/citations.d.ts.map +1 -1
  82. package/dist/federation/citations.js +44 -28
  83. package/dist/federation/citations.js.map +1 -1
  84. package/dist/federation/delivery.d.ts.map +1 -1
  85. package/dist/federation/delivery.js +23 -16
  86. package/dist/federation/delivery.js.map +1 -1
  87. package/dist/index.d.ts +5 -4
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +2 -1
  90. package/dist/index.js.map +1 -1
  91. package/dist/indieauth/bearer.d.ts +10 -6
  92. package/dist/indieauth/bearer.d.ts.map +1 -1
  93. package/dist/indieauth/bearer.js +11 -9
  94. package/dist/indieauth/bearer.js.map +1 -1
  95. package/dist/indieauth/token.js +1 -1
  96. package/dist/indieauth/token.js.map +1 -1
  97. package/dist/micropub/content.d.ts +15 -0
  98. package/dist/micropub/content.d.ts.map +1 -0
  99. package/dist/micropub/content.js +254 -0
  100. package/dist/micropub/content.js.map +1 -0
  101. package/dist/micropub/create.d.ts +7 -3
  102. package/dist/micropub/create.d.ts.map +1 -1
  103. package/dist/micropub/create.js +75 -24
  104. package/dist/micropub/create.js.map +1 -1
  105. package/dist/micropub/endpoint.d.ts +4 -5
  106. package/dist/micropub/endpoint.d.ts.map +1 -1
  107. package/dist/micropub/endpoint.js +33 -12
  108. package/dist/micropub/endpoint.js.map +1 -1
  109. package/dist/micropub/media.d.ts +6 -4
  110. package/dist/micropub/media.d.ts.map +1 -1
  111. package/dist/micropub/media.js +7 -5
  112. package/dist/micropub/media.js.map +1 -1
  113. package/dist/micropub/update.d.ts +7 -1
  114. package/dist/micropub/update.d.ts.map +1 -1
  115. package/dist/micropub/update.js +32 -7
  116. package/dist/micropub/update.js.map +1 -1
  117. package/dist/web/admin-bar.d.ts.map +1 -1
  118. package/dist/web/admin-bar.js +27 -1
  119. package/dist/web/admin-bar.js.map +1 -1
  120. package/dist/web/context.d.ts +10 -3
  121. package/dist/web/context.d.ts.map +1 -1
  122. package/dist/web/context.js +12 -2
  123. package/dist/web/context.js.map +1 -1
  124. package/dist/web/documents.d.ts +21 -6
  125. package/dist/web/documents.d.ts.map +1 -1
  126. package/dist/web/documents.js +23 -12
  127. package/dist/web/documents.js.map +1 -1
  128. package/dist/web/feed-item.d.ts +26 -3
  129. package/dist/web/feed-item.d.ts.map +1 -1
  130. package/dist/web/feed-item.js +63 -6
  131. package/dist/web/feed-item.js.map +1 -1
  132. package/dist/web/feed-rss.js +3 -3
  133. package/dist/web/feed-rss.js.map +1 -1
  134. package/dist/web/feed-source.d.ts +7 -0
  135. package/dist/web/feed-source.d.ts.map +1 -1
  136. package/dist/web/feed-source.js.map +1 -1
  137. package/dist/web/feeds.d.ts.map +1 -1
  138. package/dist/web/feeds.js +7 -1
  139. package/dist/web/feeds.js.map +1 -1
  140. package/dist/web/negotiate.d.ts +4 -0
  141. package/dist/web/negotiate.d.ts.map +1 -1
  142. package/dist/web/negotiate.js +5 -1
  143. package/dist/web/negotiate.js.map +1 -1
  144. package/dist/web/render.d.ts +5 -4
  145. package/dist/web/render.d.ts.map +1 -1
  146. package/dist/web/render.js +34 -12
  147. package/dist/web/render.js.map +1 -1
  148. package/dist/web/routes.d.ts.map +1 -1
  149. package/dist/web/routes.js +16 -4
  150. package/dist/web/routes.js.map +1 -1
  151. package/dist/web/sanitize.d.ts +10 -0
  152. package/dist/web/sanitize.d.ts.map +1 -1
  153. package/dist/web/sanitize.js +180 -0
  154. package/dist/web/sanitize.js.map +1 -1
  155. package/dist/web/templates.d.ts.map +1 -1
  156. package/dist/web/templates.js +2 -0
  157. package/dist/web/templates.js.map +1 -1
  158. package/dist/webmention/cited-picture.d.ts +37 -0
  159. package/dist/webmention/cited-picture.d.ts.map +1 -0
  160. package/dist/webmention/cited-picture.js +121 -0
  161. package/dist/webmention/cited-picture.js.map +1 -0
  162. package/dist/webmention/fetch-public.d.ts +26 -8
  163. package/dist/webmention/fetch-public.d.ts.map +1 -1
  164. package/dist/webmention/fetch-public.js +22 -12
  165. package/dist/webmention/fetch-public.js.map +1 -1
  166. package/dist/webmention/reply-context.d.ts +30 -8
  167. package/dist/webmention/reply-context.d.ts.map +1 -1
  168. package/dist/webmention/reply-context.js +238 -27
  169. package/dist/webmention/reply-context.js.map +1 -1
  170. package/dist/webmention/reply-contexts.d.ts +28 -16
  171. package/dist/webmention/reply-contexts.d.ts.map +1 -1
  172. package/dist/webmention/reply-contexts.js +108 -25
  173. package/dist/webmention/reply-contexts.js.map +1 -1
  174. package/package.json +10 -9
  175. package/themes/default/README.md +83 -9
  176. package/themes/default/layouts/post.njk +7 -7
  177. package/themes/default/partials/citations.njk +25 -4
  178. package/themes/default/partials/cited-page.njk +58 -0
  179. package/themes/default/partials/post-list.njk +8 -5
  180. package/themes/default/partials/reply-context.njk +9 -11
  181. package/themes/default/src/style.css +37 -0
  182. package/themes/default/static/style.css +83 -0
@@ -490,35 +490,145 @@ button[type='submit']:hover,
490
490
  min-height: 28rem;
491
491
  }
492
492
 
493
- .admin-editor-enclosure {
493
+ .admin-editor-group {
494
494
  margin: 1.25rem 0 0;
495
- padding: 0.75rem 1rem 1rem;
496
495
  border: 1px solid var(--admin-border);
497
496
  }
498
497
 
499
- .admin-editor-syndication {
500
- margin: 1.25rem 0 0;
501
- padding: 0.75rem 1rem 1rem;
502
- border: 1px solid var(--admin-border);
498
+ .admin-editor-side > .admin-editor-group:first-child {
499
+ margin-top: 0;
503
500
  }
504
501
 
505
- .admin-editor-enclosure-heading {
506
- margin: 1.25rem 0 0;
507
- font-size: 1em;
502
+ .admin-editor-group > summary {
503
+ padding: 0.5rem 0.75rem;
504
+ font-weight: 600;
505
+ cursor: pointer;
506
+ }
507
+
508
+ .admin-editor-group > summary:focus-visible {
509
+ outline: 2px solid var(--admin-link);
510
+ outline-offset: 2px;
511
+ }
512
+
513
+ .admin-editor-group > fieldset {
514
+ min-width: 0;
515
+ margin: 0;
516
+ padding: 0 0.75rem 0.75rem;
517
+ border: 0;
518
+ }
519
+
520
+ .admin-editor-group > fieldset > label:first-of-type {
521
+ margin-top: 0.25rem;
522
+ }
523
+
524
+ .admin-editor-row {
525
+ margin-top: 0.75rem;
508
526
  }
509
527
 
510
- .admin-editor-alternate {
528
+ .admin-editor-row > fieldset {
511
529
  display: grid;
512
530
  grid-template-columns: max-content minmax(0, 1fr);
513
531
  gap: 0.4rem 0.75rem;
514
532
  align-items: center;
515
- margin: 0.75rem 0 0;
516
- padding: 0.5rem 0.75rem 0.75rem;
533
+ }
534
+
535
+ .admin-editor-row > fieldset > label:first-of-type {
536
+ margin-top: 0;
537
+ }
538
+
539
+ .admin-editor-row label {
540
+ margin: 0;
541
+ }
542
+
543
+ .admin-editor-row .admin-field-error {
544
+ grid-column: 1 / -1;
545
+ }
546
+
547
+ .admin-cited-card {
548
+ position: relative;
549
+ margin-top: 0.5rem;
550
+ padding: 0.5rem;
517
551
  border: 1px solid var(--admin-border);
552
+ background: var(--admin-surface);
553
+ }
554
+
555
+ .admin-cited-card img {
556
+ display: block;
557
+ width: 100%;
558
+ height: auto;
559
+ max-height: 8rem;
560
+ object-fit: cover;
561
+ }
562
+
563
+ .admin-cited-title {
564
+ margin: 0.375rem 0 0;
565
+ overflow-wrap: break-word;
518
566
  }
519
567
 
520
- .admin-editor-alternate label {
568
+ .admin-cited-card input[type='checkbox'] {
569
+ position: absolute;
570
+ width: 1px;
571
+ height: 1px;
572
+ margin: 0;
573
+ opacity: 0;
574
+ }
575
+
576
+ .admin-editor-group .admin-cited-remove {
577
+ position: absolute;
578
+ top: 0.75rem;
579
+ inset-inline-end: 0.75rem;
580
+ display: inline-grid;
581
+ place-items: center;
582
+ width: 1.75rem;
583
+ height: 1.75rem;
521
584
  margin: 0;
585
+ border: 1px solid var(--admin-border);
586
+ border-radius: 50%;
587
+ background: var(--admin-field);
588
+ font-size: 1.1rem;
589
+ line-height: 1;
590
+ cursor: pointer;
591
+ }
592
+
593
+ .admin-cited-card input:focus-visible + .admin-cited-remove {
594
+ outline: 2px solid var(--admin-focus);
595
+ outline-offset: 2px;
596
+ }
597
+
598
+ .admin-cited-card input:checked + .admin-cited-remove {
599
+ background: var(--admin-text);
600
+ color: var(--admin-surface);
601
+ }
602
+
603
+ .admin-cited-removed {
604
+ display: none;
605
+ margin: 0.25rem 0 0;
606
+ color: var(--admin-muted);
607
+ font-size: 0.9em;
608
+ }
609
+
610
+ .admin-cited-card:has(input:checked) img,
611
+ .admin-cited-card:has(input:checked) .admin-cited-title {
612
+ opacity: 0.4;
613
+ }
614
+
615
+ .admin-cited-card:has(input:checked) .admin-cited-removed {
616
+ display: block;
617
+ }
618
+
619
+ .admin-location-here {
620
+ margin-top: 0.75rem;
621
+ padding: 0.3rem 0.8rem;
622
+ border: 1px solid var(--admin-link);
623
+ border-radius: 3px;
624
+ background: var(--admin-surface);
625
+ color: var(--admin-link);
626
+ font: inherit;
627
+ cursor: pointer;
628
+ }
629
+
630
+ .admin-location-here:hover {
631
+ background: var(--admin-field);
522
632
  }
523
633
 
524
634
  .admin-hint {
@@ -0,0 +1,38 @@
1
+ (function () {
2
+ if (!navigator.geolocation) return;
3
+
4
+ var button = document.getElementById('editor-location-here');
5
+ var status = document.getElementById('editor-location-status');
6
+ var geo = document.getElementById('editor-location-geo');
7
+ var accuracy = document.getElementById('editor-location-accuracy');
8
+ if (!button || !status || !geo || !accuracy) return;
9
+
10
+ var problems = {
11
+ 1: 'The browser was not allowed to share its location. Type the coordinates instead, or allow location for this site and try again.',
12
+ 2: 'The browser could not find its location. Type the coordinates instead.',
13
+ 3: 'The browser took too long to find its location. Try again, or type the coordinates instead.',
14
+ };
15
+
16
+ button.hidden = false;
17
+ button.addEventListener('click', function () {
18
+ button.disabled = true;
19
+ status.textContent = 'Finding your location…';
20
+ navigator.geolocation.getCurrentPosition(
21
+ function (position) {
22
+ var coords = position.coords;
23
+ geo.value = coords.latitude.toFixed(5) + ', ' + coords.longitude.toFixed(5);
24
+ accuracy.value = String(Math.round(coords.accuracy));
25
+ var block = button.closest('details');
26
+ if (block) block.open = true;
27
+ status.textContent =
28
+ 'Filled in from the browser, to within about ' + accuracy.value + ' metres.';
29
+ button.disabled = false;
30
+ },
31
+ function (error) {
32
+ status.textContent = problems[error.code] || problems[2];
33
+ button.disabled = false;
34
+ },
35
+ { enableHighAccuracy: true, timeout: 20000, maximumAge: 60000 },
36
+ );
37
+ });
38
+ })();
@@ -3,6 +3,7 @@ import type { Document, DocumentType } from '../content/document.ts';
3
3
  import type { Enclosure } from '../content/enclosure.ts';
4
4
  import type { Photo } from '../content/photo.ts';
5
5
  import type { PostLocation } from '../content/location.ts';
6
+ import type { KeptProperties } from '../content/kept-properties.ts';
6
7
  import type { ContentStore, ListAllOptions } from '../content/store.ts';
7
8
  import type { StoredVisibility } from '../content/visibility.ts';
8
9
  import type { ResolvedConfig } from '../config.ts';
@@ -10,9 +11,11 @@ import type { DocumentChange } from '../content/sync.ts';
10
11
  import type { GeekityEnv } from '../env.ts';
11
12
  import type { UndescribedImage } from '../images/alt-text.ts';
12
13
  import type { EnclosureForm } from './enclosure-field.ts';
14
+ import type { Refusal } from './editor-layout.ts';
13
15
  import type { LocationForm } from './location-field.ts';
14
16
  import type { PhotoRow } from './photo-field.ts';
15
17
  import type { ReadOfForm } from './read-field.ts';
18
+ import type { ReplyContext } from '../webmention/reply-context.ts';
16
19
  /**
17
20
  * Everything that differs between the posts screens and the pages screens.
18
21
  *
@@ -124,6 +127,8 @@ export interface DocumentSite {
124
127
  readonly announce: (change: DocumentChange) => Promise<void>;
125
128
  /** The username of whoever is writing: the author a new document starts on. */
126
129
  readonly writer: string | undefined;
130
+ readonly citedContext: (target: string) => Promise<ReplyContext | undefined>;
131
+ readonly storedContext: (target: string) => ReplyContext | undefined;
127
132
  }
128
133
  /** What {@link writeDocument} is asked to write. */
129
134
  export interface DocumentWrite {
@@ -133,6 +138,7 @@ export interface DocumentWrite {
133
138
  readonly form: EditorForm;
134
139
  /** Whether it is saved as a draft, which the editor's buttons decide. */
135
140
  readonly draft: boolean;
141
+ readonly keptProperties?: KeptProperties | undefined;
136
142
  }
137
143
  /** What came of a {@link writeDocument}. */
138
144
  export type WriteOutcome = {
@@ -140,10 +146,9 @@ export type WriteOutcome = {
140
146
  readonly saved: Document;
141
147
  /** Images published without alt text, which the editor warns about. */
142
148
  readonly undescribed: readonly UndescribedImage[];
143
- } | {
149
+ } | ({
144
150
  readonly outcome: 'refused';
145
- readonly message: string;
146
- } | {
151
+ } & Refusal) | {
147
152
  readonly outcome: 'conflict';
148
153
  /** The document as the form loaded it, which only an edit has. */
149
154
  readonly document: Document;
@@ -283,6 +288,16 @@ export interface EditorForm {
283
288
  contact: boolean;
284
289
  /** Whether the post is pinned to its author's profile (TASK-207). Posts only. */
285
290
  pinned: boolean;
291
+ /**
292
+ * Whether the post hides the previews of the pages it cites, `preview:
293
+ * false` (TASK-252). Posts only.
294
+ */
295
+ previewHidden: boolean;
296
+ /**
297
+ * The alt text of an image the post cites, `cited-alt` (TASK-255). Posts
298
+ * only; empty for none, when the post's title describes it.
299
+ */
300
+ citedAlt: string;
286
301
  /**
287
302
  * What the document says about comments: one of {@link COMMENT_SETTINGS}.
288
303
  *
@@ -1 +1 @@
1
- {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/admin/documents.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"documents.d.ts","sourceRoot":"","sources":["../../src/admin/documents.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,14 @@
1
1
  import { mkdir, readFile, rename, rm } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
- import { CITATION_PROPERTIES, citationText } from '../content/citation.js';
3
+ import { CITATION_PROPERTIES, citationText, CITED_ALT_FRONT_MATTER_KEY, citedHost, PREVIEW_FRONT_MATTER_KEY, previewShown, } from '../content/citation.js';
4
4
  import { renderMarkdown } from '../content/markdown.js';
5
5
  import { parseDocument } from '../content/parser.js';
6
6
  import { PINNED_FRONT_MATTER_KEY, PINNED_POST_LIMIT, pinnedAt } from '../content/pinned.js';
7
- import { postLabel, replyTarget } from '../content/post-type.js';
7
+ import { discoverPostType, postLabel, replyTarget } from '../content/post-type.js';
8
8
  import { isReadStatus, READ_OF_FRONT_MATTER_KEY, READ_STATUS_FRONT_MATTER_KEY, READ_STATUS_LABELS, READ_STATUSES, readWork, readWorkFrontMatter, } from '../content/read.js';
9
9
  import { ENCLOSURE_FRONT_MATTER_KEY, enclosureOf, isWebUrl, TRANSCRIPT_TYPES, } from '../content/enclosure.js';
10
10
  import { PHOTO_FRONT_MATTER_KEY, photoFrontMatter } from '../content/photo.js';
11
+ import { keptProperties } from '../content/kept-properties.js';
11
12
  import { postLocations } from '../content/locations.js';
12
13
  import { contentFilePath, freeSlug, saveDocument } from '../content/save.js';
13
14
  import { scheduledFor } from '../content/schedule.js';
@@ -33,10 +34,13 @@ import { ADMIN_PREFIX } from './session.js';
33
34
  import { ADMIN_TEMPLATES } from './templates.js';
34
35
  import { UPLOADS_PATH } from './uploads.js';
35
36
  import { BLANK_ALTERNATE_ROW, BLANK_ENCLOSURE_FORM, ENCLOSURE_FIELDS, enclosureChoices, enclosureForm, enclosureFrontMatter, readEnclosureForm, resolveEnclosure, } from './enclosure-field.js';
37
+ import { openGroups } from './editor-layout.js';
38
+ import { allowGeolocation } from './headers.js';
36
39
  import { BLANK_LOCATION_FORM, LOCATION_FIELDS, locationForm, readLocationForm, resolveLocation, } from './location-field.js';
37
40
  import { PHOTO_FIELDS, photoChoices, photoRows, photoRowViews, readPhotoForm, resolvePhotos, } from './photo-field.js';
38
41
  import { BLANK_READ_OF_FORM, READ_FIELDS, readOfForm, resolveRead, submittedReadOfForm, } from './read-field.js';
39
42
  import { SYNDICATE_TO_FRONT_MATTER_KEY, syndicateToOf, syndicationTargetsReader, } from '../webmention/syndication.js';
43
+ import { citesAnImage, shownInFull } from '../webmention/cited-picture.js';
40
44
  /**
41
45
  * The Eleventy key that keeps a document out of every collection.
42
46
  *
@@ -232,6 +236,8 @@ async function saveFromForm(c, options) {
232
236
  exclude: body['exclude'] !== undefined,
233
237
  contact: body['contact'] !== undefined,
234
238
  pinned: kind.type === 'post' && body['pinned'] !== undefined,
239
+ previewHidden: kind.type === 'post' && body[PREVIEW_FRONT_MATTER_KEY] !== undefined,
240
+ citedAlt: kind.type === 'post' ? text(body[CITED_ALT_FRONT_MATTER_KEY]).trim() : '',
235
241
  comments: commentSetting(text(body['comments'])),
236
242
  enclosure: kind.type === 'post' ? readEnclosureForm(body) : BLANK_ENCLOSURE_FORM,
237
243
  photos: kind.type === 'post' ? readPhotoForm(body) : [],
@@ -248,13 +254,13 @@ async function saveFromForm(c, options) {
248
254
  // The buttons doc-5 names are shortcuts past the checkbox: Save draft and
249
255
  // Publish say what they do, and Update leaves the decision to the checkbox.
250
256
  const draft = action === 'save-draft' ? true : action === 'publish' ? false : form.draft;
251
- function refuse(message) {
257
+ function refuse(refusal) {
252
258
  return renderEditor(c, {
253
259
  kind,
254
260
  render,
255
261
  document,
256
262
  form: { ...form, draft },
257
- error: message,
263
+ refusal,
258
264
  status: 400,
259
265
  });
260
266
  }
@@ -263,9 +269,11 @@ async function saveFromForm(c, options) {
263
269
  config: c.var.config,
264
270
  announce: c.var.announce,
265
271
  writer: currentUsername(c),
272
+ citedContext: (target) => c.var.replyContexts.describe(target),
273
+ storedContext: (target) => c.var.replyContexts.read(target),
266
274
  }, { kind, document, form, draft });
267
275
  if (written.outcome === 'refused')
268
- return refuse(written.message);
276
+ return refuse(written);
269
277
  if (written.outcome === 'conflict') {
270
278
  return renderConflict(c, {
271
279
  kind,
@@ -295,52 +303,52 @@ export async function writeDocument(site, write) {
295
303
  const { store, config, writer } = site;
296
304
  const { kind, document, form, draft } = write;
297
305
  const contentDir = config.contentDir;
298
- function refused(message) {
299
- return { outcome: 'refused', message };
306
+ function refused(message, field) {
307
+ return { outcome: 'refused', message, field };
300
308
  }
301
309
  // A post with no title is a note; a page is always named.
302
310
  if (form.title === '' && kind.type === 'page') {
303
- return refused(`A ${kind.singular} needs a title.`);
311
+ return refused(`A ${kind.singular} needs a title.`, 'editor-title');
304
312
  }
305
313
  // A post is a reply only when the target is a URL (Post Type Discovery), so
306
314
  // anything else would be saved as a reply that is not one.
307
315
  if (kind.type === 'post' && form.inReplyTo !== '' && replyTarget(form) === undefined) {
308
- return refused('In reply to has to be a web address, like https://example.com/a-post/.');
316
+ return refused('In reply to has to be a web address, like https://example.com/a-post/.', 'editor-in-reply-to');
309
317
  }
310
318
  let read;
311
319
  if (kind.type === 'post') {
312
320
  for (const property of CITATION_PROPERTIES) {
313
321
  const cited = form[CITATION_FIELDS[property]];
314
322
  if (cited !== '' && !isWebUrl(cited)) {
315
- return refused(`${CITATION_LABELS[property]} has to be a web address, like https://example.com/a-post/.`);
323
+ return refused(`${CITATION_LABELS[property]} has to be a web address, like https://example.com/a-post/.`, `editor-${property}`);
316
324
  }
317
325
  }
318
326
  const resolved = resolveRead(form.readStatus, form.readOf);
319
327
  if ('error' in resolved)
320
- return refused(resolved.error);
328
+ return refused(resolved.error, resolved.field);
321
329
  read = resolved.read;
322
330
  }
323
331
  if (read !== undefined && form.description !== '') {
324
- return refused('A read is described by what it says, so it keeps no Description. Empty Description to save it.');
332
+ return refused('A read is described by what it says, so it keeps no Description. Empty Description to save it.', 'editor-description');
325
333
  }
326
334
  if (form.lang !== '' && !LANGUAGE_TAG_PATTERN.test(form.lang)) {
327
- return refused('That is not a language tag, such as en, fr or pt-BR.');
335
+ return refused('That is not a language tag, such as en, fr or pt-BR.', 'editor-lang');
328
336
  }
329
337
  let media = { recording: undefined, photos: [] };
330
338
  if (kind.type === 'post') {
331
339
  const resolved = resolveEnclosure(form.enclosure, document === undefined ? undefined : enclosureOf(document.extra), contentDir);
332
340
  if ('error' in resolved)
333
- return refused(resolved.error);
341
+ return refused(resolved.error, resolved.field);
334
342
  const photos = resolvePhotos(form.photos, contentDir);
335
343
  if ('error' in photos)
336
- return refused(photos.error);
344
+ return refused(photos.error, photos.field);
337
345
  media = { recording: resolved.enclosure, photos: photos.photos };
338
346
  }
339
347
  let location;
340
348
  if (kind.type === 'post') {
341
349
  const resolved = resolveLocation(form.location);
342
350
  if ('error' in resolved)
343
- return refused(resolved.error);
351
+ return refused(resolved.error, resolved.field);
344
352
  location = resolved.location;
345
353
  }
346
354
  // TASK-207: a pin is new when the file does not carry one yet, and only a
@@ -350,7 +358,7 @@ export async function writeDocument(site, write) {
350
358
  const author = userForAuthor(users, chosenAuthor(config.dataDir, form.author, document, writer) ?? '');
351
359
  const names = author === undefined ? [] : authorNames(users, author);
352
360
  if (store.listPinnedByAuthor(names).length >= PINNED_POST_LIMIT) {
353
- return refused(`You can pin up to ${String(PINNED_POST_LIMIT)} posts. Unpin one first.`);
361
+ return refused(`You can pin up to ${String(PINNED_POST_LIMIT)} posts. Unpin one first.`, 'editor-pinned');
354
362
  }
355
363
  }
356
364
  // TASK-141: an image nobody described is a problem to fix before readers
@@ -366,22 +374,29 @@ export async function writeDocument(site, write) {
366
374
  if (undescribed.length > 0 && config.requireAltText) {
367
375
  return refused(`This site publishes no image without alt text. ${missingAltText(undescribed)}`);
368
376
  }
377
+ if (!draft &&
378
+ config.requireAltText &&
379
+ kind.type === 'post' &&
380
+ (await citesUndescribedImage(site, document, form))) {
381
+ return refused('This site publishes no image without alt text. Describe the image this post reposts in its alt text field.', 'editor-cited-alt');
382
+ }
369
383
  const timezone = readSiteSettings(contentDir).timezone;
370
384
  // decision-11: what the file gets is a UTC instant, and an offset-less field
371
385
  // is the site's own wall clock rather than the server's.
372
386
  const typed = kind.dated ? (form.date === '' ? store.now().toISOString() : form.date) : undefined;
373
387
  if (typed !== undefined && !/^\d{4}-\d{2}-\d{2}/.test(typed)) {
374
- return refused('A date has to start with a year, a month and a day, like 2026-03-04.');
388
+ return refused('A date has to start with a year, a month and a day, like 2026-03-04.', 'editor-date');
375
389
  }
376
390
  const date = typed === undefined ? undefined : toUtcInstant(typed, timezone);
377
391
  if (typed !== undefined && date === undefined) {
378
- return refused('That date is not one anybody can read. Try 2026-03-04 09:00.');
392
+ return refused('That date is not one anybody can read. Try 2026-03-04 09:00.', 'editor-date');
379
393
  }
380
394
  const slug = slugify(form.slug) ||
381
395
  slugify(form.title) ||
382
396
  (document?.slug ?? '') ||
383
397
  noteSlug(form.body) ||
384
398
  slugify(form.readOf.name) ||
399
+ (await typeSlug(kind, form, media.photos, site.citedContext)) ||
385
400
  'untitled';
386
401
  const trashed = document !== undefined && isTrashedPath(document.path);
387
402
  // The calendar day the document is filed under: the site zone's day at its
@@ -419,7 +434,7 @@ export async function writeDocument(site, write) {
419
434
  }
420
435
  }
421
436
  if (target !== document?.path && store.getByPath(target) !== undefined) {
422
- return refused(`Another ${kind.singular} already lives in ${target}.`);
437
+ return refused(`Another ${kind.singular} already lives in ${target}.`, 'editor-slug');
423
438
  }
424
439
  const content = {
425
440
  title: form.title,
@@ -459,10 +474,15 @@ export async function writeDocument(site, write) {
459
474
  }
460
475
  if (kind.type === 'post') {
461
476
  const locations = postLocations(config.dataDir);
477
+ const kept = keptProperties(config.dataDir);
462
478
  if (document !== undefined && document.permalink !== saved.permalink) {
463
479
  await locations.move(document.permalink, saved.permalink);
480
+ await kept.move(document.permalink, saved.permalink);
464
481
  }
465
482
  await locations.set(saved.permalink, location);
483
+ if (write.keptProperties !== undefined) {
484
+ await kept.set(saved.permalink, write.keptProperties);
485
+ }
466
486
  }
467
487
  // Announced rather than left to the watcher: the index already holds what
468
488
  // was written, so the watcher's re-read is a no-op and nobody would ever
@@ -479,6 +499,19 @@ export async function writeDocument(site, write) {
479
499
  });
480
500
  return { outcome: 'saved', saved, undescribed };
481
501
  }
502
+ async function citesUndescribedImage(site, document, form) {
503
+ if (form.previewHidden || form.citedAlt !== '' || form.title !== '')
504
+ return false;
505
+ for (const property of CITATION_PROPERTIES) {
506
+ const url = form[CITATION_FIELDS[property]];
507
+ if (url === '' || !shownInFull(property, { kind: 'photo' }))
508
+ continue;
509
+ const context = document === undefined ? await site.citedContext(url) : site.storedContext(url);
510
+ if (context !== undefined && citesAnImage(context))
511
+ return true;
512
+ }
513
+ return false;
514
+ }
482
515
  /** What a save says about the images it found with no alt text, naming each. */
483
516
  function missingAltText(images) {
484
517
  const names = images.map((image) => image.name).join(', ');
@@ -493,6 +526,51 @@ function noteSlug(body) {
493
526
  const words = htmlToText(renderMarkdown(body)).split(' ').slice(0, NOTE_SLUG_WORDS);
494
527
  return slugify(words.join(' '));
495
528
  }
529
+ const TARGET_SLUG_WORDS = 4;
530
+ const CITED_SLUGS = {
531
+ repost: { prefix: 'reposted', field: 'repostOf' },
532
+ like: { prefix: 'liked', field: 'likeOf' },
533
+ reply: { prefix: 'reply-to', field: 'inReplyTo' },
534
+ bookmark: { prefix: 'bookmarked', field: 'bookmarkOf' },
535
+ };
536
+ async function typeSlug(kind, form, photos, citedContext) {
537
+ if (kind.type !== 'post')
538
+ return '';
539
+ const type = discoverPostType({
540
+ 'repost-of': form.repostOf,
541
+ 'like-of': form.likeOf,
542
+ 'in-reply-to': form.inReplyTo,
543
+ 'bookmark-of': form.bookmarkOf,
544
+ photo: photos.map((photo) => photo.url),
545
+ });
546
+ if (type === 'photo')
547
+ return 'photo';
548
+ const cited = CITED_SLUGS[type];
549
+ if (cited === undefined)
550
+ return '';
551
+ const target = form[cited.field];
552
+ const title = slugWords((await citedContext(target))?.name ?? '', NOTE_SLUG_WORDS);
553
+ return `${cited.prefix}-${title || targetWords(target)}`;
554
+ }
555
+ function targetWords(address) {
556
+ const url = new URL(address);
557
+ const segments = url.pathname.split('/').map(decodedSegment).filter(holdsALetter);
558
+ return slugWords([url.hostname.replace(/^www\./, ''), ...segments].join(' '), TARGET_SLUG_WORDS);
559
+ }
560
+ function slugWords(text, cap) {
561
+ return slugify(text).split('-').slice(0, cap).join('-');
562
+ }
563
+ function holdsALetter(segment) {
564
+ return /\p{L}/u.test(segment);
565
+ }
566
+ function decodedSegment(segment) {
567
+ try {
568
+ return decodeURIComponent(segment);
569
+ }
570
+ catch {
571
+ return segment;
572
+ }
573
+ }
496
574
  /** What the flash says after a save, which depends on what the save did. */
497
575
  function savedMessage(kind, previous, saved, now) {
498
576
  if (saved.draft)
@@ -676,6 +754,14 @@ function resolveExtra(kind, document, form, now, media, declared) {
676
754
  else
677
755
  extra[property] = cited;
678
756
  }
757
+ if (form.previewHidden)
758
+ extra[PREVIEW_FRONT_MATTER_KEY] = false;
759
+ else
760
+ delete extra[PREVIEW_FRONT_MATTER_KEY];
761
+ if (form.citedAlt === '')
762
+ delete extra[CITED_ALT_FRONT_MATTER_KEY];
763
+ else
764
+ extra[CITED_ALT_FRONT_MATTER_KEY] = form.citedAlt;
679
765
  const resolved = resolveRead(form.readStatus, form.readOf);
680
766
  if ('read' in resolved) {
681
767
  const { read } = resolved;
@@ -1053,6 +1139,8 @@ export function blankForm(kind, timezone = DEFAULT_TIMEZONE, now = new Date()) {
1053
1139
  exclude: false,
1054
1140
  contact: false,
1055
1141
  pinned: false,
1142
+ previewHidden: false,
1143
+ citedAlt: '',
1056
1144
  comments: COMMENT_SETTINGS.site,
1057
1145
  enclosure: BLANK_ENCLOSURE_FORM,
1058
1146
  photos: [],
@@ -1099,6 +1187,10 @@ export function formFor(document, timezone, location) {
1099
1187
  exclude: document.extra[EXCLUDE_KEY] === true,
1100
1188
  contact: document.extra[CONTACT_FRONT_MATTER_KEY] === true,
1101
1189
  pinned: pinnedAt(document) !== undefined,
1190
+ previewHidden: document.type === 'post' && !previewShown(document.extra),
1191
+ citedAlt: document.type === 'post' && typeof document.extra[CITED_ALT_FRONT_MATTER_KEY] === 'string'
1192
+ ? document.extra[CITED_ALT_FRONT_MATTER_KEY]
1193
+ : '',
1102
1194
  comments: commentSettingOf(document),
1103
1195
  enclosure: document.type === 'post' ? enclosureForm(document) : BLANK_ENCLOSURE_FORM,
1104
1196
  photos: document.type === 'post' ? photoRows(document) : [],
@@ -1138,6 +1230,10 @@ async function renderEditor(c, options) {
1138
1230
  actions.push({ value: 'trash', label: 'Move to trash' });
1139
1231
  if (options.status !== undefined)
1140
1232
  c.status(options.status);
1233
+ const permissions = c.var.config.securityHeaders['permissions-policy'];
1234
+ if (kind.type === 'post' && permissions !== undefined) {
1235
+ c.header('Permissions-Policy', allowGeolocation(permissions));
1236
+ }
1141
1237
  return options.render(c, ADMIN_TEMPLATES.documentEditor, {
1142
1238
  section: kind.section,
1143
1239
  // The blank form is Add new; editing one that exists is still All posts,
@@ -1158,6 +1254,7 @@ async function renderEditor(c, options) {
1158
1254
  photoRows: photoRowViews(form.photos, readAltTexts(c.var.config.contentDir)),
1159
1255
  photoChoices: await photoChoices(c.var.config.contentDir),
1160
1256
  locationFields: LOCATION_FIELDS,
1257
+ ...citedPreviews(c, form),
1161
1258
  readFields: READ_FIELDS,
1162
1259
  readStatuses: READ_STATUSES.map((value) => ({ value, label: READ_STATUS_LABELS[value] })),
1163
1260
  ...(form.readStatus === '' || isReadStatus(form.readStatus)
@@ -1187,9 +1284,41 @@ async function renderEditor(c, options) {
1187
1284
  // exactly the ambiguity decision-11 exists to remove.
1188
1285
  ...(kind.dated ? { dateZone: zoneLabel(form.date === '' ? now : form.date, timezone) } : {}),
1189
1286
  ...(scheduledAt === undefined ? {} : { scheduledFor: formatInTimezone(scheduledAt, timezone) }),
1190
- ...(options.error === undefined ? {} : { error: options.error }),
1287
+ ...(options.refusal === undefined
1288
+ ? {}
1289
+ : { error: options.refusal.message, errorField: options.refusal.field }),
1290
+ open: openGroups(form, options.refusal?.field),
1191
1291
  });
1192
1292
  }
1293
+ function citedPreviews(c, form) {
1294
+ const cited = [
1295
+ ['in-reply-to', form.inReplyTo],
1296
+ ...CITATION_PROPERTIES.map((property) => [
1297
+ property,
1298
+ form[CITATION_FIELDS[property]],
1299
+ ]),
1300
+ ];
1301
+ const cards = {};
1302
+ for (const [property, url] of cited) {
1303
+ if (url === '')
1304
+ continue;
1305
+ const context = c.var.replyContexts.read(url);
1306
+ if (context?.picture === undefined)
1307
+ continue;
1308
+ const image = citesAnImage(context);
1309
+ cards[property] = {
1310
+ name: context.name ??
1311
+ context.author?.name ??
1312
+ `${image ? 'An image from' : 'A page on'} ${citedHost(url)}`,
1313
+ picture: context.picture,
1314
+ described: image && shownInFull(property, context.picture),
1315
+ };
1316
+ }
1317
+ return {
1318
+ citedPreviews: cards,
1319
+ describesCitedImage: Object.values(cards).some((card) => card.described),
1320
+ };
1321
+ }
1193
1322
  /**
1194
1323
  * The document of this kind with this slug.
1195
1324
  *