@openleaf-editor/core 0.1.0-beta.1 → 0.1.0-beta.3

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 (101) hide show
  1. package/README.md +115 -0
  2. package/dist/autolink.d.ts +12 -0
  3. package/dist/autolink.d.ts.map +1 -0
  4. package/dist/autolink.js +136 -0
  5. package/dist/autolink.js.map +1 -0
  6. package/dist/command-helpers.d.ts +8 -0
  7. package/dist/command-helpers.d.ts.map +1 -0
  8. package/dist/command-helpers.js +36 -0
  9. package/dist/command-helpers.js.map +1 -0
  10. package/dist/commands.d.ts +43 -22
  11. package/dist/commands.d.ts.map +1 -1
  12. package/dist/commands.js +513 -115
  13. package/dist/commands.js.map +1 -1
  14. package/dist/css.d.ts +1 -123
  15. package/dist/css.d.ts.map +1 -1
  16. package/dist/css.js +1 -214
  17. package/dist/css.js.map +1 -1
  18. package/dist/disclosure.d.ts +21 -0
  19. package/dist/disclosure.d.ts.map +1 -0
  20. package/dist/disclosure.js +144 -0
  21. package/dist/disclosure.js.map +1 -0
  22. package/dist/elements.d.ts +2 -0
  23. package/dist/elements.d.ts.map +1 -0
  24. package/dist/elements.js +2 -0
  25. package/dist/elements.js.map +1 -0
  26. package/dist/embed.d.ts +2 -0
  27. package/dist/embed.d.ts.map +1 -0
  28. package/dist/embed.js +2 -0
  29. package/dist/embed.js.map +1 -0
  30. package/dist/errors.d.ts +38 -0
  31. package/dist/errors.d.ts.map +1 -0
  32. package/dist/errors.js +40 -0
  33. package/dist/errors.js.map +1 -0
  34. package/dist/extensions.d.ts +46 -5
  35. package/dist/extensions.d.ts.map +1 -1
  36. package/dist/extensions.js +292 -65
  37. package/dist/extensions.js.map +1 -1
  38. package/dist/formats.d.ts +44 -0
  39. package/dist/formats.d.ts.map +1 -0
  40. package/dist/formats.js +123 -0
  41. package/dist/formats.js.map +1 -0
  42. package/dist/html.d.ts +32 -2
  43. package/dist/html.d.ts.map +1 -1
  44. package/dist/html.js +185 -31
  45. package/dist/html.js.map +1 -1
  46. package/dist/index.d.ts +27 -6
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +44 -10
  49. package/dist/index.js.map +1 -1
  50. package/dist/insert-commands.d.ts +172 -0
  51. package/dist/insert-commands.d.ts.map +1 -0
  52. package/dist/insert-commands.js +560 -0
  53. package/dist/insert-commands.js.map +1 -0
  54. package/dist/isolating-selection.d.ts +41 -0
  55. package/dist/isolating-selection.d.ts.map +1 -0
  56. package/dist/isolating-selection.js +162 -0
  57. package/dist/isolating-selection.js.map +1 -0
  58. package/dist/keymap.d.ts.map +1 -1
  59. package/dist/keymap.js +6 -3
  60. package/dist/keymap.js.map +1 -1
  61. package/dist/noneditable.d.ts +14 -0
  62. package/dist/noneditable.d.ts.map +1 -0
  63. package/dist/noneditable.js +107 -0
  64. package/dist/noneditable.js.map +1 -0
  65. package/dist/plugins.d.ts +20 -2
  66. package/dist/plugins.d.ts.map +1 -1
  67. package/dist/plugins.js +27 -2
  68. package/dist/plugins.js.map +1 -1
  69. package/dist/preserve.d.ts +76 -0
  70. package/dist/preserve.d.ts.map +1 -1
  71. package/dist/preserve.js +308 -58
  72. package/dist/preserve.js.map +1 -1
  73. package/dist/schema.d.ts +15 -0
  74. package/dist/schema.d.ts.map +1 -1
  75. package/dist/schema.js +356 -76
  76. package/dist/schema.js.map +1 -1
  77. package/dist/structure.d.ts +76 -0
  78. package/dist/structure.d.ts.map +1 -0
  79. package/dist/structure.js +422 -0
  80. package/dist/structure.js.map +1 -0
  81. package/dist/tables.d.ts +60 -1
  82. package/dist/tables.d.ts.map +1 -1
  83. package/dist/tables.js +617 -35
  84. package/dist/tables.js.map +1 -1
  85. package/dist/testing.d.ts +3 -0
  86. package/dist/testing.d.ts.map +1 -0
  87. package/dist/testing.js +3 -0
  88. package/dist/testing.js.map +1 -0
  89. package/dist/tokens.d.ts +36 -0
  90. package/dist/tokens.d.ts.map +1 -0
  91. package/dist/tokens.js +116 -0
  92. package/dist/tokens.js.map +1 -0
  93. package/dist/url.d.ts +1 -25
  94. package/dist/url.d.ts.map +1 -1
  95. package/dist/url.js +1 -77
  96. package/dist/url.js.map +1 -1
  97. package/dist/visual-aids.d.ts +20 -0
  98. package/dist/visual-aids.d.ts.map +1 -0
  99. package/dist/visual-aids.js +149 -0
  100. package/dist/visual-aids.js.map +1 -0
  101. package/package.json +16 -1
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Keep a `TextSelection` from straddling an isolating boundary.
3
+ *
4
+ * `isolating: true` already means ProseMirror will not join or lift across that
5
+ * node. `Selection.near` honours it when *finding* a caret; `TextSelection.between`
6
+ * does not when *building* a range, so Firefox and WebKit can report a selection
7
+ * that starts in a `<blockquote>` and ends in a following `<details>`. Typing
8
+ * then runs `replaceSelection`, which tries to nest the leftover `details` in
9
+ * the quote (legal: `blockquote` is `block+`, `details` is `group: 'block'`) and
10
+ * join, and `content: 'summary block+'` refuses with `TransformError`.
11
+ *
12
+ * The throw escapes the input handler. ProseMirror re-derives the document from
13
+ * the DOM, history never sees a step, and Ctrl+Z cannot undo the mangling.
14
+ *
15
+ * Chromium already clamps at the isolating boundary natively. This plugin does
16
+ * the same for every isolating node, not just `details`: after a transaction,
17
+ * a crossing `TextSelection` is narrowed to the side the anchor sits on. Input
18
+ * handlers also refuse to let a throwing replace run, so even a race with the
19
+ * native selection cannot rewrite the document outside history.
20
+ *
21
+ * `CellSelection` / `AllSelection` / `NodeSelection` are left alone. Select-all
22
+ * is an `AllSelection` in the base keymap; a `TextSelection` that merely
23
+ * contains a whole isolating node (both endpoints outside it) is not crossing.
24
+ */
25
+ import { Plugin, PluginKey, TextSelection } from 'prosemirror-state';
26
+ const key = new PluginKey('openleaf-isolating-selection');
27
+ /** Depth of the innermost isolating ancestor, or 0 if the pos sits in none. */
28
+ export function innermostIsolatingDepth($pos) {
29
+ for (let depth = $pos.depth; depth > 0; depth -= 1) {
30
+ if ($pos.node(depth).type.spec.isolating)
31
+ return depth;
32
+ }
33
+ return 0;
34
+ }
35
+ /**
36
+ * True when the endpoints do not share an isolating ancestor: one is inside a
37
+ * given isolating node and the other is not (or is inside a different one).
38
+ */
39
+ export function textSelectionCrossesIsolating(selection) {
40
+ if (!(selection instanceof TextSelection) || selection.empty)
41
+ return false;
42
+ return !sameIsolatingContext(selection.$from, selection.$to);
43
+ }
44
+ function sameIsolatingContext($a, $b) {
45
+ const depthA = innermostIsolatingDepth($a);
46
+ const depthB = innermostIsolatingDepth($b);
47
+ if (depthA === 0 && depthB === 0)
48
+ return true;
49
+ if (depthA === 0 || depthB === 0)
50
+ return false;
51
+ return $a.before(depthA) === $b.before(depthB);
52
+ }
53
+ /**
54
+ * Narrow a crossing text selection to the isolating context that contains the
55
+ * anchor, or to just outside the isolating node that contains the head when the
56
+ * anchor itself sits in none. Same-context selections are returned unchanged.
57
+ */
58
+ export function clampIsolatingTextSelection(selection) {
59
+ if (selection.empty || sameIsolatingContext(selection.$anchor, selection.$head)) {
60
+ return selection;
61
+ }
62
+ const { $anchor, $head } = selection;
63
+ const doc = $anchor.doc;
64
+ const anchorDepth = innermostIsolatingDepth($anchor);
65
+ if (anchorDepth > 0) {
66
+ const min = $anchor.start(anchorDepth);
67
+ const max = $anchor.end(anchorDepth);
68
+ const head = Math.max(min, Math.min(max, $head.pos));
69
+ if (head === $head.pos)
70
+ return selection;
71
+ const next = TextSelection.between($anchor, doc.resolve(head));
72
+ return next instanceof TextSelection ? next : selection;
73
+ }
74
+ const headDepth = innermostIsolatingDepth($head);
75
+ if (headDepth > 0) {
76
+ const before = $head.before(headDepth);
77
+ const after = $head.after(headDepth);
78
+ const boundary = $anchor.pos <= before ? before : after;
79
+ const next = TextSelection.between($anchor, doc.resolve(boundary));
80
+ return next instanceof TextSelection ? next : selection;
81
+ }
82
+ return selection;
83
+ }
84
+ function tryInsertText(view, from, to, text) {
85
+ try {
86
+ view.state.tr.insertText(text, from, to);
87
+ return true;
88
+ }
89
+ catch {
90
+ return false;
91
+ }
92
+ }
93
+ export function isolatingSelectionPlugin() {
94
+ return new Plugin({
95
+ key,
96
+ appendTransaction(transactions, _oldState, newState) {
97
+ if (transactions.some((tr) => tr.getMeta(key)))
98
+ return null;
99
+ const { selection } = newState;
100
+ if (!(selection instanceof TextSelection) || selection.empty)
101
+ return null;
102
+ const clamped = clampIsolatingTextSelection(selection);
103
+ if (clamped.eq(selection))
104
+ return null;
105
+ return newState.tr.setSelection(clamped).setMeta(key, true);
106
+ },
107
+ props: {
108
+ /*
109
+ * `from`/`to` are the view's idea of the range at the moment of the
110
+ * input event. The DOM can still report a crossing range in the same
111
+ * tick as a keystroke, before `appendTransaction` has run, so the
112
+ * default `insertText` would throw. Building the transaction first is
113
+ * what keeps a throw from ever reaching ProseMirror's input handler:
114
+ * that handler does not catch, and the DOM-derived repair that follows
115
+ * is the corruption that cannot be undone.
116
+ */
117
+ handleTextInput(view, from, to, text) {
118
+ const { doc, selection } = view.state;
119
+ const size = doc.content.size;
120
+ const start = Math.max(0, Math.min(from, size));
121
+ const end = Math.max(start, Math.min(to, size));
122
+ let replaceFrom = start;
123
+ let replaceTo = end;
124
+ if (start !== end) {
125
+ const probe = TextSelection.create(doc, start, end);
126
+ const oriented = selection instanceof TextSelection && selection.anchor === end
127
+ ? new TextSelection(probe.$to, probe.$from)
128
+ : probe;
129
+ const clamped = clampIsolatingTextSelection(oriented);
130
+ replaceFrom = Math.min(clamped.from, clamped.to);
131
+ replaceTo = Math.max(clamped.from, clamped.to);
132
+ }
133
+ if (!tryInsertText(view, replaceFrom, replaceTo, text))
134
+ return true;
135
+ if (replaceFrom === start && replaceTo === end)
136
+ return false;
137
+ view.dispatch(view.state.tr.insertText(text, replaceFrom, replaceTo).scrollIntoView());
138
+ return true;
139
+ },
140
+ handleKeyDown(view, event) {
141
+ if (event.key !== 'Backspace' && event.key !== 'Delete' && event.key !== 'Enter') {
142
+ return false;
143
+ }
144
+ const { selection } = view.state;
145
+ if (!(selection instanceof TextSelection) || selection.empty)
146
+ return false;
147
+ if (!textSelectionCrossesIsolating(selection))
148
+ return false;
149
+ const clamped = clampIsolatingTextSelection(selection);
150
+ try {
151
+ view.state.tr.setSelection(clamped).deleteSelection();
152
+ }
153
+ catch {
154
+ return true;
155
+ }
156
+ view.dispatch(view.state.tr.setSelection(clamped));
157
+ return false;
158
+ },
159
+ },
160
+ });
161
+ }
162
+ //# sourceMappingURL=isolating-selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isolating-selection.js","sourceRoot":"","sources":["../src/isolating-selection.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"keymap.d.ts","sourceRoot":"","sources":["../src/keymap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAoBhD,uEAAuE;AACvE,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,EAAE,QAAQ,EAyC/B,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuBzB;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,UAAc,GAAG,MAAM,GAAG,IAAI,CAQ7E"}
1
+ {"version":3,"file":"keymap.d.ts","sourceRoot":"","sources":["../src/keymap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAuBhD,uEAAuE;AACvE,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,EAAE,QAAQ,EA4C/B,CAAA;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACnC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAuBzB;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,UAAc,GAAG,MAAM,GAAG,IAAI,CAQ7E"}
package/dist/keymap.js CHANGED
@@ -22,7 +22,7 @@
22
22
  */
23
23
  import { baseKeymap, chainCommands, exitCode } from 'prosemirror-commands';
24
24
  import { redo, undo } from 'prosemirror-history';
25
- import { indentListItem, insertHorizontalRule, outdentListItem, setParagraph, toggleTextAlign, splitListItemCommand, toggleBlockquote, toggleBold, toggleBulletList, toggleCodeBlock, toggleHeading, toggleInlineCode, toggleItalic, toggleOrderedList, toggleStrike, toggleUnderline, } from './commands.js';
25
+ import { indent, insertHorizontalRule, outdent, setParagraph, toggleTextAlign, splitListItemCommand, toggleBlockquote, toggleBold, toggleBulletList, toggleCodeBlock, toggleHeading, toggleInlineCode, toggleItalic, toggleOrderedList, toggleStrike, toggleSubscript, toggleSuperscript, toggleUnderline, clearFormatting, } from './commands.js';
26
26
  /**
27
27
  * The default shortcut table.
28
28
  *
@@ -40,6 +40,9 @@ export const shortcuts = [
40
40
  { keys: 'Mod-u', command: toggleUnderline, label: 'Underline' },
41
41
  { keys: 'Mod-Shift-x', command: toggleStrike, label: 'Strikethrough' },
42
42
  { keys: 'Mod-e', command: toggleInlineCode, label: 'Inline code' },
43
+ { keys: 'Mod-=', command: toggleSubscript, label: 'Subscript' },
44
+ { keys: 'Mod-Shift-=', command: toggleSuperscript, label: 'Superscript' },
45
+ { keys: 'Mod-\\', command: clearFormatting, label: 'Clear formatting' },
43
46
  // Blocks. Mod-Alt-N for headings matches Google Docs.
44
47
  { keys: 'Mod-Alt-0', command: setParagraph, label: 'Paragraph' },
45
48
  ...[1, 2, 3, 4, 5, 6].map((level) => ({
@@ -62,8 +65,8 @@ export const shortcuts = [
62
65
  // Lists. Mod-Shift-7/8 matches Word and Google Docs.
63
66
  { keys: 'Mod-Shift-7', command: toggleOrderedList, label: 'Numbered list' },
64
67
  { keys: 'Mod-Shift-8', command: toggleBulletList, label: 'Bulleted list' },
65
- { keys: 'Mod-]', command: indentListItem, label: 'Indent list item' },
66
- { keys: 'Mod-[', command: outdentListItem, label: 'Outdent list item' },
68
+ { keys: 'Mod-]', command: indent, label: 'Indent' },
69
+ { keys: 'Mod-[', command: outdent, label: 'Outdent' },
67
70
  // History.
68
71
  { keys: 'Mod-z', command: undo, label: 'Undo' },
69
72
  { keys: 'Mod-Shift-z', command: redo, label: 'Redo' },
@@ -1 +1 @@
1
- {"version":3,"file":"keymap.js","sourceRoot":"","sources":["../src/keymap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC1E,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAEhD,OAAO,EACL,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,eAAe,GAChB,MAAM,eAAe,CAAA;AAStB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAe;IACnC,uEAAuE;IACvE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE;IACrD,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,QAAQ,EAAE;IACzD,6EAA6E;IAC7E,2EAA2E;IAC3E,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,WAAW,EAAE;IAC/D,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE;IACtE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,aAAa,EAAE;IAElE,sDAAsD;IACtD,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,WAAW,EAAE;IAChE,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,EAAE,WAAW,KAAK,EAAE;QACxB,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC;QAC7B,KAAK,EAAE,WAAW,KAAK,EAAE;KAC1B,CAAC,CAAC;IACH,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,YAAY,EAAE;IACvE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,YAAY,EAAE;IACpE,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,oBAAoB,EAAE,KAAK,EAAE,iBAAiB,EAAE;IAEpF,4EAA4E;IAC5E,6EAA6E;IAC7E,4EAA4E;IAC5E,8EAA8E;IAC9E,4BAA4B;IAC5B,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE;IAC9E,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,eAAe,CAAC,QAAQ,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE;IAClF,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE;IAChF,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,eAAe,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE;IAE9E,qDAAqD;IACrD,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,eAAe,EAAE;IAC3E,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,EAAE;IAC1E,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,kBAAkB,EAAE;IACrE,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,mBAAmB,EAAE;IAEvE,WAAW;IACX,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;IAC/C,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;IACrD,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE;CAChD,CAAA;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CACzB,SAAkC,EAAE;IAEpC,MAAM,QAAQ,GAA4B,EAAE,CAAA;IAE5C,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,SAAS,EAAE,CAAC;QAC1C,2EAA2E;QAC3E,wEAAwE;QACxE,gDAAgD;QAChD,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;QAC/B,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;IACxE,CAAC;IAED,QAAQ,CAAC,OAAO,CAAC,GAAG,aAAa,CAAC,oBAAoB,EAAE,UAAU,CAAC,OAAO,CAAY,CAAC,CAAA;IACvF,QAAQ,CAAC,aAAa,CAAC,GAAG,aAAa,CACrC,QAAQ,EACR,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QAClB,MAAM,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;QAC3C,IAAI,CAAC,EAAE;YAAE,OAAO,KAAK,CAAA;QACrB,IAAI,QAAQ;YAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,cAAc,EAAE,CAAC,CAAA;QACnF,OAAO,IAAI,CAAA;IACb,CAAC,CACF,CAAA;IAED,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAA;AACnC,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,KAAK,GAAG,SAAS,EAAE;IAC5D,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,CAAA;IACtD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,OAAO,KAAK,CAAC,IAAI;SACd,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;SACrC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;SACpC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;SACxC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;AACpC,CAAC;AAED,SAAS,SAAS;IAChB,IAAI,OAAO,SAAS,KAAK,WAAW;QAAE,OAAO,KAAK,CAAA;IAClD,OAAO,sBAAsB,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,IAAI,SAAS,CAAC,SAAS,CAAC,CAAA;AAC/E,CAAC"}
1
+ {"version":3,"file":"keymap.js","sourceRoot":"","sources":["../src/keymap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Honour `contenteditable="false"` on stored markup.
3
+ *
4
+ * The attribute already round-trips as carried residue. Without this plugin the
5
+ * browser will often still let a caret in, and ProseMirror will then "correct"
6
+ * the typing on the next transaction -- which looks like the editor eating
7
+ * keystrokes. Filtering those transactions, and marking the node in the view,
8
+ * is what makes a locked region actually locked.
9
+ */
10
+ import type { Node as PMNode } from 'prosemirror-model';
11
+ import { Plugin } from 'prosemirror-state';
12
+ export declare function isNonEditableNode(node: PMNode): boolean;
13
+ export declare function nonEditablePlugin(): Plugin;
14
+ //# sourceMappingURL=noneditable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noneditable.d.ts","sourceRoot":"","sources":["../src/noneditable.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,IAAI,MAAM,EAAE,MAAM,mBAAmB,CAAA;AACvD,OAAO,EAAE,MAAM,EAAa,MAAM,mBAAmB,CAAA;AAMrD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAIvD;AAoBD,wBAAgB,iBAAiB,IAAI,MAAM,CAgE1C"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Honour `contenteditable="false"` on stored markup.
3
+ *
4
+ * The attribute already round-trips as carried residue. Without this plugin the
5
+ * browser will often still let a caret in, and ProseMirror will then "correct"
6
+ * the typing on the next transaction -- which looks like the editor eating
7
+ * keystrokes. Filtering those transactions, and marking the node in the view,
8
+ * is what makes a locked region actually locked.
9
+ */
10
+ import { Plugin, PluginKey } from 'prosemirror-state';
11
+ import { Decoration, DecorationSet } from 'prosemirror-view';
12
+ import { CARRIED_ATTR } from './extensions.js';
13
+ const key = new PluginKey('openleaf-noneditable');
14
+ export function isNonEditableNode(node) {
15
+ const carried = node.attrs[CARRIED_ATTR];
16
+ const value = carried?.['contenteditable'];
17
+ return Boolean(value && value.toLowerCase() === 'false');
18
+ }
19
+ /** True when a change sits *inside* a locked node, not when the node itself is deleted. */
20
+ function editsLockedInterior(doc, start, end) {
21
+ // Clamped rather than trusted. A throw from here escapes `filterTransaction`
22
+ // and takes the whole transaction with it, so one bad range does not read as
23
+ // "this edit is not allowed" -- it reads as the editor ignoring the command.
24
+ const from = Math.max(0, Math.min(start, doc.content.size));
25
+ const to = Math.max(from, Math.min(end, doc.content.size));
26
+ let blocked = false;
27
+ doc.nodesBetween(from, to, (node, pos) => {
28
+ if (!isNonEditableNode(node))
29
+ return true;
30
+ const start = pos;
31
+ const end = pos + node.nodeSize;
32
+ if (from > start && to < end)
33
+ blocked = true;
34
+ return false;
35
+ });
36
+ return blocked;
37
+ }
38
+ export function nonEditablePlugin() {
39
+ return new Plugin({
40
+ key,
41
+ /**
42
+ * Refuse a transaction that edits the inside of a locked node.
43
+ *
44
+ * Each step's map reports positions in the document *that step* applied to,
45
+ * which for every step after the first is not `state.doc`. Reading the
46
+ * original document with those coordinates walks off the end of it as soon
47
+ * as a transaction has more than one step and the earlier ones grow the
48
+ * document -- `nodesBetween` then throws, the throw escapes here, and
49
+ * ProseMirror drops the transaction. The symptom was a toolbar button doing
50
+ * nothing at all: inserting a table column after inserting a row produces
51
+ * exactly that shape, and the error was swallowed by the toolbar's guard.
52
+ *
53
+ * The transaction already holds those documents. `tr.docs[i]` is the
54
+ * document step `i` was applied to, kept by `Transform` so that a step can
55
+ * be inverted, so each range can simply be read against it -- no mapping at
56
+ * all, and the positions are exact rather than an approximation recovered
57
+ * through an inverse.
58
+ *
59
+ * The mapping is what made this expensive. It used to be
60
+ * `tr.mapping.slice(0, i).invert()`, built inside the loop: an i-length
61
+ * mapping allocated and inverted for every step, so the cost was the sum of
62
+ * i rather than the count of them. A single-character transaction has one
63
+ * step and never showed it; `clearFormatting` over a select-all on a
64
+ * 100-page document produces about three thousand, and measured 180 ms in
65
+ * this function alone.
66
+ */
67
+ filterTransaction(tr, state) {
68
+ if (!tr.docChanged)
69
+ return true;
70
+ let blocked = false;
71
+ for (let i = 0; i < tr.steps.length; i += 1) {
72
+ if (blocked)
73
+ break;
74
+ const step = tr.steps[i];
75
+ if (!step)
76
+ continue;
77
+ // `docs[0]` is `state.doc`; the fallback covers a transaction whose
78
+ // steps were recorded elsewhere, where the first document is the only
79
+ // one we can name.
80
+ const before = tr.docs[i] ?? state.doc;
81
+ step.getMap().forEach((start, end) => {
82
+ if (blocked)
83
+ return;
84
+ if (editsLockedInterior(before, start, end))
85
+ blocked = true;
86
+ });
87
+ }
88
+ return !blocked;
89
+ },
90
+ props: {
91
+ decorations(state) {
92
+ const decorations = [];
93
+ state.doc.descendants((node, pos) => {
94
+ if (!isNonEditableNode(node))
95
+ return true;
96
+ decorations.push(Decoration.node(pos, pos + node.nodeSize, {
97
+ class: 'ol-noneditable',
98
+ contenteditable: 'false',
99
+ }));
100
+ return false;
101
+ });
102
+ return DecorationSet.create(state.doc, decorations);
103
+ },
104
+ },
105
+ });
106
+ }
107
+ //# sourceMappingURL=noneditable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"noneditable.js","sourceRoot":"","sources":["../src/noneditable.ts"],"names":[],"mappings":"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"}
package/dist/plugins.d.ts CHANGED
@@ -14,9 +14,27 @@
14
14
  import type { Plugin } from 'prosemirror-state';
15
15
  import type { Schema } from 'prosemirror-model';
16
16
  export type EditorPluginFactory = (schema: Schema) => Plugin[];
17
- /** Register plugins to be installed in every editor created from now on. */
17
+ /**
18
+ * Register plugins to be installed in every editor created from now on.
19
+ *
20
+ * Throws `OpenLeafError` with code `invalid-argument` when handed something that
21
+ * is not a function. `registerEditorPlugin(42)` used to be accepted silently and
22
+ * fail on the far side of the registry -- once per editor, through
23
+ * `console.error`, with a stack pointing at `createRegisteredPlugins` rather
24
+ * than at the script tag that got it wrong.
25
+ */
18
26
  export declare function registerEditorPlugin(factory: EditorPluginFactory): () => void;
19
- /** Build plugin instances for an editor, reusing cached instances when given. */
27
+ /**
28
+ * Build plugin instances for an editor, reusing cached instances when given.
29
+ *
30
+ * `cache` is a host's own per-editor map, and it is genuinely part of the
31
+ * contract rather than an optimisation that leaked: without it, reconfiguring an
32
+ * editor after a late registration builds *new* instances of the plugins already
33
+ * running, and each one starts from its initial state -- so a table plugin loses
34
+ * its selection and a session plugin its draft, on every later registration.
35
+ * Omit it and every call returns fresh instances, which is correct for a host
36
+ * building one editor once.
37
+ */
20
38
  export declare function createRegisteredPlugins(schema: Schema, cache?: Map<EditorPluginFactory, Plugin[]>): Plugin[];
21
39
  /**
22
40
  * Notified when a plugin registers.
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/C,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,CAAA;AAK9D,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,IAAI,CAU7E;AAoBD,iFAAiF;AACjF,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,GAAG,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAAC,GACzC,MAAM,EAAE,CA2BV;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAKtE"}
1
+ {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAG/C,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,EAAE,CAAA;AAK9D;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,IAAI,CAmB7E;AAoBD;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,GAAG,CAAC,mBAAmB,EAAE,MAAM,EAAE,CAAC,GACzC,MAAM,EAAE,CA2BV;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAKtE"}
package/dist/plugins.js CHANGED
@@ -11,10 +11,25 @@
11
11
  * Calling the factory once per editor is the difference between two working
12
12
  * editors and two editors fighting over one plugin's state.
13
13
  */
14
+ import { OpenLeafError } from './errors.js';
14
15
  const factories = new Set();
15
16
  const listeners = new Set();
16
- /** Register plugins to be installed in every editor created from now on. */
17
+ /**
18
+ * Register plugins to be installed in every editor created from now on.
19
+ *
20
+ * Throws `OpenLeafError` with code `invalid-argument` when handed something that
21
+ * is not a function. `registerEditorPlugin(42)` used to be accepted silently and
22
+ * fail on the far side of the registry -- once per editor, through
23
+ * `console.error`, with a stack pointing at `createRegisteredPlugins` rather
24
+ * than at the script tag that got it wrong.
25
+ */
17
26
  export function registerEditorPlugin(factory) {
27
+ if (typeof factory !== 'function') {
28
+ throw new OpenLeafError('invalid-argument', '@openleaf-editor/core: registerEditorPlugin expects a function taking a schema and ' +
29
+ `returning an array of ProseMirror plugins, received ${typeof factory}. Passing a ` +
30
+ 'plugin instance is the usual mistake: instances carry per-editor state and cannot ' +
31
+ 'be shared, which is why this takes a factory.');
32
+ }
18
33
  factories.add(factory);
19
34
  notify();
20
35
  return () => {
@@ -44,7 +59,17 @@ function notify() {
44
59
  }
45
60
  }
46
61
  }
47
- /** Build plugin instances for an editor, reusing cached instances when given. */
62
+ /**
63
+ * Build plugin instances for an editor, reusing cached instances when given.
64
+ *
65
+ * `cache` is a host's own per-editor map, and it is genuinely part of the
66
+ * contract rather than an optimisation that leaked: without it, reconfiguring an
67
+ * editor after a late registration builds *new* instances of the plugins already
68
+ * running, and each one starts from its initial state -- so a table plugin loses
69
+ * its selection and a session plugin its draft, on every later registration.
70
+ * Omit it and every call returns fresh instances, which is correct for a host
71
+ * building one editor once.
72
+ */
48
73
  export function createRegisteredPlugins(schema, cache) {
49
74
  const plugins = [];
50
75
  const seen = new Set();
@@ -1 +1 @@
1
- {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAOH,MAAM,SAAS,GAAG,IAAI,GAAG,EAAuB,CAAA;AAChD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAA;AAEvC,4EAA4E;AAC5E,MAAM,UAAU,oBAAoB,CAAC,OAA4B;IAC/D,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,MAAM,EAAE,CAAA;IACR,OAAO,GAAG,EAAE;QACV,yEAAyE;QACzE,2EAA2E;QAC3E,4EAA4E;QAC5E,2CAA2C;QAC3C,IAAI,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;YAAE,MAAM,EAAE,CAAA;IACzC,CAAC,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,MAAM;IACb,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,QAAQ,EAAE,CAAA;QACZ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kEAAkE,EAAE,KAAK,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,uBAAuB,CACrC,MAAc,EACd,KAA0C;IAE1C,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC3C,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACjB,MAAM,MAAM,GAAG,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;QAClC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAA;YACvB,SAAQ;QACV,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;YAC/B,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC5B,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAA;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,yEAAyE;YACzE,wEAAwE;YACxE,oDAAoD;YACpD,OAAO,CAAC,KAAK,CAAC,4DAA4D,EAAE,KAAK,CAAC,CAAA;QACpF,CAAC;IACH,CAAC;IACD,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,MAAM,OAAO,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAC/C,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAoB;IACxD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACvB,OAAO,GAAG,EAAE;QACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC5B,CAAC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAI3C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAuB,CAAA;AAChD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAA;AAEvC;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA4B;IAC/D,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;QAClC,MAAM,IAAI,aAAa,CACrB,kBAAkB,EAClB,qFAAqF;YACnF,uDAAuD,OAAO,OAAO,cAAc;YACnF,oFAAoF;YACpF,+CAA+C,CAClD,CAAA;IACH,CAAC;IACD,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACtB,MAAM,EAAE,CAAA;IACR,OAAO,GAAG,EAAE;QACV,yEAAyE;QACzE,2EAA2E;QAC3E,4EAA4E;QAC5E,2CAA2C;QAC3C,IAAI,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC;YAAE,MAAM,EAAE,CAAA;IACzC,CAAC,CAAA;AACH,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,MAAM;IACb,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC;YACH,QAAQ,EAAE,CAAA;QACZ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,kEAAkE,EAAE,KAAK,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,uBAAuB,CACrC,MAAc,EACd,KAA0C;IAE1C,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC3C,KAAK,MAAM,OAAO,IAAI,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACjB,MAAM,MAAM,GAAG,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;QAClC,IAAI,MAAM,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAA;YACvB,SAAQ;QACV,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;YAC/B,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;YAC5B,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAA;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,yEAAyE;YACzE,wEAAwE;YACxE,oDAAoD;YACpD,OAAO,CAAC,KAAK,CAAC,4DAA4D,EAAE,KAAK,CAAC,CAAA;QACpF,CAAC;IACH,CAAC;IACD,IAAI,KAAK,EAAE,CAAC;QACV,KAAK,MAAM,OAAO,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;QAC/C,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAoB;IACxD,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACvB,OAAO,GAAG,EAAE;QACV,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;IAC5B,CAAC,CAAA;AACH,CAAC"}
@@ -27,6 +27,64 @@
27
27
  * and is preserved intact.
28
28
  */
29
29
  import type { NodeSpec } from 'prosemirror-model';
30
+ /**
31
+ * Elements that are never preserved, and whose contents are discarded with them.
32
+ *
33
+ * This is where the project's two strongest instincts collide. The preservation
34
+ * layer exists because silently deleting a customer's markup is the failure
35
+ * OpenLeaf was built to prevent -- but "markup the schema does not recognise"
36
+ * includes `<script>`.
37
+ *
38
+ * Preserving an author's `<div class="callout">` is the product working.
39
+ * Preserving a `<script>` is a vulnerability with extra steps: the editor would
40
+ * hand it back on save, the server would store it, and the next reader would
41
+ * execute it. The content-safety promise is about *authorial content*, and a
42
+ * script tag is not that.
43
+ *
44
+ * `ignore` rather than `skip`: the element AND its contents go. Skipping would
45
+ * unwrap `<script>alert(1)</script>` into the literal text "alert(1)" appearing
46
+ * in the document, which is a different kind of wrong.
47
+ *
48
+ * Spread from `@openleaf-editor/content-policy` rather than written out here.
49
+ * This list and the sanitize policy's `dropWithContent` are the same decision
50
+ * made in two packages, they were maintained by hand, and they drifted: `<svg>`
51
+ * and `<math>` were on the sanitizer's list and missing from this one, so the
52
+ * editor stored exactly the markup the server was configured to delete. Sharing
53
+ * the constant is what makes that drift impossible rather than merely unlikely.
54
+ *
55
+ * Exported so the divergence can be asserted in a test as well as prevented by
56
+ * construction. Not re-exported from the package index: it is an internal
57
+ * invariant, and the shared list itself is public in content-policy.
58
+ */
59
+ export declare const NEVER_PRESERVE: readonly string[];
60
+ /**
61
+ * `<source>` and `<track>`: media children the schema stores as markup rather
62
+ * than as nodes, so they do not count as content when deciding what to keep.
63
+ *
64
+ * Lives here because this module owns the "keep it whole or claim it" decision,
65
+ * and `structure.ts` asks the same question when it reads a media element.
66
+ */
67
+ export declare const MEDIA_FURNITURE_TAGS: ReadonlySet<string>;
68
+ /**
69
+ * True when a media element holds content its node cannot carry.
70
+ *
71
+ * Video and audio are atoms whose only modelled children are `<source>` and
72
+ * `<track>`, so fallback content -- "Download <a href=...>the video</a>", shown
73
+ * by a browser that cannot play the file -- has nowhere to live on the node.
74
+ */
75
+ export declare function hasMediaFallback(el: Element): boolean;
76
+ /**
77
+ * Scrub markup before it is stored for preservation.
78
+ *
79
+ * Preserving an element verbatim means preserving its attributes verbatim, and
80
+ * `<div class="callout" onclick="steal()">` is not something an author needs
81
+ * kept. Works on a clone so the live parse tree is untouched.
82
+ *
83
+ * Exported because the table schema stores `<caption>` and `<colgroup>` the same
84
+ * way, for the same reason, and a second scrubber that drifted from this one
85
+ * would be a hole in exactly the code path that exists to close holes.
86
+ */
87
+ export declare function scrub(el: Element): string;
30
88
  /**
31
89
  * True when this element can be unwrapped without losing information.
32
90
  *
@@ -54,6 +112,24 @@ export declare function isInsidePreserved(node: Element | null): boolean;
54
112
  * delete it, but never edits its interior, so its markup cannot drift.
55
113
  */
56
114
  export declare const unknownBlock: NodeSpec;
115
+ /**
116
+ * Start tags that close an open `<p>` in the HTML "in body" insertion mode.
117
+ *
118
+ * Serializing one of these as an inline atom wraps it in `<p>…</p>`. The next
119
+ * parse cannot keep it there, so it splits into an empty paragraph, the
120
+ * element, and another empty paragraph -- and the following save wraps it
121
+ * again. The same unbounded growth `<plaintext>` caused by having no end tag.
122
+ *
123
+ * Shared with anything else that must not claim a p-closing element as inline
124
+ * (`figcaption` being inline is the other door into this). Custom elements are
125
+ * not on the list: they do not close a `<p>`, so `<drupal-media>` inside a
126
+ * blockquote is correctly an inline atom.
127
+ *
128
+ * Source: WHATWG HTML parsing, "in body" -- every start tag that runs
129
+ * "if the stack of open elements has a p element in button scope, then close
130
+ * a p element" before inserting.
131
+ */
132
+ export declare const CLOSES_OPEN_P: ReadonlySet<string>;
57
133
  /**
58
134
  * Inline preserved content, for unrecognised markup appearing inside a
59
135
  * paragraph -- the `<o:p>` and `<w:sdt>` debris of a Word paste, custom
@@ -1 +1 @@
1
- {"version":3,"file":"preserve.d.ts","sourceRoot":"","sources":["../src/preserve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAwGjD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAyC5D;AAoBD,0EAA0E;AAC1E,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAQ1E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,CAE9C;AAwCD,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAK/D;AAeD;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,QA4B1B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,QA4B3B,CAAA"}
1
+ {"version":3,"file":"preserve.d.ts","sourceRoot":"","sources":["../src/preserve.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAUjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAA2B,CAAA;AAuBvE;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,WAAW,CAAC,MAAM,CAAgC,CAAA;AAErF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAWrD;AA+BD;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,CA+BzC;AA0BD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAkC5D;AAqED,0EAA0E;AAC1E,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAQ1E;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,CAE9C;AAwCD,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,GAAG,OAAO,CAK/D;AAeD;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,QA8B1B,CAAA;AA+CD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CA8C5C,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,QA2C3B,CAAA"}