(doc, type, allowSelectionOnly)
| 3298 | |
| 3299 | // Revert a change stored in a document's history. |
| 3300 | function makeChangeFromHistory(doc, type, allowSelectionOnly) { |
| 3301 | if (doc.cm && doc.cm.state.suppressEdits) return; |
| 3302 | |
| 3303 | var hist = doc.history, event, selAfter = doc.sel; |
| 3304 | var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done; |
| 3305 | |
| 3306 | // Verify that there is a useable event (so that ctrl-z won't |
| 3307 | // needlessly clear selection events) |
| 3308 | for (var i = 0; i < source.length; i++) { |
| 3309 | event = source[i]; |
| 3310 | if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges) |
| 3311 | break; |
| 3312 | } |
| 3313 | if (i == source.length) return; |
| 3314 | hist.lastOrigin = hist.lastSelOrigin = null; |
| 3315 | |
| 3316 | for (;;) { |
| 3317 | event = source.pop(); |
| 3318 | if (event.ranges) { |
| 3319 | pushSelectionToHistory(event, dest); |
| 3320 | if (allowSelectionOnly && !event.equals(doc.sel)) { |
| 3321 | setSelection(doc, event, {clearRedo: false}); |
| 3322 | return; |
| 3323 | } |
| 3324 | selAfter = event; |
| 3325 | } |
| 3326 | else break; |
| 3327 | } |
| 3328 | |
| 3329 | // Build up a reverse change object to add to the opposite history |
| 3330 | // stack (redo when undoing, and vice versa). |
| 3331 | var antiChanges = []; |
| 3332 | pushSelectionToHistory(selAfter, dest); |
| 3333 | dest.push({changes: antiChanges, generation: hist.generation}); |
| 3334 | hist.generation = event.generation || ++hist.maxGeneration; |
| 3335 | |
| 3336 | var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange"); |
| 3337 | |
| 3338 | for (var i = event.changes.length - 1; i >= 0; --i) { |
| 3339 | var change = event.changes[i]; |
| 3340 | change.origin = type; |
| 3341 | if (filter && !filterChange(doc, change, false)) { |
| 3342 | source.length = 0; |
| 3343 | return; |
| 3344 | } |
| 3345 | |
| 3346 | antiChanges.push(historyChangeFromChange(doc, change)); |
| 3347 | |
| 3348 | var after = i ? computeSelAfterChange(doc, change, null) : lst(source); |
| 3349 | makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change)); |
| 3350 | if (doc.cm) ensureCursorVisible(doc.cm); |
| 3351 | var rebased = []; |
| 3352 | |
| 3353 | // Propagate to the linked documents |
| 3354 | linkedDocs(doc, function(doc, sharedHist) { |
| 3355 | if (!sharedHist && indexOf(rebased, doc.history) == -1) { |
| 3356 | rebaseHist(doc.history, change); |
| 3357 | rebased.push(doc.history); |
no test coverage detected