@openleaf-editor/core 0.1.0-beta.2 → 0.1.0-beta.4

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 (104) hide show
  1. package/README.md +127 -0
  2. package/dist/autolink.d.ts +7 -4
  3. package/dist/autolink.d.ts.map +1 -1
  4. package/dist/autolink.js +90 -11
  5. package/dist/autolink.js.map +1 -1
  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 +21 -63
  11. package/dist/commands.d.ts.map +1 -1
  12. package/dist/commands.js +430 -346
  13. package/dist/commands.js.map +1 -1
  14. package/dist/css.d.ts +1 -175
  15. package/dist/css.d.ts.map +1 -1
  16. package/dist/css.js +1 -516
  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 +1 -51
  27. package/dist/embed.d.ts.map +1 -1
  28. package/dist/embed.js +1 -115
  29. package/dist/embed.js.map +1 -1
  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 +272 -52
  37. package/dist/extensions.js.map +1 -1
  38. package/dist/figure-drag.d.ts +26 -0
  39. package/dist/figure-drag.d.ts.map +1 -0
  40. package/dist/figure-drag.js +75 -0
  41. package/dist/figure-drag.js.map +1 -0
  42. package/dist/formats.d.ts.map +1 -1
  43. package/dist/formats.js +19 -7
  44. package/dist/formats.js.map +1 -1
  45. package/dist/gapcursor.d.ts +14 -0
  46. package/dist/gapcursor.d.ts.map +1 -0
  47. package/dist/gapcursor.js +17 -0
  48. package/dist/gapcursor.js.map +1 -0
  49. package/dist/html.d.ts +32 -2
  50. package/dist/html.d.ts.map +1 -1
  51. package/dist/html.js +185 -31
  52. package/dist/html.js.map +1 -1
  53. package/dist/index.d.ts +23 -6
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +34 -6
  56. package/dist/index.js.map +1 -1
  57. package/dist/insert-commands.d.ts +172 -0
  58. package/dist/insert-commands.d.ts.map +1 -0
  59. package/dist/insert-commands.js +560 -0
  60. package/dist/insert-commands.js.map +1 -0
  61. package/dist/isolating-selection.d.ts +59 -0
  62. package/dist/isolating-selection.d.ts.map +1 -0
  63. package/dist/isolating-selection.js +251 -0
  64. package/dist/isolating-selection.js.map +1 -0
  65. package/dist/noneditable.d.ts.map +1 -1
  66. package/dist/noneditable.js +18 -4
  67. package/dist/noneditable.js.map +1 -1
  68. package/dist/plugins.d.ts +20 -2
  69. package/dist/plugins.d.ts.map +1 -1
  70. package/dist/plugins.js +27 -2
  71. package/dist/plugins.js.map +1 -1
  72. package/dist/preserve.d.ts +48 -17
  73. package/dist/preserve.d.ts.map +1 -1
  74. package/dist/preserve.js +214 -43
  75. package/dist/preserve.js.map +1 -1
  76. package/dist/schema.d.ts +15 -0
  77. package/dist/schema.d.ts.map +1 -1
  78. package/dist/schema.js +157 -28
  79. package/dist/schema.js.map +1 -1
  80. package/dist/structure.d.ts +32 -0
  81. package/dist/structure.d.ts.map +1 -1
  82. package/dist/structure.js +53 -10
  83. package/dist/structure.js.map +1 -1
  84. package/dist/tables.d.ts +47 -1
  85. package/dist/tables.d.ts.map +1 -1
  86. package/dist/tables.js +417 -40
  87. package/dist/tables.js.map +1 -1
  88. package/dist/testing.d.ts +3 -0
  89. package/dist/testing.d.ts.map +1 -0
  90. package/dist/testing.js +3 -0
  91. package/dist/testing.js.map +1 -0
  92. package/dist/tokens.d.ts +8 -0
  93. package/dist/tokens.d.ts.map +1 -1
  94. package/dist/tokens.js +54 -6
  95. package/dist/tokens.js.map +1 -1
  96. package/dist/url.d.ts +1 -25
  97. package/dist/url.d.ts.map +1 -1
  98. package/dist/url.js +1 -77
  99. package/dist/url.js.map +1 -1
  100. package/dist/visual-aids.d.ts +11 -1
  101. package/dist/visual-aids.d.ts.map +1 -1
  102. package/dist/visual-aids.js +124 -36
  103. package/dist/visual-aids.js.map +1 -1
  104. package/package.json +17 -1
