@bigbinary/neeto-editor 1.47.119 → 1.47.121

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 (96) hide show
  1. package/dist/Editor.js +60 -45
  2. package/dist/Editor.js.map +1 -1
  3. package/dist/EditorContent.js +3 -3
  4. package/dist/FormikEditor.js +8 -9
  5. package/dist/FormikEditor.js.map +1 -1
  6. package/dist/Menu.js +5 -7
  7. package/dist/Menu.js.map +1 -1
  8. package/dist/chunk-Bmhz4YEy.js +16777 -0
  9. package/dist/chunk-Bmhz4YEy.js.map +1 -0
  10. package/dist/{chunk-W5-WB6Fb.js → chunk-BwyS6si8.js} +3 -3
  11. package/dist/{chunk-W5-WB6Fb.js.map → chunk-BwyS6si8.js.map} +1 -1
  12. package/dist/{chunk-CBN5naeP.js → chunk-C5svTfyQ.js} +311 -146
  13. package/dist/chunk-C5svTfyQ.js.map +1 -0
  14. package/dist/{chunk-BmY70WOK.js → chunk-CHpkesFt.js} +10 -11
  15. package/dist/chunk-CHpkesFt.js.map +1 -0
  16. package/dist/{chunk-Ck5Gyhaq.js → chunk-COgPAsPy.js} +11 -12
  17. package/dist/chunk-COgPAsPy.js.map +1 -0
  18. package/dist/chunk-ChNzXvhJ.js +20357 -0
  19. package/dist/chunk-ChNzXvhJ.js.map +1 -0
  20. package/dist/{chunk-bG6hOjuU.js → chunk-CnsiyshR.js} +2 -2
  21. package/dist/{chunk-bG6hOjuU.js.map → chunk-CnsiyshR.js.map} +1 -1
  22. package/dist/{chunk-BR5ZkH7J.js → chunk-Qg4uQqj3.js} +2 -2
  23. package/dist/{chunk-BR5ZkH7J.js.map → chunk-Qg4uQqj3.js.map} +1 -1
  24. package/dist/{chunk-D_B4kuIc.js → chunk-aCTMceVU.js} +3 -3
  25. package/dist/{chunk-D_B4kuIc.js.map → chunk-aCTMceVU.js.map} +1 -1
  26. package/dist/{chunk-9TNlsObP.js → chunk-fDmcpgqx.js} +2 -2
  27. package/dist/{chunk-9TNlsObP.js.map → chunk-fDmcpgqx.js.map} +1 -1
  28. package/dist/cjs/Editor.cjs.js +109 -94
  29. package/dist/cjs/Editor.cjs.js.map +1 -1
  30. package/dist/cjs/EditorContent.cjs.js +3 -3
  31. package/dist/cjs/FormikEditor.cjs.js +8 -9
  32. package/dist/cjs/FormikEditor.cjs.js.map +1 -1
  33. package/dist/cjs/Menu.cjs.js +5 -7
  34. package/dist/cjs/Menu.cjs.js.map +1 -1
  35. package/dist/cjs/{chunk-4ILtbNxB.cjs.js → chunk-BGvf6C3z.cjs.js} +2 -2
  36. package/dist/cjs/{chunk-4ILtbNxB.cjs.js.map → chunk-BGvf6C3z.cjs.js.map} +1 -1
  37. package/dist/cjs/{chunk-De3nCFAF.cjs.js → chunk-BKvkHB8E.cjs.js} +2 -1
  38. package/dist/cjs/{chunk-De3nCFAF.cjs.js.map → chunk-BKvkHB8E.cjs.js.map} +1 -1
  39. package/dist/cjs/chunk-BXZTd0jZ.cjs.js +16844 -0
  40. package/dist/cjs/chunk-BXZTd0jZ.cjs.js.map +1 -0
  41. package/dist/cjs/{chunk-TrGAGew5.cjs.js → chunk-CesnwG-V.cjs.js} +3 -3
  42. package/dist/cjs/{chunk-TrGAGew5.cjs.js.map → chunk-CesnwG-V.cjs.js.map} +1 -1
  43. package/dist/cjs/chunk-DQoBksKy.cjs.js +20441 -0
  44. package/dist/cjs/chunk-DQoBksKy.cjs.js.map +1 -0
  45. package/dist/cjs/{chunk-DE_yHAbe.cjs.js → chunk-DS2JcxXk.cjs.js} +3 -3
  46. package/dist/cjs/{chunk-DE_yHAbe.cjs.js.map → chunk-DS2JcxXk.cjs.js.map} +1 -1
  47. package/dist/cjs/{chunk-JCA39oKB.cjs.js → chunk-DXsX8co9.cjs.js} +2 -2
  48. package/dist/cjs/{chunk-JCA39oKB.cjs.js.map → chunk-DXsX8co9.cjs.js.map} +1 -1
  49. package/dist/cjs/{chunk-Cqq9Q2Ty.cjs.js → chunk-DoYRXWHQ.cjs.js} +11 -12
  50. package/dist/cjs/chunk-DoYRXWHQ.cjs.js.map +1 -0
  51. package/dist/cjs/{chunk-DNpQGCaK.cjs.js → chunk-DpqV12Vi.cjs.js} +10 -11
  52. package/dist/cjs/chunk-DpqV12Vi.cjs.js.map +1 -0
  53. package/dist/cjs/{chunk-eyfbjfPH.cjs.js → chunk-NqciyXN3.cjs.js} +312 -147
  54. package/dist/cjs/chunk-NqciyXN3.cjs.js.map +1 -0
  55. package/dist/cjs/index.cjs.js +9 -10
  56. package/dist/cjs/index.cjs.js.map +1 -1
  57. package/dist/cjs/utils.cjs.js +5 -5
  58. package/dist/cjs/v2/Editor.cjs.js +95 -80
  59. package/dist/cjs/v2/Editor.cjs.js.map +1 -1
  60. package/dist/cjs/v2/EditorContent.cjs.js +3 -3
  61. package/dist/cjs/v2/FormikEditor.cjs.js +8 -9
  62. package/dist/cjs/v2/FormikEditor.cjs.js.map +1 -1
  63. package/dist/cjs/v2/Menu.cjs.js +5 -7
  64. package/dist/cjs/v2/Menu.cjs.js.map +1 -1
  65. package/dist/cjs/v2/index.cjs.js +11 -12
  66. package/dist/cjs/v2/index.cjs.js.map +1 -1
  67. package/dist/cjs/v2/utils.cjs.js +5 -5
  68. package/dist/editor-stats.html +1 -19
  69. package/dist/index.js +9 -10
  70. package/dist/index.js.map +1 -1
  71. package/dist/utils.js +5 -5
  72. package/dist/v2/Editor.js +61 -46
  73. package/dist/v2/Editor.js.map +1 -1
  74. package/dist/v2/EditorContent.js +3 -3
  75. package/dist/v2/FormikEditor.js +8 -9
  76. package/dist/v2/FormikEditor.js.map +1 -1
  77. package/dist/v2/Menu.js +5 -7
  78. package/dist/v2/Menu.js.map +1 -1
  79. package/dist/v2/index.js +11 -12
  80. package/dist/v2/index.js.map +1 -1
  81. package/dist/v2/utils.js +5 -5
  82. package/package.json +24 -31
  83. package/dist/chunk-BLXUWWgi.js +0 -15671
  84. package/dist/chunk-BLXUWWgi.js.map +0 -1
  85. package/dist/chunk-BmY70WOK.js.map +0 -1
  86. package/dist/chunk-CBN5naeP.js.map +0 -1
  87. package/dist/chunk-Ck5Gyhaq.js.map +0 -1
  88. package/dist/chunk-Dj7lS7Cs.js +0 -16980
  89. package/dist/chunk-Dj7lS7Cs.js.map +0 -1
  90. package/dist/cjs/chunk-Cqq9Q2Ty.cjs.js.map +0 -1
  91. package/dist/cjs/chunk-Cv0ocaVh.cjs.js +0 -15726
  92. package/dist/cjs/chunk-Cv0ocaVh.cjs.js.map +0 -1
  93. package/dist/cjs/chunk-DNpQGCaK.cjs.js.map +0 -1
  94. package/dist/cjs/chunk-DOxH3Agq.cjs.js +0 -17048
  95. package/dist/cjs/chunk-DOxH3Agq.cjs.js.map +0 -1
  96. package/dist/cjs/chunk-eyfbjfPH.cjs.js.map +0 -1
