0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-22 07:13:08 -05:00

Add undo point for automatic list creation

If you do `*` then space or `1. ` then space at the beginning of a line,
we automatically create a list. Now you can use undo to undo just the
automatic list creation, reverting to the plain text you typed.
This commit is contained in:
Neil Jenkins 2023-12-20 14:17:12 +11:00
parent 3804ea50ba
commit 6cfd85bd8e
2 changed files with 22 additions and 13 deletions

View file

@ -839,33 +839,39 @@ class Squire {
* Leaves bookmark. * Leaves bookmark.
*/ */
_recordUndoState(range: Range, replace?: boolean): Squire { _recordUndoState(range: Range, replace?: boolean): Squire {
// Don't record if we're already in an undo state const isInUndoState = this._isInUndoState;
if (!this._isInUndoState || replace) { if (!isInUndoState || replace) {
// Advance pointer to new position // Advance pointer to new position
let undoIndex = this._undoIndex; let undoIndex = this._undoIndex + 1;
const undoStack = this._undoStack; const undoStack = this._undoStack;
const undoConfig = this._config.undo; const undoConfig = this._config.undo;
const undoThreshold = undoConfig.documentSizeThreshold; const undoThreshold = undoConfig.documentSizeThreshold;
const undoLimit = undoConfig.undoLimit; const undoLimit = undoConfig.undoLimit;
if (!replace) {
undoIndex += 1;
}
// Truncate stack if longer (i.e. if has been previously undone) // Truncate stack if longer (i.e. if has been previously undone)
if (undoIndex < this._undoStackLength) { if (undoIndex < this._undoStackLength) {
undoStack.length = this._undoStackLength = undoIndex; undoStack.length = this._undoStackLength = undoIndex;
} }
// Get data // Add bookmark
if (range) { if (range) {
this._saveRangeToBookmark(range); this._saveRangeToBookmark(range);
} }
// Don't record if we're already in an undo state
if (isInUndoState) {
return this;
}
// Get data
const html = this._getRawHTML(); const html = this._getRawHTML();
// If this document is above the configured size threshold, // If this document is above the configured size threshold,
// limit the number of saved undo states. // limit the number of saved undo states.
// Threshold is in bytes, JS uses 2 bytes per character // Threshold is in bytes, JS uses 2 bytes per character
if (replace) {
undoIndex -= 1;
}
if (undoThreshold > -1 && html.length * 2 > undoThreshold) { if (undoThreshold > -1 && html.length * 2 > undoThreshold) {
if (undoLimit > -1 && undoIndex > undoLimit) { if (undoLimit > -1 && undoIndex > undoLimit) {
undoStack.splice(0, undoIndex - undoLimit); undoStack.splice(0, undoIndex - undoLimit);

View file

@ -1,4 +1,4 @@
import { getLength } from '../node/Node'; import { detach, getLength } from '../node/Node';
import { moveRangeBoundariesDownTree } from '../range/Boundaries'; import { moveRangeBoundariesDownTree } from '../range/Boundaries';
import { deleteContentsOfRange } from '../range/InsertDelete'; import { deleteContentsOfRange } from '../range/InsertDelete';
@ -9,7 +9,7 @@ import {
rangeDoesEndAtBlockBoundary, rangeDoesEndAtBlockBoundary,
} from '../range/Block'; } from '../range/Block';
import { SHOW_TEXT, TreeIterator } from '../node/TreeIterator'; import { SHOW_TEXT, TreeIterator } from '../node/TreeIterator';
import { ZWS, cantFocusEmptyTextNodes } from '../Constants'; import { ZWS } from '../Constants';
// --- // ---
@ -31,10 +31,13 @@ const Space = (self: Squire, event: KeyboardEvent, range: Range): void => {
const text = block.textContent?.trimEnd().replace(ZWS, ''); const text = block.textContent?.trimEnd().replace(ZWS, '');
if (text === '*' || text === '1.') { if (text === '*' || text === '1.') {
event.preventDefault(); event.preventDefault();
self.insertPlainText(' ', false);
self._docWasChanged();
self.saveUndoState(range);
const walker = new TreeIterator<Text>(block, SHOW_TEXT); const walker = new TreeIterator<Text>(block, SHOW_TEXT);
let textNode: Text | null; let textNode: Text | null;
while ((textNode = walker.nextNode())) { while ((textNode = walker.nextNode())) {
textNode.data = cantFocusEmptyTextNodes ? ZWS : ''; detach(textNode);
} }
if (text === '*') { if (text === '*') {
self.makeUnorderedList(); self.makeUnorderedList();