Initial
This commit is contained in:
8
resources/app/node_modules/prosemirror-history/.tern-project
generated
vendored
Normal file
8
resources/app/node_modules/prosemirror-history/.tern-project
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"libs": ["browser"],
|
||||
"plugins": {
|
||||
"node": {},
|
||||
"complete_strings": {},
|
||||
"es_modules": {}
|
||||
}
|
||||
}
|
||||
104
resources/app/node_modules/prosemirror-history/CONTRIBUTING.md
generated
vendored
Normal file
104
resources/app/node_modules/prosemirror-history/CONTRIBUTING.md
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
# How to contribute
|
||||
|
||||
- [Getting help](#getting-help)
|
||||
- [Submitting bug reports](#submitting-bug-reports)
|
||||
- [Contributing code](#contributing-code)
|
||||
|
||||
## Getting help
|
||||
|
||||
Community discussion, questions, and informal bug reporting is done on the
|
||||
[discuss.ProseMirror forum](http://discuss.prosemirror.net).
|
||||
|
||||
## Submitting bug reports
|
||||
|
||||
Report bugs on the
|
||||
[GitHub issue tracker](http://github.com/prosemirror/prosemirror/issues).
|
||||
Before reporting a bug, please read these pointers.
|
||||
|
||||
- The issue tracker is for *bugs*, not requests for help. Questions
|
||||
should be asked on the [forum](http://discuss.prosemirror.net).
|
||||
|
||||
- Include information about the version of the code that exhibits the
|
||||
problem. For browser-related issues, include the browser and browser
|
||||
version on which the problem occurred.
|
||||
|
||||
- Mention very precisely what went wrong. "X is broken" is not a good
|
||||
bug report. What did you expect to happen? What happened instead?
|
||||
Describe the exact steps a maintainer has to take to make the
|
||||
problem occur. A screencast can be useful, but is no substitute for
|
||||
a textual description.
|
||||
|
||||
- A great way to make it easy to reproduce your problem, if it can not
|
||||
be trivially reproduced on the website demos, is to submit a script
|
||||
that triggers the issue.
|
||||
|
||||
## Contributing code
|
||||
|
||||
If you want to make a change that involves a significant overhaul of
|
||||
the code or introduces a user-visible new feature, create an
|
||||
[RFC](https://github.com/ProseMirror/rfcs/) first with your proposal.
|
||||
|
||||
- Make sure you have a [GitHub Account](https://github.com/signup/free)
|
||||
|
||||
- Fork the relevant repository
|
||||
([how to fork a repo](https://help.github.com/articles/fork-a-repo))
|
||||
|
||||
- Create a local checkout of the code. You can use the
|
||||
[main repository](https://github.com/prosemirror/prosemirror) to
|
||||
easily check out all core modules.
|
||||
|
||||
- Make your changes, and commit them
|
||||
|
||||
- Follow the code style of the rest of the project (see below). Run
|
||||
`npm run lint` (in the main repository checkout) to make sure that
|
||||
the linter is happy.
|
||||
|
||||
- If your changes are easy to test or likely to regress, add tests in
|
||||
the relevant `test/` directory. Either put them in an existing
|
||||
`test-*.js` file, if they fit there, or add a new file.
|
||||
|
||||
- Make sure all tests pass. Run `npm run test` to verify tests pass
|
||||
(you will need Node.js v6+).
|
||||
|
||||
- Submit a pull request ([how to create a pull request](https://help.github.com/articles/fork-a-repo)).
|
||||
Don't put more than one feature/fix in a single pull request.
|
||||
|
||||
By contributing code to ProseMirror you
|
||||
|
||||
- Agree to license the contributed code under the project's [MIT
|
||||
license](https://github.com/ProseMirror/prosemirror/blob/master/LICENSE).
|
||||
|
||||
- Confirm that you have the right to contribute and license the code
|
||||
in question. (Either you hold all rights on the code, or the rights
|
||||
holder has explicitly granted the right to use it like this,
|
||||
through a compatible open source license or through a direct
|
||||
agreement with you.)
|
||||
|
||||
### Coding standards
|
||||
|
||||
- ES6 syntax, targeting an ES5 runtime (i.e. don't use library
|
||||
elements added by ES6, don't use ES7/ES.next syntax).
|
||||
|
||||
- 2 spaces per indentation level, no tabs.
|
||||
|
||||
- No semicolons except when necessary.
|
||||
|
||||
- Follow the surrounding code when it comes to spacing, brace
|
||||
placement, etc.
|
||||
|
||||
- Brace-less single-statement bodies are encouraged (whenever they
|
||||
don't impact readability).
|
||||
|
||||
- [getdocs](https://github.com/marijnh/getdocs)-style doc comments
|
||||
above items that are part of the public API.
|
||||
|
||||
- When documenting non-public items, you can put the type after a
|
||||
single colon, so that getdocs doesn't pick it up and add it to the
|
||||
API reference.
|
||||
|
||||
- The linter (`npm run lint`) complains about unused variables and
|
||||
functions. Prefix their names with an underscore to muffle it.
|
||||
|
||||
- ProseMirror does *not* follow JSHint or JSLint prescribed style.
|
||||
Patches that try to 'fix' code to pass one of these linters will not
|
||||
be accepted.
|
||||
19
resources/app/node_modules/prosemirror-history/LICENSE
generated
vendored
Normal file
19
resources/app/node_modules/prosemirror-history/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (C) 2015-2017 by Marijn Haverbeke <marijn@haverbeke.berlin> and others
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
378
resources/app/node_modules/prosemirror-history/dist/index.cjs
generated
vendored
Normal file
378
resources/app/node_modules/prosemirror-history/dist/index.cjs
generated
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
'use strict';
|
||||
|
||||
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
||||
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
||||
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
||||
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
||||
var RopeSequence = require('rope-sequence');
|
||||
var prosemirrorTransform = require('prosemirror-transform');
|
||||
var prosemirrorState = require('prosemirror-state');
|
||||
var max_empty_items = 500;
|
||||
var Branch = function () {
|
||||
function Branch(items, eventCount) {
|
||||
_classCallCheck(this, Branch);
|
||||
this.items = items;
|
||||
this.eventCount = eventCount;
|
||||
}
|
||||
_createClass(Branch, [{
|
||||
key: "popEvent",
|
||||
value: function popEvent(state, preserveItems) {
|
||||
var _this = this;
|
||||
if (this.eventCount == 0) return null;
|
||||
var end = this.items.length;
|
||||
for (;; end--) {
|
||||
var next = this.items.get(end - 1);
|
||||
if (next.selection) {
|
||||
--end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var remap, mapFrom;
|
||||
if (preserveItems) {
|
||||
remap = this.remapping(end, this.items.length);
|
||||
mapFrom = remap.maps.length;
|
||||
}
|
||||
var transform = state.tr;
|
||||
var selection, remaining;
|
||||
var addAfter = [],
|
||||
addBefore = [];
|
||||
this.items.forEach(function (item, i) {
|
||||
if (!item.step) {
|
||||
if (!remap) {
|
||||
remap = _this.remapping(end, i + 1);
|
||||
mapFrom = remap.maps.length;
|
||||
}
|
||||
mapFrom--;
|
||||
addBefore.push(item);
|
||||
return;
|
||||
}
|
||||
if (remap) {
|
||||
addBefore.push(new Item(item.map));
|
||||
var step = item.step.map(remap.slice(mapFrom)),
|
||||
map;
|
||||
if (step && transform.maybeStep(step).doc) {
|
||||
map = transform.mapping.maps[transform.mapping.maps.length - 1];
|
||||
addAfter.push(new Item(map, undefined, undefined, addAfter.length + addBefore.length));
|
||||
}
|
||||
mapFrom--;
|
||||
if (map) remap.appendMap(map, mapFrom);
|
||||
} else {
|
||||
transform.maybeStep(item.step);
|
||||
}
|
||||
if (item.selection) {
|
||||
selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection;
|
||||
remaining = new Branch(_this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), _this.eventCount - 1);
|
||||
return false;
|
||||
}
|
||||
}, this.items.length, 0);
|
||||
return {
|
||||
remaining: remaining,
|
||||
transform: transform,
|
||||
selection: selection
|
||||
};
|
||||
}
|
||||
}, {
|
||||
key: "addTransform",
|
||||
value: function addTransform(transform, selection, histOptions, preserveItems) {
|
||||
var newItems = [],
|
||||
eventCount = this.eventCount;
|
||||
var oldItems = this.items,
|
||||
lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;
|
||||
for (var i = 0; i < transform.steps.length; i++) {
|
||||
var step = transform.steps[i].invert(transform.docs[i]);
|
||||
var item = new Item(transform.mapping.maps[i], step, selection),
|
||||
merged = void 0;
|
||||
if (merged = lastItem && lastItem.merge(item)) {
|
||||
item = merged;
|
||||
if (i) newItems.pop();else oldItems = oldItems.slice(0, oldItems.length - 1);
|
||||
}
|
||||
newItems.push(item);
|
||||
if (selection) {
|
||||
eventCount++;
|
||||
selection = undefined;
|
||||
}
|
||||
if (!preserveItems) lastItem = item;
|
||||
}
|
||||
var overflow = eventCount - histOptions.depth;
|
||||
if (overflow > DEPTH_OVERFLOW) {
|
||||
oldItems = cutOffEvents(oldItems, overflow);
|
||||
eventCount -= overflow;
|
||||
}
|
||||
return new Branch(oldItems.append(newItems), eventCount);
|
||||
}
|
||||
}, {
|
||||
key: "remapping",
|
||||
value: function remapping(from, to) {
|
||||
var maps = new prosemirrorTransform.Mapping();
|
||||
this.items.forEach(function (item, i) {
|
||||
var mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from ? maps.maps.length - item.mirrorOffset : undefined;
|
||||
maps.appendMap(item.map, mirrorPos);
|
||||
}, from, to);
|
||||
return maps;
|
||||
}
|
||||
}, {
|
||||
key: "addMaps",
|
||||
value: function addMaps(array) {
|
||||
if (this.eventCount == 0) return this;
|
||||
return new Branch(this.items.append(array.map(function (map) {
|
||||
return new Item(map);
|
||||
})), this.eventCount);
|
||||
}
|
||||
}, {
|
||||
key: "rebased",
|
||||
value: function rebased(rebasedTransform, rebasedCount) {
|
||||
if (!this.eventCount) return this;
|
||||
var rebasedItems = [],
|
||||
start = Math.max(0, this.items.length - rebasedCount);
|
||||
var mapping = rebasedTransform.mapping;
|
||||
var newUntil = rebasedTransform.steps.length;
|
||||
var eventCount = this.eventCount;
|
||||
this.items.forEach(function (item) {
|
||||
if (item.selection) eventCount--;
|
||||
}, start);
|
||||
var iRebased = rebasedCount;
|
||||
this.items.forEach(function (item) {
|
||||
var pos = mapping.getMirror(--iRebased);
|
||||
if (pos == null) return;
|
||||
newUntil = Math.min(newUntil, pos);
|
||||
var map = mapping.maps[pos];
|
||||
if (item.step) {
|
||||
var step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]);
|
||||
var selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));
|
||||
if (selection) eventCount++;
|
||||
rebasedItems.push(new Item(map, step, selection));
|
||||
} else {
|
||||
rebasedItems.push(new Item(map));
|
||||
}
|
||||
}, start);
|
||||
var newMaps = [];
|
||||
for (var i = rebasedCount; i < newUntil; i++) newMaps.push(new Item(mapping.maps[i]));
|
||||
var items = this.items.slice(0, start).append(newMaps).append(rebasedItems);
|
||||
var branch = new Branch(items, eventCount);
|
||||
if (branch.emptyItemCount() > max_empty_items) branch = branch.compress(this.items.length - rebasedItems.length);
|
||||
return branch;
|
||||
}
|
||||
}, {
|
||||
key: "emptyItemCount",
|
||||
value: function emptyItemCount() {
|
||||
var count = 0;
|
||||
this.items.forEach(function (item) {
|
||||
if (!item.step) count++;
|
||||
});
|
||||
return count;
|
||||
}
|
||||
}, {
|
||||
key: "compress",
|
||||
value: function compress() {
|
||||
var upto = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.items.length;
|
||||
var remap = this.remapping(0, upto),
|
||||
mapFrom = remap.maps.length;
|
||||
var items = [],
|
||||
events = 0;
|
||||
this.items.forEach(function (item, i) {
|
||||
if (i >= upto) {
|
||||
items.push(item);
|
||||
if (item.selection) events++;
|
||||
} else if (item.step) {
|
||||
var step = item.step.map(remap.slice(mapFrom)),
|
||||
map = step && step.getMap();
|
||||
mapFrom--;
|
||||
if (map) remap.appendMap(map, mapFrom);
|
||||
if (step) {
|
||||
var selection = item.selection && item.selection.map(remap.slice(mapFrom));
|
||||
if (selection) events++;
|
||||
var newItem = new Item(map.invert(), step, selection),
|
||||
merged,
|
||||
last = items.length - 1;
|
||||
if (merged = items.length && items[last].merge(newItem)) items[last] = merged;else items.push(newItem);
|
||||
}
|
||||
} else if (item.map) {
|
||||
mapFrom--;
|
||||
}
|
||||
}, this.items.length, 0);
|
||||
return new Branch(RopeSequence.from(items.reverse()), events);
|
||||
}
|
||||
}]);
|
||||
return Branch;
|
||||
}();
|
||||
Branch.empty = new Branch(RopeSequence.empty, 0);
|
||||
function cutOffEvents(items, n) {
|
||||
var cutPoint;
|
||||
items.forEach(function (item, i) {
|
||||
if (item.selection && n-- == 0) {
|
||||
cutPoint = i;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return items.slice(cutPoint);
|
||||
}
|
||||
var Item = function () {
|
||||
function Item(map, step, selection, mirrorOffset) {
|
||||
_classCallCheck(this, Item);
|
||||
this.map = map;
|
||||
this.step = step;
|
||||
this.selection = selection;
|
||||
this.mirrorOffset = mirrorOffset;
|
||||
}
|
||||
_createClass(Item, [{
|
||||
key: "merge",
|
||||
value: function merge(other) {
|
||||
if (this.step && other.step && !other.selection) {
|
||||
var step = other.step.merge(this.step);
|
||||
if (step) return new Item(step.getMap().invert(), step, this.selection);
|
||||
}
|
||||
}
|
||||
}]);
|
||||
return Item;
|
||||
}();
|
||||
var HistoryState = _createClass(function HistoryState(done, undone, prevRanges, prevTime, prevComposition) {
|
||||
_classCallCheck(this, HistoryState);
|
||||
this.done = done;
|
||||
this.undone = undone;
|
||||
this.prevRanges = prevRanges;
|
||||
this.prevTime = prevTime;
|
||||
this.prevComposition = prevComposition;
|
||||
});
|
||||
var DEPTH_OVERFLOW = 20;
|
||||
function applyTransaction(history, state, tr, options) {
|
||||
var historyTr = tr.getMeta(historyKey),
|
||||
rebased;
|
||||
if (historyTr) return historyTr.historyState;
|
||||
if (tr.getMeta(closeHistoryKey)) history = new HistoryState(history.done, history.undone, null, 0, -1);
|
||||
var appended = tr.getMeta("appendedTransaction");
|
||||
if (tr.steps.length == 0) {
|
||||
return history;
|
||||
} else if (appended && appended.getMeta(historyKey)) {
|
||||
if (appended.getMeta(historyKey).redo) return new HistoryState(history.done.addTransform(tr, undefined, options, mustPreserveItems(state)), history.undone, rangesFor(tr.mapping.maps[tr.steps.length - 1]), history.prevTime, history.prevComposition);else return new HistoryState(history.done, history.undone.addTransform(tr, undefined, options, mustPreserveItems(state)), null, history.prevTime, history.prevComposition);
|
||||
} else if (tr.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) {
|
||||
var composition = tr.getMeta("composition");
|
||||
var newGroup = history.prevTime == 0 || !appended && history.prevComposition != composition && (history.prevTime < (tr.time || 0) - options.newGroupDelay || !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() : undefined, options, mustPreserveItems(state)), Branch.empty, prevRanges, tr.time, composition == null ? history.prevComposition : composition);
|
||||
} else if (rebased = tr.getMeta("rebased")) {
|
||||
return new HistoryState(history.done.rebased(tr, rebased), history.undone.rebased(tr, rebased), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
||||
} else {
|
||||
return new HistoryState(history.done.addMaps(tr.mapping.maps), history.undone.addMaps(tr.mapping.maps), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
||||
}
|
||||
}
|
||||
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;
|
||||
});
|
||||
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;
|
||||
}
|
||||
function histTransaction(history, state, redo) {
|
||||
var preserveItems = mustPreserveItems(state);
|
||||
var histOptions = historyKey.get(state).spec.config;
|
||||
var pop = (redo ? history.undone : history.done).popEvent(state, preserveItems);
|
||||
if (!pop) return null;
|
||||
var selection = pop.selection.resolve(pop.transform.doc);
|
||||
var added = (redo ? history.done : history.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems);
|
||||
var newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0, -1);
|
||||
return pop.transform.setSelection(selection).setMeta(historyKey, {
|
||||
redo: redo,
|
||||
historyState: newHist
|
||||
});
|
||||
}
|
||||
var cachedPreserveItems = false,
|
||||
cachedPreserveItemsPlugins = null;
|
||||
function mustPreserveItems(state) {
|
||||
var plugins = state.plugins;
|
||||
if (cachedPreserveItemsPlugins != plugins) {
|
||||
cachedPreserveItems = false;
|
||||
cachedPreserveItemsPlugins = plugins;
|
||||
for (var i = 0; i < plugins.length; i++) if (plugins[i].spec.historyPreserveItems) {
|
||||
cachedPreserveItems = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cachedPreserveItems;
|
||||
}
|
||||
function closeHistory(tr) {
|
||||
return tr.setMeta(closeHistoryKey, true);
|
||||
}
|
||||
var historyKey = new prosemirrorState.PluginKey("history");
|
||||
var closeHistoryKey = new prosemirrorState.PluginKey("closeHistory");
|
||||
function history() {
|
||||
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
||||
config = {
|
||||
depth: config.depth || 100,
|
||||
newGroupDelay: config.newGroupDelay || 500
|
||||
};
|
||||
return new prosemirrorState.Plugin({
|
||||
key: historyKey,
|
||||
state: {
|
||||
init: function init() {
|
||||
return new HistoryState(Branch.empty, Branch.empty, null, 0, -1);
|
||||
},
|
||||
apply: function apply(tr, hist, state) {
|
||||
return applyTransaction(hist, state, tr, config);
|
||||
}
|
||||
},
|
||||
config: config,
|
||||
props: {
|
||||
handleDOMEvents: {
|
||||
beforeinput: function beforeinput(view, e) {
|
||||
var inputType = e.inputType;
|
||||
var command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
|
||||
if (!command) return false;
|
||||
e.preventDefault();
|
||||
return command(view.state, view.dispatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function buildCommand(redo, scroll) {
|
||||
return function (state, dispatch) {
|
||||
var hist = historyKey.getState(state);
|
||||
if (!hist || (redo ? hist.undone : hist.done).eventCount == 0) return false;
|
||||
if (dispatch) {
|
||||
var tr = histTransaction(hist, state, redo);
|
||||
if (tr) dispatch(scroll ? tr.scrollIntoView() : tr);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
var undo = buildCommand(false, true);
|
||||
var redo = buildCommand(true, true);
|
||||
var undoNoScroll = buildCommand(false, false);
|
||||
var redoNoScroll = buildCommand(true, false);
|
||||
function undoDepth(state) {
|
||||
var hist = historyKey.getState(state);
|
||||
return hist ? hist.done.eventCount : 0;
|
||||
}
|
||||
function redoDepth(state) {
|
||||
var hist = historyKey.getState(state);
|
||||
return hist ? hist.undone.eventCount : 0;
|
||||
}
|
||||
exports.closeHistory = closeHistory;
|
||||
exports.history = history;
|
||||
exports.redo = redo;
|
||||
exports.redoDepth = redoDepth;
|
||||
exports.redoNoScroll = redoNoScroll;
|
||||
exports.undo = undo;
|
||||
exports.undoDepth = undoDepth;
|
||||
exports.undoNoScroll = undoNoScroll;
|
||||
59
resources/app/node_modules/prosemirror-history/dist/index.d.cts
generated
vendored
Normal file
59
resources/app/node_modules/prosemirror-history/dist/index.d.cts
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
import { Transaction, Plugin, Command, EditorState } from 'prosemirror-state';
|
||||
|
||||
/**
|
||||
Set a flag on the given transaction that will prevent further steps
|
||||
from being appended to an existing history event (so that they
|
||||
require a separate undo command to undo).
|
||||
*/
|
||||
declare function closeHistory(tr: Transaction): Transaction;
|
||||
interface HistoryOptions {
|
||||
/**
|
||||
The amount of history events that are collected before the
|
||||
oldest events are discarded. Defaults to 100.
|
||||
*/
|
||||
depth?: number;
|
||||
/**
|
||||
The delay between changes after which a new group should be
|
||||
started. Defaults to 500 (milliseconds). Note that when changes
|
||||
aren't adjacent, a new group is always started.
|
||||
*/
|
||||
newGroupDelay?: number;
|
||||
}
|
||||
/**
|
||||
Returns a plugin that enables the undo history for an editor. The
|
||||
plugin will track undo and redo stacks, which can be used with the
|
||||
[`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.
|
||||
|
||||
You can set an `"addToHistory"` [metadata
|
||||
property](https://prosemirror.net/docs/ref/#state.Transaction.setMeta) of `false` on a transaction
|
||||
to prevent it from being rolled back by undo.
|
||||
*/
|
||||
declare function history(config?: HistoryOptions): Plugin;
|
||||
/**
|
||||
A command function that undoes the last change, if any.
|
||||
*/
|
||||
declare const undo: Command;
|
||||
/**
|
||||
A command function that redoes the last undone change, if any.
|
||||
*/
|
||||
declare const redo: Command;
|
||||
/**
|
||||
A command function that undoes the last change. Don't scroll the
|
||||
selection into view.
|
||||
*/
|
||||
declare const undoNoScroll: Command;
|
||||
/**
|
||||
A command function that redoes the last undone change. Don't
|
||||
scroll the selection into view.
|
||||
*/
|
||||
declare const redoNoScroll: Command;
|
||||
/**
|
||||
The amount of undoable events available in a given state.
|
||||
*/
|
||||
declare function undoDepth(state: EditorState): any;
|
||||
/**
|
||||
The amount of redoable events available in a given editor state.
|
||||
*/
|
||||
declare function redoDepth(state: EditorState): any;
|
||||
|
||||
export { closeHistory, history, redo, redoDepth, redoNoScroll, undo, undoDepth, undoNoScroll };
|
||||
445
resources/app/node_modules/prosemirror-history/dist/index.js
generated
vendored
Normal file
445
resources/app/node_modules/prosemirror-history/dist/index.js
generated
vendored
Normal file
@@ -0,0 +1,445 @@
|
||||
import RopeSequence from 'rope-sequence';
|
||||
import { Mapping } from 'prosemirror-transform';
|
||||
import { PluginKey, Plugin } from 'prosemirror-state';
|
||||
|
||||
// ProseMirror's history isn't simply a way to roll back to a previous
|
||||
// state, because ProseMirror supports applying changes without adding
|
||||
// them to the history (for example during collaboration).
|
||||
//
|
||||
// To this end, each 'Branch' (one for the undo history and one for
|
||||
// the redo history) keeps an array of 'Items', which can optionally
|
||||
// hold a step (an actual undoable change), and always hold a position
|
||||
// map (which is needed to move changes below them to apply to the
|
||||
// current document).
|
||||
//
|
||||
// An item that has both a step and a selection bookmark is the start
|
||||
// of an 'event' — a group of changes that will be undone or redone at
|
||||
// once. (It stores only the bookmark, since that way we don't have to
|
||||
// provide a document until the selection is actually applied, which
|
||||
// is useful when compressing.)
|
||||
// Used to schedule history compression
|
||||
const max_empty_items = 500;
|
||||
class Branch {
|
||||
constructor(items, eventCount) {
|
||||
this.items = items;
|
||||
this.eventCount = eventCount;
|
||||
}
|
||||
// Pop the latest event off the branch's history and apply it
|
||||
// to a document transform.
|
||||
popEvent(state, preserveItems) {
|
||||
if (this.eventCount == 0)
|
||||
return null;
|
||||
let end = this.items.length;
|
||||
for (;; end--) {
|
||||
let next = this.items.get(end - 1);
|
||||
if (next.selection) {
|
||||
--end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
let remap, mapFrom;
|
||||
if (preserveItems) {
|
||||
remap = this.remapping(end, this.items.length);
|
||||
mapFrom = remap.maps.length;
|
||||
}
|
||||
let transform = state.tr;
|
||||
let selection, remaining;
|
||||
let addAfter = [], addBefore = [];
|
||||
this.items.forEach((item, i) => {
|
||||
if (!item.step) {
|
||||
if (!remap) {
|
||||
remap = this.remapping(end, i + 1);
|
||||
mapFrom = remap.maps.length;
|
||||
}
|
||||
mapFrom--;
|
||||
addBefore.push(item);
|
||||
return;
|
||||
}
|
||||
if (remap) {
|
||||
addBefore.push(new Item(item.map));
|
||||
let step = item.step.map(remap.slice(mapFrom)), map;
|
||||
if (step && transform.maybeStep(step).doc) {
|
||||
map = transform.mapping.maps[transform.mapping.maps.length - 1];
|
||||
addAfter.push(new Item(map, undefined, undefined, addAfter.length + addBefore.length));
|
||||
}
|
||||
mapFrom--;
|
||||
if (map)
|
||||
remap.appendMap(map, mapFrom);
|
||||
}
|
||||
else {
|
||||
transform.maybeStep(item.step);
|
||||
}
|
||||
if (item.selection) {
|
||||
selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection;
|
||||
remaining = new Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1);
|
||||
return false;
|
||||
}
|
||||
}, this.items.length, 0);
|
||||
return { remaining: remaining, transform, selection: selection };
|
||||
}
|
||||
// Create a new branch with the given transform added.
|
||||
addTransform(transform, selection, histOptions, preserveItems) {
|
||||
let newItems = [], eventCount = this.eventCount;
|
||||
let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null;
|
||||
for (let i = 0; i < transform.steps.length; i++) {
|
||||
let step = transform.steps[i].invert(transform.docs[i]);
|
||||
let item = new Item(transform.mapping.maps[i], step, selection), merged;
|
||||
if (merged = lastItem && lastItem.merge(item)) {
|
||||
item = merged;
|
||||
if (i)
|
||||
newItems.pop();
|
||||
else
|
||||
oldItems = oldItems.slice(0, oldItems.length - 1);
|
||||
}
|
||||
newItems.push(item);
|
||||
if (selection) {
|
||||
eventCount++;
|
||||
selection = undefined;
|
||||
}
|
||||
if (!preserveItems)
|
||||
lastItem = item;
|
||||
}
|
||||
let overflow = eventCount - histOptions.depth;
|
||||
if (overflow > DEPTH_OVERFLOW) {
|
||||
oldItems = cutOffEvents(oldItems, overflow);
|
||||
eventCount -= overflow;
|
||||
}
|
||||
return new Branch(oldItems.append(newItems), eventCount);
|
||||
}
|
||||
remapping(from, to) {
|
||||
let maps = new Mapping;
|
||||
this.items.forEach((item, i) => {
|
||||
let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from
|
||||
? maps.maps.length - item.mirrorOffset : undefined;
|
||||
maps.appendMap(item.map, mirrorPos);
|
||||
}, from, to);
|
||||
return maps;
|
||||
}
|
||||
addMaps(array) {
|
||||
if (this.eventCount == 0)
|
||||
return this;
|
||||
return new Branch(this.items.append(array.map(map => new Item(map))), this.eventCount);
|
||||
}
|
||||
// When the collab module receives remote changes, the history has
|
||||
// to know about those, so that it can adjust the steps that were
|
||||
// rebased on top of the remote changes, and include the position
|
||||
// maps for the remote changes in its array of items.
|
||||
rebased(rebasedTransform, rebasedCount) {
|
||||
if (!this.eventCount)
|
||||
return this;
|
||||
let rebasedItems = [], start = Math.max(0, this.items.length - rebasedCount);
|
||||
let mapping = rebasedTransform.mapping;
|
||||
let newUntil = rebasedTransform.steps.length;
|
||||
let eventCount = this.eventCount;
|
||||
this.items.forEach(item => { if (item.selection)
|
||||
eventCount--; }, start);
|
||||
let iRebased = rebasedCount;
|
||||
this.items.forEach(item => {
|
||||
let pos = mapping.getMirror(--iRebased);
|
||||
if (pos == null)
|
||||
return;
|
||||
newUntil = Math.min(newUntil, pos);
|
||||
let map = mapping.maps[pos];
|
||||
if (item.step) {
|
||||
let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos]);
|
||||
let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos));
|
||||
if (selection)
|
||||
eventCount++;
|
||||
rebasedItems.push(new Item(map, step, selection));
|
||||
}
|
||||
else {
|
||||
rebasedItems.push(new Item(map));
|
||||
}
|
||||
}, start);
|
||||
let newMaps = [];
|
||||
for (let i = rebasedCount; i < newUntil; i++)
|
||||
newMaps.push(new Item(mapping.maps[i]));
|
||||
let items = this.items.slice(0, start).append(newMaps).append(rebasedItems);
|
||||
let branch = new Branch(items, eventCount);
|
||||
if (branch.emptyItemCount() > max_empty_items)
|
||||
branch = branch.compress(this.items.length - rebasedItems.length);
|
||||
return branch;
|
||||
}
|
||||
emptyItemCount() {
|
||||
let count = 0;
|
||||
this.items.forEach(item => { if (!item.step)
|
||||
count++; });
|
||||
return count;
|
||||
}
|
||||
// Compressing a branch means rewriting it to push the air (map-only
|
||||
// items) out. During collaboration, these naturally accumulate
|
||||
// because each remote change adds one. The `upto` argument is used
|
||||
// to ensure that only the items below a given level are compressed,
|
||||
// because `rebased` relies on a clean, untouched set of items in
|
||||
// order to associate old items with rebased steps.
|
||||
compress(upto = this.items.length) {
|
||||
let remap = this.remapping(0, upto), mapFrom = remap.maps.length;
|
||||
let items = [], events = 0;
|
||||
this.items.forEach((item, i) => {
|
||||
if (i >= upto) {
|
||||
items.push(item);
|
||||
if (item.selection)
|
||||
events++;
|
||||
}
|
||||
else if (item.step) {
|
||||
let step = item.step.map(remap.slice(mapFrom)), map = step && step.getMap();
|
||||
mapFrom--;
|
||||
if (map)
|
||||
remap.appendMap(map, mapFrom);
|
||||
if (step) {
|
||||
let selection = item.selection && item.selection.map(remap.slice(mapFrom));
|
||||
if (selection)
|
||||
events++;
|
||||
let newItem = new Item(map.invert(), step, selection), merged, last = items.length - 1;
|
||||
if (merged = items.length && items[last].merge(newItem))
|
||||
items[last] = merged;
|
||||
else
|
||||
items.push(newItem);
|
||||
}
|
||||
}
|
||||
else if (item.map) {
|
||||
mapFrom--;
|
||||
}
|
||||
}, this.items.length, 0);
|
||||
return new Branch(RopeSequence.from(items.reverse()), events);
|
||||
}
|
||||
}
|
||||
Branch.empty = new Branch(RopeSequence.empty, 0);
|
||||
function cutOffEvents(items, n) {
|
||||
let cutPoint;
|
||||
items.forEach((item, i) => {
|
||||
if (item.selection && (n-- == 0)) {
|
||||
cutPoint = i;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
return items.slice(cutPoint);
|
||||
}
|
||||
class Item {
|
||||
constructor(
|
||||
// The (forward) step map for this item.
|
||||
map,
|
||||
// The inverted step
|
||||
step,
|
||||
// If this is non-null, this item is the start of a group, and
|
||||
// this selection is the starting selection for the group (the one
|
||||
// that was active before the first step was applied)
|
||||
selection,
|
||||
// If this item is the inverse of a previous mapping on the stack,
|
||||
// this points at the inverse's offset
|
||||
mirrorOffset) {
|
||||
this.map = map;
|
||||
this.step = step;
|
||||
this.selection = selection;
|
||||
this.mirrorOffset = mirrorOffset;
|
||||
}
|
||||
merge(other) {
|
||||
if (this.step && other.step && !other.selection) {
|
||||
let step = other.step.merge(this.step);
|
||||
if (step)
|
||||
return new Item(step.getMap().invert(), step, this.selection);
|
||||
}
|
||||
}
|
||||
}
|
||||
// The value of the state field that tracks undo/redo history for that
|
||||
// state. Will be stored in the plugin state when the history plugin
|
||||
// is active.
|
||||
class HistoryState {
|
||||
constructor(done, undone, prevRanges, prevTime, prevComposition) {
|
||||
this.done = done;
|
||||
this.undone = undone;
|
||||
this.prevRanges = prevRanges;
|
||||
this.prevTime = prevTime;
|
||||
this.prevComposition = prevComposition;
|
||||
}
|
||||
}
|
||||
const DEPTH_OVERFLOW = 20;
|
||||
// Record a transformation in undo history.
|
||||
function applyTransaction(history, state, tr, options) {
|
||||
let historyTr = tr.getMeta(historyKey), rebased;
|
||||
if (historyTr)
|
||||
return historyTr.historyState;
|
||||
if (tr.getMeta(closeHistoryKey))
|
||||
history = new HistoryState(history.done, history.undone, null, 0, -1);
|
||||
let appended = tr.getMeta("appendedTransaction");
|
||||
if (tr.steps.length == 0) {
|
||||
return history;
|
||||
}
|
||||
else if (appended && appended.getMeta(historyKey)) {
|
||||
if (appended.getMeta(historyKey).redo)
|
||||
return new HistoryState(history.done.addTransform(tr, undefined, options, mustPreserveItems(state)), history.undone, rangesFor(tr.mapping.maps[tr.steps.length - 1]), history.prevTime, history.prevComposition);
|
||||
else
|
||||
return new HistoryState(history.done, history.undone.addTransform(tr, undefined, options, mustPreserveItems(state)), null, history.prevTime, history.prevComposition);
|
||||
}
|
||||
else if (tr.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) {
|
||||
// Group transforms that occur in quick succession into one event.
|
||||
let composition = tr.getMeta("composition");
|
||||
let newGroup = history.prevTime == 0 ||
|
||||
(!appended && history.prevComposition != composition &&
|
||||
(history.prevTime < (tr.time || 0) - options.newGroupDelay || !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() : undefined, options, mustPreserveItems(state)), Branch.empty, prevRanges, tr.time, composition == null ? history.prevComposition : composition);
|
||||
}
|
||||
else if (rebased = tr.getMeta("rebased")) {
|
||||
// Used by the collab module to tell the history that some of its
|
||||
// content has been rebased.
|
||||
return new HistoryState(history.done.rebased(tr, rebased), history.undone.rebased(tr, rebased), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
||||
}
|
||||
else {
|
||||
return new HistoryState(history.done.addMaps(tr.mapping.maps), history.undone.addMaps(tr.mapping.maps), mapRanges(history.prevRanges, tr.mapping), history.prevTime, history.prevComposition);
|
||||
}
|
||||
}
|
||||
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;
|
||||
});
|
||||
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;
|
||||
}
|
||||
// Apply the latest event from one branch to the document and shift the event
|
||||
// onto the other branch.
|
||||
function histTransaction(history, state, redo) {
|
||||
let preserveItems = mustPreserveItems(state);
|
||||
let histOptions = historyKey.get(state).spec.config;
|
||||
let pop = (redo ? history.undone : history.done).popEvent(state, preserveItems);
|
||||
if (!pop)
|
||||
return null;
|
||||
let selection = pop.selection.resolve(pop.transform.doc);
|
||||
let added = (redo ? history.done : history.undone).addTransform(pop.transform, state.selection.getBookmark(), histOptions, preserveItems);
|
||||
let newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0, -1);
|
||||
return pop.transform.setSelection(selection).setMeta(historyKey, { redo, historyState: newHist });
|
||||
}
|
||||
let cachedPreserveItems = false, cachedPreserveItemsPlugins = null;
|
||||
// Check whether any plugin in the given state has a
|
||||
// `historyPreserveItems` property in its spec, in which case we must
|
||||
// preserve steps exactly as they came in, so that they can be
|
||||
// rebased.
|
||||
function mustPreserveItems(state) {
|
||||
let plugins = state.plugins;
|
||||
if (cachedPreserveItemsPlugins != plugins) {
|
||||
cachedPreserveItems = false;
|
||||
cachedPreserveItemsPlugins = plugins;
|
||||
for (let i = 0; i < plugins.length; i++)
|
||||
if (plugins[i].spec.historyPreserveItems) {
|
||||
cachedPreserveItems = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return cachedPreserveItems;
|
||||
}
|
||||
/**
|
||||
Set a flag on the given transaction that will prevent further steps
|
||||
from being appended to an existing history event (so that they
|
||||
require a separate undo command to undo).
|
||||
*/
|
||||
function closeHistory(tr) {
|
||||
return tr.setMeta(closeHistoryKey, true);
|
||||
}
|
||||
const historyKey = new PluginKey("history");
|
||||
const closeHistoryKey = new PluginKey("closeHistory");
|
||||
/**
|
||||
Returns a plugin that enables the undo history for an editor. The
|
||||
plugin will track undo and redo stacks, which can be used with the
|
||||
[`undo`](https://prosemirror.net/docs/ref/#history.undo) and [`redo`](https://prosemirror.net/docs/ref/#history.redo) commands.
|
||||
|
||||
You can set an `"addToHistory"` [metadata
|
||||
property](https://prosemirror.net/docs/ref/#state.Transaction.setMeta) of `false` on a transaction
|
||||
to prevent it from being rolled back by undo.
|
||||
*/
|
||||
function history(config = {}) {
|
||||
config = { depth: config.depth || 100,
|
||||
newGroupDelay: config.newGroupDelay || 500 };
|
||||
return new Plugin({
|
||||
key: historyKey,
|
||||
state: {
|
||||
init() {
|
||||
return new HistoryState(Branch.empty, Branch.empty, null, 0, -1);
|
||||
},
|
||||
apply(tr, hist, state) {
|
||||
return applyTransaction(hist, state, tr, config);
|
||||
}
|
||||
},
|
||||
config,
|
||||
props: {
|
||||
handleDOMEvents: {
|
||||
beforeinput(view, e) {
|
||||
let inputType = e.inputType;
|
||||
let command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null;
|
||||
if (!command)
|
||||
return false;
|
||||
e.preventDefault();
|
||||
return command(view.state, view.dispatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
function buildCommand(redo, scroll) {
|
||||
return (state, dispatch) => {
|
||||
let hist = historyKey.getState(state);
|
||||
if (!hist || (redo ? hist.undone : hist.done).eventCount == 0)
|
||||
return false;
|
||||
if (dispatch) {
|
||||
let tr = histTransaction(hist, state, redo);
|
||||
if (tr)
|
||||
dispatch(scroll ? tr.scrollIntoView() : tr);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
}
|
||||
/**
|
||||
A command function that undoes the last change, if any.
|
||||
*/
|
||||
const undo = buildCommand(false, true);
|
||||
/**
|
||||
A command function that redoes the last undone change, if any.
|
||||
*/
|
||||
const redo = buildCommand(true, true);
|
||||
/**
|
||||
A command function that undoes the last change. Don't scroll the
|
||||
selection into view.
|
||||
*/
|
||||
const undoNoScroll = buildCommand(false, false);
|
||||
/**
|
||||
A command function that redoes the last undone change. Don't
|
||||
scroll the selection into view.
|
||||
*/
|
||||
const redoNoScroll = buildCommand(true, false);
|
||||
/**
|
||||
The amount of undoable events available in a given state.
|
||||
*/
|
||||
function undoDepth(state) {
|
||||
let hist = historyKey.getState(state);
|
||||
return hist ? hist.done.eventCount : 0;
|
||||
}
|
||||
/**
|
||||
The amount of redoable events available in a given editor state.
|
||||
*/
|
||||
function redoDepth(state) {
|
||||
let hist = historyKey.getState(state);
|
||||
return hist ? hist.undone.eventCount : 0;
|
||||
}
|
||||
|
||||
export { closeHistory, history, redo, redoDepth, redoNoScroll, undo, undoDepth, undoNoScroll };
|
||||
36
resources/app/node_modules/prosemirror-history/package.json
generated
vendored
Normal file
36
resources/app/node_modules/prosemirror-history/package.json
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "prosemirror-history",
|
||||
"version": "1.4.0",
|
||||
"description": "Undo history for ProseMirror",
|
||||
"type": "module",
|
||||
"main": "dist/index.cjs",
|
||||
"module": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.cjs"
|
||||
},
|
||||
"sideEffects": false,
|
||||
"license": "MIT",
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Marijn Haverbeke",
|
||||
"email": "marijn@haverbeke.berlin",
|
||||
"web": "http://marijnhaverbeke.nl"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/prosemirror/prosemirror-history.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.2.2",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
"prosemirror-view": "^1.31.0",
|
||||
"rope-sequence": "^1.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@prosemirror/buildhelper": "^0.1.5",
|
||||
"prosemirror-test-builder": "^1.0.0"
|
||||
}
|
||||
}
|
||||
21
resources/app/node_modules/prosemirror-history/src/README.md
generated
vendored
Normal file
21
resources/app/node_modules/prosemirror-history/src/README.md
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
An implementation of an undo/redo history for ProseMirror. This
|
||||
history is _selective_, meaning it does not just roll back to a
|
||||
previous state but can undo some changes while keeping other, later
|
||||
changes intact. (This is necessary for collaborative editing, and
|
||||
comes up in other situations as well.)
|
||||
|
||||
@history
|
||||
|
||||
@undo
|
||||
|
||||
@redo
|
||||
|
||||
@undoNoScroll
|
||||
|
||||
@redoNoScroll
|
||||
|
||||
@undoDepth
|
||||
|
||||
@redoDepth
|
||||
|
||||
@closeHistory
|
||||
458
resources/app/node_modules/prosemirror-history/src/history.ts
generated
vendored
Normal file
458
resources/app/node_modules/prosemirror-history/src/history.ts
generated
vendored
Normal file
@@ -0,0 +1,458 @@
|
||||
import RopeSequence from "rope-sequence"
|
||||
import {Mapping, Step, StepMap, Transform} from "prosemirror-transform"
|
||||
import {Plugin, Command, PluginKey, EditorState, Transaction, SelectionBookmark} from "prosemirror-state"
|
||||
|
||||
// ProseMirror's history isn't simply a way to roll back to a previous
|
||||
// state, because ProseMirror supports applying changes without adding
|
||||
// them to the history (for example during collaboration).
|
||||
//
|
||||
// To this end, each 'Branch' (one for the undo history and one for
|
||||
// the redo history) keeps an array of 'Items', which can optionally
|
||||
// hold a step (an actual undoable change), and always hold a position
|
||||
// map (which is needed to move changes below them to apply to the
|
||||
// current document).
|
||||
//
|
||||
// An item that has both a step and a selection bookmark is the start
|
||||
// of an 'event' — a group of changes that will be undone or redone at
|
||||
// once. (It stores only the bookmark, since that way we don't have to
|
||||
// provide a document until the selection is actually applied, which
|
||||
// is useful when compressing.)
|
||||
|
||||
// Used to schedule history compression
|
||||
const max_empty_items = 500
|
||||
|
||||
class Branch {
|
||||
constructor(readonly items: RopeSequence<Item>, readonly eventCount: number) {}
|
||||
|
||||
// Pop the latest event off the branch's history and apply it
|
||||
// to a document transform.
|
||||
popEvent(state: EditorState, preserveItems: boolean) {
|
||||
if (this.eventCount == 0) return null
|
||||
|
||||
let end = this.items.length
|
||||
for (;; end--) {
|
||||
let next = this.items.get(end - 1)
|
||||
if (next.selection) { --end; break }
|
||||
}
|
||||
|
||||
let remap: Mapping | undefined, mapFrom: number | undefined
|
||||
if (preserveItems) {
|
||||
remap = this.remapping(end, this.items.length)
|
||||
mapFrom = remap.maps.length
|
||||
}
|
||||
let transform = state.tr
|
||||
let selection: SelectionBookmark | undefined, remaining: Branch | undefined
|
||||
let addAfter: Item[] = [], addBefore: Item[] = []
|
||||
|
||||
this.items.forEach((item, i) => {
|
||||
if (!item.step) {
|
||||
if (!remap) {
|
||||
remap = this.remapping(end, i + 1)
|
||||
mapFrom = remap.maps.length
|
||||
}
|
||||
mapFrom!--
|
||||
addBefore.push(item)
|
||||
return
|
||||
}
|
||||
|
||||
if (remap) {
|
||||
addBefore.push(new Item(item.map))
|
||||
let step = item.step.map(remap.slice(mapFrom)), map
|
||||
|
||||
if (step && transform.maybeStep(step).doc) {
|
||||
map = transform.mapping.maps[transform.mapping.maps.length - 1]
|
||||
addAfter.push(new Item(map, undefined, undefined, addAfter.length + addBefore.length))
|
||||
}
|
||||
mapFrom!--
|
||||
if (map) remap.appendMap(map, mapFrom)
|
||||
} else {
|
||||
transform.maybeStep(item.step)
|
||||
}
|
||||
|
||||
if (item.selection) {
|
||||
selection = remap ? item.selection.map(remap.slice(mapFrom)) : item.selection
|
||||
remaining = new Branch(this.items.slice(0, end).append(addBefore.reverse().concat(addAfter)), this.eventCount - 1)
|
||||
return false
|
||||
}
|
||||
}, this.items.length, 0)
|
||||
|
||||
return {remaining: remaining!, transform, selection: selection!}
|
||||
}
|
||||
|
||||
// Create a new branch with the given transform added.
|
||||
addTransform(transform: Transform, selection: SelectionBookmark | undefined,
|
||||
histOptions: Required<HistoryOptions>, preserveItems: boolean) {
|
||||
let newItems = [], eventCount = this.eventCount
|
||||
let oldItems = this.items, lastItem = !preserveItems && oldItems.length ? oldItems.get(oldItems.length - 1) : null
|
||||
|
||||
for (let i = 0; i < transform.steps.length; i++) {
|
||||
let step = transform.steps[i].invert(transform.docs[i])
|
||||
let item = new Item(transform.mapping.maps[i], step, selection), merged
|
||||
if (merged = lastItem && lastItem.merge(item)) {
|
||||
item = merged
|
||||
if (i) newItems.pop()
|
||||
else oldItems = oldItems.slice(0, oldItems.length - 1)
|
||||
}
|
||||
newItems.push(item)
|
||||
if (selection) {
|
||||
eventCount++
|
||||
selection = undefined
|
||||
}
|
||||
if (!preserveItems) lastItem = item
|
||||
}
|
||||
let overflow = eventCount - histOptions.depth
|
||||
if (overflow > DEPTH_OVERFLOW) {
|
||||
oldItems = cutOffEvents(oldItems, overflow)
|
||||
eventCount -= overflow
|
||||
}
|
||||
return new Branch(oldItems.append(newItems), eventCount)
|
||||
}
|
||||
|
||||
remapping(from: number, to: number): Mapping {
|
||||
let maps = new Mapping
|
||||
this.items.forEach((item, i) => {
|
||||
let mirrorPos = item.mirrorOffset != null && i - item.mirrorOffset >= from
|
||||
? maps.maps.length - item.mirrorOffset : undefined
|
||||
maps.appendMap(item.map, mirrorPos)
|
||||
}, from, to)
|
||||
return maps
|
||||
}
|
||||
|
||||
addMaps(array: readonly StepMap[]) {
|
||||
if (this.eventCount == 0) return this
|
||||
return new Branch(this.items.append(array.map(map => new Item(map))), this.eventCount)
|
||||
}
|
||||
|
||||
// When the collab module receives remote changes, the history has
|
||||
// to know about those, so that it can adjust the steps that were
|
||||
// rebased on top of the remote changes, and include the position
|
||||
// maps for the remote changes in its array of items.
|
||||
rebased(rebasedTransform: Transform, rebasedCount: number) {
|
||||
if (!this.eventCount) return this
|
||||
|
||||
let rebasedItems: Item[] = [], start = Math.max(0, this.items.length - rebasedCount)
|
||||
|
||||
let mapping = rebasedTransform.mapping
|
||||
let newUntil = rebasedTransform.steps.length
|
||||
let eventCount = this.eventCount
|
||||
this.items.forEach(item => { if (item.selection) eventCount-- }, start)
|
||||
|
||||
let iRebased = rebasedCount
|
||||
this.items.forEach(item => {
|
||||
let pos = mapping.getMirror(--iRebased)
|
||||
if (pos == null) return
|
||||
newUntil = Math.min(newUntil, pos)
|
||||
let map = mapping.maps[pos]
|
||||
if (item.step) {
|
||||
let step = rebasedTransform.steps[pos].invert(rebasedTransform.docs[pos])
|
||||
let selection = item.selection && item.selection.map(mapping.slice(iRebased + 1, pos))
|
||||
if (selection) eventCount++
|
||||
rebasedItems.push(new Item(map, step, selection))
|
||||
} else {
|
||||
rebasedItems.push(new Item(map))
|
||||
}
|
||||
}, start)
|
||||
|
||||
let newMaps = []
|
||||
for (let i = rebasedCount; i < newUntil; i++)
|
||||
newMaps.push(new Item(mapping.maps[i]))
|
||||
let items = this.items.slice(0, start).append(newMaps).append(rebasedItems)
|
||||
let branch = new Branch(items, eventCount)
|
||||
|
||||
if (branch.emptyItemCount() > max_empty_items)
|
||||
branch = branch.compress(this.items.length - rebasedItems.length)
|
||||
return branch
|
||||
}
|
||||
|
||||
emptyItemCount() {
|
||||
let count = 0
|
||||
this.items.forEach(item => { if (!item.step) count++ })
|
||||
return count
|
||||
}
|
||||
|
||||
// Compressing a branch means rewriting it to push the air (map-only
|
||||
// items) out. During collaboration, these naturally accumulate
|
||||
// because each remote change adds one. The `upto` argument is used
|
||||
// to ensure that only the items below a given level are compressed,
|
||||
// because `rebased` relies on a clean, untouched set of items in
|
||||
// order to associate old items with rebased steps.
|
||||
compress(upto = this.items.length) {
|
||||
let remap = this.remapping(0, upto), mapFrom = remap.maps.length
|
||||
let items: Item[] = [], events = 0
|
||||
this.items.forEach((item, i) => {
|
||||
if (i >= upto) {
|
||||
items.push(item)
|
||||
if (item.selection) events++
|
||||
} else if (item.step) {
|
||||
let step = item.step.map(remap.slice(mapFrom)), map = step && step.getMap()
|
||||
mapFrom--
|
||||
if (map) remap.appendMap(map, mapFrom)
|
||||
if (step) {
|
||||
let selection = item.selection && item.selection.map(remap.slice(mapFrom))
|
||||
if (selection) events++
|
||||
let newItem = new Item(map!.invert(), step, selection), merged, last = items.length - 1
|
||||
if (merged = items.length && items[last].merge(newItem))
|
||||
items[last] = merged
|
||||
else
|
||||
items.push(newItem)
|
||||
}
|
||||
} else if (item.map) {
|
||||
mapFrom--
|
||||
}
|
||||
}, this.items.length, 0)
|
||||
return new Branch(RopeSequence.from(items.reverse()), events)
|
||||
}
|
||||
|
||||
static empty = new Branch(RopeSequence.empty, 0)
|
||||
}
|
||||
|
||||
function cutOffEvents(items: RopeSequence<Item>, n: number) {
|
||||
let cutPoint: number | undefined
|
||||
items.forEach((item, i) => {
|
||||
if (item.selection && (n-- == 0)) {
|
||||
cutPoint = i
|
||||
return false
|
||||
}
|
||||
})
|
||||
return items.slice(cutPoint!)
|
||||
}
|
||||
|
||||
class Item {
|
||||
constructor(
|
||||
// The (forward) step map for this item.
|
||||
readonly map: StepMap,
|
||||
// The inverted step
|
||||
readonly step?: Step,
|
||||
// If this is non-null, this item is the start of a group, and
|
||||
// this selection is the starting selection for the group (the one
|
||||
// that was active before the first step was applied)
|
||||
readonly selection?: SelectionBookmark,
|
||||
// If this item is the inverse of a previous mapping on the stack,
|
||||
// this points at the inverse's offset
|
||||
readonly mirrorOffset?: number
|
||||
) {}
|
||||
|
||||
merge(other: Item) {
|
||||
if (this.step && other.step && !other.selection) {
|
||||
let step = other.step.merge(this.step)
|
||||
if (step) return new Item(step.getMap().invert(), step, this.selection)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The value of the state field that tracks undo/redo history for that
|
||||
// state. Will be stored in the plugin state when the history plugin
|
||||
// is active.
|
||||
class HistoryState {
|
||||
constructor(
|
||||
readonly done: Branch,
|
||||
readonly undone: Branch,
|
||||
readonly prevRanges: readonly number[] | null,
|
||||
readonly prevTime: number,
|
||||
readonly prevComposition: number
|
||||
) {}
|
||||
}
|
||||
|
||||
const DEPTH_OVERFLOW = 20
|
||||
|
||||
// Record a transformation in undo history.
|
||||
function applyTransaction(history: HistoryState, state: EditorState, tr: Transaction, options: Required<HistoryOptions>) {
|
||||
let historyTr = tr.getMeta(historyKey), rebased
|
||||
if (historyTr) return historyTr.historyState
|
||||
|
||||
if (tr.getMeta(closeHistoryKey)) history = new HistoryState(history.done, history.undone, null, 0, -1)
|
||||
|
||||
let appended = tr.getMeta("appendedTransaction")
|
||||
|
||||
if (tr.steps.length == 0) {
|
||||
return history
|
||||
} else if (appended && appended.getMeta(historyKey)) {
|
||||
if (appended.getMeta(historyKey).redo)
|
||||
return new HistoryState(history.done.addTransform(tr, undefined, options, mustPreserveItems(state)),
|
||||
history.undone, rangesFor(tr.mapping.maps[tr.steps.length - 1]),
|
||||
history.prevTime, history.prevComposition)
|
||||
else
|
||||
return new HistoryState(history.done, history.undone.addTransform(tr, undefined, options, mustPreserveItems(state)),
|
||||
null, history.prevTime, history.prevComposition)
|
||||
} else if (tr.getMeta("addToHistory") !== false && !(appended && appended.getMeta("addToHistory") === false)) {
|
||||
// Group transforms that occur in quick succession into one event.
|
||||
let composition = tr.getMeta("composition")
|
||||
let newGroup = history.prevTime == 0 ||
|
||||
(!appended && history.prevComposition != composition &&
|
||||
(history.prevTime < (tr.time || 0) - options.newGroupDelay || !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() : undefined,
|
||||
options, mustPreserveItems(state)),
|
||||
Branch.empty, prevRanges, tr.time, composition == null ? history.prevComposition : composition)
|
||||
} else if (rebased = tr.getMeta("rebased")) {
|
||||
// Used by the collab module to tell the history that some of its
|
||||
// content has been rebased.
|
||||
return new HistoryState(history.done.rebased(tr, rebased),
|
||||
history.undone.rebased(tr, rebased),
|
||||
mapRanges(history.prevRanges!, tr.mapping), history.prevTime, history.prevComposition)
|
||||
} else {
|
||||
return new HistoryState(history.done.addMaps(tr.mapping.maps),
|
||||
history.undone.addMaps(tr.mapping.maps),
|
||||
mapRanges(history.prevRanges!, tr.mapping), history.prevTime, history.prevComposition)
|
||||
}
|
||||
}
|
||||
|
||||
function isAdjacentTo(transform: Transform, prevRanges: readonly number[]) {
|
||||
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
|
||||
})
|
||||
return adjacent
|
||||
}
|
||||
|
||||
function rangesFor(map: StepMap) {
|
||||
let result: number[] = []
|
||||
map.forEach((_from, _to, from, to) => result.push(from, to))
|
||||
return result
|
||||
}
|
||||
|
||||
function mapRanges(ranges: readonly number[], mapping: 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
|
||||
}
|
||||
|
||||
// Apply the latest event from one branch to the document and shift the event
|
||||
// onto the other branch.
|
||||
function histTransaction(history: HistoryState, state: EditorState, redo: boolean): Transaction | null {
|
||||
let preserveItems = mustPreserveItems(state)
|
||||
let histOptions = (historyKey.get(state)!.spec as any).config as Required<HistoryOptions>
|
||||
let pop = (redo ? history.undone : history.done).popEvent(state, preserveItems)
|
||||
if (!pop) return null
|
||||
|
||||
let selection = pop.selection!.resolve(pop.transform.doc)
|
||||
let added = (redo ? history.done : history.undone).addTransform(pop.transform, state.selection.getBookmark(),
|
||||
histOptions, preserveItems)
|
||||
|
||||
let newHist = new HistoryState(redo ? added : pop.remaining, redo ? pop.remaining : added, null, 0, -1)
|
||||
return pop.transform.setSelection(selection).setMeta(historyKey, {redo, historyState: newHist})
|
||||
}
|
||||
|
||||
let cachedPreserveItems = false, cachedPreserveItemsPlugins: readonly Plugin[] | null = null
|
||||
// Check whether any plugin in the given state has a
|
||||
// `historyPreserveItems` property in its spec, in which case we must
|
||||
// preserve steps exactly as they came in, so that they can be
|
||||
// rebased.
|
||||
function mustPreserveItems(state: EditorState) {
|
||||
let plugins = state.plugins
|
||||
if (cachedPreserveItemsPlugins != plugins) {
|
||||
cachedPreserveItems = false
|
||||
cachedPreserveItemsPlugins = plugins
|
||||
for (let i = 0; i < plugins.length; i++) if ((plugins[i].spec as any).historyPreserveItems) {
|
||||
cachedPreserveItems = true
|
||||
break
|
||||
}
|
||||
}
|
||||
return cachedPreserveItems
|
||||
}
|
||||
|
||||
/// Set a flag on the given transaction that will prevent further steps
|
||||
/// from being appended to an existing history event (so that they
|
||||
/// require a separate undo command to undo).
|
||||
export function closeHistory(tr: Transaction) {
|
||||
return tr.setMeta(closeHistoryKey, true)
|
||||
}
|
||||
|
||||
const historyKey = new PluginKey("history")
|
||||
const closeHistoryKey = new PluginKey("closeHistory")
|
||||
|
||||
interface HistoryOptions {
|
||||
/// The amount of history events that are collected before the
|
||||
/// oldest events are discarded. Defaults to 100.
|
||||
depth?: number
|
||||
|
||||
/// The delay between changes after which a new group should be
|
||||
/// started. Defaults to 500 (milliseconds). Note that when changes
|
||||
/// aren't adjacent, a new group is always started.
|
||||
newGroupDelay?: number
|
||||
}
|
||||
|
||||
/// Returns a plugin that enables the undo history for an editor. The
|
||||
/// plugin will track undo and redo stacks, which can be used with the
|
||||
/// [`undo`](#history.undo) and [`redo`](#history.redo) commands.
|
||||
///
|
||||
/// You can set an `"addToHistory"` [metadata
|
||||
/// property](#state.Transaction.setMeta) of `false` on a transaction
|
||||
/// to prevent it from being rolled back by undo.
|
||||
export function history(config: HistoryOptions = {}): Plugin {
|
||||
config = {depth: config.depth || 100,
|
||||
newGroupDelay: config.newGroupDelay || 500}
|
||||
|
||||
return new Plugin({
|
||||
key: historyKey,
|
||||
|
||||
state: {
|
||||
init() {
|
||||
return new HistoryState(Branch.empty, Branch.empty, null, 0, -1)
|
||||
},
|
||||
apply(tr, hist, state) {
|
||||
return applyTransaction(hist, state, tr, config as Required<HistoryOptions>)
|
||||
}
|
||||
},
|
||||
|
||||
config,
|
||||
|
||||
props: {
|
||||
handleDOMEvents: {
|
||||
beforeinput(view, e: Event) {
|
||||
let inputType = (e as InputEvent).inputType
|
||||
let command = inputType == "historyUndo" ? undo : inputType == "historyRedo" ? redo : null
|
||||
if (!command) return false
|
||||
e.preventDefault()
|
||||
return command(view.state, view.dispatch)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function buildCommand(redo: boolean, scroll: boolean): Command {
|
||||
return (state, dispatch) => {
|
||||
let hist = historyKey.getState(state)
|
||||
if (!hist || (redo ? hist.undone : hist.done).eventCount == 0) return false
|
||||
if (dispatch) {
|
||||
let tr = histTransaction(hist, state, redo)
|
||||
if (tr) dispatch(scroll ? tr.scrollIntoView() : tr)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
/// A command function that undoes the last change, if any.
|
||||
export const undo = buildCommand(false, true)
|
||||
|
||||
/// A command function that redoes the last undone change, if any.
|
||||
export const redo = buildCommand(true, true)
|
||||
|
||||
/// A command function that undoes the last change. Don't scroll the
|
||||
/// selection into view.
|
||||
export const undoNoScroll = buildCommand(false, false)
|
||||
|
||||
/// A command function that redoes the last undone change. Don't
|
||||
/// scroll the selection into view.
|
||||
export const redoNoScroll = buildCommand(true, false)
|
||||
|
||||
/// The amount of undoable events available in a given state.
|
||||
export function undoDepth(state: EditorState) {
|
||||
let hist = historyKey.getState(state)
|
||||
return hist ? hist.done.eventCount : 0
|
||||
}
|
||||
|
||||
/// The amount of redoable events available in a given editor state.
|
||||
export function redoDepth(state: EditorState) {
|
||||
let hist = historyKey.getState(state)
|
||||
return hist ? hist.undone.eventCount : 0
|
||||
}
|
||||
Reference in New Issue
Block a user