/**
 * Wed-specific undo functionality.
 * @author Louis-Dominique Dubeau
 * @license MPL 2.0
 * @copyright Mangalam Research Center for Buddhist Languages
 */
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
define(["require", "exports", "./undo"], function (require, exports, undo) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    undo = __importStar(undo);
    /**
     * This class extends the vanilla UndoGroup class by recording the
     * location of the caret when the group is created and when group
     * recording ends. This allows restoring the caret to sensible
     * positions before and after undoing or redoing.
     */
    class UndoGroup extends undo.UndoGroup {
        /**
         * @param desc The description of this group.
         *
         * @param editor The editor for which this undo group is created.
         */
        constructor(desc, editor) {
            super(desc);
            this.editor = editor;
            this.caretAsPathBefore = this.getDataCaretAsPath();
        }
        performUndo() {
            super.performUndo();
            this.setDataCaretAsPath(this.caretAsPathBefore);
        }
        performRedo() {
            super.performRedo();
            if (this.caretAsPathAfter === undefined) {
                throw new Error(`caretAsPathAfter is undefined, this indicates a \
corrupted state and thus an internal error`);
            }
            this.setDataCaretAsPath(this.caretAsPathAfter);
        }
        /**
         * Get the current data caret position as a path.
         *
         * @returns A caret.
         */
        getDataCaretAsPath() {
            const caret = this.editor.caretManager.getDataCaret(true);
            if (caret === undefined) {
                // Returning undefined for "the caret was undefined" would not
                // trap stupid mistakes in managing the data.
                return [undefined, undefined];
            }
            return [this.editor.dataUpdater.nodeToPath(caret.node), caret.offset];
        }
        /**
         * Set the data caret.
         *
         * @param caret A caret.
         */
        setDataCaretAsPath(caret) {
            // [undefined, undefined] === the caret was undefined. We can't do anything.
            if (caret[0] === undefined && caret[1] === undefined) {
                return;
            }
            this.editor.caretManager.setCaret(this.editor.dataUpdater.pathToNode(caret[0]), caret[1]);
        }
        /**
         * This method can be used to record the caret position after the acts
         * recorded by this undo are performed. If the caret is recorded by means of
         * this method, then [[end]] will not record the caret position again. This
         * can be useful in cases for which it is not clear when an UndoGroup might
         * end. [[TextUndoGroup]] is a case in point. This method can be called any
         * number of times to update the caret position at the end of the group.
         */
        recordCaretAfter() {
            this.caretAsPathAfter = this.getDataCaretAsPath();
        }
        end() {
            if (this.caretAsPathAfter === undefined) {
                this.recordCaretAfter();
            }
        }
    }
    exports.UndoGroup = UndoGroup;
    /**
     * Grouping of text operations should be limited in size. For instance, if the
     * user hits backspace to delete a whole sentence and then wants to undo this
     * operation. It is better to undo it in chunks instead of reinserting the whole
     * sentence. This class allows for limiting the length of such chunks.
     */
    class TextUndoGroup extends UndoGroup {
        /**
         * @param desc The description of this group.
         *
         * @param editor The editor for which this undo group is created.
         *
         * @param undoList The list which will hold this group.
         *
         * @param limit The maximum number of undo operations that this group should
         * record.
         */
        constructor(desc, editor, undoList, limit) {
            super(desc, editor);
            this.undoList = undoList;
            this.limit = limit;
        }
        record(undoToRecord) {
            if (this.list.length >= this.limit) {
                throw new Error("TextUndoGroup.record called beyond the limit");
            }
            super.record(undoToRecord);
            if (this.list.length === this.limit) {
                this.undoList.endGroup();
            }
        }
    }
    exports.TextUndoGroup = TextUndoGroup;
});
//  LocalWords:  pathToNode nodeToPath Dubeau MPL Mangalam param UndoGroup
//  LocalWords:  TextUndoGroup caretAsPathAfter
//# sourceMappingURL=wundo.js.map