@lobehub/editor 3.14.0 → 3.15.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/es/editor-kernel/kernel.d.ts +8 -2
- package/es/editor-kernel/kernel.js +155 -11
- package/es/index.d.ts +1 -0
- package/es/index.js +1 -0
- package/es/plugins/markdown/command/index.d.ts +5 -1
- package/es/plugins/markdown/command/index.js +53 -4
- package/es/plugins/markdown/index.d.ts +1 -1
- package/es/plugins/markdown/index.js +1 -1
- package/es/plugins/markdown/plugin/index.js +1 -1
- package/es/plugins/slash/plugin/index.js +2 -2
- package/es/plugins/table/plugin/index.js +24 -3
- package/es/types/kernel.d.ts +30 -1
- package/es/utils/scrollIntoView.d.ts +5 -0
- package/es/utils/scrollIntoView.js +45 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import { HistoryState } from '@lexical/history';
|
|
|
2
2
|
import EventEmitter from 'eventemitter3';
|
|
3
3
|
import { CommandListener, CommandListenerPriority, CommandPayloadType, LexicalCommand, LexicalEditor, LexicalNodeConfig } from 'lexical';
|
|
4
4
|
import { HotkeyId } from "../types/hotkey";
|
|
5
|
-
import { IDecorator, IEditor, IEditorKernel, IEditorPluginConstructor, IPlugin, IServiceID } from "../types/kernel";
|
|
5
|
+
import { IDecorator, IDocumentOptions, IEditor, IEditorKernel, IEditorPluginConstructor, IPlugin, ISelectionObject, IServiceID } from "../types/kernel";
|
|
6
6
|
import { ILocaleKeys } from "../types/locale";
|
|
7
7
|
import { HotkeyOptions, HotkeysEvent } from "../utils/hotkey/registerHotkey";
|
|
8
8
|
import DataSource from './data-source';
|
|
@@ -22,6 +22,7 @@ export declare class Kernel extends EventEmitter implements IEditorKernel {
|
|
|
22
22
|
private historyState;
|
|
23
23
|
private editor?;
|
|
24
24
|
constructor();
|
|
25
|
+
cloneNodeEditor(): IEditorKernel;
|
|
25
26
|
getHistoryState(): HistoryState;
|
|
26
27
|
isEditable(): boolean;
|
|
27
28
|
private detectDevelopmentMode;
|
|
@@ -40,7 +41,12 @@ export declare class Kernel extends EventEmitter implements IEditorKernel {
|
|
|
40
41
|
setRootElement(dom: HTMLElement, editable?: boolean): LexicalEditor;
|
|
41
42
|
setEditable(editable: boolean): void;
|
|
42
43
|
initNodeEditor(): LexicalEditor;
|
|
43
|
-
setDocument(type: string, content: any, options?:
|
|
44
|
+
setDocument(type: string, content: any, options?: IDocumentOptions): void;
|
|
45
|
+
setSelection(selection: ISelectionObject, opt?: {
|
|
46
|
+
collapseToEnd?: boolean;
|
|
47
|
+
collapseToStart?: boolean;
|
|
48
|
+
}): Promise<boolean>;
|
|
49
|
+
getSelection(): ISelectionObject | null;
|
|
44
50
|
focus(): void;
|
|
45
51
|
blur(): void;
|
|
46
52
|
getDocument(type: string): DataSource | undefined;
|
|
@@ -3,6 +3,10 @@ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread n
|
|
|
3
3
|
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
|
|
4
4
|
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
|
|
5
5
|
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); }
|
|
6
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
7
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
8
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
9
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
6
10
|
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
11
|
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
12
|
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; }
|
|
@@ -20,16 +24,17 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
|
|
|
20
24
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
21
25
|
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); }
|
|
22
26
|
import { createEmptyHistoryState } from '@lexical/history';
|
|
27
|
+
import { $createTableSelection, $isTableNode, $isTableSelection } from '@lexical/table';
|
|
23
28
|
import { get, merge, template, templateSettings } from 'es-toolkit/compat';
|
|
24
29
|
import EventEmitter from 'eventemitter3';
|
|
25
|
-
import { $getSelection, $isRangeSelection, COMMAND_PRIORITY_CRITICAL, KEY_DOWN_COMMAND, createEditor } from 'lexical';
|
|
30
|
+
import { $createNodeSelection, $createRangeSelection, $getNodeByKey, $getSelection, $isElementNode, $isNodeSelection, $isRangeSelection, $setSelection, COMMAND_PRIORITY_CRITICAL, KEY_DOWN_COMMAND, createEditor } from 'lexical';
|
|
26
31
|
import defaultLocale from "../locale";
|
|
27
32
|
import { $isRootTextContentEmpty } from "../plugins/common/utils";
|
|
28
33
|
import { createDebugLogger } from "../utils/debug";
|
|
29
34
|
import { getHotkeyById, registerHotkey as _registerHotkey } from "../utils/hotkey/registerHotkey";
|
|
30
35
|
import { registerEvent } from "./event";
|
|
31
36
|
import { KernelPlugin } from "./plugin";
|
|
32
|
-
import { EDITOR_THEME_KEY, createEmptyEditorState, generateEditorId, noop, registerEditorKernel, unregisterEditorKernel } from "./utils";
|
|
37
|
+
import { $closest, EDITOR_THEME_KEY, createEmptyEditorState, generateEditorId, noop, registerEditorKernel, unregisterEditorKernel } from "./utils";
|
|
33
38
|
templateSettings.interpolate = /{{([\S\s]+?)}}/g;
|
|
34
39
|
export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
35
40
|
_inherits(Kernel, _EventEmitter);
|
|
@@ -61,6 +66,17 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
61
66
|
return _this;
|
|
62
67
|
}
|
|
63
68
|
_createClass(Kernel, [{
|
|
69
|
+
key: "cloneNodeEditor",
|
|
70
|
+
value: function cloneNodeEditor() {
|
|
71
|
+
var newKernel = new Kernel();
|
|
72
|
+
newKernel.registerPlugins(this.plugins);
|
|
73
|
+
newKernel.initNodeEditor();
|
|
74
|
+
newKernel.setDocument('json', this.getDocument('json') || '{}', {
|
|
75
|
+
keepId: true
|
|
76
|
+
});
|
|
77
|
+
return newKernel;
|
|
78
|
+
}
|
|
79
|
+
}, {
|
|
64
80
|
key: "getHistoryState",
|
|
65
81
|
value: function getHistoryState() {
|
|
66
82
|
return this.historyState;
|
|
@@ -271,13 +287,141 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
271
287
|
this.logger.error('❌ Editor not initialized');
|
|
272
288
|
throw new Error("Editor is not initialized.");
|
|
273
289
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
290
|
+
// Clear history if not keeping history
|
|
291
|
+
if (!(options !== null && options !== void 0 && options.keepHistory)) {
|
|
292
|
+
this.historyState.redoStack = [];
|
|
293
|
+
this.historyState.undoStack = [];
|
|
294
|
+
this.historyState.current = null;
|
|
295
|
+
}
|
|
277
296
|
datasource.read(this.editor, content, options);
|
|
278
297
|
this.emit('documentChange', type, content);
|
|
279
298
|
this.logger.debug("\uD83D\uDCE5 Set ".concat(type, " document"));
|
|
280
299
|
}
|
|
300
|
+
}, {
|
|
301
|
+
key: "setSelection",
|
|
302
|
+
value: function setSelection(selection, opt) {
|
|
303
|
+
var _this4 = this;
|
|
304
|
+
if (!this.editor) {
|
|
305
|
+
this.logger.error('❌ Editor not initialized');
|
|
306
|
+
throw new Error("Editor is not initialized.");
|
|
307
|
+
}
|
|
308
|
+
var editor = this.editor;
|
|
309
|
+
return new Promise(function (resolve) {
|
|
310
|
+
editor.update(function () {
|
|
311
|
+
try {
|
|
312
|
+
if (selection.type === 'range') {
|
|
313
|
+
var startNodeId = opt !== null && opt !== void 0 && opt.collapseToEnd ? selection.endNodeId : selection.startNodeId;
|
|
314
|
+
var endNodeId = opt !== null && opt !== void 0 && opt.collapseToStart ? selection.startNodeId : selection.endNodeId;
|
|
315
|
+
var startOffset = opt !== null && opt !== void 0 && opt.collapseToEnd ? selection.endOffset : selection.startOffset;
|
|
316
|
+
var endOffset = opt !== null && opt !== void 0 && opt.collapseToStart ? selection.startOffset : selection.endOffset;
|
|
317
|
+
var anchorNode = $getNodeByKey(startNodeId);
|
|
318
|
+
var focusNode = $getNodeByKey(endNodeId);
|
|
319
|
+
if (!anchorNode || !focusNode) {
|
|
320
|
+
_this4.logger.error('❌ Nodes for selection not found');
|
|
321
|
+
resolve(false);
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
var rng = $createRangeSelection();
|
|
325
|
+
rng.anchor.set(anchorNode.getKey(), startOffset, $isElementNode(anchorNode) ? 'element' : 'text');
|
|
326
|
+
rng.focus.set(focusNode.getKey(), endOffset, $isElementNode(focusNode) ? 'element' : 'text');
|
|
327
|
+
$setSelection(rng);
|
|
328
|
+
resolve(true);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
if (selection.type === 'node') {
|
|
332
|
+
var node = $getNodeByKey(selection.startNodeId);
|
|
333
|
+
if (!node) {
|
|
334
|
+
_this4.logger.error('❌ Node for selection not found');
|
|
335
|
+
resolve(false);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
var nodeSel = $createNodeSelection();
|
|
339
|
+
nodeSel.add(selection.startNodeId);
|
|
340
|
+
$setSelection(nodeSel);
|
|
341
|
+
resolve(true);
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (selection.type === 'table') {
|
|
345
|
+
var startNode = $getNodeByKey(selection.startNodeId);
|
|
346
|
+
if (!startNode) {
|
|
347
|
+
_this4.logger.error('❌ Node for selection not found');
|
|
348
|
+
resolve(false);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
var endNode = $getNodeByKey(selection.endNodeId);
|
|
352
|
+
if (!endNode) {
|
|
353
|
+
_this4.logger.error('❌ Node for selection not found');
|
|
354
|
+
resolve(false);
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
var table1 = $closest(startNode, function (n) {
|
|
358
|
+
return $isTableNode(n);
|
|
359
|
+
});
|
|
360
|
+
var table2 = $closest(endNode, function (n) {
|
|
361
|
+
return $isTableNode(n);
|
|
362
|
+
});
|
|
363
|
+
if (!table1 || !table2 || table1 !== table2) {
|
|
364
|
+
_this4.logger.error('❌ Table nodes for selection not found or do not match');
|
|
365
|
+
resolve(false);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
var _rng = $createTableSelection();
|
|
369
|
+
_rng.set(table1.getKey(), selection.startNodeId, selection.endNodeId);
|
|
370
|
+
$setSelection(_rng);
|
|
371
|
+
resolve(true);
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
resolve(false);
|
|
375
|
+
} catch (error) {
|
|
376
|
+
_this4.logger.error('❌ Error setting selection:', error);
|
|
377
|
+
resolve(false);
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
}, {
|
|
383
|
+
key: "getSelection",
|
|
384
|
+
value: function getSelection() {
|
|
385
|
+
if (!this.editor) {
|
|
386
|
+
this.logger.error('❌ Editor not initialized');
|
|
387
|
+
throw new Error("Editor is not initialized.");
|
|
388
|
+
}
|
|
389
|
+
return this.editor.read(function () {
|
|
390
|
+
var selection = $getSelection();
|
|
391
|
+
if ($isRangeSelection(selection)) {
|
|
392
|
+
return {
|
|
393
|
+
endNodeId: selection.focus.getNode().getKey(),
|
|
394
|
+
endOffset: selection.focus.offset,
|
|
395
|
+
startNodeId: selection.anchor.getNode().getKey(),
|
|
396
|
+
startOffset: selection.anchor.offset,
|
|
397
|
+
type: 'range'
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
if ($isNodeSelection(selection)) {
|
|
401
|
+
return {
|
|
402
|
+
endNodeId: selection.getNodes()[0].getKey(),
|
|
403
|
+
endOffset: 0,
|
|
404
|
+
startNodeId: selection.getNodes()[0].getKey(),
|
|
405
|
+
startOffset: 0,
|
|
406
|
+
type: 'node'
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
if ($isTableSelection(selection)) {
|
|
410
|
+
var _selection$getStartEn = selection.getStartEndPoints(),
|
|
411
|
+
_selection$getStartEn2 = _slicedToArray(_selection$getStartEn, 2),
|
|
412
|
+
start = _selection$getStartEn2[0],
|
|
413
|
+
end = _selection$getStartEn2[1];
|
|
414
|
+
return {
|
|
415
|
+
endNodeId: end.getNode().getKey(),
|
|
416
|
+
endOffset: end.offset,
|
|
417
|
+
startNodeId: start.getNode().getKey(),
|
|
418
|
+
startOffset: start.offset,
|
|
419
|
+
type: 'table'
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
return null;
|
|
423
|
+
});
|
|
424
|
+
}
|
|
281
425
|
}, {
|
|
282
426
|
key: "focus",
|
|
283
427
|
value: function focus() {
|
|
@@ -608,12 +752,12 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
608
752
|
}, {
|
|
609
753
|
key: "isEmpty",
|
|
610
754
|
get: function get() {
|
|
611
|
-
var
|
|
755
|
+
var _this5 = this;
|
|
612
756
|
if (!this.editor) {
|
|
613
757
|
return true;
|
|
614
758
|
}
|
|
615
759
|
return this.editor.getEditorState().read(function () {
|
|
616
|
-
return $isRootTextContentEmpty(
|
|
760
|
+
return $isRootTextContentEmpty(_this5.editor.isComposing(), true);
|
|
617
761
|
});
|
|
618
762
|
}
|
|
619
763
|
}, {
|
|
@@ -656,7 +800,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
656
800
|
}, {
|
|
657
801
|
key: "registerHighCommand",
|
|
658
802
|
value: function registerHighCommand(command, listener, priority) {
|
|
659
|
-
var
|
|
803
|
+
var _this6 = this;
|
|
660
804
|
var lexicalEditor = this.editor;
|
|
661
805
|
if (!lexicalEditor) {
|
|
662
806
|
throw new Error('Editor is not initialized.');
|
|
@@ -667,7 +811,7 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
667
811
|
commandsMap.set(command, [new Set(), new Set(), new Set(), new Set(), new Set()]);
|
|
668
812
|
this._commandsClean.set(command, lexicalEditor.registerCommand(command, function (payload) {
|
|
669
813
|
for (var i = 4; i >= 0; i--) {
|
|
670
|
-
var listenerInPriorityOrder =
|
|
814
|
+
var listenerInPriorityOrder = _this6._commands.get(command);
|
|
671
815
|
if (listenerInPriorityOrder !== undefined) {
|
|
672
816
|
var listenersSet = listenerInPriorityOrder[i];
|
|
673
817
|
var _iterator5 = _createForOfIteratorHelper(listenersSet),
|
|
@@ -704,9 +848,9 @@ export var Kernel = /*#__PURE__*/function (_EventEmitter) {
|
|
|
704
848
|
if (listenersInPriorityOrder.every(function (listenersSet) {
|
|
705
849
|
return listenersSet.size === 0;
|
|
706
850
|
})) {
|
|
707
|
-
var
|
|
851
|
+
var _this6$_commandsClean;
|
|
708
852
|
commandsMap.delete(command);
|
|
709
|
-
(
|
|
853
|
+
(_this6$_commandsClean = _this6._commandsClean.get(command)) === null || _this6$_commandsClean === void 0 || _this6$_commandsClean();
|
|
710
854
|
}
|
|
711
855
|
};
|
|
712
856
|
}
|
package/es/index.d.ts
CHANGED
|
@@ -27,6 +27,7 @@ export { getHotkeyById } from './utils/hotkey/registerHotkey';
|
|
|
27
27
|
export { isPureUrl, isValidUrl } from './utils/url';
|
|
28
28
|
export { browserDebug, createDebugLogger, debugLogger, debugLoggers, devConsole, prodSafeLogger, } from './utils/debug';
|
|
29
29
|
export { Kernel } from './editor-kernel/kernel';
|
|
30
|
+
export { scrollIntoView } from './utils/scrollIntoView';
|
|
30
31
|
/**
|
|
31
32
|
* Enable hot reload mode globally for all editor instances
|
|
32
33
|
* Call this in your app's entry point during development
|
package/es/index.js
CHANGED
|
@@ -33,6 +33,7 @@ export { browserDebug, createDebugLogger, debugLogger, debugLoggers, devConsole,
|
|
|
33
33
|
|
|
34
34
|
// Hot reload utilities
|
|
35
35
|
export { Kernel } from "./editor-kernel/kernel";
|
|
36
|
+
export { scrollIntoView } from "./utils/scrollIntoView";
|
|
36
37
|
|
|
37
38
|
/**
|
|
38
39
|
* Enable hot reload mode globally for all editor instances
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { HistoryState, HistoryStateEntry } from '@lexical/history';
|
|
2
2
|
import { LexicalEditor } from 'lexical';
|
|
3
|
+
import { IEditorKernel } from "../../../types";
|
|
3
4
|
import { MarkdownShortCutService } from '../service/shortcut';
|
|
4
5
|
export declare const INSERT_MARKDOWN_COMMAND: import("lexical").LexicalCommand<{
|
|
5
6
|
historyState: HistoryStateEntry | null;
|
|
6
7
|
markdown: string;
|
|
7
8
|
}>;
|
|
8
|
-
export declare
|
|
9
|
+
export declare const GET_MARKDOWN_SELECTION_COMMAND: import("lexical").LexicalCommand<{
|
|
10
|
+
onResult: (startLine: number, endLine: number) => void;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function registerMarkdownCommand(editor: LexicalEditor, kernel: IEditorKernel, service: MarkdownShortCutService, history: HistoryState): () => void;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mergeRegister } from '@lexical/utils';
|
|
2
|
+
import { $getSelection, $isRangeSelection, CAN_UNDO_COMMAND, COMMAND_PRIORITY_HIGH, HISTORIC_TAG, createCommand } from 'lexical';
|
|
2
3
|
import { createDebugLogger } from "../../../utils/debug";
|
|
3
4
|
import { parseMarkdownToLexical } from "../data-source/markdown/parse";
|
|
4
5
|
import { $generateNodesFromSerializedNodes, $insertGeneratedNodes } from "../utils";
|
|
5
6
|
var logger = createDebugLogger('plugin', 'markdown');
|
|
6
7
|
export var INSERT_MARKDOWN_COMMAND = createCommand('INSERT_MARKDOWN_COMMAND');
|
|
8
|
+
export var GET_MARKDOWN_SELECTION_COMMAND = createCommand('GET_MARKDOWN_SELECTION_COMMAND');
|
|
7
9
|
function undoToEntry(editor, historyState, entry) {
|
|
8
10
|
var undoStack = historyState.undoStack;
|
|
9
11
|
var current = historyState.current;
|
|
@@ -19,8 +21,12 @@ function undoToEntry(editor, historyState, entry) {
|
|
|
19
21
|
}
|
|
20
22
|
return editor.getEditorState();
|
|
21
23
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
var SPICAL_TEXT = "\uFFF0";
|
|
25
|
+
var getLineNumber = function getLineNumber(content, charIndex) {
|
|
26
|
+
return content.slice(0, Math.max(0, charIndex)).split('\n').length;
|
|
27
|
+
};
|
|
28
|
+
export function registerMarkdownCommand(editor, kernel, service, history) {
|
|
29
|
+
return mergeRegister(editor.registerCommand(INSERT_MARKDOWN_COMMAND, function (payload) {
|
|
24
30
|
var markdown = payload.markdown;
|
|
25
31
|
logger.debug('INSERT_MARKDOWN_COMMAND payload:', payload);
|
|
26
32
|
undoToEntry(editor, history, payload.historyState);
|
|
@@ -41,5 +47,48 @@ export function registerMarkdownCommand(editor, service, history) {
|
|
|
41
47
|
});
|
|
42
48
|
return false;
|
|
43
49
|
}, COMMAND_PRIORITY_HIGH // Priority
|
|
44
|
-
)
|
|
50
|
+
), editor.registerCommand(GET_MARKDOWN_SELECTION_COMMAND, function (payload) {
|
|
51
|
+
var newEditor = kernel.cloneNodeEditor();
|
|
52
|
+
var s = kernel.getSelection();
|
|
53
|
+
if (s) {
|
|
54
|
+
var _newEditor$getLexical;
|
|
55
|
+
newEditor.setSelection(s);
|
|
56
|
+
(_newEditor$getLexical = newEditor.getLexicalEditor()) === null || _newEditor$getLexical === void 0 || _newEditor$getLexical.update(function () {
|
|
57
|
+
var sel = $getSelection();
|
|
58
|
+
if (!sel) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if ($isRangeSelection(sel)) {
|
|
62
|
+
var _sel$anchor = sel.anchor,
|
|
63
|
+
anchorKey = _sel$anchor.key,
|
|
64
|
+
anchorOffset = _sel$anchor.offset,
|
|
65
|
+
anchorType = _sel$anchor.type;
|
|
66
|
+
var _sel$focus = sel.focus,
|
|
67
|
+
focusKey = _sel$focus.key,
|
|
68
|
+
focusOffset = _sel$focus.offset,
|
|
69
|
+
focusType = _sel$focus.type;
|
|
70
|
+
var newRang = sel.clone();
|
|
71
|
+
newRang.anchor.set(anchorKey, anchorOffset, anchorType);
|
|
72
|
+
newRang.focus.set(anchorKey, anchorOffset, anchorType);
|
|
73
|
+
newRang.insertText(SPICAL_TEXT);
|
|
74
|
+
newRang.focus.set(focusKey, focusOffset, focusType);
|
|
75
|
+
newRang.anchor.set(focusKey, focusOffset, focusType);
|
|
76
|
+
newRang.insertText(SPICAL_TEXT);
|
|
77
|
+
}
|
|
78
|
+
}, {
|
|
79
|
+
onUpdate: function onUpdate() {
|
|
80
|
+
var markdownContent = newEditor.getDocument('markdown');
|
|
81
|
+
var startIndex = markdownContent.indexOf(SPICAL_TEXT);
|
|
82
|
+
var endIndex = markdownContent.lastIndexOf(SPICAL_TEXT);
|
|
83
|
+
var startLine = getLineNumber(markdownContent, startIndex);
|
|
84
|
+
var endLine = getLineNumber(markdownContent, endIndex);
|
|
85
|
+
payload.onResult(startLine, endLine);
|
|
86
|
+
logger.debug('GET_MARKDOWN_SELECTION_COMMAND markdownContent:', markdownContent);
|
|
87
|
+
logger.debug('GET_MARKDOWN_SELECTION_COMMAND startLine:', startLine, 'endLine:', endLine);
|
|
88
|
+
return markdownContent;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return false;
|
|
93
|
+
}, COMMAND_PRIORITY_HIGH));
|
|
45
94
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { INSERT_MARKDOWN_COMMAND } from './command';
|
|
1
|
+
export { GET_MARKDOWN_SELECTION_COMMAND, INSERT_MARKDOWN_COMMAND } from './command';
|
|
2
2
|
export { MarkdownPlugin } from './plugin';
|
|
3
3
|
export { default as ReactMarkdownPlugin } from './react';
|
|
4
4
|
export type { MARKDOWN_READER_LEVEL } from './service/shortcut';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { INSERT_MARKDOWN_COMMAND } from "./command";
|
|
1
|
+
export { GET_MARKDOWN_SELECTION_COMMAND, INSERT_MARKDOWN_COMMAND } from "./command";
|
|
2
2
|
export { MarkdownPlugin } from "./plugin";
|
|
3
3
|
export { default as ReactMarkdownPlugin } from "./react";
|
|
4
4
|
export { IMarkdownShortCutService, MARKDOWN_READER_LEVEL_HIGH, MARKDOWN_READER_LEVEL_NORMAL, MARKDOWN_WRITER_LEVEL_MAX } from "./service/shortcut";
|
|
@@ -159,7 +159,7 @@ export var MarkdownPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
159
159
|
}
|
|
160
160
|
return false;
|
|
161
161
|
}, COMMAND_PRIORITY_CRITICAL));
|
|
162
|
-
this.register(registerMarkdownCommand(editor, this.service, this.kernel.getHistoryState()));
|
|
162
|
+
this.register(registerMarkdownCommand(editor, this.kernel, this.service, this.kernel.getHistoryState()));
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
/**
|
|
@@ -44,8 +44,8 @@ export var SlashPlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
44
44
|
_createClass(SlashPlugin, [{
|
|
45
45
|
key: "triggerClose",
|
|
46
46
|
value: function triggerClose() {
|
|
47
|
-
var _this$config;
|
|
48
|
-
(_this$config = this.config) === null || _this$config === void 0 || _this$config.triggerClose();
|
|
47
|
+
var _this$config, _this$config$triggerC;
|
|
48
|
+
(_this$config = this.config) === null || _this$config === void 0 || (_this$config$triggerC = _this$config.triggerClose) === null || _this$config$triggerC === void 0 || _this$config$triggerC.call(_this$config);
|
|
49
49
|
this.currentSlashTrigger = null;
|
|
50
50
|
this.currentSlashTriggerIndex = -1;
|
|
51
51
|
// After an explicit close, suppress reopening until next typing input
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
var _class;
|
|
2
2
|
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); }
|
|
3
|
+
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; } } }; }
|
|
4
|
+
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); }
|
|
5
|
+
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; }
|
|
3
6
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
4
7
|
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
|
|
5
8
|
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
@@ -103,10 +106,26 @@ export var TablePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
103
106
|
var colWidths = colWidthsAttr ? colWidthsAttr.split(',').map(function (width) {
|
|
104
107
|
return parseInt(width, 10);
|
|
105
108
|
}) : [];
|
|
109
|
+
var maxTdlen = 1;
|
|
110
|
+
var _iterator = _createForOfIteratorHelper(children),
|
|
111
|
+
_step;
|
|
112
|
+
try {
|
|
113
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
114
|
+
var _child$children;
|
|
115
|
+
var child = _step.value;
|
|
116
|
+
if ((((_child$children = child.children) === null || _child$children === void 0 ? void 0 : _child$children.length) || -1) > maxTdlen) {
|
|
117
|
+
maxTdlen = child.children.length;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
} catch (err) {
|
|
121
|
+
_iterator.e(err);
|
|
122
|
+
} finally {
|
|
123
|
+
_iterator.f();
|
|
124
|
+
}
|
|
106
125
|
return INodeHelper.createElementNode(TableNode.getType(), {
|
|
107
126
|
children: children,
|
|
108
127
|
// eslint-disable-next-line unicorn/no-new-array
|
|
109
|
-
colWidths: colWidths.length > 0 ? colWidths :
|
|
128
|
+
colWidths: colWidths.length > 0 ? colWidths : new Array(maxTdlen).fill(750 / maxTdlen),
|
|
110
129
|
direction: null,
|
|
111
130
|
format: '',
|
|
112
131
|
indent: 0,
|
|
@@ -123,7 +142,7 @@ export var TablePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
123
142
|
version: 1
|
|
124
143
|
});
|
|
125
144
|
});
|
|
126
|
-
|
|
145
|
+
var tdReader = function tdReader(xmlNode, children) {
|
|
127
146
|
return INodeHelper.createElementNode(TableCellNode.getType(), {
|
|
128
147
|
backgroundColor: xmlNode.getAttribute('backgroundColor') || null,
|
|
129
148
|
children: children,
|
|
@@ -135,7 +154,9 @@ export var TablePlugin = (_class = /*#__PURE__*/function (_KernelPlugin) {
|
|
|
135
154
|
rowSpan: xmlNode.getAttribute('rowSpan') ? parseInt(xmlNode.getAttribute('rowSpan'), 10) : 1,
|
|
136
155
|
version: 1
|
|
137
156
|
});
|
|
138
|
-
}
|
|
157
|
+
};
|
|
158
|
+
litexmlService.registerXMLReader('th', tdReader);
|
|
159
|
+
litexmlService.registerXMLReader('td', tdReader);
|
|
139
160
|
}
|
|
140
161
|
}, {
|
|
141
162
|
key: "registerMarkdown",
|
package/es/types/kernel.d.ts
CHANGED
|
@@ -18,6 +18,19 @@ export type IServiceID<Service> = {
|
|
|
18
18
|
readonly __serviceId: string;
|
|
19
19
|
__serviceType?: Service;
|
|
20
20
|
};
|
|
21
|
+
export interface ISelectionObject {
|
|
22
|
+
endNodeId: string;
|
|
23
|
+
endOffset: number;
|
|
24
|
+
startNodeId: string;
|
|
25
|
+
startOffset: number;
|
|
26
|
+
type: 'range' | 'node' | 'table';
|
|
27
|
+
}
|
|
28
|
+
export interface IDocumentOptions {
|
|
29
|
+
[key: string]: unknown;
|
|
30
|
+
keepHistory?: boolean;
|
|
31
|
+
/** only work for json datasource */
|
|
32
|
+
keepId?: boolean;
|
|
33
|
+
}
|
|
21
34
|
export interface IKernelEventMap {
|
|
22
35
|
/**
|
|
23
36
|
* Document change event
|
|
@@ -88,6 +101,10 @@ export interface IEditor {
|
|
|
88
101
|
* Get document editor root node
|
|
89
102
|
*/
|
|
90
103
|
getRootElement(): HTMLElement | null;
|
|
104
|
+
/**
|
|
105
|
+
* Get editor selection information
|
|
106
|
+
*/
|
|
107
|
+
getSelection(): ISelectionObject | null;
|
|
91
108
|
/**
|
|
92
109
|
* Get document editor selection content of specified type
|
|
93
110
|
* @param type
|
|
@@ -186,7 +203,7 @@ export interface IEditor {
|
|
|
186
203
|
* @param type
|
|
187
204
|
* @param content
|
|
188
205
|
*/
|
|
189
|
-
setDocument(type: string, content: any, options?:
|
|
206
|
+
setDocument(type: string, content: any, options?: IDocumentOptions): void;
|
|
190
207
|
/**
|
|
191
208
|
* Enable or disable editor editing capability
|
|
192
209
|
* @param editable
|
|
@@ -197,6 +214,14 @@ export interface IEditor {
|
|
|
197
214
|
* @param dom
|
|
198
215
|
*/
|
|
199
216
|
setRootElement(dom: HTMLElement, editable?: boolean): LexicalEditor;
|
|
217
|
+
/**
|
|
218
|
+
* set editor selection
|
|
219
|
+
* @param selection
|
|
220
|
+
*/
|
|
221
|
+
setSelection(selection: ISelectionObject, opt?: {
|
|
222
|
+
collapseToEnd?: boolean;
|
|
223
|
+
collapseToStart?: boolean;
|
|
224
|
+
}): Promise<boolean>;
|
|
200
225
|
/**
|
|
201
226
|
* Get translation text
|
|
202
227
|
* @param key Translation key
|
|
@@ -214,6 +239,10 @@ export interface IEditor {
|
|
|
214
239
|
* API provided to plugins
|
|
215
240
|
*/
|
|
216
241
|
export interface IEditorKernel extends IEditor {
|
|
242
|
+
/**
|
|
243
|
+
* Clone the current editor kernel instance
|
|
244
|
+
*/
|
|
245
|
+
cloneNodeEditor(): IEditorKernel;
|
|
217
246
|
emit<T extends keyof IKernelEventMap>(event: T, params: Parameters<IKernelEventMap[T]>[0]): void;
|
|
218
247
|
/**
|
|
219
248
|
* Get editor Node decorator for specific Node rendering
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scroll the current selection into view, centered vertically in the viewport
|
|
3
|
+
* @param offsetY Optional vertical offset from center (default: 0)
|
|
4
|
+
*/
|
|
5
|
+
export function scrollIntoView() {
|
|
6
|
+
var offsetY = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
7
|
+
// Skip on server side
|
|
8
|
+
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
var selection = window.getSelection();
|
|
12
|
+
if (!selection || selection.rangeCount === 0) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
var range = selection.getRangeAt(0);
|
|
16
|
+
var rect = range.getBoundingClientRect();
|
|
17
|
+
|
|
18
|
+
// If selection has no visible rect, try to get it from the focus node
|
|
19
|
+
if (rect.height === 0 && rect.width === 0) {
|
|
20
|
+
var focusNode = selection.focusNode;
|
|
21
|
+
if (focusNode) {
|
|
22
|
+
var element = focusNode.nodeType === Node.ELEMENT_NODE ? focusNode : focusNode.parentElement;
|
|
23
|
+
if (element) {
|
|
24
|
+
element.scrollIntoView({
|
|
25
|
+
behavior: 'smooth',
|
|
26
|
+
block: 'center'
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Calculate the center position of the selection
|
|
34
|
+
var selectionCenter = rect.top + rect.height / 2;
|
|
35
|
+
var viewportCenter = window.innerHeight / 2;
|
|
36
|
+
|
|
37
|
+
// Calculate scroll amount needed to center the selection
|
|
38
|
+
var scrollAmount = selectionCenter - viewportCenter + offsetY;
|
|
39
|
+
|
|
40
|
+
// Perform smooth scroll
|
|
41
|
+
window.scrollBy({
|
|
42
|
+
behavior: 'smooth',
|
|
43
|
+
top: scrollAmount
|
|
44
|
+
});
|
|
45
|
+
}
|
package/package.json
CHANGED