@bigbinary/neeto-editor 1.47.120 → 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-B0_4S6ol.js → chunk-COgPAsPy.js} +10 -11
  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-BFfrwCXy.cjs.js → chunk-DoYRXWHQ.cjs.js} +10 -11
  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 +94 -79
  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 +7 -8
  62. package/dist/cjs/v2/FormikEditor.cjs.js.map +1 -1
  63. package/dist/cjs/v2/Menu.cjs.js +4 -6
  64. package/dist/cjs/v2/Menu.cjs.js.map +1 -1
  65. package/dist/cjs/v2/index.cjs.js +10 -11
  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 -1
  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 +60 -45
  73. package/dist/v2/Editor.js.map +1 -1
  74. package/dist/v2/EditorContent.js +3 -3
  75. package/dist/v2/FormikEditor.js +7 -8
  76. package/dist/v2/FormikEditor.js.map +1 -1
  77. package/dist/v2/Menu.js +4 -6
  78. package/dist/v2/Menu.js.map +1 -1
  79. package/dist/v2/index.js +10 -11
  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-B0_4S6ol.js.map +0 -1
  84. package/dist/chunk-BLXUWWgi.js +0 -15671
  85. package/dist/chunk-BLXUWWgi.js.map +0 -1
  86. package/dist/chunk-BmY70WOK.js.map +0 -1
  87. package/dist/chunk-CBN5naeP.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-BFfrwCXy.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
