stilo-editor 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +226 -2
  3. package/dist/characters--8h5uTeF.js +854 -0
  4. package/dist/content.css +398 -0
  5. package/dist/core/drop.d.ts +6 -0
  6. package/dist/core/editor.d.ts +120 -0
  7. package/dist/core/errors.d.ts +6 -0
  8. package/dist/core/events.d.ts +19 -0
  9. package/dist/core/extension-manager.d.ts +57 -0
  10. package/dist/core/extension.d.ts +48 -0
  11. package/dist/core/helpers/active.d.ts +33 -0
  12. package/dist/core/helpers/block-style.d.ts +25 -0
  13. package/dist/core/helpers/input-rules.d.ts +28 -0
  14. package/dist/core/helpers/lists.d.ts +20 -0
  15. package/dist/core/helpers/marks.d.ts +52 -0
  16. package/dist/core/helpers/nodes.d.ts +26 -0
  17. package/dist/core/helpers/parse-rules.d.ts +8 -0
  18. package/dist/core/helpers/word-count.d.ts +14 -0
  19. package/dist/core/html/css.d.ts +106 -0
  20. package/dist/core/html/parse.d.ts +7 -0
  21. package/dist/core/html/paste/base-styles.d.ts +7 -0
  22. package/dist/core/html/paste/google-docs.d.ts +7 -0
  23. package/dist/core/html/paste/index.d.ts +9 -0
  24. package/dist/core/html/paste/table-widths.d.ts +7 -0
  25. package/dist/core/html/paste/word.d.ts +8 -0
  26. package/dist/core/html/sanitize.d.ts +49 -0
  27. package/dist/core/html/serialize.d.ts +31 -0
  28. package/dist/core/types.d.ts +107 -0
  29. package/dist/extensions/blockquote/index.d.ts +15 -0
  30. package/dist/extensions/bold/index.d.ts +17 -0
  31. package/dist/extensions/bullet-list/index.d.ts +9 -0
  32. package/dist/extensions/clear-formatting/index.d.ts +12 -0
  33. package/dist/extensions/code/index.d.ts +15 -0
  34. package/dist/extensions/code-block/index.d.ts +24 -0
  35. package/dist/extensions/default-extensions/index.d.ts +57 -0
  36. package/dist/extensions/document/index.d.ts +17 -0
  37. package/dist/extensions/drop-cursor/index.d.ts +15 -0
  38. package/dist/extensions/gap-cursor/index.d.ts +6 -0
  39. package/dist/extensions/hard-break/index.d.ts +11 -0
  40. package/dist/extensions/heading/index.d.ts +25 -0
  41. package/dist/extensions/highlight/index.d.ts +24 -0
  42. package/dist/extensions/history/index.d.ts +21 -0
  43. package/dist/extensions/horizontal-rule/index.d.ts +11 -0
  44. package/dist/extensions/image/image-view.d.ts +27 -0
  45. package/dist/extensions/image/index.d.ts +29 -0
  46. package/dist/extensions/index.d.ts +36 -0
  47. package/dist/extensions/italic/index.d.ts +16 -0
  48. package/dist/extensions/line-height/index.d.ts +18 -0
  49. package/dist/extensions/link/index.d.ts +23 -0
  50. package/dist/extensions/list-item/index.d.ts +16 -0
  51. package/dist/extensions/move-block/index.d.ts +17 -0
  52. package/dist/extensions/ordered-list/index.d.ts +12 -0
  53. package/dist/extensions/paragraph/index.d.ts +14 -0
  54. package/dist/extensions/placeholder/index.d.ts +13 -0
  55. package/dist/extensions/search/index.d.ts +55 -0
  56. package/dist/extensions/strike/index.d.ts +16 -0
  57. package/dist/extensions/subscript/index.d.ts +16 -0
  58. package/dist/extensions/superscript/index.d.ts +17 -0
  59. package/dist/extensions/table/index.d.ts +70 -0
  60. package/dist/extensions/task-item/index.d.ts +24 -0
  61. package/dist/extensions/task-item/task-item-view.d.ts +24 -0
  62. package/dist/extensions/task-list/index.d.ts +11 -0
  63. package/dist/extensions/text/index.d.ts +12 -0
  64. package/dist/extensions/text-align/index.d.ts +18 -0
  65. package/dist/extensions/text-case/index.d.ts +14 -0
  66. package/dist/extensions/text-style/font-size.d.ts +21 -0
  67. package/dist/extensions/text-style/index.d.ts +30 -0
  68. package/dist/extensions/underline/index.d.ts +15 -0
  69. package/dist/index.d.ts +14 -0
  70. package/dist/index.js +1 -0
  71. package/dist/src-CV6pgfTS.js +2662 -0
  72. package/dist/style.css +1395 -0
  73. package/dist/ui/components/character-picker.d.ts +22 -0
  74. package/dist/ui/components/characters.d.ts +10 -0
  75. package/dist/ui/components/color-button.d.ts +23 -0
  76. package/dist/ui/components/dropdown.d.ts +34 -0
  77. package/dist/ui/components/find-bar.d.ts +24 -0
  78. package/dist/ui/components/font-size-input.d.ts +21 -0
  79. package/dist/ui/components/icon-menu.d.ts +20 -0
  80. package/dist/ui/components/icon.d.ts +3 -0
  81. package/dist/ui/components/link-bubble.d.ts +19 -0
  82. package/dist/ui/components/link-popover.d.ts +20 -0
  83. package/dist/ui/components/popover.d.ts +27 -0
  84. package/dist/ui/components/shortcut.d.ts +11 -0
  85. package/dist/ui/components/status-bar.d.ts +19 -0
  86. package/dist/ui/components/table-actions.d.ts +25 -0
  87. package/dist/ui/components/table-handles.d.ts +16 -0
  88. package/dist/ui/components/table-menu.d.ts +21 -0
  89. package/dist/ui/i18n/en.d.ts +3 -0
  90. package/dist/ui/i18n/it.d.ts +3 -0
  91. package/dist/ui/i18n/types.d.ts +4 -0
  92. package/dist/ui/index.d.ts +23 -0
  93. package/dist/ui/toolbar/fonts.d.ts +8 -0
  94. package/dist/ui/toolbar/items.d.ts +33 -0
  95. package/dist/ui/toolbar/palette.d.ts +6 -0
  96. package/dist/ui/toolbar/toolbar.d.ts +28 -0
  97. package/dist/ui/toolbar/types.d.ts +150 -0
  98. package/dist/ui.css +996 -0
  99. package/dist/ui.js +2350 -0
  100. package/package.json +96 -4
