prosemirror-changeset
Advanced tools
+605
| // Convert the given range of a fragment to tokens, where node open | ||
| // tokens are encoded as strings holding the node name, characters as | ||
| // their character code, and node close tokens as -1. | ||
| function tokens(frag, start, end, target) { | ||
| for (var i = 0, off = 0; i < frag.childCount; i++) { | ||
| var child = frag.child(i), endOff = off + child.nodeSize; | ||
| var from = Math.max(off, start), to = Math.min(endOff, end); | ||
| if (from < to) { | ||
| if (child.isText) { | ||
| for (var j = from; j < to; j++) { target.push(child.text.charCodeAt(j - off)); } | ||
| } else if (child.isLeaf) { | ||
| target.push(child.type.name); | ||
| } else { | ||
| if (from == off) { target.push(child.type.name); } | ||
| tokens(child.content, Math.max(off + 1, from) - off - 1, Math.min(endOff - 1, to) - off - 1, target); | ||
| if (to == endOff) { target.push(-1); } | ||
| } | ||
| } | ||
| off = endOff; | ||
| } | ||
| return target | ||
| } | ||
| // The code below will refuse to compute a diff with more than 5000 | ||
| // insertions or deletions, which takes about 300ms to reach on my | ||
| // machine. This is a safeguard against runaway computations. | ||
| var MAX_DIFF_SIZE = 5000; | ||
| // This obscure mess of constants computes the minimum length of an | ||
| // unchanged range (not at the start/end of the compared content). The | ||
| // idea is to make it higher in bigger replacements, so that you don't | ||
| // get a diff soup of coincidentally identical letters when replacing | ||
| // a paragraph. | ||
| function minUnchanged(sizeA, sizeB) { | ||
| return Math.min(15, Math.max(2, Math.floor(Math.max(sizeA, sizeB) / 10))) | ||
| } | ||
| // : (Fragment, Fragment, Change) → [Change] | ||
| function computeDiff(fragA, fragB, range) { | ||
| var tokA = tokens(fragA, range.fromA, range.toA, []); | ||
| var tokB = tokens(fragB, range.fromB, range.toB, []); | ||
| // Scan from both sides to cheaply eliminate work | ||
| var start = 0, endA = tokA.length, endB = tokB.length; | ||
| while (start < tokA.length && start < tokB.length && tokA[start] === tokB[start]) { start++; } | ||
| if (start == tokA.length && start == tokB.length) { return [] } | ||
| while (endA > start && endB > start && tokA[endA - 1] === tokB[endB - 1]) { endA--, endB--; } | ||
| // If the result is simple _or_ too big to cheaply compute, return | ||
| // the remaining region as the diff | ||
| if (endA == start || endB == start || (endA == endB && endA == start + 1)) | ||
| { return [range.slice(start, endA, start, endB)] } | ||
| // This is an implementation of Myers' diff algorithm | ||
| // See https://neil.fraser.name/writing/diff/myers.pdf and | ||
| // https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/ | ||
| var lenA = endA - start, lenB = endB - start; | ||
| var max = Math.min(MAX_DIFF_SIZE, lenA + lenB), off = max + 1; | ||
| var history = []; | ||
| var frontier = []; | ||
| for (var len = off * 2, i = 0; i < len; i++) { frontier[i] = -1; } | ||
| for (var size = 0; size <= max; size++) { | ||
| for (var diag = -size; diag <= size; diag += 2) { | ||
| var next = frontier[diag + 1 + max], prev = frontier[diag - 1 + max]; | ||
| var x = next < prev ? prev : next + 1, y = x + diag; | ||
| while (x < lenA && y < lenB && tokA[start + x] === tokB[start + y]) { x++, y++; } | ||
| frontier[diag + max] = x; | ||
| // Found a match | ||
| if (x >= lenA && y >= lenB) { | ||
| // Trace back through the history to build up a set of changed ranges. | ||
| var diff = [], minSpan = minUnchanged(endA - start, endB - start); | ||
| // Used to add steps to a diff one at a time, back to front, merging | ||
| // ones that are less than minSpan tokens apart | ||
| var fromA = -1, toA = -1, fromB = -1, toB = -1; | ||
| var add = function (fA, tA, fB, tB) { | ||
| if (fromA > -1 && fromA < tA + minSpan) { | ||
| fromA = fA; fromB = fB; | ||
| } else { | ||
| if (fromA > -1) | ||
| { diff.push(range.slice(fromA, toA, fromB, toB)); } | ||
| fromA = fA; toA = tA; | ||
| fromB = fB; toB = tB; | ||
| } | ||
| }; | ||
| for (var i$1 = size - 1; i$1 >= 0; i$1--) { | ||
| var next$1 = frontier[diag + 1 + max], prev$1 = frontier[diag - 1 + max]; | ||
| if (next$1 < prev$1) { // Deletion | ||
| diag--; | ||
| x = prev$1 + start; y = x + diag; | ||
| add(x, x, y, y + 1); | ||
| } else { // Insertion | ||
| diag++; | ||
| x = next$1 + start; y = x + diag; | ||
| add(x, x + 1, y, y); | ||
| } | ||
| frontier = history[i$1 >> 1]; | ||
| } | ||
| if (fromA > -1) { diff.push(range.slice(fromA, toA, fromB, toB)); } | ||
| return diff.reverse() | ||
| } | ||
| } | ||
| // Since only either odd or even diagonals are read from each | ||
| // frontier, we only copy them every other iteration. | ||
| if (size % 2 == 0) { history.push(frontier.slice()); } | ||
| } | ||
| // The loop exited, meaning the maximum amount of work was done. | ||
| // Just return a change spanning the entire range. | ||
| return [range.slice(start, endA, start, endB)] | ||
| } | ||
| // ::- Stores metadata for a part of a change. | ||
| var Span = function Span(length, data) { | ||
| // :: number | ||
| this.length = length; | ||
| // :: any | ||
| this.data = data; | ||
| }; | ||
| Span.prototype.cut = function cut (length) { | ||
| return length == this.length ? this : new Span(length, this.data) | ||
| }; | ||
| Span.slice = function slice (spans, from, to) { | ||
| if (from == to) { return Span.none } | ||
| if (from == 0 && to == Span.len(spans)) { return spans } | ||
| var result = []; | ||
| for (var i = 0, off = 0; off < to; i++) { | ||
| var span = spans[i], end = off + span.length; | ||
| var overlap = Math.min(to, end) - Math.max(from, off); | ||
| if (overlap > 0) { result.push(span.cut(overlap)); } | ||
| off = end; | ||
| } | ||
| return result | ||
| }; | ||
| Span.join = function join (a, b, combine) { | ||
| if (a.length == 0) { return b } | ||
| if (b.length == 0) { return a } | ||
| var combined = combine(a[a.length - 1].data, b[0].data); | ||
| if (combined == null) { return a.concat(b) } | ||
| var result = a.slice(0, a.length - 1); | ||
| result.push(new Span(a[a.length - 1].length + b[0].length, combined)); | ||
| for (var i = 1; i < b.length; i++) { result.push(b[i]); } | ||
| return result | ||
| }; | ||
| Span.len = function len (spans) { | ||
| var len = 0; | ||
| for (var i = 0; i < spans.length; i++) { len += spans[i].length; } | ||
| return len | ||
| }; | ||
| Span.none = []; | ||
| // ::- A replaced range with metadata associated with it. | ||
| var Change = function Change(fromA, toA, fromB, toB, deleted, inserted) { | ||
| // :: number The start of the range deleted/replaced in the old | ||
| // document. | ||
| this.fromA = fromA; | ||
| // :: number The end of the range in the old document. | ||
| this.toA = toA; | ||
| // :: number The start of the range inserted in the new document. | ||
| this.fromB = fromB; | ||
| // :: number The end of the range in the new document. | ||
| this.toB = toB; | ||
| // :: [Span] Data associated with the deleted content. The length | ||
| // of these spans adds up to `this.toA - this.fromA`. | ||
| this.deleted = deleted; | ||
| // :: [Span] Data associated with the inserted content. Length | ||
| // adds up to `this.toB - this.toA`. | ||
| this.inserted = inserted; | ||
| }; | ||
| var prototypeAccessors = { lenA: { configurable: true },lenB: { configurable: true } }; | ||
| prototypeAccessors.lenA.get = function () { return this.toA - this.fromA }; | ||
| prototypeAccessors.lenB.get = function () { return this.toB - this.fromB }; | ||
| Change.prototype.slice = function slice (startA, endA, startB, endB) { | ||
| if (startA == 0 && startB == 0 && endA == this.toA - this.fromA && | ||
| endB == this.toB - this.fromB) { return this } | ||
| return new Change(this.fromA + startA, this.fromA + endA, | ||
| this.fromB + startB, this.fromB + endB, | ||
| Span.slice(this.deleted, startA, endA), | ||
| Span.slice(this.inserted, startB, endB)) | ||
| }; | ||
| // : ([Change], [Change], (any, any) → any) → [Change] | ||
| // This merges two changesets (the end document of x should be the | ||
| // start document of y) into a single one spanning the start of x to | ||
| // the end of y. | ||
| Change.merge = function merge (x, y, combine) { | ||
| if (x.length == 0) { return y } | ||
| if (y.length == 0) { return x } | ||
| var result = []; | ||
| // Iterate over both sets in parallel, using the middle coordinate | ||
| // system (B in x, A in y) to synchronize. | ||
| for (var iX = 0, iY = 0, curX = x[0], curY = y[0];;) { | ||
| if (!curX && !curY) { | ||
| return result | ||
| } else if (curX && (!curY || curX.toB < curY.fromA)) { // curX entirely in front of curY | ||
| var off = iY ? y[iY - 1].toB - y[iY - 1].toA : 0; | ||
| result.push(off == 0 ? curX : | ||
| new Change(curX.fromA, curX.toA, curX.fromB + off, curX.toB + off, | ||
| curX.deleted, curX.inserted)); | ||
| curX = iX++ == x.length ? null : x[iX]; | ||
| } else if (curY && (!curX || curY.toA < curX.fromB)) { // curY entirely in front of curX | ||
| var off$1 = iX ? x[iX - 1].toB - x[iX - 1].toA : 0; | ||
| result.push(off$1 == 0 ? curY : | ||
| new Change(curY.fromA - off$1, curY.toA - off$1, curY.fromB, curY.toB, | ||
| curY.deleted, curY.inserted)); | ||
| curY = iY++ == y.length ? null : y[iY]; | ||
| } else { // Touch, need to merge | ||
| // The rules for merging ranges are that deletions from the | ||
| // old set and insertions from the new are kept. Areas of the | ||
| // middle document covered by a but not by b are insertions | ||
| // from a that need to be added, and areas covered by b but | ||
| // not a are deletions from b that need to be added. | ||
| var pos = Math.min(curX.fromB, curY.fromA); | ||
| var fromA = Math.min(curX.fromA, curY.fromA - (iX ? x[iX - 1].toB - x[iX - 1].toA : 0)), toA = fromA; | ||
| var fromB = Math.min(curY.fromB, curX.fromB + (iY ? y[iY - 1].toB - y[iY - 1].toA : 0)), toB = fromB; | ||
| var deleted = Span.none, inserted = Span.none; | ||
| // Used to prevent appending ins/del range for the same Change twice | ||
| var enteredX = false, enteredY = false; | ||
| // Need to have an inner loop since any number of further | ||
| // ranges might be touching this group | ||
| for (;;) { | ||
| var nextX = !curX ? 2e8 : pos >= curX.fromB ? curX.toB : curX.fromB; | ||
| var nextY = !curY ? 2e8 : pos >= curY.fromA ? curY.toA : curY.fromA; | ||
| var next = Math.min(nextX, nextY); | ||
| var inX = curX && pos >= curX.fromB, inY = curY && pos >= curY.fromA; | ||
| if (!inX && !inY) { break } | ||
| if (inX && pos == curX.fromB && !enteredX) { | ||
| deleted = Span.join(deleted, curX.deleted, combine); | ||
| toA += curX.lenA; | ||
| enteredX = true; | ||
| } | ||
| if (inX && !inY) { | ||
| inserted = Span.join(inserted, Span.slice(curX.inserted, pos - curX.fromB, next - curX.fromB), combine); | ||
| toB += next - pos; | ||
| } | ||
| if (inY && pos == curY.fromA && !enteredY) { | ||
| inserted = Span.join(inserted, curY.inserted, combine); | ||
| toB += curY.lenB; | ||
| enteredY = true; | ||
| } | ||
| if (inY && !inX) { | ||
| deleted = Span.join(deleted, Span.slice(curY.deleted, pos - curY.fromA, next - curY.fromA), combine); | ||
| toA += next - pos; | ||
| } | ||
| if (inX && next == curX.toB) { | ||
| curX = iX++ == x.length ? null : x[iX]; | ||
| enteredX = false; | ||
| } | ||
| if (inY && next == curY.toA) { | ||
| curY = iY++ == y.length ? null : y[iY]; | ||
| enteredY = false; | ||
| } | ||
| pos = next; | ||
| } | ||
| if (fromA < toA || fromB < toB) | ||
| { result.push(new Change(fromA, toA, fromB, toB, deleted, inserted)); } | ||
| } | ||
| } | ||
| }; | ||
| Object.defineProperties( Change.prototype, prototypeAccessors ); | ||
| var letter; | ||
| // If the runtime support unicode properties in regexps, that's a good | ||
| // source of info on whether something is a letter. | ||
| try { letter = new RegExp("[\\p{Alphabetic}_]", "u"); } catch(_) {} | ||
| // Otherwise, we see if the character changes when upper/lowercased, | ||
| // or if it is part of these common single-case scripts. | ||
| var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; | ||
| function isLetter(code) { | ||
| if (code < 128) | ||
| { return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 79 && code <= 122 } | ||
| var ch = String.fromCharCode(code); | ||
| if (letter) { return letter.test(ch) } | ||
| return ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch) | ||
| } | ||
| // Convert a range of document into a string, so that we can easily | ||
| // access characters at a given position. Treat non-text tokens as | ||
| // spaces so that they aren't considered part of a word. | ||
| function getText(frag, start, end) { | ||
| var out = ""; | ||
| function convert(frag, start, end) { | ||
| for (var i = 0, off = 0; i < frag.childCount; i++) { | ||
| var child = frag.child(i), endOff = off + child.nodeSize; | ||
| var from = Math.max(off, start), to = Math.min(endOff, end); | ||
| if (from < to) { | ||
| if (child.isText) { | ||
| out += child.text.slice(Math.max(0, start - off), Math.min(child.text.length, end - off)); | ||
| } else if (child.isLeaf) { | ||
| out += " "; | ||
| } else { | ||
| if (from == off) { out += " "; } | ||
| convert(child.content, Math.max(0, from - off - 1), Math.min(child.content.size, end - off)); | ||
| if (to == endOff) { out += " "; } | ||
| } | ||
| } | ||
| off = endOff; | ||
| } | ||
| } | ||
| convert(frag, start, end); | ||
| return out | ||
| } | ||
| // The distance changes have to be apart for us to not consider them | ||
| // candidates for merging. | ||
| var MAX_SIMPLIFY_DISTANCE = 30; | ||
| // :: ([Change], Node) → [Change] | ||
| // Simplifies a set of changes for presentation. This makes the | ||
| // assumption that having both insertions and deletions within a word | ||
| // is confusing, and, when such changes occur without a word boundary | ||
| // between them, they should be expanded to cover the entire set of | ||
| // words (in the new document) they touch. An exception is made for | ||
| // single-character replacements. | ||
| function simplifyChanges(changes, doc) { | ||
| var result = []; | ||
| for (var i = 0; i < changes.length; i++) { | ||
| var end = changes[i].toB, start = i; | ||
| while (i < changes.length - 1 && changes[i + 1].fromB <= end + MAX_SIMPLIFY_DISTANCE) | ||
| { end = changes[++i].toB; } | ||
| simplifyAdjacentChanges(changes, start, i + 1, doc, result); | ||
| } | ||
| return result | ||
| } | ||
| function simplifyAdjacentChanges(changes, from, to, doc, target) { | ||
| var start = Math.max(0, changes[from].fromB - MAX_SIMPLIFY_DISTANCE); | ||
| var end = Math.min(doc.content.size, changes[to - 1].toB + MAX_SIMPLIFY_DISTANCE); | ||
| var text = getText(doc.content, start, end); | ||
| for (var i = from; i < to; i++) { | ||
| var startI = i, last = changes[i], deleted = last.lenA, inserted = last.lenB; | ||
| while (i < to - 1) { | ||
| var next = changes[i + 1], boundary = false; | ||
| var prevLetter = last.toB == end ? false : isLetter(text.charCodeAt(last.toB - 1 - start)); | ||
| for (var pos = last.toB; !boundary && pos < next.fromB; pos++) { | ||
| var nextLetter = pos == end ? false : isLetter(text.charCodeAt(pos - start)); | ||
| if ((!prevLetter || !nextLetter) && pos != changes[startI].fromB) { boundary = true; } | ||
| prevLetter = nextLetter; | ||
| } | ||
| if (boundary) { break } | ||
| deleted += next.lenA; inserted += next.lenB; | ||
| last = next; | ||
| i++; | ||
| } | ||
| if (inserted > 0 && deleted > 0 && !(inserted == 1 && deleted == 1)) { | ||
| var from$1 = changes[startI].fromB, to$1 = changes[i].toB; | ||
| if (from$1 < end && isLetter(text.charCodeAt(from$1 - start))) | ||
| { while (from$1 > start && isLetter(text.charCodeAt(from$1 - 1 - start))) { from$1--; } } | ||
| if (to$1 > start && isLetter(text.charCodeAt(to$1 - 1 - start))) | ||
| { while (to$1 < end && isLetter(text.charCodeAt(to$1 - start))) { to$1++; } } | ||
| var joined = fillChange(changes.slice(startI, i + 1), from$1, to$1); | ||
| var last$1 = target.length ? target[target.length - 1] : null; | ||
| if (last$1 && last$1.toA == joined.fromA) | ||
| { target[target.length - 1] = new Change(last$1.fromA, joined.toA, last$1.fromB, joined.toB, | ||
| last$1.deleted.concat(joined.deleted), last$1.inserted.concat(joined.inserted)); } | ||
| else | ||
| { target.push(joined); } | ||
| } else { | ||
| for (var j = startI; j <= i; j++) { target.push(changes[j]); } | ||
| } | ||
| } | ||
| return changes | ||
| } | ||
| function combine(a, b) { return a === b ? a : null } | ||
| function fillChange(changes, fromB, toB) { | ||
| var fromA = changes[0].fromA - (changes[0].fromB - fromB); | ||
| var last = changes[changes.length - 1]; | ||
| var toA = last.toA + (toB - last.toB); | ||
| var deleted = Span.none, inserted = Span.none; | ||
| var delData = (changes[0].deleted.length ? changes[0].deleted : changes[0].inserted)[0].data; | ||
| var insData = (changes[0].inserted.length ? changes[0].inserted : changes[0].deleted)[0].data; | ||
| for (var posA = fromA, posB = fromB, i = 0;; i++) { | ||
| var next = i == changes.length ? null : changes[i]; | ||
| var endA = next ? next.fromA : toA, endB = next ? next.fromB : toB; | ||
| if (endA > posA) { deleted = Span.join(deleted, [new Span(endA - posA, delData)], combine); } | ||
| if (endB > posB) { inserted = Span.join(inserted, [new Span(endB - posB, insData)], combine); } | ||
| if (!next) { break } | ||
| deleted = Span.join(deleted, next.deleted, combine); | ||
| inserted = Span.join(inserted, next.inserted, combine); | ||
| if (deleted.length) { delData = deleted[deleted.length - 1].data; } | ||
| if (inserted.length) { insData = inserted[inserted.length - 1].data; } | ||
| posA = next.toA; posB = next.toB; | ||
| } | ||
| return new Change(fromA, toA, fromB, toB, deleted, inserted) | ||
| } | ||
| // ::- A change set tracks the changes to a document from a given | ||
| // point in the past. It condenses a number of step maps down to a | ||
| // flat sequence of replacements, and simplifies replacments that | ||
| // partially undo themselves by comparing their content. | ||
| var ChangeSet = function ChangeSet(config, changes) { | ||
| this.config = config; | ||
| // :: [Change] Replaced regions. | ||
| this.changes = changes; | ||
| }; | ||
| var prototypeAccessors$1 = { startDoc: { configurable: true } }; | ||
| // :: (Node, [StepMap], union<[any], any>) → ChangeSet | ||
| // Computes a new changeset by adding the given step maps and | ||
| // metadata (either as an array, per-map, or as a single value to be | ||
| // associated with all maps) to the current set. Will not mutate the | ||
| // old set. | ||
| // | ||
| // Note that due to simplification that happens after each add, | ||
| // incrementally adding steps might create a different final set | ||
| // than adding all those changes at once, since different document | ||
| // tokens might be matched during simplification depending on the | ||
| // boundaries of the current changed ranges. | ||
| ChangeSet.prototype.addSteps = function addSteps (newDoc, maps, data) { | ||
| var this$1 = this; | ||
| // This works by inspecting the position maps for the changes, | ||
| // which indicate what parts of the document were replaced by new | ||
| // content, and the size of that new content. It uses these to | ||
| // build up Change objects. | ||
| // | ||
| // These change objects are put in sets and merged together using | ||
| // Change.merge, giving us the changes created by the new steps. | ||
| // Those changes can then be merged with the existing set of | ||
| // changes. | ||
| // | ||
| // For each change that was touched by the new steps, we recompute | ||
| // a diff to try to minimize the change by dropping matching | ||
| // pieces of the old and new document from the change. | ||
| var stepChanges = []; | ||
| // Add spans for new steps. | ||
| var loop = function ( i ) { | ||
| var d = Array.isArray(data) ? data[i] : data; | ||
| var off = 0; | ||
| maps[i].forEach(function (fromA, toA, fromB, toB) { | ||
| stepChanges.push(new Change(fromA + off, toA + off, fromB, toB, | ||
| fromA == toA ? Span.none : [new Span(toA - fromA, d)], | ||
| fromB == toB ? Span.none : [new Span(toB - fromB, d)])); | ||
| off = (toB - fromB) - (toA - fromA); | ||
| }); | ||
| }; | ||
| for (var i = 0; i < maps.length; i++) loop( i ); | ||
| if (stepChanges.length == 0) { return this } | ||
| var newChanges = mergeAll(stepChanges, this.config.combine); | ||
| var changes = Change.merge(this.changes, newChanges, this.config.combine); | ||
| // Minimize changes when possible | ||
| var loop$1 = function ( i$2 ) { | ||
| var change = changes[i$2]; | ||
| if (change.fromA == change.toA || change.fromB == change.toB || | ||
| // Only look at changes that touch newly added changed ranges | ||
| !newChanges.some(function (r) { return r.toB > change.fromB && r.fromB < change.toB; })) { return } | ||
| var diff = computeDiff(this$1.config.doc.content, newDoc.content, change); | ||
| // Fast path: If they are completely different, don't do anything | ||
| if (diff.length == 1 && diff[0].fromB == 0 && diff[0].toB == change.toB - change.fromB) | ||
| { return } | ||
| if (diff.length == 1) { | ||
| changes[i$2] = diff[0]; | ||
| } else { | ||
| changes.splice.apply(changes, [ i$2, 1 ].concat( diff )); | ||
| i$2 += diff.length - 1; | ||
| } | ||
| i$1 = i$2; | ||
| }; | ||
| for (var i$1 = 0; i$1 < changes.length; i$1++) loop$1( i$1 ); | ||
| return new ChangeSet(this.config, changes) | ||
| }; | ||
| // :: Node | ||
| // The starting document of the change set. | ||
| prototypeAccessors$1.startDoc.get = function () { return this.config.doc }; | ||
| // :: (f: (range: Change) → any) → ChangeSet | ||
| // Map the span's data values in the given set through a function | ||
| // and construct a new set with the resulting data. | ||
| ChangeSet.prototype.map = function map (f) { | ||
| return new ChangeSet(this.config, this.changes.map(function (change) { | ||
| var data = f(change); | ||
| return data === change.data ? change : | ||
| new Change(change.fromA, change.toA, change.fromB, change.toB, data) | ||
| })) | ||
| }; | ||
| // :: (ChangeSet, ?[StepMap]) → ?{from: number, to: number} | ||
| // Compare two changesets and return the range in which they are | ||
| // changed, if any. If the document changed between the maps, pass | ||
| // the maps for the steps that changed it as second argument, and | ||
| // make sure the method is called on the old set and passed the new | ||
| // set. The returned positions will be in new document coordinates. | ||
| ChangeSet.prototype.changedRange = function changedRange (b, maps) { | ||
| if (b == this) { return null } | ||
| var touched = maps && touchedRange(maps); | ||
| var moved = touched ? (touched.toB - touched.fromB) - (touched.toA - touched.fromA) : 0; | ||
| function map(p) { | ||
| return !touched || p <= touched.fromA ? p : p + moved | ||
| } | ||
| var from = touched ? touched.fromB : 2e8, to = touched ? touched.toB : -2e8; | ||
| function add(start, end) { | ||
| if ( end === void 0 ) end = start; | ||
| from = Math.min(start, from); to = Math.max(end, to); | ||
| } | ||
| var rA = this.changes, rB = b.changes; | ||
| for (var iA = 0, iB = 0; iA < rA.length && iB < rB.length;) { | ||
| var rangeA = rA[iA], rangeB = rB[iB]; | ||
| if (rangeA && rangeB && sameRanges(rangeA, rangeB, map)) { iA++; iB++; } | ||
| else if (rangeB && (!rangeA || map(rangeA.fromB) >= rangeB.fromB)) { add(rangeB.fromB, rangeB.toB); iB++; } | ||
| else { add(map(rangeA.fromB), map(rangeA.toB)); iA++; } | ||
| } | ||
| return from <= to ? {from: from, to: to} : null | ||
| }; | ||
| // :: (Node, ?(a: any, b: any) → any) → ChangeSet | ||
| // Create a changeset with the given base object and configuration. | ||
| // The `combine` function is used to compare and combine metadata—it | ||
| // should return null when metadata isn't compatible, and a combined | ||
| // version for a merged range when it is. | ||
| ChangeSet.create = function create (doc, combine) { | ||
| if ( combine === void 0 ) combine = function (a, b) { return a === b ? a : null; }; | ||
| return new ChangeSet({combine: combine, doc: doc}, [], []) | ||
| }; | ||
| Object.defineProperties( ChangeSet.prototype, prototypeAccessors$1 ); | ||
| // Exported for testing | ||
| ChangeSet.computeDiff = computeDiff; | ||
| // : ([[Change]], (any, any) → any, number, number) → [Change] | ||
| // Divide-and-conquer approach to merging a series of ranges. | ||
| function mergeAll(ranges, combine, start, end) { | ||
| if ( start === void 0 ) start = 0; | ||
| if ( end === void 0 ) end = ranges.length; | ||
| if (end == start + 1) { return [ranges[start]] } | ||
| var mid = (start + end) >> 1; | ||
| return Change.merge(mergeAll(ranges, combine, start, mid), | ||
| mergeAll(ranges, combine, mid, end), combine) | ||
| } | ||
| function endRange(maps) { | ||
| var from = 2e8, to = -2e8; | ||
| for (var i = 0; i < maps.length; i++) { | ||
| var map = maps[i]; | ||
| if (from != 2e8) { | ||
| from = map.map(from, -1); | ||
| to = map.map(to, 1); | ||
| } | ||
| map.forEach(function (_s, _e, start, end) { | ||
| from = Math.min(from, start); | ||
| to = Math.max(to, end); | ||
| }); | ||
| } | ||
| return from == 2e8 ? null : {from: from, to: to} | ||
| } | ||
| function touchedRange(maps) { | ||
| var b = endRange(maps); | ||
| if (!b) { return null } | ||
| var a = endRange(maps.map(function (m) { return m.invert(); }).reverse()); | ||
| return {fromA: a.from, toA: a.to, fromB: b.from, toB: b.to} | ||
| } | ||
| function sameRanges(a, b, map) { | ||
| return map(a.fromB) == b.fromB && map(a.toB) == b.toB && | ||
| sameSpans(a.deleted, b.deleted) && sameSpans(a.inserted, b.inserted) | ||
| } | ||
| function sameSpans(a, b) { | ||
| if (a.length != b.length) { return false } | ||
| for (var i = 0; i < a.length; i++) | ||
| { if (a[i].length != b[i].length || a[i].data !== b[i].data) { return false } } | ||
| return true | ||
| } | ||
| export { Change, ChangeSet, Span, simplifyChanges }; | ||
| //# sourceMappingURL=index.es.js.map |
| {"version":3,"file":"index.es.js","sources":["../src/diff.js","../src/change.js","../src/simplify.js","../src/changeset.js"],"sourcesContent":["// Convert the given range of a fragment to tokens, where node open\n// tokens are encoded as strings holding the node name, characters as\n// their character code, and node close tokens as -1.\nfunction tokens(frag, start, end, target) {\n for (let i = 0, off = 0; i < frag.childCount; i++) {\n let child = frag.child(i), endOff = off + child.nodeSize\n let from = Math.max(off, start), to = Math.min(endOff, end)\n if (from < to) {\n if (child.isText) {\n for (let j = from; j < to; j++) target.push(child.text.charCodeAt(j - off))\n } else if (child.isLeaf) {\n target.push(child.type.name)\n } else {\n if (from == off) target.push(child.type.name)\n tokens(child.content, Math.max(off + 1, from) - off - 1, Math.min(endOff - 1, to) - off - 1, target)\n if (to == endOff) target.push(-1)\n }\n }\n off = endOff\n }\n return target\n}\n\n// The code below will refuse to compute a diff with more than 5000\n// insertions or deletions, which takes about 300ms to reach on my\n// machine. This is a safeguard against runaway computations.\nconst MAX_DIFF_SIZE = 5000\n\n// This obscure mess of constants computes the minimum length of an\n// unchanged range (not at the start/end of the compared content). The\n// idea is to make it higher in bigger replacements, so that you don't\n// get a diff soup of coincidentally identical letters when replacing\n// a paragraph.\nfunction minUnchanged(sizeA, sizeB) {\n return Math.min(15, Math.max(2, Math.floor(Math.max(sizeA, sizeB) / 10)))\n}\n\n// : (Fragment, Fragment, Change) → [Change]\nexport function computeDiff(fragA, fragB, range) {\n let tokA = tokens(fragA, range.fromA, range.toA, [])\n let tokB = tokens(fragB, range.fromB, range.toB, [])\n\n // Scan from both sides to cheaply eliminate work\n let start = 0, endA = tokA.length, endB = tokB.length\n while (start < tokA.length && start < tokB.length && tokA[start] === tokB[start]) start++\n if (start == tokA.length && start == tokB.length) return []\n while (endA > start && endB > start && tokA[endA - 1] === tokB[endB - 1]) endA--, endB--\n // If the result is simple _or_ too big to cheaply compute, return\n // the remaining region as the diff\n if (endA == start || endB == start || (endA == endB && endA == start + 1))\n return [range.slice(start, endA, start, endB)]\n\n // This is an implementation of Myers' diff algorithm\n // See https://neil.fraser.name/writing/diff/myers.pdf and\n // https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/\n\n let lenA = endA - start, lenB = endB - start\n let max = Math.min(MAX_DIFF_SIZE, lenA + lenB), off = max + 1\n let history = []\n let frontier = []\n for (let len = off * 2, i = 0; i < len; i++) frontier[i] = -1\n\n for (let size = 0; size <= max; size++) {\n for (let diag = -size; diag <= size; diag += 2) {\n let next = frontier[diag + 1 + max], prev = frontier[diag - 1 + max]\n let x = next < prev ? prev : next + 1, y = x + diag\n while (x < lenA && y < lenB && tokA[start + x] === tokB[start + y]) x++, y++\n frontier[diag + max] = x\n // Found a match\n if (x >= lenA && y >= lenB) {\n // Trace back through the history to build up a set of changed ranges.\n let diff = [], minSpan = minUnchanged(endA - start, endB - start)\n // Used to add steps to a diff one at a time, back to front, merging\n // ones that are less than minSpan tokens apart\n let fromA = -1, toA = -1, fromB = -1, toB = -1\n let add = (fA, tA, fB, tB) => {\n if (fromA > -1 && fromA < tA + minSpan) {\n fromA = fA; fromB = fB\n } else {\n if (fromA > -1)\n diff.push(range.slice(fromA, toA, fromB, toB))\n fromA = fA; toA = tA\n fromB = fB; toB = tB\n }\n }\n\n for (let i = size - 1; i >= 0; i--) {\n let next = frontier[diag + 1 + max], prev = frontier[diag - 1 + max]\n if (next < prev) { // Deletion\n diag--\n x = prev + start; y = x + diag\n add(x, x, y, y + 1)\n } else { // Insertion\n diag++\n x = next + start; y = x + diag\n add(x, x + 1, y, y)\n }\n frontier = history[i >> 1]\n }\n if (fromA > -1) diff.push(range.slice(fromA, toA, fromB, toB))\n return diff.reverse()\n }\n }\n // Since only either odd or even diagonals are read from each\n // frontier, we only copy them every other iteration.\n if (size % 2 == 0) history.push(frontier.slice())\n }\n // The loop exited, meaning the maximum amount of work was done.\n // Just return a change spanning the entire range.\n return [range.slice(start, endA, start, endB)]\n}\n","// ::- Stores metadata for a part of a change.\nexport class Span {\n constructor(length, data) {\n // :: number\n this.length = length\n // :: any\n this.data = data\n }\n\n cut(length) {\n return length == this.length ? this : new Span(length, this.data)\n }\n\n static slice(spans, from, to) {\n if (from == to) return Span.none\n if (from == 0 && to == Span.len(spans)) return spans\n let result = []\n for (let i = 0, off = 0; off < to; i++) {\n let span = spans[i], end = off + span.length\n let overlap = Math.min(to, end) - Math.max(from, off)\n if (overlap > 0) result.push(span.cut(overlap))\n off = end\n }\n return result\n }\n\n static join(a, b, combine) {\n if (a.length == 0) return b\n if (b.length == 0) return a\n let combined = combine(a[a.length - 1].data, b[0].data)\n if (combined == null) return a.concat(b)\n let result = a.slice(0, a.length - 1)\n result.push(new Span(a[a.length - 1].length + b[0].length, combined))\n for (let i = 1; i < b.length; i++) result.push(b[i])\n return result\n }\n\n static len(spans) {\n let len = 0\n for (let i = 0; i < spans.length; i++) len += spans[i].length\n return len\n }\n}\n\nSpan.none = []\n\n// ::- A replaced range with metadata associated with it.\nexport class Change {\n constructor(fromA, toA, fromB, toB, deleted, inserted) {\n // :: number The start of the range deleted/replaced in the old\n // document.\n this.fromA = fromA\n // :: number The end of the range in the old document.\n this.toA = toA\n // :: number The start of the range inserted in the new document.\n this.fromB = fromB\n // :: number The end of the range in the new document.\n this.toB = toB\n // :: [Span] Data associated with the deleted content. The length\n // of these spans adds up to `this.toA - this.fromA`.\n this.deleted = deleted\n // :: [Span] Data associated with the inserted content. Length\n // adds up to `this.toB - this.toA`.\n this.inserted = inserted\n }\n\n get lenA() { return this.toA - this.fromA }\n get lenB() { return this.toB - this.fromB }\n\n slice(startA, endA, startB, endB) {\n if (startA == 0 && startB == 0 && endA == this.toA - this.fromA &&\n endB == this.toB - this.fromB) return this\n return new Change(this.fromA + startA, this.fromA + endA,\n this.fromB + startB, this.fromB + endB,\n Span.slice(this.deleted, startA, endA),\n Span.slice(this.inserted, startB, endB))\n }\n\n // : ([Change], [Change], (any, any) → any) → [Change]\n // This merges two changesets (the end document of x should be the\n // start document of y) into a single one spanning the start of x to\n // the end of y.\n static merge(x, y, combine) {\n if (x.length == 0) return y\n if (y.length == 0) return x\n\n let result = []\n // Iterate over both sets in parallel, using the middle coordinate\n // system (B in x, A in y) to synchronize.\n for (let iX = 0, iY = 0, curX = x[0], curY = y[0];;) {\n if (!curX && !curY) {\n return result\n } else if (curX && (!curY || curX.toB < curY.fromA)) { // curX entirely in front of curY\n let off = iY ? y[iY - 1].toB - y[iY - 1].toA : 0\n result.push(off == 0 ? curX :\n new Change(curX.fromA, curX.toA, curX.fromB + off, curX.toB + off,\n curX.deleted, curX.inserted))\n curX = iX++ == x.length ? null : x[iX]\n } else if (curY && (!curX || curY.toA < curX.fromB)) { // curY entirely in front of curX\n let off = iX ? x[iX - 1].toB - x[iX - 1].toA : 0\n result.push(off == 0 ? curY :\n new Change(curY.fromA - off, curY.toA - off, curY.fromB, curY.toB,\n curY.deleted, curY.inserted))\n curY = iY++ == y.length ? null : y[iY]\n } else { // Touch, need to merge\n // The rules for merging ranges are that deletions from the\n // old set and insertions from the new are kept. Areas of the\n // middle document covered by a but not by b are insertions\n // from a that need to be added, and areas covered by b but\n // not a are deletions from b that need to be added.\n let pos = Math.min(curX.fromB, curY.fromA)\n let fromA = Math.min(curX.fromA, curY.fromA - (iX ? x[iX - 1].toB - x[iX - 1].toA : 0)), toA = fromA\n let fromB = Math.min(curY.fromB, curX.fromB + (iY ? y[iY - 1].toB - y[iY - 1].toA : 0)), toB = fromB\n let deleted = Span.none, inserted = Span.none\n\n // Used to prevent appending ins/del range for the same Change twice\n let enteredX = false, enteredY = false\n\n // Need to have an inner loop since any number of further\n // ranges might be touching this group\n for (;;) {\n let nextX = !curX ? 2e8 : pos >= curX.fromB ? curX.toB : curX.fromB\n let nextY = !curY ? 2e8 : pos >= curY.fromA ? curY.toA : curY.fromA\n let next = Math.min(nextX, nextY)\n let inX = curX && pos >= curX.fromB, inY = curY && pos >= curY.fromA\n if (!inX && !inY) break\n if (inX && pos == curX.fromB && !enteredX) {\n deleted = Span.join(deleted, curX.deleted, combine)\n toA += curX.lenA\n enteredX = true\n }\n if (inX && !inY) {\n inserted = Span.join(inserted, Span.slice(curX.inserted, pos - curX.fromB, next - curX.fromB), combine)\n toB += next - pos\n }\n if (inY && pos == curY.fromA && !enteredY) {\n inserted = Span.join(inserted, curY.inserted, combine)\n toB += curY.lenB\n enteredY = true\n }\n if (inY && !inX) {\n deleted = Span.join(deleted, Span.slice(curY.deleted, pos - curY.fromA, next - curY.fromA), combine)\n toA += next - pos\n }\n\n if (inX && next == curX.toB) {\n curX = iX++ == x.length ? null : x[iX]\n enteredX = false\n }\n if (inY && next == curY.toA) {\n curY = iY++ == y.length ? null : y[iY]\n enteredY = false\n }\n pos = next\n }\n if (fromA < toA || fromB < toB)\n result.push(new Change(fromA, toA, fromB, toB, deleted, inserted))\n }\n }\n }\n}\n","import {Span, Change} from \"./change\"\n\nlet letter\n// If the runtime support unicode properties in regexps, that's a good\n// source of info on whether something is a letter.\ntry { letter = new RegExp(\"[\\\\p{Alphabetic}_]\", \"u\") } catch(_) {}\n\n// Otherwise, we see if the character changes when upper/lowercased,\n// or if it is part of these common single-case scripts.\nconst nonASCIISingleCaseWordChar = /[\\u00df\\u0587\\u0590-\\u05f4\\u0600-\\u06ff\\u3040-\\u309f\\u30a0-\\u30ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\uac00-\\ud7af]/\n\nfunction isLetter(code) {\n if (code < 128)\n return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 79 && code <= 122\n let ch = String.fromCharCode(code)\n if (letter) return letter.test(ch)\n return ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)\n}\n\n// Convert a range of document into a string, so that we can easily\n// access characters at a given position. Treat non-text tokens as\n// spaces so that they aren't considered part of a word.\nfunction getText(frag, start, end) {\n let out = \"\"\n function convert(frag, start, end) {\n for (let i = 0, off = 0; i < frag.childCount; i++) {\n let child = frag.child(i), endOff = off + child.nodeSize\n let from = Math.max(off, start), to = Math.min(endOff, end)\n if (from < to) {\n if (child.isText) {\n out += child.text.slice(Math.max(0, start - off), Math.min(child.text.length, end - off))\n } else if (child.isLeaf) {\n out += \" \"\n } else {\n if (from == off) out += \" \"\n convert(child.content, Math.max(0, from - off - 1), Math.min(child.content.size, end - off))\n if (to == endOff) out += \" \"\n }\n }\n off = endOff\n }\n }\n convert(frag, start, end)\n return out\n}\n\n// The distance changes have to be apart for us to not consider them\n// candidates for merging.\nconst MAX_SIMPLIFY_DISTANCE = 30\n\n// :: ([Change], Node) → [Change]\n// Simplifies a set of changes for presentation. This makes the\n// assumption that having both insertions and deletions within a word\n// is confusing, and, when such changes occur without a word boundary\n// between them, they should be expanded to cover the entire set of\n// words (in the new document) they touch. An exception is made for\n// single-character replacements.\nexport function simplifyChanges(changes, doc) {\n let result = []\n for (let i = 0; i < changes.length; i++) {\n let end = changes[i].toB, start = i\n while (i < changes.length - 1 && changes[i + 1].fromB <= end + MAX_SIMPLIFY_DISTANCE)\n end = changes[++i].toB\n simplifyAdjacentChanges(changes, start, i + 1, doc, result)\n }\n return result\n}\n\nfunction simplifyAdjacentChanges(changes, from, to, doc, target) {\n let start = Math.max(0, changes[from].fromB - MAX_SIMPLIFY_DISTANCE)\n let end = Math.min(doc.content.size, changes[to - 1].toB + MAX_SIMPLIFY_DISTANCE)\n let text = getText(doc.content, start, end)\n\n for (let i = from; i < to; i++) {\n let startI = i, last = changes[i], deleted = last.lenA, inserted = last.lenB\n while (i < to - 1) {\n let next = changes[i + 1], boundary = false\n let prevLetter = last.toB == end ? false : isLetter(text.charCodeAt(last.toB - 1 - start))\n for (let pos = last.toB; !boundary && pos < next.fromB; pos++) {\n let nextLetter = pos == end ? false : isLetter(text.charCodeAt(pos - start))\n if ((!prevLetter || !nextLetter) && pos != changes[startI].fromB) boundary = true\n prevLetter = nextLetter\n }\n if (boundary) break\n deleted += next.lenA; inserted += next.lenB\n last = next\n i++\n }\n\n if (inserted > 0 && deleted > 0 && !(inserted == 1 && deleted == 1)) {\n let from = changes[startI].fromB, to = changes[i].toB\n if (from < end && isLetter(text.charCodeAt(from - start)))\n while (from > start && isLetter(text.charCodeAt(from - 1 - start))) from--\n if (to > start && isLetter(text.charCodeAt(to - 1 - start)))\n while (to < end && isLetter(text.charCodeAt(to - start))) to++\n let joined = fillChange(changes.slice(startI, i + 1), from, to)\n let last = target.length ? target[target.length - 1] : null\n if (last && last.toA == joined.fromA)\n target[target.length - 1] = new Change(last.fromA, joined.toA, last.fromB, joined.toB,\n last.deleted.concat(joined.deleted), last.inserted.concat(joined.inserted))\n else\n target.push(joined)\n } else {\n for (let j = startI; j <= i; j++) target.push(changes[j])\n }\n }\n return changes\n}\n\nfunction combine(a, b) { return a === b ? a : null }\n\nfunction fillChange(changes, fromB, toB) {\n let fromA = changes[0].fromA - (changes[0].fromB - fromB)\n let last = changes[changes.length - 1]\n let toA = last.toA + (toB - last.toB)\n let deleted = Span.none, inserted = Span.none\n let delData = (changes[0].deleted.length ? changes[0].deleted : changes[0].inserted)[0].data\n let insData = (changes[0].inserted.length ? changes[0].inserted : changes[0].deleted)[0].data\n for (let posA = fromA, posB = fromB, i = 0;; i++) {\n let next = i == changes.length ? null : changes[i]\n let endA = next ? next.fromA : toA, endB = next ? next.fromB : toB\n if (endA > posA) deleted = Span.join(deleted, [new Span(endA - posA, delData)], combine)\n if (endB > posB) inserted = Span.join(inserted, [new Span(endB - posB, insData)], combine)\n if (!next) break\n deleted = Span.join(deleted, next.deleted, combine)\n inserted = Span.join(inserted, next.inserted, combine)\n if (deleted.length) delData = deleted[deleted.length - 1].data\n if (inserted.length) insData = inserted[inserted.length - 1].data\n posA = next.toA; posB = next.toB\n }\n return new Change(fromA, toA, fromB, toB, deleted, inserted)\n}\n","import {computeDiff} from \"./diff\"\nimport {Change, Span} from \"./change\"\nexport {Change, Span}\nexport {simplifyChanges} from \"./simplify\"\n\n// ::- A change set tracks the changes to a document from a given\n// point in the past. It condenses a number of step maps down to a\n// flat sequence of replacements, and simplifies replacments that\n// partially undo themselves by comparing their content.\nexport class ChangeSet {\n constructor(config, changes) {\n this.config = config\n // :: [Change] Replaced regions.\n this.changes = changes\n }\n\n // :: (Node, [StepMap], union<[any], any>) → ChangeSet\n // Computes a new changeset by adding the given step maps and\n // metadata (either as an array, per-map, or as a single value to be\n // associated with all maps) to the current set. Will not mutate the\n // old set.\n //\n // Note that due to simplification that happens after each add,\n // incrementally adding steps might create a different final set\n // than adding all those changes at once, since different document\n // tokens might be matched during simplification depending on the\n // boundaries of the current changed ranges.\n addSteps(newDoc, maps, data) {\n // This works by inspecting the position maps for the changes,\n // which indicate what parts of the document were replaced by new\n // content, and the size of that new content. It uses these to\n // build up Change objects.\n //\n // These change objects are put in sets and merged together using\n // Change.merge, giving us the changes created by the new steps.\n // Those changes can then be merged with the existing set of\n // changes.\n //\n // For each change that was touched by the new steps, we recompute\n // a diff to try to minimize the change by dropping matching\n // pieces of the old and new document from the change.\n\n let stepChanges = []\n // Add spans for new steps.\n for (let i = 0; i < maps.length; i++) {\n let d = Array.isArray(data) ? data[i] : data\n let off = 0\n maps[i].forEach((fromA, toA, fromB, toB) => {\n\n stepChanges.push(new Change(fromA + off, toA + off, fromB, toB,\n fromA == toA ? Span.none : [new Span(toA - fromA, d)],\n fromB == toB ? Span.none : [new Span(toB - fromB, d)]))\n\n off = (toB - fromB) - (toA - fromA)\n })\n }\n if (stepChanges.length == 0) return this\n\n let newChanges = mergeAll(stepChanges, this.config.combine)\n let changes = Change.merge(this.changes, newChanges, this.config.combine)\n\n // Minimize changes when possible\n for (let i = 0; i < changes.length; i++) {\n let change = changes[i]\n if (change.fromA == change.toA || change.fromB == change.toB ||\n // Only look at changes that touch newly added changed ranges\n !newChanges.some(r => r.toB > change.fromB && r.fromB < change.toB)) continue\n let diff = computeDiff(this.config.doc.content, newDoc.content, change)\n\n // Fast path: If they are completely different, don't do anything\n if (diff.length == 1 && diff[0].fromB == 0 && diff[0].toB == change.toB - change.fromB)\n continue\n\n if (diff.length == 1) {\n changes[i] = diff[0]\n } else {\n changes.splice(i, 1, ...diff)\n i += diff.length - 1\n }\n }\n\n return new ChangeSet(this.config, changes)\n }\n\n // :: Node\n // The starting document of the change set.\n get startDoc() { return this.config.doc }\n\n // :: (f: (range: Change) → any) → ChangeSet\n // Map the span's data values in the given set through a function\n // and construct a new set with the resulting data.\n map(f) {\n return new ChangeSet(this.config, this.changes.map(change => {\n let data = f(change)\n return data === change.data ? change :\n new Change(change.fromA, change.toA, change.fromB, change.toB, data)\n }))\n }\n\n // :: (ChangeSet, ?[StepMap]) → ?{from: number, to: number}\n // Compare two changesets and return the range in which they are\n // changed, if any. If the document changed between the maps, pass\n // the maps for the steps that changed it as second argument, and\n // make sure the method is called on the old set and passed the new\n // set. The returned positions will be in new document coordinates.\n changedRange(b, maps) {\n if (b == this) return null\n let touched = maps && touchedRange(maps)\n let moved = touched ? (touched.toB - touched.fromB) - (touched.toA - touched.fromA) : 0\n function map(p) {\n return !touched || p <= touched.fromA ? p : p + moved\n }\n\n let from = touched ? touched.fromB : 2e8, to = touched ? touched.toB : -2e8\n function add(start, end = start) {\n from = Math.min(start, from); to = Math.max(end, to)\n }\n\n let rA = this.changes, rB = b.changes\n for (let iA = 0, iB = 0; iA < rA.length && iB < rB.length;) {\n let rangeA = rA[iA], rangeB = rB[iB]\n if (rangeA && rangeB && sameRanges(rangeA, rangeB, map)) { iA++; iB++ }\n else if (rangeB && (!rangeA || map(rangeA.fromB) >= rangeB.fromB)) { add(rangeB.fromB, rangeB.toB); iB++ }\n else { add(map(rangeA.fromB), map(rangeA.toB)); iA++ }\n }\n\n return from <= to ? {from, to} : null\n }\n\n // :: (Node, ?(a: any, b: any) → any) → ChangeSet\n // Create a changeset with the given base object and configuration.\n // The `combine` function is used to compare and combine metadata—it\n // should return null when metadata isn't compatible, and a combined\n // version for a merged range when it is.\n static create(doc, combine = (a, b) => a === b ? a : null) {\n return new ChangeSet({combine, doc}, [], [])\n }\n}\n\n// Exported for testing\nChangeSet.computeDiff = computeDiff\n\n// : ([[Change]], (any, any) → any, number, number) → [Change]\n// Divide-and-conquer approach to merging a series of ranges.\nfunction mergeAll(ranges, combine, start = 0, end = ranges.length) {\n if (end == start + 1) return [ranges[start]]\n let mid = (start + end) >> 1\n return Change.merge(mergeAll(ranges, combine, start, mid),\n mergeAll(ranges, combine, mid, end), combine)\n}\n\nfunction endRange(maps) {\n let from = 2e8, to = -2e8\n for (let i = 0; i < maps.length; i++) {\n let map = maps[i]\n if (from != 2e8) {\n from = map.map(from, -1)\n to = map.map(to, 1)\n }\n map.forEach((_s, _e, start, end) => {\n from = Math.min(from, start)\n to = Math.max(to, end)\n })\n }\n return from == 2e8 ? null : {from, to}\n}\n\nfunction touchedRange(maps) {\n let b = endRange(maps)\n if (!b) return null\n let a = endRange(maps.map(m => m.invert()).reverse())\n return {fromA: a.from, toA: a.to, fromB: b.from, toB: b.to}\n}\n\nfunction sameRanges(a, b, map) {\n return map(a.fromB) == b.fromB && map(a.toB) == b.toB &&\n sameSpans(a.deleted, b.deleted) && sameSpans(a.inserted, b.inserted)\n}\n\nfunction sameSpans(a, b) {\n if (a.length != b.length) return false\n for (let i = 0; i < a.length; i++)\n if (a[i].length != b[i].length || a[i].data !== b[i].data) return false\n return true\n}\n"],"names":["let","const","i","next","prev","off","from","to","last","this","prototypeAccessors"],"mappings":"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"} |
+6
-0
@@ -0,1 +1,7 @@ | ||
| ## 2.1.2 (2019-11-20) | ||
| ### Bug fixes | ||
| Rename ES module files to use a .js extension, since Webpack gets confused by .mjs | ||
| ## 2.1.1 (2019-11-19) | ||
@@ -2,0 +8,0 @@ |
+2
-2
| { | ||
| "name": "prosemirror-changeset", | ||
| "version": "2.1.1", | ||
| "version": "2.1.2", | ||
| "description": "Distills a series of editing steps into deleted and added ranges", | ||
| "main": "dist/index.js", | ||
| "module": "dist/index.mjs", | ||
| "module": "dist/index.es.js", | ||
| "license": "MIT", | ||
@@ -8,0 +8,0 @@ "maintainers": [ |
+1
-1
@@ -8,3 +8,3 @@ module.exports = { | ||
| }, { | ||
| file: 'dist/index.mjs', | ||
| file: 'dist/index.es.js', | ||
| format: 'es', | ||
@@ -11,0 +11,0 @@ sourcemap: true |
-605
| // Convert the given range of a fragment to tokens, where node open | ||
| // tokens are encoded as strings holding the node name, characters as | ||
| // their character code, and node close tokens as -1. | ||
| function tokens(frag, start, end, target) { | ||
| for (var i = 0, off = 0; i < frag.childCount; i++) { | ||
| var child = frag.child(i), endOff = off + child.nodeSize; | ||
| var from = Math.max(off, start), to = Math.min(endOff, end); | ||
| if (from < to) { | ||
| if (child.isText) { | ||
| for (var j = from; j < to; j++) { target.push(child.text.charCodeAt(j - off)); } | ||
| } else if (child.isLeaf) { | ||
| target.push(child.type.name); | ||
| } else { | ||
| if (from == off) { target.push(child.type.name); } | ||
| tokens(child.content, Math.max(off + 1, from) - off - 1, Math.min(endOff - 1, to) - off - 1, target); | ||
| if (to == endOff) { target.push(-1); } | ||
| } | ||
| } | ||
| off = endOff; | ||
| } | ||
| return target | ||
| } | ||
| // The code below will refuse to compute a diff with more than 5000 | ||
| // insertions or deletions, which takes about 300ms to reach on my | ||
| // machine. This is a safeguard against runaway computations. | ||
| var MAX_DIFF_SIZE = 5000; | ||
| // This obscure mess of constants computes the minimum length of an | ||
| // unchanged range (not at the start/end of the compared content). The | ||
| // idea is to make it higher in bigger replacements, so that you don't | ||
| // get a diff soup of coincidentally identical letters when replacing | ||
| // a paragraph. | ||
| function minUnchanged(sizeA, sizeB) { | ||
| return Math.min(15, Math.max(2, Math.floor(Math.max(sizeA, sizeB) / 10))) | ||
| } | ||
| // : (Fragment, Fragment, Change) → [Change] | ||
| function computeDiff(fragA, fragB, range) { | ||
| var tokA = tokens(fragA, range.fromA, range.toA, []); | ||
| var tokB = tokens(fragB, range.fromB, range.toB, []); | ||
| // Scan from both sides to cheaply eliminate work | ||
| var start = 0, endA = tokA.length, endB = tokB.length; | ||
| while (start < tokA.length && start < tokB.length && tokA[start] === tokB[start]) { start++; } | ||
| if (start == tokA.length && start == tokB.length) { return [] } | ||
| while (endA > start && endB > start && tokA[endA - 1] === tokB[endB - 1]) { endA--, endB--; } | ||
| // If the result is simple _or_ too big to cheaply compute, return | ||
| // the remaining region as the diff | ||
| if (endA == start || endB == start || (endA == endB && endA == start + 1)) | ||
| { return [range.slice(start, endA, start, endB)] } | ||
| // This is an implementation of Myers' diff algorithm | ||
| // See https://neil.fraser.name/writing/diff/myers.pdf and | ||
| // https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/ | ||
| var lenA = endA - start, lenB = endB - start; | ||
| var max = Math.min(MAX_DIFF_SIZE, lenA + lenB), off = max + 1; | ||
| var history = []; | ||
| var frontier = []; | ||
| for (var len = off * 2, i = 0; i < len; i++) { frontier[i] = -1; } | ||
| for (var size = 0; size <= max; size++) { | ||
| for (var diag = -size; diag <= size; diag += 2) { | ||
| var next = frontier[diag + 1 + max], prev = frontier[diag - 1 + max]; | ||
| var x = next < prev ? prev : next + 1, y = x + diag; | ||
| while (x < lenA && y < lenB && tokA[start + x] === tokB[start + y]) { x++, y++; } | ||
| frontier[diag + max] = x; | ||
| // Found a match | ||
| if (x >= lenA && y >= lenB) { | ||
| // Trace back through the history to build up a set of changed ranges. | ||
| var diff = [], minSpan = minUnchanged(endA - start, endB - start); | ||
| // Used to add steps to a diff one at a time, back to front, merging | ||
| // ones that are less than minSpan tokens apart | ||
| var fromA = -1, toA = -1, fromB = -1, toB = -1; | ||
| var add = function (fA, tA, fB, tB) { | ||
| if (fromA > -1 && fromA < tA + minSpan) { | ||
| fromA = fA; fromB = fB; | ||
| } else { | ||
| if (fromA > -1) | ||
| { diff.push(range.slice(fromA, toA, fromB, toB)); } | ||
| fromA = fA; toA = tA; | ||
| fromB = fB; toB = tB; | ||
| } | ||
| }; | ||
| for (var i$1 = size - 1; i$1 >= 0; i$1--) { | ||
| var next$1 = frontier[diag + 1 + max], prev$1 = frontier[diag - 1 + max]; | ||
| if (next$1 < prev$1) { // Deletion | ||
| diag--; | ||
| x = prev$1 + start; y = x + diag; | ||
| add(x, x, y, y + 1); | ||
| } else { // Insertion | ||
| diag++; | ||
| x = next$1 + start; y = x + diag; | ||
| add(x, x + 1, y, y); | ||
| } | ||
| frontier = history[i$1 >> 1]; | ||
| } | ||
| if (fromA > -1) { diff.push(range.slice(fromA, toA, fromB, toB)); } | ||
| return diff.reverse() | ||
| } | ||
| } | ||
| // Since only either odd or even diagonals are read from each | ||
| // frontier, we only copy them every other iteration. | ||
| if (size % 2 == 0) { history.push(frontier.slice()); } | ||
| } | ||
| // The loop exited, meaning the maximum amount of work was done. | ||
| // Just return a change spanning the entire range. | ||
| return [range.slice(start, endA, start, endB)] | ||
| } | ||
| // ::- Stores metadata for a part of a change. | ||
| var Span = function Span(length, data) { | ||
| // :: number | ||
| this.length = length; | ||
| // :: any | ||
| this.data = data; | ||
| }; | ||
| Span.prototype.cut = function cut (length) { | ||
| return length == this.length ? this : new Span(length, this.data) | ||
| }; | ||
| Span.slice = function slice (spans, from, to) { | ||
| if (from == to) { return Span.none } | ||
| if (from == 0 && to == Span.len(spans)) { return spans } | ||
| var result = []; | ||
| for (var i = 0, off = 0; off < to; i++) { | ||
| var span = spans[i], end = off + span.length; | ||
| var overlap = Math.min(to, end) - Math.max(from, off); | ||
| if (overlap > 0) { result.push(span.cut(overlap)); } | ||
| off = end; | ||
| } | ||
| return result | ||
| }; | ||
| Span.join = function join (a, b, combine) { | ||
| if (a.length == 0) { return b } | ||
| if (b.length == 0) { return a } | ||
| var combined = combine(a[a.length - 1].data, b[0].data); | ||
| if (combined == null) { return a.concat(b) } | ||
| var result = a.slice(0, a.length - 1); | ||
| result.push(new Span(a[a.length - 1].length + b[0].length, combined)); | ||
| for (var i = 1; i < b.length; i++) { result.push(b[i]); } | ||
| return result | ||
| }; | ||
| Span.len = function len (spans) { | ||
| var len = 0; | ||
| for (var i = 0; i < spans.length; i++) { len += spans[i].length; } | ||
| return len | ||
| }; | ||
| Span.none = []; | ||
| // ::- A replaced range with metadata associated with it. | ||
| var Change = function Change(fromA, toA, fromB, toB, deleted, inserted) { | ||
| // :: number The start of the range deleted/replaced in the old | ||
| // document. | ||
| this.fromA = fromA; | ||
| // :: number The end of the range in the old document. | ||
| this.toA = toA; | ||
| // :: number The start of the range inserted in the new document. | ||
| this.fromB = fromB; | ||
| // :: number The end of the range in the new document. | ||
| this.toB = toB; | ||
| // :: [Span] Data associated with the deleted content. The length | ||
| // of these spans adds up to `this.toA - this.fromA`. | ||
| this.deleted = deleted; | ||
| // :: [Span] Data associated with the inserted content. Length | ||
| // adds up to `this.toB - this.toA`. | ||
| this.inserted = inserted; | ||
| }; | ||
| var prototypeAccessors = { lenA: { configurable: true },lenB: { configurable: true } }; | ||
| prototypeAccessors.lenA.get = function () { return this.toA - this.fromA }; | ||
| prototypeAccessors.lenB.get = function () { return this.toB - this.fromB }; | ||
| Change.prototype.slice = function slice (startA, endA, startB, endB) { | ||
| if (startA == 0 && startB == 0 && endA == this.toA - this.fromA && | ||
| endB == this.toB - this.fromB) { return this } | ||
| return new Change(this.fromA + startA, this.fromA + endA, | ||
| this.fromB + startB, this.fromB + endB, | ||
| Span.slice(this.deleted, startA, endA), | ||
| Span.slice(this.inserted, startB, endB)) | ||
| }; | ||
| // : ([Change], [Change], (any, any) → any) → [Change] | ||
| // This merges two changesets (the end document of x should be the | ||
| // start document of y) into a single one spanning the start of x to | ||
| // the end of y. | ||
| Change.merge = function merge (x, y, combine) { | ||
| if (x.length == 0) { return y } | ||
| if (y.length == 0) { return x } | ||
| var result = []; | ||
| // Iterate over both sets in parallel, using the middle coordinate | ||
| // system (B in x, A in y) to synchronize. | ||
| for (var iX = 0, iY = 0, curX = x[0], curY = y[0];;) { | ||
| if (!curX && !curY) { | ||
| return result | ||
| } else if (curX && (!curY || curX.toB < curY.fromA)) { // curX entirely in front of curY | ||
| var off = iY ? y[iY - 1].toB - y[iY - 1].toA : 0; | ||
| result.push(off == 0 ? curX : | ||
| new Change(curX.fromA, curX.toA, curX.fromB + off, curX.toB + off, | ||
| curX.deleted, curX.inserted)); | ||
| curX = iX++ == x.length ? null : x[iX]; | ||
| } else if (curY && (!curX || curY.toA < curX.fromB)) { // curY entirely in front of curX | ||
| var off$1 = iX ? x[iX - 1].toB - x[iX - 1].toA : 0; | ||
| result.push(off$1 == 0 ? curY : | ||
| new Change(curY.fromA - off$1, curY.toA - off$1, curY.fromB, curY.toB, | ||
| curY.deleted, curY.inserted)); | ||
| curY = iY++ == y.length ? null : y[iY]; | ||
| } else { // Touch, need to merge | ||
| // The rules for merging ranges are that deletions from the | ||
| // old set and insertions from the new are kept. Areas of the | ||
| // middle document covered by a but not by b are insertions | ||
| // from a that need to be added, and areas covered by b but | ||
| // not a are deletions from b that need to be added. | ||
| var pos = Math.min(curX.fromB, curY.fromA); | ||
| var fromA = Math.min(curX.fromA, curY.fromA - (iX ? x[iX - 1].toB - x[iX - 1].toA : 0)), toA = fromA; | ||
| var fromB = Math.min(curY.fromB, curX.fromB + (iY ? y[iY - 1].toB - y[iY - 1].toA : 0)), toB = fromB; | ||
| var deleted = Span.none, inserted = Span.none; | ||
| // Used to prevent appending ins/del range for the same Change twice | ||
| var enteredX = false, enteredY = false; | ||
| // Need to have an inner loop since any number of further | ||
| // ranges might be touching this group | ||
| for (;;) { | ||
| var nextX = !curX ? 2e8 : pos >= curX.fromB ? curX.toB : curX.fromB; | ||
| var nextY = !curY ? 2e8 : pos >= curY.fromA ? curY.toA : curY.fromA; | ||
| var next = Math.min(nextX, nextY); | ||
| var inX = curX && pos >= curX.fromB, inY = curY && pos >= curY.fromA; | ||
| if (!inX && !inY) { break } | ||
| if (inX && pos == curX.fromB && !enteredX) { | ||
| deleted = Span.join(deleted, curX.deleted, combine); | ||
| toA += curX.lenA; | ||
| enteredX = true; | ||
| } | ||
| if (inX && !inY) { | ||
| inserted = Span.join(inserted, Span.slice(curX.inserted, pos - curX.fromB, next - curX.fromB), combine); | ||
| toB += next - pos; | ||
| } | ||
| if (inY && pos == curY.fromA && !enteredY) { | ||
| inserted = Span.join(inserted, curY.inserted, combine); | ||
| toB += curY.lenB; | ||
| enteredY = true; | ||
| } | ||
| if (inY && !inX) { | ||
| deleted = Span.join(deleted, Span.slice(curY.deleted, pos - curY.fromA, next - curY.fromA), combine); | ||
| toA += next - pos; | ||
| } | ||
| if (inX && next == curX.toB) { | ||
| curX = iX++ == x.length ? null : x[iX]; | ||
| enteredX = false; | ||
| } | ||
| if (inY && next == curY.toA) { | ||
| curY = iY++ == y.length ? null : y[iY]; | ||
| enteredY = false; | ||
| } | ||
| pos = next; | ||
| } | ||
| if (fromA < toA || fromB < toB) | ||
| { result.push(new Change(fromA, toA, fromB, toB, deleted, inserted)); } | ||
| } | ||
| } | ||
| }; | ||
| Object.defineProperties( Change.prototype, prototypeAccessors ); | ||
| var letter; | ||
| // If the runtime support unicode properties in regexps, that's a good | ||
| // source of info on whether something is a letter. | ||
| try { letter = new RegExp("[\\p{Alphabetic}_]", "u"); } catch(_) {} | ||
| // Otherwise, we see if the character changes when upper/lowercased, | ||
| // or if it is part of these common single-case scripts. | ||
| var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/; | ||
| function isLetter(code) { | ||
| if (code < 128) | ||
| { return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 79 && code <= 122 } | ||
| var ch = String.fromCharCode(code); | ||
| if (letter) { return letter.test(ch) } | ||
| return ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch) | ||
| } | ||
| // Convert a range of document into a string, so that we can easily | ||
| // access characters at a given position. Treat non-text tokens as | ||
| // spaces so that they aren't considered part of a word. | ||
| function getText(frag, start, end) { | ||
| var out = ""; | ||
| function convert(frag, start, end) { | ||
| for (var i = 0, off = 0; i < frag.childCount; i++) { | ||
| var child = frag.child(i), endOff = off + child.nodeSize; | ||
| var from = Math.max(off, start), to = Math.min(endOff, end); | ||
| if (from < to) { | ||
| if (child.isText) { | ||
| out += child.text.slice(Math.max(0, start - off), Math.min(child.text.length, end - off)); | ||
| } else if (child.isLeaf) { | ||
| out += " "; | ||
| } else { | ||
| if (from == off) { out += " "; } | ||
| convert(child.content, Math.max(0, from - off - 1), Math.min(child.content.size, end - off)); | ||
| if (to == endOff) { out += " "; } | ||
| } | ||
| } | ||
| off = endOff; | ||
| } | ||
| } | ||
| convert(frag, start, end); | ||
| return out | ||
| } | ||
| // The distance changes have to be apart for us to not consider them | ||
| // candidates for merging. | ||
| var MAX_SIMPLIFY_DISTANCE = 30; | ||
| // :: ([Change], Node) → [Change] | ||
| // Simplifies a set of changes for presentation. This makes the | ||
| // assumption that having both insertions and deletions within a word | ||
| // is confusing, and, when such changes occur without a word boundary | ||
| // between them, they should be expanded to cover the entire set of | ||
| // words (in the new document) they touch. An exception is made for | ||
| // single-character replacements. | ||
| function simplifyChanges(changes, doc) { | ||
| var result = []; | ||
| for (var i = 0; i < changes.length; i++) { | ||
| var end = changes[i].toB, start = i; | ||
| while (i < changes.length - 1 && changes[i + 1].fromB <= end + MAX_SIMPLIFY_DISTANCE) | ||
| { end = changes[++i].toB; } | ||
| simplifyAdjacentChanges(changes, start, i + 1, doc, result); | ||
| } | ||
| return result | ||
| } | ||
| function simplifyAdjacentChanges(changes, from, to, doc, target) { | ||
| var start = Math.max(0, changes[from].fromB - MAX_SIMPLIFY_DISTANCE); | ||
| var end = Math.min(doc.content.size, changes[to - 1].toB + MAX_SIMPLIFY_DISTANCE); | ||
| var text = getText(doc.content, start, end); | ||
| for (var i = from; i < to; i++) { | ||
| var startI = i, last = changes[i], deleted = last.lenA, inserted = last.lenB; | ||
| while (i < to - 1) { | ||
| var next = changes[i + 1], boundary = false; | ||
| var prevLetter = last.toB == end ? false : isLetter(text.charCodeAt(last.toB - 1 - start)); | ||
| for (var pos = last.toB; !boundary && pos < next.fromB; pos++) { | ||
| var nextLetter = pos == end ? false : isLetter(text.charCodeAt(pos - start)); | ||
| if ((!prevLetter || !nextLetter) && pos != changes[startI].fromB) { boundary = true; } | ||
| prevLetter = nextLetter; | ||
| } | ||
| if (boundary) { break } | ||
| deleted += next.lenA; inserted += next.lenB; | ||
| last = next; | ||
| i++; | ||
| } | ||
| if (inserted > 0 && deleted > 0 && !(inserted == 1 && deleted == 1)) { | ||
| var from$1 = changes[startI].fromB, to$1 = changes[i].toB; | ||
| if (from$1 < end && isLetter(text.charCodeAt(from$1 - start))) | ||
| { while (from$1 > start && isLetter(text.charCodeAt(from$1 - 1 - start))) { from$1--; } } | ||
| if (to$1 > start && isLetter(text.charCodeAt(to$1 - 1 - start))) | ||
| { while (to$1 < end && isLetter(text.charCodeAt(to$1 - start))) { to$1++; } } | ||
| var joined = fillChange(changes.slice(startI, i + 1), from$1, to$1); | ||
| var last$1 = target.length ? target[target.length - 1] : null; | ||
| if (last$1 && last$1.toA == joined.fromA) | ||
| { target[target.length - 1] = new Change(last$1.fromA, joined.toA, last$1.fromB, joined.toB, | ||
| last$1.deleted.concat(joined.deleted), last$1.inserted.concat(joined.inserted)); } | ||
| else | ||
| { target.push(joined); } | ||
| } else { | ||
| for (var j = startI; j <= i; j++) { target.push(changes[j]); } | ||
| } | ||
| } | ||
| return changes | ||
| } | ||
| function combine(a, b) { return a === b ? a : null } | ||
| function fillChange(changes, fromB, toB) { | ||
| var fromA = changes[0].fromA - (changes[0].fromB - fromB); | ||
| var last = changes[changes.length - 1]; | ||
| var toA = last.toA + (toB - last.toB); | ||
| var deleted = Span.none, inserted = Span.none; | ||
| var delData = (changes[0].deleted.length ? changes[0].deleted : changes[0].inserted)[0].data; | ||
| var insData = (changes[0].inserted.length ? changes[0].inserted : changes[0].deleted)[0].data; | ||
| for (var posA = fromA, posB = fromB, i = 0;; i++) { | ||
| var next = i == changes.length ? null : changes[i]; | ||
| var endA = next ? next.fromA : toA, endB = next ? next.fromB : toB; | ||
| if (endA > posA) { deleted = Span.join(deleted, [new Span(endA - posA, delData)], combine); } | ||
| if (endB > posB) { inserted = Span.join(inserted, [new Span(endB - posB, insData)], combine); } | ||
| if (!next) { break } | ||
| deleted = Span.join(deleted, next.deleted, combine); | ||
| inserted = Span.join(inserted, next.inserted, combine); | ||
| if (deleted.length) { delData = deleted[deleted.length - 1].data; } | ||
| if (inserted.length) { insData = inserted[inserted.length - 1].data; } | ||
| posA = next.toA; posB = next.toB; | ||
| } | ||
| return new Change(fromA, toA, fromB, toB, deleted, inserted) | ||
| } | ||
| // ::- A change set tracks the changes to a document from a given | ||
| // point in the past. It condenses a number of step maps down to a | ||
| // flat sequence of replacements, and simplifies replacments that | ||
| // partially undo themselves by comparing their content. | ||
| var ChangeSet = function ChangeSet(config, changes) { | ||
| this.config = config; | ||
| // :: [Change] Replaced regions. | ||
| this.changes = changes; | ||
| }; | ||
| var prototypeAccessors$1 = { startDoc: { configurable: true } }; | ||
| // :: (Node, [StepMap], union<[any], any>) → ChangeSet | ||
| // Computes a new changeset by adding the given step maps and | ||
| // metadata (either as an array, per-map, or as a single value to be | ||
| // associated with all maps) to the current set. Will not mutate the | ||
| // old set. | ||
| // | ||
| // Note that due to simplification that happens after each add, | ||
| // incrementally adding steps might create a different final set | ||
| // than adding all those changes at once, since different document | ||
| // tokens might be matched during simplification depending on the | ||
| // boundaries of the current changed ranges. | ||
| ChangeSet.prototype.addSteps = function addSteps (newDoc, maps, data) { | ||
| var this$1 = this; | ||
| // This works by inspecting the position maps for the changes, | ||
| // which indicate what parts of the document were replaced by new | ||
| // content, and the size of that new content. It uses these to | ||
| // build up Change objects. | ||
| // | ||
| // These change objects are put in sets and merged together using | ||
| // Change.merge, giving us the changes created by the new steps. | ||
| // Those changes can then be merged with the existing set of | ||
| // changes. | ||
| // | ||
| // For each change that was touched by the new steps, we recompute | ||
| // a diff to try to minimize the change by dropping matching | ||
| // pieces of the old and new document from the change. | ||
| var stepChanges = []; | ||
| // Add spans for new steps. | ||
| var loop = function ( i ) { | ||
| var d = Array.isArray(data) ? data[i] : data; | ||
| var off = 0; | ||
| maps[i].forEach(function (fromA, toA, fromB, toB) { | ||
| stepChanges.push(new Change(fromA + off, toA + off, fromB, toB, | ||
| fromA == toA ? Span.none : [new Span(toA - fromA, d)], | ||
| fromB == toB ? Span.none : [new Span(toB - fromB, d)])); | ||
| off = (toB - fromB) - (toA - fromA); | ||
| }); | ||
| }; | ||
| for (var i = 0; i < maps.length; i++) loop( i ); | ||
| if (stepChanges.length == 0) { return this } | ||
| var newChanges = mergeAll(stepChanges, this.config.combine); | ||
| var changes = Change.merge(this.changes, newChanges, this.config.combine); | ||
| // Minimize changes when possible | ||
| var loop$1 = function ( i$2 ) { | ||
| var change = changes[i$2]; | ||
| if (change.fromA == change.toA || change.fromB == change.toB || | ||
| // Only look at changes that touch newly added changed ranges | ||
| !newChanges.some(function (r) { return r.toB > change.fromB && r.fromB < change.toB; })) { return } | ||
| var diff = computeDiff(this$1.config.doc.content, newDoc.content, change); | ||
| // Fast path: If they are completely different, don't do anything | ||
| if (diff.length == 1 && diff[0].fromB == 0 && diff[0].toB == change.toB - change.fromB) | ||
| { return } | ||
| if (diff.length == 1) { | ||
| changes[i$2] = diff[0]; | ||
| } else { | ||
| changes.splice.apply(changes, [ i$2, 1 ].concat( diff )); | ||
| i$2 += diff.length - 1; | ||
| } | ||
| i$1 = i$2; | ||
| }; | ||
| for (var i$1 = 0; i$1 < changes.length; i$1++) loop$1( i$1 ); | ||
| return new ChangeSet(this.config, changes) | ||
| }; | ||
| // :: Node | ||
| // The starting document of the change set. | ||
| prototypeAccessors$1.startDoc.get = function () { return this.config.doc }; | ||
| // :: (f: (range: Change) → any) → ChangeSet | ||
| // Map the span's data values in the given set through a function | ||
| // and construct a new set with the resulting data. | ||
| ChangeSet.prototype.map = function map (f) { | ||
| return new ChangeSet(this.config, this.changes.map(function (change) { | ||
| var data = f(change); | ||
| return data === change.data ? change : | ||
| new Change(change.fromA, change.toA, change.fromB, change.toB, data) | ||
| })) | ||
| }; | ||
| // :: (ChangeSet, ?[StepMap]) → ?{from: number, to: number} | ||
| // Compare two changesets and return the range in which they are | ||
| // changed, if any. If the document changed between the maps, pass | ||
| // the maps for the steps that changed it as second argument, and | ||
| // make sure the method is called on the old set and passed the new | ||
| // set. The returned positions will be in new document coordinates. | ||
| ChangeSet.prototype.changedRange = function changedRange (b, maps) { | ||
| if (b == this) { return null } | ||
| var touched = maps && touchedRange(maps); | ||
| var moved = touched ? (touched.toB - touched.fromB) - (touched.toA - touched.fromA) : 0; | ||
| function map(p) { | ||
| return !touched || p <= touched.fromA ? p : p + moved | ||
| } | ||
| var from = touched ? touched.fromB : 2e8, to = touched ? touched.toB : -2e8; | ||
| function add(start, end) { | ||
| if ( end === void 0 ) end = start; | ||
| from = Math.min(start, from); to = Math.max(end, to); | ||
| } | ||
| var rA = this.changes, rB = b.changes; | ||
| for (var iA = 0, iB = 0; iA < rA.length && iB < rB.length;) { | ||
| var rangeA = rA[iA], rangeB = rB[iB]; | ||
| if (rangeA && rangeB && sameRanges(rangeA, rangeB, map)) { iA++; iB++; } | ||
| else if (rangeB && (!rangeA || map(rangeA.fromB) >= rangeB.fromB)) { add(rangeB.fromB, rangeB.toB); iB++; } | ||
| else { add(map(rangeA.fromB), map(rangeA.toB)); iA++; } | ||
| } | ||
| return from <= to ? {from: from, to: to} : null | ||
| }; | ||
| // :: (Node, ?(a: any, b: any) → any) → ChangeSet | ||
| // Create a changeset with the given base object and configuration. | ||
| // The `combine` function is used to compare and combine metadata—it | ||
| // should return null when metadata isn't compatible, and a combined | ||
| // version for a merged range when it is. | ||
| ChangeSet.create = function create (doc, combine) { | ||
| if ( combine === void 0 ) combine = function (a, b) { return a === b ? a : null; }; | ||
| return new ChangeSet({combine: combine, doc: doc}, [], []) | ||
| }; | ||
| Object.defineProperties( ChangeSet.prototype, prototypeAccessors$1 ); | ||
| // Exported for testing | ||
| ChangeSet.computeDiff = computeDiff; | ||
| // : ([[Change]], (any, any) → any, number, number) → [Change] | ||
| // Divide-and-conquer approach to merging a series of ranges. | ||
| function mergeAll(ranges, combine, start, end) { | ||
| if ( start === void 0 ) start = 0; | ||
| if ( end === void 0 ) end = ranges.length; | ||
| if (end == start + 1) { return [ranges[start]] } | ||
| var mid = (start + end) >> 1; | ||
| return Change.merge(mergeAll(ranges, combine, start, mid), | ||
| mergeAll(ranges, combine, mid, end), combine) | ||
| } | ||
| function endRange(maps) { | ||
| var from = 2e8, to = -2e8; | ||
| for (var i = 0; i < maps.length; i++) { | ||
| var map = maps[i]; | ||
| if (from != 2e8) { | ||
| from = map.map(from, -1); | ||
| to = map.map(to, 1); | ||
| } | ||
| map.forEach(function (_s, _e, start, end) { | ||
| from = Math.min(from, start); | ||
| to = Math.max(to, end); | ||
| }); | ||
| } | ||
| return from == 2e8 ? null : {from: from, to: to} | ||
| } | ||
| function touchedRange(maps) { | ||
| var b = endRange(maps); | ||
| if (!b) { return null } | ||
| var a = endRange(maps.map(function (m) { return m.invert(); }).reverse()); | ||
| return {fromA: a.from, toA: a.to, fromB: b.from, toB: b.to} | ||
| } | ||
| function sameRanges(a, b, map) { | ||
| return map(a.fromB) == b.fromB && map(a.toB) == b.toB && | ||
| sameSpans(a.deleted, b.deleted) && sameSpans(a.inserted, b.inserted) | ||
| } | ||
| function sameSpans(a, b) { | ||
| if (a.length != b.length) { return false } | ||
| for (var i = 0; i < a.length; i++) | ||
| { if (a[i].length != b[i].length || a[i].data !== b[i].data) { return false } } | ||
| return true | ||
| } | ||
| export { Change, ChangeSet, Span, simplifyChanges }; | ||
| //# sourceMappingURL=index.mjs.map |
| {"version":3,"file":"index.mjs","sources":["../src/diff.js","../src/change.js","../src/simplify.js","../src/changeset.js"],"sourcesContent":["// Convert the given range of a fragment to tokens, where node open\n// tokens are encoded as strings holding the node name, characters as\n// their character code, and node close tokens as -1.\nfunction tokens(frag, start, end, target) {\n for (let i = 0, off = 0; i < frag.childCount; i++) {\n let child = frag.child(i), endOff = off + child.nodeSize\n let from = Math.max(off, start), to = Math.min(endOff, end)\n if (from < to) {\n if (child.isText) {\n for (let j = from; j < to; j++) target.push(child.text.charCodeAt(j - off))\n } else if (child.isLeaf) {\n target.push(child.type.name)\n } else {\n if (from == off) target.push(child.type.name)\n tokens(child.content, Math.max(off + 1, from) - off - 1, Math.min(endOff - 1, to) - off - 1, target)\n if (to == endOff) target.push(-1)\n }\n }\n off = endOff\n }\n return target\n}\n\n// The code below will refuse to compute a diff with more than 5000\n// insertions or deletions, which takes about 300ms to reach on my\n// machine. This is a safeguard against runaway computations.\nconst MAX_DIFF_SIZE = 5000\n\n// This obscure mess of constants computes the minimum length of an\n// unchanged range (not at the start/end of the compared content). The\n// idea is to make it higher in bigger replacements, so that you don't\n// get a diff soup of coincidentally identical letters when replacing\n// a paragraph.\nfunction minUnchanged(sizeA, sizeB) {\n return Math.min(15, Math.max(2, Math.floor(Math.max(sizeA, sizeB) / 10)))\n}\n\n// : (Fragment, Fragment, Change) → [Change]\nexport function computeDiff(fragA, fragB, range) {\n let tokA = tokens(fragA, range.fromA, range.toA, [])\n let tokB = tokens(fragB, range.fromB, range.toB, [])\n\n // Scan from both sides to cheaply eliminate work\n let start = 0, endA = tokA.length, endB = tokB.length\n while (start < tokA.length && start < tokB.length && tokA[start] === tokB[start]) start++\n if (start == tokA.length && start == tokB.length) return []\n while (endA > start && endB > start && tokA[endA - 1] === tokB[endB - 1]) endA--, endB--\n // If the result is simple _or_ too big to cheaply compute, return\n // the remaining region as the diff\n if (endA == start || endB == start || (endA == endB && endA == start + 1))\n return [range.slice(start, endA, start, endB)]\n\n // This is an implementation of Myers' diff algorithm\n // See https://neil.fraser.name/writing/diff/myers.pdf and\n // https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/\n\n let lenA = endA - start, lenB = endB - start\n let max = Math.min(MAX_DIFF_SIZE, lenA + lenB), off = max + 1\n let history = []\n let frontier = []\n for (let len = off * 2, i = 0; i < len; i++) frontier[i] = -1\n\n for (let size = 0; size <= max; size++) {\n for (let diag = -size; diag <= size; diag += 2) {\n let next = frontier[diag + 1 + max], prev = frontier[diag - 1 + max]\n let x = next < prev ? prev : next + 1, y = x + diag\n while (x < lenA && y < lenB && tokA[start + x] === tokB[start + y]) x++, y++\n frontier[diag + max] = x\n // Found a match\n if (x >= lenA && y >= lenB) {\n // Trace back through the history to build up a set of changed ranges.\n let diff = [], minSpan = minUnchanged(endA - start, endB - start)\n // Used to add steps to a diff one at a time, back to front, merging\n // ones that are less than minSpan tokens apart\n let fromA = -1, toA = -1, fromB = -1, toB = -1\n let add = (fA, tA, fB, tB) => {\n if (fromA > -1 && fromA < tA + minSpan) {\n fromA = fA; fromB = fB\n } else {\n if (fromA > -1)\n diff.push(range.slice(fromA, toA, fromB, toB))\n fromA = fA; toA = tA\n fromB = fB; toB = tB\n }\n }\n\n for (let i = size - 1; i >= 0; i--) {\n let next = frontier[diag + 1 + max], prev = frontier[diag - 1 + max]\n if (next < prev) { // Deletion\n diag--\n x = prev + start; y = x + diag\n add(x, x, y, y + 1)\n } else { // Insertion\n diag++\n x = next + start; y = x + diag\n add(x, x + 1, y, y)\n }\n frontier = history[i >> 1]\n }\n if (fromA > -1) diff.push(range.slice(fromA, toA, fromB, toB))\n return diff.reverse()\n }\n }\n // Since only either odd or even diagonals are read from each\n // frontier, we only copy them every other iteration.\n if (size % 2 == 0) history.push(frontier.slice())\n }\n // The loop exited, meaning the maximum amount of work was done.\n // Just return a change spanning the entire range.\n return [range.slice(start, endA, start, endB)]\n}\n","// ::- Stores metadata for a part of a change.\nexport class Span {\n constructor(length, data) {\n // :: number\n this.length = length\n // :: any\n this.data = data\n }\n\n cut(length) {\n return length == this.length ? this : new Span(length, this.data)\n }\n\n static slice(spans, from, to) {\n if (from == to) return Span.none\n if (from == 0 && to == Span.len(spans)) return spans\n let result = []\n for (let i = 0, off = 0; off < to; i++) {\n let span = spans[i], end = off + span.length\n let overlap = Math.min(to, end) - Math.max(from, off)\n if (overlap > 0) result.push(span.cut(overlap))\n off = end\n }\n return result\n }\n\n static join(a, b, combine) {\n if (a.length == 0) return b\n if (b.length == 0) return a\n let combined = combine(a[a.length - 1].data, b[0].data)\n if (combined == null) return a.concat(b)\n let result = a.slice(0, a.length - 1)\n result.push(new Span(a[a.length - 1].length + b[0].length, combined))\n for (let i = 1; i < b.length; i++) result.push(b[i])\n return result\n }\n\n static len(spans) {\n let len = 0\n for (let i = 0; i < spans.length; i++) len += spans[i].length\n return len\n }\n}\n\nSpan.none = []\n\n// ::- A replaced range with metadata associated with it.\nexport class Change {\n constructor(fromA, toA, fromB, toB, deleted, inserted) {\n // :: number The start of the range deleted/replaced in the old\n // document.\n this.fromA = fromA\n // :: number The end of the range in the old document.\n this.toA = toA\n // :: number The start of the range inserted in the new document.\n this.fromB = fromB\n // :: number The end of the range in the new document.\n this.toB = toB\n // :: [Span] Data associated with the deleted content. The length\n // of these spans adds up to `this.toA - this.fromA`.\n this.deleted = deleted\n // :: [Span] Data associated with the inserted content. Length\n // adds up to `this.toB - this.toA`.\n this.inserted = inserted\n }\n\n get lenA() { return this.toA - this.fromA }\n get lenB() { return this.toB - this.fromB }\n\n slice(startA, endA, startB, endB) {\n if (startA == 0 && startB == 0 && endA == this.toA - this.fromA &&\n endB == this.toB - this.fromB) return this\n return new Change(this.fromA + startA, this.fromA + endA,\n this.fromB + startB, this.fromB + endB,\n Span.slice(this.deleted, startA, endA),\n Span.slice(this.inserted, startB, endB))\n }\n\n // : ([Change], [Change], (any, any) → any) → [Change]\n // This merges two changesets (the end document of x should be the\n // start document of y) into a single one spanning the start of x to\n // the end of y.\n static merge(x, y, combine) {\n if (x.length == 0) return y\n if (y.length == 0) return x\n\n let result = []\n // Iterate over both sets in parallel, using the middle coordinate\n // system (B in x, A in y) to synchronize.\n for (let iX = 0, iY = 0, curX = x[0], curY = y[0];;) {\n if (!curX && !curY) {\n return result\n } else if (curX && (!curY || curX.toB < curY.fromA)) { // curX entirely in front of curY\n let off = iY ? y[iY - 1].toB - y[iY - 1].toA : 0\n result.push(off == 0 ? curX :\n new Change(curX.fromA, curX.toA, curX.fromB + off, curX.toB + off,\n curX.deleted, curX.inserted))\n curX = iX++ == x.length ? null : x[iX]\n } else if (curY && (!curX || curY.toA < curX.fromB)) { // curY entirely in front of curX\n let off = iX ? x[iX - 1].toB - x[iX - 1].toA : 0\n result.push(off == 0 ? curY :\n new Change(curY.fromA - off, curY.toA - off, curY.fromB, curY.toB,\n curY.deleted, curY.inserted))\n curY = iY++ == y.length ? null : y[iY]\n } else { // Touch, need to merge\n // The rules for merging ranges are that deletions from the\n // old set and insertions from the new are kept. Areas of the\n // middle document covered by a but not by b are insertions\n // from a that need to be added, and areas covered by b but\n // not a are deletions from b that need to be added.\n let pos = Math.min(curX.fromB, curY.fromA)\n let fromA = Math.min(curX.fromA, curY.fromA - (iX ? x[iX - 1].toB - x[iX - 1].toA : 0)), toA = fromA\n let fromB = Math.min(curY.fromB, curX.fromB + (iY ? y[iY - 1].toB - y[iY - 1].toA : 0)), toB = fromB\n let deleted = Span.none, inserted = Span.none\n\n // Used to prevent appending ins/del range for the same Change twice\n let enteredX = false, enteredY = false\n\n // Need to have an inner loop since any number of further\n // ranges might be touching this group\n for (;;) {\n let nextX = !curX ? 2e8 : pos >= curX.fromB ? curX.toB : curX.fromB\n let nextY = !curY ? 2e8 : pos >= curY.fromA ? curY.toA : curY.fromA\n let next = Math.min(nextX, nextY)\n let inX = curX && pos >= curX.fromB, inY = curY && pos >= curY.fromA\n if (!inX && !inY) break\n if (inX && pos == curX.fromB && !enteredX) {\n deleted = Span.join(deleted, curX.deleted, combine)\n toA += curX.lenA\n enteredX = true\n }\n if (inX && !inY) {\n inserted = Span.join(inserted, Span.slice(curX.inserted, pos - curX.fromB, next - curX.fromB), combine)\n toB += next - pos\n }\n if (inY && pos == curY.fromA && !enteredY) {\n inserted = Span.join(inserted, curY.inserted, combine)\n toB += curY.lenB\n enteredY = true\n }\n if (inY && !inX) {\n deleted = Span.join(deleted, Span.slice(curY.deleted, pos - curY.fromA, next - curY.fromA), combine)\n toA += next - pos\n }\n\n if (inX && next == curX.toB) {\n curX = iX++ == x.length ? null : x[iX]\n enteredX = false\n }\n if (inY && next == curY.toA) {\n curY = iY++ == y.length ? null : y[iY]\n enteredY = false\n }\n pos = next\n }\n if (fromA < toA || fromB < toB)\n result.push(new Change(fromA, toA, fromB, toB, deleted, inserted))\n }\n }\n }\n}\n","import {Span, Change} from \"./change\"\n\nlet letter\n// If the runtime support unicode properties in regexps, that's a good\n// source of info on whether something is a letter.\ntry { letter = new RegExp(\"[\\\\p{Alphabetic}_]\", \"u\") } catch(_) {}\n\n// Otherwise, we see if the character changes when upper/lowercased,\n// or if it is part of these common single-case scripts.\nconst nonASCIISingleCaseWordChar = /[\\u00df\\u0587\\u0590-\\u05f4\\u0600-\\u06ff\\u3040-\\u309f\\u30a0-\\u30ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\uac00-\\ud7af]/\n\nfunction isLetter(code) {\n if (code < 128)\n return code >= 48 && code <= 57 || code >= 65 && code <= 90 || code >= 79 && code <= 122\n let ch = String.fromCharCode(code)\n if (letter) return letter.test(ch)\n return ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch)\n}\n\n// Convert a range of document into a string, so that we can easily\n// access characters at a given position. Treat non-text tokens as\n// spaces so that they aren't considered part of a word.\nfunction getText(frag, start, end) {\n let out = \"\"\n function convert(frag, start, end) {\n for (let i = 0, off = 0; i < frag.childCount; i++) {\n let child = frag.child(i), endOff = off + child.nodeSize\n let from = Math.max(off, start), to = Math.min(endOff, end)\n if (from < to) {\n if (child.isText) {\n out += child.text.slice(Math.max(0, start - off), Math.min(child.text.length, end - off))\n } else if (child.isLeaf) {\n out += \" \"\n } else {\n if (from == off) out += \" \"\n convert(child.content, Math.max(0, from - off - 1), Math.min(child.content.size, end - off))\n if (to == endOff) out += \" \"\n }\n }\n off = endOff\n }\n }\n convert(frag, start, end)\n return out\n}\n\n// The distance changes have to be apart for us to not consider them\n// candidates for merging.\nconst MAX_SIMPLIFY_DISTANCE = 30\n\n// :: ([Change], Node) → [Change]\n// Simplifies a set of changes for presentation. This makes the\n// assumption that having both insertions and deletions within a word\n// is confusing, and, when such changes occur without a word boundary\n// between them, they should be expanded to cover the entire set of\n// words (in the new document) they touch. An exception is made for\n// single-character replacements.\nexport function simplifyChanges(changes, doc) {\n let result = []\n for (let i = 0; i < changes.length; i++) {\n let end = changes[i].toB, start = i\n while (i < changes.length - 1 && changes[i + 1].fromB <= end + MAX_SIMPLIFY_DISTANCE)\n end = changes[++i].toB\n simplifyAdjacentChanges(changes, start, i + 1, doc, result)\n }\n return result\n}\n\nfunction simplifyAdjacentChanges(changes, from, to, doc, target) {\n let start = Math.max(0, changes[from].fromB - MAX_SIMPLIFY_DISTANCE)\n let end = Math.min(doc.content.size, changes[to - 1].toB + MAX_SIMPLIFY_DISTANCE)\n let text = getText(doc.content, start, end)\n\n for (let i = from; i < to; i++) {\n let startI = i, last = changes[i], deleted = last.lenA, inserted = last.lenB\n while (i < to - 1) {\n let next = changes[i + 1], boundary = false\n let prevLetter = last.toB == end ? false : isLetter(text.charCodeAt(last.toB - 1 - start))\n for (let pos = last.toB; !boundary && pos < next.fromB; pos++) {\n let nextLetter = pos == end ? false : isLetter(text.charCodeAt(pos - start))\n if ((!prevLetter || !nextLetter) && pos != changes[startI].fromB) boundary = true\n prevLetter = nextLetter\n }\n if (boundary) break\n deleted += next.lenA; inserted += next.lenB\n last = next\n i++\n }\n\n if (inserted > 0 && deleted > 0 && !(inserted == 1 && deleted == 1)) {\n let from = changes[startI].fromB, to = changes[i].toB\n if (from < end && isLetter(text.charCodeAt(from - start)))\n while (from > start && isLetter(text.charCodeAt(from - 1 - start))) from--\n if (to > start && isLetter(text.charCodeAt(to - 1 - start)))\n while (to < end && isLetter(text.charCodeAt(to - start))) to++\n let joined = fillChange(changes.slice(startI, i + 1), from, to)\n let last = target.length ? target[target.length - 1] : null\n if (last && last.toA == joined.fromA)\n target[target.length - 1] = new Change(last.fromA, joined.toA, last.fromB, joined.toB,\n last.deleted.concat(joined.deleted), last.inserted.concat(joined.inserted))\n else\n target.push(joined)\n } else {\n for (let j = startI; j <= i; j++) target.push(changes[j])\n }\n }\n return changes\n}\n\nfunction combine(a, b) { return a === b ? a : null }\n\nfunction fillChange(changes, fromB, toB) {\n let fromA = changes[0].fromA - (changes[0].fromB - fromB)\n let last = changes[changes.length - 1]\n let toA = last.toA + (toB - last.toB)\n let deleted = Span.none, inserted = Span.none\n let delData = (changes[0].deleted.length ? changes[0].deleted : changes[0].inserted)[0].data\n let insData = (changes[0].inserted.length ? changes[0].inserted : changes[0].deleted)[0].data\n for (let posA = fromA, posB = fromB, i = 0;; i++) {\n let next = i == changes.length ? null : changes[i]\n let endA = next ? next.fromA : toA, endB = next ? next.fromB : toB\n if (endA > posA) deleted = Span.join(deleted, [new Span(endA - posA, delData)], combine)\n if (endB > posB) inserted = Span.join(inserted, [new Span(endB - posB, insData)], combine)\n if (!next) break\n deleted = Span.join(deleted, next.deleted, combine)\n inserted = Span.join(inserted, next.inserted, combine)\n if (deleted.length) delData = deleted[deleted.length - 1].data\n if (inserted.length) insData = inserted[inserted.length - 1].data\n posA = next.toA; posB = next.toB\n }\n return new Change(fromA, toA, fromB, toB, deleted, inserted)\n}\n","import {computeDiff} from \"./diff\"\nimport {Change, Span} from \"./change\"\nexport {Change, Span}\nexport {simplifyChanges} from \"./simplify\"\n\n// ::- A change set tracks the changes to a document from a given\n// point in the past. It condenses a number of step maps down to a\n// flat sequence of replacements, and simplifies replacments that\n// partially undo themselves by comparing their content.\nexport class ChangeSet {\n constructor(config, changes) {\n this.config = config\n // :: [Change] Replaced regions.\n this.changes = changes\n }\n\n // :: (Node, [StepMap], union<[any], any>) → ChangeSet\n // Computes a new changeset by adding the given step maps and\n // metadata (either as an array, per-map, or as a single value to be\n // associated with all maps) to the current set. Will not mutate the\n // old set.\n //\n // Note that due to simplification that happens after each add,\n // incrementally adding steps might create a different final set\n // than adding all those changes at once, since different document\n // tokens might be matched during simplification depending on the\n // boundaries of the current changed ranges.\n addSteps(newDoc, maps, data) {\n // This works by inspecting the position maps for the changes,\n // which indicate what parts of the document were replaced by new\n // content, and the size of that new content. It uses these to\n // build up Change objects.\n //\n // These change objects are put in sets and merged together using\n // Change.merge, giving us the changes created by the new steps.\n // Those changes can then be merged with the existing set of\n // changes.\n //\n // For each change that was touched by the new steps, we recompute\n // a diff to try to minimize the change by dropping matching\n // pieces of the old and new document from the change.\n\n let stepChanges = []\n // Add spans for new steps.\n for (let i = 0; i < maps.length; i++) {\n let d = Array.isArray(data) ? data[i] : data\n let off = 0\n maps[i].forEach((fromA, toA, fromB, toB) => {\n\n stepChanges.push(new Change(fromA + off, toA + off, fromB, toB,\n fromA == toA ? Span.none : [new Span(toA - fromA, d)],\n fromB == toB ? Span.none : [new Span(toB - fromB, d)]))\n\n off = (toB - fromB) - (toA - fromA)\n })\n }\n if (stepChanges.length == 0) return this\n\n let newChanges = mergeAll(stepChanges, this.config.combine)\n let changes = Change.merge(this.changes, newChanges, this.config.combine)\n\n // Minimize changes when possible\n for (let i = 0; i < changes.length; i++) {\n let change = changes[i]\n if (change.fromA == change.toA || change.fromB == change.toB ||\n // Only look at changes that touch newly added changed ranges\n !newChanges.some(r => r.toB > change.fromB && r.fromB < change.toB)) continue\n let diff = computeDiff(this.config.doc.content, newDoc.content, change)\n\n // Fast path: If they are completely different, don't do anything\n if (diff.length == 1 && diff[0].fromB == 0 && diff[0].toB == change.toB - change.fromB)\n continue\n\n if (diff.length == 1) {\n changes[i] = diff[0]\n } else {\n changes.splice(i, 1, ...diff)\n i += diff.length - 1\n }\n }\n\n return new ChangeSet(this.config, changes)\n }\n\n // :: Node\n // The starting document of the change set.\n get startDoc() { return this.config.doc }\n\n // :: (f: (range: Change) → any) → ChangeSet\n // Map the span's data values in the given set through a function\n // and construct a new set with the resulting data.\n map(f) {\n return new ChangeSet(this.config, this.changes.map(change => {\n let data = f(change)\n return data === change.data ? change :\n new Change(change.fromA, change.toA, change.fromB, change.toB, data)\n }))\n }\n\n // :: (ChangeSet, ?[StepMap]) → ?{from: number, to: number}\n // Compare two changesets and return the range in which they are\n // changed, if any. If the document changed between the maps, pass\n // the maps for the steps that changed it as second argument, and\n // make sure the method is called on the old set and passed the new\n // set. The returned positions will be in new document coordinates.\n changedRange(b, maps) {\n if (b == this) return null\n let touched = maps && touchedRange(maps)\n let moved = touched ? (touched.toB - touched.fromB) - (touched.toA - touched.fromA) : 0\n function map(p) {\n return !touched || p <= touched.fromA ? p : p + moved\n }\n\n let from = touched ? touched.fromB : 2e8, to = touched ? touched.toB : -2e8\n function add(start, end = start) {\n from = Math.min(start, from); to = Math.max(end, to)\n }\n\n let rA = this.changes, rB = b.changes\n for (let iA = 0, iB = 0; iA < rA.length && iB < rB.length;) {\n let rangeA = rA[iA], rangeB = rB[iB]\n if (rangeA && rangeB && sameRanges(rangeA, rangeB, map)) { iA++; iB++ }\n else if (rangeB && (!rangeA || map(rangeA.fromB) >= rangeB.fromB)) { add(rangeB.fromB, rangeB.toB); iB++ }\n else { add(map(rangeA.fromB), map(rangeA.toB)); iA++ }\n }\n\n return from <= to ? {from, to} : null\n }\n\n // :: (Node, ?(a: any, b: any) → any) → ChangeSet\n // Create a changeset with the given base object and configuration.\n // The `combine` function is used to compare and combine metadata—it\n // should return null when metadata isn't compatible, and a combined\n // version for a merged range when it is.\n static create(doc, combine = (a, b) => a === b ? a : null) {\n return new ChangeSet({combine, doc}, [], [])\n }\n}\n\n// Exported for testing\nChangeSet.computeDiff = computeDiff\n\n// : ([[Change]], (any, any) → any, number, number) → [Change]\n// Divide-and-conquer approach to merging a series of ranges.\nfunction mergeAll(ranges, combine, start = 0, end = ranges.length) {\n if (end == start + 1) return [ranges[start]]\n let mid = (start + end) >> 1\n return Change.merge(mergeAll(ranges, combine, start, mid),\n mergeAll(ranges, combine, mid, end), combine)\n}\n\nfunction endRange(maps) {\n let from = 2e8, to = -2e8\n for (let i = 0; i < maps.length; i++) {\n let map = maps[i]\n if (from != 2e8) {\n from = map.map(from, -1)\n to = map.map(to, 1)\n }\n map.forEach((_s, _e, start, end) => {\n from = Math.min(from, start)\n to = Math.max(to, end)\n })\n }\n return from == 2e8 ? null : {from, to}\n}\n\nfunction touchedRange(maps) {\n let b = endRange(maps)\n if (!b) return null\n let a = endRange(maps.map(m => m.invert()).reverse())\n return {fromA: a.from, toA: a.to, fromB: b.from, toB: b.to}\n}\n\nfunction sameRanges(a, b, map) {\n return map(a.fromB) == b.fromB && map(a.toB) == b.toB &&\n sameSpans(a.deleted, b.deleted) && sameSpans(a.inserted, b.inserted)\n}\n\nfunction sameSpans(a, b) {\n if (a.length != b.length) return false\n for (let i = 0; i < a.length; i++)\n if (a[i].length != b[i].length || a[i].data !== b[i].data) return false\n return true\n}\n"],"names":["let","const","i","next","prev","off","from","to","last","this","prototypeAccessors"],"mappings":"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"} |
199753
0.07%