@aicayzer/inkkit 0.0.18 → 0.1.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.
Files changed (90) hide show
  1. package/NOTICE +4 -2
  2. package/README.md +11 -7
  3. package/dist/THIRD-PARTY-NOTICES.txt +2742 -0
  4. package/dist/chunks/core-CYp5ONPO.js +56519 -0
  5. package/dist/chunks/highlight-BW9W8PtS.js +14122 -0
  6. package/dist/core.d.ts +2 -5
  7. package/dist/core.js +2 -2
  8. package/dist/editor.d.ts +229 -47
  9. package/dist/index.js +5 -3
  10. package/dist/style.css +231 -202
  11. package/dist/types.d.ts +143 -18
  12. package/package.json +16 -13
  13. package/dist/autolink.d.ts +0 -1
  14. package/dist/autolink.js +0 -18
  15. package/dist/callouts.d.ts +0 -25
  16. package/dist/callouts.js +0 -288
  17. package/dist/clipboard.d.ts +0 -11
  18. package/dist/clipboard.js +0 -261
  19. package/dist/code-fences.d.ts +0 -8
  20. package/dist/code-fences.js +0 -171
  21. package/dist/comments.d.ts +0 -76
  22. package/dist/comments.js +0 -545
  23. package/dist/cursor.d.ts +0 -2
  24. package/dist/cursor.js +0 -40
  25. package/dist/decorations.d.ts +0 -2
  26. package/dist/decorations.js +0 -67
  27. package/dist/dialect.d.ts +0 -9
  28. package/dist/dialect.js +0 -446
  29. package/dist/drop-placement.d.ts +0 -19
  30. package/dist/drop-placement.js +0 -47
  31. package/dist/editor.js +0 -2673
  32. package/dist/files.d.ts +0 -40
  33. package/dist/files.js +0 -133
  34. package/dist/highlight.d.ts +0 -1
  35. package/dist/highlight.js +0 -136
  36. package/dist/html-import.d.ts +0 -13
  37. package/dist/html-import.js +0 -477
  38. package/dist/image-blocks.d.ts +0 -86
  39. package/dist/image-blocks.js +0 -329
  40. package/dist/images.d.ts +0 -51
  41. package/dist/images.js +0 -398
  42. package/dist/inline-highlight.d.ts +0 -6
  43. package/dist/inline-highlight.js +0 -112
  44. package/dist/labels.d.ts +0 -36
  45. package/dist/labels.js +0 -34
  46. package/dist/link-safety.d.ts +0 -17
  47. package/dist/link-safety.js +0 -29
  48. package/dist/linked-syntax.d.ts +0 -48
  49. package/dist/linked-syntax.js +0 -320
  50. package/dist/literals.d.ts +0 -20
  51. package/dist/literals.js +0 -216
  52. package/dist/mermaid.d.ts +0 -28
  53. package/dist/mermaid.js +0 -404
  54. package/dist/outline.d.ts +0 -22
  55. package/dist/outline.js +0 -79
  56. package/dist/paste-html.d.ts +0 -31
  57. package/dist/paste-html.js +0 -462
  58. package/dist/paste.d.ts +0 -33
  59. package/dist/paste.js +0 -591
  60. package/dist/portable-files.d.ts +0 -10
  61. package/dist/portable-files.js +0 -36
  62. package/dist/preserve.d.ts +0 -38
  63. package/dist/preserve.js +0 -1396
  64. package/dist/print.d.ts +0 -7
  65. package/dist/print.js +0 -406
  66. package/dist/reference-clipboard.d.ts +0 -8
  67. package/dist/reference-clipboard.js +0 -201
  68. package/dist/references.d.ts +0 -16
  69. package/dist/references.js +0 -418
  70. package/dist/scroll.d.ts +0 -15
  71. package/dist/scroll.js +0 -27
  72. package/dist/search.d.ts +0 -15
  73. package/dist/search.js +0 -202
  74. package/dist/selection.d.ts +0 -1
  75. package/dist/selection.js +0 -59
  76. package/dist/source.d.ts +0 -16
  77. package/dist/source.js +0 -57
  78. package/dist/spreadsheet.d.ts +0 -8
  79. package/dist/spreadsheet.js +0 -289
  80. package/dist/table-alignment.d.ts +0 -2
  81. package/dist/table-alignment.js +0 -46
  82. package/dist/tables.d.ts +0 -27
  83. package/dist/tables.js +0 -344
  84. package/dist/tasks.d.ts +0 -3
  85. package/dist/tasks.js +0 -51
  86. package/dist/text-ranges.d.ts +0 -29
  87. package/dist/text-ranges.js +0 -256
  88. package/dist/types.js +0 -8
  89. package/dist/wiki-view.d.ts +0 -21
  90. package/dist/wiki-view.js +0 -78