@@ -148,8 +148,11 @@ function findDiffStart(a, b, pos) {
148
148
  if (!childA.sameMarkup(childB))
149
149
  return pos;
150
150
  if (childA.isText && childA.text != childB.text) {
151
- for (let j = 0; childA.text[j] == childB.text[j]; j++)
151
+ let tA = childA.text, tB = childB.text, j = 0;
152
+ for (; tA[j] == tB[j]; j++)
152
153
  pos++;
154
+ if (j && j < tA.length && j < tB.length && surrogateHigh(tA.charCodeAt(j - 1)) && surrogateLow(tA.charCodeAt(j)))
155
+ pos--;
153
156
  return pos;
154
157
  }
155
158
  if (childA.content.size || childB.content.size) {
@@ -173,12 +176,17 @@ function findDiffEnd(a, b, posA, posB) {
173
176
  if (!childA.sameMarkup(childB))
174
177
  return { a: posA, b: posB };
175
178
  if (childA.isText && childA.text != childB.text) {
176
- let same = 0, minSize = Math.min(childA.text.length, childB.text.length);
177
- while (same < minSize && childA.text[childA.text.length - same - 1] == childB.text[childB.text.length - same - 1]) {
178
- same++;
179
+ let tA = childA.text, tB = childB.text, iA = tA.length, iB = tB.length;
180
+ while (iA > 0 && iB > 0 && tA[iA - 1] == tB[iB - 1]) {
181
+ iA--;
182
+ iB--;
179
183
  posA--;
180
184
  posB--;
181
185
  }
186
+ if (iA && iB && iA < tA.length && surrogateHigh(tA.charCodeAt(iA - 1)) && surrogateLow(tA.charCodeAt(iA))) {
187
+ posA++;
188
+ posB++;
189
+ }
182
190
  return { a: posA, b: posB };
183
191
  }
184
192
  if (childA.content.size || childB.content.size) {
@@ -190,6 +198,8 @@ function findDiffEnd(a, b, posA, posB) {
190
198
  posB -= size;
191
199
  }
192
200
  }
201
+ function surrogateLow(ch) { return ch >= 0xDC00 && ch < 0xE000; }
202
+ function surrogateHigh(ch) { return ch >= 0xD800 && ch < 0xDC00; }
193
203
 
194
204
  /**
195
205
  A fragment represents a node's collection of child nodes.
@@ -204,7 +214,7 @@ class Fragment {
204
214
  */
205
215
  constructor(
206
216
  /**
207
- @internal
217
+ The child nodes in this fragment.
208
218
  */
209
219
  content, size) {
210
220
  this.content = content;
@@ -408,7 +418,7 @@ class Fragment {
408
418
  position in this fragment. The result object will be reused
409
419
  (overwritten) the next time the function is called. @internal
410
420
  */
411
- findIndex(pos, round = -1) {
421
+ findIndex(pos) {
412
422
  if (pos == 0)
413
423
  return retIndex(0, pos);
414
424
  if (pos == this.size)
@@ -418,7 +428,7 @@ class Fragment {
418
428
  for (let i = 0, curPos = 0;; i++) {
419
429
  let cur = this.child(i), end = curPos + cur.nodeSize;
420
430
  if (end >= pos) {
421
- if (end == pos || round > 0)
431
+ if (end == pos)
422
432
  return retIndex(i + 1, end);
423
433
  return retIndex(i, curPos);
424
434
  }
@@ -447,7 +457,7 @@ class Fragment {
447
457
  return Fragment.empty;
448
458
  if (!Array.isArray(value))
449
459
  throw new RangeError("Invalid input for Fragment.fromJSON");
450
- return new Fragment(value.map(schema.nodeFromJSON));
460
+ return Fragment.fromArray(value.map(schema.nodeFromJSON));
451
461
  }
452
462
  /**
453
463
  Build a fragment from an array of nodes. Ensures that adjacent
@@ -681,17 +691,6 @@ given an invalid replacement.
681
691
  */
682
692
  class ReplaceError extends Error {
683
693
  }
684
- /*
685
- ReplaceError = function(this: any, message: string) {
686
- let err = Error.call(this, message)
687
- ;(err as any).__proto__ = ReplaceError.prototype
688
- return err
689
- } as any
690
-
691
- ReplaceError.prototype = Object.create(Error.prototype)
692
- ReplaceError.prototype.constructor = ReplaceError
693
- ReplaceError.prototype.name = "ReplaceError"
694
- */
695
694
  /**
696
695
  A slice represents a piece cut out of a larger document. It
697
696
  stores not only a fragment, but also the depth up to which nodes on
@@ -737,7 +736,7 @@ class Slice {
737
736
  @internal
738
737
  */
739
738
  insertAt(pos, fragment) {
740
- let content = insertInto(this.content, pos + this.openStart, fragment);
739
+ let content = insertInto(this.content, pos + this.openStart, fragment, this.openStart + 1, this.openEnd + 1);
741
740
  return content && new Slice(content, this.openStart, this.openEnd);
742
741
  }
743
742
  /**
@@ -811,12 +810,14 @@ function removeRange(content, from, to) {
811
810
  throw new RangeError("Removing non-flat range");
812
811
  return content.replaceChild(index, child.copy(removeRange(child.content, from - offset - 1, to - offset - 1)));
813
812
  }
814
- function insertInto(content, dist, insert, parent) {
813
+ function insertInto(content, dist, insert, openStart, openEnd, parent) {
815
814
  let { index, offset } = content.findIndex(dist), child = content.maybeChild(index);
816
815
  if (offset == dist || child.isText) {
816
+ if (parent && openStart <= 0 && openEnd <= 0 && !parent.canReplace(index, index, insert))
817
+ return null;
817
818
  return content.cut(0, dist).append(insert).append(content.cut(dist));
818
819
  }
819
- let inner = insertInto(child.content, dist - offset - 1, insert);
820
+ let inner = insertInto(child.content, dist - offset - 1, insert, index == 0 ? openStart - 1 : 0, index == content.childCount - 1 ? openEnd - 1 : 0, child);
820
821
  return inner && content.replaceChild(index, child.copy(inner));
821
822
  }
822
823
  function replace($from, $to, slice) {
@@ -879,7 +880,8 @@ function addRange($start, $end, depth, target) {
879
880
  addNode($end.nodeBefore, target);
880
881
  }
881
882
  function close(node, content) {
882
- node.type.checkContent(content);
883
+ if (!node.type.validContent(content))
884
+ throw new ReplaceError("Invalid content for node " + node.type.name);
883
885
  return node.copy(content);
884
886
  }
885
887
  function replaceThreeWay($from, $start, $end, $to, depth) {
@@ -1286,7 +1288,7 @@ structure between the old and new data as much as possible, which a
1286
1288
  tree shape like this (without back pointers) makes easy.
1287
1289
 
1288
1290
  **Do not** directly mutate the properties of a `Node` object. See
1289
- [the guide](/docs/guide/#doc) for more information.
1291
+ [the guide](https://prosemirror.net/docs/guide/#doc) for more information.
1290
1292
  */
1291
1293
  class Node {
1292
1294
  /**
@@ -1316,8 +1318,12 @@ class Node {
1316
1318
  this.content = content || Fragment.empty;
1317
1319
  }
1318
1320
  /**
1321
+ The array of this node's child nodes.
1322
+ */
1323
+ get children() { return this.content.content; }
1324
+ /**
1319
1325
  The size of this node, as defined by the integer-based [indexing
1320
- scheme](/docs/guide/#doc.indexing). For text nodes, this is the
1326
+ scheme](https://prosemirror.net/docs/guide/#doc.indexing). For text nodes, this is the
1321
1327
  amount of characters. For other leaf nodes, it is one. For
1322
1328
  non-leaf nodes, it is the size of the content plus two (the
1323
1329
  start and end token).
@@ -1342,10 +1348,11 @@ class Node {
1342
1348
  */
1343
1349
  forEach(f) { this.content.forEach(f); }
1344
1350
  /**
1345
- Invoke a callback for all descendant nodes recursively between
1351
+ Invoke a callback for all descendant nodes recursively overlapping
1346
1352
  the given two positions that are relative to start of this
1347
- node's content. The callback is invoked with the node, its
1348
- position relative to the original node (method receiver),
1353
+ node's content. This includes all ancestors of the nodes
1354
+ containing the two positions. The callback is invoked with the
1355
+ node, its position relative to the original node (method receiver),
1349
1356
  its parent node, and its child index. When the callback returns
1350
1357
  false for a given node, that node's children will not be
1351
1358
  recursed over. The last parameter can be used to specify a
@@ -1375,7 +1382,7 @@ class Node {
1375
1382
  `blockSeparator` is given, it will be inserted to separate text
1376
1383
  from different block nodes. If `leafText` is given, it'll be
1377
1384
  inserted for every non-text leaf node encountered, otherwise
1378
- [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec^leafText) will be used.
1385
+ [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec.leafText) will be used.
1379
1386
  */
1380
1387
  textBetween(from, to, blockSeparator, leafText) {
1381
1388
  return this.content.textBetween(from, to, blockSeparator, leafText);
@@ -1982,7 +1989,7 @@ function resolveName(stream, name) {
1982
1989
  let result = [];
1983
1990
  for (let typeName in types) {
1984
1991
  let type = types[typeName];
1985
- if (type.groups.indexOf(name) > -1)
1992
+ if (type.isInGroup(name))
1986
1993
  result.push(type);
1987
1994
  }
1988
1995
  if (result.length == 0)
@@ -2011,16 +2018,14 @@ function parseExprAtom(stream) {
2011
2018
  stream.err("Unexpected token '" + stream.next + "'");
2012
2019
  }
2013
2020
  }
2014
- /**
2015
- Construct an NFA from an expression as returned by the parser. The
2016
- NFA is represented as an array of states, which are themselves
2017
- arrays of edges, which are `{term, to}` objects. The first state is
2018
- the entry state and the last node is the success state.
2019
-
2020
- Note that unlike typical NFAs, the edge ordering in this one is
2021
- significant, in that it is used to contruct filler content when
2022
- necessary.
2023
- */
2021
+ // Construct an NFA from an expression as returned by the parser. The
2022
+ // NFA is represented as an array of states, which are themselves
2023
+ // arrays of edges, which are `{term, to}` objects. The first state is
2024
+ // the entry state and the last node is the success state.
2025
+ //
2026
+ // Note that unlike typical NFAs, the edge ordering in this one is
2027
+ // significant, in that it is used to contruct filler content when
2028
+ // necessary.
2024
2029
  function nfa(expr) {
2025
2030
  let nfa = [[]];
2026
2031
  connect(compile(expr, 0), node());
@@ -2187,13 +2192,12 @@ function computeAttrs(attrs, value) {
2187
2192
  return built;
2188
2193
  }
2189
2194
  function checkAttrs(attrs, values, type, name) {
2190
- for (let name in values)
2191
- if (!(name in attrs))
2192
- throw new RangeError(`Unsupported attribute ${name} for ${type} of type ${name}`);
2193
- for (let name in attrs) {
2194
- let attr = attrs[name];
2195
- if (attr.validate)
2196
- attr.validate(values[name]);
2195
+ for (let attr in values)
2196
+ if (!(attr in attrs))
2197
+ throw new RangeError(`Unsupported attribute ${attr} for ${type} of type ${name}`);
2198
+ for (let attr in attrs) {
2199
+ if (attrs[attr].validate)
2200
+ attrs[attr].validate(values[attr]);
2197
2201
  }
2198
2202
  }
2199
2203
  function initAttrs(typeName, attrs) {
@@ -2261,6 +2265,13 @@ class NodeType {
2261
2265
  */
2262
2266
  get isAtom() { return this.isLeaf || !!this.spec.atom; }
2263
2267
  /**
2268
+ Return true when this node type is part of the given
2269
+ [group](https://prosemirror.net/docs/ref/#model.NodeSpec.group).
2270
+ */
2271
+ isInGroup(group) {
2272
+ return this.groups.indexOf(group) > -1;
2273
+ }
2274
+ /**
2264
2275
  The node type's [whitespace](https://prosemirror.net/docs/ref/#model.NodeSpec.whitespace) option.
2265
2276
  */
2266
2277
  get whitespace() {
@@ -2580,8 +2591,8 @@ class Schema {
2580
2591
  let type = this.marks[prop], excl = type.spec.excludes;
2581
2592
  type.excluded = excl == null ? [type] : excl == "" ? [] : gatherMarks(this, excl.split(" "));
2582
2593
  }
2583
- this.nodeFromJSON = this.nodeFromJSON.bind(this);
2584
- this.markFromJSON = this.markFromJSON.bind(this);
2594
+ this.nodeFromJSON = json => Node.fromJSON(this, json);
2595
+ this.markFromJSON = json => Mark.fromJSON(this, json);
2585
2596
  this.topNodeType = this.nodes[this.spec.topNode || "doc"];
2586
2597
  this.cached.wrappings = Object.create(null);
2587
2598
  }
@@ -2617,20 +2628,6 @@ class Schema {
2617
2628
  return type.create(attrs);
2618
2629
  }
2619
2630
  /**
2620
- Deserialize a node from its JSON representation. This method is
2621
- bound.
2622
- */
2623
- nodeFromJSON(json) {
2624
- return Node.fromJSON(this, json);
2625
- }
2626
- /**
2627
- Deserialize a mark from its JSON representation. This method is
2628
- bound.
2629
- */
2630
- markFromJSON(json) {
2631
- return Mark.fromJSON(this, json);
2632
- }
2633
- /**
2634
2631
  @internal
2635
2632
  */
2636
2633
  nodeType(name) {
@@ -2812,7 +2809,7 @@ class DOMParser {
2812
2809
  /**
2813
2810
  Construct a DOM parser using the parsing rules listed in a
2814
2811
  schema's [node specs](https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM), reordered by
2815
- [priority](https://prosemirror.net/docs/ref/#model.ParseRule.priority).
2812
+ [priority](https://prosemirror.net/docs/ref/#model.GenericParseRule.priority).
2816
2813
  */
2817
2814
  static fromSchema(schema) {
2818
2815
  return schema.cached.domParser ||
@@ -2905,6 +2902,7 @@ class ParseContext {
2905
2902
  this.options = options;
2906
2903
  this.isOpen = isOpen;
2907
2904
  this.open = 0;
2905
+ this.localPreserveWS = false;
2908
2906
  let topNode = options.topNode, topContext;
2909
2907
  let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0);
2910
2908
  if (topNode)
@@ -2931,11 +2929,13 @@ class ParseContext {
2931
2929
  }
2932
2930
  addTextNode(dom, marks) {
2933
2931
  let value = dom.nodeValue;
2934
- let top = this.top;
2935
- if (top.options & OPT_PRESERVE_WS_FULL ||
2932
+ let top = this.top, preserveWS = (top.options & OPT_PRESERVE_WS_FULL) ? "full"
2933
+ : this.localPreserveWS || (top.options & OPT_PRESERVE_WS) > 0;
2934
+ let { schema } = this.parser;
2935
+ if (preserveWS === "full" ||
2936
2936
  top.inlineContext(dom) ||
2937
2937
  /[^ \t\r\n\u000c]/.test(value)) {
2938
- if (!(top.options & OPT_PRESERVE_WS)) {
2938
+ if (!preserveWS) {
2939
2939
  value = value.replace(/[ \t\r\n\u000c]+/g, " ");
2940
2940
  // If this starts with whitespace, and there is no node before it, or
2941
2941
  // a hard break, or a text node that ends with whitespace, strip the
@@ -2949,14 +2949,24 @@ class ParseContext {
2949
2949
  value = value.slice(1);
2950
2950
  }
2951
2951
  }
2952
- else if (!(top.options & OPT_PRESERVE_WS_FULL)) {
2953
- value = value.replace(/\r?\n|\r/g, " ");
2952
+ else if (preserveWS === "full") {
2953
+ value = value.replace(/\r\n?/g, "\n");
2954
+ }
2955
+ else if (schema.linebreakReplacement && /[\r\n]/.test(value) && this.top.findWrapping(schema.linebreakReplacement.create())) {
2956
+ let lines = value.split(/\r?\n|\r/);
2957
+ for (let i = 0; i < lines.length; i++) {
2958
+ if (i)
2959
+ this.insertNode(schema.linebreakReplacement.create(), marks, true);
2960
+ if (lines[i])
2961
+ this.insertNode(schema.text(lines[i]), marks, !/\S/.test(lines[i]));
2962
+ }
2963
+ value = "";
2954
2964
  }
2955
2965
  else {
2956
- value = value.replace(/\r\n?/g, "\n");
2966
+ value = value.replace(/\r?\n|\r/g, " ");
2957
2967
  }
2958
2968
  if (value)
2959
- this.insertNode(this.parser.schema.text(value), marks);
2969
+ this.insertNode(schema.text(value), marks, !/\S/.test(value));
2960
2970
  this.findInText(dom);
2961
2971
  }
2962
2972
  else {
@@ -2966,12 +2976,15 @@ class ParseContext {
2966
2976
  // Try to find a handler for the given tag and use that to parse. If
2967
2977
  // none is found, the element's content nodes are added directly.
2968
2978
  addElement(dom, marks, matchAfter) {
2979
+ let outerWS = this.localPreserveWS, top = this.top;
2980
+ if (dom.tagName == "PRE" || /pre/.test(dom.style && dom.style.whiteSpace))
2981
+ this.localPreserveWS = true;
2969
2982
  let name = dom.nodeName.toLowerCase(), ruleID;
2970
2983
  if (listTags.hasOwnProperty(name) && this.parser.normalizeLists)
2971
2984
  normalizeList(dom);
2972
2985
  let rule = (this.options.ruleFromNode && this.options.ruleFromNode(dom)) ||
2973
2986
  (ruleID = this.parser.matchTag(dom, this, matchAfter));
2974
- if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
2987
+ out: if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
2975
2988
  this.findInside(dom);
2976
2989
  this.ignoreFallback(dom, marks);
2977
2990
  }
@@ -2980,7 +2993,7 @@ class ParseContext {
2980
2993
  this.open = Math.max(0, this.open - 1);
2981
2994
  else if (rule && rule.skip.nodeType)
2982
2995
  dom = rule.skip;
2983
- let sync, top = this.top, oldNeedsBlock = this.needsBlock;
2996
+ let sync, oldNeedsBlock = this.needsBlock;
2984
2997
  if (blockTags.hasOwnProperty(name)) {
2985
2998
  if (top.content.length && top.content[0].isInline && this.open) {
2986
2999
  this.open--;
@@ -2992,7 +3005,7 @@ class ParseContext {
2992
3005
  }
2993
3006
  else if (!dom.firstChild) {
2994
3007
  this.leafFallback(dom, marks);
2995
- return;
3008
+ break out;
2996
3009
  }
2997
3010
  let innerMarks = rule && rule.skip ? marks : this.readStyles(dom, marks);
2998
3011
  if (innerMarks)
@@ -3006,6 +3019,7 @@ class ParseContext {
3006
3019
  if (innerMarks)
3007
3020
  this.addElementByRule(dom, rule, innerMarks, rule.consuming === false ? ruleID : undefined);
3008
3021
  }
3022
+ this.localPreserveWS = outerWS;
3009
3023
  }
3010
3024
  // Called for leaf DOM nodes that would otherwise be ignored
3011
3025
  leafFallback(dom, marks) {
@@ -3016,7 +3030,7 @@ class ParseContext {
3016
3030
  ignoreFallback(dom, marks) {
3017
3031
  // Ignored BR nodes should at least create an inline context
3018
3032
  if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent))
3019
- this.findPlace(this.parser.schema.text("-"), marks);
3033
+ this.findPlace(this.parser.schema.text("-"), marks, true);
3020
3034
  }
3021
3035
  // Run any style parser associated with the node's styles. Either
3022
3036
  // return an updated array of marks, or null to indicate some of the
@@ -3064,7 +3078,7 @@ class ParseContext {
3064
3078
  marks = inner;
3065
3079
  }
3066
3080
  }
3067
- else if (!this.insertNode(nodeType.create(rule.attrs), marks)) {
3081
+ else if (!this.insertNode(nodeType.create(rule.attrs), marks, dom.nodeName == "BR")) {
3068
3082
  this.leafFallback(dom, marks);
3069
3083
  }
3070
3084
  }
@@ -3081,7 +3095,7 @@ class ParseContext {
3081
3095
  }
3082
3096
  else if (rule.getContent) {
3083
3097
  this.findInside(dom);
3084
- rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks));
3098
+ rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks, false));
3085
3099
  }
3086
3100
  else {
3087
3101
  let contentDOM = dom;
@@ -3093,6 +3107,7 @@ class ParseContext {
3093
3107
  contentDOM = rule.contentElement;
3094
3108
  this.findAround(dom, contentDOM, true);
3095
3109
  this.addAll(contentDOM, marks);
3110
+ this.findAround(dom, contentDOM, false);
3096
3111
  }
3097
3112
  if (sync && this.sync(startIn))
3098
3113
  this.open--;
@@ -3111,19 +3126,22 @@ class ParseContext {
3111
3126
  // Try to find a way to fit the given node type into the current
3112
3127
  // context. May add intermediate wrappers and/or leave non-solid
3113
3128
  // nodes that we're in.
3114
- findPlace(node, marks) {
3129
+ findPlace(node, marks, cautious) {
3115
3130
  let route, sync;
3116
- for (let depth = this.open; depth >= 0; depth--) {
3131
+ for (let depth = this.open, penalty = 0; depth >= 0; depth--) {
3117
3132
  let cx = this.nodes[depth];
3118
3133
  let found = cx.findWrapping(node);
3119
- if (found && (!route || route.length > found.length)) {
3134
+ if (found && (!route || route.length > found.length + penalty)) {
3120
3135
  route = found;
3121
3136
  sync = cx;
3122
3137
  if (!found.length)
3123
3138
  break;
3124
3139
  }
3125
- if (cx.solid)
3126
- break;
3140
+ if (cx.solid) {
3141
+ if (cautious)
3142
+ break;
3143
+ penalty += 2;
3144
+ }
3127
3145
  }
3128
3146
  if (!route)
3129
3147
  return null;
@@ -3133,13 +3151,13 @@ class ParseContext {
3133
3151
  return marks;
3134
3152
  }
3135
3153
  // Try to insert the given node, adjusting the context when needed.
3136
- insertNode(node, marks) {
3154
+ insertNode(node, marks, cautious) {
3137
3155
  if (node.isInline && this.needsBlock && !this.top.type) {
3138
3156
  let block = this.textblockFromContext();
3139
3157
  if (block)
3140
3158
  marks = this.enterInner(block, null, marks);
3141
3159
  }
3142
- let innerMarks = this.findPlace(node, marks);
3160
+ let innerMarks = this.findPlace(node, marks, cautious);
3143
3161
  if (innerMarks) {
3144
3162
  this.closeExtra();
3145
3163
  let top = this.top;
@@ -3157,7 +3175,7 @@ class ParseContext {
3157
3175
  // Try to start a node of the given type, adjusting the context when
3158
3176
  // necessary.
3159
3177
  enter(type, attrs, marks, preserveWS) {
3160
- let innerMarks = this.findPlace(type.create(attrs), marks);
3178
+ let innerMarks = this.findPlace(type.create(attrs), marks, false);
3161
3179
  if (innerMarks)
3162
3180
  innerMarks = this.enterInner(type, attrs, marks, true, preserveWS);
3163
3181
  return innerMarks;
@@ -3195,14 +3213,18 @@ class ParseContext {
3195
3213
  finish() {
3196
3214
  this.open = 0;
3197
3215
  this.closeExtra(this.isOpen);
3198
- return this.nodes[0].finish(this.isOpen || this.options.topOpen);
3216
+ return this.nodes[0].finish(!!(this.isOpen || this.options.topOpen));
3199
3217
  }
3200
3218
  sync(to) {
3201
- for (let i = this.open; i >= 0; i--)
3219
+ for (let i = this.open; i >= 0; i--) {
3202
3220
  if (this.nodes[i] == to) {
3203
3221
  this.open = i;
3204
3222
  return true;
3205
3223
  }
3224
+ else if (this.localPreserveWS) {
3225
+ this.nodes[i].options |= OPT_PRESERVE_WS;
3226
+ }
3227
+ }
3206
3228
  return false;
3207
3229
  }
3208
3230
  get currentPos() {
@@ -3271,7 +3293,7 @@ class ParseContext {
3271
3293
  let next = depth > 0 || (depth == 0 && useRoot) ? this.nodes[depth].type
3272
3294
  : option && depth >= minDepth ? option.node(depth - minDepth).type
3273
3295
  : null;
3274
- if (!next || (next.name != part && next.groups.indexOf(part) == -1))
3296
+ if (!next || (next.name != part && !next.isInGroup(part)))
3275
3297
  return false;
3276
3298
  depth--;
3277
3299
  }
@@ -3417,6 +3439,8 @@ class DOMSerializer {
3417
3439
  @internal
3418
3440
  */
3419
3441
  serializeNodeInner(node, options) {
3442
+ if (node.isText)
3443
+ return doc(options).createTextNode(node.text);
3420
3444
  let { dom, contentDOM } = renderSpec(doc(options), this.nodes[node.type.name](node), null, node.attrs);
3421
3445
  if (contentDOM) {
3422
3446
  if (node.isLeaf)
@@ -3451,6 +3475,9 @@ class DOMSerializer {
3451
3475
  return toDOM && renderSpec(doc(options), toDOM(mark, inline), null, mark.attrs);
3452
3476
  }
3453
3477
  static renderSpec(doc, structure, xmlNS = null, blockArraysIn) {
3478
+ // Kludge for backwards-compatibility with accidental original behavious
3479
+ if (typeof structure == "string")
3480
+ return { dom: doc.createTextNode(structure) };
3454
3481
  return renderSpec(doc, structure, xmlNS, blockArraysIn);
3455
3482
  }
3456
3483
  /**
@@ -3522,11 +3549,9 @@ function suspiciousAttributesInner(attrs) {
3522
3549
  return result;
3523
3550
  }
3524
3551
  function renderSpec(doc, structure, xmlNS, blockArraysIn) {
3525
- if (typeof structure == "string")
3526
- return { dom: doc.createTextNode(structure) };
3527
- if (structure.nodeType != null)
3552
+ if (structure.nodeType == 1)
3528
3553
  return { dom: structure };
3529
- if (structure.dom && structure.dom.nodeType != null)
3554
+ if (structure.dom && structure.dom.nodeType == 1)
3530
3555
  return structure;
3531
3556
  let tagName = structure[0], suspicious;
3532
3557
  if (typeof tagName != "string")
@@ -3549,6 +3574,8 @@ function renderSpec(doc, structure, xmlNS, blockArraysIn) {
3549
3574
  let space = name.indexOf(" ");
3550
3575
  if (space > 0)
3551
3576
  dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
3577
+ else if (name == "style" && dom.style)
3578
+ dom.style.cssText = attrs[name];
3552
3579
  else
3553
3580
  dom.setAttribute(name, attrs[name]);
3554
3581
  }
@@ -3560,6 +3587,9 @@ function renderSpec(doc, structure, xmlNS, blockArraysIn) {
3560
3587
  throw new RangeError("Content hole must be the only child of its parent node");
3561
3588
  return { dom, contentDOM: dom };
3562
3589
  }
3590
+ else if (typeof child == "string") {
3591
+ dom.appendChild(doc.createTextNode(child));
3592
+ }
3563
3593
  else {
3564
3594
  let { dom: inner, contentDOM: innerContent } = renderSpec(doc, child, xmlNS, blockArraysIn);
3565
3595
  dom.appendChild(inner);
@@ -3758,18 +3788,14 @@ A mapping represents a pipeline of zero or more [step
3758
3788
  maps](https://prosemirror.net/docs/ref/#transform.StepMap). It has special provisions for losslessly
3759
3789
  handling mapping positions through a series of steps in which some
3760
3790
  steps are inverted versions of earlier steps. (This comes up when
3761
- ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for
3791
+ ‘[rebasing](https://prosemirror.net/docs/guide/#transform.rebasing)’ steps for
3762
3792
  collaboration or history management.)
3763
3793
  */
3764
3794
  class Mapping {
3765
3795
  /**
3766
3796
  Create a new mapping with the given position maps.
3767
3797
  */
3768
- constructor(
3769
- /**
3770
- The step maps in this mapping.
3771
- */
3772
- maps = [],
3798
+ constructor(maps,
3773
3799
  /**
3774
3800
  @internal
3775
3801
  */
@@ -3782,23 +3808,22 @@ class Mapping {
3782
3808
  /**
3783
3809
  The end position in the `maps` array.
3784
3810
  */
3785
- to = maps.length) {
3786
- this.maps = maps;
3811
+ to = maps ? maps.length : 0) {
3787
3812
  this.mirror = mirror;
3788
3813
  this.from = from;
3789
3814
  this.to = to;
3815
+ this._maps = maps || [];
3816
+ this.ownData = !(maps || mirror);
3790
3817
  }
3791
3818
  /**
3792
- Create a mapping that maps only through a part of this one.
3819
+ The step maps in this mapping.
3793
3820
  */
3794
- slice(from = 0, to = this.maps.length) {
3795
- return new Mapping(this.maps, this.mirror, from, to);
3796
- }
3821
+ get maps() { return this._maps; }
3797
3822
  /**
3798
- @internal
3823
+ Create a mapping that maps only through a part of this one.
3799
3824
  */
3800
- copy() {
3801
- return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to);
3825
+ slice(from = 0, to = this.maps.length) {
3826
+ return new Mapping(this._maps, this.mirror, from, to);
3802
3827
  }
3803
3828
  /**
3804
3829
  Add a step map to the end of this mapping. If `mirrors` is
@@ -3806,18 +3831,23 @@ class Mapping {
3806
3831
  image of this one.
3807
3832
  */
3808
3833
  appendMap(map, mirrors) {
3809
- this.to = this.maps.push(map);
3834
+ if (!this.ownData) {
3835
+ this._maps = this._maps.slice();
3836
+ this.mirror = this.mirror && this.mirror.slice();
3837
+ this.ownData = true;
3838
+ }
3839
+ this.to = this._maps.push(map);
3810
3840
  if (mirrors != null)
3811
- this.setMirror(this.maps.length - 1, mirrors);
3841
+ this.setMirror(this._maps.length - 1, mirrors);
3812
3842
  }
3813
3843
  /**
3814
3844
  Add all the step maps in a given mapping to this one (preserving
3815
3845
  mirroring information).
3816
3846
  */
3817
3847
  appendMapping(mapping) {
3818
- for (let i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) {
3848
+ for (let i = 0, startSize = this._maps.length; i < mapping._maps.length; i++) {
3819
3849
  let mirr = mapping.getMirror(i);
3820
- this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : undefined);
3850
+ this.appendMap(mapping._maps[i], mirr != null && mirr < i ? startSize + mirr : undefined);
3821
3851
  }
3822
3852
  }
3823
3853
  /**
@@ -3843,9 +3873,9 @@ class Mapping {
3843
3873
  Append the inverse of the given mapping to this one.
3844
3874
  */
3845
3875
  appendMappingInverted(mapping) {
3846
- for (let i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) {
3876
+ for (let i = mapping.maps.length - 1, totalSize = this._maps.length + mapping._maps.length; i >= 0; i--) {
3847
3877
  let mirr = mapping.getMirror(i);
3848
- this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : undefined);
3878
+ this.appendMap(mapping._maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : undefined);
3849
3879
  }
3850
3880
  }
3851
3881
  /**
@@ -3863,7 +3893,7 @@ class Mapping {
3863
3893
  if (this.mirror)
3864
3894
  return this._map(pos, assoc, true);
3865
3895
  for (let i = this.from; i < this.to; i++)
3866
- pos = this.maps[i].map(pos, assoc);
3896
+ pos = this._maps[i].map(pos, assoc);
3867
3897
  return pos;
3868
3898
  }
3869
3899
  /**
@@ -3877,12 +3907,12 @@ class Mapping {
3877
3907
  _map(pos, assoc, simple) {
3878
3908
  let delInfo = 0;
3879
3909
  for (let i = this.from; i < this.to; i++) {
3880
- let map = this.maps[i], result = map.mapResult(pos, assoc);
3910
+ let map = this._maps[i], result = map.mapResult(pos, assoc);
3881
3911
  if (result.recover != null) {
3882
3912
  let corr = this.getMirror(i);
3883
3913
  if (corr != null && corr > i && corr < this.to) {
3884
3914
  i = corr;
3885
- pos = this.maps[corr].recover(result.recover);
3915
+ pos = this._maps[corr].recover(result.recover);
3886
3916
  continue;
3887
3917
  }
3888
3918
  }
@@ -4284,10 +4314,11 @@ class ReplaceStep extends Step {
4284
4314
  return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to));
4285
4315
  }
4286
4316
  map(mapping) {
4287
- let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
4317
+ let to = mapping.mapResult(this.to, -1);
4318
+ let from = this.from == this.to && ReplaceStep.MAP_BIAS < 0 ? to : mapping.mapResult(this.from, 1);
4288
4319
  if (from.deletedAcross && to.deletedAcross)
4289
4320
  return null;
4290
- return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice);
4321
+ return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice, this.structure);
4291
4322
  }
4292
4323
  merge(other) {
4293
4324
  if (!(other instanceof ReplaceStep) || other.structure || this.structure)
@@ -4323,6 +4354,15 @@ class ReplaceStep extends Step {
4323
4354
  return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure);
4324
4355
  }
4325
4356
  }
4357
+ /**
4358
+ By default, for backwards compatibility, an inserting step
4359
+ mapped over an insertion at that same position fill move after
4360
+ the inserted content. In a collaborative editing situation, that
4361
+ can make redone insertions appear in unexpected places. You can
4362
+ set this to -1 to make such mapping keep the step before the
4363
+ insertion instead.
4364
+ */
4365
+ ReplaceStep.MAP_BIAS = 1;
4326
4366
  Step.jsonID("replace", ReplaceStep);
4327
4367
  /**
4328
4368
  Replace a part of the document with a slice of content, but
@@ -4397,7 +4437,8 @@ class ReplaceAroundStep extends Step {
4397
4437
  }
4398
4438
  map(mapping) {
4399
4439
  let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
4400
- let gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1);
4440
+ let gapFrom = this.from == this.gapFrom ? from.pos : mapping.map(this.gapFrom, -1);
4441
+ let gapTo = this.to == this.gapTo ? to.pos : mapping.map(this.gapTo, 1);
4401
4442
  if ((from.deletedAcross && to.deletedAcross) || gapFrom < from.pos || gapTo > to.pos)
4402
4443
  return null;
4403
4444
  return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure);
@@ -4509,7 +4550,7 @@ function removeMark(tr, from, to, mark) {
4509
4550
  });
4510
4551
  matched.forEach(m => tr.step(new RemoveMarkStep(m.from, m.to, m.style)));
4511
4552
  }
4512
- function clearIncompatible(tr, pos, parentType, match = parentType.contentMatch) {
4553
+ function clearIncompatible(tr, pos, parentType, match = parentType.contentMatch, clearNewlines = true) {
4513
4554
  let node = tr.doc.nodeAt(pos);
4514
4555
  let replSteps = [], cur = pos + 1;
4515
4556
  for (let i = 0; i < node.childCount; i++) {
@@ -4523,7 +4564,7 @@ function clearIncompatible(tr, pos, parentType, match = parentType.contentMatch)
4523
4564
  for (let j = 0; j < child.marks.length; j++)
4524
4565
  if (!parentType.allowsMarkType(child.marks[j].type))
4525
4566
  tr.step(new RemoveMarkStep(cur, end, child.marks[j]));
4526
- if (child.isText && !parentType.spec.code) {
4567
+ if (clearNewlines && child.isText && parentType.whitespace != "pre") {
4527
4568
  let m, newline = /\r?\n|\r/g, slice;
4528
4569
  while (m = newline.exec(child.text)) {
4529
4570
  if (!slice)
@@ -4554,13 +4595,17 @@ can be lifted. Will not go across
4554
4595
  function liftTarget(range) {
4555
4596
  let parent = range.parent;
4556
4597
  let content = parent.content.cutByIndex(range.startIndex, range.endIndex);
4557
- for (let depth = range.depth;; --depth) {
4598
+ for (let depth = range.depth, contentBefore = 0, contentAfter = 0;; --depth) {
4558
4599
  let node = range.$from.node(depth);
4559
- let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth);
4600
+ let index = range.$from.index(depth) + contentBefore, endIndex = range.$to.indexAfter(depth) - contentAfter;
4560
4601
  if (depth < range.depth && node.canReplace(index, endIndex, content))
4561
4602
  return depth;
4562
4603
  if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex))
4563
4604
  break;
4605
+ if (index)
4606
+ contentBefore = 1;
4607
+ if (endIndex < node.childCount)
4608
+ contentAfter = 1;
4564
4609
  }
4565
4610
  return null;
4566
4611
  }
@@ -4647,16 +4692,49 @@ function setBlockType(tr, from, to, type, attrs) {
4647
4692
  throw new RangeError("Type given to setBlockType should be a textblock");
4648
4693
  let mapFrom = tr.steps.length;
4649
4694
  tr.doc.nodesBetween(from, to, (node, pos) => {
4650
- if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(tr.doc, tr.mapping.slice(mapFrom).map(pos), type)) {
4695
+ let attrsHere = typeof attrs == "function" ? attrs(node) : attrs;
4696
+ if (node.isTextblock && !node.hasMarkup(type, attrsHere) &&
4697
+ canChangeType(tr.doc, tr.mapping.slice(mapFrom).map(pos), type)) {
4698
+ let convertNewlines = null;
4699
+ if (type.schema.linebreakReplacement) {
4700
+ let pre = type.whitespace == "pre", supportLinebreak = !!type.contentMatch.matchType(type.schema.linebreakReplacement);
4701
+ if (pre && !supportLinebreak)
4702
+ convertNewlines = false;
4703
+ else if (!pre && supportLinebreak)
4704
+ convertNewlines = true;
4705
+ }
4651
4706
  // Ensure all markup that isn't allowed in the new node type is cleared
4652
- tr.clearIncompatible(tr.mapping.slice(mapFrom).map(pos, 1), type);
4707
+ if (convertNewlines === false)
4708
+ replaceLinebreaks(tr, node, pos, mapFrom);
4709
+ clearIncompatible(tr, tr.mapping.slice(mapFrom).map(pos, 1), type, undefined, convertNewlines === null);
4653
4710
  let mapping = tr.mapping.slice(mapFrom);
4654
4711
  let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1);
4655
- tr.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, new Slice(Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true));
4712
+ tr.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, new Slice(Fragment.from(type.create(attrsHere, null, node.marks)), 0, 0), 1, true));
4713
+ if (convertNewlines === true)
4714
+ replaceNewlines(tr, node, pos, mapFrom);
4656
4715
  return false;
4657
4716
  }
4658
4717
  });
4659
4718
  }
4719
+ function replaceNewlines(tr, node, pos, mapFrom) {
4720
+ node.forEach((child, offset) => {
4721
+ if (child.isText) {
4722
+ let m, newline = /\r?\n|\r/g;
4723
+ while (m = newline.exec(child.text)) {
4724
+ let start = tr.mapping.slice(mapFrom).map(pos + 1 + offset + m.index);
4725
+ tr.replaceWith(start, start + 1, node.type.schema.linebreakReplacement.create());
4726
+ }
4727
+ }
4728
+ });
4729
+ }
4730
+ function replaceLinebreaks(tr, node, pos, mapFrom) {
4731
+ node.forEach((child, offset) => {
4732
+ if (child.type == child.type.schema.linebreakReplacement) {
4733
+ let start = tr.mapping.slice(mapFrom).map(pos + 1 + offset);
4734
+ tr.replaceWith(start, start + 1, node.type.schema.text("\n"));
4735
+ }
4736
+ });
4737
+ }
4660
4738
  function canChangeType(doc, pos, type) {
4661
4739
  let $pos = doc.resolve(pos), index = $pos.index();
4662
4740
  return $pos.parent.canReplaceWith(index, index + 1, type);
@@ -4722,8 +4800,24 @@ function canJoin(doc, pos) {
4722
4800
  return joinable($pos.nodeBefore, $pos.nodeAfter) &&
4723
4801
  $pos.parent.canReplace(index, index + 1);
4724
4802
  }
4803
+ function canAppendWithSubstitutedLinebreaks(a, b) {
4804
+ if (!b.content.size)
4805
+ a.type.compatibleContent(b.type);
4806
+ let match = a.contentMatchAt(a.childCount);
4807
+ let { linebreakReplacement } = a.type.schema;
4808
+ for (let i = 0; i < b.childCount; i++) {
4809
+ let child = b.child(i);
4810
+ let type = child.type == linebreakReplacement ? a.type.schema.nodes.text : child.type;
4811
+ match = match.matchType(type);
4812
+ if (!match)
4813
+ return false;
4814
+ if (!a.type.allowsMarks(child.marks))
4815
+ return false;
4816
+ }
4817
+ return match.validEnd;
4818
+ }
4725
4819
  function joinable(a, b) {
4726
- return !!(a && b && !a.isLeaf && a.canAppend(b));
4820
+ return !!(a && b && !a.isLeaf && canAppendWithSubstitutedLinebreaks(a, b));
4727
4821
  }
4728
4822
  /**
4729
4823
  Find an ancestor of the given position that can be joined to the
@@ -4756,8 +4850,31 @@ function joinPoint(doc, pos, dir = -1) {
4756
4850
  }
4757
4851
  }
4758
4852
  function join(tr, pos, depth) {
4759
- let step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true);
4760
- tr.step(step);
4853
+ let convertNewlines = null;
4854
+ let { linebreakReplacement } = tr.doc.type.schema;
4855
+ let $before = tr.doc.resolve(pos - depth), beforeType = $before.node().type;
4856
+ if (linebreakReplacement && beforeType.inlineContent) {
4857
+ let pre = beforeType.whitespace == "pre";
4858
+ let supportLinebreak = !!beforeType.contentMatch.matchType(linebreakReplacement);
4859
+ if (pre && !supportLinebreak)
4860
+ convertNewlines = false;
4861
+ else if (!pre && supportLinebreak)
4862
+ convertNewlines = true;
4863
+ }
4864
+ let mapFrom = tr.steps.length;
4865
+ if (convertNewlines === false) {
4866
+ let $after = tr.doc.resolve(pos + depth);
4867
+ replaceLinebreaks(tr, $after.node(), $after.before(), mapFrom);
4868
+ }
4869
+ if (beforeType.inlineContent)
4870
+ clearIncompatible(tr, pos + depth - 1, beforeType, $before.node().contentMatchAt($before.index()), convertNewlines == null);
4871
+ let mapping = tr.mapping.slice(mapFrom), start = mapping.map(pos - depth);
4872
+ tr.step(new ReplaceStep(start, mapping.map(pos + depth, -1), Slice.empty, true));
4873
+ if (convertNewlines === true) {
4874
+ let $full = tr.doc.resolve(start);
4875
+ replaceNewlines(tr, $full.node(), $full.before(), tr.steps.length);
4876
+ }
4877
+ return tr;
4761
4878
  }
4762
4879
  /**
4763
4880
  Try to find a point where a node of the given type can be inserted
@@ -5139,7 +5256,7 @@ function replaceRange(tr, from, to, slice) {
5139
5256
  let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to);
5140
5257
  if (fitsTrivially($from, $to, slice))
5141
5258
  return tr.step(new ReplaceStep(from, to, slice));
5142
- let targetDepths = coveredDepths($from, tr.doc.resolve(to));
5259
+ let targetDepths = coveredDepths($from, $to);
5143
5260
  // Can't replace the whole document, so remove 0 if it's present
5144
5261
  if (targetDepths[targetDepths.length - 1] == 0)
5145
5262
  targetDepths.pop();
@@ -5232,6 +5349,26 @@ function replaceRangeWith(tr, from, to, node) {
5232
5349
  }
5233
5350
  function deleteRange(tr, from, to) {
5234
5351
  let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to);
5352
+ // When the deleted range spans from the start of one textblock to
5353
+ // the start of another one, move out of the start of both blocks.
5354
+ if ($from.parent.isTextblock && $to.parent.isTextblock && $from.start() != $to.start() &&
5355
+ $from.parentOffset == 0 && $to.parentOffset == 0) {
5356
+ let shared = $from.sharedDepth(to), isolated = false;
5357
+ for (let d = $from.depth; d > shared; d--)
5358
+ if ($from.node(d).type.spec.isolating)
5359
+ isolated = true;
5360
+ for (let d = $to.depth; d > shared; d--)
5361
+ if ($to.node(d).type.spec.isolating)
5362
+ isolated = true;
5363
+ if (!isolated) {
5364
+ for (let d = $from.depth; d > 0 && from == $from.start(d); d--)
5365
+ from = $from.before(d);
5366
+ for (let d = $to.depth; d > 0 && to == $to.start(d); d--)
5367
+ to = $to.before(d);
5368
+ $from = tr.doc.resolve(from);
5369
+ $to = tr.doc.resolve(to);
5370
+ }
5371
+ }
5235
5372
  let covered = coveredDepths($from, $to);
5236
5373
  for (let i = 0; i < covered.length; i++) {
5237
5374
  let depth = covered[i], last = i == covered.length - 1;
@@ -5241,7 +5378,8 @@ function deleteRange(tr, from, to) {
5241
5378
  return tr.delete($from.before(depth), $to.after(depth));
5242
5379
  }
5243
5380
  for (let d = 1; d <= $from.depth && d <= $to.depth; d++) {
5244
- if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d)
5381
+ if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d &&
5382
+ $from.start(d - 1) == $to.start(d - 1) && $from.node(d - 1).canReplace($from.index(d - 1), $to.index(d - 1)))
5245
5383
  return tr.delete($from.before(d), to);
5246
5384
  }
5247
5385
  tr.delete(from, to);
@@ -5441,6 +5579,27 @@ class Transform {
5441
5579
  return this.steps.length > 0;
5442
5580
  }
5443
5581
  /**
5582
+ Return a single range, in post-transform document positions,
5583
+ that covers all content changed by this transform. Returns null
5584
+ if no replacements are made. Note that this will ignore changes
5585
+ that add/remove marks without replacing the underlying content.
5586
+ */
5587
+ changedRange() {
5588
+ let from = 1e9, to = -1e9;
5589
+ for (let i = 0; i < this.mapping.maps.length; i++) {
5590
+ let map = this.mapping.maps[i];
5591
+ if (i) {
5592
+ from = map.map(from, 1);
5593
+ to = map.map(to, -1);
5594
+ }
5595
+ map.forEach((_f, _t, fromB, toB) => {
5596
+ from = Math.min(from, fromB);
5597
+ to = Math.max(to, toB);
5598
+ });
5599
+ }
5600
+ return from == 1e9 ? null : { from, to };
5601
+ }
5602
+ /**
5444
5603
  @internal
5445
5604
  */
5446
5605
  addStep(step, doc) {
@@ -5590,19 +5749,26 @@ class Transform {
5590
5749
  return this;
5591
5750
  }
5592
5751
  /**
5593
- Remove a mark (or a mark of the given type) from the node at
5752
+ Remove a mark (or all marks of the given type) from the node at
5594
5753
  position `pos`.
5595
5754
  */
5596
5755
  removeNodeMark(pos, mark) {
5597
- if (!(mark instanceof Mark)) {
5598
- let node = this.doc.nodeAt(pos);
5599
- if (!node)
5600
- throw new RangeError("No node at position " + pos);
5601
- mark = mark.isInSet(node.marks);
5602
- if (!mark)
5603
- return this;
5756
+ let node = this.doc.nodeAt(pos);
5757
+ if (!node)
5758
+ throw new RangeError("No node at position " + pos);
5759
+ if (mark instanceof Mark) {
5760
+ if (mark.isInSet(node.marks))
5761
+ this.step(new RemoveNodeMarkStep(pos, mark));
5762
+ }
5763
+ else {
5764
+ let set = node.marks, found, steps = [];
5765
+ while (found = mark.isInSet(set)) {
5766
+ steps.push(new RemoveNodeMarkStep(pos, found));
5767
+ set = found.removeFromSet(set);
5768
+ }
5769
+ for (let i = steps.length - 1; i >= 0; i--)
5770
+ this.step(steps[i]);
5604
5771
  }
5605
- this.step(new RemoveNodeMarkStep(pos, mark));
5606
5772
  return this;
5607
5773
  }
5608
5774
  /**
@@ -5610,7 +5776,7 @@ class Transform {
5610
5776
  greater than one, any number of nodes above that. By default, the
5611
5777
  parts split off will inherit the node type of the original node.
5612
5778
  This can be changed by passing an array of types and attributes to
5613
- use after the split.
5779
+ use after the split (with the outermost nodes coming first).
5614
5780
  */
5615
5781
  split(pos, depth = 1, typesAfter) {
5616
5782
  split(this, pos, depth, typesAfter);
@@ -6278,7 +6444,6 @@ class Transaction extends Transform {
6278
6444
  else {
6279
6445
  if (to == null)
6280
6446
  to = from;
6281
- to = to == null ? from : to;
6282
6447
  if (!text)
6283
6448
  return this.deleteRange(from, to);
6284
6449
  let marks = this.storedMarks;
@@ -6287,7 +6452,7 @@ class Transaction extends Transform {
6287
6452
  marks = to == from ? $from.marks() : $from.marksAcross(this.doc.resolve(to));
6288
6453
  }
6289
6454
  this.replaceRangeWith(from, to, schema.text(text, marks));
6290
- if (!this.selection.empty)
6455
+ if (!this.selection.empty && this.selection.to == from + text.length)
6291
6456
  this.setSelection(Selection.near(this.selection.$to));
6292
6457
  return this;
6293
6458
  }
@@ -6483,7 +6648,7 @@ class EditorState {
6483
6648
  return newInstance;
6484
6649
  }
6485
6650
  /**
6486
- Start a [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state.
6651
+ Accessor that constructs and returns a new [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state.
6487
6652
  */
6488
6653
  get tr() { return new Transaction(this); }
6489
6654
  /**
@@ -6651,20 +6816,20 @@ exports.EditorState = EditorState;
6651
6816
  exports.Fragment = Fragment;
6652
6817
  exports.Mapping = Mapping;
6653
6818
  exports.Mark = Mark;
6654
- exports.MarkType = MarkType;
6655
6819
  exports.Node = Node;
6656
6820
  exports.NodeRange = NodeRange;
6657
6821
  exports.NodeSelection = NodeSelection;
6658
6822
  exports.Plugin = Plugin;
6659
6823
  exports.PluginKey = PluginKey;
6824
+ exports.RemoveMarkStep = RemoveMarkStep;
6660
6825
  exports.ReplaceAroundStep = ReplaceAroundStep;
6661
- exports.ReplaceError = ReplaceError;
6662
6826
  exports.ReplaceStep = ReplaceStep;
6663
6827
  exports.Schema = Schema;
6664
6828
  exports.Selection = Selection;
6665
6829
  exports.SelectionRange = SelectionRange;
6666
6830
  exports.Slice = Slice;
6667
6831
  exports.TextSelection = TextSelection;
6832
+ exports.Transform = Transform;
6668
6833
  exports.canJoin = canJoin;
6669
6834
  exports.canSplit = canSplit;
6670
6835
  exports.dropPoint = dropPoint;
@@ -6672,4 +6837,4 @@ exports.findWrapping = findWrapping;
6672
6837
  exports.joinPoint = joinPoint;
6673
6838
  exports.liftTarget = liftTarget;
6674
6839
  exports.replaceStep = replaceStep;
6675
- //# sourceMappingURL=chunk-eyfbjfPH.cjs.js.map
6840
+ //# sourceMappingURL=chunk-NqciyXN3.cjs.js.map