xiaodao-editor 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 (72) hide show
  1. package/README.md +306 -0
  2. package/dist/block-editor.js +23254 -0
  3. package/dist/block-editor.umd.cjs +26 -0
  4. package/dist/core/Editor.d.ts +83 -0
  5. package/dist/core/command/Command.d.ts +32 -0
  6. package/dist/core/command/InputRule.d.ts +21 -0
  7. package/dist/core/command/Keymap.d.ts +42 -0
  8. package/dist/core/command/SlashCommand.d.ts +24 -0
  9. package/dist/core/command/primitiveCommands.d.ts +97 -0
  10. package/dist/core/extension/Extension.d.ts +52 -0
  11. package/dist/core/extension/Registry.d.ts +46 -0
  12. package/dist/core/history/HistoryManager.d.ts +37 -0
  13. package/dist/core/ids.d.ts +5 -0
  14. package/dist/core/index.d.ts +35 -0
  15. package/dist/core/plugin/Plugin.d.ts +26 -0
  16. package/dist/core/schema/BlockSchema.d.ts +70 -0
  17. package/dist/core/schema/SchemaRegistry.d.ts +22 -0
  18. package/dist/core/selection/Selection.d.ts +25 -0
  19. package/dist/core/serialize/Serializer.d.ts +31 -0
  20. package/dist/core/state/EditorState.d.ts +26 -0
  21. package/dist/core/state/Step.d.ts +39 -0
  22. package/dist/core/state/Transaction.d.ts +52 -0
  23. package/dist/core/state/invert.d.ts +19 -0
  24. package/dist/core/state/store.d.ts +78 -0
  25. package/dist/core/types.d.ts +105 -0
  26. package/dist/extensions/BulletList.d.ts +2 -0
  27. package/dist/extensions/CodeBlock.d.ts +2 -0
  28. package/dist/extensions/Divider.d.ts +2 -0
  29. package/dist/extensions/Heading.d.ts +2 -0
  30. package/dist/extensions/History.d.ts +2 -0
  31. package/dist/extensions/Image.d.ts +34 -0
  32. package/dist/extensions/Keymap.d.ts +2 -0
  33. package/dist/extensions/OrderedList.d.ts +18 -0
  34. package/dist/extensions/Paragraph.d.ts +5 -0
  35. package/dist/extensions/Quote.d.ts +2 -0
  36. package/dist/extensions/Table.d.ts +74 -0
  37. package/dist/extensions/TableOfContents.d.ts +18 -0
  38. package/dist/extensions/TodoList.d.ts +2 -0
  39. package/dist/extensions/_commonAttrs.d.ts +84 -0
  40. package/dist/extensions/builtin.d.ts +15 -0
  41. package/dist/extensions/tableModel.d.ts +199 -0
  42. package/dist/i18n.d.ts +31 -0
  43. package/dist/index.d.ts +30 -0
  44. package/dist/style.css +1 -0
  45. package/dist/test-img.png +0 -0
  46. package/dist/view/BlockContent.vue.d.ts +21 -0
  47. package/dist/view/BlockEditor.vue.d.ts +67 -0
  48. package/dist/view/BlockHost.vue.d.ts +51 -0
  49. package/dist/view/BlockList.vue.d.ts +64 -0
  50. package/dist/view/clipboard.d.ts +11 -0
  51. package/dist/view/context.d.ts +116 -0
  52. package/dist/view/domSelection.d.ts +65 -0
  53. package/dist/view/imageUpload.d.ts +130 -0
  54. package/dist/view/inlineDom.d.ts +23 -0
  55. package/dist/view/keymapHandler.d.ts +7 -0
  56. package/dist/view/ui/BlockHandle.vue.d.ts +33 -0
  57. package/dist/view/ui/BlockSettingsMenu.vue.d.ts +32 -0
  58. package/dist/view/ui/CodeLangPicker.vue.d.ts +20 -0
  59. package/dist/view/ui/HoverToolbar.vue.d.ts +81 -0
  60. package/dist/view/ui/LinkPopover.vue.d.ts +62 -0
  61. package/dist/view/ui/MobileToolbar.vue.d.ts +29 -0
  62. package/dist/view/ui/NumberPicker.vue.d.ts +20 -0
  63. package/dist/view/ui/OrderedListMenu.vue.d.ts +37 -0
  64. package/dist/view/ui/PlusMenu.vue.d.ts +29 -0
  65. package/dist/view/ui/SafeHtml.vue.d.ts +8 -0
  66. package/dist/view/ui/icons.d.ts +51 -0
  67. package/dist/view/ui/inputRulesEngine.d.ts +33 -0
  68. package/dist/view/ui/popup.d.ts +75 -0
  69. package/dist/view/ui/useMenuDismiss.d.ts +9 -0
  70. package/dist/view/ui/useMenuScroll.d.ts +2 -0
  71. package/dist/view/urlUtils.d.ts +39 -0
  72. package/package.json +73 -0
