(doc, type, allowSelectionOnly)
| 88 | |
| 89 | // Revert a change stored in a document's history. |
| 90 | export function makeChangeFromHistory(doc, type, allowSelectionOnly) { |
| 91 | let suppress = doc.cm && doc.cm.state.suppressEdits |
| 92 | if (suppress && !allowSelectionOnly) return |
| 93 | |
| 94 | let hist = doc.history, event, selAfter = doc.sel |
| 95 | let source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done |
| 96 | |
| 97 | // Verify that there is a useable event (so that ctrl-z won't |
| 98 | // needlessly clear selection events) |
| 99 | let i = 0 |
| 100 | for (; i < source.length; i++) { |
| 101 | event = source[i] |
| 102 | if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) |
| 103 | break |
| 104 | } |
| 105 | if (i == source.length) return |
| 106 | hist.lastOrigin = hist.lastSelOrigin = null |
| 107 | |
| 108 | for (;;) { |
| 109 | event = source.pop() |
| 110 | if (event.ranges) { |
| 111 | pushSelectionToHistory(event, dest) |
| 112 | if (allowSelectionOnly && !event.equals(doc.sel)) { |
| 113 | setSelection(doc, event, {clearRedo: false}) |
| 114 | return |
| 115 | } |
| 116 | selAfter = event |
| 117 | } else if (suppress) { |
| 118 | source.push(event) |
| 119 | return |
| 120 | } else break |
| 121 | } |
| 122 | |
| 123 | // Build up a reverse change object to add to the opposite history |
| 124 | // stack (redo when undoing, and vice versa). |
| 125 | let antiChanges = [] |
| 126 | pushSelectionToHistory(selAfter, dest) |
| 127 | dest.push({changes: antiChanges, generation: hist.generation}) |
| 128 | hist.generation = event.generation || ++hist.maxGeneration |
| 129 | |
| 130 | let filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange") |
| 131 | |
| 132 | for (let i = event.changes.length - 1; i >= 0; --i) { |
| 133 | let change = event.changes[i] |
| 134 | change.origin = type |
| 135 | if (filter && !filterChange(doc, change, false)) { |
| 136 | source.length = 0 |
| 137 | return |
| 138 | } |
| 139 | |
| 140 | antiChanges.push(historyChangeFromChange(doc, change)) |
| 141 | |
| 142 | let after = i ? computeSelAfterChange(doc, change) : lst(source) |
| 143 | makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)) |
| 144 | if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)}) |
| 145 | let rebased = [] |
| 146 | |
| 147 | // Propagate to the linked documents |
no test coverage detected