@@ -0,0 +1,251 @@
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
+ * `handleTextInput` is not enough on its own. When the model selection is still
22
+ * a collapsed caret, ProseMirror never calls it, and Chromium applies the
23
+ * keystroke to the *DOM* range — which can still straddle `details`. That path
24
+ * emptied `<summary>` and lifted the body out of `<details>` on a subset of
25
+ * Shift+ArrowDown runs (#163). `beforeinput` fires for every input type before
26
+ * any mutation, so it can read the DOM range (via `posAtDOM`; `state.selection`
27
+ * is untrustworthy in that tick) and apply the clamped edit itself.
28
+ *
29
+ * `CellSelection` / `AllSelection` / `NodeSelection` are left alone. Select-all
30
+ * is an `AllSelection` in the base keymap; a `TextSelection` that merely
31
+ * contains a whole isolating node (both endpoints outside it) is not crossing.
32
+ */
33
+ import { Plugin, PluginKey, TextSelection } from 'prosemirror-state';
34
+ const key = new PluginKey('openleaf-isolating-selection');
35
+ /** Depth of the innermost isolating ancestor, or 0 if the pos sits in none. */
36
+ export function innermostIsolatingDepth($pos) {
37
+ for (let depth = $pos.depth; depth > 0; depth -= 1) {
38
+ if ($pos.node(depth).type.spec.isolating)
39
+ return depth;
40
+ }
41
+ return 0;
42
+ }
43
+ /**
44
+ * True when the endpoints do not share an isolating ancestor: one is inside a
45
+ * given isolating node and the other is not (or is inside a different one).
46
+ */
47
+ export function textSelectionCrossesIsolating(selection) {
48
+ if (!(selection instanceof TextSelection) || selection.empty)
49
+ return false;
50
+ return !sameIsolatingContext(selection.$from, selection.$to);
51
+ }
52
+ function sameIsolatingContext($a, $b) {
53
+ const depthA = innermostIsolatingDepth($a);
54
+ const depthB = innermostIsolatingDepth($b);
55
+ if (depthA === 0 && depthB === 0)
56
+ return true;
57
+ if (depthA === 0 || depthB === 0)
58
+ return false;
59
+ return $a.before(depthA) === $b.before(depthB);
60
+ }
61
+ /**
62
+ * Narrow a crossing text selection to the isolating context that contains the
63
+ * anchor, or to just outside the isolating node that contains the head when the
64
+ * anchor itself sits in none. Same-context selections are returned unchanged.
65
+ */
66
+ export function clampIsolatingTextSelection(selection) {
67
+ if (selection.empty || sameIsolatingContext(selection.$anchor, selection.$head)) {
68
+ return selection;
69
+ }
70
+ const { $anchor, $head } = selection;
71
+ const doc = $anchor.doc;
72
+ const anchorDepth = innermostIsolatingDepth($anchor);
73
+ if (anchorDepth > 0) {
74
+ const min = $anchor.start(anchorDepth);
75
+ const max = $anchor.end(anchorDepth);
76
+ const head = Math.max(min, Math.min(max, $head.pos));
77
+ if (head === $head.pos)
78
+ return selection;
79
+ const next = TextSelection.between($anchor, doc.resolve(head));
80
+ return next instanceof TextSelection ? next : selection;
81
+ }
82
+ const headDepth = innermostIsolatingDepth($head);
83
+ if (headDepth > 0) {
84
+ const before = $head.before(headDepth);
85
+ const after = $head.after(headDepth);
86
+ const boundary = $anchor.pos <= before ? before : after;
87
+ const next = TextSelection.between($anchor, doc.resolve(boundary));
88
+ return next instanceof TextSelection ? next : selection;
89
+ }
90
+ return selection;
91
+ }
92
+ /**
93
+ * Given a DOM-derived (anchor, head) pair — not necessarily `state.selection` —
94
+ * return the range a keystroke must replace so the edit stays on one side of an
95
+ * isolating boundary. `null` means the range does not cross and the default
96
+ * editor path should run.
97
+ */
98
+ export function clampIsolatingReplaceRange(doc, anchor, head) {
99
+ const size = doc.content.size;
100
+ const a = Math.max(0, Math.min(anchor, size));
101
+ const h = Math.max(0, Math.min(head, size));
102
+ if (a === h)
103
+ return null;
104
+ let oriented;
105
+ try {
106
+ oriented = TextSelection.create(doc, a, h);
107
+ }
108
+ catch {
109
+ return null;
110
+ }
111
+ if (!textSelectionCrossesIsolating(oriented))
112
+ return null;
113
+ const clamped = clampIsolatingTextSelection(oriented);
114
+ return {
115
+ from: Math.min(clamped.from, clamped.to),
116
+ to: Math.max(clamped.from, clamped.to),
117
+ };
118
+ }
119
+ function tryInsertText(view, from, to, text) {
120
+ try {
121
+ view.state.tr.insertText(text, from, to);
122
+ return true;
123
+ }
124
+ catch {
125
+ return false;
126
+ }
127
+ }
128
+ function textSelectionFromDOM(view) {
129
+ const sel = view.dom.ownerDocument.getSelection();
130
+ if (!sel || sel.rangeCount === 0 || !sel.anchorNode || !sel.focusNode)
131
+ return null;
132
+ if (!view.dom.contains(sel.anchorNode) || !view.dom.contains(sel.focusNode))
133
+ return null;
134
+ try {
135
+ const anchor = view.posAtDOM(sel.anchorNode, sel.anchorOffset);
136
+ const head = view.posAtDOM(sel.focusNode, sel.focusOffset);
137
+ return TextSelection.create(view.state.doc, anchor, head);
138
+ }
139
+ catch {
140
+ return null;
141
+ }
142
+ }
143
+ function handleIsolatingBeforeInput(view, event) {
144
+ if (!view.editable || !(event instanceof InputEvent))
145
+ return false;
146
+ // insertCompositionText is not cancelable. preventDefault is a no-op, and
147
+ // event.data is the whole composition on every update — committing that as
148
+ // document text duplicates IME candidates on top of the UA mutation.
149
+ if (!event.cancelable)
150
+ return false;
151
+ const type = event.inputType;
152
+ const inserting = type === 'insertText';
153
+ if (!inserting && type !== 'insertParagraph' && !type.startsWith('delete'))
154
+ return false;
155
+ const domSel = textSelectionFromDOM(view);
156
+ if (!domSel || domSel.empty)
157
+ return false;
158
+ const clamped = clampIsolatingReplaceRange(view.state.doc, domSel.anchor, domSel.head);
159
+ if (!clamped)
160
+ return false;
161
+ // Swallow the default. A crossing DOM range that reaches the browser becomes
162
+ // a parse-from-DOM repair, which is the #163 corruption.
163
+ event.preventDefault();
164
+ const { from, to } = clamped;
165
+ try {
166
+ if (inserting) {
167
+ const text = event.data ?? '';
168
+ if (!tryInsertText(view, from, to, text))
169
+ return true;
170
+ view.dispatch(view.state.tr.insertText(text, from, to).scrollIntoView());
171
+ return true;
172
+ }
173
+ // delete* and insertParagraph: drop the clamped span so Chromium cannot
174
+ // parse-from-DOM across the isolating node. Desktop Enter is usually eaten
175
+ // by the keymap before beforeinput; Android virtual Enter is this path.
176
+ view.dispatch(view.state.tr.delete(from, to).scrollIntoView());
177
+ return true;
178
+ }
179
+ catch {
180
+ return true;
181
+ }
182
+ }
183
+ export function isolatingSelectionPlugin() {
184
+ return new Plugin({
185
+ key,
186
+ appendTransaction(transactions, _oldState, newState) {
187
+ if (transactions.some((tr) => tr.getMeta(key)))
188
+ return null;
189
+ const { selection } = newState;
190
+ if (!(selection instanceof TextSelection) || selection.empty)
191
+ return null;
192
+ const clamped = clampIsolatingTextSelection(selection);
193
+ if (clamped.eq(selection))
194
+ return null;
195
+ return newState.tr.setSelection(clamped).setMeta(key, true);
196
+ },
197
+ props: {
198
+ /*
199
+ * `from`/`to` are the view's idea of the range at the moment of the
200
+ * input event. The DOM can still report a crossing range in the same
201
+ * tick as a keystroke, before `appendTransaction` has run, so the
202
+ * default `insertText` would throw. Building the transaction first is
203
+ * what keeps a throw from ever reaching ProseMirror's input handler:
204
+ * that handler does not catch, and the DOM-derived repair that follows
205
+ * is the corruption that cannot be undone.
206
+ */
207
+ handleTextInput(view, from, to, text) {
208
+ const { doc, selection } = view.state;
209
+ const size = doc.content.size;
210
+ const start = Math.max(0, Math.min(from, size));
211
+ const end = Math.max(start, Math.min(to, size));
212
+ const anchor = selection instanceof TextSelection && selection.anchor === end ? end : start;
213
+ const head = anchor === end ? start : end;
214
+ const clamped = start === end ? null : clampIsolatingReplaceRange(doc, anchor, head);
215
+ const replaceFrom = clamped?.from ?? start;
216
+ const replaceTo = clamped?.to ?? end;
217
+ if (!tryInsertText(view, replaceFrom, replaceTo, text))
218
+ return true;
219
+ if (replaceFrom === start && replaceTo === end)
220
+ return false;
221
+ view.dispatch(view.state.tr.insertText(text, replaceFrom, replaceTo).scrollIntoView());
222
+ return true;
223
+ },
224
+ handleDOMEvents: {
225
+ beforeinput(view, event) {
226
+ return handleIsolatingBeforeInput(view, event);
227
+ },
228
+ },
229
+ handleKeyDown(view, event) {
230
+ if (event.key !== 'Backspace' && event.key !== 'Delete' && event.key !== 'Enter') {
231
+ return false;
232
+ }
233
+ const { selection } = view.state;
234
+ if (!(selection instanceof TextSelection) || selection.empty)
235
+ return false;
236
+ if (!textSelectionCrossesIsolating(selection))
237
+ return false;
238
+ const clamped = clampIsolatingTextSelection(selection);
239
+ try {
240
+ view.state.tr.setSelection(clamped).deleteSelection();
241
+ }
242
+ catch {
243
+ return true;
244
+ }
245
+ view.dispatch(view.state.tr.setSelection(clamped));
246
+ return false;
247
+ },
248
+ },
249
+ });
250
+ }
251
+ //# 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":"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,CAmD1C"}
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"}
@@ -50,7 +50,19 @@ export function nonEditablePlugin() {
50
50
  * nothing at all: inserting a table column after inserting a row produces
51
51
  * exactly that shape, and the error was swallowed by the toolbar's guard.
52
52
  *
53
- * So each range is mapped back through the steps before it first.
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.
54
66
  */
55
67
  filterTransaction(tr, state) {
56
68
  if (!tr.docChanged)
@@ -62,13 +74,15 @@ export function nonEditablePlugin() {
62
74
  const step = tr.steps[i];
63
75
  if (!step)
64
76
  continue;
65
- const back = tr.mapping.slice(0, i).invert();
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;
66
81
  step.getMap().forEach((start, end) => {
67
82
  if (blocked)
68
83
  return;
69
- if (editsLockedInterior(state.doc, back.map(start, -1), back.map(end, 1))) {
84
+ if (editsLockedInterior(before, start, end))
70
85
  blocked = true;
71
- }
72
86
  });
73
87
  }
74
88
  return !blocked;
@@ -1 +1 @@
1
- {"version":3,"file":"noneditable.js","sourceRoot":"","sources":["../src/noneditable.ts"],"names":[],"mappings":"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"}
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,36 @@
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[];
30
60
  /**
31
61
  * `<source>` and `<track>`: media children the schema stores as markup rather
32
62
  * than as nodes, so they do not count as content when deciding what to keep.
@@ -67,23 +97,6 @@ export declare function scrub(el: Element): string;
67
97
  export declare function isLosslesslyUnwrappable(el: Element): boolean;
68
98
  /** Run `fn` with preserved-node serialization targeting this Document. */
69
99
  export declare function withSerializationDocument<T>(doc: Document, fn: () => T): T;
70
- /**
71
- * True while `serializeHtml` is running.
72
- *
73
- * A node whose `toDOM` needs to render differently for the editor than for the
74
- * saved HTML has no other way to tell which one it is building. The table spec
75
- * needs exactly that: a preserved `<caption>` must be `contenteditable="false"`
76
- * on screen, because it sits inside the editable area but outside the node's
77
- * `contentDOM`, and letting a caret into it means typing that ProseMirror will
78
- * silently revert. That attribute must NOT reach the saved HTML, where it would
79
- * be our editor scribbling on the author's markup.
80
- *
81
- * Stripping it afterwards was the other option and is worse: it cannot tell the
82
- * attribute it just added from the same attribute in somebody's document -- the
83
- * collision the preserved-element WeakSet above exists to avoid. Not emitting it
84
- * at all has no such failure mode.
85
- */
86
- export declare function isSerializing(): boolean;
87
100
  /**
88
101
  * The Document that serialization should build into.
89
102
  *
@@ -99,6 +112,24 @@ export declare function isInsidePreserved(node: Element | null): boolean;
99
112
  * delete it, but never edits its interior, so its markup cannot drift.
100
113
  */
101
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>;
102
133
  /**
103
134
  * Inline preserved content, for unrecognised markup appearing inside a
104
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;AA8CjD;;;;;;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,CAwBzC;AA0BD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,OAAO,GAAG,OAAO,CAkC5D;AAoBD,0EAA0E;AAC1E,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAQ1E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;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;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,QA8B3B,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"}