@glw907/cairn-cms 0.60.1 → 0.62.1
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.
- package/CHANGELOG.md +69 -0
- package/dist/components/AdminLayout.svelte +22 -0
- package/dist/components/CairnAdmin.svelte +3 -0
- package/dist/components/CairnTidySettings.svelte +2 -2
- package/dist/components/CairnTidySettings.svelte.d.ts +1 -1
- package/dist/components/EditPage.svelte +116 -39
- package/dist/components/HelpHome.svelte +824 -0
- package/dist/components/HelpHome.svelte.d.ts +22 -0
- package/dist/components/MarkdownHelpDialog.svelte +4 -15
- package/dist/components/client-ingest.d.ts +16 -8
- package/dist/components/client-ingest.js +12 -6
- package/dist/components/editor-media.js +16 -8
- package/dist/components/editor-placeholder.d.ts +4 -2
- package/dist/components/editor-tidy.d.ts +24 -12
- package/dist/components/editor-tidy.js +8 -4
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +1 -0
- package/dist/components/link-completion.d.ts +12 -6
- package/dist/components/link-completion.js +12 -6
- package/dist/components/markdown-directives.d.ts +9 -6
- package/dist/components/markdown-directives.js +9 -6
- package/dist/components/markdown-format.d.ts +7 -2
- package/dist/components/markdown-format.js +59 -28
- package/dist/components/markdown-reference.d.ts +8 -0
- package/dist/components/markdown-reference.js +22 -0
- package/dist/components/media-upload-outcome.d.ts +12 -6
- package/dist/components/objective-errors.d.ts +8 -4
- package/dist/components/objective-errors.js +8 -4
- package/dist/components/preview-doc.d.ts +4 -2
- package/dist/components/preview-doc.js +4 -2
- package/dist/components/spellcheck.d.ts +55 -29
- package/dist/components/spellcheck.js +39 -21
- package/dist/components/tidy-categorize.d.ts +20 -10
- package/dist/components/tidy-categorize.js +16 -8
- package/dist/components/tidy-validate.d.ts +12 -6
- package/dist/components/tidy-validate.js +20 -10
- package/dist/components/topbar-context.d.ts +4 -2
- package/dist/content/advisories.d.ts +51 -0
- package/dist/content/advisories.js +79 -0
- package/dist/content/compose.d.ts +4 -2
- package/dist/content/compose.js +1 -0
- package/dist/content/excerpt.js +4 -2
- package/dist/content/getting-started.d.ts +18 -0
- package/dist/content/getting-started.js +12 -0
- package/dist/content/links.d.ts +16 -8
- package/dist/content/links.js +12 -6
- package/dist/content/manifest.d.ts +36 -18
- package/dist/content/manifest.js +32 -16
- package/dist/content/media-refs.d.ts +4 -2
- package/dist/content/media-refs.js +4 -2
- package/dist/content/media-rewrite.d.ts +8 -4
- package/dist/content/media-rewrite.js +76 -38
- package/dist/content/schema.d.ts +20 -10
- package/dist/content/site-dictionary.d.ts +4 -2
- package/dist/content/site-dictionary.js +8 -4
- package/dist/content/types.d.ts +97 -42
- package/dist/delivery/content-index.d.ts +16 -8
- package/dist/delivery/feeds.js +4 -2
- package/dist/delivery/json-ld.d.ts +3 -0
- package/dist/delivery/json-ld.js +3 -0
- package/dist/delivery/manifest.d.ts +4 -2
- package/dist/delivery/manifest.js +4 -2
- package/dist/delivery/public-routes.d.ts +12 -6
- package/dist/delivery/public-routes.js +4 -2
- package/dist/delivery/seo-fields.d.ts +12 -6
- package/dist/delivery/seo-fields.js +8 -4
- package/dist/delivery/site-indexes.d.ts +4 -2
- package/dist/delivery/site-resolver.d.ts +4 -2
- package/dist/delivery/site-resolver.js +4 -2
- package/dist/doctor/cloudflare-api.d.ts +6 -0
- package/dist/doctor/cloudflare-api.js +6 -0
- package/dist/doctor/index.d.ts +12 -6
- package/dist/doctor/report.d.ts +3 -0
- package/dist/doctor/report.js +3 -0
- package/dist/doctor/run.d.ts +3 -0
- package/dist/doctor/run.js +3 -0
- package/dist/doctor/types.d.ts +10 -2
- package/dist/doctor/types.js +6 -0
- package/dist/doctor/wrangler-config.d.ts +7 -2
- package/dist/doctor/wrangler-config.js +3 -0
- package/dist/email.d.ts +4 -2
- package/dist/env.d.ts +0 -3
- package/dist/env.js +0 -3
- package/dist/github/branches.d.ts +4 -2
- package/dist/github/branches.js +4 -2
- package/dist/github/signing.d.ts +1 -1
- package/dist/github/signing.js +2 -2
- package/dist/log/events.d.ts +1 -1
- package/dist/media/bulk-delete-plan.d.ts +8 -4
- package/dist/media/config.d.ts +12 -6
- package/dist/media/config.js +16 -8
- package/dist/media/delivery-bucket.d.ts +4 -2
- package/dist/media/library-entry.d.ts +4 -2
- package/dist/media/library-entry.js +4 -2
- package/dist/media/manifest.d.ts +29 -15
- package/dist/media/manifest.js +29 -16
- package/dist/media/naming.d.ts +12 -6
- package/dist/media/naming.js +24 -12
- package/dist/media/orphan-scan.d.ts +4 -2
- package/dist/media/reconcile.d.ts +21 -11
- package/dist/media/reconcile.js +12 -6
- package/dist/media/reference.d.ts +8 -4
- package/dist/media/reference.js +12 -6
- package/dist/media/rewrite-plan.d.ts +12 -6
- package/dist/media/sniff.d.ts +4 -2
- package/dist/media/sniff.js +28 -14
- package/dist/media/store.d.ts +16 -8
- package/dist/media/store.js +4 -2
- package/dist/media/transform-url.d.ts +12 -6
- package/dist/media/transform-url.js +8 -4
- package/dist/media/usage.d.ts +8 -4
- package/dist/nav/site-config.d.ts +16 -8
- package/dist/render/component-grammar.d.ts +23 -10
- package/dist/render/component-grammar.js +19 -8
- package/dist/render/component-insert.d.ts +8 -4
- package/dist/render/component-insert.js +4 -2
- package/dist/render/component-reference.d.ts +4 -2
- package/dist/render/component-reference.js +4 -2
- package/dist/render/component-validate.d.ts +3 -0
- package/dist/render/component-validate.js +3 -0
- package/dist/render/glyph.d.ts +4 -2
- package/dist/render/glyph.js +4 -2
- package/dist/render/pipeline.d.ts +20 -10
- package/dist/render/pipeline.js +4 -2
- package/dist/render/registry.d.ts +40 -20
- package/dist/render/registry.js +16 -8
- package/dist/render/rehype-dispatch.d.ts +22 -8
- package/dist/render/rehype-dispatch.js +22 -8
- package/dist/render/remark-directives.d.ts +3 -0
- package/dist/render/remark-directives.js +3 -0
- package/dist/render/remark-figure.d.ts +4 -2
- package/dist/render/remark-figure.js +4 -2
- package/dist/render/resolve-links.d.ts +4 -2
- package/dist/render/resolve-links.js +4 -2
- package/dist/render/resolve-media.d.ts +16 -8
- package/dist/render/resolve-media.js +12 -6
- package/dist/sveltekit/admin-dispatch.d.ts +2 -0
- package/dist/sveltekit/admin-dispatch.js +9 -3
- package/dist/sveltekit/auth-routes.d.ts +3 -0
- package/dist/sveltekit/auth-routes.js +3 -0
- package/dist/sveltekit/cairn-admin.d.ts +16 -5
- package/dist/sveltekit/cairn-admin.js +26 -10
- package/dist/sveltekit/content-routes.d.ts +191 -86
- package/dist/sveltekit/content-routes.js +295 -107
- package/dist/sveltekit/editors-routes.d.ts +3 -0
- package/dist/sveltekit/editors-routes.js +3 -0
- package/dist/sveltekit/guard.d.ts +4 -2
- package/dist/sveltekit/guard.js +4 -2
- package/dist/sveltekit/https-required-page.d.ts +1 -1
- package/dist/sveltekit/https-required-page.js +1 -1
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/sveltekit/media-route.d.ts +1 -2
- package/dist/sveltekit/media-route.js +13 -8
- package/dist/sveltekit/nav-routes.d.ts +7 -2
- package/dist/sveltekit/nav-routes.js +3 -0
- package/dist/sveltekit/types.d.ts +4 -2
- package/dist/vite/index.d.ts +32 -16
- package/dist/vite/index.js +52 -26
- package/dist/vite/resolve-root.d.ts +8 -4
- package/dist/vite/resolve-root.js +4 -2
- package/package.json +7 -1
- package/src/lib/components/AdminLayout.svelte +22 -0
- package/src/lib/components/CairnAdmin.svelte +3 -0
- package/src/lib/components/CairnTidySettings.svelte +2 -2
- package/src/lib/components/ComponentForm.svelte +0 -1
- package/src/lib/components/EditPage.svelte +133 -41
- package/src/lib/components/HelpHome.svelte +850 -0
- package/src/lib/components/MarkdownHelpDialog.svelte +4 -15
- package/src/lib/components/client-ingest.ts +20 -10
- package/src/lib/components/editor-media.ts +20 -10
- package/src/lib/components/editor-placeholder.ts +12 -6
- package/src/lib/components/editor-tidy.ts +28 -14
- package/src/lib/components/index.ts +1 -0
- package/src/lib/components/link-completion.ts +12 -6
- package/src/lib/components/markdown-directives.ts +13 -8
- package/src/lib/components/markdown-format.ts +63 -30
- package/src/lib/components/markdown-reference.ts +30 -0
- package/src/lib/components/media-upload-outcome.ts +12 -6
- package/src/lib/components/objective-errors.ts +16 -8
- package/src/lib/components/preview-doc.ts +4 -2
- package/src/lib/components/spellcheck.ts +79 -41
- package/src/lib/components/tidy-categorize.ts +28 -14
- package/src/lib/components/tidy-validate.ts +28 -14
- package/src/lib/components/topbar-context.ts +4 -2
- package/src/lib/content/advisories.ts +141 -0
- package/src/lib/content/compose.ts +5 -2
- package/src/lib/content/excerpt.ts +4 -2
- package/src/lib/content/getting-started.ts +31 -0
- package/src/lib/content/links.ts +16 -8
- package/src/lib/content/manifest.ts +36 -18
- package/src/lib/content/media-refs.ts +4 -2
- package/src/lib/content/media-rewrite.ts +100 -50
- package/src/lib/content/schema.ts +20 -10
- package/src/lib/content/site-dictionary.ts +8 -4
- package/src/lib/content/types.ts +97 -42
- package/src/lib/delivery/content-index.ts +16 -8
- package/src/lib/delivery/feeds.ts +4 -2
- package/src/lib/delivery/json-ld.ts +3 -0
- package/src/lib/delivery/manifest.ts +4 -2
- package/src/lib/delivery/public-routes.ts +16 -8
- package/src/lib/delivery/seo-fields.ts +12 -6
- package/src/lib/delivery/site-indexes.ts +4 -2
- package/src/lib/delivery/site-resolver.ts +4 -2
- package/src/lib/doctor/cloudflare-api.ts +6 -0
- package/src/lib/doctor/index.ts +12 -6
- package/src/lib/doctor/report.ts +3 -0
- package/src/lib/doctor/run.ts +3 -0
- package/src/lib/doctor/types.ts +10 -2
- package/src/lib/doctor/wrangler-config.ts +7 -2
- package/src/lib/email.ts +4 -2
- package/src/lib/env.ts +0 -3
- package/src/lib/github/branches.ts +4 -2
- package/src/lib/github/signing.ts +2 -2
- package/src/lib/log/events.ts +1 -0
- package/src/lib/media/bulk-delete-plan.ts +8 -4
- package/src/lib/media/config.ts +24 -12
- package/src/lib/media/delivery-bucket.ts +4 -2
- package/src/lib/media/library-entry.ts +4 -2
- package/src/lib/media/manifest.ts +33 -18
- package/src/lib/media/naming.ts +24 -12
- package/src/lib/media/orphan-scan.ts +4 -2
- package/src/lib/media/reconcile.ts +21 -11
- package/src/lib/media/reference.ts +12 -6
- package/src/lib/media/rewrite-plan.ts +12 -6
- package/src/lib/media/sniff.ts +28 -14
- package/src/lib/media/store.ts +16 -8
- package/src/lib/media/transform-url.ts +12 -6
- package/src/lib/media/usage.ts +8 -4
- package/src/lib/nav/site-config.ts +16 -8
- package/src/lib/render/component-grammar.ts +23 -10
- package/src/lib/render/component-insert.ts +8 -4
- package/src/lib/render/component-reference.ts +4 -2
- package/src/lib/render/component-validate.ts +3 -0
- package/src/lib/render/glyph.ts +4 -2
- package/src/lib/render/pipeline.ts +20 -10
- package/src/lib/render/registry.ts +44 -22
- package/src/lib/render/rehype-dispatch.ts +22 -8
- package/src/lib/render/remark-directives.ts +3 -0
- package/src/lib/render/remark-figure.ts +4 -2
- package/src/lib/render/resolve-links.ts +4 -2
- package/src/lib/render/resolve-media.ts +16 -8
- package/src/lib/sveltekit/admin-dispatch.ts +10 -4
- package/src/lib/sveltekit/auth-routes.ts +3 -0
- package/src/lib/sveltekit/cairn-admin.ts +37 -15
- package/src/lib/sveltekit/content-routes.ts +492 -197
- package/src/lib/sveltekit/editors-routes.ts +3 -0
- package/src/lib/sveltekit/guard.ts +4 -2
- package/src/lib/sveltekit/https-required-page.ts +1 -1
- package/src/lib/sveltekit/index.ts +3 -0
- package/src/lib/sveltekit/media-route.ts +13 -8
- package/src/lib/sveltekit/nav-routes.ts +7 -2
- package/src/lib/sveltekit/types.ts +4 -2
- package/src/lib/vite/index.ts +60 -30
- package/src/lib/vite/resolve-root.ts +8 -4
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { HelpData } from '../sveltekit/content-routes.js';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
data: HelpData;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* The Help home admin screen, the standing place an author comes to get their bearings and look up
|
|
7
|
+
* how things work. It renders inside `AdminLayout` (the office shell), so it carries no `data-theme`
|
|
8
|
+
* wrapper and imports no CSS: the layout owns the theme and `cairn-admin.css`, and this component
|
|
9
|
+
* consumes the Warm Stone tokens through its scoped `<style>` block.
|
|
10
|
+
*
|
|
11
|
+
* The content is one calm column: a masthead, then three co-equal eyebrow-plus-display sections.
|
|
12
|
+
*
|
|
13
|
+
* - Getting started reads `data.gettingStarted`, the count derived from the committed manifest and
|
|
14
|
+
* the open edit branches (never a stored count). At 3 of 3 the whole section is omitted, never
|
|
15
|
+
* shown as a done checklist. A per-device localStorage flag hides it on request.
|
|
16
|
+
* - Formatting renders `data.reference` (the everyday text and links rows) as a real semantic table.
|
|
17
|
+
* - Get help reads the optional `data.supportContact`. Unset is the canonical self-serve default,
|
|
18
|
+
* with no control; set renders the hand-off shaped by the contact (email, URL, or a note).
|
|
19
|
+
*/
|
|
20
|
+
declare const HelpHome: import("svelte").Component<$$ComponentProps, {}, "">;
|
|
21
|
+
type HelpHome = ReturnType<typeof HelpHome>;
|
|
22
|
+
export default HelpHome;
|
|
@@ -6,6 +6,7 @@ Built on a native <dialog>, the DeleteDialog recipe; the host drives it through
|
|
|
6
6
|
open(), so the component renders no trigger of its own.
|
|
7
7
|
-->
|
|
8
8
|
<script lang="ts">import ShortcutsGrid from "./ShortcutsGrid.svelte";
|
|
9
|
+
import { markdownReference } from "./markdown-reference.js";
|
|
9
10
|
let dialog = $state(null);
|
|
10
11
|
export function open() {
|
|
11
12
|
dialog?.showModal();
|
|
@@ -29,21 +30,9 @@ function close() {
|
|
|
29
30
|
</tr>
|
|
30
31
|
</thead>
|
|
31
32
|
<tbody>
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<tr><td><code>**bold**</code></td><td>Bold text</td></tr>
|
|
36
|
-
<tr><td><code>*italic*</code></td><td>Italic text</td></tr>
|
|
37
|
-
<tr><td><code>~~text~~</code></td><td>Crossed-out text</td></tr>
|
|
38
|
-
<tr><td><code>[text](url)</code></td><td>A link</td></tr>
|
|
39
|
-
<tr><td><code>[[page-name]]</code></td><td>A link to one of your pages</td></tr>
|
|
40
|
-
<tr><td><code>- item</code></td><td>A bulleted list</td></tr>
|
|
41
|
-
<tr><td><code>1. item</code></td><td>A numbered list</td></tr>
|
|
42
|
-
<tr><td><code>- [ ] item</code></td><td>A checklist</td></tr>
|
|
43
|
-
<tr><td><code>> quote</code></td><td>A quote</td></tr>
|
|
44
|
-
<tr><td><code>`code`</code></td><td>Code</td></tr>
|
|
45
|
-
<tr><td>Table</td><td>The Table button in the toolbar inserts one</td></tr>
|
|
46
|
-
<tr><td><code>---</code></td><td>A horizontal rule</td></tr>
|
|
33
|
+
{#each markdownReference as row (row.syntax)}
|
|
34
|
+
<tr><td><code>{row.syntax}</code></td><td>{row.makes}</td></tr>
|
|
35
|
+
{/each}
|
|
47
36
|
</tbody>
|
|
48
37
|
</table>
|
|
49
38
|
<h3 class="mt-4 mb-2 text-sm font-semibold">Keyboard shortcuts</h3>
|
|
@@ -44,11 +44,15 @@ export declare function firstImageFile(dt: {
|
|
|
44
44
|
files?: ArrayLike<File>;
|
|
45
45
|
items?: ArrayLike<DataTransferItem>;
|
|
46
46
|
}): File | null;
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
47
|
+
/**
|
|
48
|
+
* The conservative canvas area budget, about 16.7M px (4096 x 4096). A source over this is scaled
|
|
49
|
+
* down before any `drawImage`, never clipped.
|
|
50
|
+
*/
|
|
49
51
|
export declare const MAX_AREA = 16777216;
|
|
50
|
-
/**
|
|
51
|
-
*
|
|
52
|
+
/**
|
|
53
|
+
* The conservative short-side budget. A source whose smaller dimension exceeds this is scaled down so
|
|
54
|
+
* the short side lands at the cap, even when its area is within MAX_AREA.
|
|
55
|
+
*/
|
|
52
56
|
export declare const MAX_SHORT_SIDE = 4096;
|
|
53
57
|
/**
|
|
54
58
|
* The canvas budget for a source of the given dimensions. When the source area exceeds MAX_AREA or its
|
|
@@ -60,9 +64,11 @@ export declare function budgetForDimensions(width: number, height: number): {
|
|
|
60
64
|
width: number;
|
|
61
65
|
height: number;
|
|
62
66
|
};
|
|
63
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* The ingest failure taxonomy. `decode-unsupported` is a format the browser and the HEIC decoder both
|
|
64
69
|
* refuse; `transcode-failed` is a HEIC decode or a canvas re-encode that threw; `too-large` is a
|
|
65
|
-
* source still over budget after a transcode; `network` is the upload fetch rejecting.
|
|
70
|
+
* source still over budget after a transcode; `network` is the upload fetch rejecting.
|
|
71
|
+
*/
|
|
66
72
|
export type IngestFailureKind = 'decode-unsupported' | 'transcode-failed' | 'too-large' | 'network';
|
|
67
73
|
/** A failed ingest card: a stable discriminant plus a human message the capture card renders. */
|
|
68
74
|
export interface IngestFailureCard {
|
|
@@ -136,7 +142,9 @@ export declare function ingestFailureKind(error: unknown): IngestFailureKind;
|
|
|
136
142
|
* `fetch`.
|
|
137
143
|
*/
|
|
138
144
|
export declare function sendUpload(url: string, init: RequestInit): Promise<Response>;
|
|
139
|
-
/**
|
|
140
|
-
*
|
|
145
|
+
/**
|
|
146
|
+
* Guard a drop target: cancel the browser's default open-the-file behavior on `dragover` and `drop`
|
|
147
|
+
* so a dropped image stays inside the editor rather than navigating the page to the file.
|
|
148
|
+
*/
|
|
141
149
|
export declare function guardDropTarget(event: DragEvent): void;
|
|
142
150
|
export {};
|
|
@@ -109,11 +109,15 @@ export function normalizeDataTransfer(dt) {
|
|
|
109
109
|
export function firstImageFile(dt) {
|
|
110
110
|
return normalizeDataTransfer(dt)[0] ?? null;
|
|
111
111
|
}
|
|
112
|
-
/**
|
|
113
|
-
*
|
|
112
|
+
/**
|
|
113
|
+
* The conservative canvas area budget, about 16.7M px (4096 x 4096). A source over this is scaled
|
|
114
|
+
* down before any `drawImage`, never clipped.
|
|
115
|
+
*/
|
|
114
116
|
export const MAX_AREA = 16_777_216;
|
|
115
|
-
/**
|
|
116
|
-
*
|
|
117
|
+
/**
|
|
118
|
+
* The conservative short-side budget. A source whose smaller dimension exceeds this is scaled down so
|
|
119
|
+
* the short side lands at the cap, even when its area is within MAX_AREA.
|
|
120
|
+
*/
|
|
117
121
|
export const MAX_SHORT_SIDE = 4096;
|
|
118
122
|
/**
|
|
119
123
|
* The canvas budget for a source of the given dimensions. When the source area exceeds MAX_AREA or its
|
|
@@ -290,8 +294,10 @@ export async function sendUpload(url, init) {
|
|
|
290
294
|
throw new IngestError('network');
|
|
291
295
|
}
|
|
292
296
|
}
|
|
293
|
-
/**
|
|
294
|
-
*
|
|
297
|
+
/**
|
|
298
|
+
* Guard a drop target: cancel the browser's default open-the-file behavior on `dragover` and `drop`
|
|
299
|
+
* so a dropped image stays inside the editor rather than navigating the page to the file.
|
|
300
|
+
*/
|
|
295
301
|
export function guardDropTarget(event) {
|
|
296
302
|
event.preventDefault();
|
|
297
303
|
}
|
|
@@ -103,8 +103,10 @@ class MediaChipWidget extends WidgetType {
|
|
|
103
103
|
return false;
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
-
/**
|
|
107
|
-
*
|
|
106
|
+
/**
|
|
107
|
+
* Scan one line's text for media image tokens, mapping each to its document offsets and resolving its
|
|
108
|
+
* library entry. lineFrom is the line's document start, so the match offsets become absolute.
|
|
109
|
+
*/
|
|
108
110
|
function matchesInLine(text, lineFrom, library) {
|
|
109
111
|
const out = [];
|
|
110
112
|
MEDIA_IMAGE.lastIndex = 0;
|
|
@@ -133,10 +135,12 @@ function matchesInLine(text, lineFrom, library) {
|
|
|
133
135
|
}
|
|
134
136
|
return out;
|
|
135
137
|
}
|
|
136
|
-
/**
|
|
138
|
+
/**
|
|
139
|
+
* Every media image match across the editor's visible ranges, in document order, each carrying its
|
|
137
140
|
* enclosing figure role. One {@link fenceScan} over the whole document feeds the cheap per-token
|
|
138
141
|
* figure detection (no remark parse on the per-rebuild chip path); the visible lines are scanned
|
|
139
|
-
* for tokens, then each token's line index drives {@link figureRoleAtLine}.
|
|
142
|
+
* for tokens, then each token's line index drives {@link figureRoleAtLine}.
|
|
143
|
+
*/
|
|
140
144
|
function visibleMatches(view, library) {
|
|
141
145
|
const lines = view.state.doc.toString().split('\n');
|
|
142
146
|
const scan = fenceScan(lines);
|
|
@@ -153,8 +157,10 @@ function visibleMatches(view, library) {
|
|
|
153
157
|
}
|
|
154
158
|
return out;
|
|
155
159
|
}
|
|
156
|
-
/**
|
|
157
|
-
*
|
|
160
|
+
/**
|
|
161
|
+
* Replace decorations for each visible media image's reference token: the chip widget over the URL
|
|
162
|
+
* token, the alt left untouched. The same spans seed the atomic-range set.
|
|
163
|
+
*/
|
|
158
164
|
function buildMediaDecorations(view, library) {
|
|
159
165
|
const builder = new RangeSetBuilder();
|
|
160
166
|
for (const match of visibleMatches(view, library)) {
|
|
@@ -162,9 +168,11 @@ function buildMediaDecorations(view, library) {
|
|
|
162
168
|
}
|
|
163
169
|
return builder.finish();
|
|
164
170
|
}
|
|
165
|
-
/**
|
|
171
|
+
/**
|
|
172
|
+
* The atomic ranges for the visible media reference tokens: a caret or selection edit treats each
|
|
166
173
|
* token as one unit, so a stray keystroke replaces the whole reference rather than corrupting a hex
|
|
167
|
-
* digit. Built from the same matches the decorations use, so the two never disagree.
|
|
174
|
+
* digit. Built from the same matches the decorations use, so the two never disagree.
|
|
175
|
+
*/
|
|
168
176
|
function buildAtomicRanges(view, library) {
|
|
169
177
|
const ranges = [];
|
|
170
178
|
for (const match of visibleMatches(view, library)) {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { EditorView } from '@codemirror/view';
|
|
2
2
|
import { type Extension } from '@codemirror/state';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* The seam the host drives: begin lands a placeholder and returns its id; progress moves its bar;
|
|
4
5
|
* resolveTo swaps it for the committed image text; cancel removes it leaving the source untouched.
|
|
5
|
-
* Mirrors the register-callback idiom MarkdownEditor uses for its other editor ops.
|
|
6
|
+
* Mirrors the register-callback idiom MarkdownEditor uses for its other editor ops.
|
|
7
|
+
*/
|
|
6
8
|
export interface ImagePlaceholderApi {
|
|
7
9
|
/** Land an optimistic placeholder at the current caret from a local object URL; returns its id. */
|
|
8
10
|
begin(objectUrl: string): number;
|
|
@@ -1,31 +1,43 @@
|
|
|
1
1
|
import { EditorView } from '@codemirror/view';
|
|
2
2
|
import { type Extension } from '@codemirror/state';
|
|
3
3
|
import type { Change } from './tidy-diff.js';
|
|
4
|
-
/**
|
|
4
|
+
/**
|
|
5
|
+
* The api the host drives over one editor view (spec 2.5). Mirrors imagePlaceholderApi: the host
|
|
5
6
|
* registers it through registerTidy, and the review surface calls it as the author works the list.
|
|
6
|
-
* Every accept lands as a CodeMirror transaction; reject and reject-all write no text.
|
|
7
|
+
* Every accept lands as a CodeMirror transaction; reject and reject-all write no text.
|
|
8
|
+
*/
|
|
7
9
|
export interface TidyApi {
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
+
/**
|
|
11
|
+
* Open tidy with the validated change set: seed the field, show the decorations. The buffer is
|
|
12
|
+
* untouched; the originals stay until an accept writes.
|
|
13
|
+
*/
|
|
10
14
|
enter(changes: Change[]): void;
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
15
|
+
/**
|
|
16
|
+
* Accept one change: dispatch its replacement over its current span in one transaction and mark it
|
|
17
|
+
* accepted. The other pending changes map across the edit.
|
|
18
|
+
*/
|
|
13
19
|
acceptOne(index: number): void;
|
|
14
20
|
/** Reject one change: mark it rejected so its decorations clear, leaving the original untouched. */
|
|
15
21
|
rejectOne(index: number): void;
|
|
16
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Accept many changes (the bulk action) in ONE transaction: the whole edit is one undoable step.
|
|
17
24
|
* The caller passes ONLY the indexes it has decided to keep; this never sweeps an index the caller
|
|
18
|
-
* did not name, which is how Accept-fixes confines itself to objective hunks.
|
|
25
|
+
* did not name, which is how Accept-fixes confines itself to objective hunks.
|
|
26
|
+
*/
|
|
19
27
|
acceptMany(indexes: number[]): void;
|
|
20
28
|
/** Reject every remaining pending change, leaving the document byte-identical. */
|
|
21
29
|
rejectAll(): void;
|
|
22
30
|
/** Close tidy: clear the field and the decorations. The buffer holds whatever the accepts wrote. */
|
|
23
31
|
exit(): void;
|
|
24
32
|
}
|
|
25
|
-
/**
|
|
33
|
+
/**
|
|
34
|
+
* The tidy extension: the StateField holding the change set and its decorations. The host adds it to
|
|
26
35
|
* the initial editor state (in its own compartment beside media and folding), then builds the driving
|
|
27
|
-
* api with tidyApi once the view exists.
|
|
36
|
+
* api with tidyApi once the view exists.
|
|
37
|
+
*/
|
|
28
38
|
export declare function cairnTidy(): Extension;
|
|
29
|
-
/**
|
|
30
|
-
*
|
|
39
|
+
/**
|
|
40
|
+
* Build the api that drives tidy against one editor view. The host registers it through registerTidy;
|
|
41
|
+
* the review surface calls enter, the per-hunk and bulk accept/reject, and exit.
|
|
42
|
+
*/
|
|
31
43
|
export declare function tidyApi(view: EditorView): TidyApi;
|
|
@@ -152,14 +152,18 @@ const tidyField = StateField.define({
|
|
|
152
152
|
},
|
|
153
153
|
provide: (f) => EditorView.decorations.from(f, (v) => buildDecorations(v)),
|
|
154
154
|
});
|
|
155
|
-
/**
|
|
155
|
+
/**
|
|
156
|
+
* The tidy extension: the StateField holding the change set and its decorations. The host adds it to
|
|
156
157
|
* the initial editor state (in its own compartment beside media and folding), then builds the driving
|
|
157
|
-
* api with tidyApi once the view exists.
|
|
158
|
+
* api with tidyApi once the view exists.
|
|
159
|
+
*/
|
|
158
160
|
export function cairnTidy() {
|
|
159
161
|
return tidyField;
|
|
160
162
|
}
|
|
161
|
-
/**
|
|
162
|
-
*
|
|
163
|
+
/**
|
|
164
|
+
* Build the api that drives tidy against one editor view. The host registers it through registerTidy;
|
|
165
|
+
* the review surface calls enter, the per-hunk and bulk accept/reject, and exit.
|
|
166
|
+
*/
|
|
163
167
|
export function tidyApi(view) {
|
|
164
168
|
// Dispatch the named changes' replacements over their CURRENT mapped spans in one transaction, mark
|
|
165
169
|
// them accepted, and let the field map any remaining pending entries. The changes are read from the
|
|
@@ -6,6 +6,7 @@ export { default as CsrfField } from './CsrfField.svelte';
|
|
|
6
6
|
export { default as ConceptList } from './ConceptList.svelte';
|
|
7
7
|
export { default as CairnMediaLibrary } from './CairnMediaLibrary.svelte';
|
|
8
8
|
export { default as CairnTidySettings } from './CairnTidySettings.svelte';
|
|
9
|
+
export { default as HelpHome } from './HelpHome.svelte';
|
|
9
10
|
export { default as EditPage } from './EditPage.svelte';
|
|
10
11
|
export { default as ManageEditors } from './ManageEditors.svelte';
|
|
11
12
|
export { default as MarkdownEditor } from './MarkdownEditor.svelte';
|
package/dist/components/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export { default as CsrfField } from './CsrfField.svelte';
|
|
|
8
8
|
export { default as ConceptList } from './ConceptList.svelte';
|
|
9
9
|
export { default as CairnMediaLibrary } from './CairnMediaLibrary.svelte';
|
|
10
10
|
export { default as CairnTidySettings } from './CairnTidySettings.svelte';
|
|
11
|
+
export { default as HelpHome } from './HelpHome.svelte';
|
|
11
12
|
export { default as EditPage } from './EditPage.svelte';
|
|
12
13
|
export { default as ManageEditors } from './ManageEditors.svelte';
|
|
13
14
|
export { default as MarkdownEditor } from './MarkdownEditor.svelte';
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import type { Completion, CompletionSource } from '@codemirror/autocomplete';
|
|
2
2
|
import type { LinkTarget } from '../content/manifest.js';
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
3
|
+
/**
|
|
4
|
+
* The open `[[query` before the cursor, or null. The query stops at a closing bracket or a newline,
|
|
5
|
+
* so a finished `[[x]]` link and ordinary prose never trigger. `from` is the index of the `[[`.
|
|
6
|
+
*/
|
|
5
7
|
export declare function matchCairnTrigger(before: string): {
|
|
6
8
|
query: string;
|
|
7
9
|
from: number;
|
|
8
10
|
} | null;
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
+
/**
|
|
12
|
+
* The completion options for a query: a case-insensitive title substring match, each option grouped
|
|
13
|
+
* by concept, a draft marked and a post date shown in the detail, and the apply text the full link.
|
|
14
|
+
*/
|
|
11
15
|
export declare function linkCompletions(targets: LinkTarget[], query: string): Completion[];
|
|
12
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* A CodeMirror CompletionSource over the site's link targets, triggered by `[[`. It replaces the
|
|
13
18
|
* whole `[[query` with the chosen link, and sets filter:false because linkCompletions already
|
|
14
|
-
* filtered by the query (CodeMirror would otherwise re-filter against the literal `[[query`).
|
|
19
|
+
* filtered by the query (CodeMirror would otherwise re-filter against the literal `[[query`).
|
|
20
|
+
*/
|
|
15
21
|
export declare function cairnLinkCompletionSource(targets: LinkTarget[]): CompletionSource;
|
|
@@ -11,14 +11,18 @@ const CONCEPT_SECTIONS = {
|
|
|
11
11
|
function sectionFor(concept) {
|
|
12
12
|
return CONCEPT_SECTIONS[concept] ?? { name: concept.charAt(0).toUpperCase() + concept.slice(1), rank: 2 };
|
|
13
13
|
}
|
|
14
|
-
/**
|
|
15
|
-
*
|
|
14
|
+
/**
|
|
15
|
+
* The open `[[query` before the cursor, or null. The query stops at a closing bracket or a newline,
|
|
16
|
+
* so a finished `[[x]]` link and ordinary prose never trigger. `from` is the index of the `[[`.
|
|
17
|
+
*/
|
|
16
18
|
export function matchCairnTrigger(before) {
|
|
17
19
|
const match = /\[\[([^[\]\n]*)$/.exec(before);
|
|
18
20
|
return match ? { query: match[1], from: match.index } : null;
|
|
19
21
|
}
|
|
20
|
-
/**
|
|
21
|
-
*
|
|
22
|
+
/**
|
|
23
|
+
* The completion options for a query: a case-insensitive title substring match, each option grouped
|
|
24
|
+
* by concept, a draft marked and a post date shown in the detail, and the apply text the full link.
|
|
25
|
+
*/
|
|
22
26
|
export function linkCompletions(targets, query) {
|
|
23
27
|
const q = query.trim().toLowerCase();
|
|
24
28
|
const matched = q ? targets.filter((t) => t.title.toLowerCase().includes(q)) : targets;
|
|
@@ -29,9 +33,11 @@ export function linkCompletions(targets, query) {
|
|
|
29
33
|
apply: `[${escapeLinkText(t.title)}](${formatCairnToken(t)})`,
|
|
30
34
|
}));
|
|
31
35
|
}
|
|
32
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* A CodeMirror CompletionSource over the site's link targets, triggered by `[[`. It replaces the
|
|
33
38
|
* whole `[[query` with the chosen link, and sets filter:false because linkCompletions already
|
|
34
|
-
* filtered by the query (CodeMirror would otherwise re-filter against the literal `[[query`).
|
|
39
|
+
* filtered by the query (CodeMirror would otherwise re-filter against the literal `[[query`).
|
|
40
|
+
*/
|
|
35
41
|
export function cairnLinkCompletionSource(targets) {
|
|
36
42
|
return async (context) => {
|
|
37
43
|
const line = context.state.doc.lineAt(context.pos);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The directive name from a container opener line (`:::callout{...}`
|
|
3
|
-
* `::::cta[Book]`
|
|
2
|
+
* The directive name from a container opener line (`:::callout{...}` gives `callout`,
|
|
3
|
+
* `::::cta[Book]` gives `cta`), or null when the line is not a named container opener. Reads the
|
|
4
4
|
* same FENCE match the scan uses: group 2 is the name, empty on a bare closer, so a closer or a
|
|
5
5
|
* non-fence line returns null.
|
|
6
6
|
*/
|
|
@@ -11,9 +11,11 @@ export declare function directiveLineKind(line: string): 'fence' | 'leaf' | null
|
|
|
11
11
|
export interface FenceScan {
|
|
12
12
|
/** The 1-based container depth per line, or null outside any container. */
|
|
13
13
|
depths: (number | null)[];
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Whether a line opened or closed a container, or null for everything else. A fence-shaped
|
|
15
16
|
* line the code-block tracking disowned is null too, so the role array is the one source of
|
|
16
|
-
* truth for pairing and no caller re-parses a line the scan already judged.
|
|
17
|
+
* truth for pairing and no caller re-parses a line the scan already judged.
|
|
18
|
+
*/
|
|
17
19
|
roles: ('opener' | 'closer' | null)[];
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
@@ -56,7 +58,8 @@ export declare function caretContainerRange(scan: FenceScan, caretLine: number):
|
|
|
56
58
|
* example can neither open nor close a range. This is the sole source of fold ranges.
|
|
57
59
|
*/
|
|
58
60
|
export declare function containerRanges(scan: FenceScan): ContainerRange[];
|
|
59
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* The figure placement role for a media token sitting on `lineIndex`, derived from the editor's
|
|
60
63
|
* line scan without a remark parse (the chip rebuild runs on every doc and viewport change).
|
|
61
64
|
*
|
|
62
65
|
* Returns the closed-set role (`center`/`wide`/`full`) when the innermost container holding the
|
|
@@ -76,7 +79,7 @@ export interface FenceToken {
|
|
|
76
79
|
}
|
|
77
80
|
/**
|
|
78
81
|
* Split a fence line into machinery and meaning. The colon run, the label's brackets, and the
|
|
79
|
-
* whole {attrs} group are machinery; the directive name and the label text are meaning, the
|
|
82
|
+
* whole `{attrs}` group are machinery; the directive name and the label text are meaning, the
|
|
80
83
|
* parts an editor reads. A bare closer is a single machinery span, and a non-fence line yields
|
|
81
84
|
* no spans at all.
|
|
82
85
|
*/
|
|
@@ -15,8 +15,8 @@ const INLINE = /(?<![:\w]):[\w-]+\[[^\]]*\](\{[^}]*\})?/g;
|
|
|
15
15
|
// never opens a real container.
|
|
16
16
|
const CODE_FENCE = /^\s{0,3}(`{3,}|~{3,})/;
|
|
17
17
|
/**
|
|
18
|
-
* The directive name from a container opener line (`:::callout{...}`
|
|
19
|
-
* `::::cta[Book]`
|
|
18
|
+
* The directive name from a container opener line (`:::callout{...}` gives `callout`,
|
|
19
|
+
* `::::cta[Book]` gives `cta`), or null when the line is not a named container opener. Reads the
|
|
20
20
|
* same FENCE match the scan uses: group 2 is the name, empty on a bare closer, so a closer or a
|
|
21
21
|
* non-fence line returns null.
|
|
22
22
|
*/
|
|
@@ -145,8 +145,10 @@ export function containerRanges(scan) {
|
|
|
145
145
|
}
|
|
146
146
|
return out;
|
|
147
147
|
}
|
|
148
|
-
/**
|
|
149
|
-
*
|
|
148
|
+
/**
|
|
149
|
+
* The closed placement-role set for the reserved `figure` directive, mirroring remark-figure.ts.
|
|
150
|
+
* A class outside this set is the measure default, never passed through as a role.
|
|
151
|
+
*/
|
|
150
152
|
const FIGURE_ROLES = new Set(['center', 'wide', 'full']);
|
|
151
153
|
// The directive `{attrs}` brace, and the `.class` shorthands inside it. mdast-util-directive folds
|
|
152
154
|
// every `.class` into a space-joined node.attributes.class, and remark-figure honors a role only when
|
|
@@ -156,7 +158,8 @@ const FIGURE_ROLES = new Set(['center', 'wide', 'full']);
|
|
|
156
158
|
const ATTR_BRACE = /\{([^}]*)\}/;
|
|
157
159
|
const CLASS_SHORTHAND = /\.([\w-]+)/g;
|
|
158
160
|
const CLASS_ATTR = /class\s*=\s*"([^"]*)"/;
|
|
159
|
-
/**
|
|
161
|
+
/**
|
|
162
|
+
* The figure placement role for a media token sitting on `lineIndex`, derived from the editor's
|
|
160
163
|
* line scan without a remark parse (the chip rebuild runs on every doc and viewport change).
|
|
161
164
|
*
|
|
162
165
|
* Returns the closed-set role (`center`/`wide`/`full`) when the innermost container holding the
|
|
@@ -189,7 +192,7 @@ export function figureRoleAtLine(scan, lines, lineIndex) {
|
|
|
189
192
|
}
|
|
190
193
|
/**
|
|
191
194
|
* Split a fence line into machinery and meaning. The colon run, the label's brackets, and the
|
|
192
|
-
* whole {attrs} group are machinery; the directive name and the label text are meaning, the
|
|
195
|
+
* whole `{attrs}` group are machinery; the directive name and the label text are meaning, the
|
|
193
196
|
* parts an editor reads. A bare closer is a single machinery span, and a non-fence line yields
|
|
194
197
|
* no spans at all.
|
|
195
198
|
*/
|
|
@@ -4,6 +4,9 @@ export interface FormatResult {
|
|
|
4
4
|
from: number;
|
|
5
5
|
to: number;
|
|
6
6
|
}
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
7
10
|
export declare function applyMarkdownFormat(doc: string, from: number, to: number, kind: FormatKind): FormatResult;
|
|
8
11
|
/**
|
|
9
12
|
* Insert an inline markdown link at the selection. With a non-empty selection the selected text
|
|
@@ -50,8 +53,10 @@ export declare function findMediaImagesNeedingAlt(doc: string): MediaImageNeedin
|
|
|
50
53
|
* is left in place.
|
|
51
54
|
*/
|
|
52
55
|
export declare function unwrapCairnLink(doc: string, href: string): string;
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
56
|
+
/**
|
|
57
|
+
* The closed placement role set the figure render step honors. A role outside it is the measure
|
|
58
|
+
* default (null), so the control never writes one. Mirrors the set in render/remark-figure.ts.
|
|
59
|
+
*/
|
|
55
60
|
export type FigureRole = 'center' | 'wide' | 'full';
|
|
56
61
|
/**
|
|
57
62
|
* The media image at a caret, with the enclosing `:::figure` block when there is one. `imageFrom`
|