@lobehub/editor 4.3.2 → 4.5.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.
@@ -9,6 +9,11 @@ interface MentionOption extends Partial<ReactSlashOptionProps> {
9
9
  }
10
10
  export interface EditorProps extends Partial<ReactEditorContentProps>, Omit<ReactPlainTextProps, 'children'> {
11
11
  autoFocus?: boolean;
12
+ /**
13
+ * Automatically convert pasted markdown once the detection threshold is reached
14
+ * @default true
15
+ */
16
+ autoFormatMarkdown?: boolean;
12
17
  children?: ReactNode;
13
18
  className?: string;
14
19
  /**
@@ -19,7 +24,7 @@ export interface EditorProps extends Partial<ReactEditorContentProps>, Omit<Reac
19
24
  editable?: boolean;
20
25
  editor?: IEditor;
21
26
  /**
22
- * Enable automatic markdown formatting for pasted content
27
+ * Enable automatic markdown conversion for pasted content
23
28
  * @default true
24
29
  */
25
30
  enablePasteMarkdown?: boolean;
@@ -42,6 +47,11 @@ export interface EditorProps extends Partial<ReactEditorContentProps>, Omit<Reac
42
47
  * Unlike onChange, this won't trigger on cursor movement or selection changes
43
48
  */
44
49
  onTextChange?: (editor: IEditor) => void;
50
+ /**
51
+ * Minimum markdown score required before auto conversion runs
52
+ * @default 5
53
+ */
54
+ pasteMarkdownAutoConvertThreshold?: number;
45
55
  plugins?: EditorPlugin[];
46
56
  slashOption?: Partial<ReactSlashOptionProps>;
47
57
  /** Force slash menu placement direction, skipping auto-flip detection */
@@ -0,0 +1,22 @@
1
+ import type { SerializedEditorState } from 'lexical';
2
+ import type { CSSProperties, ReactNode } from 'react';
3
+ import type { LexicalDiffBlockRenderer } from './diff/types';
4
+ import type { LexicalRendererProps } from './types';
5
+ export type { LexicalDiffBlockRenderContext, LexicalDiffBlockRenderer, LexicalDiffCell, LexicalDiffRow, LexicalDiffRowKind, } from './diff/types';
6
+ export interface LexicalDiffProps {
7
+ blockRenderers?: Record<string, LexicalDiffBlockRenderer>;
8
+ className?: string;
9
+ extraNodes?: LexicalRendererProps['extraNodes'];
10
+ labels?: {
11
+ new?: ReactNode;
12
+ old?: ReactNode;
13
+ };
14
+ newValue: SerializedEditorState;
15
+ oldValue: SerializedEditorState;
16
+ overrides?: LexicalRendererProps['overrides'];
17
+ renderBlockDiff?: LexicalDiffBlockRenderer;
18
+ renderContext?: LexicalRendererProps['renderContext'];
19
+ style?: CSSProperties;
20
+ variant?: LexicalRendererProps['variant'];
21
+ }
22
+ export declare function LexicalDiff({ oldValue, newValue, variant, extraNodes, overrides, renderContext, labels, blockRenderers, renderBlockDiff, className, style, }: LexicalDiffProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,116 @@
1
+ import { cx } from 'antd-style';
2
+ import { useMemo } from 'react';
3
+ import { LexicalRenderer } from "./LexicalRenderer";
4
+ import { computeLexicalDiffRows } from "./diff/compute";
5
+ import { styles } from "./diff/style";
6
+ import { jsx as _jsx } from "react/jsx-runtime";
7
+ import { jsxs as _jsxs } from "react/jsx-runtime";
8
+ function wrapBlock(block) {
9
+ return {
10
+ root: {
11
+ children: [block],
12
+ direction: 'ltr',
13
+ format: '',
14
+ indent: 0,
15
+ type: 'root',
16
+ version: 1
17
+ }
18
+ };
19
+ }
20
+ function RowCell(_ref) {
21
+ var className = _ref.className,
22
+ content = _ref.content;
23
+ return /*#__PURE__*/_jsx("div", {
24
+ className: className,
25
+ children: content
26
+ });
27
+ }
28
+ export function LexicalDiff(_ref2) {
29
+ var _labels$old, _labels$new;
30
+ var oldValue = _ref2.oldValue,
31
+ newValue = _ref2.newValue,
32
+ _ref2$variant = _ref2.variant,
33
+ variant = _ref2$variant === void 0 ? 'default' : _ref2$variant,
34
+ extraNodes = _ref2.extraNodes,
35
+ overrides = _ref2.overrides,
36
+ renderContext = _ref2.renderContext,
37
+ labels = _ref2.labels,
38
+ blockRenderers = _ref2.blockRenderers,
39
+ renderBlockDiff = _ref2.renderBlockDiff,
40
+ className = _ref2.className,
41
+ style = _ref2.style;
42
+ var rows = useMemo(function () {
43
+ return computeLexicalDiffRows(oldValue, newValue);
44
+ }, [oldValue, newValue]);
45
+ var renderDefaultCell = function renderDefaultCell(block) {
46
+ if (!block) return null;
47
+ return /*#__PURE__*/_jsx(LexicalRenderer, {
48
+ extraNodes: extraNodes,
49
+ overrides: overrides,
50
+ renderContext: renderContext,
51
+ value: wrapBlock(block),
52
+ variant: variant
53
+ });
54
+ };
55
+ var renderRow = function renderRow(row, index) {
56
+ var _row$oldCell, _row$newCell, _ref3, _row$oldCell$blockTyp, _row$oldCell2, _row$newCell2, _row$oldCell3, _row$newCell3, _ref4, _row$oldCell$baseBloc, _row$oldCell4, _row$newCell4, _row$newCell$baseBloc, _row$newCell5, _row$newCell$blockTyp, _row$newCell6, _row$oldCell$baseBloc2, _row$oldCell5, _row$oldCell$blockTyp2, _row$oldCell6, _rendered$old, _rendered, _rendered$new, _rendered2;
57
+ var blockType = (_row$oldCell = row.oldCell) !== null && _row$oldCell !== void 0 && _row$oldCell.blockType && (_row$newCell = row.newCell) !== null && _row$newCell !== void 0 && _row$newCell.blockType ? row.oldCell.blockType === row.newCell.blockType ? row.oldCell.blockType : null : (_ref3 = (_row$oldCell$blockTyp = (_row$oldCell2 = row.oldCell) === null || _row$oldCell2 === void 0 ? void 0 : _row$oldCell2.blockType) !== null && _row$oldCell$blockTyp !== void 0 ? _row$oldCell$blockTyp : (_row$newCell2 = row.newCell) === null || _row$newCell2 === void 0 ? void 0 : _row$newCell2.blockType) !== null && _ref3 !== void 0 ? _ref3 : null;
58
+ var baseBlockType = (_row$oldCell3 = row.oldCell) !== null && _row$oldCell3 !== void 0 && _row$oldCell3.baseBlockType && (_row$newCell3 = row.newCell) !== null && _row$newCell3 !== void 0 && _row$newCell3.baseBlockType ? row.oldCell.baseBlockType === row.newCell.baseBlockType ? row.oldCell.baseBlockType : null : (_ref4 = (_row$oldCell$baseBloc = (_row$oldCell4 = row.oldCell) === null || _row$oldCell4 === void 0 ? void 0 : _row$oldCell4.baseBlockType) !== null && _row$oldCell$baseBloc !== void 0 ? _row$oldCell$baseBloc : (_row$newCell4 = row.newCell) === null || _row$newCell4 === void 0 ? void 0 : _row$newCell4.baseBlockType) !== null && _ref4 !== void 0 ? _ref4 : null;
59
+ var context = {
60
+ baseBlockType: baseBlockType,
61
+ blockType: blockType,
62
+ newBaseBlockType: (_row$newCell$baseBloc = (_row$newCell5 = row.newCell) === null || _row$newCell5 === void 0 ? void 0 : _row$newCell5.baseBlockType) !== null && _row$newCell$baseBloc !== void 0 ? _row$newCell$baseBloc : null,
63
+ newBlockType: (_row$newCell$blockTyp = (_row$newCell6 = row.newCell) === null || _row$newCell6 === void 0 ? void 0 : _row$newCell6.blockType) !== null && _row$newCell$blockTyp !== void 0 ? _row$newCell$blockTyp : null,
64
+ oldBaseBlockType: (_row$oldCell$baseBloc2 = (_row$oldCell5 = row.oldCell) === null || _row$oldCell5 === void 0 ? void 0 : _row$oldCell5.baseBlockType) !== null && _row$oldCell$baseBloc2 !== void 0 ? _row$oldCell$baseBloc2 : null,
65
+ oldBlockType: (_row$oldCell$blockTyp2 = (_row$oldCell6 = row.oldCell) === null || _row$oldCell6 === void 0 ? void 0 : _row$oldCell6.blockType) !== null && _row$oldCell$blockTyp2 !== void 0 ? _row$oldCell$blockTyp2 : null,
66
+ renderDefaultNew: function renderDefaultNew() {
67
+ var _row$newCell$block, _row$newCell7;
68
+ return renderDefaultCell((_row$newCell$block = (_row$newCell7 = row.newCell) === null || _row$newCell7 === void 0 ? void 0 : _row$newCell7.block) !== null && _row$newCell$block !== void 0 ? _row$newCell$block : null);
69
+ },
70
+ renderDefaultOld: function renderDefaultOld() {
71
+ var _row$oldCell$block, _row$oldCell7;
72
+ return renderDefaultCell((_row$oldCell$block = (_row$oldCell7 = row.oldCell) === null || _row$oldCell7 === void 0 ? void 0 : _row$oldCell7.block) !== null && _row$oldCell$block !== void 0 ? _row$oldCell$block : null);
73
+ },
74
+ row: row
75
+ };
76
+ var renderers = [blockType ? blockRenderers === null || blockRenderers === void 0 ? void 0 : blockRenderers[blockType] : undefined, baseBlockType && baseBlockType !== blockType ? blockRenderers === null || blockRenderers === void 0 ? void 0 : blockRenderers[baseBlockType] : undefined, renderBlockDiff];
77
+ var rendered;
78
+ for (var _i = 0, _renderers = renderers; _i < _renderers.length; _i++) {
79
+ var renderer = _renderers[_i];
80
+ if (!renderer) continue;
81
+ var next = renderer(context);
82
+ if (next === null) continue;
83
+ rendered = next;
84
+ break;
85
+ }
86
+ var oldContent = (_rendered$old = (_rendered = rendered) === null || _rendered === void 0 ? void 0 : _rendered.old) !== null && _rendered$old !== void 0 ? _rendered$old : context.renderDefaultOld();
87
+ var newContent = (_rendered$new = (_rendered2 = rendered) === null || _rendered2 === void 0 ? void 0 : _rendered2.new) !== null && _rendered$new !== void 0 ? _rendered$new : context.renderDefaultNew();
88
+ return /*#__PURE__*/_jsxs("div", {
89
+ className: styles.row,
90
+ children: [/*#__PURE__*/_jsx(RowCell, {
91
+ className: cx(styles.cell, styles.cellOld, !row.oldCell && styles.emptyCell, row.kind === 'delete' && styles.deleteCell),
92
+ content: oldContent
93
+ }), /*#__PURE__*/_jsx(RowCell, {
94
+ className: cx(styles.cell, !row.newCell && styles.emptyCell, row.kind === 'insert' && styles.insertCell),
95
+ content: newContent
96
+ })]
97
+ }, "row-".concat(index));
98
+ };
99
+ return /*#__PURE__*/_jsxs("div", {
100
+ className: cx(styles.root, className),
101
+ style: style,
102
+ children: [/*#__PURE__*/_jsxs("div", {
103
+ className: styles.header,
104
+ children: [/*#__PURE__*/_jsx("div", {
105
+ className: cx(styles.headerCell, styles.headerOld),
106
+ children: (_labels$old = labels === null || labels === void 0 ? void 0 : labels.old) !== null && _labels$old !== void 0 ? _labels$old : 'Old'
107
+ }), /*#__PURE__*/_jsx("div", {
108
+ className: styles.headerCell,
109
+ children: (_labels$new = labels === null || labels === void 0 ? void 0 : labels.new) !== null && _labels$new !== void 0 ? _labels$new : 'New'
110
+ })]
111
+ }), /*#__PURE__*/_jsx("div", {
112
+ className: styles.body,
113
+ children: rows.map(renderRow)
114
+ })]
115
+ });
116
+ }
@@ -0,0 +1,3 @@
1
+ import type { SerializedEditorState } from 'lexical';
2
+ import type { LexicalDiffRow } from './types';
3
+ export declare function computeLexicalDiffRows(oldState: SerializedEditorState, newState: SerializedEditorState): LexicalDiffRow[];
@@ -0,0 +1,510 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
3
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
7
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
8
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
9
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
10
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
11
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
12
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
13
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
14
+ var CHAR_DIFF_MAX_MATRIX_CELLS = 50000;
15
+ var DELETE_MARK_STYLE = 'background-color: color-mix(in srgb, var(--ant-color-error) 18%, transparent); text-decoration: line-through;';
16
+ var INSERT_MARK_STYLE = 'background-color: color-mix(in srgb, var(--ant-color-success) 18%, transparent);';
17
+ function getBaseNodeType(node) {
18
+ if (!node) return null;
19
+ var type = node.type;
20
+ return typeof type === 'string' ? type : null;
21
+ }
22
+ function getNormalizedBlockType(node) {
23
+ if (!node) return null;
24
+ var record = node;
25
+ var type = getBaseNodeType(node);
26
+ if (!type) return null;
27
+ if (type === 'heading') return "heading:".concat(String(record.tag || 'unknown'));
28
+ if (type === 'list') return "list:".concat(String(record.listType || 'bullet'));
29
+ return type;
30
+ }
31
+ function createCell(block) {
32
+ if (!block) return null;
33
+ return {
34
+ baseBlockType: getBaseNodeType(block),
35
+ block: block,
36
+ blockType: getNormalizedBlockType(block)
37
+ };
38
+ }
39
+ function getChildren(node) {
40
+ var children = node.children;
41
+ return Array.isArray(children) ? children : null;
42
+ }
43
+ function nodesEqual(a, b) {
44
+ return JSON.stringify(a) === JSON.stringify(b);
45
+ }
46
+ function isTextNode(node) {
47
+ var record = node;
48
+ return record.type === 'text' && typeof record.text === 'string';
49
+ }
50
+ function appendStyle(baseStyle, extraStyle) {
51
+ var normalizedBase = typeof baseStyle === 'string' ? baseStyle.trim() : '';
52
+ if (!normalizedBase) return extraStyle;
53
+ return "".concat(normalizedBase).concat(normalizedBase.endsWith(';') ? '' : ';', " ").concat(extraStyle);
54
+ }
55
+ function cloneTextNode(node, text, markKind) {
56
+ var style = node.style;
57
+ if (markKind === 'delete') {
58
+ style = appendStyle(style, DELETE_MARK_STYLE);
59
+ } else if (markKind === 'insert') {
60
+ style = appendStyle(style, INSERT_MARK_STYLE);
61
+ }
62
+ return _objectSpread(_objectSpread({}, node), {}, {
63
+ style: style,
64
+ text: text
65
+ });
66
+ }
67
+ function cloneNodeWithChildren(node, children) {
68
+ return _objectSpread(_objectSpread({}, node), {}, {
69
+ children: children
70
+ });
71
+ }
72
+ function decorateSubtree(node, kind) {
73
+ if (isTextNode(node)) return cloneTextNode(node, node.text, kind);
74
+ var children = getChildren(node);
75
+ if (!children) return node;
76
+ return cloneNodeWithChildren(node, children.map(function (child) {
77
+ return decorateSubtree(child, kind);
78
+ }));
79
+ }
80
+ function reverseText(value) {
81
+ return Array.from(value).reverse().join('');
82
+ }
83
+ function mergeTextOps(ops) {
84
+ var merged = [];
85
+ var _iterator = _createForOfIteratorHelper(ops),
86
+ _step;
87
+ try {
88
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
89
+ var op = _step.value;
90
+ if (!op.text) continue;
91
+ var last = merged.at(-1);
92
+ if (last && last.kind === op.kind) {
93
+ last.text += op.text;
94
+ continue;
95
+ }
96
+ merged.push(_objectSpread({}, op));
97
+ }
98
+ } catch (err) {
99
+ _iterator.e(err);
100
+ } finally {
101
+ _iterator.f();
102
+ }
103
+ return merged;
104
+ }
105
+ function diffMiddleChars(oldChars, newChars) {
106
+ var m = oldChars.length;
107
+ var n = newChars.length;
108
+ if (m === 0 && n === 0) return [];
109
+ if (m === 0) return [{
110
+ kind: 'insert',
111
+ text: newChars.join('')
112
+ }];
113
+ if (n === 0) return [{
114
+ kind: 'delete',
115
+ text: oldChars.join('')
116
+ }];
117
+ if (m * n > CHAR_DIFF_MAX_MATRIX_CELLS) {
118
+ return [{
119
+ kind: 'delete',
120
+ text: oldChars.join('')
121
+ }, {
122
+ kind: 'insert',
123
+ text: newChars.join('')
124
+ }];
125
+ }
126
+ var dp = Array.from({
127
+ length: m + 1
128
+ }, function () {
129
+ return Array.from({
130
+ length: n + 1
131
+ }).fill(0);
132
+ });
133
+ for (var _i = 1; _i <= m; _i++) {
134
+ for (var _j = 1; _j <= n; _j++) {
135
+ if (oldChars[_i - 1] === newChars[_j - 1]) {
136
+ dp[_i][_j] = dp[_i - 1][_j - 1] + 1;
137
+ } else {
138
+ dp[_i][_j] = Math.max(dp[_i - 1][_j], dp[_i][_j - 1]);
139
+ }
140
+ }
141
+ }
142
+ var reversedOps = [];
143
+ var i = m;
144
+ var j = n;
145
+ while (i > 0 && j > 0) {
146
+ if (oldChars[i - 1] === newChars[j - 1]) {
147
+ var last = reversedOps.at(-1);
148
+ if (last && last.kind === 'equal') {
149
+ last.text += oldChars[i - 1];
150
+ } else {
151
+ reversedOps.push({
152
+ kind: 'equal',
153
+ text: oldChars[i - 1]
154
+ });
155
+ }
156
+ i--;
157
+ j--;
158
+ continue;
159
+ }
160
+ if (dp[i - 1][j] >= dp[i][j - 1]) {
161
+ var _last = reversedOps.at(-1);
162
+ if (_last && _last.kind === 'delete') {
163
+ _last.text += oldChars[i - 1];
164
+ } else {
165
+ reversedOps.push({
166
+ kind: 'delete',
167
+ text: oldChars[i - 1]
168
+ });
169
+ }
170
+ i--;
171
+ } else {
172
+ var _last2 = reversedOps.at(-1);
173
+ if (_last2 && _last2.kind === 'insert') {
174
+ _last2.text += newChars[j - 1];
175
+ } else {
176
+ reversedOps.push({
177
+ kind: 'insert',
178
+ text: newChars[j - 1]
179
+ });
180
+ }
181
+ j--;
182
+ }
183
+ }
184
+ while (i > 0) {
185
+ var _last3 = reversedOps.at(-1);
186
+ if (_last3 && _last3.kind === 'delete') {
187
+ _last3.text += oldChars[i - 1];
188
+ } else {
189
+ reversedOps.push({
190
+ kind: 'delete',
191
+ text: oldChars[i - 1]
192
+ });
193
+ }
194
+ i--;
195
+ }
196
+ while (j > 0) {
197
+ var _last4 = reversedOps.at(-1);
198
+ if (_last4 && _last4.kind === 'insert') {
199
+ _last4.text += newChars[j - 1];
200
+ } else {
201
+ reversedOps.push({
202
+ kind: 'insert',
203
+ text: newChars[j - 1]
204
+ });
205
+ }
206
+ j--;
207
+ }
208
+ return mergeTextOps(reversedOps.reverse().map(function (op) {
209
+ return {
210
+ kind: op.kind,
211
+ text: reverseText(op.text)
212
+ };
213
+ }));
214
+ }
215
+ function diffTextByChar(oldText, newText) {
216
+ var oldChars = Array.from(oldText);
217
+ var newChars = Array.from(newText);
218
+ var prefix = 0;
219
+ while (prefix < oldChars.length && prefix < newChars.length && oldChars[prefix] === newChars[prefix]) {
220
+ prefix++;
221
+ }
222
+ var oldSuffix = oldChars.length - 1;
223
+ var newSuffix = newChars.length - 1;
224
+ while (oldSuffix >= prefix && newSuffix >= prefix && oldChars[oldSuffix] === newChars[newSuffix]) {
225
+ oldSuffix--;
226
+ newSuffix--;
227
+ }
228
+ var ops = [];
229
+ if (prefix > 0) {
230
+ ops.push({
231
+ kind: 'equal',
232
+ text: oldChars.slice(0, prefix).join('')
233
+ });
234
+ }
235
+ ops.push.apply(ops, _toConsumableArray(diffMiddleChars(oldChars.slice(prefix, oldSuffix + 1), newChars.slice(prefix, newSuffix + 1))));
236
+ if (oldSuffix < oldChars.length - 1) {
237
+ ops.push({
238
+ kind: 'equal',
239
+ text: oldChars.slice(oldSuffix + 1).join('')
240
+ });
241
+ }
242
+ return mergeTextOps(ops);
243
+ }
244
+ function splitTextNodeByCharDiff(oldNode, newNode) {
245
+ var ops = diffTextByChar(oldNode.text, newNode.text);
246
+ var oldNodes = [];
247
+ var newNodes = [];
248
+ var changed = false;
249
+ var _iterator2 = _createForOfIteratorHelper(ops),
250
+ _step2;
251
+ try {
252
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
253
+ var op = _step2.value;
254
+ if (!op.text) continue;
255
+ if (op.kind === 'equal') {
256
+ oldNodes.push(cloneTextNode(oldNode, op.text));
257
+ newNodes.push(cloneTextNode(newNode, op.text));
258
+ continue;
259
+ }
260
+ changed = true;
261
+ if (op.kind === 'delete') {
262
+ oldNodes.push(cloneTextNode(oldNode, op.text, 'delete'));
263
+ continue;
264
+ }
265
+ newNodes.push(cloneTextNode(newNode, op.text, 'insert'));
266
+ }
267
+ } catch (err) {
268
+ _iterator2.e(err);
269
+ } finally {
270
+ _iterator2.f();
271
+ }
272
+ return {
273
+ changed: changed,
274
+ newNodes: newNodes.length > 0 ? newNodes : [newNode],
275
+ oldNodes: oldNodes.length > 0 ? oldNodes : [oldNode]
276
+ };
277
+ }
278
+ function alignNodes(oldNodes, newNodes) {
279
+ var m = oldNodes.length;
280
+ var n = newNodes.length;
281
+ var dp = Array.from({
282
+ length: m + 1
283
+ }, function () {
284
+ return Array.from({
285
+ length: n + 1
286
+ }).fill(0);
287
+ });
288
+ for (var _i2 = 1; _i2 <= m; _i2++) {
289
+ for (var _j2 = 1; _j2 <= n; _j2++) {
290
+ var skip = Math.max(dp[_i2 - 1][_j2], dp[_i2][_j2 - 1]);
291
+ var oldType = getNormalizedBlockType(oldNodes[_i2 - 1]);
292
+ var newType = getNormalizedBlockType(newNodes[_j2 - 1]);
293
+ if (oldType && oldType === newType) {
294
+ var score = nodesEqual(oldNodes[_i2 - 1], newNodes[_j2 - 1]) ? 2 : 1;
295
+ dp[_i2][_j2] = Math.max(skip, dp[_i2 - 1][_j2 - 1] + score);
296
+ } else {
297
+ dp[_i2][_j2] = skip;
298
+ }
299
+ }
300
+ }
301
+ var ops = [];
302
+ var i = m;
303
+ var j = n;
304
+ while (i > 0 && j > 0) {
305
+ var _oldType = getNormalizedBlockType(oldNodes[i - 1]);
306
+ var _newType = getNormalizedBlockType(newNodes[j - 1]);
307
+ if (_oldType && _oldType === _newType) {
308
+ var exact = nodesEqual(oldNodes[i - 1], newNodes[j - 1]);
309
+ var _score = exact ? 2 : 1;
310
+ if (dp[i][j] === dp[i - 1][j - 1] + _score) {
311
+ ops.push(exact ? {
312
+ kind: 'equal',
313
+ node: oldNodes[i - 1]
314
+ } : {
315
+ kind: 'modify',
316
+ newNode: newNodes[j - 1],
317
+ oldNode: oldNodes[i - 1]
318
+ });
319
+ i--;
320
+ j--;
321
+ continue;
322
+ }
323
+ }
324
+ if (dp[i - 1][j] >= dp[i][j - 1]) {
325
+ ops.push({
326
+ kind: 'delete',
327
+ node: oldNodes[i - 1]
328
+ });
329
+ i--;
330
+ } else {
331
+ ops.push({
332
+ kind: 'insert',
333
+ node: newNodes[j - 1]
334
+ });
335
+ j--;
336
+ }
337
+ }
338
+ while (i > 0) {
339
+ ops.push({
340
+ kind: 'delete',
341
+ node: oldNodes[--i]
342
+ });
343
+ }
344
+ while (j > 0) {
345
+ ops.push({
346
+ kind: 'insert',
347
+ node: newNodes[--j]
348
+ });
349
+ }
350
+ return ops.reverse();
351
+ }
352
+ function diffChildrenInline(oldChildren, newChildren) {
353
+ var ops = alignNodes(oldChildren, newChildren);
354
+ var nextOldChildren = [];
355
+ var nextNewChildren = [];
356
+ var changed = false;
357
+ var _iterator3 = _createForOfIteratorHelper(ops),
358
+ _step3;
359
+ try {
360
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
361
+ var op = _step3.value;
362
+ switch (op.kind) {
363
+ case 'equal':
364
+ {
365
+ nextOldChildren.push(op.node);
366
+ nextNewChildren.push(op.node);
367
+ break;
368
+ }
369
+ case 'delete':
370
+ {
371
+ changed = true;
372
+ nextOldChildren.push(decorateSubtree(op.node, 'delete'));
373
+ break;
374
+ }
375
+ case 'insert':
376
+ {
377
+ changed = true;
378
+ nextNewChildren.push(decorateSubtree(op.node, 'insert'));
379
+ break;
380
+ }
381
+ case 'modify':
382
+ {
383
+ changed = true;
384
+ if (isTextNode(op.oldNode) && isTextNode(op.newNode)) {
385
+ var textDiff = splitTextNodeByCharDiff(op.oldNode, op.newNode);
386
+ nextOldChildren.push.apply(nextOldChildren, _toConsumableArray(textDiff.oldNodes));
387
+ nextNewChildren.push.apply(nextNewChildren, _toConsumableArray(textDiff.newNodes));
388
+ break;
389
+ }
390
+
391
+ // Recursive descent is intentional here: same-type element nodes diff their children.
392
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
393
+ var nested = diffNodeInline(op.oldNode, op.newNode);
394
+ nextOldChildren.push(nested.oldNode);
395
+ nextNewChildren.push(nested.newNode);
396
+ break;
397
+ }
398
+ }
399
+ }
400
+ } catch (err) {
401
+ _iterator3.e(err);
402
+ } finally {
403
+ _iterator3.f();
404
+ }
405
+ return {
406
+ changed: changed,
407
+ newChildren: nextNewChildren,
408
+ oldChildren: nextOldChildren
409
+ };
410
+ }
411
+ function diffNodeInline(oldNode, newNode) {
412
+ if (nodesEqual(oldNode, newNode)) {
413
+ return {
414
+ changed: false,
415
+ newNode: newNode,
416
+ oldNode: oldNode
417
+ };
418
+ }
419
+ var oldChildren = getChildren(oldNode);
420
+ var newChildren = getChildren(newNode);
421
+ if (!oldChildren || !newChildren) {
422
+ return {
423
+ changed: true,
424
+ newNode: newNode,
425
+ oldNode: oldNode
426
+ };
427
+ }
428
+ var childDiff = diffChildrenInline(oldChildren, newChildren);
429
+ if (!childDiff.changed) {
430
+ return {
431
+ changed: false,
432
+ newNode: newNode,
433
+ oldNode: oldNode
434
+ };
435
+ }
436
+ return {
437
+ changed: true,
438
+ newNode: cloneNodeWithChildren(newNode, childDiff.newChildren),
439
+ oldNode: cloneNodeWithChildren(oldNode, childDiff.oldChildren)
440
+ };
441
+ }
442
+ function getRootChildren(state) {
443
+ return Array.isArray(state.root.children) ? _toConsumableArray(state.root.children) : [];
444
+ }
445
+ export function computeLexicalDiffRows(oldState, newState) {
446
+ var ops = alignNodes(getRootChildren(oldState), getRootChildren(newState));
447
+ var rows = [];
448
+ var index = 0;
449
+ while (index < ops.length) {
450
+ var op = ops[index];
451
+ if (op.kind === 'equal') {
452
+ rows.push({
453
+ kind: 'equal',
454
+ newCell: createCell(op.node),
455
+ oldCell: createCell(op.node)
456
+ });
457
+ index++;
458
+ continue;
459
+ }
460
+ if (op.kind === 'modify') {
461
+ var diffed = diffNodeInline(op.oldNode, op.newNode);
462
+ rows.push({
463
+ kind: 'modify',
464
+ newCell: createCell(diffed.newNode),
465
+ oldCell: createCell(diffed.oldNode)
466
+ });
467
+ index++;
468
+ continue;
469
+ }
470
+ var deletes = [];
471
+ var inserts = [];
472
+ while (index < ops.length && (ops[index].kind === 'delete' || ops[index].kind === 'insert')) {
473
+ var current = ops[index];
474
+ if (current.kind === 'delete') {
475
+ deletes.push(current.node);
476
+ } else if (current.kind === 'insert') {
477
+ inserts.push(current.node);
478
+ }
479
+ index++;
480
+ }
481
+ var maxLength = Math.max(deletes.length, inserts.length);
482
+ for (var pairIndex = 0; pairIndex < maxLength; pairIndex++) {
483
+ var _deletes$pairIndex, _inserts$pairIndex;
484
+ var oldBlock = (_deletes$pairIndex = deletes[pairIndex]) !== null && _deletes$pairIndex !== void 0 ? _deletes$pairIndex : null;
485
+ var newBlock = (_inserts$pairIndex = inserts[pairIndex]) !== null && _inserts$pairIndex !== void 0 ? _inserts$pairIndex : null;
486
+ if (oldBlock && newBlock) {
487
+ rows.push({
488
+ kind: 'modify',
489
+ newCell: createCell(newBlock),
490
+ oldCell: createCell(oldBlock)
491
+ });
492
+ continue;
493
+ }
494
+ if (oldBlock) {
495
+ rows.push({
496
+ kind: 'delete',
497
+ newCell: null,
498
+ oldCell: createCell(oldBlock)
499
+ });
500
+ continue;
501
+ }
502
+ rows.push({
503
+ kind: 'insert',
504
+ newCell: createCell(newBlock),
505
+ oldCell: null
506
+ });
507
+ }
508
+ }
509
+ return rows;
510
+ }