@@ -146,8 +146,11 @@ function findDiffStart(a, b, pos) {
146
146
  if (!childA.sameMarkup(childB))
147
147
  return pos;
148
148
  if (childA.isText && childA.text != childB.text) {
149
- for (let j = 0; childA.text[j] == childB.text[j]; j++)
149
+ let tA = childA.text, tB = childB.text, j = 0;
150
+ for (; tA[j] == tB[j]; j++)
150
151
  pos++;
152
+ if (j && j < tA.length && j < tB.length && surrogateHigh(tA.charCodeAt(j - 1)) && surrogateLow(tA.charCodeAt(j)))
153
+ pos--;
151
154
  return pos;
152
155
  }
153
156
  if (childA.content.size || childB.content.size) {
@@ -171,12 +174,17 @@ function findDiffEnd(a, b, posA, posB) {
171
174
  if (!childA.sameMarkup(childB))
172
175
  return { a: posA, b: posB };
173
176
  if (childA.isText && childA.text != childB.text) {
174
- let same = 0, minSize = Math.min(childA.text.length, childB.text.length);
175
- while (same < minSize && childA.text[childA.text.length - same - 1] == childB.text[childB.text.length - same - 1]) {
176
- same++;
177
+ let tA = childA.text, tB = childB.text, iA = tA.length, iB = tB.length;
178
+ while (iA > 0 && iB > 0 && tA[iA - 1] == tB[iB - 1]) {
179
+ iA--;
180
+ iB--;
177
181
  posA--;
178
182
  posB--;
179
183
  }
184
+ if (iA && iB && iA < tA.length && surrogateHigh(tA.charCodeAt(iA - 1)) && surrogateLow(tA.charCodeAt(iA))) {
185
+ posA++;
186
+ posB++;
187
+ }
180
188
  return { a: posA, b: posB };
181
189
  }
182
190
  if (childA.content.size || childB.content.size) {
@@ -188,6 +196,8 @@ function findDiffEnd(a, b, posA, posB) {
188
196
  posB -= size;
189
197
  }
190
198
  }
199
+ function surrogateLow(ch) { return ch >= 0xDC00 && ch < 0xE000; }
200
+ function surrogateHigh(ch) { return ch >= 0xD800 && ch < 0xDC00; }
191
201
 
192
202
  /**
193
203
  A fragment represents a node's collection of child nodes.
@@ -202,7 +212,7 @@ class Fragment {
202
212
  */
203
213
  constructor(
204
214
  /**
205
- @internal
215
+ The child nodes in this fragment.
206
216
  */
207
217
  content, size) {
208
218
  this.content = content;
@@ -406,7 +416,7 @@ class Fragment {
406
416
  position in this fragment. The result object will be reused
407
417
  (overwritten) the next time the function is called. @internal
408
418
  */
409
- findIndex(pos, round = -1) {
419
+ findIndex(pos) {
410
420
  if (pos == 0)
411
421
  return retIndex(0, pos);
412
422
  if (pos == this.size)
@@ -416,7 +426,7 @@ class Fragment {
416
426
  for (let i = 0, curPos = 0;; i++) {
417
427
  let cur = this.child(i), end = curPos + cur.nodeSize;
418
428
  if (end >= pos) {
419
- if (end == pos || round > 0)
429
+ if (end == pos)
420
430
  return retIndex(i + 1, end);
421
431
  return retIndex(i, curPos);
422
432
  }
@@ -445,7 +455,7 @@ class Fragment {
445
455
  return Fragment.empty;
446
456
  if (!Array.isArray(value))
447
457
  throw new RangeError("Invalid input for Fragment.fromJSON");
448
- return new Fragment(value.map(schema.nodeFromJSON));
458
+ return Fragment.fromArray(value.map(schema.nodeFromJSON));
449
459
  }
450
460
  /**
451
461
  Build a fragment from an array of nodes. Ensures that adjacent
@@ -679,17 +689,6 @@ given an invalid replacement.
679
689
  */
680
690
  class ReplaceError extends Error {
681
691
  }
682
- /*
683
- ReplaceError = function(this: any, message: string) {
684
- let err = Error.call(this, message)
685
- ;(err as any).__proto__ = ReplaceError.prototype
686
- return err
687
- } as any
688
-
689
- ReplaceError.prototype = Object.create(Error.prototype)
690
- ReplaceError.prototype.constructor = ReplaceError
691
- ReplaceError.prototype.name = "ReplaceError"
692
- */
693
692
  /**
694
693
  A slice represents a piece cut out of a larger document. It
695
694
  stores not only a fragment, but also the depth up to which nodes on
@@ -735,7 +734,7 @@ class Slice {
735
734
  @internal
736
735
  */
737
736
  insertAt(pos, fragment) {
738
- let content = insertInto(this.content, pos + this.openStart, fragment);
737
+ let content = insertInto(this.content, pos + this.openStart, fragment, this.openStart + 1, this.openEnd + 1);
739
738
  return content && new Slice(content, this.openStart, this.openEnd);
740
739
  }
741
740
  /**
@@ -809,12 +808,14 @@ function removeRange(content, from, to) {
809
808
  throw new RangeError("Removing non-flat range");
810
809
  return content.replaceChild(index, child.copy(removeRange(child.content, from - offset - 1, to - offset - 1)));
811
810
  }
812
- function insertInto(content, dist, insert, parent) {
811
+ function insertInto(content, dist, insert, openStart, openEnd, parent) {
813
812
  let { index, offset } = content.findIndex(dist), child = content.maybeChild(index);
814
813
  if (offset == dist || child.isText) {
814
+ if (parent && openStart <= 0 && openEnd <= 0 && !parent.canReplace(index, index, insert))
815
+ return null;
815
816
  return content.cut(0, dist).append(insert).append(content.cut(dist));
816
817
  }
817
- let inner = insertInto(child.content, dist - offset - 1, insert);
818
+ let inner = insertInto(child.content, dist - offset - 1, insert, index == 0 ? openStart - 1 : 0, index == content.childCount - 1 ? openEnd - 1 : 0, child);
818
819
  return inner && content.replaceChild(index, child.copy(inner));
819
820
  }
820
821
  function replace($from, $to, slice) {
@@ -877,7 +878,8 @@ function addRange($start, $end, depth, target) {
877
878
  addNode($end.nodeBefore, target);
878
879
  }
879
880
  function close(node, content) {
880
- node.type.checkContent(content);
881
+ if (!node.type.validContent(content))
882
+ throw new ReplaceError("Invalid content for node " + node.type.name);
881
883
  return node.copy(content);
882
884
  }
883
885
  function replaceThreeWay($from, $start, $end, $to, depth) {
@@ -1284,7 +1286,7 @@ structure between the old and new data as much as possible, which a
1284
1286
  tree shape like this (without back pointers) makes easy.
1285
1287
 
1286
1288
  **Do not** directly mutate the properties of a `Node` object. See
1287
- [the guide](/docs/guide/#doc) for more information.
1289
+ [the guide](https://prosemirror.net/docs/guide/#doc) for more information.
1288
1290
  */
1289
1291
  class Node {
1290
1292
  /**
@@ -1314,8 +1316,12 @@ class Node {
1314
1316
  this.content = content || Fragment.empty;
1315
1317
  }
1316
1318
  /**
1319
+ The array of this node's child nodes.
1320
+ */
1321
+ get children() { return this.content.content; }
1322
+ /**
1317
1323
  The size of this node, as defined by the integer-based [indexing
1318
- scheme](/docs/guide/#doc.indexing). For text nodes, this is the
1324
+ scheme](https://prosemirror.net/docs/guide/#doc.indexing). For text nodes, this is the
1319
1325
  amount of characters. For other leaf nodes, it is one. For
1320
1326
  non-leaf nodes, it is the size of the content plus two (the
1321
1327
  start and end token).
@@ -1340,10 +1346,11 @@ class Node {
1340
1346
  */
1341
1347
  forEach(f) { this.content.forEach(f); }
1342
1348
  /**
1343
- Invoke a callback for all descendant nodes recursively between
1349
+ Invoke a callback for all descendant nodes recursively overlapping
1344
1350
  the given two positions that are relative to start of this
1345
- node's content. The callback is invoked with the node, its
1346
- position relative to the original node (method receiver),
1351
+ node's content. This includes all ancestors of the nodes
1352
+ containing the two positions. The callback is invoked with the
1353
+ node, its position relative to the original node (method receiver),
1347
1354
  its parent node, and its child index. When the callback returns
1348
1355
  false for a given node, that node's children will not be
1349
1356
  recursed over. The last parameter can be used to specify a
@@ -1373,7 +1380,7 @@ class Node {
1373
1380
  `blockSeparator` is given, it will be inserted to separate text
1374
1381
  from different block nodes. If `leafText` is given, it'll be
1375
1382
  inserted for every non-text leaf node encountered, otherwise
1376
- [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec^leafText) will be used.
1383
+ [`leafText`](https://prosemirror.net/docs/ref/#model.NodeSpec.leafText) will be used.
1377
1384
  */
1378
1385
  textBetween(from, to, blockSeparator, leafText) {
1379
1386
  return this.content.textBetween(from, to, blockSeparator, leafText);
@@ -1980,7 +1987,7 @@ function resolveName(stream, name) {
1980
1987
  let result = [];
1981
1988
  for (let typeName in types) {
1982
1989
  let type = types[typeName];
1983
- if (type.groups.indexOf(name) > -1)
1990
+ if (type.isInGroup(name))
1984
1991
  result.push(type);
1985
1992
  }
1986
1993
  if (result.length == 0)
@@ -2009,16 +2016,14 @@ function parseExprAtom(stream) {
2009
2016
  stream.err("Unexpected token '" + stream.next + "'");
2010
2017
  }
2011
2018
  }
2012
- /**
2013
- Construct an NFA from an expression as returned by the parser. The
2014
- NFA is represented as an array of states, which are themselves
2015
- arrays of edges, which are `{term, to}` objects. The first state is
2016
- the entry state and the last node is the success state.
2017
-
2018
- Note that unlike typical NFAs, the edge ordering in this one is
2019
- significant, in that it is used to contruct filler content when
2020
- necessary.
2021
- */
2019
+ // Construct an NFA from an expression as returned by the parser. The
2020
+ // NFA is represented as an array of states, which are themselves
2021
+ // arrays of edges, which are `{term, to}` objects. The first state is
2022
+ // the entry state and the last node is the success state.
2023
+ //
2024
+ // Note that unlike typical NFAs, the edge ordering in this one is
2025
+ // significant, in that it is used to contruct filler content when
2026
+ // necessary.
2022
2027
  function nfa(expr) {
2023
2028
  let nfa = [[]];
2024
2029
  connect(compile(expr, 0), node());
@@ -2185,13 +2190,12 @@ function computeAttrs(attrs, value) {
2185
2190
  return built;
2186
2191
  }
2187
2192
  function checkAttrs(attrs, values, type, name) {
2188
- for (let name in values)
2189
- if (!(name in attrs))
2190
- throw new RangeError(`Unsupported attribute ${name} for ${type} of type ${name}`);
2191
- for (let name in attrs) {
2192
- let attr = attrs[name];
2193
- if (attr.validate)
2194
- attr.validate(values[name]);
2193
+ for (let attr in values)
2194
+ if (!(attr in attrs))
2195
+ throw new RangeError(`Unsupported attribute ${attr} for ${type} of type ${name}`);
2196
+ for (let attr in attrs) {
2197
+ if (attrs[attr].validate)
2198
+ attrs[attr].validate(values[attr]);
2195
2199
  }
2196
2200
  }
2197
2201
  function initAttrs(typeName, attrs) {
@@ -2259,6 +2263,13 @@ class NodeType {
2259
2263
  */
2260
2264
  get isAtom() { return this.isLeaf || !!this.spec.atom; }
2261
2265
  /**
2266
+ Return true when this node type is part of the given
2267
+ [group](https://prosemirror.net/docs/ref/#model.NodeSpec.group).
2268
+ */
2269
+ isInGroup(group) {
2270
+ return this.groups.indexOf(group) > -1;
2271
+ }
2272
+ /**
2262
2273
  The node type's [whitespace](https://prosemirror.net/docs/ref/#model.NodeSpec.whitespace) option.
2263
2274
  */
2264
2275
  get whitespace() {
@@ -2578,8 +2589,8 @@ class Schema {
2578
2589
  let type = this.marks[prop], excl = type.spec.excludes;
2579
2590
  type.excluded = excl == null ? [type] : excl == "" ? [] : gatherMarks(this, excl.split(" "));
2580
2591
  }
2581
- this.nodeFromJSON = this.nodeFromJSON.bind(this);
2582
- this.markFromJSON = this.markFromJSON.bind(this);
2592
+ this.nodeFromJSON = json => Node.fromJSON(this, json);
2593
+ this.markFromJSON = json => Mark.fromJSON(this, json);
2583
2594
  this.topNodeType = this.nodes[this.spec.topNode || "doc"];
2584
2595
  this.cached.wrappings = Object.create(null);
2585
2596
  }
@@ -2615,20 +2626,6 @@ class Schema {
2615
2626
  return type.create(attrs);
2616
2627
  }
2617
2628
  /**
2618
- Deserialize a node from its JSON representation. This method is
2619
- bound.
2620
- */
2621
- nodeFromJSON(json) {
2622
- return Node.fromJSON(this, json);
2623
- }
2624
- /**
2625
- Deserialize a mark from its JSON representation. This method is
2626
- bound.
2627
- */
2628
- markFromJSON(json) {
2629
- return Mark.fromJSON(this, json);
2630
- }
2631
- /**
2632
2629
  @internal
2633
2630
  */
2634
2631
  nodeType(name) {
@@ -2810,7 +2807,7 @@ class DOMParser {
2810
2807
  /**
2811
2808
  Construct a DOM parser using the parsing rules listed in a
2812
2809
  schema's [node specs](https://prosemirror.net/docs/ref/#model.NodeSpec.parseDOM), reordered by
2813
- [priority](https://prosemirror.net/docs/ref/#model.ParseRule.priority).
2810
+ [priority](https://prosemirror.net/docs/ref/#model.GenericParseRule.priority).
2814
2811
  */
2815
2812
  static fromSchema(schema) {
2816
2813
  return schema.cached.domParser ||
@@ -2903,6 +2900,7 @@ class ParseContext {
2903
2900
  this.options = options;
2904
2901
  this.isOpen = isOpen;
2905
2902
  this.open = 0;
2903
+ this.localPreserveWS = false;
2906
2904
  let topNode = options.topNode, topContext;
2907
2905
  let topOptions = wsOptionsFor(null, options.preserveWhitespace, 0) | (isOpen ? OPT_OPEN_LEFT : 0);
2908
2906
  if (topNode)
@@ -2929,11 +2927,13 @@ class ParseContext {
2929
2927
  }
2930
2928
  addTextNode(dom, marks) {
2931
2929
  let value = dom.nodeValue;
2932
- let top = this.top;
2933
- if (top.options & OPT_PRESERVE_WS_FULL ||
2930
+ let top = this.top, preserveWS = (top.options & OPT_PRESERVE_WS_FULL) ? "full"
2931
+ : this.localPreserveWS || (top.options & OPT_PRESERVE_WS) > 0;
2932
+ let { schema } = this.parser;
2933
+ if (preserveWS === "full" ||
2934
2934
  top.inlineContext(dom) ||
2935
2935
  /[^ \t\r\n\u000c]/.test(value)) {
2936
- if (!(top.options & OPT_PRESERVE_WS)) {
2936
+ if (!preserveWS) {
2937
2937
  value = value.replace(/[ \t\r\n\u000c]+/g, " ");
2938
2938
  // If this starts with whitespace, and there is no node before it, or
2939
2939
  // a hard break, or a text node that ends with whitespace, strip the
@@ -2947,14 +2947,24 @@ class ParseContext {
2947
2947
  value = value.slice(1);
2948
2948
  }
2949
2949
  }
2950
- else if (!(top.options & OPT_PRESERVE_WS_FULL)) {
2951
- value = value.replace(/\r?\n|\r/g, " ");
2950
+ else if (preserveWS === "full") {
2951
+ value = value.replace(/\r\n?/g, "\n");
2952
+ }
2953
+ else if (schema.linebreakReplacement && /[\r\n]/.test(value) && this.top.findWrapping(schema.linebreakReplacement.create())) {
2954
+ let lines = value.split(/\r?\n|\r/);
2955
+ for (let i = 0; i < lines.length; i++) {
2956
+ if (i)
2957
+ this.insertNode(schema.linebreakReplacement.create(), marks, true);
2958
+ if (lines[i])
2959
+ this.insertNode(schema.text(lines[i]), marks, !/\S/.test(lines[i]));
2960
+ }
2961
+ value = "";
2952
2962
  }
2953
2963
  else {
2954
- value = value.replace(/\r\n?/g, "\n");
2964
+ value = value.replace(/\r?\n|\r/g, " ");
2955
2965
  }
2956
2966
  if (value)
2957
- this.insertNode(this.parser.schema.text(value), marks);
2967
+ this.insertNode(schema.text(value), marks, !/\S/.test(value));
2958
2968
  this.findInText(dom);
2959
2969
  }
2960
2970
  else {
@@ -2964,12 +2974,15 @@ class ParseContext {
2964
2974
  // Try to find a handler for the given tag and use that to parse. If
2965
2975
  // none is found, the element's content nodes are added directly.
2966
2976
  addElement(dom, marks, matchAfter) {
2977
+ let outerWS = this.localPreserveWS, top = this.top;
2978
+ if (dom.tagName == "PRE" || /pre/.test(dom.style && dom.style.whiteSpace))
2979
+ this.localPreserveWS = true;
2967
2980
  let name = dom.nodeName.toLowerCase(), ruleID;
2968
2981
  if (listTags.hasOwnProperty(name) && this.parser.normalizeLists)
2969
2982
  normalizeList(dom);
2970
2983
  let rule = (this.options.ruleFromNode && this.options.ruleFromNode(dom)) ||
2971
2984
  (ruleID = this.parser.matchTag(dom, this, matchAfter));
2972
- if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
2985
+ out: if (rule ? rule.ignore : ignoreTags.hasOwnProperty(name)) {
2973
2986
  this.findInside(dom);
2974
2987
  this.ignoreFallback(dom, marks);
2975
2988
  }
@@ -2978,7 +2991,7 @@ class ParseContext {
2978
2991
  this.open = Math.max(0, this.open - 1);
2979
2992
  else if (rule && rule.skip.nodeType)
2980
2993
  dom = rule.skip;
2981
- let sync, top = this.top, oldNeedsBlock = this.needsBlock;
2994
+ let sync, oldNeedsBlock = this.needsBlock;
2982
2995
  if (blockTags.hasOwnProperty(name)) {
2983
2996
  if (top.content.length && top.content[0].isInline && this.open) {
2984
2997
  this.open--;
@@ -2990,7 +3003,7 @@ class ParseContext {
2990
3003
  }
2991
3004
  else if (!dom.firstChild) {
2992
3005
  this.leafFallback(dom, marks);
2993
- return;
3006
+ break out;
2994
3007
  }
2995
3008
  let innerMarks = rule && rule.skip ? marks : this.readStyles(dom, marks);
2996
3009
  if (innerMarks)
@@ -3004,6 +3017,7 @@ class ParseContext {
3004
3017
  if (innerMarks)
3005
3018
  this.addElementByRule(dom, rule, innerMarks, rule.consuming === false ? ruleID : undefined);
3006
3019
  }
3020
+ this.localPreserveWS = outerWS;
3007
3021
  }
3008
3022
  // Called for leaf DOM nodes that would otherwise be ignored
3009
3023
  leafFallback(dom, marks) {
@@ -3014,7 +3028,7 @@ class ParseContext {
3014
3028
  ignoreFallback(dom, marks) {
3015
3029
  // Ignored BR nodes should at least create an inline context
3016
3030
  if (dom.nodeName == "BR" && (!this.top.type || !this.top.type.inlineContent))
3017
- this.findPlace(this.parser.schema.text("-"), marks);
3031
+ this.findPlace(this.parser.schema.text("-"), marks, true);
3018
3032
  }
3019
3033
  // Run any style parser associated with the node's styles. Either
3020
3034
  // return an updated array of marks, or null to indicate some of the
@@ -3062,7 +3076,7 @@ class ParseContext {
3062
3076
  marks = inner;
3063
3077
  }
3064
3078
  }
3065
- else if (!this.insertNode(nodeType.create(rule.attrs), marks)) {
3079
+ else if (!this.insertNode(nodeType.create(rule.attrs), marks, dom.nodeName == "BR")) {
3066
3080
  this.leafFallback(dom, marks);
3067
3081
  }
3068
3082
  }
@@ -3079,7 +3093,7 @@ class ParseContext {
3079
3093
  }
3080
3094
  else if (rule.getContent) {
3081
3095
  this.findInside(dom);
3082
- rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks));
3096
+ rule.getContent(dom, this.parser.schema).forEach(node => this.insertNode(node, marks, false));
3083
3097
  }
3084
3098
  else {
3085
3099
  let contentDOM = dom;
@@ -3091,6 +3105,7 @@ class ParseContext {
3091
3105
  contentDOM = rule.contentElement;
3092
3106
  this.findAround(dom, contentDOM, true);
3093
3107
  this.addAll(contentDOM, marks);
3108
+ this.findAround(dom, contentDOM, false);
3094
3109
  }
3095
3110
  if (sync && this.sync(startIn))
3096
3111
  this.open--;
@@ -3109,19 +3124,22 @@ class ParseContext {
3109
3124
  // Try to find a way to fit the given node type into the current
3110
3125
  // context. May add intermediate wrappers and/or leave non-solid
3111
3126
  // nodes that we're in.
3112
- findPlace(node, marks) {
3127
+ findPlace(node, marks, cautious) {
3113
3128
  let route, sync;
3114
- for (let depth = this.open; depth >= 0; depth--) {
3129
+ for (let depth = this.open, penalty = 0; depth >= 0; depth--) {
3115
3130
  let cx = this.nodes[depth];
3116
3131
  let found = cx.findWrapping(node);
3117
- if (found && (!route || route.length > found.length)) {
3132
+ if (found && (!route || route.length > found.length + penalty)) {
3118
3133
  route = found;
3119
3134
  sync = cx;
3120
3135
  if (!found.length)
3121
3136
  break;
3122
3137
  }
3123
- if (cx.solid)
3124
- break;
3138
+ if (cx.solid) {
3139
+ if (cautious)
3140
+ break;
3141
+ penalty += 2;
3142
+ }
3125
3143
  }
3126
3144
  if (!route)
3127
3145
  return null;
@@ -3131,13 +3149,13 @@ class ParseContext {
3131
3149
  return marks;
3132
3150
  }
3133
3151
  // Try to insert the given node, adjusting the context when needed.
3134
- insertNode(node, marks) {
3152
+ insertNode(node, marks, cautious) {
3135
3153
  if (node.isInline && this.needsBlock && !this.top.type) {
3136
3154
  let block = this.textblockFromContext();
3137
3155
  if (block)
3138
3156
  marks = this.enterInner(block, null, marks);
3139
3157
  }
3140
- let innerMarks = this.findPlace(node, marks);
3158
+ let innerMarks = this.findPlace(node, marks, cautious);
3141
3159
  if (innerMarks) {
3142
3160
  this.closeExtra();
3143
3161
  let top = this.top;
@@ -3155,7 +3173,7 @@ class ParseContext {
3155
3173
  // Try to start a node of the given type, adjusting the context when
3156
3174
  // necessary.
3157
3175
  enter(type, attrs, marks, preserveWS) {
3158
- let innerMarks = this.findPlace(type.create(attrs), marks);
3176
+ let innerMarks = this.findPlace(type.create(attrs), marks, false);
3159
3177
  if (innerMarks)
3160
3178
  innerMarks = this.enterInner(type, attrs, marks, true, preserveWS);
3161
3179
  return innerMarks;
@@ -3193,14 +3211,18 @@ class ParseContext {
3193
3211
  finish() {
3194
3212
  this.open = 0;
3195
3213
  this.closeExtra(this.isOpen);
3196
- return this.nodes[0].finish(this.isOpen || this.options.topOpen);
3214
+ return this.nodes[0].finish(!!(this.isOpen || this.options.topOpen));
3197
3215
  }
3198
3216
  sync(to) {
3199
- for (let i = this.open; i >= 0; i--)
3217
+ for (let i = this.open; i >= 0; i--) {
3200
3218
  if (this.nodes[i] == to) {
3201
3219
  this.open = i;
3202
3220
  return true;
3203
3221
  }
3222
+ else if (this.localPreserveWS) {
3223
+ this.nodes[i].options |= OPT_PRESERVE_WS;
3224
+ }
3225
+ }
3204
3226
  return false;
3205
3227
  }
3206
3228
  get currentPos() {
@@ -3269,7 +3291,7 @@ class ParseContext {
3269
3291
  let next = depth > 0 || (depth == 0 && useRoot) ? this.nodes[depth].type
3270
3292
  : option && depth >= minDepth ? option.node(depth - minDepth).type
3271
3293
  : null;
3272
- if (!next || (next.name != part && next.groups.indexOf(part) == -1))
3294
+ if (!next || (next.name != part && !next.isInGroup(part)))
3273
3295
  return false;
3274
3296
  depth--;
3275
3297
  }
@@ -3415,6 +3437,8 @@ class DOMSerializer {
3415
3437
  @internal
3416
3438
  */
3417
3439
  serializeNodeInner(node, options) {
3440
+ if (node.isText)
3441
+ return doc(options).createTextNode(node.text);
3418
3442
  let { dom, contentDOM } = renderSpec(doc(options), this.nodes[node.type.name](node), null, node.attrs);
3419
3443
  if (contentDOM) {
3420
3444
  if (node.isLeaf)
@@ -3449,6 +3473,9 @@ class DOMSerializer {
3449
3473
  return toDOM && renderSpec(doc(options), toDOM(mark, inline), null, mark.attrs);
3450
3474
  }
3451
3475
  static renderSpec(doc, structure, xmlNS = null, blockArraysIn) {
3476
+ // Kludge for backwards-compatibility with accidental original behavious
3477
+ if (typeof structure == "string")
3478
+ return { dom: doc.createTextNode(structure) };
3452
3479
  return renderSpec(doc, structure, xmlNS, blockArraysIn);
3453
3480
  }
3454
3481
  /**
@@ -3520,11 +3547,9 @@ function suspiciousAttributesInner(attrs) {
3520
3547
  return result;
3521
3548
  }
3522
3549
  function renderSpec(doc, structure, xmlNS, blockArraysIn) {
3523
- if (typeof structure == "string")
3524
- return { dom: doc.createTextNode(structure) };
3525
- if (structure.nodeType != null)
3550
+ if (structure.nodeType == 1)
3526
3551
  return { dom: structure };
3527
- if (structure.dom && structure.dom.nodeType != null)
3552
+ if (structure.dom && structure.dom.nodeType == 1)
3528
3553
  return structure;
3529
3554
  let tagName = structure[0], suspicious;
3530
3555
  if (typeof tagName != "string")
@@ -3547,6 +3572,8 @@ function renderSpec(doc, structure, xmlNS, blockArraysIn) {
3547
3572
  let space = name.indexOf(" ");
3548
3573
  if (space > 0)
3549
3574
  dom.setAttributeNS(name.slice(0, space), name.slice(space + 1), attrs[name]);
3575
+ else if (name == "style" && dom.style)
3576
+ dom.style.cssText = attrs[name];
3550
3577
  else
3551
3578
  dom.setAttribute(name, attrs[name]);
3552
3579
  }
@@ -3558,6 +3585,9 @@ function renderSpec(doc, structure, xmlNS, blockArraysIn) {
3558
3585
  throw new RangeError("Content hole must be the only child of its parent node");
3559
3586
  return { dom, contentDOM: dom };
3560
3587
  }
3588
+ else if (typeof child == "string") {
3589
+ dom.appendChild(doc.createTextNode(child));
3590
+ }
3561
3591
  else {
3562
3592
  let { dom: inner, contentDOM: innerContent } = renderSpec(doc, child, xmlNS, blockArraysIn);
3563
3593
  dom.appendChild(inner);
@@ -3756,18 +3786,14 @@ A mapping represents a pipeline of zero or more [step
3756
3786
  maps](https://prosemirror.net/docs/ref/#transform.StepMap). It has special provisions for losslessly
3757
3787
  handling mapping positions through a series of steps in which some
3758
3788
  steps are inverted versions of earlier steps. (This comes up when
3759
- ‘[rebasing](/docs/guide/#transform.rebasing)’ steps for
3789
+ ‘[rebasing](https://prosemirror.net/docs/guide/#transform.rebasing)’ steps for
3760
3790
  collaboration or history management.)
3761
3791
  */
3762
3792
  class Mapping {
3763
3793
  /**
3764
3794
  Create a new mapping with the given position maps.
3765
3795
  */
3766
- constructor(
3767
- /**
3768
- The step maps in this mapping.
3769
- */
3770
- maps = [],
3796
+ constructor(maps,
3771
3797
  /**
3772
3798
  @internal
3773
3799
  */
@@ -3780,23 +3806,22 @@ class Mapping {
3780
3806
  /**
3781
3807
  The end position in the `maps` array.
3782
3808
  */
3783
- to = maps.length) {
3784
- this.maps = maps;
3809
+ to = maps ? maps.length : 0) {
3785
3810
  this.mirror = mirror;
3786
3811
  this.from = from;
3787
3812
  this.to = to;
3813
+ this._maps = maps || [];
3814
+ this.ownData = !(maps || mirror);
3788
3815
  }
3789
3816
  /**
3790
- Create a mapping that maps only through a part of this one.
3817
+ The step maps in this mapping.
3791
3818
  */
3792
- slice(from = 0, to = this.maps.length) {
3793
- return new Mapping(this.maps, this.mirror, from, to);
3794
- }
3819
+ get maps() { return this._maps; }
3795
3820
  /**
3796
- @internal
3821
+ Create a mapping that maps only through a part of this one.
3797
3822
  */
3798
- copy() {
3799
- return new Mapping(this.maps.slice(), this.mirror && this.mirror.slice(), this.from, this.to);
3823
+ slice(from = 0, to = this.maps.length) {
3824
+ return new Mapping(this._maps, this.mirror, from, to);
3800
3825
  }
3801
3826
  /**
3802
3827
  Add a step map to the end of this mapping. If `mirrors` is
@@ -3804,18 +3829,23 @@ class Mapping {
3804
3829
  image of this one.
3805
3830
  */
3806
3831
  appendMap(map, mirrors) {
3807
- this.to = this.maps.push(map);
3832
+ if (!this.ownData) {
3833
+ this._maps = this._maps.slice();
3834
+ this.mirror = this.mirror && this.mirror.slice();
3835
+ this.ownData = true;
3836
+ }
3837
+ this.to = this._maps.push(map);
3808
3838
  if (mirrors != null)
3809
- this.setMirror(this.maps.length - 1, mirrors);
3839
+ this.setMirror(this._maps.length - 1, mirrors);
3810
3840
  }
3811
3841
  /**
3812
3842
  Add all the step maps in a given mapping to this one (preserving
3813
3843
  mirroring information).
3814
3844
  */
3815
3845
  appendMapping(mapping) {
3816
- for (let i = 0, startSize = this.maps.length; i < mapping.maps.length; i++) {
3846
+ for (let i = 0, startSize = this._maps.length; i < mapping._maps.length; i++) {
3817
3847
  let mirr = mapping.getMirror(i);
3818
- this.appendMap(mapping.maps[i], mirr != null && mirr < i ? startSize + mirr : undefined);
3848
+ this.appendMap(mapping._maps[i], mirr != null && mirr < i ? startSize + mirr : undefined);
3819
3849
  }
3820
3850
  }
3821
3851
  /**
@@ -3841,9 +3871,9 @@ class Mapping {
3841
3871
  Append the inverse of the given mapping to this one.
3842
3872
  */
3843
3873
  appendMappingInverted(mapping) {
3844
- for (let i = mapping.maps.length - 1, totalSize = this.maps.length + mapping.maps.length; i >= 0; i--) {
3874
+ for (let i = mapping.maps.length - 1, totalSize = this._maps.length + mapping._maps.length; i >= 0; i--) {
3845
3875
  let mirr = mapping.getMirror(i);
3846
- this.appendMap(mapping.maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : undefined);
3876
+ this.appendMap(mapping._maps[i].invert(), mirr != null && mirr > i ? totalSize - mirr - 1 : undefined);
3847
3877
  }
3848
3878
  }
3849
3879
  /**
@@ -3861,7 +3891,7 @@ class Mapping {
3861
3891
  if (this.mirror)
3862
3892
  return this._map(pos, assoc, true);
3863
3893
  for (let i = this.from; i < this.to; i++)
3864
- pos = this.maps[i].map(pos, assoc);
3894
+ pos = this._maps[i].map(pos, assoc);
3865
3895
  return pos;
3866
3896
  }
3867
3897
  /**
@@ -3875,12 +3905,12 @@ class Mapping {
3875
3905
  _map(pos, assoc, simple) {
3876
3906
  let delInfo = 0;
3877
3907
  for (let i = this.from; i < this.to; i++) {
3878
- let map = this.maps[i], result = map.mapResult(pos, assoc);
3908
+ let map = this._maps[i], result = map.mapResult(pos, assoc);
3879
3909
  if (result.recover != null) {
3880
3910
  let corr = this.getMirror(i);
3881
3911
  if (corr != null && corr > i && corr < this.to) {
3882
3912
  i = corr;
3883
- pos = this.maps[corr].recover(result.recover);
3913
+ pos = this._maps[corr].recover(result.recover);
3884
3914
  continue;
3885
3915
  }
3886
3916
  }
@@ -4282,10 +4312,11 @@ class ReplaceStep extends Step {
4282
4312
  return new ReplaceStep(this.from, this.from + this.slice.size, doc.slice(this.from, this.to));
4283
4313
  }
4284
4314
  map(mapping) {
4285
- let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
4315
+ let to = mapping.mapResult(this.to, -1);
4316
+ let from = this.from == this.to && ReplaceStep.MAP_BIAS < 0 ? to : mapping.mapResult(this.from, 1);
4286
4317
  if (from.deletedAcross && to.deletedAcross)
4287
4318
  return null;
4288
- return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice);
4319
+ return new ReplaceStep(from.pos, Math.max(from.pos, to.pos), this.slice, this.structure);
4289
4320
  }
4290
4321
  merge(other) {
4291
4322
  if (!(other instanceof ReplaceStep) || other.structure || this.structure)
@@ -4321,6 +4352,15 @@ class ReplaceStep extends Step {
4321
4352
  return new ReplaceStep(json.from, json.to, Slice.fromJSON(schema, json.slice), !!json.structure);
4322
4353
  }
4323
4354
  }
4355
+ /**
4356
+ By default, for backwards compatibility, an inserting step
4357
+ mapped over an insertion at that same position fill move after
4358
+ the inserted content. In a collaborative editing situation, that
4359
+ can make redone insertions appear in unexpected places. You can
4360
+ set this to -1 to make such mapping keep the step before the
4361
+ insertion instead.
4362
+ */
4363
+ ReplaceStep.MAP_BIAS = 1;
4324
4364
  Step.jsonID("replace", ReplaceStep);
4325
4365
  /**
4326
4366
  Replace a part of the document with a slice of content, but
@@ -4395,7 +4435,8 @@ class ReplaceAroundStep extends Step {
4395
4435
  }
4396
4436
  map(mapping) {
4397
4437
  let from = mapping.mapResult(this.from, 1), to = mapping.mapResult(this.to, -1);
4398
- let gapFrom = mapping.map(this.gapFrom, -1), gapTo = mapping.map(this.gapTo, 1);
4438
+ let gapFrom = this.from == this.gapFrom ? from.pos : mapping.map(this.gapFrom, -1);
4439
+ let gapTo = this.to == this.gapTo ? to.pos : mapping.map(this.gapTo, 1);
4399
4440
  if ((from.deletedAcross && to.deletedAcross) || gapFrom < from.pos || gapTo > to.pos)
4400
4441
  return null;
4401
4442
  return new ReplaceAroundStep(from.pos, to.pos, gapFrom, gapTo, this.slice, this.insert, this.structure);
@@ -4507,7 +4548,7 @@ function removeMark(tr, from, to, mark) {
4507
4548
  });
4508
4549
  matched.forEach(m => tr.step(new RemoveMarkStep(m.from, m.to, m.style)));
4509
4550
  }
4510
- function clearIncompatible(tr, pos, parentType, match = parentType.contentMatch) {
4551
+ function clearIncompatible(tr, pos, parentType, match = parentType.contentMatch, clearNewlines = true) {
4511
4552
  let node = tr.doc.nodeAt(pos);
4512
4553
  let replSteps = [], cur = pos + 1;
4513
4554
  for (let i = 0; i < node.childCount; i++) {
@@ -4521,7 +4562,7 @@ function clearIncompatible(tr, pos, parentType, match = parentType.contentMatch)
4521
4562
  for (let j = 0; j < child.marks.length; j++)
4522
4563
  if (!parentType.allowsMarkType(child.marks[j].type))
4523
4564
  tr.step(new RemoveMarkStep(cur, end, child.marks[j]));
4524
- if (child.isText && !parentType.spec.code) {
4565
+ if (clearNewlines && child.isText && parentType.whitespace != "pre") {
4525
4566
  let m, newline = /\r?\n|\r/g, slice;
4526
4567
  while (m = newline.exec(child.text)) {
4527
4568
  if (!slice)
@@ -4552,13 +4593,17 @@ can be lifted. Will not go across
4552
4593
  function liftTarget(range) {
4553
4594
  let parent = range.parent;
4554
4595
  let content = parent.content.cutByIndex(range.startIndex, range.endIndex);
4555
- for (let depth = range.depth;; --depth) {
4596
+ for (let depth = range.depth, contentBefore = 0, contentAfter = 0;; --depth) {
4556
4597
  let node = range.$from.node(depth);
4557
- let index = range.$from.index(depth), endIndex = range.$to.indexAfter(depth);
4598
+ let index = range.$from.index(depth) + contentBefore, endIndex = range.$to.indexAfter(depth) - contentAfter;
4558
4599
  if (depth < range.depth && node.canReplace(index, endIndex, content))
4559
4600
  return depth;
4560
4601
  if (depth == 0 || node.type.spec.isolating || !canCut(node, index, endIndex))
4561
4602
  break;
4603
+ if (index)
4604
+ contentBefore = 1;
4605
+ if (endIndex < node.childCount)
4606
+ contentAfter = 1;
4562
4607
  }
4563
4608
  return null;
4564
4609
  }
@@ -4645,16 +4690,49 @@ function setBlockType(tr, from, to, type, attrs) {
4645
4690
  throw new RangeError("Type given to setBlockType should be a textblock");
4646
4691
  let mapFrom = tr.steps.length;
4647
4692
  tr.doc.nodesBetween(from, to, (node, pos) => {
4648
- if (node.isTextblock && !node.hasMarkup(type, attrs) && canChangeType(tr.doc, tr.mapping.slice(mapFrom).map(pos), type)) {
4693
+ let attrsHere = typeof attrs == "function" ? attrs(node) : attrs;
4694
+ if (node.isTextblock && !node.hasMarkup(type, attrsHere) &&
4695
+ canChangeType(tr.doc, tr.mapping.slice(mapFrom).map(pos), type)) {
4696
+ let convertNewlines = null;
4697
+ if (type.schema.linebreakReplacement) {
4698
+ let pre = type.whitespace == "pre", supportLinebreak = !!type.contentMatch.matchType(type.schema.linebreakReplacement);
4699
+ if (pre && !supportLinebreak)
4700
+ convertNewlines = false;
4701
+ else if (!pre && supportLinebreak)
4702
+ convertNewlines = true;
4703
+ }
4649
4704
  // Ensure all markup that isn't allowed in the new node type is cleared
4650
- tr.clearIncompatible(tr.mapping.slice(mapFrom).map(pos, 1), type);
4705
+ if (convertNewlines === false)
4706
+ replaceLinebreaks(tr, node, pos, mapFrom);
4707
+ clearIncompatible(tr, tr.mapping.slice(mapFrom).map(pos, 1), type, undefined, convertNewlines === null);
4651
4708
  let mapping = tr.mapping.slice(mapFrom);
4652
4709
  let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1);
4653
- tr.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, new Slice(Fragment.from(type.create(attrs, null, node.marks)), 0, 0), 1, true));
4710
+ tr.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1, new Slice(Fragment.from(type.create(attrsHere, null, node.marks)), 0, 0), 1, true));
4711
+ if (convertNewlines === true)
4712
+ replaceNewlines(tr, node, pos, mapFrom);
4654
4713
  return false;
4655
4714
  }
4656
4715
  });
4657
4716
  }
4717
+ function replaceNewlines(tr, node, pos, mapFrom) {
4718
+ node.forEach((child, offset) => {
4719
+ if (child.isText) {
4720
+ let m, newline = /\r?\n|\r/g;
4721
+ while (m = newline.exec(child.text)) {
4722
+ let start = tr.mapping.slice(mapFrom).map(pos + 1 + offset + m.index);
4723
+ tr.replaceWith(start, start + 1, node.type.schema.linebreakReplacement.create());
4724
+ }
4725
+ }
4726
+ });
4727
+ }
4728
+ function replaceLinebreaks(tr, node, pos, mapFrom) {
4729
+ node.forEach((child, offset) => {
4730
+ if (child.type == child.type.schema.linebreakReplacement) {
4731
+ let start = tr.mapping.slice(mapFrom).map(pos + 1 + offset);
4732
+ tr.replaceWith(start, start + 1, node.type.schema.text("\n"));
4733
+ }
4734
+ });
4735
+ }
4658
4736
  function canChangeType(doc, pos, type) {
4659
4737
  let $pos = doc.resolve(pos), index = $pos.index();
4660
4738
  return $pos.parent.canReplaceWith(index, index + 1, type);
@@ -4720,8 +4798,24 @@ function canJoin(doc, pos) {
4720
4798
  return joinable($pos.nodeBefore, $pos.nodeAfter) &&
4721
4799
  $pos.parent.canReplace(index, index + 1);
4722
4800
  }
4801
+ function canAppendWithSubstitutedLinebreaks(a, b) {
4802
+ if (!b.content.size)
4803
+ a.type.compatibleContent(b.type);
4804
+ let match = a.contentMatchAt(a.childCount);
4805
+ let { linebreakReplacement } = a.type.schema;
4806
+ for (let i = 0; i < b.childCount; i++) {
4807
+ let child = b.child(i);
4808
+ let type = child.type == linebreakReplacement ? a.type.schema.nodes.text : child.type;
4809
+ match = match.matchType(type);
4810
+ if (!match)
4811
+ return false;
4812
+ if (!a.type.allowsMarks(child.marks))
4813
+ return false;
4814
+ }
4815
+ return match.validEnd;
4816
+ }
4723
4817
  function joinable(a, b) {
4724
- return !!(a && b && !a.isLeaf && a.canAppend(b));
4818
+ return !!(a && b && !a.isLeaf && canAppendWithSubstitutedLinebreaks(a, b));
4725
4819
  }
4726
4820
  /**
4727
4821
  Find an ancestor of the given position that can be joined to the
@@ -4754,8 +4848,31 @@ function joinPoint(doc, pos, dir = -1) {
4754
4848
  }
4755
4849
  }
4756
4850
  function join(tr, pos, depth) {
4757
- let step = new ReplaceStep(pos - depth, pos + depth, Slice.empty, true);
4758
- tr.step(step);
4851
+ let convertNewlines = null;
4852
+ let { linebreakReplacement } = tr.doc.type.schema;
4853
+ let $before = tr.doc.resolve(pos - depth), beforeType = $before.node().type;
4854
+ if (linebreakReplacement && beforeType.inlineContent) {
4855
+ let pre = beforeType.whitespace == "pre";
4856
+ let supportLinebreak = !!beforeType.contentMatch.matchType(linebreakReplacement);
4857
+ if (pre && !supportLinebreak)
4858
+ convertNewlines = false;
4859
+ else if (!pre && supportLinebreak)
4860
+ convertNewlines = true;
4861
+ }
4862
+ let mapFrom = tr.steps.length;
4863
+ if (convertNewlines === false) {
4864
+ let $after = tr.doc.resolve(pos + depth);
4865
+ replaceLinebreaks(tr, $after.node(), $after.before(), mapFrom);
4866
+ }
4867
+ if (beforeType.inlineContent)
4868
+ clearIncompatible(tr, pos + depth - 1, beforeType, $before.node().contentMatchAt($before.index()), convertNewlines == null);
4869
+ let mapping = tr.mapping.slice(mapFrom), start = mapping.map(pos - depth);
4870
+ tr.step(new ReplaceStep(start, mapping.map(pos + depth, -1), Slice.empty, true));
4871
+ if (convertNewlines === true) {
4872
+ let $full = tr.doc.resolve(start);
4873
+ replaceNewlines(tr, $full.node(), $full.before(), tr.steps.length);
4874
+ }
4875
+ return tr;
4759
4876
  }
4760
4877
  /**
4761
4878
  Try to find a point where a node of the given type can be inserted
@@ -5137,7 +5254,7 @@ function replaceRange(tr, from, to, slice) {
5137
5254
  let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to);
5138
5255
  if (fitsTrivially($from, $to, slice))
5139
5256
  return tr.step(new ReplaceStep(from, to, slice));
5140
- let targetDepths = coveredDepths($from, tr.doc.resolve(to));
5257
+ let targetDepths = coveredDepths($from, $to);
5141
5258
  // Can't replace the whole document, so remove 0 if it's present
5142
5259
  if (targetDepths[targetDepths.length - 1] == 0)
5143
5260
  targetDepths.pop();
@@ -5230,6 +5347,26 @@ function replaceRangeWith(tr, from, to, node) {
5230
5347
  }
5231
5348
  function deleteRange(tr, from, to) {
5232
5349
  let $from = tr.doc.resolve(from), $to = tr.doc.resolve(to);
5350
+ // When the deleted range spans from the start of one textblock to
5351
+ // the start of another one, move out of the start of both blocks.
5352
+ if ($from.parent.isTextblock && $to.parent.isTextblock && $from.start() != $to.start() &&
5353
+ $from.parentOffset == 0 && $to.parentOffset == 0) {
5354
+ let shared = $from.sharedDepth(to), isolated = false;
5355
+ for (let d = $from.depth; d > shared; d--)
5356
+ if ($from.node(d).type.spec.isolating)
5357
+ isolated = true;
5358
+ for (let d = $to.depth; d > shared; d--)
5359
+ if ($to.node(d).type.spec.isolating)
5360
+ isolated = true;
5361
+ if (!isolated) {
5362
+ for (let d = $from.depth; d > 0 && from == $from.start(d); d--)
5363
+ from = $from.before(d);
5364
+ for (let d = $to.depth; d > 0 && to == $to.start(d); d--)
5365
+ to = $to.before(d);
5366
+ $from = tr.doc.resolve(from);
5367
+ $to = tr.doc.resolve(to);
5368
+ }
5369
+ }
5233
5370
  let covered = coveredDepths($from, $to);
5234
5371
  for (let i = 0; i < covered.length; i++) {
5235
5372
  let depth = covered[i], last = i == covered.length - 1;
@@ -5239,7 +5376,8 @@ function deleteRange(tr, from, to) {
5239
5376
  return tr.delete($from.before(depth), $to.after(depth));
5240
5377
  }
5241
5378
  for (let d = 1; d <= $from.depth && d <= $to.depth; d++) {
5242
- if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d)
5379
+ if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d &&
5380
+ $from.start(d - 1) == $to.start(d - 1) && $from.node(d - 1).canReplace($from.index(d - 1), $to.index(d - 1)))
5243
5381
  return tr.delete($from.before(d), to);
5244
5382
  }
5245
5383
  tr.delete(from, to);
@@ -5439,6 +5577,27 @@ class Transform {
5439
5577
  return this.steps.length > 0;
5440
5578
  }
5441
5579
  /**
5580
+ Return a single range, in post-transform document positions,
5581
+ that covers all content changed by this transform. Returns null
5582
+ if no replacements are made. Note that this will ignore changes
5583
+ that add/remove marks without replacing the underlying content.
5584
+ */
5585
+ changedRange() {
5586
+ let from = 1e9, to = -1e9;
5587
+ for (let i = 0; i < this.mapping.maps.length; i++) {
5588
+ let map = this.mapping.maps[i];
5589
+ if (i) {
5590
+ from = map.map(from, 1);
5591
+ to = map.map(to, -1);
5592
+ }
5593
+ map.forEach((_f, _t, fromB, toB) => {
5594
+ from = Math.min(from, fromB);
5595
+ to = Math.max(to, toB);
5596
+ });
5597
+ }
5598
+ return from == 1e9 ? null : { from, to };
5599
+ }
5600
+ /**
5442
5601
  @internal
5443
5602
  */
5444
5603
  addStep(step, doc) {
@@ -5588,19 +5747,26 @@ class Transform {
5588
5747
  return this;
5589
5748
  }
5590
5749
  /**
5591
- Remove a mark (or a mark of the given type) from the node at
5750
+ Remove a mark (or all marks of the given type) from the node at
5592
5751
  position `pos`.
5593
5752
  */
5594
5753
  removeNodeMark(pos, mark) {
5595
- if (!(mark instanceof Mark)) {
5596
- let node = this.doc.nodeAt(pos);
5597
- if (!node)
5598
- throw new RangeError("No node at position " + pos);
5599
- mark = mark.isInSet(node.marks);
5600
- if (!mark)
5601
- return this;
5754
+ let node = this.doc.nodeAt(pos);
5755
+ if (!node)
5756
+ throw new RangeError("No node at position " + pos);
5757
+ if (mark instanceof Mark) {
5758
+ if (mark.isInSet(node.marks))
5759
+ this.step(new RemoveNodeMarkStep(pos, mark));
5760
+ }
5761
+ else {
5762
+ let set = node.marks, found, steps = [];
5763
+ while (found = mark.isInSet(set)) {
5764
+ steps.push(new RemoveNodeMarkStep(pos, found));
5765
+ set = found.removeFromSet(set);
5766
+ }
5767
+ for (let i = steps.length - 1; i >= 0; i--)
5768
+ this.step(steps[i]);
5602
5769
  }
5603
- this.step(new RemoveNodeMarkStep(pos, mark));
5604
5770
  return this;
5605
5771
  }
5606
5772
  /**
@@ -5608,7 +5774,7 @@ class Transform {
5608
5774
  greater than one, any number of nodes above that. By default, the
5609
5775
  parts split off will inherit the node type of the original node.
5610
5776
  This can be changed by passing an array of types and attributes to
5611
- use after the split.
5777
+ use after the split (with the outermost nodes coming first).
5612
5778
  */
5613
5779
  split(pos, depth = 1, typesAfter) {
5614
5780
  split(this, pos, depth, typesAfter);
@@ -6276,7 +6442,6 @@ class Transaction extends Transform {
6276
6442
  else {
6277
6443
  if (to == null)
6278
6444
  to = from;
6279
- to = to == null ? from : to;
6280
6445
  if (!text)
6281
6446
  return this.deleteRange(from, to);
6282
6447
  let marks = this.storedMarks;
@@ -6285,7 +6450,7 @@ class Transaction extends Transform {
6285
6450
  marks = to == from ? $from.marks() : $from.marksAcross(this.doc.resolve(to));
6286
6451
  }
6287
6452
  this.replaceRangeWith(from, to, schema.text(text, marks));
6288
- if (!this.selection.empty)
6453
+ if (!this.selection.empty && this.selection.to == from + text.length)
6289
6454
  this.setSelection(Selection.near(this.selection.$to));
6290
6455
  return this;
6291
6456
  }
@@ -6481,7 +6646,7 @@ class EditorState {
6481
6646
  return newInstance;
6482
6647
  }
6483
6648
  /**
6484
- Start a [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state.
6649
+ Accessor that constructs and returns a new [transaction](https://prosemirror.net/docs/ref/#state.Transaction) from this state.
6485
6650
  */
6486
6651
  get tr() { return new Transaction(this); }
6487
6652
  /**
@@ -6642,5 +6807,5 @@ class PluginKey {
6642
6807
  getState(state) { return state[this.key]; }
6643
6808
  }
6644
6809
 
6645
- export { AllSelection as A, DOMSerializer as D, EditorState as E, Fragment as F, Mark as M, Node as N, Plugin as P, ReplaceError as R, Slice as S, TextSelection as T, Selection as a, NodeSelection as b, DOMParser as c, dropPoint as d, MarkType as e, findWrapping as f, canSplit as g, canJoin as h, ReplaceStep as i, joinPoint as j, ReplaceAroundStep as k, liftTarget as l, NodeRange as m, PluginKey as n, Schema as o, Mapping as p, SelectionRange as q, replaceStep as r };
6646
- //# sourceMappingURL=chunk-CBN5naeP.js.map
6810
+ export { AllSelection as A, DOMSerializer as D, EditorState as E, Fragment as F, Mark as M, Node as N, Plugin as P, ReplaceAroundStep as R, Slice as S, TextSelection as T, Selection as a, NodeSelection as b, DOMParser as c, dropPoint as d, canJoin as e, canSplit as f, findWrapping as g, ReplaceStep as h, NodeRange as i, joinPoint as j, Transform as k, liftTarget as l, PluginKey as m, RemoveMarkStep as n, Schema as o, SelectionRange as p, Mapping as q, replaceStep as r };
6811
+ //# sourceMappingURL=chunk-C5svTfyQ.js.map