prosemirror-history
Advanced tools
Comparing version 1.0.2 to 1.0.3
@@ -0,1 +1,9 @@ | ||
## 1.0.3 (2018-10-08) | ||
### Bug fixes | ||
Appending a transaction to an undo transaction will no longer immediately clear the redo history. | ||
When handling appended transactions, the history will keep the last step in the original transaction, not the one from the appended transaction, for testing whether a subsequent transaction is adjacent to the previous one. | ||
## 1.0.2 (2018-03-13) | ||
@@ -2,0 +10,0 @@ |
@@ -35,3 +35,3 @@ 'use strict'; | ||
// : (Node, bool, ?Item) → ?{transform: Transform, selection: Object} | ||
// : (EditorState, bool) → ?{transform: Transform, selection: ?SelectionBookmark, remaining: Branch} | ||
// Pop the latest event off the branch's history and apply it | ||
@@ -94,3 +94,3 @@ // to a document transform. | ||
// : (Transform, Selection, Object) | ||
// : (Transform, ?SelectionBookmark, Object) → Branch | ||
// Create a new branch with the given transform added. | ||
@@ -125,11 +125,9 @@ Branch.prototype.addTransform = function addTransform (transform, selection, histOptions, preserveItems) { | ||
Branch.prototype.remapping = function remapping (from, to) { | ||
var maps = [], mirrors = []; | ||
var maps = new prosemirrorTransform.Mapping; | ||
this.items.forEach(function (item, i) { | ||
if (item.mirrorOffset != null) { | ||
var mirrorPos = i - item.mirrorOffset; | ||
if (mirrorPos >= from) { mirrors.push(maps.length - item.mirrorOffset, maps.length); } | ||
} | ||
maps.push(item.map); | ||
var mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from | ||
? mirrorPos = maps.maps.length - item.mirrorOffset : null; | ||
maps.appendMap(item.map, mirrorPos); | ||
}, from, to); | ||
return new prosemirrorTransform.Mapping(maps, mirrors) | ||
return maps | ||
}; | ||
@@ -142,3 +140,3 @@ | ||
// : ([StepMap], Transform, [number]) | ||
// : (Transform, number) | ||
// When the collab module receives remote changes, the history has | ||
@@ -156,3 +154,3 @@ // to know about those, so that it can adjust the steps that were | ||
var eventCount = this.eventCount; | ||
this.items.forEach(function (item) { if (item.selection) { eventCount--; } }, this.items.length - rebasedCount); | ||
this.items.forEach(function (item) { if (item.selection) { eventCount--; } }, start); | ||
@@ -257,6 +255,6 @@ var iRebased = rebasedCount; | ||
// is active. | ||
var HistoryState = function HistoryState(done, undone, prevMap, prevTime) { | ||
var HistoryState = function HistoryState(done, undone, prevRanges, prevTime) { | ||
this.done = done; | ||
this.undone = undone; | ||
this.prevMap = prevMap; | ||
this.prevRanges = prevRanges; | ||
this.prevTime = prevTime; | ||
@@ -267,7 +265,7 @@ }; | ||
// : (EditorState, EditorState, Selection, Object) | ||
// : (HistoryState, EditorState, Transaction, Object) | ||
// Record a transformation in undo history. | ||
function applyTransaction(history, state, tr, options) { | ||
var newState = tr.getMeta(historyKey), rebased; | ||
if (newState) { return newState } | ||
var historyTr = tr.getMeta(historyKey), rebased; | ||
if (historyTr) { return historyTr.historyState } | ||
@@ -277,11 +275,20 @@ if (tr.getMeta(closeHistoryKey)) { history = new HistoryState(history.done, history.undone, null, 0); } | ||
var appended = tr.getMeta("appendedTransaction"); | ||
if (tr.steps.length == 0) { | ||
return history | ||
} else if ((appended || tr).getMeta("addToHistory") !== false) { | ||
} else if (appended && appended.getMeta(historyKey)) { | ||
if (appended.getMeta(historyKey).redo) | ||
{ return new HistoryState(history.done.addTransform(tr, null, options, mustPreserveItems(state)), | ||
history.undone, rangesFor(tr.mapping.maps[tr.steps.length - 1]), history.prevTime) } | ||
else | ||
{ return new HistoryState(history.done, history.undone.addTransform(tr, null, options, mustPreserveItems(state)), | ||
null, history.prevTime) } | ||
} else if (tr.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) { | ||
// Group transforms that occur in quick succession into one event. | ||
var newGroup = history.prevTime < (tr.time || 0) - options.newGroupDelay || | ||
!appended && !isAdjacentToLastStep(tr, history.prevMap, history.done); | ||
!appended && !isAdjacentTo(tr, history.prevRanges); | ||
var prevRanges = appended ? mapRanges(history.prevRanges, tr.mapping) : rangesFor(tr.mapping.maps[tr.steps.length - 1]); | ||
return new HistoryState(history.done.addTransform(tr, newGroup ? state.selection.getBookmark() : null, | ||
options, mustPreserveItems(state)), | ||
Branch.empty, tr.mapping.maps[tr.steps.length - 1], tr.time) | ||
Branch.empty, prevRanges, tr.time) | ||
} else if (rebased = tr.getMeta("rebased")) { | ||
@@ -292,26 +299,18 @@ // Used by the collab module to tell the history that some of its | ||
history.undone.rebased(tr, rebased), | ||
history.prevMap && tr.mapping.maps[tr.steps.length - 1], history.prevTime) | ||
mapRanges(history.prevRanges, tr.mapping), history.prevTime) | ||
} else { | ||
return new HistoryState(history.done.addMaps(tr.mapping.maps), | ||
history.undone.addMaps(tr.mapping.maps), | ||
history.prevMap, history.prevTime) | ||
mapRanges(history.prevRanges, tr.mapping), history.prevTime) | ||
} | ||
} | ||
function isAdjacentToLastStep(transform, prevMap, done) { | ||
if (!prevMap) { return false } | ||
var firstMap = transform.mapping.maps[0], adjacent = false; | ||
if (!firstMap) { return true } | ||
firstMap.forEach(function (start, end) { | ||
done.items.forEach(function (item) { | ||
if (item.step) { | ||
prevMap.forEach(function (_start, _end, rStart, rEnd) { | ||
if (start <= rEnd && end >= rStart) { adjacent = true; } | ||
}); | ||
return false | ||
} else { | ||
start = item.map.invert().map(start, -1); | ||
end = item.map.invert().map(end, 1); | ||
} | ||
}, done.items.length, 0); | ||
function isAdjacentTo(transform, prevRanges) { | ||
if (!prevRanges) { return false } | ||
if (!transform.docChanged) { return true } | ||
var adjacent = false; | ||
transform.mapping.maps[0].forEach(function (start, end) { | ||
for (var i = 0; i < prevRanges.length; i += 2) | ||
{ if (start <= prevRanges[i + 1] && end >= prevRanges[i]) | ||
{ adjacent = true; } } | ||
}); | ||
@@ -321,6 +320,21 @@ return adjacent | ||
function rangesFor(map) { | ||
var result = []; | ||
map.forEach(function (_from, _to, from, to) { return result.push(from, to); }); | ||
return result | ||
} | ||
function mapRanges(ranges, mapping) { | ||
if (!ranges) { return null } | ||
var result = []; | ||
for (var i = 0; i < ranges.length; i += 2) { | ||
var from = mapping.map(ranges[i], 1), to = mapping.map(ranges[i + 1], -1); | ||
if (from <= to) { result.push(from, to); } | ||
} | ||
return result | ||
} | ||
// : (HistoryState, EditorState, (tr: Transaction), bool) | ||
// Apply the latest event from one branch to the document and optionally | ||
// shift the event onto the other branch. Returns true when an event could | ||
// be shifted. | ||
// Apply the latest event from one branch to the document and shift the event | ||
// onto the other branch. | ||
function histTransaction(history, state, dispatch, redo) { | ||
@@ -336,3 +350,3 @@ var preserveItems = mustPreserveItems(state), histOptions = historyKey.get(state).spec.config; | ||
var newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0); | ||
dispatch(pop.transform.setSelection(selection).setMeta(historyKey, newHist).scrollIntoView()); | ||
dispatch(pop.transform.setSelection(selection).setMeta(historyKey, {redo: redo, historyState: newHist}).scrollIntoView()); | ||
} | ||
@@ -339,0 +353,0 @@ |
{ | ||
"name": "prosemirror-history", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"description": "Undo history for ProseMirror", | ||
@@ -19,3 +19,3 @@ "main": "dist/history.js", | ||
"dependencies": { | ||
"prosemirror-state": "^1.0.0", | ||
"prosemirror-state": "^1.2.2", | ||
"prosemirror-transform": "^1.0.0", | ||
@@ -22,0 +22,0 @@ "rope-sequence": "^1.2.0" |
# prosemirror-history | ||
[ [**WEBSITE**](http://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) | [**CHANGELOG**](https://github.com/ProseMirror/prosemirror/blob/master/CHANGELOG.md) ] | ||
[ [**WEBSITE**](http://prosemirror.net) | [**ISSUES**](https://github.com/prosemirror/prosemirror/issues) | [**FORUM**](https://discuss.prosemirror.net) | [**GITTER**](https://gitter.im/ProseMirror/prosemirror) | [**CHANGELOG**](https://github.com/ProseMirror/prosemirror-history/blob/master/CHANGELOG.md) ] | ||
@@ -5,0 +5,0 @@ This is a [core module](http://prosemirror.net/docs/ref/#history) of [ProseMirror](http://prosemirror.net). |
@@ -30,3 +30,3 @@ import RopeSequence from "rope-sequence" | ||
// : (Node, bool, ?Item) → ?{transform: Transform, selection: Object} | ||
// : (EditorState, bool) → ?{transform: Transform, selection: ?SelectionBookmark, remaining: Branch} | ||
// Pop the latest event off the branch's history and apply it | ||
@@ -87,3 +87,3 @@ // to a document transform. | ||
// : (Transform, Selection, Object) | ||
// : (Transform, ?SelectionBookmark, Object) → Branch | ||
// Create a new branch with the given transform added. | ||
@@ -118,11 +118,9 @@ addTransform(transform, selection, histOptions, preserveItems) { | ||
remapping(from, to) { | ||
let maps = [], mirrors = [] | ||
let maps = new Mapping | ||
this.items.forEach((item, i) => { | ||
if (item.mirrorOffset != null) { | ||
let mirrorPos = i - item.mirrorOffset | ||
if (mirrorPos >= from) mirrors.push(maps.length - item.mirrorOffset, maps.length) | ||
} | ||
maps.push(item.map) | ||
let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from | ||
? mirrorPos = maps.maps.length - item.mirrorOffset : null | ||
maps.appendMap(item.map, mirrorPos) | ||
}, from, to) | ||
return new Mapping(maps, mirrors) | ||
return maps | ||
} | ||
@@ -135,3 +133,3 @@ | ||
// : ([StepMap], Transform, [number]) | ||
// : (Transform, number) | ||
// When the collab module receives remote changes, the history has | ||
@@ -149,3 +147,3 @@ // to know about those, so that it can adjust the steps that were | ||
let eventCount = this.eventCount | ||
this.items.forEach(item => { if (item.selection) eventCount-- }, this.items.length - rebasedCount) | ||
this.items.forEach(item => { if (item.selection) eventCount-- }, start) | ||
@@ -252,6 +250,6 @@ let iRebased = rebasedCount | ||
export class HistoryState { | ||
constructor(done, undone, prevMap, prevTime) { | ||
constructor(done, undone, prevRanges, prevTime) { | ||
this.done = done | ||
this.undone = undone | ||
this.prevMap = prevMap | ||
this.prevRanges = prevRanges | ||
this.prevTime = prevTime | ||
@@ -263,7 +261,7 @@ } | ||
// : (EditorState, EditorState, Selection, Object) | ||
// : (HistoryState, EditorState, Transaction, Object) | ||
// Record a transformation in undo history. | ||
function applyTransaction(history, state, tr, options) { | ||
let newState = tr.getMeta(historyKey), rebased | ||
if (newState) return newState | ||
let historyTr = tr.getMeta(historyKey), rebased | ||
if (historyTr) return historyTr.historyState | ||
@@ -273,11 +271,20 @@ if (tr.getMeta(closeHistoryKey)) history = new HistoryState(history.done, history.undone, null, 0) | ||
let appended = tr.getMeta("appendedTransaction") | ||
if (tr.steps.length == 0) { | ||
return history | ||
} else if ((appended || tr).getMeta("addToHistory") !== false) { | ||
} else if (appended && appended.getMeta(historyKey)) { | ||
if (appended.getMeta(historyKey).redo) | ||
return new HistoryState(history.done.addTransform(tr, null, options, mustPreserveItems(state)), | ||
history.undone, rangesFor(tr.mapping.maps[tr.steps.length - 1]), history.prevTime) | ||
else | ||
return new HistoryState(history.done, history.undone.addTransform(tr, null, options, mustPreserveItems(state)), | ||
null, history.prevTime) | ||
} else if (tr.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) { | ||
// Group transforms that occur in quick succession into one event. | ||
let newGroup = history.prevTime < (tr.time || 0) - options.newGroupDelay || | ||
!appended && !isAdjacentToLastStep(tr, history.prevMap, history.done) | ||
!appended && !isAdjacentTo(tr, history.prevRanges) | ||
let prevRanges = appended ? mapRanges(history.prevRanges, tr.mapping) : rangesFor(tr.mapping.maps[tr.steps.length - 1]) | ||
return new HistoryState(history.done.addTransform(tr, newGroup ? state.selection.getBookmark() : null, | ||
options, mustPreserveItems(state)), | ||
Branch.empty, tr.mapping.maps[tr.steps.length - 1], tr.time) | ||
Branch.empty, prevRanges, tr.time) | ||
} else if (rebased = tr.getMeta("rebased")) { | ||
@@ -288,26 +295,18 @@ // Used by the collab module to tell the history that some of its | ||
history.undone.rebased(tr, rebased), | ||
history.prevMap && tr.mapping.maps[tr.steps.length - 1], history.prevTime) | ||
mapRanges(history.prevRanges, tr.mapping), history.prevTime) | ||
} else { | ||
return new HistoryState(history.done.addMaps(tr.mapping.maps), | ||
history.undone.addMaps(tr.mapping.maps), | ||
history.prevMap, history.prevTime) | ||
mapRanges(history.prevRanges, tr.mapping), history.prevTime) | ||
} | ||
} | ||
function isAdjacentToLastStep(transform, prevMap, done) { | ||
if (!prevMap) return false | ||
let firstMap = transform.mapping.maps[0], adjacent = false | ||
if (!firstMap) return true | ||
firstMap.forEach((start, end) => { | ||
done.items.forEach(item => { | ||
if (item.step) { | ||
prevMap.forEach((_start, _end, rStart, rEnd) => { | ||
if (start <= rEnd && end >= rStart) adjacent = true | ||
}) | ||
return false | ||
} else { | ||
start = item.map.invert().map(start, -1) | ||
end = item.map.invert().map(end, 1) | ||
} | ||
}, done.items.length, 0) | ||
function isAdjacentTo(transform, prevRanges) { | ||
if (!prevRanges) return false | ||
if (!transform.docChanged) return true | ||
let adjacent = false | ||
transform.mapping.maps[0].forEach((start, end) => { | ||
for (let i = 0; i < prevRanges.length; i += 2) | ||
if (start <= prevRanges[i + 1] && end >= prevRanges[i]) | ||
adjacent = true | ||
}) | ||
@@ -317,6 +316,21 @@ return adjacent | ||
function rangesFor(map) { | ||
let result = [] | ||
map.forEach((_from, _to, from, to) => result.push(from, to)) | ||
return result | ||
} | ||
function mapRanges(ranges, mapping) { | ||
if (!ranges) return null | ||
let result = [] | ||
for (let i = 0; i < ranges.length; i += 2) { | ||
let from = mapping.map(ranges[i], 1), to = mapping.map(ranges[i + 1], -1) | ||
if (from <= to) result.push(from, to) | ||
} | ||
return result | ||
} | ||
// : (HistoryState, EditorState, (tr: Transaction), bool) | ||
// Apply the latest event from one branch to the document and optionally | ||
// shift the event onto the other branch. Returns true when an event could | ||
// be shifted. | ||
// Apply the latest event from one branch to the document and shift the event | ||
// onto the other branch. | ||
function histTransaction(history, state, dispatch, redo) { | ||
@@ -332,3 +346,3 @@ let preserveItems = mustPreserveItems(state), histOptions = historyKey.get(state).spec.config | ||
let newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0) | ||
dispatch(pop.transform.setSelection(selection).setMeta(historyKey, newHist).scrollIntoView()) | ||
dispatch(pop.transform.setSelection(selection).setMeta(historyKey, {redo, historyState: newHist}).scrollIntoView()) | ||
} | ||
@@ -335,0 +349,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
74385
791
Updatedprosemirror-state@^1.2.2