@aicayzer/inkkit 0.0.8 → 0.0.10
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/README.md +5 -3
- package/dist/callouts.js +2 -1
- package/dist/clipboard.d.ts +3 -3
- package/dist/clipboard.js +64 -25
- package/dist/dialect.d.ts +1 -1
- package/dist/dialect.js +36 -2
- package/dist/editor.d.ts +27 -1
- package/dist/editor.js +478 -35
- package/dist/files.d.ts +40 -0
- package/dist/files.js +133 -0
- package/dist/images.d.ts +20 -4
- package/dist/images.js +242 -25
- package/dist/index.d.ts +1 -1
- package/dist/labels.d.ts +8 -0
- package/dist/labels.js +8 -0
- package/dist/linked-syntax.d.ts +48 -0
- package/dist/linked-syntax.js +308 -0
- package/dist/literals.js +40 -1
- package/dist/portable-files.d.ts +10 -0
- package/dist/portable-files.js +36 -0
- package/dist/preserve.js +7 -0
- package/dist/print.d.ts +2 -2
- package/dist/print.js +49 -17
- package/dist/search.d.ts +2 -1
- package/dist/search.js +53 -22
- package/dist/source.d.ts +0 -1
- package/dist/source.js +0 -60
- package/dist/style.css +39 -0
- package/dist/text-ranges.d.ts +26 -0
- package/dist/text-ranges.js +233 -0
- package/dist/types.d.ts +84 -2
- package/dist/wiki-view.d.ts +21 -0
- package/dist/wiki-view.js +78 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
InkKit is a reusable Markdown editor for simple writing tools and richer document apps. It provides formatted editing, source preservation, portable clipboard content and optional host-managed images, while your app controls its appearance, files and interface.
|
|
4
4
|
|
|
5
|
-
Write in formatted or source mode with shared undo/redo. Edit tables, task lists, footnotes, reference links, highlights and callouts. Preview bounded Mermaid diagrams offline. Copy readable text and semantic HTML, explicitly copy Markdown source, or capture a complete printable document. Unsupported syntax remains editable literal Markdown.
|
|
5
|
+
Write in formatted or source mode with shared undo/redo. Edit tables, task lists, footnotes, reference links, highlights and callouts. Preview bounded Mermaid diagrams offline. Copy readable text and semantic HTML, explicitly copy Markdown source, or capture a complete printable document. Native hosts can use scoped readable-text ranges and demand-driven geometry with their own search controls and viewport insets. Unsupported syntax remains editable literal Markdown.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Host controls, read-only and text-input policies, command availability, scoped appearance, labels and shortcuts are available from 0.0.8. Check the [releases](https://github.com/aicayzer/inkkit/releases) for published versions and verification evidence.
|
|
8
8
|
|
|
9
9
|
```sh
|
|
10
10
|
npm install @aicayzer/inkkit
|
|
@@ -43,6 +43,8 @@ InkKit runs on the web and in offline web views. Hosts use its public TypeScript
|
|
|
43
43
|
|
|
44
44
|
Start with the [feature guide](docs/supported-syntax.md) and [simple and rich integration examples](docs/integration.md). The [documentation index](docs/README.md) links to precise API, preservation, playground, verification and publication guidance.
|
|
45
45
|
|
|
46
|
-
Scope and release status live in the [InkKit Project](https://github.com/users/aicayzer/projects/3) and [version milestones](https://github.com/aicayzer/inkkit/milestones).
|
|
46
|
+
Scope and release status live in the [InkKit Project](https://github.com/users/aicayzer/projects/3) and [version milestones](https://github.com/aicayzer/inkkit/milestones). Optional media extensions are tracked there. Only documented, released features form the supported package contract.
|
|
47
47
|
|
|
48
48
|
MIT licensed. InkKit builds on the public PadPad and Memos editors; see [NOTICE](NOTICE).
|
|
49
|
+
|
|
50
|
+
Optional wiki links and a host-owned asynchronous file adapter support named/path images, audio, video, PDFs and file cards. Authored source and sizing are preserved; portable copy/print uses validated images or documented descriptive fallbacks. See [linked syntax](docs/supported-syntax.md#linked-syntax) and [adapter contracts](docs/api.md#optional-wiki-links-and-files).
|
package/dist/callouts.js
CHANGED
|
@@ -243,7 +243,7 @@ export const calloutView = $prose((ctx) => new Plugin({
|
|
|
243
243
|
key: new PluginKey('inkkitCalloutView'),
|
|
244
244
|
props: {
|
|
245
245
|
nodeViews: {
|
|
246
|
-
inkkit_callout(node) {
|
|
246
|
+
inkkit_callout(node, view) {
|
|
247
247
|
const dom = document.createElement('blockquote');
|
|
248
248
|
dom.className = 'inkkit-callout';
|
|
249
249
|
dom.setAttribute('data-inkkit-callout', String(node.attrs.kind));
|
|
@@ -265,6 +265,7 @@ export const calloutView = $prose((ctx) => new Plugin({
|
|
|
265
265
|
.toLowerCase()
|
|
266
266
|
.replace(/^./, (letter) => letter.toUpperCase());
|
|
267
267
|
dom.setAttribute('data-inkkit-folded', String(folded));
|
|
268
|
+
view.dom.dispatchEvent(new Event('inkkit-media-policy'));
|
|
268
269
|
button.hidden = !node.attrs.fold;
|
|
269
270
|
button.setAttribute('aria-expanded', String(!folded));
|
|
270
271
|
button.setAttribute('aria-label', `${folded ? editorLabels(ctx).expandCallout : editorLabels(ctx).collapseCallout} ${title.textContent}`);
|
package/dist/clipboard.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type Fragment, type Schema } from '@milkdown/kit/prose/model';
|
|
2
|
-
import type { ClipboardOutput, DocumentContext, ImageAdapter } from './types.js';
|
|
2
|
+
import type { ClipboardOutput, DocumentContext, ImageAdapter, FileAdapter } from './types.js';
|
|
3
3
|
export interface ClipboardContent {
|
|
4
4
|
text: string;
|
|
5
5
|
html: string;
|
|
6
6
|
}
|
|
7
|
-
export declare function clipboardText(content: Fragment, missingImages?: ReadonlySet<string>): string;
|
|
7
|
+
export declare function clipboardText(content: Fragment, missingImages?: ReadonlySet<string>, fileDescriptions?: ReadonlyMap<object, string>): string;
|
|
8
8
|
export declare function clipboardContent(content: Fragment, schema: Schema): ClipboardContent;
|
|
9
9
|
export declare const visibleClipboard: import("@milkdown/kit/utils").$Prose;
|
|
10
10
|
/** Export a frozen document fragment; presentation URLs never enter the clipboard. */
|
|
11
|
-
export declare function portableClipboard(content: Fragment, schema: Schema, markdown: string, adapter: ImageAdapter | undefined, context: DocumentContext, completeDiagrams?: ReadonlySet<string
|
|
11
|
+
export declare function portableClipboard(content: Fragment, schema: Schema, markdown: string, adapter: ImageAdapter | undefined, context: DocumentContext, completeDiagrams?: ReadonlySet<string>, files?: FileAdapter, signal?: AbortSignal): Promise<ClipboardOutput>;
|
package/dist/clipboard.js
CHANGED
|
@@ -3,30 +3,35 @@ import { Plugin, PluginKey } from '@milkdown/kit/prose/state';
|
|
|
3
3
|
import { $prose } from '@milkdown/kit/utils';
|
|
4
4
|
import { shareableFragment } from './comments.js';
|
|
5
5
|
import { diagramImage } from './mermaid.js';
|
|
6
|
+
import { fileReference } from './linked-syntax.js';
|
|
7
|
+
import { portableFile, portableFileImage } from './portable-files.js';
|
|
8
|
+
import { withFileSignal } from './files.js';
|
|
6
9
|
// Clipboard text is the visible document, not Markdown serialization: escaping
|
|
7
10
|
// punctuation or trailing spaces here leaks source syntax into other apps.
|
|
8
|
-
export function clipboardText(content, missingImages = new Set()) {
|
|
11
|
+
export function clipboardText(content, missingImages = new Set(), fileDescriptions = new Map()) {
|
|
9
12
|
content = shareableFragment(content);
|
|
10
13
|
const blocks = [];
|
|
11
14
|
content.forEach((node) => {
|
|
12
15
|
if (node.type.name !== 'reference_definition')
|
|
13
|
-
blocks.push(nodeText(node, missingImages));
|
|
16
|
+
blocks.push(nodeText(node, missingImages, fileDescriptions));
|
|
14
17
|
});
|
|
15
18
|
const inline = content.firstChild?.isInline ?? false;
|
|
16
19
|
return blocks.join(inline ? '' : '\n\n');
|
|
17
20
|
}
|
|
18
|
-
function nodeText(node, missingImages) {
|
|
21
|
+
function nodeText(node, missingImages, fileDescriptions) {
|
|
22
|
+
if (node.type.name === 'inkkit_wiki_link')
|
|
23
|
+
return String(node.attrs.label || node.attrs.target || 'Link');
|
|
19
24
|
if (node.type.name === 'inkkit_callout')
|
|
20
25
|
return `${node.attrs.title ||
|
|
21
26
|
String(node.attrs.kind)
|
|
22
27
|
.toLowerCase()
|
|
23
|
-
.replace(/^./, (letter) => letter.toUpperCase())}\n${clipboardText(node.content, missingImages)}`;
|
|
28
|
+
.replace(/^./, (letter) => letter.toUpperCase())}\n${clipboardText(node.content, missingImages, fileDescriptions)}`;
|
|
24
29
|
if (node.type.name === 'reference_definition')
|
|
25
30
|
return '';
|
|
26
31
|
if (node.type.name === 'footnote_reference')
|
|
27
32
|
return `[${node.attrs.label}]`;
|
|
28
33
|
if (node.type.name === 'footnote_definition')
|
|
29
|
-
return `[${node.attrs.label}] ${clipboardText(node.content, missingImages)}`;
|
|
34
|
+
return `[${node.attrs.label}] ${clipboardText(node.content, missingImages, fileDescriptions)}`;
|
|
30
35
|
if (node.isText)
|
|
31
36
|
return node.text ?? '';
|
|
32
37
|
if (node.type.name === 'hardbreak' || node.type.name === 'hard_break')
|
|
@@ -42,7 +47,7 @@ function nodeText(node, missingImages) {
|
|
|
42
47
|
const indent = ' '.repeat(marker.length);
|
|
43
48
|
const blocks = [];
|
|
44
49
|
item.forEach((child, _childOffset, childIndex) => {
|
|
45
|
-
const text = nodeText(child, missingImages);
|
|
50
|
+
const text = nodeText(child, missingImages, fileDescriptions);
|
|
46
51
|
const nestedList = child.type.name === 'bullet_list' ||
|
|
47
52
|
child.type.name === 'ordered_list';
|
|
48
53
|
const lines = text.split('\n');
|
|
@@ -58,7 +63,10 @@ function nodeText(node, missingImages) {
|
|
|
58
63
|
return items.join('\n');
|
|
59
64
|
}
|
|
60
65
|
if (node.type.name === 'image') {
|
|
61
|
-
const
|
|
66
|
+
const description = fileDescriptions.get(node.attrs);
|
|
67
|
+
if (description != null)
|
|
68
|
+
return description;
|
|
69
|
+
const alt = fileReference(node).label || 'Image';
|
|
62
70
|
return missingImages.has(String(node.attrs.src ?? ''))
|
|
63
71
|
? `[${alt}: image unavailable]`
|
|
64
72
|
: alt;
|
|
@@ -67,12 +75,12 @@ function nodeText(node, missingImages) {
|
|
|
67
75
|
const rows = [];
|
|
68
76
|
node.forEach((row) => {
|
|
69
77
|
const cells = [];
|
|
70
|
-
row.forEach((cell) => cells.push(clipboardText(cell.content, missingImages)));
|
|
78
|
+
row.forEach((cell) => cells.push(clipboardText(cell.content, missingImages, fileDescriptions)));
|
|
71
79
|
rows.push(cells.join('\t'));
|
|
72
80
|
});
|
|
73
81
|
return rows.join('\n');
|
|
74
82
|
}
|
|
75
|
-
return clipboardText(node.content, missingImages);
|
|
83
|
+
return clipboardText(node.content, missingImages, fileDescriptions);
|
|
76
84
|
}
|
|
77
85
|
export function clipboardContent(content, schema) {
|
|
78
86
|
content = shareableFragment(content);
|
|
@@ -82,6 +90,10 @@ export function clipboardContent(content, schema) {
|
|
|
82
90
|
// fetches authored references or temporary presentation URLs.
|
|
83
91
|
const safe = new DOMSerializer({
|
|
84
92
|
...serializer.nodes,
|
|
93
|
+
inkkit_wiki_link: (node) => [
|
|
94
|
+
'span',
|
|
95
|
+
String(node.attrs.label || node.attrs.target || 'Link'),
|
|
96
|
+
],
|
|
85
97
|
image: (node) => [
|
|
86
98
|
'img',
|
|
87
99
|
{
|
|
@@ -111,31 +123,53 @@ export const visibleClipboard = $prose(() => new Plugin({
|
|
|
111
123
|
},
|
|
112
124
|
}));
|
|
113
125
|
/** Export a frozen document fragment; presentation URLs never enter the clipboard. */
|
|
114
|
-
export async function portableClipboard(content, schema, markdown, adapter, context, completeDiagrams) {
|
|
126
|
+
export async function portableClipboard(content, schema, markdown, adapter, context, completeDiagrams, files, signal = new AbortController().signal) {
|
|
127
|
+
signal.throwIfAborted();
|
|
115
128
|
content = shareableFragment(content);
|
|
116
129
|
const base = clipboardContent(content, schema);
|
|
117
130
|
const container = document.createElement('div');
|
|
118
131
|
container.innerHTML = base.html;
|
|
119
132
|
const images = [];
|
|
120
133
|
const references = [];
|
|
134
|
+
const fileDescriptions = new Map();
|
|
121
135
|
content.descendants((node) => {
|
|
122
136
|
if (node.type.name === 'image')
|
|
123
|
-
references.push(
|
|
137
|
+
references.push(node);
|
|
124
138
|
});
|
|
125
139
|
const captured = [...container.querySelectorAll('img')].map((element, index) => {
|
|
126
|
-
const
|
|
127
|
-
const
|
|
140
|
+
const node = references[index];
|
|
141
|
+
const reference = String(node?.attrs.src ?? '');
|
|
142
|
+
const { label: authoredAlt, width } = fileReference(node);
|
|
143
|
+
const alt = authoredAlt || 'Image';
|
|
144
|
+
if (width != null && width > 0)
|
|
145
|
+
element.setAttribute('width', String(Math.min(4096, width)));
|
|
128
146
|
element.removeAttribute('src');
|
|
129
147
|
element.removeAttribute('srcset');
|
|
130
|
-
return { element, reference, alt };
|
|
148
|
+
return { element, node, reference, alt };
|
|
131
149
|
});
|
|
132
|
-
await Promise.all(captured.map(async ({ element, reference, alt }, index) => {
|
|
150
|
+
await Promise.all(captured.map(async ({ element, node, reference, alt }, index) => {
|
|
151
|
+
let label = alt;
|
|
133
152
|
element.setAttribute('data-inkkit-image-slot', String(index));
|
|
134
153
|
element.setAttribute('data-inkkit-authored-image-slot', String(index));
|
|
135
154
|
try {
|
|
136
|
-
|
|
155
|
+
const file = files
|
|
156
|
+
? await portableFile(node, files, context, signal)
|
|
157
|
+
: undefined;
|
|
158
|
+
if (file && file.presentation.kind !== 'image') {
|
|
159
|
+
const fallback = document.createElement('span');
|
|
160
|
+
fallback.textContent = file.description;
|
|
161
|
+
element.replaceWith(fallback);
|
|
162
|
+
fileDescriptions.set(node.attrs, file.description);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
label = file?.label || alt;
|
|
166
|
+
if (!files && !adapter)
|
|
137
167
|
throw new Error('The image is unavailable.');
|
|
138
|
-
const
|
|
168
|
+
const input = file
|
|
169
|
+
? await portableFileImage(file, files, adapter, context, signal)
|
|
170
|
+
: await withFileSignal(adapter.exportImage(reference, { ...context }), signal);
|
|
171
|
+
signal.throwIfAborted();
|
|
172
|
+
const image = { ...input, bytes: new Uint8Array(input.bytes) };
|
|
139
173
|
if (!/^image\/(png|jpeg|gif|webp|avif|bmp|tiff)$/i.test(image.mimeType))
|
|
140
174
|
throw new Error('The image format cannot be exported.');
|
|
141
175
|
let binary = '';
|
|
@@ -143,15 +177,18 @@ export async function portableClipboard(content, schema, markdown, adapter, cont
|
|
|
143
177
|
binary += String.fromCharCode(byte);
|
|
144
178
|
const portable = `data:${image.mimeType};base64,${btoa(binary)}`;
|
|
145
179
|
element.setAttribute('src', portable);
|
|
146
|
-
element.setAttribute('alt',
|
|
147
|
-
|
|
180
|
+
element.setAttribute('alt', label);
|
|
181
|
+
fileDescriptions.set(node.attrs, label);
|
|
182
|
+
images[index] = { reference, alt: label, image };
|
|
148
183
|
}
|
|
149
184
|
catch (error) {
|
|
185
|
+
signal.throwIfAborted();
|
|
150
186
|
const message = error instanceof Error ? error.message : 'The image is unavailable.';
|
|
151
187
|
const warning = document.createElement('span');
|
|
152
|
-
warning.textContent = `[${
|
|
188
|
+
warning.textContent = `[${label}: image unavailable]`;
|
|
153
189
|
element.replaceWith(warning);
|
|
154
|
-
|
|
190
|
+
fileDescriptions.set(node.attrs, warning.textContent);
|
|
191
|
+
images[index] = { reference, alt: label, error: message };
|
|
155
192
|
}
|
|
156
193
|
}));
|
|
157
194
|
const diagrams = [];
|
|
@@ -162,7 +199,7 @@ export async function portableClipboard(content, schema, markdown, adapter, cont
|
|
|
162
199
|
const result = { source };
|
|
163
200
|
diagrams.push(result);
|
|
164
201
|
try {
|
|
165
|
-
const image = await diagramImage(source);
|
|
202
|
+
const image = await withFileSignal(diagramImage(source), signal);
|
|
166
203
|
let binary = '';
|
|
167
204
|
for (const byte of image.bytes)
|
|
168
205
|
binary += String.fromCharCode(byte);
|
|
@@ -179,6 +216,7 @@ export async function portableClipboard(content, schema, markdown, adapter, cont
|
|
|
179
216
|
result.image = image;
|
|
180
217
|
}
|
|
181
218
|
catch (error) {
|
|
219
|
+
signal.throwIfAborted();
|
|
182
220
|
result.error =
|
|
183
221
|
error instanceof Error
|
|
184
222
|
? error.message
|
|
@@ -211,12 +249,13 @@ export async function portableClipboard(content, schema, markdown, adapter, cont
|
|
|
211
249
|
/^javascript:/i.test(attribute.value)))
|
|
212
250
|
element.removeAttribute(attribute.name);
|
|
213
251
|
}
|
|
214
|
-
const missing = new Set(images.filter((image) => image
|
|
252
|
+
const missing = new Set(images.filter((image) => image?.error).map((image) => image.reference));
|
|
253
|
+
signal.throwIfAborted();
|
|
215
254
|
return {
|
|
216
|
-
text: clipboardText(content, missing),
|
|
255
|
+
text: clipboardText(content, missing, fileDescriptions),
|
|
217
256
|
html: container.innerHTML,
|
|
218
257
|
markdown,
|
|
219
|
-
images: [...orderedImages, ...images.filter((image) => image
|
|
258
|
+
images: [...orderedImages, ...images.filter((image) => image?.error)],
|
|
220
259
|
diagrams,
|
|
221
260
|
};
|
|
222
261
|
}
|
package/dist/dialect.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Node as ProseNode } from '@milkdown/kit/prose/model';
|
|
|
3
3
|
import { type Options as StringifyOptions } from 'mdast-util-to-markdown';
|
|
4
4
|
export declare const remarkDialectPlugin: import("@milkdown/kit/utils").$Remark<"remarkDialect", unknown>;
|
|
5
5
|
export declare const tables: MilkdownPlugin[];
|
|
6
|
-
export declare function createDialect(images: boolean): MilkdownPlugin[];
|
|
6
|
+
export declare function createDialect(images: boolean, wikiLinks?: boolean, files?: boolean): MilkdownPlugin[];
|
|
7
7
|
export declare const dialect: MilkdownPlugin[];
|
|
8
8
|
export declare const stringifyOptions: StringifyOptions;
|
|
9
9
|
export declare function serialize(ctx: Ctx, doc?: ProseNode): string;
|
package/dist/dialect.js
CHANGED
|
@@ -4,6 +4,7 @@ import { extendListItemSchemaForTask, strikethroughAttr, strikethroughInputRule,
|
|
|
4
4
|
import { $node, $remark } from '@milkdown/kit/utils';
|
|
5
5
|
import { autolinkInputRule } from './autolink.js';
|
|
6
6
|
import { sourceAttribute } from './source.js';
|
|
7
|
+
import { linkedSyntax, wikiLinkSchema, namedFileMarkdown, fileReference, } from './linked-syntax.js';
|
|
7
8
|
import { normalizeTableAlignment, normalizeTableColumnAlignment, } from './table-alignment.js';
|
|
8
9
|
import { preservingCodeBlocks, remarkCodeFences, fencedCodeHandler, } from './code-fences.js';
|
|
9
10
|
import { literalBlock, createLiteralPreservation } from './literals.js';
|
|
@@ -178,6 +179,14 @@ const normalizedImages = imageSchema.extendSchema((base) => (ctx) => {
|
|
|
178
179
|
const schema = base(ctx);
|
|
179
180
|
return {
|
|
180
181
|
...schema,
|
|
182
|
+
attrs: {
|
|
183
|
+
...schema.attrs,
|
|
184
|
+
inkkitFileRaw: { default: null },
|
|
185
|
+
inkkitFileTarget: { default: null },
|
|
186
|
+
inkkitFileFragment: { default: null },
|
|
187
|
+
inkkitFileWidth: { default: null },
|
|
188
|
+
inkkitFileInTable: { default: false },
|
|
189
|
+
},
|
|
181
190
|
parseDOM: [
|
|
182
191
|
{
|
|
183
192
|
tag: 'img[src]',
|
|
@@ -197,6 +206,29 @@ const normalizedImages = imageSchema.extendSchema((base) => (ctx) => {
|
|
|
197
206
|
src: String(node.url ?? ''),
|
|
198
207
|
alt: String(node.alt ?? ''),
|
|
199
208
|
title: String(node.title ?? ''),
|
|
209
|
+
inkkitFileRaw: node.inkkitFileRaw ?? null,
|
|
210
|
+
inkkitFileTarget: node.inkkitFileTarget ?? null,
|
|
211
|
+
inkkitFileFragment: node.inkkitFileFragment ?? null,
|
|
212
|
+
inkkitFileWidth: node.inkkitFileWidth ?? null,
|
|
213
|
+
inkkitFileInTable: node.inkkitFileInTable ?? false,
|
|
214
|
+
});
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
toMarkdown: {
|
|
218
|
+
...schema.toMarkdown,
|
|
219
|
+
runner(state, node) {
|
|
220
|
+
const raw = namedFileMarkdown(node, Boolean(node.attrs.inkkitFileInTable));
|
|
221
|
+
if (raw == null)
|
|
222
|
+
return schema.toMarkdown.runner(state, node);
|
|
223
|
+
state.addNode('image', undefined, undefined, {
|
|
224
|
+
url: node.attrs.src,
|
|
225
|
+
alt: node.attrs.alt,
|
|
226
|
+
title: node.attrs.title || null,
|
|
227
|
+
inkkitFileRaw: raw,
|
|
228
|
+
inkkitFileTarget: node.attrs.inkkitFileTarget,
|
|
229
|
+
inkkitFileFragment: node.attrs.inkkitFileFragment,
|
|
230
|
+
inkkitFileWidth: fileReference(node).width ?? null,
|
|
231
|
+
inkkitFileInTable: node.attrs.inkkitFileInTable,
|
|
200
232
|
});
|
|
201
233
|
},
|
|
202
234
|
},
|
|
@@ -266,14 +298,15 @@ export const tables = [
|
|
|
266
298
|
setAlignCommand,
|
|
267
299
|
exitTable,
|
|
268
300
|
].flat();
|
|
269
|
-
export function createDialect(images) {
|
|
301
|
+
export function createDialect(images, wikiLinks = false, files = false) {
|
|
270
302
|
return [
|
|
271
303
|
remarkCodeFences,
|
|
272
304
|
remarkReferencesPlugin,
|
|
273
305
|
remarkCalloutsPlugin,
|
|
274
306
|
remarkCommentsPlugin,
|
|
307
|
+
wikiLinks || files ? linkedSyntax(wikiLinks, files) : [],
|
|
275
308
|
// Protect unsupported inline HTML before the empty-line plugin consumes break nodes.
|
|
276
|
-
createLiteralPreservation(images),
|
|
309
|
+
createLiteralPreservation(images || files),
|
|
277
310
|
commonmarkWithLiteralReferences,
|
|
278
311
|
$node('doc', () => ({
|
|
279
312
|
...docSchema.schema,
|
|
@@ -283,6 +316,7 @@ export function createDialect(images) {
|
|
|
283
316
|
},
|
|
284
317
|
})),
|
|
285
318
|
references,
|
|
319
|
+
wikiLinks ? wikiLinkSchema : [],
|
|
286
320
|
callouts,
|
|
287
321
|
comments,
|
|
288
322
|
inlineHighlight,
|
package/dist/editor.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type EditorLabels } from './labels.js';
|
|
2
2
|
import { type TableCommand, type TableOptions } from './tables.js';
|
|
3
|
-
import { type DocumentInput, type DocumentSnapshot, type ImageAdapter, type ClipboardInput, type ClipboardOutput, type PrintableDocument } from './types.js';
|
|
3
|
+
import { type DocumentInput, type DocumentSnapshot, type ImageAdapter, type FileAdapter, type WikiLinkAdapter, type ClipboardInput, type ClipboardOutput, type PrintableDocument, type TextRange, type ReadableTextSnapshot, type TextRect, type ViewportOptions, type ViewportSnapshot } from './types.js';
|
|
4
4
|
import { type Heading } from './outline.js';
|
|
5
5
|
export type Mark = 'bold' | 'italic' | 'strikethrough' | 'highlight' | 'code' | 'link';
|
|
6
6
|
export type Block = {
|
|
@@ -34,6 +34,8 @@ export interface TextInputPreferences {
|
|
|
34
34
|
}
|
|
35
35
|
export interface EditorOptions {
|
|
36
36
|
images?: ImageAdapter;
|
|
37
|
+
files?: FileAdapter;
|
|
38
|
+
wikiLinks?: WikiLinkAdapter;
|
|
37
39
|
editable?: boolean;
|
|
38
40
|
textInput?: TextInputPreferences;
|
|
39
41
|
labels?: Partial<EditorLabels>;
|
|
@@ -89,6 +91,7 @@ export declare class InkKitEditor {
|
|
|
89
91
|
private revision;
|
|
90
92
|
private documentEpoch;
|
|
91
93
|
private operationSequence;
|
|
94
|
+
private exportControllers;
|
|
92
95
|
private plainComposing;
|
|
93
96
|
private plainSearch;
|
|
94
97
|
private literalMatch?;
|
|
@@ -110,6 +113,10 @@ export declare class InkKitEditor {
|
|
|
110
113
|
private generation;
|
|
111
114
|
private reportingSuppressed;
|
|
112
115
|
private loading;
|
|
116
|
+
private readonly textIdentity;
|
|
117
|
+
private textScope?;
|
|
118
|
+
private viewportContainer?;
|
|
119
|
+
private viewportInsets;
|
|
113
120
|
private writable;
|
|
114
121
|
private inputPreferences;
|
|
115
122
|
private policyEpoch;
|
|
@@ -120,6 +127,9 @@ export declare class InkKitEditor {
|
|
|
120
127
|
private keys;
|
|
121
128
|
private constructor();
|
|
122
129
|
private context;
|
|
130
|
+
private cancelExports;
|
|
131
|
+
private exportContent;
|
|
132
|
+
private mediaPolicy;
|
|
123
133
|
private assertAlive;
|
|
124
134
|
private assertCurrent;
|
|
125
135
|
private assertMutation;
|
|
@@ -155,6 +165,22 @@ export declare class InkKitEditor {
|
|
|
155
165
|
static mount(root: HTMLElement, events: EditorEvents, options?: EditorOptions): Promise<InkKitEditor>;
|
|
156
166
|
loadDocument(input: DocumentInput): void;
|
|
157
167
|
reloadDocument(input: DocumentInput): void;
|
|
168
|
+
setViewport(options: ViewportOptions): void;
|
|
169
|
+
viewport(): ViewportSnapshot;
|
|
170
|
+
private readableScope;
|
|
171
|
+
textSnapshot(expectedGeneration?: number): ReadableTextSnapshot;
|
|
172
|
+
private validateTextRange;
|
|
173
|
+
selectTextRange(range: TextRange, options?: {
|
|
174
|
+
focus?: boolean;
|
|
175
|
+
reveal?: boolean;
|
|
176
|
+
}): void;
|
|
177
|
+
replaceTextRange(range: TextRange, text: string): boolean;
|
|
178
|
+
textRangeRects(range: TextRange): readonly TextRect[];
|
|
179
|
+
visibleTextRanges(snapshotId: string): readonly TextRange[];
|
|
180
|
+
revealTextRange(range: TextRange): void;
|
|
181
|
+
private revealRects;
|
|
182
|
+
private revealCurrentSelection;
|
|
183
|
+
private revealLiteralSelection;
|
|
158
184
|
private load;
|
|
159
185
|
find(text: string, expectedGeneration?: number): void;
|
|
160
186
|
replace(search: string, replacement: string, expectedGeneration?: number): boolean;
|