(doc, change, markedSpans, estimateHeight)
| 21 | |
| 22 | // Perform a change on the document data structure. |
| 23 | export function updateDoc(doc, change, markedSpans, estimateHeight) { |
| 24 | function spansFor(n) {return markedSpans ? markedSpans[n] : null} |
| 25 | function update(line, text, spans) { |
| 26 | updateLine(line, text, spans, estimateHeight) |
| 27 | signalLater(line, "change", line, change) |
| 28 | } |
| 29 | function linesFor(start, end) { |
| 30 | let result = [] |
| 31 | for (let i = start; i < end; ++i) |
| 32 | result.push(new Line(text[i], spansFor(i), estimateHeight)) |
| 33 | return result |
| 34 | } |
| 35 | |
| 36 | let from = change.from, to = change.to, text = change.text |
| 37 | let firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line) |
| 38 | let lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line |
| 39 | |
| 40 | // Adjust the line structure |
| 41 | if (change.full) { |
| 42 | doc.insert(0, linesFor(0, text.length)) |
| 43 | doc.remove(text.length, doc.size - text.length) |
| 44 | } else if (isWholeLineUpdate(doc, change)) { |
| 45 | // This is a whole-line replace. Treated specially to make |
| 46 | // sure line objects move the way they are supposed to. |
| 47 | let added = linesFor(0, text.length - 1) |
| 48 | update(lastLine, lastLine.text, lastSpans) |
| 49 | if (nlines) doc.remove(from.line, nlines) |
| 50 | if (added.length) doc.insert(from.line, added) |
| 51 | } else if (firstLine == lastLine) { |
| 52 | if (text.length == 1) { |
| 53 | update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans) |
| 54 | } else { |
| 55 | let added = linesFor(1, text.length - 1) |
| 56 | added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight)) |
| 57 | update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)) |
| 58 | doc.insert(from.line + 1, added) |
| 59 | } |
| 60 | } else if (text.length == 1) { |
| 61 | update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0)) |
| 62 | doc.remove(from.line + 1, nlines) |
| 63 | } else { |
| 64 | update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0)) |
| 65 | update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans) |
| 66 | let added = linesFor(1, text.length - 1) |
| 67 | if (nlines > 1) doc.remove(from.line + 1, nlines - 1) |
| 68 | doc.insert(from.line + 1, added) |
| 69 | } |
| 70 | |
| 71 | signalLater(doc, "change", doc, change) |
| 72 | } |
| 73 | |
| 74 | // Call f for all linked documents. |
| 75 | export function linkedDocs(doc, f, sharedHistOnly) { |
no test coverage detected