@@ -0,0 +1,26 @@
1
+ import { DocState, Selection } from '../types';
2
+ import { Plugin, PluginState } from '../plugin/Plugin';
3
+ import { Transaction } from './Transaction';
4
+ import { ApplyResult } from './Step';
5
+ export interface EditorState {
6
+ readonly doc: DocState;
7
+ readonly selection: Selection;
8
+ readonly pluginState: Readonly<Record<string, PluginState>>;
9
+ /** Monotonic counter; bumped once per applied transaction. */
10
+ readonly version: number;
11
+ }
12
+ export interface ApplyTransactionResult extends ApplyResult {
13
+ readonly state: EditorState;
14
+ }
15
+ interface TransactionApplier {
16
+ readonly name: string;
17
+ readonly applyTransaction?: NonNullable<Plugin['applyTransaction']>;
18
+ }
19
+ /**
20
+ * Apply a transaction to a state, producing a new state plus a diff
21
+ * (changed / removed) that the view bridge consumes.
22
+ */
23
+ export declare function applyTransaction(state: EditorState, tr: Transaction, plugins: readonly TransactionApplier[]): ApplyTransactionResult;
24
+ /** Create the initial state from a document and a (possibly null) selection. */
25
+ export declare function createState(doc: DocState, selection: Selection, pluginState?: Readonly<Record<string, PluginState>>): EditorState;
26
+ export {};
@@ -0,0 +1,39 @@
1
+ import { Attrs, BlockId, BlockType, DocState, InlineSeq } from '../types';
2
+ export type Step = {
3
+ readonly op: 'insertBlock';
4
+ readonly parent: BlockId | null;
5
+ readonly index: number;
6
+ readonly id: BlockId;
7
+ readonly type: BlockType;
8
+ readonly attrs: Attrs;
9
+ readonly content: InlineSeq;
10
+ } | {
11
+ readonly op: 'removeBlock';
12
+ readonly id: BlockId;
13
+ } | {
14
+ readonly op: 'replaceBlock';
15
+ readonly id: BlockId;
16
+ readonly type: BlockType;
17
+ readonly attrs: Attrs;
18
+ } | {
19
+ readonly op: 'moveBlock';
20
+ readonly id: BlockId;
21
+ readonly toParent: BlockId | null;
22
+ readonly toIndex: number;
23
+ } | {
24
+ readonly op: 'setText';
25
+ readonly id: BlockId;
26
+ readonly content: InlineSeq;
27
+ } | {
28
+ readonly op: 'setAttrs';
29
+ readonly id: BlockId;
30
+ readonly attrs: Attrs;
31
+ };
32
+ export interface ApplyResult {
33
+ readonly doc: DocState;
34
+ /** Block ids whose `Block` reference changed (content/attrs/type) or were inserted. */
35
+ readonly changed: ReadonlySet<BlockId>;
36
+ /** Block ids removed from the document (the subtree roots and their descendants). */
37
+ readonly removed: ReadonlySet<BlockId>;
38
+ }
39
+ export declare function applySteps(doc: DocState, steps: readonly Step[]): ApplyResult;
@@ -0,0 +1,52 @@
1
+ import { Attrs, BlockId, BlockType, InlineSeq, Selection } from '../types';
2
+ import { Step } from './Step';
3
+ export interface TransactionMeta {
4
+ readonly addToHistory?: boolean;
5
+ readonly historyGroup?: string | null;
6
+ readonly viewHints?: {
7
+ readonly skipDomWrite?: readonly BlockId[];
8
+ };
9
+ /** Provenance hint for debugging: 'input' | 'command' | 'clipboard' | ... */
10
+ readonly source?: string;
11
+ readonly [key: string]: unknown;
12
+ }
13
+ export interface Transaction {
14
+ readonly steps: readonly Step[];
15
+ readonly selectionAfter?: Selection;
16
+ readonly meta: TransactionMeta;
17
+ }
18
+ export interface InsertBlockParams {
19
+ readonly parent: BlockId | null;
20
+ readonly index: number;
21
+ readonly type: BlockType;
22
+ readonly attrs?: Attrs;
23
+ readonly content?: InlineSeq;
24
+ /** Optional explicit id (otherwise generated). Used by undo/redo & paste. */
25
+ readonly id?: BlockId;
26
+ }
27
+ /**
28
+ * Fluent builder. Each step method returns `this` for chaining. `build()`
29
+ * freezes the result into a `Transaction`.
30
+ */
31
+ export declare class TransactionBuilder {
32
+ private readonly steps;
33
+ private selectionAfter?;
34
+ private meta;
35
+ insertBlock(params: InsertBlockParams): BlockId;
36
+ removeBlock(id: BlockId): this;
37
+ replaceBlock(id: BlockId, type: BlockType, attrs: Attrs): this;
38
+ moveBlock(id: BlockId, toParent: BlockId | null, toIndex: number): this;
39
+ setText(id: BlockId, content: InlineSeq): this;
40
+ setAttrs(id: BlockId, attrs: Attrs): this;
41
+ /** Return a snapshot of the steps accumulated so far (read-only). */
42
+ peek(): readonly Step[];
43
+ /** Append a pre-built list of steps (used by history undo/redo). */
44
+ appendSteps(steps: readonly Step[]): this;
45
+ setSelection(selection: Selection): this;
46
+ setMeta(meta: Partial<TransactionMeta>): this;
47
+ addToHistory(value: boolean): this;
48
+ historyGroup(key: string | null): this;
49
+ skipDomWrite(ids: readonly BlockId[]): this;
50
+ build(): Transaction;
51
+ }
52
+ export declare function createTransaction(): TransactionBuilder;
@@ -0,0 +1,19 @@
1
+ import { DocState } from '../types';
2
+ import { Step } from './Step';
3
+ /**
4
+ * Invert a sequence of steps against the pre-state. Returns a new step list
5
+ * that, when applied to the post-state, restores the pre-state. Steps are
6
+ * inverted in reverse order so the last-applied change is undone first.
7
+ *
8
+ * Important — forward-step is a sequential program:
9
+ * [ setAttrs(A, x'), insertBlock(B), replaceBlock(B), setAttrs(B) ]
10
+ * When reversing, we may see `replaceBlock(B)` / `setAttrs(B)` BEFORE we see
11
+ * the `insertBlock(B)` that actually added B to the document. In that case
12
+ * B is NOT present in `prevDoc` (prevDoc is the pre-transaction snapshot,
13
+ * not the mid-transaction intermediate). Inverting B's attribute/replace
14
+ * changes is redundant because the final `insertBlock(B)` → inverse
15
+ * `removeBlock(B)` already erases B entirely. So these "unknown id" cases
16
+ * are skipped — the block is handled by its matching insertBlock inverse
17
+ * further up the step list.
18
+ */
19
+ export declare function invertSteps(steps: readonly Step[], prevDoc: DocState): Step[];
@@ -0,0 +1,78 @@
1
+ import { Attrs, Block, BlockId, DocState, DocumentData, InlineSeq } from '../types';
2
+ export interface DocBuildResult {
3
+ readonly doc: DocState;
4
+ /** Map from source JSON id (if any) to the assigned stable `BlockId`. */
5
+ readonly idMap: ReadonlyMap<string, BlockId>;
6
+ }
7
+ /**
8
+ * Build a normalized `DocState` from nested JSON.
9
+ *
10
+ * Id policy (docs §4.1, §17.1): a source id is preserved if it is non-empty
11
+ * and unique within this document; otherwise a fresh id is generated. The
12
+ * mapping from source id → assigned id is returned for caller use.
13
+ *
14
+ * Legacy migration: if the input JSON is "flat-by-indent" (children never
15
+ * written; every block sits at root level; attrs.indent encodes depth) we
16
+ * rebuild the real parent/children tree so the rest of the editor operates
17
+ * on a real tree. The attrs.indent field on each block is then normalized to
18
+ * mirror the computed depth so downstream renderers stay consistent.
19
+ */
20
+ export declare function docFromData(json: DocumentData): DocBuildResult;
21
+ /** Serialize a `DocState` to nested JSON (the external format). */
22
+ export declare function docToData(doc: DocState): DocumentData;
23
+ export declare function getBlock(doc: DocState, id: BlockId): Block | undefined;
24
+ export declare function requireBlock(doc: DocState, id: BlockId): Block;
25
+ export declare function parentOf(doc: DocState, id: BlockId): BlockId | null;
26
+ /**
27
+ * Nesting depth of a block: count of ancestors.
28
+ * • Root blocks: depth 0
29
+ * • Direct child of a root block: depth 1
30
+ * • etc.
31
+ *
32
+ * This is the AUTHORITATIVE source for indent level; `attrs.indent` is only a
33
+ * synchronized mirror kept for backward compatibility with the CSS class
34
+ * pipeline (`classesFromAttrs`) and legacy renderers.
35
+ */
36
+ export declare function depthOf(doc: DocState, id: BlockId): number;
37
+ /** The ordered sibling list a block belongs to (root or a parent's children). */
38
+ export declare function siblingList(doc: DocState, id: BlockId): readonly BlockId[];
39
+ export declare function indexOf(doc: DocState, id: BlockId): number;
40
+ export declare function prevSibling(doc: DocState, id: BlockId): Block | undefined;
41
+ export declare function nextSibling(doc: DocState, id: BlockId): Block | undefined;
42
+ /**
43
+ * All block ids in document order (root-first, depth-first). Used by the view
44
+ * bridge to derive the flat render list and by navigation to find the
45
+ * previous/next *visible* block across nesting boundaries.
46
+ */
47
+ export declare function flatten(doc: DocState): BlockId[];
48
+ /** The previous block in document (depth-first) order across nesting. */
49
+ export declare function blockBefore(doc: DocState, id: BlockId): Block | undefined;
50
+ export declare function blockAfter(doc: DocState, id: BlockId): Block | undefined;
51
+ /** The deepest last descendant of a block (or the block itself if leaf). */
52
+ export declare function lastDescendant(doc: DocState, id: BlockId): Block;
53
+ /**
54
+ * Returns the setAttrs patches needed to make every block's `attrs.indent`
55
+ * exactly equal to `depthOf(doc, id)` (clamped to 0..MAX_INDENT). Any block
56
+ * whose indent already matches is omitted so we don't emit spurious changed
57
+ * entries in the next transaction.
58
+ *
59
+ * This is the SINGLE place that is allowed to *write* `attrs.indent`.
60
+ * Commands and transaction callers should NOT manually set attrs.indent;
61
+ * instead they should manipulate parent/children (via moveBlock /
62
+ * insertBlock/removeBlock) and then run this synchronizer at the end of the
63
+ * transaction build.
64
+ *
65
+ * If a `schema` is supplied, blocks whose schema does not declare an
66
+ * `indent` attr have the indent key stripped entirely (matching the
67
+ * coerceAttrs convention used across extensions).
68
+ */
69
+ export declare function collectIndentSyncPatches(doc: DocState, schema?: {
70
+ get(type: string): {
71
+ attrs: Readonly<Record<string, unknown>>;
72
+ };
73
+ }): Array<{
74
+ id: BlockId;
75
+ attrs: Attrs;
76
+ }>;
77
+ export declare function withContent(block: Block, content: InlineSeq): Block;
78
+ export declare function withAttrs(block: Block, attrs: Block['attrs']): Block;
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Core domain types for the block editor.
3
+ *
4
+ * This module is the single source of truth for the editor's data model. It is
5
+ * intentionally framework-agnostic (no Vue) and contains only type definitions
6
+ * plus a few pure type guards. All runtime behavior lives in dedicated modules.
7
+ *
8
+ * See docs/editor-architecture.md §4 (Document model) and §8 (Selection).
9
+ */
10
+ /**
11
+ * A stable, opaque identifier for a block. Branded so that a plain `string`
12
+ * cannot be passed where a `BlockId` is expected — this catches an entire
13
+ * class of bugs at compile time.
14
+ */
15
+ export type BlockId = string & {
16
+ readonly __brand: 'BlockId';
17
+ };
18
+ /** A registered block type id (e.g. "paragraph", "heading"). */
19
+ export type BlockType = string;
20
+ export type JSONValue = string | number | boolean | null | JSONValue[] | {
21
+ [key: string]: JSONValue;
22
+ };
23
+ /** Block-level attributes. A plain JSON object shaped by the block's schema. */
24
+ export type Attrs = Readonly<Record<string, JSONValue>>;
25
+ /** An inline mark applied to a text run (bold, italic, link, …). */
26
+ export interface Mark {
27
+ readonly type: string;
28
+ readonly attrs?: Attrs;
29
+ }
30
+ /**
31
+ * A single inline node. Phase 1 only has text runs; the model is already a
32
+ * discriminated union so future inline atoms (mention, equation) extend it
33
+ * without changing the block shape.
34
+ */
35
+ export interface TextRun {
36
+ readonly type: 'text';
37
+ readonly text: string;
38
+ readonly marks?: readonly Mark[];
39
+ }
40
+ export type InlineNode = TextRun;
41
+ /** The ordered inline content of a block. An empty array means "no text". */
42
+ export type InlineSeq = readonly InlineNode[];
43
+ /**
44
+ * A block. Treated as immutable within an `EditorState` version: any mutation
45
+ * produces a new `Block` object while siblings keep referential identity.
46
+ */
47
+ export interface Block {
48
+ readonly id: BlockId;
49
+ readonly type: BlockType;
50
+ readonly attrs: Attrs;
51
+ readonly content: InlineSeq;
52
+ /** Ordered child block ids. Nesting is resolved via the document store. */
53
+ readonly children: readonly BlockId[];
54
+ }
55
+ /**
56
+ * The normalized document: a forest of blocks stored in a map keyed by id,
57
+ * plus the ordered list of top-level ids and a parent index for O(1) upward
58
+ * navigation. Plain (non-reactive) data; see docs §10.
59
+ */
60
+ export interface DocState {
61
+ readonly id: string;
62
+ readonly root: readonly BlockId[];
63
+ readonly blocks: ReadonlyMap<BlockId, Block>;
64
+ /** Parent of each block; `null` means "top-level (child of root)". */
65
+ readonly parent: ReadonlyMap<BlockId, BlockId | null>;
66
+ }
67
+ export interface Anchor {
68
+ readonly blockId: BlockId;
69
+ readonly offset: number;
70
+ }
71
+ export type Selection = {
72
+ readonly kind: 'caret';
73
+ readonly blockId: BlockId;
74
+ readonly offset: number;
75
+ } | {
76
+ readonly kind: 'text';
77
+ readonly anchor: Anchor;
78
+ readonly focus: Anchor;
79
+ } | {
80
+ readonly kind: 'blocks';
81
+ readonly blockIds: readonly BlockId[];
82
+ };
83
+ export interface BlockData {
84
+ readonly id?: string;
85
+ readonly type: string;
86
+ readonly attrs?: Attrs;
87
+ readonly content?: InlineSeq;
88
+ readonly children?: readonly BlockData[];
89
+ }
90
+ export interface DocumentData {
91
+ readonly id?: string;
92
+ readonly blocks: readonly BlockData[];
93
+ }
94
+ export declare function isBlockId(value: unknown): value is BlockId;
95
+ export declare function isTextRun(node: InlineNode): node is TextRun;
96
+ /** Concatenate all text in an inline sequence. */
97
+ export declare function inlineText(seq: InlineSeq): string;
98
+ /** Build an inline sequence from a plain string. */
99
+ export declare function inlineFromString(text: string): InlineSeq;
100
+ /**
101
+ * Split an InlineSeq at character offset into two halves.
102
+ * TextRuns that straddle the boundary are split into two TextRun copies
103
+ * (preserving marks). Empty runs are omitted.
104
+ */
105
+ export declare function splitInline(seq: InlineSeq, offset: number): readonly [InlineSeq, InlineSeq];
@@ -0,0 +1,2 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ export declare const BulletListExtension: Extension;
@@ -0,0 +1,2 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ export declare const CodeBlockExtension: Extension;
@@ -0,0 +1,2 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ export declare const DividerExtension: Extension;
@@ -0,0 +1,2 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ export declare const HeadingExtension: Extension;
@@ -0,0 +1,2 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ export declare const HistoryExtension: Extension;
@@ -0,0 +1,34 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ import { BlockId } from '../core/types';
3
+ export interface ImageAttrs {
4
+ readonly align: string;
5
+ readonly src: string;
6
+ readonly alt: string;
7
+ readonly title: string;
8
+ readonly width: number;
9
+ readonly height: number;
10
+ readonly caption: string;
11
+ /**
12
+ * Optional server-side file identifier (integer). Set by the external
13
+ * `uploadImage` handler when it returns a result. The editor tracks
14
+ * reference counts for each fileId and emits `cleanup:image-file` when
15
+ * the last block referencing a fileId is removed, so the consumer can
16
+ * reclaim cloud storage.
17
+ * 0 (the default) means "no file id" / not uploaded yet / no managed file.
18
+ */
19
+ readonly fileId: number;
20
+ }
21
+ export interface InsertImageBlockArgs {
22
+ readonly after?: BlockId;
23
+ readonly parent?: BlockId | null;
24
+ readonly index?: number;
25
+ readonly attrs?: {
26
+ src?: string;
27
+ alt?: string;
28
+ title?: string;
29
+ width?: number;
30
+ height?: number;
31
+ caption?: string;
32
+ };
33
+ }
34
+ export declare const ImageExtension: Extension;
@@ -0,0 +1,2 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ export declare const KeymapExtension: Extension;
@@ -0,0 +1,18 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ import { BlockId } from '../core/types';
3
+ import { siblingList } from '../core/state/store';
4
+ /**
5
+ * Compute the displayed 1-based ordinal for an ordered-list block.
6
+ *
7
+ * Numbering is scoped per **sibling list** (i.e. per
8
+ * same parent). Consecutive `orderedList` siblings in that single list are
9
+ * numbered continuously; any non-orderedList sibling in between breaks the
10
+ * chain; an explicit `attrs.startNumber` acts as a reset anchor.
11
+ *
12
+ * This is strictly narrower than the old flat-indent model: blocks under a
13
+ * DIFFERENT parent (even at the same depthOf) never share a counter —
14
+ * crossing any parent boundary resets numbering by design. This matches the
15
+ * rendering (BlockList nests children) and user intuition.
16
+ */
17
+ export declare function orderedListNumber(doc: Parameters<typeof siblingList>[0], id: BlockId): number;
18
+ export declare const OrderedListExtension: Extension;
@@ -0,0 +1,5 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ import { BlockId } from '../core/types';
3
+ /** Slash-menu icon — SVG string from shared icons module. */
4
+ export declare const ParagraphExtension: Extension;
5
+ export declare const CURRENT_BLOCK_PLACEHOLDER: BlockId;
@@ -0,0 +1,2 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ export declare const QuoteExtension: Extension;
@@ -0,0 +1,74 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ import { EditorRegistries } from '../core/extension/Registry';
3
+ import { BlockId } from '../core/types';
4
+ import { AnyCommandEntry } from '../core/command/Command';
5
+ export interface TableInsertRowArgs {
6
+ readonly id: BlockId;
7
+ readonly beforeRow?: number;
8
+ }
9
+ export interface TableRemoveRowArgs {
10
+ readonly id: BlockId;
11
+ readonly row?: number;
12
+ }
13
+ export interface TableInsertColArgs {
14
+ readonly id: BlockId;
15
+ readonly beforeCol?: number;
16
+ }
17
+ export interface TableRemoveColArgs {
18
+ readonly id: BlockId;
19
+ readonly col?: number;
20
+ }
21
+ export interface TableToggleHeaderArgs {
22
+ readonly id: BlockId;
23
+ }
24
+ export interface TableMergeCellsArgs {
25
+ readonly id: BlockId;
26
+ readonly r1: number;
27
+ readonly c1: number;
28
+ readonly r2: number;
29
+ readonly c2: number;
30
+ }
31
+ export interface TableSplitCellArgs {
32
+ readonly id: BlockId;
33
+ readonly row: number;
34
+ readonly col: number;
35
+ }
36
+ export interface TableSplitCellsInRectArgs {
37
+ readonly id: BlockId;
38
+ readonly r1: number;
39
+ readonly c1: number;
40
+ readonly r2: number;
41
+ readonly c2: number;
42
+ }
43
+ export interface TableSetColWidthArgs {
44
+ readonly id: BlockId;
45
+ readonly col: number;
46
+ readonly width: number;
47
+ }
48
+ export interface TableDeleteArgs {
49
+ readonly id: BlockId;
50
+ }
51
+ export interface InsertTableArgs {
52
+ readonly rows?: number;
53
+ readonly cols?: number;
54
+ readonly after?: BlockId;
55
+ readonly replaceCurrent?: boolean;
56
+ }
57
+ /** Build all table commands. The registry context is accepted for parity with
58
+ * other factories but currently unused — kept for future callers that need
59
+ * schema-level coordination. */
60
+ export declare function createTableCommands(_registries: EditorRegistries): AnyCommandEntry[];
61
+ export declare const TableExtension: Extension;
62
+ export declare const TABLE_ICONS: {
63
+ ICON_TABLE: string;
64
+ ICON_ROW_ABOVE: string;
65
+ ICON_ROW_BELOW: string;
66
+ ICON_COL_LEFT: string;
67
+ ICON_COL_RIGHT: string;
68
+ ICON_DEL_ROW: string;
69
+ ICON_DEL_COL: string;
70
+ ICON_MERGE: string;
71
+ ICON_SPLIT: string;
72
+ ICON_HEADER: string;
73
+ ICON_DELETE_TABLE: string;
74
+ };
@@ -0,0 +1,18 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ import { BlockId, DocState } from '../core/types';
3
+ /** A single TOC entry: the heading's stable id, level, and display text. */
4
+ export interface TocItem {
5
+ readonly id: BlockId;
6
+ readonly level: number;
7
+ readonly text: string;
8
+ }
9
+ /**
10
+ * Collect headings from a `DocState`, considering only TOP-LEVEL blocks
11
+ * (`doc.root`). Nested / indented heading blocks are ignored.
12
+ *
13
+ * Only headings that carry text are included (an empty heading is invisible
14
+ * and skipped). Table cells do not live in the block tree (their content is in
15
+ * `Block.attrs`), so any headings inside table cells are naturally excluded.
16
+ */
17
+ export declare function collectHeadings(doc: DocState): readonly TocItem[];
18
+ export declare const TableOfContentsExtension: Extension;
@@ -0,0 +1,2 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ export declare const TodoListExtension: Extension;
@@ -0,0 +1,84 @@
1
+ import { Attrs } from '../core/types';
2
+ export type AlignValue = 'left' | 'center' | 'right' | 'justify';
3
+ /** 支持缩进属性的块类型。 */
4
+ export declare const INDENT_TYPES: readonly string[];
5
+ /** 缩进上限。 */
6
+ export declare const MAX_INDENT = 10;
7
+ export declare const COMMON_ATTRS: {
8
+ readonly align: {
9
+ readonly default: "left";
10
+ readonly validate: (v: unknown) => boolean;
11
+ };
12
+ readonly color: {
13
+ readonly default: "default";
14
+ readonly validate: (v: unknown) => boolean;
15
+ };
16
+ readonly bgColor: {
17
+ readonly default: "default";
18
+ readonly validate: (v: unknown) => boolean;
19
+ };
20
+ readonly indent: {
21
+ readonly default: 0;
22
+ readonly validate: (v: unknown) => boolean;
23
+ };
24
+ };
25
+ /**
26
+ * 不支持缩进的块类型(quote)使用此子集,
27
+ * coerceAttrs 会自动丢弃 indent 属性。
28
+ */
29
+ export declare const COMMON_ATTRS_NO_INDENT: {
30
+ readonly align: {
31
+ readonly default: "left";
32
+ readonly validate: (v: unknown) => boolean;
33
+ };
34
+ readonly color: {
35
+ readonly default: "default";
36
+ readonly validate: (v: unknown) => boolean;
37
+ };
38
+ readonly bgColor: {
39
+ readonly default: "default";
40
+ readonly validate: (v: unknown) => boolean;
41
+ };
42
+ };
43
+ /**
44
+ * 既不支持缩进也不支持对齐的块类型(codeBlock)使用此子集。
45
+ * 代码块只能左对齐:coerceAttrs 会自动丢弃 align 和 indent 属性,
46
+ * 这样将文本块转为代码块时会自动清除对齐属性。
47
+ */
48
+ export declare const COMMON_ATTRS_NO_INDENT_NO_ALIGN: {
49
+ readonly color: {
50
+ readonly default: "default";
51
+ readonly validate: (v: unknown) => boolean;
52
+ };
53
+ readonly bgColor: {
54
+ readonly default: "default";
55
+ readonly validate: (v: unknown) => boolean;
56
+ };
57
+ };
58
+ /**
59
+ * 代码块(codeBlock)使用的 attrs 集合。
60
+ * 代码块不允许 color / bgColor / align,但允许 indent(作为子块时需要 be-indent-n 类)。
61
+ * coerceAttrs 会自动丢弃 color / bgColor / align 属性,转换时自动清除。
62
+ */
63
+ export declare const CODE_BLOCK_ATTRS: {
64
+ readonly indent: {
65
+ readonly default: 0;
66
+ readonly validate: (v: unknown) => boolean;
67
+ };
68
+ };
69
+ /**
70
+ * Apply common attrs (align/color/bgColor) as CSS classes so the playground
71
+ * stylesheet can render them. The renderer uses `classList` instead of
72
+ * inline styles for theming consistency.
73
+ */
74
+ export declare function classesFromAttrs(attrs: Attrs): string[];
75
+ /** Preset text + background colors shown in the block settings menu. */
76
+ export interface ColorPreset {
77
+ readonly key: string;
78
+ readonly label: string;
79
+ readonly cssValue: string;
80
+ /** Background opacity (0-1). Only meaningful for bg color presets. */
81
+ readonly opacity: number;
82
+ }
83
+ export declare const TEXT_COLOR_PRESETS: readonly ColorPreset[];
84
+ export declare const BG_COLOR_PRESETS: readonly ColorPreset[];
@@ -0,0 +1,15 @@
1
+ import { Extension } from '../core/extension/Extension';
2
+ export declare const BuiltinExtensions: readonly Extension[];
3
+ export { ParagraphExtension } from './Paragraph';
4
+ export { HeadingExtension } from './Heading';
5
+ export { KeymapExtension } from './Keymap';
6
+ export { HistoryExtension } from './History';
7
+ export { BulletListExtension } from './BulletList';
8
+ export { OrderedListExtension } from './OrderedList';
9
+ export { TodoListExtension } from './TodoList';
10
+ export { QuoteExtension } from './Quote';
11
+ export { CodeBlockExtension } from './CodeBlock';
12
+ export { ImageExtension } from './Image';
13
+ export { TableExtension, createTableCommands } from './Table';
14
+ export { DividerExtension } from './Divider';
15
+ export { TableOfContentsExtension } from './TableOfContents';