@lexical/history 0.35.1-nightly.20250924.0 → 0.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LexicalHistory.dev.js +65 -1
- package/LexicalHistory.dev.mjs +65 -3
- package/LexicalHistory.js.flow +14 -1
- package/LexicalHistory.mjs +2 -0
- package/LexicalHistory.node.mjs +2 -0
- package/LexicalHistory.prod.js +1 -1
- package/LexicalHistory.prod.mjs +1 -1
- package/index.d.ts +32 -1
- package/package.json +4 -3
package/LexicalHistory.dev.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
'use strict';
|
|
10
10
|
|
|
11
|
+
var extension = require('@lexical/extension');
|
|
11
12
|
var utils = require('@lexical/utils');
|
|
12
13
|
var lexical = require('lexical');
|
|
13
14
|
|
|
@@ -118,7 +119,7 @@ function isTextNodeUnchanged(key, prevEditorState, nextEditorState) {
|
|
|
118
119
|
}
|
|
119
120
|
return false;
|
|
120
121
|
}
|
|
121
|
-
function createMergeActionGetter(editor,
|
|
122
|
+
function createMergeActionGetter(editor, delayOrStore) {
|
|
122
123
|
let prevChangeTime = Date.now();
|
|
123
124
|
let prevChangeType = OTHER;
|
|
124
125
|
return (prevEditorState, nextEditorState, currentHistoryEntry, dirtyLeaves, dirtyElements, tags) => {
|
|
@@ -150,6 +151,7 @@ function createMergeActionGetter(editor, delay) {
|
|
|
150
151
|
}
|
|
151
152
|
return DISCARD_HISTORY_CANDIDATE;
|
|
152
153
|
}
|
|
154
|
+
const delay = typeof delayOrStore === 'number' ? delayOrStore : delayOrStore.peek();
|
|
153
155
|
if (shouldPushHistory === false && changeType !== OTHER && changeType === prevChangeType && changeTime < prevChangeTime + delay && isSameEditor) {
|
|
154
156
|
return HISTORY_MERGE;
|
|
155
157
|
}
|
|
@@ -294,6 +296,68 @@ function createEmptyHistoryState() {
|
|
|
294
296
|
undoStack: []
|
|
295
297
|
};
|
|
296
298
|
}
|
|
299
|
+
/**
|
|
300
|
+
* Registers necessary listeners to manage undo/redo history stack and related
|
|
301
|
+
* editor commands, via the \@lexical/history module.
|
|
302
|
+
*/
|
|
303
|
+
|
|
304
|
+
const HistoryExtension = lexical.defineExtension({
|
|
305
|
+
build: (editor, {
|
|
306
|
+
delay,
|
|
307
|
+
createInitialHistoryState,
|
|
308
|
+
disabled
|
|
309
|
+
}) => extension.namedSignals({
|
|
310
|
+
delay,
|
|
311
|
+
disabled,
|
|
312
|
+
historyState: createInitialHistoryState(editor)
|
|
313
|
+
}),
|
|
314
|
+
config: lexical.safeCast({
|
|
315
|
+
createInitialHistoryState: createEmptyHistoryState,
|
|
316
|
+
delay: 300,
|
|
317
|
+
disabled: typeof window === 'undefined'
|
|
318
|
+
}),
|
|
319
|
+
name: '@lexical/history/History',
|
|
320
|
+
register: (editor, config, state) => {
|
|
321
|
+
const stores = state.getOutput();
|
|
322
|
+
return extension.effect(() => stores.disabled.value ? undefined : registerHistory(editor, stores.historyState.value, stores.delay));
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
function getHistoryPeer(editor) {
|
|
326
|
+
return editor ? extension.getPeerDependencyFromEditor(editor, HistoryExtension.name) : null;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Registers necessary listeners to manage undo/redo history stack and related
|
|
331
|
+
* editor commands, via the \@lexical/history module, only if the parent editor
|
|
332
|
+
* has a history plugin implementation.
|
|
333
|
+
*/
|
|
334
|
+
const SharedHistoryExtension = lexical.defineExtension({
|
|
335
|
+
dependencies: [lexical.configExtension(HistoryExtension, {
|
|
336
|
+
createInitialHistoryState: () => {
|
|
337
|
+
throw new Error('SharedHistory did not inherit parent history');
|
|
338
|
+
},
|
|
339
|
+
disabled: true
|
|
340
|
+
})],
|
|
341
|
+
name: '@lexical/history/SharedHistory',
|
|
342
|
+
register(editor, _config, state) {
|
|
343
|
+
const {
|
|
344
|
+
output
|
|
345
|
+
} = state.getDependency(HistoryExtension);
|
|
346
|
+
const parentPeer = getHistoryPeer(editor._parentEditor);
|
|
347
|
+
if (!parentPeer) {
|
|
348
|
+
return () => {};
|
|
349
|
+
}
|
|
350
|
+
const parentOutput = parentPeer.output;
|
|
351
|
+
return extension.effect(() => extension.batch(() => {
|
|
352
|
+
output.delay.value = parentOutput.delay.value;
|
|
353
|
+
output.historyState.value = parentOutput.historyState.value;
|
|
354
|
+
// Note that toggling the parent history will force this to be changed
|
|
355
|
+
output.disabled.value = parentOutput.disabled.value;
|
|
356
|
+
}));
|
|
357
|
+
}
|
|
358
|
+
});
|
|
297
359
|
|
|
360
|
+
exports.HistoryExtension = HistoryExtension;
|
|
361
|
+
exports.SharedHistoryExtension = SharedHistoryExtension;
|
|
298
362
|
exports.createEmptyHistoryState = createEmptyHistoryState;
|
|
299
363
|
exports.registerHistory = registerHistory;
|
package/LexicalHistory.dev.mjs
CHANGED
|
@@ -6,8 +6,9 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { namedSignals, effect, batch, getPeerDependencyFromEditor } from '@lexical/extension';
|
|
9
10
|
import { mergeRegister } from '@lexical/utils';
|
|
10
|
-
import { UNDO_COMMAND, COMMAND_PRIORITY_EDITOR, REDO_COMMAND, CLEAR_EDITOR_COMMAND, CLEAR_HISTORY_COMMAND, CAN_REDO_COMMAND, CAN_UNDO_COMMAND, HISTORIC_TAG, HISTORY_PUSH_TAG, HISTORY_MERGE_TAG, $isRangeSelection, $isTextNode, $isRootNode } from 'lexical';
|
|
11
|
+
import { defineExtension, safeCast, configExtension, UNDO_COMMAND, COMMAND_PRIORITY_EDITOR, REDO_COMMAND, CLEAR_EDITOR_COMMAND, CLEAR_HISTORY_COMMAND, CAN_REDO_COMMAND, CAN_UNDO_COMMAND, HISTORIC_TAG, HISTORY_PUSH_TAG, HISTORY_MERGE_TAG, $isRangeSelection, $isTextNode, $isRootNode } from 'lexical';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
@@ -116,7 +117,7 @@ function isTextNodeUnchanged(key, prevEditorState, nextEditorState) {
|
|
|
116
117
|
}
|
|
117
118
|
return false;
|
|
118
119
|
}
|
|
119
|
-
function createMergeActionGetter(editor,
|
|
120
|
+
function createMergeActionGetter(editor, delayOrStore) {
|
|
120
121
|
let prevChangeTime = Date.now();
|
|
121
122
|
let prevChangeType = OTHER;
|
|
122
123
|
return (prevEditorState, nextEditorState, currentHistoryEntry, dirtyLeaves, dirtyElements, tags) => {
|
|
@@ -148,6 +149,7 @@ function createMergeActionGetter(editor, delay) {
|
|
|
148
149
|
}
|
|
149
150
|
return DISCARD_HISTORY_CANDIDATE;
|
|
150
151
|
}
|
|
152
|
+
const delay = typeof delayOrStore === 'number' ? delayOrStore : delayOrStore.peek();
|
|
151
153
|
if (shouldPushHistory === false && changeType !== OTHER && changeType === prevChangeType && changeTime < prevChangeTime + delay && isSameEditor) {
|
|
152
154
|
return HISTORY_MERGE;
|
|
153
155
|
}
|
|
@@ -292,5 +294,65 @@ function createEmptyHistoryState() {
|
|
|
292
294
|
undoStack: []
|
|
293
295
|
};
|
|
294
296
|
}
|
|
297
|
+
/**
|
|
298
|
+
* Registers necessary listeners to manage undo/redo history stack and related
|
|
299
|
+
* editor commands, via the \@lexical/history module.
|
|
300
|
+
*/
|
|
301
|
+
|
|
302
|
+
const HistoryExtension = defineExtension({
|
|
303
|
+
build: (editor, {
|
|
304
|
+
delay,
|
|
305
|
+
createInitialHistoryState,
|
|
306
|
+
disabled
|
|
307
|
+
}) => namedSignals({
|
|
308
|
+
delay,
|
|
309
|
+
disabled,
|
|
310
|
+
historyState: createInitialHistoryState(editor)
|
|
311
|
+
}),
|
|
312
|
+
config: safeCast({
|
|
313
|
+
createInitialHistoryState: createEmptyHistoryState,
|
|
314
|
+
delay: 300,
|
|
315
|
+
disabled: typeof window === 'undefined'
|
|
316
|
+
}),
|
|
317
|
+
name: '@lexical/history/History',
|
|
318
|
+
register: (editor, config, state) => {
|
|
319
|
+
const stores = state.getOutput();
|
|
320
|
+
return effect(() => stores.disabled.value ? undefined : registerHistory(editor, stores.historyState.value, stores.delay));
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
function getHistoryPeer(editor) {
|
|
324
|
+
return editor ? getPeerDependencyFromEditor(editor, HistoryExtension.name) : null;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Registers necessary listeners to manage undo/redo history stack and related
|
|
329
|
+
* editor commands, via the \@lexical/history module, only if the parent editor
|
|
330
|
+
* has a history plugin implementation.
|
|
331
|
+
*/
|
|
332
|
+
const SharedHistoryExtension = defineExtension({
|
|
333
|
+
dependencies: [configExtension(HistoryExtension, {
|
|
334
|
+
createInitialHistoryState: () => {
|
|
335
|
+
throw new Error('SharedHistory did not inherit parent history');
|
|
336
|
+
},
|
|
337
|
+
disabled: true
|
|
338
|
+
})],
|
|
339
|
+
name: '@lexical/history/SharedHistory',
|
|
340
|
+
register(editor, _config, state) {
|
|
341
|
+
const {
|
|
342
|
+
output
|
|
343
|
+
} = state.getDependency(HistoryExtension);
|
|
344
|
+
const parentPeer = getHistoryPeer(editor._parentEditor);
|
|
345
|
+
if (!parentPeer) {
|
|
346
|
+
return () => {};
|
|
347
|
+
}
|
|
348
|
+
const parentOutput = parentPeer.output;
|
|
349
|
+
return effect(() => batch(() => {
|
|
350
|
+
output.delay.value = parentOutput.delay.value;
|
|
351
|
+
output.historyState.value = parentOutput.historyState.value;
|
|
352
|
+
// Note that toggling the parent history will force this to be changed
|
|
353
|
+
output.disabled.value = parentOutput.disabled.value;
|
|
354
|
+
}));
|
|
355
|
+
}
|
|
356
|
+
});
|
|
295
357
|
|
|
296
|
-
export { createEmptyHistoryState, registerHistory };
|
|
358
|
+
export { HistoryExtension, SharedHistoryExtension, createEmptyHistoryState, registerHistory };
|
package/LexicalHistory.js.flow
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @flow strict
|
|
8
8
|
*/
|
|
9
|
-
import type {EditorState, BaseSelection, LexicalEditor} from 'lexical';
|
|
9
|
+
import type {LexicalExtension, ExtensionConfigBase, EditorState, BaseSelection, LexicalEditor} from 'lexical';
|
|
10
|
+
import type {NamedSignalsOutput} from '@lexical/extension';
|
|
10
11
|
|
|
11
12
|
export type HistoryStateEntry = {
|
|
12
13
|
editor: LexicalEditor,
|
|
@@ -24,3 +25,15 @@ declare export function registerHistory(
|
|
|
24
25
|
delay: number,
|
|
25
26
|
): () => void;
|
|
26
27
|
declare export function createEmptyHistoryState(): HistoryState;
|
|
28
|
+
|
|
29
|
+
export type HistoryConfig = {
|
|
30
|
+
delay: number;
|
|
31
|
+
createInitialHistoryState: (editor: LexicalEditor) => HistoryState;
|
|
32
|
+
disabled: boolean;
|
|
33
|
+
}
|
|
34
|
+
declare export var HistoryExtension: LexicalExtension<HistoryConfig, "@lexical/history/History", NamedSignalsOutput<{
|
|
35
|
+
delay: number;
|
|
36
|
+
disabled: boolean;
|
|
37
|
+
historyState: HistoryState;
|
|
38
|
+
}>, void>;
|
|
39
|
+
declare export var SharedHistoryExtension: LexicalExtension<ExtensionConfigBase, "@lexical/history/SharedHistory", void, void>;
|
package/LexicalHistory.mjs
CHANGED
|
@@ -9,5 +9,7 @@
|
|
|
9
9
|
import * as modDev from './LexicalHistory.dev.mjs';
|
|
10
10
|
import * as modProd from './LexicalHistory.prod.mjs';
|
|
11
11
|
const mod = process.env.NODE_ENV !== 'production' ? modDev : modProd;
|
|
12
|
+
export const HistoryExtension = mod.HistoryExtension;
|
|
13
|
+
export const SharedHistoryExtension = mod.SharedHistoryExtension;
|
|
12
14
|
export const createEmptyHistoryState = mod.createEmptyHistoryState;
|
|
13
15
|
export const registerHistory = mod.registerHistory;
|
package/LexicalHistory.node.mjs
CHANGED
|
@@ -7,5 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
const mod = await (process.env.NODE_ENV !== 'production' ? import('./LexicalHistory.dev.mjs') : import('./LexicalHistory.prod.mjs'));
|
|
10
|
+
export const HistoryExtension = mod.HistoryExtension;
|
|
11
|
+
export const SharedHistoryExtension = mod.SharedHistoryExtension;
|
|
10
12
|
export const createEmptyHistoryState = mod.createEmptyHistoryState;
|
|
11
13
|
export const registerHistory = mod.registerHistory;
|
package/LexicalHistory.prod.js
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
"use strict";var t=require("@lexical/utils"),
|
|
9
|
+
"use strict";var e=require("@lexical/extension"),t=require("@lexical/utils"),n=require("lexical");const r=0,o=1,i=2,s=0,a=1,c=2,d=3,u=4;function l(e,t,r,o,i){if(null===e||0===r.size&&0===o.size&&!i)return s;const l=t._selection,_=e._selection;if(i)return a;if(!(n.$isRangeSelection(l)&&n.$isRangeSelection(_)&&_.isCollapsed()&&l.isCollapsed()))return s;const f=function(e,t,r){const o=e._nodeMap,i=[];for(const e of t){const t=o.get(e);void 0!==t&&i.push(t)}for(const[e,t]of r){if(!t)continue;const r=o.get(e);void 0===r||n.$isRootNode(r)||i.push(r)}return i}(t,r,o);if(0===f.length)return s;if(f.length>1){const r=t._nodeMap,o=r.get(l.anchor.key),i=r.get(_.anchor.key);return o&&i&&!e._nodeMap.has(o.__key)&&n.$isTextNode(o)&&1===o.__text.length&&1===l.anchor.offset?c:s}const p=f[0],h=e._nodeMap.get(p.__key);if(!n.$isTextNode(h)||!n.$isTextNode(p)||h.__mode!==p.__mode)return s;const O=h.__text,S=p.__text;if(O===S)return s;const C=l.anchor,y=_.anchor;if(C.key!==y.key||"text"!==C.type)return s;const g=C.offset,m=y.offset,M=S.length-O.length;return 1===M&&m===g-1?c:-1===M&&m===g+1?d:-1===M&&m===g?u:s}function _(e,t){let a=Date.now(),c=s;return(d,u,_,f,p,h)=>{const O=Date.now();if(h.has(n.HISTORIC_TAG))return c=s,a=O,i;const S=l(d,u,f,p,e.isComposing()),C=(()=>{const l=null===_||_.editor===e,C=h.has(n.HISTORY_PUSH_TAG);if(!C&&l&&h.has(n.HISTORY_MERGE_TAG))return r;if(null===d)return o;const y=u._selection;if(!(f.size>0||p.size>0))return null!==y?r:i;const g="number"==typeof t?t:t.peek();if(!1===C&&S!==s&&S===c&&O<a+g&&l)return r;if(1===f.size){if(function(e,t,r){const o=t._nodeMap.get(e),i=r._nodeMap.get(e),s=t._selection,a=r._selection;return!(n.$isRangeSelection(s)&&n.$isRangeSelection(a)&&"element"===s.anchor.type&&"element"===s.focus.type&&"text"===a.anchor.type&&"text"===a.focus.type||!n.$isTextNode(o)||!n.$isTextNode(i)||o.__parent!==i.__parent)&&JSON.stringify(t.read((()=>o.exportJSON())))===JSON.stringify(r.read((()=>i.exportJSON())))}(Array.from(f)[0],d,u))return r}return o})();return a=O,c=S,C}}function f(e){e.undoStack=[],e.redoStack=[],e.current=null}function p(e,r,s){const a=_(e,s),c=t.mergeRegister(e.registerCommand(n.UNDO_COMMAND,(()=>(function(e,t){const r=t.redoStack,o=t.undoStack;if(0!==o.length){const i=t.current,s=o.pop();null!==i&&(r.push(i),e.dispatchCommand(n.CAN_REDO_COMMAND,!0)),0===o.length&&e.dispatchCommand(n.CAN_UNDO_COMMAND,!1),t.current=s||null,s&&s.editor.setEditorState(s.editorState,{tag:n.HISTORIC_TAG})}}(e,r),!0)),n.COMMAND_PRIORITY_EDITOR),e.registerCommand(n.REDO_COMMAND,(()=>(function(e,t){const r=t.redoStack,o=t.undoStack;if(0!==r.length){const i=t.current;null!==i&&(o.push(i),e.dispatchCommand(n.CAN_UNDO_COMMAND,!0));const s=r.pop();0===r.length&&e.dispatchCommand(n.CAN_REDO_COMMAND,!1),t.current=s||null,s&&s.editor.setEditorState(s.editorState,{tag:n.HISTORIC_TAG})}}(e,r),!0)),n.COMMAND_PRIORITY_EDITOR),e.registerCommand(n.CLEAR_EDITOR_COMMAND,(()=>(f(r),!1)),n.COMMAND_PRIORITY_EDITOR),e.registerCommand(n.CLEAR_HISTORY_COMMAND,(()=>(f(r),e.dispatchCommand(n.CAN_REDO_COMMAND,!1),e.dispatchCommand(n.CAN_UNDO_COMMAND,!1),!0)),n.COMMAND_PRIORITY_EDITOR),e.registerUpdateListener((({editorState:t,prevEditorState:s,dirtyLeaves:c,dirtyElements:d,tags:u})=>{const l=r.current,_=r.redoStack,f=r.undoStack,p=null===l?null:l.editorState;if(null!==l&&t===p)return;const h=a(s,t,l,c,d,u);if(h===o)0!==_.length&&(r.redoStack=[],e.dispatchCommand(n.CAN_REDO_COMMAND,!1)),null!==l&&(f.push({...l}),e.dispatchCommand(n.CAN_UNDO_COMMAND,!0));else if(h===i)return;r.current={editor:e,editorState:t}})));return c}function h(){return{current:null,redoStack:[],undoStack:[]}}const O=n.defineExtension({build:(t,{delay:n,createInitialHistoryState:r,disabled:o})=>e.namedSignals({delay:n,disabled:o,historyState:r(t)}),config:n.safeCast({createInitialHistoryState:h,delay:300,disabled:"undefined"==typeof window}),name:"@lexical/history/History",register:(t,n,r)=>{const o=r.getOutput();return e.effect((()=>o.disabled.value?void 0:p(t,o.historyState.value,o.delay)))}});const S=n.defineExtension({dependencies:[n.configExtension(O,{createInitialHistoryState:()=>{throw new Error("SharedHistory did not inherit parent history")},disabled:!0})],name:"@lexical/history/SharedHistory",register(t,n,r){const{output:o}=r.getDependency(O),i=function(t){return t?e.getPeerDependencyFromEditor(t,O.name):null}(t._parentEditor);if(!i)return()=>{};const s=i.output;return e.effect((()=>e.batch((()=>{o.delay.value=s.delay.value,o.historyState.value=s.historyState.value,o.disabled.value=s.disabled.value}))))}});exports.HistoryExtension=O,exports.SharedHistoryExtension=S,exports.createEmptyHistoryState=h,exports.registerHistory=p;
|
package/LexicalHistory.prod.mjs
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import{
|
|
9
|
+
import{namedSignals as t,effect as e,batch as n,getPeerDependencyFromEditor as r}from"@lexical/extension";import{mergeRegister as o}from"@lexical/utils";import{defineExtension as i,safeCast as a,configExtension as s,UNDO_COMMAND as c,COMMAND_PRIORITY_EDITOR as d,REDO_COMMAND as u,CLEAR_EDITOR_COMMAND as l,CLEAR_HISTORY_COMMAND as f,CAN_REDO_COMMAND as p,CAN_UNDO_COMMAND as h,HISTORIC_TAG as m,HISTORY_PUSH_TAG as y,HISTORY_MERGE_TAG as g,$isRangeSelection as S,$isTextNode as _,$isRootNode as k}from"lexical";const x=0,C=1,v=2,b=0,w=1,E=2,H=3,M=4;function z(t,e,n,r,o){if(null===t||0===n.size&&0===r.size&&!o)return b;const i=e._selection,a=t._selection;if(o)return w;if(!(S(i)&&S(a)&&a.isCollapsed()&&i.isCollapsed()))return b;const s=function(t,e,n){const r=t._nodeMap,o=[];for(const t of e){const e=r.get(t);void 0!==e&&o.push(e)}for(const[t,e]of n){if(!e)continue;const n=r.get(t);void 0===n||k(n)||o.push(n)}return o}(e,n,r);if(0===s.length)return b;if(s.length>1){const n=e._nodeMap,r=n.get(i.anchor.key),o=n.get(a.anchor.key);return r&&o&&!t._nodeMap.has(r.__key)&&_(r)&&1===r.__text.length&&1===i.anchor.offset?E:b}const c=s[0],d=t._nodeMap.get(c.__key);if(!_(d)||!_(c)||d.__mode!==c.__mode)return b;const u=d.__text,l=c.__text;if(u===l)return b;const f=i.anchor,p=a.anchor;if(f.key!==p.key||"text"!==f.type)return b;const h=f.offset,m=p.offset,y=l.length-u.length;return 1===y&&m===h-1?E:-1===y&&m===h+1?H:-1===y&&m===h?M:b}function O(t,e){let n=Date.now(),r=b;return(o,i,a,s,c,d)=>{const u=Date.now();if(d.has(m))return r=b,n=u,v;const l=z(o,i,s,c,t.isComposing()),f=(()=>{const f=null===a||a.editor===t,p=d.has(y);if(!p&&f&&d.has(g))return x;if(null===o)return C;const h=i._selection;if(!(s.size>0||c.size>0))return null!==h?x:v;const m="number"==typeof e?e:e.peek();if(!1===p&&l!==b&&l===r&&u<n+m&&f)return x;if(1===s.size){if(function(t,e,n){const r=e._nodeMap.get(t),o=n._nodeMap.get(t),i=e._selection,a=n._selection;return!(S(i)&&S(a)&&"element"===i.anchor.type&&"element"===i.focus.type&&"text"===a.anchor.type&&"text"===a.focus.type||!_(r)||!_(o)||r.__parent!==o.__parent)&&JSON.stringify(e.read((()=>r.exportJSON())))===JSON.stringify(n.read((()=>o.exportJSON())))}(Array.from(s)[0],o,i))return x}return C})();return n=u,r=l,f}}function J(t){t.undoStack=[],t.redoStack=[],t.current=null}function N(t,e,n){const r=O(t,n),i=o(t.registerCommand(c,(()=>(function(t,e){const n=e.redoStack,r=e.undoStack;if(0!==r.length){const o=e.current,i=r.pop();null!==o&&(n.push(o),t.dispatchCommand(p,!0)),0===r.length&&t.dispatchCommand(h,!1),e.current=i||null,i&&i.editor.setEditorState(i.editorState,{tag:m})}}(t,e),!0)),d),t.registerCommand(u,(()=>(function(t,e){const n=e.redoStack,r=e.undoStack;if(0!==n.length){const o=e.current;null!==o&&(r.push(o),t.dispatchCommand(h,!0));const i=n.pop();0===n.length&&t.dispatchCommand(p,!1),e.current=i||null,i&&i.editor.setEditorState(i.editorState,{tag:m})}}(t,e),!0)),d),t.registerCommand(l,(()=>(J(e),!1)),d),t.registerCommand(f,(()=>(J(e),t.dispatchCommand(p,!1),t.dispatchCommand(h,!1),!0)),d),t.registerUpdateListener((({editorState:n,prevEditorState:o,dirtyLeaves:i,dirtyElements:a,tags:s})=>{const c=e.current,d=e.redoStack,u=e.undoStack,l=null===c?null:c.editorState;if(null!==c&&n===l)return;const f=r(o,n,c,i,a,s);if(f===C)0!==d.length&&(e.redoStack=[],t.dispatchCommand(p,!1)),null!==c&&(u.push({...c}),t.dispatchCommand(h,!0));else if(f===v)return;e.current={editor:t,editorState:n}})));return i}function D(){return{current:null,redoStack:[],undoStack:[]}}const I=i({build:(e,{delay:n,createInitialHistoryState:r,disabled:o})=>t({delay:n,disabled:o,historyState:r(e)}),config:a({createInitialHistoryState:D,delay:300,disabled:"undefined"==typeof window}),name:"@lexical/history/History",register:(t,n,r)=>{const o=r.getOutput();return e((()=>o.disabled.value?void 0:N(t,o.historyState.value,o.delay)))}});const L=i({dependencies:[s(I,{createInitialHistoryState:()=>{throw new Error("SharedHistory did not inherit parent history")},disabled:!0})],name:"@lexical/history/SharedHistory",register(t,o,i){const{output:a}=i.getDependency(I),s=function(t){return t?r(t,I.name):null}(t._parentEditor);if(!s)return()=>{};const c=s.output;return e((()=>n((()=>{a.delay.value=c.delay.value,a.historyState.value=c.historyState.value,a.disabled.value=c.disabled.value}))))}});export{I as HistoryExtension,L as SharedHistoryExtension,D as createEmptyHistoryState,N as registerHistory};
|
package/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*
|
|
7
7
|
*/
|
|
8
8
|
import type { EditorState, LexicalEditor } from 'lexical';
|
|
9
|
+
import { ReadonlySignal } from '@lexical/extension';
|
|
9
10
|
export type HistoryStateEntry = {
|
|
10
11
|
editor: LexicalEditor;
|
|
11
12
|
editorState: EditorState;
|
|
@@ -24,9 +25,39 @@ export type HistoryState = {
|
|
|
24
25
|
* instead of merging the current changes with the current stack.
|
|
25
26
|
* @returns The listeners cleanup callback function.
|
|
26
27
|
*/
|
|
27
|
-
export declare function registerHistory(editor: LexicalEditor, historyState: HistoryState, delay: number): () => void;
|
|
28
|
+
export declare function registerHistory(editor: LexicalEditor, historyState: HistoryState, delay: number | ReadonlySignal<number>): () => void;
|
|
28
29
|
/**
|
|
29
30
|
* Creates an empty history state.
|
|
30
31
|
* @returns - The empty history state, as an object.
|
|
31
32
|
*/
|
|
32
33
|
export declare function createEmptyHistoryState(): HistoryState;
|
|
34
|
+
export interface HistoryConfig {
|
|
35
|
+
/**
|
|
36
|
+
* The time (in milliseconds) the editor should delay generating a new history stack,
|
|
37
|
+
* instead of merging the current changes with the current stack. The default is 300ms.
|
|
38
|
+
*/
|
|
39
|
+
delay: number;
|
|
40
|
+
/**
|
|
41
|
+
* The initial history state, the default is {@link createEmptyHistoryState}.
|
|
42
|
+
*/
|
|
43
|
+
createInitialHistoryState: (editor: LexicalEditor) => HistoryState;
|
|
44
|
+
/**
|
|
45
|
+
* Whether history is disabled or not
|
|
46
|
+
*/
|
|
47
|
+
disabled: boolean;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Registers necessary listeners to manage undo/redo history stack and related
|
|
51
|
+
* editor commands, via the \@lexical/history module.
|
|
52
|
+
*/
|
|
53
|
+
export declare const HistoryExtension: import("lexical").LexicalExtension<HistoryConfig, "@lexical/history/History", import("@lexical/extension").NamedSignalsOutput<{
|
|
54
|
+
delay: number;
|
|
55
|
+
disabled: boolean;
|
|
56
|
+
historyState: HistoryState;
|
|
57
|
+
}>, unknown>;
|
|
58
|
+
/**
|
|
59
|
+
* Registers necessary listeners to manage undo/redo history stack and related
|
|
60
|
+
* editor commands, via the \@lexical/history module, only if the parent editor
|
|
61
|
+
* has a history plugin implementation.
|
|
62
|
+
*/
|
|
63
|
+
export declare const SharedHistoryExtension: import("lexical").LexicalExtension<import("lexical").ExtensionConfigBase, "@lexical/history/SharedHistory", unknown, unknown>;
|
package/package.json
CHANGED
|
@@ -8,12 +8,13 @@
|
|
|
8
8
|
"history"
|
|
9
9
|
],
|
|
10
10
|
"license": "MIT",
|
|
11
|
-
"version": "0.
|
|
11
|
+
"version": "0.36.0",
|
|
12
12
|
"main": "LexicalHistory.js",
|
|
13
13
|
"types": "index.d.ts",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@lexical/
|
|
16
|
-
"lexical": "0.
|
|
15
|
+
"@lexical/extension": "0.36.0",
|
|
16
|
+
"@lexical/utils": "0.36.0",
|
|
17
|
+
"lexical": "0.36.0"
|
|
17
18
|
},
|
|
18
19
|
"repository": {
|
|
19
20
|
"type": "git",
|