0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-21 23:03:11 -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

@ -267,8 +267,8 @@ class Squire {
// stop it by preventing default.
// 30-11-2023 Update: The fix for Grammarly bug prevents pasting
// text directly from the keyboard on Android if the text to be
// inserted contains \n, as pasting from the keyboard does not
// fire a true paste event. The Grammarly bug seems to have been
// inserted contains \n, as pasting from the keyboard does not
// fire a true paste event. The Grammarly bug seems to have been
// fixed in Samsung keyboard as of v5.6.10.4, but leaving the
// fix in place for now, as the bug is particularly destructive.
if (isAndroid && event.data && event.data.includes('\n')) {
@ -839,33 +839,39 @@ class Squire {
* Leaves bookmark.
*/
_recordUndoState(range: Range, replace?: boolean): Squire {
// Don't record if we're already in an undo state
if (!this._isInUndoState || replace) {
const isInUndoState = this._isInUndoState;
if (!isInUndoState || replace) {
// Advance pointer to new position
let undoIndex = this._undoIndex;
let undoIndex = this._undoIndex + 1;
const undoStack = this._undoStack;
const undoConfig = this._config.undo;
const undoThreshold = undoConfig.documentSizeThreshold;
const undoLimit = undoConfig.undoLimit;
if (!replace) {
undoIndex += 1;
}
// Truncate stack if longer (i.e. if has been previously undone)
if (undoIndex < this._undoStackLength) {
undoStack.length = this._undoStackLength = undoIndex;
}
// Get data
// Add bookmark
if (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();
// If this document is above the configured size threshold,
// limit the number of saved undo states.
// Threshold is in bytes, JS uses 2 bytes per character
if (replace) {
undoIndex -= 1;
}
if (undoThreshold > -1 && html.length * 2 > undoThreshold) {
if (undoLimit > -1 && 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 { deleteContentsOfRange } from '../range/InsertDelete';
@ -9,7 +9,7 @@ import {
rangeDoesEndAtBlockBoundary,
} from '../range/Block';
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, '');
if (text === '*' || text === '1.') {
event.preventDefault();
self.insertPlainText(' ', false);
self._docWasChanged();
self.saveUndoState(range);
const walker = new TreeIterator<Text>(block, SHOW_TEXT);
let textNode: Text | null;
while ((textNode = walker.nextNode())) {
textNode.data = cantFocusEmptyTextNodes ? ZWS : '';
detach(textNode);
}
if (text === '*') {
self.makeUnorderedList();