package/dist/dialect.js DELETED
@@ -1,446 +0,0 @@
1
- import { editorViewCtx, serializerCtx } from '@milkdown/kit/core';
2
- import { commonmark, docSchema, hardbreakSchema, imageSchema, paragraphSchema, remarkInlineLinkPlugin, } from '@milkdown/kit/preset/commonmark';
3
- import { extendListItemSchemaForTask, strikethroughAttr, strikethroughInputRule, strikethroughKeymap, strikethroughSchema, toggleStrikethroughCommand, wrapInTaskListInputRule, tableSchema, tableHeaderRowSchema, tableHeaderSchema, tableRowSchema, tableCellSchema, tableEditingPlugin, tableKeymap, goToNextTableCellCommand, goToPrevTableCellCommand, insertTableCommand, addRowBeforeCommand, addRowAfterCommand, addColBeforeCommand, addColAfterCommand, selectRowCommand, selectColCommand, deleteSelectedCellsCommand, setAlignCommand, exitTable, } from '@milkdown/kit/preset/gfm';
4
- import { $node, $prose, $remark } from '@milkdown/kit/utils';
5
- import { keymap } from '@milkdown/kit/prose/keymap';
6
- import { autolinkInputRule } from './autolink.js';
7
- import { isScriptAddress } from './link-safety.js';
8
- import { sourceAttribute } from './source.js';
9
- import { linkedSyntax, wikiLinkSchema, namedFileMarkdown, fileReference, } from './linked-syntax.js';
10
- import { normalizeTableAlignment, normalizeTableColumnAlignment, } from './table-alignment.js';
11
- import { preservingCodeBlocks, remarkCodeFences, fencedCodeHandler, } from './code-fences.js';
12
- import { literalBlock, createLiteralPreservation } from './literals.js';
13
- import { imageAttrs, imageBlockName, imageBlocks, markdownImageAttrs, readParagraph, } from './image-blocks.js';
14
- import { references, remarkReferencesPlugin } from './references.js';
15
- import { callouts, remarkCalloutsPlugin } from './callouts.js';
16
- import { inlineHighlight } from './inline-highlight.js';
17
- import { comments, remarkCommentsPlugin } from './comments.js';
18
- import { gfmTableFromMarkdown, gfmTableToMarkdown } from 'mdast-util-gfm-table';
19
- import { gfmTable } from 'micromark-extension-gfm-table';
20
- import { defaultHandlers, } from 'mdast-util-to-markdown';
21
- import { gfmAutolinkLiteralFromMarkdown, gfmAutolinkLiteralToMarkdown, } from 'mdast-util-gfm-autolink-literal';
22
- import { gfmStrikethroughFromMarkdown, gfmStrikethroughToMarkdown, } from 'mdast-util-gfm-strikethrough';
23
- import { gfmTaskListItemFromMarkdown, gfmTaskListItemToMarkdown, } from 'mdast-util-gfm-task-list-item';
24
- import { gfmAutolinkLiteral } from 'micromark-extension-gfm-autolink-literal';
25
- import { gfmStrikethrough } from 'micromark-extension-gfm-strikethrough';
26
- import { gfmTaskListItem } from 'micromark-extension-gfm-task-list-item';
27
- const bareURL = /^https?:\/\/[^\s<>]+$/;
28
- // The literal form stops at these, so a URL ending in one would come back shorter than it went out.
29
- const endsInPunctuation = /[.,;:!?]$/;
30
- // What may sit against a bare URL without the reader running the two together.
31
- const beforeURL = /(^|[\s([*_~])$/;
32
- const afterURL = /^([\s.,;:!?)\]}<]|$)/;
33
- function balanced(url) {
34
- let open = 0;
35
- for (const character of url) {
36
- if (character === '(')
37
- open += 1;
38
- else if (character === ')')
39
- open -= 1;
40
- if (open < 0)
41
- return false;
42
- }
43
- return open === 0;
44
- }
45
- function textAt(parent, node, offset) {
46
- const children = parent?.children;
47
- const index = children?.indexOf(node) ?? -1;
48
- return index < 0 ? undefined : children?.[index + offset];
49
- }
50
- /** A link whose text is its own URL is written as the bare URL, the way it was typed. Only where reading
51
- * it back gives the same link again: nothing may run into it at either end. */
52
- function writesBare(node, parent, inCell) {
53
- const [child, ...rest] = node.children;
54
- if (node.title ||
55
- rest.length > 0 ||
56
- child?.type !== 'text' ||
57
- child.value !== node.url)
58
- return false;
59
- if (!bareURL.test(node.url) ||
60
- endsInPunctuation.test(node.url) ||
61
- !balanced(node.url))
62
- return false;
63
- const before = textAt(parent, node, -1);
64
- if (before && (before.type !== 'text' || !beforeURL.test(before.value)))
65
- return false;
66
- const after = textAt(parent, node, 1);
67
- if (after && (after.type !== 'text' || !afterURL.test(after.value)))
68
- return false;
69
- // Spaces that end a cell are written as character references, which a bare URL would run into.
70
- return !(inCell &&
71
- after?.type === 'text' &&
72
- /^[ \t]+$/.test(after.value) &&
73
- parent?.children.at(-1) === after);
74
- }
75
- const link = (node, parent, state, info) => writesBare(node, parent, state.stack.includes('tableCell'))
76
- ? node.url
77
- : defaultHandlers.link(node, parent, state, info);
78
- link.peek = (node, parent, state) => writesBare(node, parent, state.stack.includes('tableCell'))
79
- ? node.url[0]
80
- : defaultHandlers.link.peek(node, parent, state);
81
- function remarkDialect() {
82
- const data = this.data();
83
- const add = (key, value) => {
84
- const list = (data[key] ??= []);
85
- list.push(value);
86
- };
87
- add('micromarkExtensions', gfmStrikethrough());
88
- add('micromarkExtensions', gfmTaskListItem());
89
- add('micromarkExtensions', gfmAutolinkLiteral());
90
- add('micromarkExtensions', gfmTable());
91
- add('fromMarkdownExtensions', gfmStrikethroughFromMarkdown());
92
- add('fromMarkdownExtensions', gfmTaskListItemFromMarkdown());
93
- add('fromMarkdownExtensions', gfmAutolinkLiteralFromMarkdown());
94
- add('fromMarkdownExtensions', gfmTableFromMarkdown());
95
- add('toMarkdownExtensions', gfmStrikethroughToMarkdown());
96
- add('toMarkdownExtensions', gfmTaskListItemToMarkdown());
97
- add('toMarkdownExtensions', gfmAutolinkLiteralToMarkdown());
98
- add('toMarkdownExtensions', gfmTableToMarkdown());
99
- add('toMarkdownExtensions', {
100
- handlers: {
101
- text(node, parent, state, info) {
102
- const value = defaultHandlers.text(node, parent, state, info);
103
- // GFM trims spaces and tabs at the edges of a cell on reopening, so
104
- // only the start of its first node and the end of its last need
105
- // encoding. Inside a mark or link, delimiters stand before the pipe.
106
- if (!state.stack.includes('tableCell') ||
107
- (parent?.type !== 'paragraph' && parent?.type !== 'tableCell'))
108
- return value;
109
- const siblings = parent.children;
110
- const encode = (spaces) => spaces.replaceAll(' ', '&#x20;').replaceAll('\t', '&#x9;');
111
- return value
112
- .replace(/^[ \t]+/, (spaces) => siblings[0] === node ? encode(spaces) : spaces)
113
- .replace(/[ \t]+$/, (spaces) => siblings.at(-1) === node ? encode(spaces) : spaces);
114
- },
115
- thematicBreak(node, parent, state) {
116
- const value = defaultHandlers.thematicBreak(node, parent, state);
117
- // A document opening with `---` reads back as front matter when
118
- // another `---` line follows.
119
- return parent?.type === 'root' &&
120
- parent.children.length > 1 &&
121
- parent.children[0] === node
122
- ? value.replaceAll('-', '*')
123
- : value;
124
- },
125
- },
126
- });
127
- add('toMarkdownExtensions', { handlers: { link, code: fencedCodeHandler } });
128
- return padShortRows;
129
- }
130
- // GFM reads a row with fewer cells than its header as ending in empty cells.
131
- // The editor holds them from the start; otherwise table editing adds them
132
- // after the first edit, and again after every Undo.
133
- function padShortRows(node) {
134
- if (node.type === 'table') {
135
- const width = node.children[0]?.children.length ?? 0;
136
- for (const row of node.children)
137
- while (row.children.length < width)
138
- row.children.push({ type: 'tableCell', children: [] });
139
- }
140
- if ('children' in node)
141
- node.children.forEach(padShortRows);
142
- }
143
- export const remarkDialectPlugin = $remark('remarkDialect', () => remarkDialect);
144
- // Reference links retain their authored form instead of expanding to inline links.
145
- const commonmarkWithLiteralReferences = commonmark.filter((plugin) => !remarkInlineLinkPlugin.includes(plugin));
146
- // The preset drops the final empty paragraph, which makes trailing spacers shrink on each reload.
147
- const preserveSpacerParagraphs = paragraphSchema.extendSchema((base) => (ctx) => {
148
- const schema = base(ctx);
149
- return {
150
- ...schema,
151
- parseMarkdown: {
152
- ...schema.parseMarkdown,
153
- runner(state, node, type) {
154
- readParagraph(state, node, type);
155
- },
156
- },
157
- toMarkdown: {
158
- ...schema.toMarkdown,
159
- runner(state, node) {
160
- if (node.lastChild?.type.name === 'hardbreak') {
161
- state.openNode('paragraph');
162
- state.next(node.content.cut(0, node.content.size - node.lastChild.nodeSize));
163
- state.addNode('html', undefined, '<br />');
164
- state.closeNode();
165
- return;
166
- }
167
- if (node.content.size > 0)
168
- return schema.toMarkdown.runner(state, node);
169
- state.openNode('paragraph');
170
- state.addNode('html', undefined, '<br />');
171
- state.closeNode();
172
- },
173
- },
174
- };
175
- });
176
- // Soft Markdown breaks still serialize as a single newline. Display the actual
177
- // line boundary rather than a space, so changing editor mode never joins lines.
178
- const visibleSoftbreaks = hardbreakSchema.extendSchema((base) => (ctx) => {
179
- const schema = base(ctx);
180
- return {
181
- ...schema,
182
- attrs: { ...schema.attrs, isHTML: { default: false } },
183
- parseDOM: [
184
- {
185
- tag: 'br[data-type="softbreak"]',
186
- getAttrs: () => ({ isInline: true }),
187
- },
188
- {
189
- tag: 'br[data-type="hardbreak"]',
190
- getAttrs: () => ({ isInline: false }),
191
- },
192
- { tag: 'br', getAttrs: () => ({ isInline: false, isHTML: true }) },
193
- ],
194
- parseMarkdown: {
195
- ...schema.parseMarkdown,
196
- runner(state, node, type) {
197
- if (node.data
198
- ?.inkkitHTMLBreak)
199
- state.addNode(type, { isInline: false, isHTML: true });
200
- else
201
- schema.parseMarkdown.runner(state, node, type);
202
- },
203
- },
204
- toMarkdown: {
205
- ...schema.toMarkdown,
206
- runner(state, node) {
207
- if (node.attrs.isHTML)
208
- state.addNode('html', undefined, '<br />');
209
- else
210
- schema.toMarkdown.runner(state, node);
211
- },
212
- },
213
- toDOM: (node) => node.attrs.isInline
214
- ? ['br', { 'data-type': 'softbreak' }]
215
- : [
216
- 'br',
217
- { 'data-type': node.attrs.isHTML ? 'htmlbreak' : 'hardbreak' },
218
- ],
219
- };
220
- });
221
- const normalizedImages = imageSchema.extendSchema((base) => (ctx) => {
222
- const schema = base(ctx);
223
- return {
224
- ...schema,
225
- attrs: imageAttrs,
226
- parseDOM: [
227
- {
228
- tag: 'img[src]',
229
- getAttrs(dom) {
230
- const src = dom.getAttribute('src') ?? '';
231
- if (isScriptAddress(src))
232
- return false;
233
- return {
234
- src,
235
- alt: dom.getAttribute('alt') ?? '',
236
- title: dom.getAttribute('title') ?? '',
237
- };
238
- },
239
- },
240
- ],
241
- parseMarkdown: {
242
- ...schema.parseMarkdown,
243
- runner(state, node, type) {
244
- state.addNode(type, markdownImageAttrs(node));
245
- },
246
- },
247
- toMarkdown: {
248
- ...schema.toMarkdown,
249
- runner(state, node) {
250
- const raw = namedFileMarkdown(node, Boolean(node.attrs.inkkitFileInTable));
251
- if (raw == null)
252
- return schema.toMarkdown.runner(state, node);
253
- state.addNode('image', undefined, undefined, {
254
- url: node.attrs.src,
255
- alt: node.attrs.alt,
256
- title: node.attrs.title || null,
257
- inkkitFileRaw: raw,
258
- inkkitFileTarget: node.attrs.inkkitFileTarget,
259
- inkkitFileFragment: node.attrs.inkkitFileFragment,
260
- inkkitFileWidth: fileReference(node).width ?? null,
261
- inkkitFileInTable: node.attrs.inkkitFileInTable,
262
- });
263
- },
264
- },
265
- };
266
- });
267
- // The preset drops a cell's final break, and a paragraph writes an empty one as
268
- // the spacer `<br />`; either reads back differently, so a cell writes its
269
- // paragraph's content directly.
270
- function cellToMarkdown(base) {
271
- return {
272
- ...base,
273
- runner(state, node) {
274
- if (node.childCount === 1 && node.firstChild.type.name === 'paragraph')
275
- state.openNode('tableCell').next(node.firstChild.content).closeNode();
276
- else
277
- base.runner(state, node);
278
- },
279
- };
280
- }
281
- // A cell cannot hold a line ending, so Shift-Enter there inserts the `<br />`
282
- // a cell reads back. The preset's command would instead split the paragraph
283
- // when it already ends in a break, which reshapes the table.
284
- const cellBreakKeymap = $prose(() => keymap({
285
- 'Shift-Enter': (state, dispatch) => {
286
- const { $from } = state.selection;
287
- if (!/^table_(cell|header)$/.test($from.node(-1)?.type.name ?? ''))
288
- return false;
289
- dispatch?.(state.tr
290
- // A break inside a mark or link would be inline HTML there, which
291
- // a cell does not read back as a break.
292
- .replaceSelectionWith(state.schema.nodes.hardbreak.create({ isHTML: true }), false)
293
- .scrollIntoView());
294
- return true;
295
- },
296
- }));
297
- // A list item that opens with a block, such as a code fence, is held with the
298
- // empty first paragraph the schema requires. Written out, that paragraph would
299
- // be a spacer `<br />` line; without it the item reads back the same.
300
- const listItems = extendListItemSchemaForTask.extendSchema((previous) => (ctx) => {
301
- const schema = previous(ctx);
302
- return {
303
- ...schema,
304
- toMarkdown: {
305
- ...schema.toMarkdown,
306
- runner(state, node) {
307
- const [first, second] = [node.firstChild, node.maybeChild(1)];
308
- // A task item's checkbox is written on its first line.
309
- if (node.attrs.checked == null &&
310
- first?.type.name === 'paragraph' &&
311
- first.content.size === 0 &&
312
- second &&
313
- second.type.name !== 'paragraph' &&
314
- // An image block reads back as a paragraph in that position.
315
- second.type.name !== imageBlockName)
316
- node = node.copy(node.content.cut(first.nodeSize));
317
- schema.toMarkdown.runner(state, node);
318
- },
319
- },
320
- };
321
- });
322
- export const tables = [
323
- tableSchema.extendSchema((previous) => (ctx) => ({
324
- ...previous(ctx),
325
- content: 'table_header_row table_row*',
326
- })),
327
- tableHeaderRowSchema,
328
- tableHeaderSchema.extendSchema((previous) => (ctx) => {
329
- const schema = previous(ctx);
330
- return {
331
- ...schema,
332
- attrs: { ...schema.attrs, alignment: { default: null } },
333
- toMarkdown: cellToMarkdown(schema.toMarkdown),
334
- parseDOM: schema.parseDOM?.map((rule) => 'tag' in rule
335
- ? {
336
- ...rule,
337
- getAttrs(dom) {
338
- const attrs = rule.getAttrs?.(dom);
339
- if (attrs === false)
340
- return false;
341
- return {
342
- ...attrs,
343
- alignment: normalizeTableAlignment(dom),
344
- };
345
- },
346
- }
347
- : rule),
348
- };
349
- }),
350
- tableRowSchema,
351
- tableCellSchema.extendSchema((previous) => (ctx) => {
352
- const schema = previous(ctx);
353
- return {
354
- ...schema,
355
- attrs: { ...schema.attrs, alignment: { default: null } },
356
- toMarkdown: cellToMarkdown(schema.toMarkdown),
357
- parseDOM: schema.parseDOM?.map((rule) => 'tag' in rule
358
- ? {
359
- ...rule,
360
- getAttrs(dom) {
361
- const attrs = rule.getAttrs?.(dom);
362
- if (attrs === false)
363
- return false;
364
- return {
365
- ...attrs,
366
- alignment: normalizeTableColumnAlignment(dom),
367
- };
368
- },
369
- }
370
- : rule),
371
- };
372
- }),
373
- tableEditingPlugin,
374
- tableKeymap,
375
- goToNextTableCellCommand,
376
- goToPrevTableCellCommand,
377
- insertTableCommand,
378
- addRowBeforeCommand,
379
- addRowAfterCommand,
380
- addColBeforeCommand,
381
- addColAfterCommand,
382
- selectRowCommand,
383
- selectColCommand,
384
- deleteSelectedCellsCommand,
385
- setAlignCommand,
386
- exitTable,
387
- ].flat();
388
- export function createDialect(images, wikiLinks = false, files = false) {
389
- return [
390
- cellBreakKeymap,
391
- remarkCodeFences,
392
- remarkReferencesPlugin,
393
- remarkCalloutsPlugin,
394
- remarkCommentsPlugin,
395
- wikiLinks || files ? linkedSyntax(wikiLinks, files) : [],
396
- // Protect unsupported inline HTML before the empty-line plugin consumes break nodes.
397
- createLiteralPreservation(images || files),
398
- commonmarkWithLiteralReferences,
399
- $node('doc', () => ({
400
- ...docSchema.schema,
401
- attrs: {
402
- ...docSchema.schema.attrs,
403
- [sourceAttribute]: { default: null },
404
- },
405
- })),
406
- references,
407
- wikiLinks ? wikiLinkSchema : [],
408
- callouts,
409
- comments,
410
- inlineHighlight,
411
- preservingCodeBlocks,
412
- preserveSpacerParagraphs,
413
- visibleSoftbreaks,
414
- normalizedImages,
415
- imageBlocks,
416
- autolinkInputRule,
417
- listItems,
418
- strikethroughAttr,
419
- strikethroughSchema,
420
- strikethroughInputRule,
421
- strikethroughKeymap,
422
- toggleStrikethroughCommand,
423
- wrapInTaskListInputRule,
424
- remarkDialectPlugin,
425
- tables,
426
- literalBlock,
427
- ].flat();
428
- }
429
- export const dialect = createDialect(false);
430
- // One output form, so a document written back unchanged is byte-stable.
431
- export const stringifyOptions = {
432
- bullet: '-',
433
- emphasis: '*',
434
- strong: '*',
435
- fences: true,
436
- listItemIndent: 'one',
437
- rule: '-',
438
- };
439
- // Milkdown preserves authored spacer paragraphs with standalone Markdown HTML breaks.
440
- export function serialize(ctx, doc = ctx.get(editorViewCtx).state.doc) {
441
- if (doc.childCount === 1 &&
442
- doc.firstChild?.type.name === 'paragraph' &&
443
- doc.firstChild.content.size === 0)
444
- return '';
445
- return ctx.get(serializerCtx)(doc);
446
- }
@@ -1,19 +0,0 @@
1
- import type { Node } from '@milkdown/kit/prose/model';
2
- import { Selection } from '@milkdown/kit/prose/state';
3
- import type { EditorView } from '@milkdown/kit/prose/view';
4
- /**
5
- * Where blocks dropped at a point go: in place of an empty top-level
6
- * paragraph at or beside the point, otherwise after the top-level block under the
7
- * point, or beside a top-level leaf such as an image rather than inside it. The result is a range
8
- * to replace; an insertion point has `from` equal to `to`.
9
- */
10
- export declare function blockDropRange(view: EditorView, x: number, y: number): {
11
- from: number;
12
- to: number;
13
- };
14
- /**
15
- * A caret just after inserted blocks that end at `pos`: at the end of the
16
- * last text block, or a gap cursor after a block that holds no text, such as
17
- * a rule or table. It never selects a node, so typing never replaces one.
18
- */
19
- export declare function caretAfter(doc: Node, pos: number): Selection;
@@ -1,47 +0,0 @@
1
- import { GapCursor } from '@milkdown/kit/prose/gapcursor';
2
- import { Selection, TextSelection } from '@milkdown/kit/prose/state';
3
- /**
4
- * Where blocks dropped at a point go: in place of an empty top-level
5
- * paragraph at or beside the point, otherwise after the top-level block under the
6
- * point, or beside a top-level leaf such as an image rather than inside it. The result is a range
7
- * to replace; an insertion point has `from` equal to `to`.
8
- */
9
- export function blockDropRange(view, x, y) {
10
- const { doc, selection } = view.state;
11
- const hit = view.posAtCoords({ left: x, top: y });
12
- const $pos = doc.resolve(hit?.pos ?? selection.from);
13
- // Only an empty paragraph is a placeholder; an empty heading or code block
14
- // was written.
15
- const empty = (node) => node?.type.name === 'paragraph' && node.content.size === 0;
16
- if ($pos.depth === 1 && empty($pos.parent))
17
- return { from: $pos.before(1), to: $pos.after(1) };
18
- if ($pos.depth > 0)
19
- return { from: $pos.after(1), to: $pos.after(1) };
20
- // A point in the margin beside an empty paragraph, as in an empty note.
21
- if (empty($pos.nodeAfter))
22
- return { from: $pos.pos, to: $pos.pos + $pos.nodeAfter.nodeSize };
23
- if (empty($pos.nodeBefore))
24
- return { from: $pos.pos - $pos.nodeBefore.nodeSize, to: $pos.pos };
25
- const leaf = hit && hit.inside >= 0 && doc.resolve(hit.inside).depth === 0
26
- ? doc.nodeAt(hit.inside)
27
- : null;
28
- const at = leaf ? hit.inside + leaf.nodeSize : $pos.pos;
29
- return { from: at, to: at };
30
- }
31
- /**
32
- * A caret just after inserted blocks that end at `pos`: at the end of the
33
- * last text block, or a gap cursor after a block that holds no text, such as
34
- * a rule or table. It never selects a node, so typing never replaces one.
35
- */
36
- export function caretAfter(doc, pos) {
37
- const $pos = doc.resolve(pos);
38
- if ($pos.nodeBefore?.isTextblock)
39
- return TextSelection.create(doc, pos - 1);
40
- // `valid` is public at run time but missing from the type declarations.
41
- const gap = GapCursor;
42
- if (gap.valid($pos))
43
- return new GapCursor($pos);
44
- return (TextSelection.findFrom($pos, -1, true) ??
45
- TextSelection.findFrom($pos, 1, true) ??
46
- Selection.near($pos));
47
- }