UNPKG

matrix-react-sdk

Version:
143 lines (137 loc) 17.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.MAX_STEP_LENGTH = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); /* Copyright 2024 New Vector Ltd. Copyright 2019 The Matrix.org Foundation C.I.C. SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only Please see LICENSE files in the repository root for full details. */ const MAX_STEP_LENGTH = exports.MAX_STEP_LENGTH = 10; class HistoryManager { constructor() { (0, _defineProperty2.default)(this, "stack", []); (0, _defineProperty2.default)(this, "newlyTypedCharCount", 0); (0, _defineProperty2.default)(this, "currentIndex", -1); (0, _defineProperty2.default)(this, "changedSinceLastPush", false); (0, _defineProperty2.default)(this, "lastCaret", void 0); (0, _defineProperty2.default)(this, "nonWordBoundarySinceLastPush", false); (0, _defineProperty2.default)(this, "addedSinceLastPush", false); (0, _defineProperty2.default)(this, "removedSinceLastPush", false); } clear() { this.stack = []; this.newlyTypedCharCount = 0; this.currentIndex = -1; this.changedSinceLastPush = false; this.lastCaret = undefined; this.nonWordBoundarySinceLastPush = false; this.addedSinceLastPush = false; this.removedSinceLastPush = false; } shouldPush(inputType, diff) { // right now we can only push a step after // the input has been applied to the model, // so we can't push the state before something happened. // not ideal but changing this would be harder to fit cleanly into // the editor model. const isNonBulkInput = inputType === "insertText" || inputType === "deleteContentForward" || inputType === "deleteContentBackward"; if (diff && isNonBulkInput) { if (diff.added) { this.addedSinceLastPush = true; } if (diff.removed) { this.removedSinceLastPush = true; } // as long as you've only been adding or removing since the last push if (this.addedSinceLastPush !== this.removedSinceLastPush) { // add steps by word boundary, up to MAX_STEP_LENGTH characters const str = diff.added ? diff.added : diff.removed; const isWordBoundary = str === " " || str === "\t" || str === "\n"; if (this.nonWordBoundarySinceLastPush && isWordBoundary) { return true; } if (!isWordBoundary) { this.nonWordBoundarySinceLastPush = true; } this.newlyTypedCharCount += str.length; return this.newlyTypedCharCount > MAX_STEP_LENGTH; } else { // if starting to remove while adding before, or the opposite, push return true; } } else { // bulk input (paste, ...) should be pushed every time return true; } } pushState(model, caret) { // remove all steps after current step while (this.currentIndex < this.stack.length - 1) { this.stack.pop(); } const parts = model.serializeParts(); this.stack.push({ parts, caret }); this.currentIndex = this.stack.length - 1; this.lastCaret = undefined; this.changedSinceLastPush = false; this.newlyTypedCharCount = 0; this.nonWordBoundarySinceLastPush = false; this.addedSinceLastPush = false; this.removedSinceLastPush = false; } // needs to persist parts and caret position tryPush(model, caret, inputType, diff) { // ignore state restoration echos. // these respect the inputType values of the input event, // but are actually passed in from MessageEditor calling model.reset() // in the keydown event handler. if (inputType === "historyUndo" || inputType === "historyRedo") { return false; } const shouldPush = this.shouldPush(inputType, diff); if (shouldPush) { this.pushState(model, caret); } else { this.lastCaret = caret; this.changedSinceLastPush = true; } return shouldPush; } ensureLastChangesPushed(model) { if (this.changedSinceLastPush && this.lastCaret) { this.pushState(model, this.lastCaret); } } canUndo() { return this.currentIndex >= 1 || this.changedSinceLastPush; } canRedo() { return this.currentIndex < this.stack.length - 1; } // returns state that should be applied to model undo(model) { if (this.canUndo()) { this.ensureLastChangesPushed(model); this.currentIndex -= 1; return this.stack[this.currentIndex]; } } // returns state that should be applied to model redo() { if (this.canRedo()) { this.changedSinceLastPush = false; this.currentIndex += 1; return this.stack[this.currentIndex]; } } } exports.default = HistoryManager; //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJNQVhfU1RFUF9MRU5HVEgiLCJleHBvcnRzIiwiSGlzdG9yeU1hbmFnZXIiLCJjb25zdHJ1Y3RvciIsIl9kZWZpbmVQcm9wZXJ0eTIiLCJkZWZhdWx0IiwiY2xlYXIiLCJzdGFjayIsIm5ld2x5VHlwZWRDaGFyQ291bnQiLCJjdXJyZW50SW5kZXgiLCJjaGFuZ2VkU2luY2VMYXN0UHVzaCIsImxhc3RDYXJldCIsInVuZGVmaW5lZCIsIm5vbldvcmRCb3VuZGFyeVNpbmNlTGFzdFB1c2giLCJhZGRlZFNpbmNlTGFzdFB1c2giLCJyZW1vdmVkU2luY2VMYXN0UHVzaCIsInNob3VsZFB1c2giLCJpbnB1dFR5cGUiLCJkaWZmIiwiaXNOb25CdWxrSW5wdXQiLCJhZGRlZCIsInJlbW92ZWQiLCJzdHIiLCJpc1dvcmRCb3VuZGFyeSIsImxlbmd0aCIsInB1c2hTdGF0ZSIsIm1vZGVsIiwiY2FyZXQiLCJwb3AiLCJwYXJ0cyIsInNlcmlhbGl6ZVBhcnRzIiwicHVzaCIsInRyeVB1c2giLCJlbnN1cmVMYXN0Q2hhbmdlc1B1c2hlZCIsImNhblVuZG8iLCJjYW5SZWRvIiwidW5kbyIsInJlZG8iXSwic291cmNlcyI6WyIuLi8uLi9zcmMvZWRpdG9yL2hpc3RvcnkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLypcbkNvcHlyaWdodCAyMDI0IE5ldyBWZWN0b3IgTHRkLlxuQ29weXJpZ2h0IDIwMTkgVGhlIE1hdHJpeC5vcmcgRm91bmRhdGlvbiBDLkkuQy5cblxuU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFHUEwtMy4wLW9ubHkgT1IgR1BMLTMuMC1vbmx5XG5QbGVhc2Ugc2VlIExJQ0VOU0UgZmlsZXMgaW4gdGhlIHJlcG9zaXRvcnkgcm9vdCBmb3IgZnVsbCBkZXRhaWxzLlxuKi9cblxuaW1wb3J0IEVkaXRvck1vZGVsIGZyb20gXCIuL21vZGVsXCI7XG5pbXBvcnQgeyBJRGlmZiB9IGZyb20gXCIuL2RpZmZcIjtcbmltcG9ydCB7IFNlcmlhbGl6ZWRQYXJ0IH0gZnJvbSBcIi4vcGFydHNcIjtcbmltcG9ydCB7IENhcmV0IH0gZnJvbSBcIi4vY2FyZXRcIjtcblxuZXhwb3J0IGludGVyZmFjZSBJSGlzdG9yeSB7XG4gICAgcGFydHM6IFNlcmlhbGl6ZWRQYXJ0W107XG4gICAgY2FyZXQ/OiBDYXJldDtcbn1cblxuZXhwb3J0IGNvbnN0IE1BWF9TVEVQX0xFTkdUSCA9IDEwO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBIaXN0b3J5TWFuYWdlciB7XG4gICAgcHJpdmF0ZSBzdGFjazogSUhpc3RvcnlbXSA9IFtdO1xuICAgIHByaXZhdGUgbmV3bHlUeXBlZENoYXJDb3VudCA9IDA7XG4gICAgcHJpdmF0ZSBjdXJyZW50SW5kZXggPSAtMTtcbiAgICBwcml2YXRlIGNoYW5nZWRTaW5jZUxhc3RQdXNoID0gZmFsc2U7XG4gICAgcHJpdmF0ZSBsYXN0Q2FyZXQ/OiBDYXJldDtcbiAgICBwcml2YXRlIG5vbldvcmRCb3VuZGFyeVNpbmNlTGFzdFB1c2ggPSBmYWxzZTtcbiAgICBwcml2YXRlIGFkZGVkU2luY2VMYXN0UHVzaCA9IGZhbHNlO1xuICAgIHByaXZhdGUgcmVtb3ZlZFNpbmNlTGFzdFB1c2ggPSBmYWxzZTtcblxuICAgIHB1YmxpYyBjbGVhcigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zdGFjayA9IFtdO1xuICAgICAgICB0aGlzLm5ld2x5VHlwZWRDaGFyQ291bnQgPSAwO1xuICAgICAgICB0aGlzLmN1cnJlbnRJbmRleCA9IC0xO1xuICAgICAgICB0aGlzLmNoYW5nZWRTaW5jZUxhc3RQdXNoID0gZmFsc2U7XG4gICAgICAgIHRoaXMubGFzdENhcmV0ID0gdW5kZWZpbmVkO1xuICAgICAgICB0aGlzLm5vbldvcmRCb3VuZGFyeVNpbmNlTGFzdFB1c2ggPSBmYWxzZTtcbiAgICAgICAgdGhpcy5hZGRlZFNpbmNlTGFzdFB1c2ggPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZW1vdmVkU2luY2VMYXN0UHVzaCA9IGZhbHNlO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2hvdWxkUHVzaChpbnB1dFR5cGU/OiBzdHJpbmcsIGRpZmY/OiBJRGlmZik6IGJvb2xlYW4ge1xuICAgICAgICAvLyByaWdodCBub3cgd2UgY2FuIG9ubHkgcHVzaCBhIHN0ZXAgYWZ0ZXJcbiAgICAgICAgLy8gdGhlIGlucHV0IGhhcyBiZWVuIGFwcGxpZWQgdG8gdGhlIG1vZGVsLFxuICAgICAgICAvLyBzbyB3ZSBjYW4ndCBwdXNoIHRoZSBzdGF0ZSBiZWZvcmUgc29tZXRoaW5nIGhhcHBlbmVkLlxuICAgICAgICAvLyBub3QgaWRlYWwgYnV0IGNoYW5naW5nIHRoaXMgd291bGQgYmUgaGFyZGVyIHRvIGZpdCBjbGVhbmx5IGludG9cbiAgICAgICAgLy8gdGhlIGVkaXRvciBtb2RlbC5cbiAgICAgICAgY29uc3QgaXNOb25CdWxrSW5wdXQgPVxuICAgICAgICAgICAgaW5wdXRUeXBlID09PSBcImluc2VydFRleHRcIiB8fCBpbnB1dFR5cGUgPT09IFwiZGVsZXRlQ29udGVudEZvcndhcmRcIiB8fCBpbnB1dFR5cGUgPT09IFwiZGVsZXRlQ29udGVudEJhY2t3YXJkXCI7XG4gICAgICAgIGlmIChkaWZmICYmIGlzTm9uQnVsa0lucHV0KSB7XG4gICAgICAgICAgICBpZiAoZGlmZi5hZGRlZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkZWRTaW5jZUxhc3RQdXNoID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChkaWZmLnJlbW92ZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlbW92ZWRTaW5jZUxhc3RQdXNoID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIGFzIGxvbmcgYXMgeW91J3ZlIG9ubHkgYmVlbiBhZGRpbmcgb3IgcmVtb3Zpbmcgc2luY2UgdGhlIGxhc3QgcHVzaFxuICAgICAgICAgICAgaWYgKHRoaXMuYWRkZWRTaW5jZUxhc3RQdXNoICE9PSB0aGlzLnJlbW92ZWRTaW5jZUxhc3RQdXNoKSB7XG4gICAgICAgICAgICAgICAgLy8gYWRkIHN0ZXBzIGJ5IHdvcmQgYm91bmRhcnksIHVwIHRvIE1BWF9TVEVQX0xFTkdUSCBjaGFyYWN0ZXJzXG4gICAgICAgICAgICAgICAgY29uc3Qgc3RyID0gZGlmZi5hZGRlZCA/IGRpZmYuYWRkZWQgOiBkaWZmLnJlbW92ZWQhO1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzV29yZEJvdW5kYXJ5ID0gc3RyID09PSBcIiBcIiB8fCBzdHIgPT09IFwiXFx0XCIgfHwgc3RyID09PSBcIlxcblwiO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLm5vbldvcmRCb3VuZGFyeVNpbmNlTGFzdFB1c2ggJiYgaXNXb3JkQm91bmRhcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmICghaXNXb3JkQm91bmRhcnkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5ub25Xb3JkQm91bmRhcnlTaW5jZUxhc3RQdXNoID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdGhpcy5uZXdseVR5cGVkQ2hhckNvdW50ICs9IHN0ci5sZW5ndGg7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubmV3bHlUeXBlZENoYXJDb3VudCA+IE1BWF9TVEVQX0xFTkdUSDtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgLy8gaWYgc3RhcnRpbmcgdG8gcmVtb3ZlIHdoaWxlIGFkZGluZyBiZWZvcmUsIG9yIHRoZSBvcHBvc2l0ZSwgcHVzaFxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gYnVsayBpbnB1dCAocGFzdGUsIC4uLikgc2hvdWxkIGJlIHB1c2hlZCBldmVyeSB0aW1lXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcHVzaFN0YXRlKG1vZGVsOiBFZGl0b3JNb2RlbCwgY2FyZXQ/OiBDYXJldCk6IHZvaWQge1xuICAgICAgICAvLyByZW1vdmUgYWxsIHN0ZXBzIGFmdGVyIGN1cnJlbnQgc3RlcFxuICAgICAgICB3aGlsZSAodGhpcy5jdXJyZW50SW5kZXggPCB0aGlzLnN0YWNrLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIHRoaXMuc3RhY2sucG9wKCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGFydHMgPSBtb2RlbC5zZXJpYWxpemVQYXJ0cygpO1xuICAgICAgICB0aGlzLnN0YWNrLnB1c2goeyBwYXJ0cywgY2FyZXQgfSk7XG4gICAgICAgIHRoaXMuY3VycmVudEluZGV4ID0gdGhpcy5zdGFjay5sZW5ndGggLSAxO1xuICAgICAgICB0aGlzLmxhc3RDYXJldCA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy5jaGFuZ2VkU2luY2VMYXN0UHVzaCA9IGZhbHNlO1xuICAgICAgICB0aGlzLm5ld2x5VHlwZWRDaGFyQ291bnQgPSAwO1xuICAgICAgICB0aGlzLm5vbldvcmRCb3VuZGFyeVNpbmNlTGFzdFB1c2ggPSBmYWxzZTtcbiAgICAgICAgdGhpcy5hZGRlZFNpbmNlTGFzdFB1c2ggPSBmYWxzZTtcbiAgICAgICAgdGhpcy5yZW1vdmVkU2luY2VMYXN0UHVzaCA9IGZhbHNlO1xuICAgIH1cblxuICAgIC8vIG5lZWRzIHRvIHBlcnNpc3QgcGFydHMgYW5kIGNhcmV0IHBvc2l0aW9uXG4gICAgcHVibGljIHRyeVB1c2gobW9kZWw6IEVkaXRvck1vZGVsLCBjYXJldD86IENhcmV0LCBpbnB1dFR5cGU/OiBzdHJpbmcsIGRpZmY/OiBJRGlmZik6IGJvb2xlYW4ge1xuICAgICAgICAvLyBpZ25vcmUgc3RhdGUgcmVzdG9yYXRpb24gZWNob3MuXG4gICAgICAgIC8vIHRoZXNlIHJlc3BlY3QgdGhlIGlucHV0VHlwZSB2YWx1ZXMgb2YgdGhlIGlucHV0IGV2ZW50LFxuICAgICAgICAvLyBidXQgYXJlIGFjdHVhbGx5IHBhc3NlZCBpbiBmcm9tIE1lc3NhZ2VFZGl0b3IgY2FsbGluZyBtb2RlbC5yZXNldCgpXG4gICAgICAgIC8vIGluIHRoZSBrZXlkb3duIGV2ZW50IGhhbmRsZXIuXG4gICAgICAgIGlmIChpbnB1dFR5cGUgPT09IFwiaGlzdG9yeVVuZG9cIiB8fCBpbnB1dFR5cGUgPT09IFwiaGlzdG9yeVJlZG9cIikge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHNob3VsZFB1c2ggPSB0aGlzLnNob3VsZFB1c2goaW5wdXRUeXBlLCBkaWZmKTtcbiAgICAgICAgaWYgKHNob3VsZFB1c2gpIHtcbiAgICAgICAgICAgIHRoaXMucHVzaFN0YXRlKG1vZGVsLCBjYXJldCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmxhc3RDYXJldCA9IGNhcmV0O1xuICAgICAgICAgICAgdGhpcy5jaGFuZ2VkU2luY2VMYXN0UHVzaCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHNob3VsZFB1c2g7XG4gICAgfVxuXG4gICAgcHVibGljIGVuc3VyZUxhc3RDaGFuZ2VzUHVzaGVkKG1vZGVsOiBFZGl0b3JNb2RlbCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jaGFuZ2VkU2luY2VMYXN0UHVzaCAmJiB0aGlzLmxhc3RDYXJldCkge1xuICAgICAgICAgICAgdGhpcy5wdXNoU3RhdGUobW9kZWwsIHRoaXMubGFzdENhcmV0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBjYW5VbmRvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50SW5kZXggPj0gMSB8fCB0aGlzLmNoYW5nZWRTaW5jZUxhc3RQdXNoO1xuICAgIH1cblxuICAgIHB1YmxpYyBjYW5SZWRvKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50SW5kZXggPCB0aGlzLnN0YWNrLmxlbmd0aCAtIDE7XG4gICAgfVxuXG4gICAgLy8gcmV0dXJucyBzdGF0ZSB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIHRvIG1vZGVsXG4gICAgcHVibGljIHVuZG8obW9kZWw6IEVkaXRvck1vZGVsKTogSUhpc3RvcnkgfCB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuY2FuVW5kbygpKSB7XG4gICAgICAgICAgICB0aGlzLmVuc3VyZUxhc3RDaGFuZ2VzUHVzaGVkKG1vZGVsKTtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEluZGV4IC09IDE7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGFja1t0aGlzLmN1cnJlbnRJbmRleF07XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvLyByZXR1cm5zIHN0YXRlIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQgdG8gbW9kZWxcbiAgICBwdWJsaWMgcmVkbygpOiBJSGlzdG9yeSB8IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jYW5SZWRvKCkpIHtcbiAgICAgICAgICAgIHRoaXMuY2hhbmdlZFNpbmNlTGFzdFB1c2ggPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudEluZGV4ICs9IDE7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGFja1t0aGlzLmN1cnJlbnRJbmRleF07XG4gICAgICAgIH1cbiAgICB9XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBWU8sTUFBTUEsZUFBZSxHQUFBQyxPQUFBLENBQUFELGVBQUEsR0FBRyxFQUFFO0FBRWxCLE1BQU1FLGNBQWMsQ0FBQztFQUFBQyxZQUFBO0lBQUEsSUFBQUMsZ0JBQUEsQ0FBQUMsT0FBQSxpQkFDSixFQUFFO0lBQUEsSUFBQUQsZ0JBQUEsQ0FBQUMsT0FBQSwrQkFDQSxDQUFDO0lBQUEsSUFBQUQsZ0JBQUEsQ0FBQUMsT0FBQSx3QkFDUixDQUFDLENBQUM7SUFBQSxJQUFBRCxnQkFBQSxDQUFBQyxPQUFBLGdDQUNNLEtBQUs7SUFBQSxJQUFBRCxnQkFB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