@@ -0,0 +1,25 @@
1
+ import type { Attrs, DOMOutputSpec, Node, NodeType } from 'prosemirror-model';
2
+ /** A text alignment (docs/SPEC.md F-308). `left` is the default and is stored as `null`. */
3
+ export type TextAlignment = 'left' | 'center' | 'right' | 'justify';
4
+ /** The `textAlign` and `lineHeight` attributes of a textblock spec, both `null` by default. */
5
+ export declare function blockStyleAttrs(): {
6
+ textAlign: {
7
+ default: null;
8
+ };
9
+ lineHeight: {
10
+ default: null;
11
+ };
12
+ };
13
+ /**
14
+ * The style attributes of `node` that `type` also has, to keep them when a block becomes `type`
15
+ * (a centered paragraph stays centered as a heading).
16
+ */
17
+ export declare function keptBlockStyles(type: NodeType, node: Node): Attrs;
18
+ /**
19
+ * The style attributes of a parsed block: its `text-align` (`null` for left) and `line-height`.
20
+ * `null` when it has neither, so the block keeps the shared default attributes: one object per
21
+ * paragraph is a lot of memory in a large document.
22
+ */
23
+ export declare function parseBlockStyle(element: HTMLElement): Attrs | null;
24
+ /** The `toDOM` output of a textblock `tag` with its style attributes, if any. */
25
+ export declare function blockStyleDOM(tag: string, node: Node): DOMOutputSpec;
@@ -0,0 +1,28 @@
1
+ import { InputRule } from 'prosemirror-inputrules';
2
+ import type { Attrs, MarkType, NodeType } from 'prosemirror-model';
3
+ /**
4
+ * Creates an input rule that turns markdown-like syntax into a mark.
5
+ *
6
+ * Contract for `regexp`: it ends with `$`; capture group 1 is the text to mark; the syntax
7
+ * characters immediately around group 1 (e.g. `**`) are part of the match, and the opening and
8
+ * closing syntax have the same length; an optional leading context (e.g. `(?:^|[^*])`) may
9
+ * precede the syntax but must be a **non-capturing** group that consumes at most one character.
10
+ *
11
+ * When the rule fires: the opening and closing syntax are deleted and the mark is added to the
12
+ * text (its other marks are kept); the leading context character (if any) is left untouched;
13
+ * the mark is removed from the stored marks so that typing continues unmarked. Returns `null`
14
+ * (rule does not apply) if group 1 is empty or the parent node does not allow the mark.
15
+ *
16
+ * ```ts
17
+ * markInputRule(/(?:^|[^*])(\*\*([^*]+)\*\*)$/, schema.marks.bold!) // NOT this: group 1 = text
18
+ * markInputRule(/(?:^|[^*])\*\*([^*]+)\*\*$/, schema.marks.bold!) // correct
19
+ * ```
20
+ */
21
+ export declare function markInputRule(regexp: RegExp, type: MarkType, attrs?: Attrs | null): InputRule;
22
+ /**
23
+ * Like `textblockTypeInputRule` from prosemirror-inputrules (turns the textblock where `regexp`
24
+ * matches at its start into `type` with `attrs`, or with the attributes `attrs` returns for the
25
+ * match), but the block keeps the style attributes (`textAlign`, `lineHeight`) that `type` also
26
+ * has, as `setTextblockType` does.
27
+ */
28
+ export declare function textblockTypeInputRule(regexp: RegExp, type: NodeType, attrs?: Attrs | null | ((match: RegExpMatchArray) => Attrs | null)): InputRule;
@@ -0,0 +1,20 @@
1
+ import type { Attrs, NodeType } from 'prosemirror-model';
2
+ import { type Command } from 'prosemirror-state';
3
+ /**
4
+ * Command: toggles a list of `listType` (whose items are `itemType`) at the selection. List
5
+ * nodes are recognized by the `list` group in their spec. Looking at the nearest list around
6
+ * the start of the selection:
7
+ *
8
+ * - a list of `listType`: the selected items are lifted out one level (`liftListItem`);
9
+ * - a list of another type: that list becomes a `listType` list with `attrs`, its items
10
+ * `itemType` items (a task item loses its `checked` state);
11
+ * - no list: the selected blocks are wrapped in a new list (`wrapInList`).
12
+ */
13
+ export declare function toggleList(listType: NodeType, itemType: NodeType, attrs?: Attrs | null): Command;
14
+ /**
15
+ * Command for `Backspace` in lists whose items are `itemType`. At the start of the first
16
+ * textblock of an item, lifts the item (`liftListItem`). At the start of a textblock right after
17
+ * such a list, moves its content to the end of the list's last textblock and deletes it (an
18
+ * empty one just disappears); without this, ProseMirror wraps the textblock in a new item.
19
+ */
20
+ export declare function backspaceInList(itemType: NodeType): Command;
@@ -0,0 +1,52 @@
1
+ import type { Attrs, MarkType, ResolvedPos } from 'prosemirror-model';
2
+ import type { Command } from 'prosemirror-state';
3
+ /**
4
+ * Command: adds a mark of `type` with `attrs` to the selection. A mark that `type` excludes
5
+ * and that excludes `type` is replaced (superscript becomes subscript).
6
+ *
7
+ * - Empty selection: adds the mark to the stored marks (applies to the next typed text).
8
+ * Returns `false` if the parent node does not allow the mark, or a mark at the cursor
9
+ * excludes it (e.g. bold inside code).
10
+ * - Non-empty selection: adds the mark to every selection range. Returns `false` if no text in
11
+ * the selection accepts the mark (parent allows it, no existing mark excludes it). The
12
+ * transaction scrolls into view.
13
+ */
14
+ export declare function setMark(type: MarkType, attrs?: Attrs | null): Command;
15
+ /**
16
+ * Command: removes marks of `type` from the selection.
17
+ *
18
+ * - Empty selection: removes the mark from the stored marks. Returns `false` if the mark is
19
+ * not in the stored marks / cursor marks.
20
+ * - Non-empty selection: removes the mark from every range. Returns `false` if no range has the
21
+ * mark. The transaction scrolls into view.
22
+ */
23
+ export declare function unsetMark(type: MarkType): Command;
24
+ /**
25
+ * Command: merges `attrs` into the mark of `type` on the selection, keeping its other
26
+ * attributes; a mark whose attributes all become `null` is removed. Lets one mark carry several
27
+ * independent attributes (`textStyle`: font family, size, color).
28
+ *
29
+ * - Setting (some value in `attrs` is not `null`): like {@link setMark}, applies to the stored
30
+ * marks or to every selected text that accepts the mark; `false` when none does.
31
+ * - Clearing (every value is `null`): applies where the mark has one of these attributes;
32
+ * `false` when none has.
33
+ *
34
+ * `attrs` can be a function of the position of each selected text (the cursor for an empty
35
+ * selection), for values that differ along the selection; `null` leaves that text alone.
36
+ */
37
+ export declare function updateMarkAttrs(type: MarkType, attrs: Attrs | ((pos: number) => Attrs | null)): Command;
38
+ /**
39
+ * Command: {@link unsetMark} when the mark is active (see `isMarkActive`), otherwise
40
+ * {@link setMark}. Unlike `toggleMark` from prosemirror-commands, a partially marked selection
41
+ * gets the mark added, consistently with `isActive`.
42
+ */
43
+ export declare function toggleMark(type: MarkType, attrs?: Attrs | null): Command;
44
+ /**
45
+ * The range of the mark of `type` at `$pos` (the one in `$pos.marks()`), extended over the
46
+ * adjacent inline nodes that carry the same mark with the same attributes. `null` if there is no
47
+ * such mark at `$pos`. Lets a command edit or remove a whole link with the cursor inside it.
48
+ */
49
+ export declare function markRangeAt($pos: ResolvedPos, type: MarkType): {
50
+ from: number;
51
+ to: number;
52
+ } | null;
@@ -0,0 +1,26 @@
1
+ import type { Attrs, Node, NodeType } from 'prosemirror-model';
2
+ import { type Command, type Transaction } from 'prosemirror-state';
3
+ /**
4
+ * Inserts a block `node` in place of the selection and puts the cursor at the start of the
5
+ * textblock after it, creating a paragraph when no textblock follows. Used by commands and
6
+ * input rules that insert atom blocks (horizontal rule, figure).
7
+ */
8
+ export declare function insertBlockNode(tr: Transaction, node: Node): Transaction;
9
+ /**
10
+ * Command: inserts a block of `type` with {@link insertBlockNode}. Returns `false` where the
11
+ * container of the selection (the parent of the selected textblock, or the parent of a selected
12
+ * block node) does not allow `type`.
13
+ */
14
+ export declare function insertBlock(type: NodeType, attrs?: Attrs | null): Command;
15
+ /**
16
+ * Command: like `setBlockType` from prosemirror-commands (turns the selected textblocks into
17
+ * `type` with `attrs`), but a block keeps the style attributes (`textAlign`, `lineHeight`) that
18
+ * `type` also has, so a centered heading stays centered as a paragraph. `false` when no selected
19
+ * textblock changes.
20
+ */
21
+ export declare function setTextblockType(type: NodeType, attrs?: Attrs): Command;
22
+ /**
23
+ * Command: sets the attribute `name` to `value` on every selected textblock whose type has that
24
+ * attribute (`textAlign`, `lineHeight`). `false` when no selected textblock has it.
25
+ */
26
+ export declare function setTextblockAttr(name: string, value: unknown): Command;
@@ -0,0 +1,8 @@
1
+ import type { StyleParseRule } from 'prosemirror-model';
2
+ /**
3
+ * Parse rules that match a `text-decoration` / `text-decoration-line` style containing
4
+ * `keyword` (e.g. `underline`). Both properties are listed because ProseMirror reads only the
5
+ * properties named in rules. The rules are not consuming, so several marks can match one
6
+ * declaration (`text-decoration: underline line-through`).
7
+ */
8
+ export declare function textDecorationRules(keyword: string): StyleParseRule[];
@@ -0,0 +1,14 @@
1
+ import type { Editor } from '../editor';
2
+ /** Words and characters of a document, from {@link getWordCount}. */
3
+ export interface WordCount {
4
+ /** Runs of non-space characters with at least one letter or digit. */
5
+ words: number;
6
+ /** Characters of the text, spaces included, line and paragraph breaks excluded. */
7
+ characters: number;
8
+ }
9
+ /**
10
+ * Counts the words and characters of the document, docs/SPEC.md F-901. The first call reads the
11
+ * whole document, later calls only the changed top-level blocks: call it on demand or debounced,
12
+ * never on every transaction (ADR 0003).
13
+ */
14
+ export declare function getWordCount(editor: Editor): WordCount;
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Inline style handling: allowlist, parsing, normalization and building of `style` strings.
3
+ * See docs/ARCHITECTURE.md §7.3. Extensions never handle raw style strings themselves.
4
+ */
5
+ /** CSS properties allowed in the HTML output, in output order. */
6
+ export declare const STYLE_PROPERTIES: readonly ['font-family', 'font-size', 'color', 'background-color', 'text-align', 'line-height', 'width'];
7
+ /** A property allowed in the HTML output. */
8
+ export type StyleProperty = (typeof STYLE_PROPERTIES)[number];
9
+ /**
10
+ * Properties accepted on input only: parse rules read them (e.g. `font-weight` → bold), but they
11
+ * never appear in the output.
12
+ */
13
+ export declare const INPUT_ONLY_STYLE_PROPERTIES: readonly ['font-weight', 'font-style', 'text-decoration', 'text-decoration-line', 'vertical-align'];
14
+ /** CSS-wide keywords rejected as color values. */
15
+ export declare const CSS_WIDE_KEYWORDS: readonly string[];
16
+ /**
17
+ * Values containing any of these are always rejected: `url(`, `expression(` (case-insensitive,
18
+ * optional spaces before `(`), `javascript:`, and the characters `<`, `>`, `{`, `}`, `\`.
19
+ */
20
+ export declare const UNSAFE_VALUE: RegExp;
21
+ /**
22
+ * Parses a `style` attribute into a map of property → value.
23
+ *
24
+ * - Declarations are separated by `;`; property and value by the first `:`.
25
+ * - Properties are trimmed and lowercased; values are trimmed and `!important` is removed.
26
+ * - Declarations without `:` or with an empty property/value are skipped.
27
+ * - When a property appears twice, the last one wins.
28
+ */
29
+ export declare function parseStyle(style: string): Map<string, string>;
30
+ /**
31
+ * Formats declarations (as returned by {@link parseStyle}) as `prop: value` joined with `; `.
32
+ * Returns `null` when there are none.
33
+ */
34
+ export declare function formatStyle(declarations: ReadonlyMap<string, string>): string | null;
35
+ /**
36
+ * Normalizes a color value (input is trimmed and lowercased first):
37
+ *
38
+ * - `#rgb` → `#rrggbb`; `#rrggbb` kept (lowercase).
39
+ * - `rgb(r, g, b)` (channels 0–255, any spacing) → `#rrggbb`.
40
+ * - `rgba(r, g, b, a)` with `a` = 1 (or 100%) → `#rrggbb`; with 0 ≤ `a` < 1 →
41
+ * `rgba(r, g, b, a)` with `, ` separators and `a` rounded to 3 decimals.
42
+ * - A keyword matching `^[a-z]{3,20}$` is kept, unless it is in {@link CSS_WIDE_KEYWORDS}.
43
+ * - Anything else (channel > 255, alpha out of range, other formats) → `null`.
44
+ */
45
+ export declare function normalizeColor(value: string): string | null;
46
+ /**
47
+ * Normalizes a font size: trimmed and lowercased, it must match
48
+ * `^\d+(\.\d+)?(px|pt|em|rem|%)$`, otherwise `null`.
49
+ */
50
+ export declare function normalizeFontSize(value: string): string | null;
51
+ /**
52
+ * Normalizes a font family list:
53
+ *
54
+ * - split by `,`; each name trimmed, surrounding `"` or `'` removed, inner whitespace collapsed;
55
+ * - empty names and names containing `"`, `'`, `<`, `>`, `;` are dropped;
56
+ * - names made only of letters, digits and `-` stay unquoted, others are wrapped in `'`;
57
+ * - joined with `, `. Returns `null` if no name remains.
58
+ *
59
+ * Example: `"Times New Roman" ,serif` → `'Times New Roman', serif`.
60
+ */
61
+ export declare function normalizeFontFamily(value: string): string | null;
62
+ /**
63
+ * Normalizes `text-align` (trimmed, lowercased): `left`, `center`, `right`, `justify` kept;
64
+ * `start` → `left`; anything else → `null`.
65
+ */
66
+ export declare function normalizeTextAlign(value: string): string | null;
67
+ /**
68
+ * Normalizes `line-height` (trimmed): a number `^\d+(\.\d+)?$` or a percentage of it (`115%` →
69
+ * `1.15`), rounded to 2 decimals without trailing zeros; zero, `normal` and lengths → `null`.
70
+ */
71
+ export declare function normalizeLineHeight(value: string): string | null;
72
+ /**
73
+ * Normalizes a `width` (trimmed, lowercased): whole pixels, `^\d+(\.\d+)?px$` rounded
74
+ * (`120.4px` → `120px`); zero, other units and keywords → `null` (docs/decisions/0005).
75
+ */
76
+ export declare function normalizeWidth(value: string): string | null;
77
+ /**
78
+ * Normalizes the value of an output property with the matching normalizer above.
79
+ * Returns `null` if the value matches {@link UNSAFE_VALUE} or the normalizer returns `null`.
80
+ */
81
+ export declare function normalizeStyleValue(property: StyleProperty, value: string): string | null;
82
+ /**
83
+ * Builds a canonical `style` string: only {@link STYLE_PROPERTIES}, in that order, values
84
+ * normalized with {@link normalizeStyleValue} (invalid ones skipped), formatted as
85
+ * `prop: value` joined with `; ` and no trailing `;`. `null`/`undefined` values are skipped.
86
+ * Returns `null` if nothing remains.
87
+ *
88
+ * Example: `{ color: 'RGB(255,0,0)', 'font-size': '12PT' }` → `font-size: 12pt; color: #ff0000`.
89
+ */
90
+ export declare function buildStyle(values: Partial<Record<StyleProperty, string | null | undefined>>): string | null;
91
+ /**
92
+ * Reads one output property from an element's `style` attribute (via {@link parseStyle}) and
93
+ * normalizes it (via {@link normalizeStyleValue}). Returns `null` if absent or invalid.
94
+ * Use this in parse rules (`getAttrs`).
95
+ */
96
+ export declare function readStyle(element: HTMLElement, property: StyleProperty): string | null;
97
+ /**
98
+ * Filters a `style` attribute for sanitization:
99
+ *
100
+ * 1. the output properties, normalized, in {@link STYLE_PROPERTIES} order (invalid dropped);
101
+ * 2. then the {@link INPUT_ONLY_STYLE_PROPERTIES}, in that order, kept only if the value matches
102
+ * `^[a-z0-9 .,%#()-]+$` (case-insensitive) and not {@link UNSAFE_VALUE}; value lowercased.
103
+ *
104
+ * Formatted like {@link buildStyle}. Returns `null` if nothing remains.
105
+ */
106
+ export declare function sanitizeStyle(style: string): string | null;
@@ -0,0 +1,7 @@
1
+ import { type Node, type Schema } from 'prosemirror-model';
2
+ /**
3
+ * Parses HTML into a ProseMirror document: the HTML is sanitized with `sanitizeToDOM` and the
4
+ * resulting element is parsed with `DOMParser.fromSchema(schema)` from prosemirror-model.
5
+ * An empty string produces the empty document (one empty paragraph).
6
+ */
7
+ export declare function parseHTML(schema: Schema, html: string): Node;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Removes the base style of a document pasted from a word processor: for each of
3
+ * {@link BASE_PROPERTIES}, the value that covers most of the pasted text (Arial, 11pt, black)
4
+ * is removed everywhere, so only the text that differs keeps its value. `font-size` is also
5
+ * removed inside headings, whose level gives the size.
6
+ */
7
+ export declare function removeBaseStyles(body: HTMLElement): void;
@@ -0,0 +1,7 @@
1
+ /** The element that wraps the HTML Google Docs puts on the clipboard. */
2
+ export declare const GOOGLE_DOCS_WRAPPER = "[id^=\"docs-internal-guid-\"]";
3
+ /**
4
+ * Cleans the HTML of Google Docs: an empty paragraph arrives as a `<br>` between the blocks of the
5
+ * wrapper and becomes an empty `<p>`.
6
+ */
7
+ export declare function cleanGoogleDocs(wrapper: Element): void;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Cleans pasted HTML before it is sanitized (docs/ARCHITECTURE.md §8). The HTML is parsed with an
3
+ * inert `DOMParser` (no scripts run, no images load), then:
4
+ *
5
+ * - from Microsoft Word or Google Docs: their own cleanup, then {@link removeBaseStyles};
6
+ * - a heading that starts a list item becomes a paragraph (a list item starts with one);
7
+ * - tables keep the column widths they carry ({@link readTableWidths}).
8
+ */
9
+ export declare function cleanPastedHTML(html: string): string;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Writes the column widths a pasted table carries as `data-colwidth` on its cells
3
+ * (docs/decisions/0005): from its `<col>` elements (`width` attribute or `style="width"`), else
4
+ * from the cells that span one column. Only pixel widths count; a table without them, or whose
5
+ * cells already have `data-colwidth`, is left as it is.
6
+ */
7
+ export declare function readTableWidths(body: HTMLElement): void;
@@ -0,0 +1,8 @@
1
+ /** Markers of the HTML that Microsoft Word puts on the clipboard. */
2
+ export declare const WORD_HTML: RegExp;
3
+ /**
4
+ * Cleans the HTML of Microsoft Word: removes the `<o:p>` paragraph ends and turns its list
5
+ * paragraphs (`style="mso-list: l0 level1 lfo1"`, the marker in a `mso-list: Ignore` span) into
6
+ * nested `<ul>` / `<ol>`.
7
+ */
8
+ export declare function cleanWord(body: HTMLElement): void;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * HTML sanitization with DOMPurify. See docs/ARCHITECTURE.md §8 and docs/SPEC.md NFR-2.
3
+ *
4
+ * Implementation requirements:
5
+ *
6
+ * - Use a **Stilo-owned DOMPurify instance**, created lazily with `DOMPurify(window)` and cached
7
+ * per `window` (WeakMap). Never add hooks to the default DOMPurify export: it may be shared
8
+ * with the host application. No DOM access at module top level.
9
+ * - Config: `ALLOWED_TAGS`, `ALLOWED_ATTR` below, `ALLOW_DATA_ATTR: false`. Unknown tags are
10
+ * unwrapped with their content kept (DOMPurify default).
11
+ * - One `uponSanitizeAttribute` hook filters attribute values; when the filter returns `null`
12
+ * the attribute is removed (`keepAttr = false`), otherwise `attrValue` is replaced:
13
+ * - `style` → `sanitizeStyle(value)` from `./css`;
14
+ * - `class` → only tokens matching `^language-[\w-]+$`, joined with a space;
15
+ * - `href` → kept (trimmed) if {@link isAllowedHref};
16
+ * - `src` → kept (trimmed) if {@link isAllowedImageSrc};
17
+ * - `target` → kept only if exactly `_blank`;
18
+ * - any other allowed attribute → unchanged.
19
+ */
20
+ /** Tags kept by the sanitizer. */
21
+ export declare const ALLOWED_TAGS: readonly string[];
22
+ /** Attributes kept by the sanitizer (values further filtered by the hook). */
23
+ export declare const ALLOWED_ATTR: readonly string[];
24
+ /** Schemes allowed in `href`. */
25
+ export declare const LINK_PROTOCOLS: readonly string[];
26
+ /** Schemes allowed in `img src` (besides the data URLs matched by {@link IMAGE_DATA_URL}). */
27
+ export declare const IMAGE_PROTOCOLS: readonly string[];
28
+ /** Image data URLs allowed in `img src`. No SVG. */
29
+ export declare const IMAGE_DATA_URL: RegExp;
30
+ /**
31
+ * Extracts the lowercased URL scheme (`"https"` for `https://x`), or `null` for relative URLs
32
+ * and fragments. Whitespace and control characters (U+0000–U+001F) are removed first, because
33
+ * browsers ignore them inside schemes (`java\tscript:` is `javascript:`).
34
+ */
35
+ export declare function urlScheme(url: string): string | null;
36
+ /** Whether a URL is allowed in `href`: relative, fragment, or scheme in {@link LINK_PROTOCOLS}. */
37
+ export declare function isAllowedHref(url: string): boolean;
38
+ /**
39
+ * Whether a URL is allowed in `img src`: non-empty relative URL, scheme in
40
+ * {@link IMAGE_PROTOCOLS}, or a `data:` URL matching {@link IMAGE_DATA_URL}.
41
+ */
42
+ export declare function isAllowedImageSrc(url: string): boolean;
43
+ /** Sanitizes HTML and returns it as a string. Used for paste (`transformPastedHTML`). */
44
+ export declare function sanitizeToString(html: string): string;
45
+ /**
46
+ * Sanitizes HTML and returns a detached `<body>` element (DOMPurify `RETURN_DOM: true`), which
47
+ * avoids a serialize/parse round trip. Used by `parseHTML`.
48
+ */
49
+ export declare function sanitizeToDOM(html: string): HTMLElement;
@@ -0,0 +1,31 @@
1
+ import { DOMSerializer, type Fragment, type Schema } from 'prosemirror-model';
2
+ /** Options of {@link serializeHTML}. */
3
+ export interface SerializeOptions {
4
+ /** Unwrap the single paragraph of list items and table cells. Default: `true`. */
5
+ compactParagraphs?: boolean;
6
+ }
7
+ /**
8
+ * Canonical post-processing of serialized HTML, in place (docs/ARCHITECTURE.md §8.1): styles
9
+ * rewritten with `sanitizeStyle`, and with `compactParagraphs` (default) the single paragraph of
10
+ * list items and table cells unwrapped (docs/decisions/0001).
11
+ */
12
+ export declare function canonicalizeDOM(root: Element | DocumentFragment, options?: SerializeOptions): void;
13
+ /**
14
+ * Serializes a fragment (usually `doc.content`) to a canonical HTML string
15
+ * (docs/ARCHITECTURE.md §7): `DOMSerializer.fromSchema(schema).serializeFragment()` into a
16
+ * container element of a detached document (`document.implementation.createHTMLDocument('')`),
17
+ * then the container's `innerHTML`. Before that:
18
+ *
19
+ * - every `style` attribute is rewritten with `sanitizeStyle`: ProseMirror sets styles through
20
+ * `style.cssText`, and the browser re-serializes them (trailing `;`, `rgb()` colors);
21
+ * - with `compactParagraphs` (default), a `<p>` without attributes that is the only child of a
22
+ * {@link COMPACT_CONTAINERS} element is replaced by its content (docs/decisions/0001).
23
+ *
24
+ * Post-processing is now handled by {@link canonicalizeDOM}.
25
+ */
26
+ export declare function serializeHTML(schema: Schema, fragment: Fragment, options?: SerializeOptions): string;
27
+ /**
28
+ * A `DOMSerializer` for the clipboard (`clipboardSerializer` prop): same output as
29
+ * `DOMSerializer.fromSchema(schema)`, post-processed with `canonicalizeDOM`.
30
+ */
31
+ export declare function createClipboardSerializer(schema: Schema, options?: SerializeOptions): DOMSerializer;
@@ -0,0 +1,107 @@
1
+ import type { Command, Transaction } from 'prosemirror-state';
2
+ import type { Editor } from './editor';
3
+ import type { Extension } from './extension';
4
+ /**
5
+ * Registry of all editor commands. Each extension adds its own entries through module
6
+ * augmentation:
7
+ *
8
+ * ```ts
9
+ * declare module '../../core/types' {
10
+ * interface Commands {
11
+ * toggleBold: () => Command;
12
+ * }
13
+ * }
14
+ * ```
15
+ */
16
+ export interface Commands {
17
+ }
18
+ /** Name of a registered command. */
19
+ export type CommandName = keyof Commands;
20
+ /** A function that receives command arguments and returns a ProseMirror command. */
21
+ export type CommandFactory = (...args: never[]) => Command;
22
+ /** The command factories an extension provides. */
23
+ export type CommandFactories = {
24
+ [K in CommandName]: Commands[K];
25
+ };
26
+ /**
27
+ * An executable command: same arguments as its factory, returns whether the command applied.
28
+ * `can(...args)` runs it without dispatching: whether it would apply.
29
+ */
30
+ export type CommandRunner<A extends unknown[]> = ((...args: A) => boolean) & {
31
+ can: (...args: A) => boolean;
32
+ };
33
+ /** Executable commands, by name. */
34
+ export type CommandRunners = {
35
+ [K in CommandName]: Commands[K] extends (...args: infer A) => Command ? CommandRunner<A> : never;
36
+ };
37
+ /** ProseMirror JSON representation of a document or node. */
38
+ export interface JSONContent {
39
+ type: string;
40
+ attrs?: Record<string, unknown>;
41
+ content?: JSONContent[];
42
+ marks?: Array<{
43
+ type: string;
44
+ attrs?: Record<string, unknown>;
45
+ }>;
46
+ text?: string;
47
+ }
48
+ /** Options of the {@link Editor} constructor. */
49
+ export interface EditorOptions {
50
+ /** Container element; the editor appends its own DOM inside it. */
51
+ element: HTMLElement;
52
+ /** Extensions to load. Nested arrays (e.g. `defaultExtensions()`) are flattened. */
53
+ extensions: Array<Extension | Extension[]>;
54
+ /** Initial HTML content. Default: empty document. */
55
+ content?: string;
56
+ /** Whether the content is editable. Default: `true`. */
57
+ editable?: boolean;
58
+ /** Focus the editor after creation. Default: `false`. */
59
+ autofocus?: boolean | 'start' | 'end';
60
+ /** `aria-label` of the editable area. */
61
+ ariaLabel?: string;
62
+ /**
63
+ * Write a list item (and, from M2, a table cell) whose only content is one paragraph without
64
+ * attributes without its `<p>`: `<li>text</li>`. `false` keeps ProseMirror's standard output,
65
+ * `<li><p>text</p></li>`. Default: `true`. See docs/decisions/0001-tight-list-items.md.
66
+ */
67
+ compactParagraphs?: boolean;
68
+ }
69
+ /** Options of `setHTML` / `setJSON`. */
70
+ export interface SetContentOptions {
71
+ /**
72
+ * `false` (default): replace the content with one undoable transaction.
73
+ * `true`: create a fresh state; history and all plugin states start from scratch.
74
+ */
75
+ resetHistory?: boolean;
76
+ /** Emit the `input` event. Default: `true`. */
77
+ emitInput?: boolean;
78
+ }
79
+ /** Events emitted by the {@link Editor}. */
80
+ export interface EditorEvents {
81
+ /** Every applied transaction. */
82
+ transaction: {
83
+ editor: Editor;
84
+ transaction: Transaction;
85
+ };
86
+ /** The document changed. `transaction` is `null` when the state was replaced (`resetHistory`). */
87
+ input: {
88
+ editor: Editor;
89
+ transaction: Transaction | null;
90
+ };
91
+ /** The selection changed while the document did not. */
92
+ selectionchange: {
93
+ editor: Editor;
94
+ transaction: Transaction;
95
+ };
96
+ focus: {
97
+ editor: Editor;
98
+ event: FocusEvent;
99
+ };
100
+ blur: {
101
+ editor: Editor;
102
+ event: FocusEvent;
103
+ };
104
+ destroy: {
105
+ editor: Editor;
106
+ };
107
+ }
@@ -0,0 +1,15 @@
1
+ import type { Command } from 'prosemirror-state';
2
+ declare module '../../core/types' {
3
+ interface Commands {
4
+ /** Turns the selected textblocks into a blockquote. */
5
+ setBlockquote: () => Command;
6
+ /** Removes the blockquote from the selected textblocks. */
7
+ unsetBlockquote: () => Command;
8
+ /** Removes the blockquote if active, otherwise adds it. */
9
+ toggleBlockquote: () => Command;
10
+ }
11
+ }
12
+ /**
13
+ * The `blockquote` node (`<blockquote>`), docs/SPEC.md F-303.
14
+ */
15
+ export declare const Blockquote: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -0,0 +1,17 @@
1
+ import type { Command } from 'prosemirror-state';
2
+ declare module '../../core/types' {
3
+ interface Commands {
4
+ /** Adds bold to the selection. */
5
+ setBold: () => Command;
6
+ /** Removes bold from the selection. */
7
+ unsetBold: () => Command;
8
+ /** Removes bold if the whole selection is bold, otherwise adds it. */
9
+ toggleBold: () => Command;
10
+ }
11
+ }
12
+ /**
13
+ * The `bold` mark (`<strong>`), docs/SPEC.md F-201. Also parsed from `<b>` (except the Google Docs
14
+ * wrapper `<b style="font-weight: normal">`) and from a bold `font-weight` style.
15
+ * Reference extension: every extension has this shape.
16
+ */
17
+ export declare const Bold: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -0,0 +1,9 @@
1
+ import type { Command } from 'prosemirror-state';
2
+ declare module '../../core/types' {
3
+ interface Commands {
4
+ /** Wraps the selection in a bullet list, lifts it out, or converts another list type. */
5
+ toggleBulletList: () => Command;
6
+ }
7
+ }
8
+ /** The `bulletList` node (`<ul>`), docs/SPEC.md F-401, F-405. Requires `ListItem`. */
9
+ export declare const BulletList: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -0,0 +1,12 @@
1
+ import type { Command } from 'prosemirror-state';
2
+ declare module '../../core/types' {
3
+ interface Commands {
4
+ /** Removes every formatting mark (all marks except links) from the selection. */
5
+ clearFormatting: () => Command;
6
+ }
7
+ }
8
+ /**
9
+ * The `clearFormatting` command, docs/SPEC.md F-212: removes the marks of the `formatting`
10
+ * group (docs/ARCHITECTURE.md §7.2), so links stay.
11
+ */
12
+ export declare const ClearFormatting: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -0,0 +1,15 @@
1
+ import type { Command } from 'prosemirror-state';
2
+ declare module '../../core/types' {
3
+ interface Commands {
4
+ /** Adds inline code to the selection. */
5
+ setCode: () => Command;
6
+ /** Removes inline code from the selection. */
7
+ unsetCode: () => Command;
8
+ /** Removes inline code if the whole selection is code, otherwise adds it. */
9
+ toggleCode: () => Command;
10
+ }
11
+ }
12
+ /**
13
+ * The `code` mark (`<code>`), docs/SPEC.md F-205.
14
+ */
15
+ export declare const Code: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;
@@ -0,0 +1,24 @@
1
+ import { type Command } from 'prosemirror-state';
2
+ declare module '../../core/types' {
3
+ interface Commands {
4
+ /**
5
+ * Turns the selected textblocks into one code block (sibling blocks are joined, one line
6
+ * each), or sets the language of the code block.
7
+ */
8
+ setCodeBlock: (attrs?: CodeBlockAttributes) => Command;
9
+ /** Turns the selected code blocks into paragraphs, one per line. */
10
+ unsetCodeBlock: () => Command;
11
+ /** Removes the code block if active, otherwise adds it. */
12
+ toggleCodeBlock: (attrs?: CodeBlockAttributes) => Command;
13
+ }
14
+ }
15
+ /** Attributes of the `codeBlock` node. */
16
+ export interface CodeBlockAttributes {
17
+ /** The language, written as `class="language-<language>"`; `null` for none. */
18
+ language?: string | null;
19
+ }
20
+ /**
21
+ * The `codeBlock` node (`<pre><code class="language-x">`), plain text without marks,
22
+ * docs/SPEC.md F-306.
23
+ */
24
+ export declare const CodeBlock: (options?: Partial<Record<string, never>> | undefined) => import("../..").Extension<Record<string, never>>;