prosemirror-transform 1.10.0 → 1.10.2
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.
- package/CHANGELOG.md +14 -0
- package/dist/index.cjs +38 -4
- package/dist/index.js +44 -4
- package/package.json +1 -1
- package/src/replace.ts +2 -1
- package/src/structure.ts +40 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## 1.10.2 (2024-10-11)
|
|
2
|
+
|
|
3
|
+
### Bug fixes
|
|
4
|
+
|
|
5
|
+
Allow `Transform.join` to clear incompatible inline content from the node after the join.
|
|
6
|
+
|
|
7
|
+
## 1.10.1 (2024-10-10)
|
|
8
|
+
|
|
9
|
+
### Bug fixes
|
|
10
|
+
|
|
11
|
+
Fix an issue where a `deleteRange` heuristic could produce unexpected deletion shapes.
|
|
12
|
+
|
|
13
|
+
Make `Transform.join` convert between newlines and line break replacement nodes when necessary.
|
|
14
|
+
|
|
1
15
|
## 1.10.0 (2024-08-13)
|
|
2
16
|
|
|
3
17
|
### New features
|
package/dist/index.cjs
CHANGED
|
@@ -1034,8 +1034,21 @@ function canJoin(doc, pos) {
|
|
|
1034
1034
|
index = $pos.index();
|
|
1035
1035
|
return joinable($pos.nodeBefore, $pos.nodeAfter) && $pos.parent.canReplace(index, index + 1);
|
|
1036
1036
|
}
|
|
1037
|
+
function canAppendWithSubstitutedLinebreaks(a, b) {
|
|
1038
|
+
if (!b.content.size) a.type.compatibleContent(b.type);
|
|
1039
|
+
var match = a.contentMatchAt(a.childCount);
|
|
1040
|
+
var linebreakReplacement = a.type.schema.linebreakReplacement;
|
|
1041
|
+
for (var i = 0; i < b.childCount; i++) {
|
|
1042
|
+
var child = b.child(i);
|
|
1043
|
+
var type = child.type == linebreakReplacement ? a.type.schema.nodes.text : child.type;
|
|
1044
|
+
match = match.matchType(type);
|
|
1045
|
+
if (!match) return false;
|
|
1046
|
+
if (!a.type.allowsMarks(child.marks)) return false;
|
|
1047
|
+
}
|
|
1048
|
+
return match.validEnd;
|
|
1049
|
+
}
|
|
1037
1050
|
function joinable(a, b) {
|
|
1038
|
-
return !!(a && b && !a.isLeaf && a
|
|
1051
|
+
return !!(a && b && !a.isLeaf && canAppendWithSubstitutedLinebreaks(a, b));
|
|
1039
1052
|
}
|
|
1040
1053
|
function joinPoint(doc, pos) {
|
|
1041
1054
|
var dir = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : -1;
|
|
@@ -1061,8 +1074,29 @@ function joinPoint(doc, pos) {
|
|
|
1061
1074
|
}
|
|
1062
1075
|
}
|
|
1063
1076
|
function _join(tr, pos, depth) {
|
|
1064
|
-
var
|
|
1065
|
-
tr.
|
|
1077
|
+
var convertNewlines = null;
|
|
1078
|
+
var linebreakReplacement = tr.doc.type.schema.linebreakReplacement;
|
|
1079
|
+
var $before = tr.doc.resolve(pos - depth),
|
|
1080
|
+
beforeType = $before.node().type;
|
|
1081
|
+
if (linebreakReplacement && beforeType.inlineContent) {
|
|
1082
|
+
var pre = beforeType.whitespace == "pre";
|
|
1083
|
+
var supportLinebreak = !!beforeType.contentMatch.matchType(linebreakReplacement);
|
|
1084
|
+
if (pre && !supportLinebreak) convertNewlines = false;else if (!pre && supportLinebreak) convertNewlines = true;
|
|
1085
|
+
}
|
|
1086
|
+
var mapFrom = tr.steps.length;
|
|
1087
|
+
if (convertNewlines === false) {
|
|
1088
|
+
var $after = tr.doc.resolve(pos + depth);
|
|
1089
|
+
replaceLinebreaks(tr, $after.node(), $after.before(), mapFrom);
|
|
1090
|
+
}
|
|
1091
|
+
if (beforeType.inlineContent) _clearIncompatible(tr, pos + depth - 1, beforeType, $before.node().contentMatchAt($before.index()), convertNewlines == null);
|
|
1092
|
+
var mapping = tr.mapping.slice(mapFrom),
|
|
1093
|
+
start = mapping.map(pos - depth);
|
|
1094
|
+
tr.step(new ReplaceStep(start, mapping.map(pos + depth, -1), prosemirrorModel.Slice.empty, true));
|
|
1095
|
+
if (convertNewlines === true) {
|
|
1096
|
+
var $full = tr.doc.resolve(start);
|
|
1097
|
+
replaceNewlines(tr, $full.node(), $full.before(), tr.steps.length);
|
|
1098
|
+
}
|
|
1099
|
+
return tr;
|
|
1066
1100
|
}
|
|
1067
1101
|
function insertPoint(doc, pos, nodeType) {
|
|
1068
1102
|
var $pos = doc.resolve(pos);
|
|
@@ -1475,7 +1509,7 @@ function _deleteRange(tr, from, to) {
|
|
|
1475
1509
|
if (depth > 0 && (last || $from.node(depth - 1).canReplace($from.index(depth - 1), $to.indexAfter(depth - 1)))) return tr["delete"]($from.before(depth), $to.after(depth));
|
|
1476
1510
|
}
|
|
1477
1511
|
for (var d = 1; d <= $from.depth && d <= $to.depth; d++) {
|
|
1478
|
-
if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d) return tr["delete"]($from.before(d), to);
|
|
1512
|
+
if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d && $from.start(d - 1) == $to.start(d - 1) && $from.node(d - 1).canReplace($from.index(d - 1), $to.index(d - 1))) return tr["delete"]($from.before(d), to);
|
|
1479
1513
|
}
|
|
1480
1514
|
tr["delete"](from, to);
|
|
1481
1515
|
}
|
package/dist/index.js
CHANGED
|
@@ -1183,8 +1183,24 @@ function canJoin(doc, pos) {
|
|
|
1183
1183
|
return joinable($pos.nodeBefore, $pos.nodeAfter) &&
|
|
1184
1184
|
$pos.parent.canReplace(index, index + 1);
|
|
1185
1185
|
}
|
|
1186
|
+
function canAppendWithSubstitutedLinebreaks(a, b) {
|
|
1187
|
+
if (!b.content.size)
|
|
1188
|
+
a.type.compatibleContent(b.type);
|
|
1189
|
+
let match = a.contentMatchAt(a.childCount);
|
|
1190
|
+
let { linebreakReplacement } = a.type.schema;
|
|
1191
|
+
for (let i = 0; i < b.childCount; i++) {
|
|
1192
|
+
let child = b.child(i);
|
|
1193
|
+
let type = child.type == linebreakReplacement ? a.type.schema.nodes.text : child.type;
|
|
1194
|
+
match = match.matchType(type);
|
|
1195
|
+
if (!match)
|
|
1196
|
+
return false;
|
|
1197
|
+
if (!a.type.allowsMarks(child.marks))
|
|
1198
|
+
return false;
|
|
1199
|
+
}
|
|
1200
|
+
return match.validEnd;
|
|
1201
|
+
}
|
|
1186
1202
|
function joinable(a, b) {
|
|
1187
|
-
return !!(a && b && !a.isLeaf && a
|
|
1203
|
+
return !!(a && b && !a.isLeaf && canAppendWithSubstitutedLinebreaks(a, b));
|
|
1188
1204
|
}
|
|
1189
1205
|
/**
|
|
1190
1206
|
Find an ancestor of the given position that can be joined to the
|
|
@@ -1217,8 +1233,31 @@ function joinPoint(doc, pos, dir = -1) {
|
|
|
1217
1233
|
}
|
|
1218
1234
|
}
|
|
1219
1235
|
function join(tr, pos, depth) {
|
|
1220
|
-
let
|
|
1221
|
-
tr.
|
|
1236
|
+
let convertNewlines = null;
|
|
1237
|
+
let { linebreakReplacement } = tr.doc.type.schema;
|
|
1238
|
+
let $before = tr.doc.resolve(pos - depth), beforeType = $before.node().type;
|
|
1239
|
+
if (linebreakReplacement && beforeType.inlineContent) {
|
|
1240
|
+
let pre = beforeType.whitespace == "pre";
|
|
1241
|
+
let supportLinebreak = !!beforeType.contentMatch.matchType(linebreakReplacement);
|
|
1242
|
+
if (pre && !supportLinebreak)
|
|
1243
|
+
convertNewlines = false;
|
|
1244
|
+
else if (!pre && supportLinebreak)
|
|
1245
|
+
convertNewlines = true;
|
|
1246
|
+
}
|
|
1247
|
+
let mapFrom = tr.steps.length;
|
|
1248
|
+
if (convertNewlines === false) {
|
|
1249
|
+
let $after = tr.doc.resolve(pos + depth);
|
|
1250
|
+
replaceLinebreaks(tr, $after.node(), $after.before(), mapFrom);
|
|
1251
|
+
}
|
|
1252
|
+
if (beforeType.inlineContent)
|
|
1253
|
+
clearIncompatible(tr, pos + depth - 1, beforeType, $before.node().contentMatchAt($before.index()), convertNewlines == null);
|
|
1254
|
+
let mapping = tr.mapping.slice(mapFrom), start = mapping.map(pos - depth);
|
|
1255
|
+
tr.step(new ReplaceStep(start, mapping.map(pos + depth, -1), Slice.empty, true));
|
|
1256
|
+
if (convertNewlines === true) {
|
|
1257
|
+
let $full = tr.doc.resolve(start);
|
|
1258
|
+
replaceNewlines(tr, $full.node(), $full.before(), tr.steps.length);
|
|
1259
|
+
}
|
|
1260
|
+
return tr;
|
|
1222
1261
|
}
|
|
1223
1262
|
/**
|
|
1224
1263
|
Try to find a point where a node of the given type can be inserted
|
|
@@ -1702,7 +1741,8 @@ function deleteRange(tr, from, to) {
|
|
|
1702
1741
|
return tr.delete($from.before(depth), $to.after(depth));
|
|
1703
1742
|
}
|
|
1704
1743
|
for (let d = 1; d <= $from.depth && d <= $to.depth; d++) {
|
|
1705
|
-
if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d
|
|
1744
|
+
if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d &&
|
|
1745
|
+
$from.start(d - 1) == $to.start(d - 1) && $from.node(d - 1).canReplace($from.index(d - 1), $to.index(d - 1)))
|
|
1706
1746
|
return tr.delete($from.before(d), to);
|
|
1707
1747
|
}
|
|
1708
1748
|
tr.delete(from, to);
|
package/package.json
CHANGED
package/src/replace.ts
CHANGED
|
@@ -434,7 +434,8 @@ export function deleteRange(tr: Transform, from: number, to: number) {
|
|
|
434
434
|
return tr.delete($from.before(depth), $to.after(depth))
|
|
435
435
|
}
|
|
436
436
|
for (let d = 1; d <= $from.depth && d <= $to.depth; d++) {
|
|
437
|
-
if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d
|
|
437
|
+
if (from - $from.start(d) == $from.depth - d && to > $from.end(d) && $to.end(d) - to != $to.depth - d &&
|
|
438
|
+
$from.start(d - 1) == $to.start(d - 1) && $from.node(d - 1).canReplace($from.index(d - 1), $to.index(d - 1)))
|
|
438
439
|
return tr.delete($from.before(d), to)
|
|
439
440
|
}
|
|
440
441
|
tr.delete(from, to)
|
package/src/structure.ts
CHANGED
|
@@ -132,7 +132,7 @@ export function setBlockType(tr: Transform, from: number, to: number,
|
|
|
132
132
|
let mapping = tr.mapping.slice(mapFrom)
|
|
133
133
|
let startM = mapping.map(pos, 1), endM = mapping.map(pos + node.nodeSize, 1)
|
|
134
134
|
tr.step(new ReplaceAroundStep(startM, endM, startM + 1, endM - 1,
|
|
135
|
-
|
|
135
|
+
new Slice(Fragment.from(type.create(attrsHere, null, node.marks)), 0, 0), 1, true))
|
|
136
136
|
if (convertNewlines === true) replaceNewlines(tr, node, pos, mapFrom)
|
|
137
137
|
return false
|
|
138
138
|
}
|
|
@@ -226,8 +226,22 @@ export function canJoin(doc: Node, pos: number): boolean {
|
|
|
226
226
|
$pos.parent.canReplace(index, index + 1)
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
function canAppendWithSubstitutedLinebreaks(a: Node, b: Node) {
|
|
230
|
+
if (!b.content.size) a.type.compatibleContent(b.type)
|
|
231
|
+
let match: ContentMatch | null = a.contentMatchAt(a.childCount)
|
|
232
|
+
let {linebreakReplacement} = a.type.schema
|
|
233
|
+
for (let i = 0; i < b.childCount; i++) {
|
|
234
|
+
let child = b.child(i)
|
|
235
|
+
let type = child.type == linebreakReplacement ? a.type.schema.nodes.text : child.type
|
|
236
|
+
match = match.matchType(type)
|
|
237
|
+
if (!match) return false
|
|
238
|
+
if (!a.type.allowsMarks(child.marks)) return false
|
|
239
|
+
}
|
|
240
|
+
return match.validEnd
|
|
241
|
+
}
|
|
242
|
+
|
|
229
243
|
function joinable(a: Node | null, b: Node | null) {
|
|
230
|
-
return !!(a && b && !a.isLeaf && a
|
|
244
|
+
return !!(a && b && !a.isLeaf && canAppendWithSubstitutedLinebreaks(a, b))
|
|
231
245
|
}
|
|
232
246
|
|
|
233
247
|
/// Find an ancestor of the given position that can be joined to the
|
|
@@ -256,8 +270,30 @@ export function joinPoint(doc: Node, pos: number, dir = -1) {
|
|
|
256
270
|
}
|
|
257
271
|
|
|
258
272
|
export function join(tr: Transform, pos: number, depth: number) {
|
|
259
|
-
let
|
|
260
|
-
tr.
|
|
273
|
+
let convertNewlines = null
|
|
274
|
+
let {linebreakReplacement} = tr.doc.type.schema
|
|
275
|
+
let $before = tr.doc.resolve(pos - depth), beforeType = $before.node().type
|
|
276
|
+
if (linebreakReplacement && beforeType.inlineContent) {
|
|
277
|
+
let pre = beforeType.whitespace == "pre"
|
|
278
|
+
let supportLinebreak = !!beforeType.contentMatch.matchType(linebreakReplacement)
|
|
279
|
+
if (pre && !supportLinebreak) convertNewlines = false
|
|
280
|
+
else if (!pre && supportLinebreak) convertNewlines = true
|
|
281
|
+
}
|
|
282
|
+
let mapFrom = tr.steps.length
|
|
283
|
+
if (convertNewlines === false) {
|
|
284
|
+
let $after = tr.doc.resolve(pos + depth)
|
|
285
|
+
replaceLinebreaks(tr, $after.node(), $after.before(), mapFrom)
|
|
286
|
+
}
|
|
287
|
+
if (beforeType.inlineContent)
|
|
288
|
+
clearIncompatible(tr, pos + depth - 1, beforeType,
|
|
289
|
+
$before.node().contentMatchAt($before.index()), convertNewlines == null)
|
|
290
|
+
let mapping = tr.mapping.slice(mapFrom), start = mapping.map(pos - depth)
|
|
291
|
+
tr.step(new ReplaceStep(start, mapping.map(pos + depth, - 1), Slice.empty, true))
|
|
292
|
+
if (convertNewlines === true) {
|
|
293
|
+
let $full = tr.doc.resolve(start)
|
|
294
|
+
replaceNewlines(tr, $full.node(), $full.before(), tr.steps.length)
|
|
295
|
+
}
|
|
296
|
+
return tr
|
|
261
297
|
}
|
|
262
298
|
|
|
263
299
|
/// Try to find a point where a node of the given type can be inserted
|