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:
parent
3804ea50ba
commit
6cfd85bd8e
2 changed files with 22 additions and 13 deletions
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue