156 lines
5.0 KiB
JavaScript
156 lines
5.0 KiB
JavaScript
'use strict';
|
|
|
|
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, 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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
|
|
var prosemirrorState = require('prosemirror-state');
|
|
|
|
var Rebaseable = _createClass(function Rebaseable(step, inverted, origin) {
|
|
_classCallCheck(this, Rebaseable);
|
|
|
|
this.step = step;
|
|
this.inverted = inverted;
|
|
this.origin = origin;
|
|
});
|
|
|
|
function rebaseSteps(steps, over, transform) {
|
|
for (var i = steps.length - 1; i >= 0; i--) {
|
|
transform.step(steps[i].inverted);
|
|
}
|
|
|
|
for (var _i = 0; _i < over.length; _i++) {
|
|
transform.step(over[_i]);
|
|
}
|
|
|
|
var result = [];
|
|
|
|
for (var _i2 = 0, mapFrom = steps.length; _i2 < steps.length; _i2++) {
|
|
var mapped = steps[_i2].step.map(transform.mapping.slice(mapFrom));
|
|
|
|
mapFrom--;
|
|
|
|
if (mapped && !transform.maybeStep(mapped).failed) {
|
|
transform.mapping.setMirror(mapFrom, transform.steps.length - 1);
|
|
result.push(new Rebaseable(mapped, mapped.invert(transform.docs[transform.docs.length - 1]), steps[_i2].origin));
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
var CollabState = _createClass(function CollabState(version, unconfirmed) {
|
|
_classCallCheck(this, CollabState);
|
|
|
|
this.version = version;
|
|
this.unconfirmed = unconfirmed;
|
|
});
|
|
|
|
function unconfirmedFrom(transform) {
|
|
var result = [];
|
|
|
|
for (var i = 0; i < transform.steps.length; i++) {
|
|
result.push(new Rebaseable(transform.steps[i], transform.steps[i].invert(transform.docs[i]), transform));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
var collabKey = new prosemirrorState.PluginKey("collab");
|
|
|
|
function collab() {
|
|
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
var conf = {
|
|
version: config.version || 0,
|
|
clientID: config.clientID == null ? Math.floor(Math.random() * 0xFFFFFFFF) : config.clientID
|
|
};
|
|
return new prosemirrorState.Plugin({
|
|
key: collabKey,
|
|
state: {
|
|
init: function init() {
|
|
return new CollabState(conf.version, []);
|
|
},
|
|
apply: function apply(tr, collab) {
|
|
var newState = tr.getMeta(collabKey);
|
|
if (newState) return newState;
|
|
if (tr.docChanged) return new CollabState(collab.version, collab.unconfirmed.concat(unconfirmedFrom(tr)));
|
|
return collab;
|
|
}
|
|
},
|
|
config: conf,
|
|
historyPreserveItems: true
|
|
});
|
|
}
|
|
|
|
function receiveTransaction(state, steps, clientIDs) {
|
|
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
|
|
var collabState = collabKey.getState(state);
|
|
var version = collabState.version + steps.length;
|
|
var ourID = collabKey.get(state).spec.config.clientID;
|
|
var ours = 0;
|
|
|
|
while (ours < clientIDs.length && clientIDs[ours] == ourID) {
|
|
++ours;
|
|
}
|
|
|
|
var unconfirmed = collabState.unconfirmed.slice(ours);
|
|
steps = ours ? steps.slice(ours) : steps;
|
|
if (!steps.length) return state.tr.setMeta(collabKey, new CollabState(version, unconfirmed));
|
|
var nUnconfirmed = unconfirmed.length;
|
|
var tr = state.tr;
|
|
|
|
if (nUnconfirmed) {
|
|
unconfirmed = rebaseSteps(unconfirmed, steps, tr);
|
|
} else {
|
|
for (var i = 0; i < steps.length; i++) {
|
|
tr.step(steps[i]);
|
|
}
|
|
|
|
unconfirmed = [];
|
|
}
|
|
|
|
var newCollabState = new CollabState(version, unconfirmed);
|
|
|
|
if (options && options.mapSelectionBackward && state.selection instanceof prosemirrorState.TextSelection) {
|
|
tr.setSelection(prosemirrorState.TextSelection.between(tr.doc.resolve(tr.mapping.map(state.selection.anchor, -1)), tr.doc.resolve(tr.mapping.map(state.selection.head, -1)), -1));
|
|
tr.updated &= ~1;
|
|
}
|
|
|
|
return tr.setMeta("rebased", nUnconfirmed).setMeta("addToHistory", false).setMeta(collabKey, newCollabState);
|
|
}
|
|
|
|
function sendableSteps(state) {
|
|
var collabState = collabKey.getState(state);
|
|
if (collabState.unconfirmed.length == 0) return null;
|
|
return {
|
|
version: collabState.version,
|
|
steps: collabState.unconfirmed.map(function (s) {
|
|
return s.step;
|
|
}),
|
|
clientID: collabKey.get(state).spec.config.clientID,
|
|
|
|
get origins() {
|
|
return this._origins || (this._origins = collabState.unconfirmed.map(function (s) {
|
|
return s.origin;
|
|
}));
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
function getVersion(state) {
|
|
return collabKey.getState(state).version;
|
|
}
|
|
|
|
exports.collab = collab;
|
|
exports.getVersion = getVersion;
|
|
exports.rebaseSteps = rebaseSteps;
|
|
exports.receiveTransaction = receiveTransaction;
|
|
exports.sendableSteps = sendableSteps;
|