@lobehub/editor 1.19.0 → 1.20.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/index.d.ts +2 -0
- package/es/index.js +4 -0
- package/es/plugins/code/node/code.d.ts +1 -1
- package/es/plugins/code/node/code.js +1 -1
- package/es/plugins/code/react/CodeReactPlugin.js +1 -1
- package/es/plugins/codeblock/plugin/index.js +1 -1
- package/es/plugins/codeblock/react/ReactCodeblockPlugin.js +1 -1
- package/es/plugins/common/plugin/index.js +2 -1
- package/es/plugins/common/plugin/mdReader.d.ts +1 -1
- package/es/plugins/common/react/ReactPlainText.js +1 -1
- package/es/plugins/file/plugin/index.js +1 -1
- package/es/plugins/hr/plugin/index.js +1 -1
- package/es/plugins/hr/react/ReactHRPlugin.js +1 -1
- package/es/plugins/link/plugin/index.js +1 -1
- package/es/plugins/link/react/ReactLinkPlugin.js +1 -1
- package/es/plugins/link-highlight/command/index.d.ts +3 -0
- package/es/plugins/link-highlight/command/index.js +46 -0
- package/es/plugins/link-highlight/index.d.ts +4 -0
- package/es/plugins/link-highlight/index.js +5 -0
- package/es/plugins/link-highlight/node/link-highlight.d.ts +29 -0
- package/es/plugins/link-highlight/node/link-highlight.js +223 -0
- package/es/plugins/link-highlight/plugin/index.d.ts +15 -0
- package/es/plugins/link-highlight/plugin/index.js +187 -0
- package/es/plugins/link-highlight/plugin/registry.d.ts +6 -0
- package/es/plugins/link-highlight/plugin/registry.js +61 -0
- package/es/plugins/link-highlight/react/ReactLinkHighlightPlugin.d.ts +4 -0
- package/es/plugins/link-highlight/react/ReactLinkHighlightPlugin.js +35 -0
- package/es/plugins/link-highlight/react/index.d.ts +1 -0
- package/es/plugins/link-highlight/react/index.js +1 -0
- package/es/plugins/link-highlight/react/style.d.ts +3 -0
- package/es/plugins/link-highlight/react/style.js +10 -0
- package/es/plugins/link-highlight/react/type.d.ts +13 -0
- package/es/plugins/link-highlight/react/type.js +1 -0
- package/es/plugins/link-highlight/utils/index.d.ts +17 -0
- package/es/plugins/link-highlight/utils/index.js +43 -0
- package/es/plugins/list/plugin/index.js +1 -1
- package/es/plugins/list/react/ReactListPlugin.js +1 -1
- package/es/plugins/markdown/index.d.ts +1 -0
- package/es/plugins/markdown/index.js +2 -1
- package/es/plugins/markdown/plugin/index.js +57 -3
- package/es/plugins/markdown/utils/url-validator.d.ts +4 -0
- package/es/plugins/markdown/utils/url-validator.js +6 -0
- package/es/plugins/math/plugin/index.js +1 -1
- package/es/plugins/math/react/index.js +1 -1
- package/es/plugins/mention/plugin/index.js +1 -1
- package/es/plugins/mention/react/ReactMentionPlugin.js +1 -1
- package/es/plugins/table/plugin/index.js +1 -1
- package/es/react/Editor/Editor.js +1 -1
- package/es/react/hooks/useEditorState/index.js +46 -6
- package/es/utils/url.d.ts +15 -0
- package/es/utils/url.js +51 -0
- package/package.json +1 -1
package/es/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './plugins/file';
|
|
|
7
7
|
export * from './plugins/hr';
|
|
8
8
|
export * from './plugins/image';
|
|
9
9
|
export * from './plugins/link';
|
|
10
|
+
export * from './plugins/link-highlight';
|
|
10
11
|
export * from './plugins/list';
|
|
11
12
|
export * from './plugins/markdown';
|
|
12
13
|
export * from './plugins/math';
|
|
@@ -17,6 +18,7 @@ export * from './plugins/upload';
|
|
|
17
18
|
export type { IEditor } from './types';
|
|
18
19
|
export * from './types/hotkey';
|
|
19
20
|
export { getHotkeyById } from './utils/hotkey/registerHotkey';
|
|
21
|
+
export { isPureUrl, isValidUrl } from './utils/url';
|
|
20
22
|
export { browserDebug, createDebugLogger, debugLogger, debugLoggers, devConsole, prodSafeLogger, } from './utils/debug';
|
|
21
23
|
export { Kernel } from './editor-kernel/kernel';
|
|
22
24
|
/**
|
package/es/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export * from "./plugins/file";
|
|
|
7
7
|
export * from "./plugins/hr";
|
|
8
8
|
export * from "./plugins/image";
|
|
9
9
|
export * from "./plugins/link";
|
|
10
|
+
export * from "./plugins/link-highlight";
|
|
10
11
|
export * from "./plugins/list";
|
|
11
12
|
export * from "./plugins/markdown";
|
|
12
13
|
export * from "./plugins/math";
|
|
@@ -18,6 +19,9 @@ export * from "./plugins/upload";
|
|
|
18
19
|
export * from "./types/hotkey";
|
|
19
20
|
export { getHotkeyById } from "./utils/hotkey/registerHotkey";
|
|
20
21
|
|
|
22
|
+
// URL utilities
|
|
23
|
+
export { isPureUrl, isValidUrl } from "./utils/url";
|
|
24
|
+
|
|
21
25
|
// Debug utilities
|
|
22
26
|
export { browserDebug, createDebugLogger, debugLogger, debugLoggers, devConsole, prodSafeLogger } from "./utils/debug";
|
|
23
27
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EditorConfig, LexicalEditor, LexicalNode, SerializedElementNode } from 'lexical';
|
|
2
|
-
import { CardLikeElementNode } from "../../common";
|
|
2
|
+
import { CardLikeElementNode } from "../../common/node/cursor";
|
|
3
3
|
export type SerializedCodeNode = SerializedElementNode;
|
|
4
4
|
export declare class CodeNode extends CardLikeElementNode {
|
|
5
5
|
static getType(): string;
|
|
@@ -16,7 +16,7 @@ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.g
|
|
|
16
16
|
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
17
17
|
import { addClassNamesToElement } from '@lexical/utils';
|
|
18
18
|
import { $applyNodeReplacement, $createTextNode, $getSelection, $isNodeSelection, $isRangeSelection } from 'lexical';
|
|
19
|
-
import { $createCursorNode, $isCursorNode, CardLikeElementNode } from "../../common";
|
|
19
|
+
import { $createCursorNode, $isCursorNode, CardLikeElementNode } from "../../common/node/cursor";
|
|
20
20
|
export var CodeNode = /*#__PURE__*/function (_CardLikeElementNode) {
|
|
21
21
|
_inherits(CodeNode, _CardLikeElementNode);
|
|
22
22
|
var _super = _createSuper(CodeNode);
|
|
@@ -8,7 +8,7 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
|
|
|
8
8
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
9
9
|
import { useLayoutEffect } from 'react';
|
|
10
10
|
import { useLexicalComposerContext } from "../../../editor-kernel/react/react-context";
|
|
11
|
-
import { MarkdownPlugin } from "../../markdown";
|
|
11
|
+
import { MarkdownPlugin } from "../../markdown/plugin";
|
|
12
12
|
import { CodePlugin } from "../plugin";
|
|
13
13
|
import { useStyles } from "./style";
|
|
14
14
|
var ReactCodePlugin = function ReactCodePlugin(_ref) {
|
|
@@ -17,7 +17,7 @@ import { $createCodeNode, $isCodeHighlightNode, $isCodeNode, CodeHighlightNode,
|
|
|
17
17
|
import { TabNode } from 'lexical';
|
|
18
18
|
import { INodeHelper } from "../../../editor-kernel/inode/helper";
|
|
19
19
|
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
20
|
-
import { IMarkdownShortCutService } from "../../markdown";
|
|
20
|
+
import { IMarkdownShortCutService } from "../../markdown/service/shortcut";
|
|
21
21
|
import { CustomShikiTokenizer, registerCodeCommand } from "../command";
|
|
22
22
|
import { getCodeLanguageByInput } from "../utils/language";
|
|
23
23
|
import { registerCodeHighlighting, toCodeTheme } from "./CodeHighlighterShiki";
|
|
@@ -9,7 +9,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
9
9
|
import { usePrevious } from 'ahooks';
|
|
10
10
|
import { useEffect, useLayoutEffect, useRef } from 'react';
|
|
11
11
|
import { useLexicalComposerContext } from "../../../editor-kernel/react/react-context";
|
|
12
|
-
import { MarkdownPlugin } from "../../markdown";
|
|
12
|
+
import { MarkdownPlugin } from "../../markdown/plugin";
|
|
13
13
|
import { CodeblockPlugin } from "../plugin";
|
|
14
14
|
import { colorReplacements, useStyles } from "./style";
|
|
15
15
|
export var ReactCodeblockPlugin = function ReactCodeblockPlugin(_ref) {
|
|
@@ -26,7 +26,8 @@ import { createEmptyHistoryState, registerHistory } from '@lexical/history';
|
|
|
26
26
|
import { $createHeadingNode, $createQuoteNode, $isHeadingNode, $isQuoteNode, HeadingNode, QuoteNode, registerRichText } from '@lexical/rich-text';
|
|
27
27
|
import { $createLineBreakNode, $createParagraphNode, $getSelection, $isRangeSelection, $isTextNode, COMMAND_PRIORITY_HIGH, INSERT_LINE_BREAK_COMMAND, INSERT_PARAGRAPH_COMMAND } from 'lexical';
|
|
28
28
|
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
29
|
-
import { IMarkdownShortCutService
|
|
29
|
+
import { IMarkdownShortCutService } from "../../markdown/service/shortcut";
|
|
30
|
+
import { isPunctuationChar } from "../../markdown/utils";
|
|
30
31
|
import { registerCommands } from "../command";
|
|
31
32
|
import JSONDataSource from "../data-source/json-data-source";
|
|
32
33
|
import TextDataSource from "../data-source/text-data-source";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type { IMarkdownShortCutService } from "../../markdown";
|
|
1
|
+
import type { IMarkdownShortCutService } from "../../markdown/service/shortcut";
|
|
2
2
|
export declare function registerMDReader(markdownService: IMarkdownShortCutService): void;
|
|
@@ -20,7 +20,7 @@ import { Children, memo, useEffect, useLayoutEffect, useRef, useState } from 're
|
|
|
20
20
|
import { LexicalErrorBoundary } from "../../../editor-kernel/react/LexicalErrorBoundary";
|
|
21
21
|
import { useLexicalComposerContext } from "../../../editor-kernel/react/react-context";
|
|
22
22
|
import { useDecorators } from "../../../editor-kernel/react/useDecorators";
|
|
23
|
-
import { MarkdownPlugin } from "../../markdown";
|
|
23
|
+
import { MarkdownPlugin } from "../../markdown/plugin";
|
|
24
24
|
import { CommonPlugin } from "../plugin";
|
|
25
25
|
import Placeholder from "./Placeholder";
|
|
26
26
|
import { useStyles, useThemeStyles } from "./style";
|
|
@@ -19,7 +19,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
19
19
|
import { $wrapNodeInElement } from '@lexical/utils';
|
|
20
20
|
import { $createParagraphNode, $createRangeSelection, $insertNodes, $isRootOrShadowRoot, $setSelection } from 'lexical';
|
|
21
21
|
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
22
|
-
import { IMarkdownShortCutService } from "../../markdown";
|
|
22
|
+
import { IMarkdownShortCutService } from "../../markdown/service/shortcut";
|
|
23
23
|
import { IUploadService } from "../../upload";
|
|
24
24
|
import { createDebugLogger } from "../../../utils/debug";
|
|
25
25
|
import { registerFileCommand } from "../command";
|
|
@@ -15,7 +15,7 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
|
|
|
15
15
|
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); }
|
|
16
16
|
import { INodeHelper } from "../../../editor-kernel/inode/helper";
|
|
17
17
|
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
18
|
-
import { IMarkdownShortCutService } from "../../markdown";
|
|
18
|
+
import { IMarkdownShortCutService } from "../../markdown/service/shortcut";
|
|
19
19
|
import { registerHorizontalRuleCommand } from "../command";
|
|
20
20
|
import { $createHorizontalRuleNode, $isHorizontalRuleNode, HorizontalRuleNode } from "../node/HorizontalRuleNode";
|
|
21
21
|
|
|
@@ -8,7 +8,7 @@ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" !=
|
|
|
8
8
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
9
9
|
import { useLayoutEffect } from 'react';
|
|
10
10
|
import { useLexicalComposerContext } from "../../../editor-kernel/react/react-context";
|
|
11
|
-
import { MarkdownPlugin } from "../../markdown";
|
|
11
|
+
import { MarkdownPlugin } from "../../markdown/plugin";
|
|
12
12
|
import { HRPlugin } from "../plugin";
|
|
13
13
|
import HRNode from "./components/HRNode";
|
|
14
14
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
@@ -22,7 +22,7 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
|
|
|
22
22
|
import { $createTextNode, COMMAND_PRIORITY_NORMAL, PASTE_COMMAND } from 'lexical';
|
|
23
23
|
import { INodeHelper } from "../../../editor-kernel/inode/helper";
|
|
24
24
|
import { KernelPlugin } from "../../../editor-kernel/plugin";
|
|
25
|
-
import { IMarkdownShortCutService } from "../../markdown";
|
|
25
|
+
import { IMarkdownShortCutService } from "../../markdown/service/shortcut";
|
|
26
26
|
import { INSERT_LINK_COMMAND, registerLinkCommand } from "../command";
|
|
27
27
|
import { $createLinkNode, $isLinkNode, AutoLinkNode, LinkNode } from "../node/LinkNode";
|
|
28
28
|
import { registerLinkCommands } from "./registry";
|
|
@@ -9,7 +9,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
|
9
9
|
import { useLayoutEffect } from 'react';
|
|
10
10
|
import PortalAnchor from "../../../editor-kernel/react/PortalAnchor";
|
|
11
11
|
import { useLexicalComposerContext } from "../../../editor-kernel/react/react-context";
|
|
12
|
-
import { MarkdownPlugin } from "../../markdown";
|
|
12
|
+
import { MarkdownPlugin } from "../../markdown/plugin";
|
|
13
13
|
import { LinkPlugin } from "../plugin";
|
|
14
14
|
import LinkEdit from "./components/LinkEdit";
|
|
15
15
|
import LinkToolbar from "./components/LinkToolbar";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
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; } } }; }
|
|
2
|
+
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); }
|
|
3
|
+
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; }
|
|
4
|
+
import { $getSelection, $insertNodes, $isRangeSelection, COMMAND_PRIORITY_EDITOR, createCommand } from 'lexical';
|
|
5
|
+
import { $createCursorNode } from "../../common/node/cursor";
|
|
6
|
+
import { $createLinkHighlightNode, $isLinkHighlightNode, getLinkHighlightNode } from "../node/link-highlight";
|
|
7
|
+
export var INSERT_LINK_HIGHLIGHT_COMMAND = createCommand('INSERT_LINK_HIGHLIGHT_COMMAND');
|
|
8
|
+
export function registerLinkHighlightCommand(editor) {
|
|
9
|
+
return editor.registerCommand(INSERT_LINK_HIGHLIGHT_COMMAND, function () {
|
|
10
|
+
editor.update(function () {
|
|
11
|
+
var selection = $getSelection();
|
|
12
|
+
if (!selection || !$isRangeSelection(selection)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
var focusNode = selection.focus.getNode();
|
|
16
|
+
var anchorNode = selection.anchor.getNode();
|
|
17
|
+
var linkHighlight = getLinkHighlightNode(focusNode);
|
|
18
|
+
if (linkHighlight !== getLinkHighlightNode(anchorNode)) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
if ($isLinkHighlightNode(linkHighlight)) {
|
|
22
|
+
// Remove link highlight formatting
|
|
23
|
+
var _iterator = _createForOfIteratorHelper(linkHighlight.getChildren().slice(0)),
|
|
24
|
+
_step;
|
|
25
|
+
try {
|
|
26
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
27
|
+
var node = _step.value;
|
|
28
|
+
linkHighlight.insertBefore(node);
|
|
29
|
+
}
|
|
30
|
+
} catch (err) {
|
|
31
|
+
_iterator.e(err);
|
|
32
|
+
} finally {
|
|
33
|
+
_iterator.f();
|
|
34
|
+
}
|
|
35
|
+
linkHighlight.remove();
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Create link highlight with selected text
|
|
40
|
+
var linkHighlightNode = $createLinkHighlightNode(selection.getTextContent());
|
|
41
|
+
$insertNodes([linkHighlightNode, $createCursorNode()]);
|
|
42
|
+
linkHighlightNode.select();
|
|
43
|
+
});
|
|
44
|
+
return true;
|
|
45
|
+
}, COMMAND_PRIORITY_EDITOR);
|
|
46
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { EditorConfig, LexicalEditor, LexicalNode, SerializedElementNode } from 'lexical';
|
|
2
|
+
import { CardLikeElementNode } from "../../common/node/cursor";
|
|
3
|
+
export type SerializedLinkHighlightNode = SerializedElementNode;
|
|
4
|
+
export declare class LinkHighlightNode extends CardLikeElementNode {
|
|
5
|
+
static getType(): string;
|
|
6
|
+
static clone(node: LinkHighlightNode): LinkHighlightNode;
|
|
7
|
+
static importJSON(serializedNode: SerializedLinkHighlightNode): LinkHighlightNode;
|
|
8
|
+
createDOM(config: EditorConfig, editor: LexicalEditor): HTMLElement;
|
|
9
|
+
/**
|
|
10
|
+
* Format URL to ensure it has proper protocol
|
|
11
|
+
*/
|
|
12
|
+
private formatUrl;
|
|
13
|
+
getDOMSlot(element: HTMLElement): import("lexical").ElementDOMSlot<HTMLElement>;
|
|
14
|
+
canBeEmpty(): boolean;
|
|
15
|
+
isCardLike(): boolean;
|
|
16
|
+
isInline(): boolean;
|
|
17
|
+
canIndent(): boolean;
|
|
18
|
+
canInsertTextBefore(): boolean;
|
|
19
|
+
canInsertTextAfter(): boolean;
|
|
20
|
+
updateDOM(prevNode: LinkHighlightNode, dom: HTMLElement, config: EditorConfig): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Get the URL from the text content
|
|
23
|
+
*/
|
|
24
|
+
getURL(): string;
|
|
25
|
+
}
|
|
26
|
+
export declare function $createLinkHighlightNode(textContent?: string): LinkHighlightNode;
|
|
27
|
+
export declare function $isLinkHighlightNode(node: unknown): node is LinkHighlightNode;
|
|
28
|
+
export declare function getLinkHighlightNode(node: LexicalNode): LexicalNode | null;
|
|
29
|
+
export declare function $isSelectionInLinkHighlight(editor: LexicalEditor): boolean;
|
|
@@ -0,0 +1,223 @@
|
|
|
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 _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
3
|
+
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); } }
|
|
4
|
+
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
|
|
5
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
6
|
+
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); }
|
|
7
|
+
function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get.bind(); } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); }
|
|
8
|
+
function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; }
|
|
9
|
+
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); }
|
|
10
|
+
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
|
|
11
|
+
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
|
|
12
|
+
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); }
|
|
13
|
+
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
|
|
14
|
+
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
15
|
+
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
16
|
+
/* eslint-disable @typescript-eslint/no-use-before-define */
|
|
17
|
+
import { addClassNamesToElement } from '@lexical/utils';
|
|
18
|
+
import { $applyNodeReplacement, $createTextNode, $getSelection, $isNodeSelection, $isRangeSelection } from 'lexical';
|
|
19
|
+
import { $createCursorNode, $isCursorNode, CardLikeElementNode } from "../../common/node/cursor";
|
|
20
|
+
export var LinkHighlightNode = /*#__PURE__*/function (_CardLikeElementNode) {
|
|
21
|
+
_inherits(LinkHighlightNode, _CardLikeElementNode);
|
|
22
|
+
var _super = _createSuper(LinkHighlightNode);
|
|
23
|
+
function LinkHighlightNode() {
|
|
24
|
+
_classCallCheck(this, LinkHighlightNode);
|
|
25
|
+
return _super.apply(this, arguments);
|
|
26
|
+
}
|
|
27
|
+
_createClass(LinkHighlightNode, [{
|
|
28
|
+
key: "createDOM",
|
|
29
|
+
value: function createDOM(config, editor) {
|
|
30
|
+
var _this = this;
|
|
31
|
+
var element = document.createElement('span');
|
|
32
|
+
// eslint-disable-next-line unicorn/prefer-dom-node-dataset
|
|
33
|
+
element.setAttribute('data-lexical-key', this.getKey());
|
|
34
|
+
var childContainer = document.createElement('ne-content');
|
|
35
|
+
element.append(childContainer);
|
|
36
|
+
addClassNamesToElement(element, config.theme.linkHighlight);
|
|
37
|
+
|
|
38
|
+
// Add click handler to open link in new window
|
|
39
|
+
element.addEventListener('click', function (event) {
|
|
40
|
+
// Only handle left click without modifier keys
|
|
41
|
+
if (event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey) {
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
event.stopPropagation();
|
|
44
|
+
|
|
45
|
+
// Read URL in editor context
|
|
46
|
+
editor.read(function () {
|
|
47
|
+
var url = _this.getURL();
|
|
48
|
+
if (url) {
|
|
49
|
+
// Format URL to ensure it has proper protocol
|
|
50
|
+
var formattedUrl = _this.formatUrl(url);
|
|
51
|
+
window.open(formattedUrl, '_blank', 'noopener,noreferrer');
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
return element;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Format URL to ensure it has proper protocol
|
|
61
|
+
*/
|
|
62
|
+
}, {
|
|
63
|
+
key: "formatUrl",
|
|
64
|
+
value: function formatUrl(url) {
|
|
65
|
+
// Check if URL already has a protocol
|
|
66
|
+
if (/^[a-z][\d+.a-z-]*:/i.test(url)) {
|
|
67
|
+
return url;
|
|
68
|
+
}
|
|
69
|
+
// Check if it's a relative path
|
|
70
|
+
if (/^[#./]/.test(url)) {
|
|
71
|
+
return url;
|
|
72
|
+
}
|
|
73
|
+
// Check for email address
|
|
74
|
+
if (url.includes('@') && !url.startsWith('mailto:')) {
|
|
75
|
+
return "mailto:".concat(url);
|
|
76
|
+
}
|
|
77
|
+
// Check for phone number
|
|
78
|
+
if (/^\+?[\d\s()-]{5,}$/.test(url)) {
|
|
79
|
+
return "tel:".concat(url);
|
|
80
|
+
}
|
|
81
|
+
// Default to https
|
|
82
|
+
if (url.startsWith('www.')) {
|
|
83
|
+
return "https://".concat(url);
|
|
84
|
+
}
|
|
85
|
+
// If no protocol, assume https
|
|
86
|
+
if (!url.includes('://')) {
|
|
87
|
+
return "https://".concat(url);
|
|
88
|
+
}
|
|
89
|
+
return url;
|
|
90
|
+
}
|
|
91
|
+
}, {
|
|
92
|
+
key: "getDOMSlot",
|
|
93
|
+
value: function getDOMSlot(element) {
|
|
94
|
+
var neContent = element.querySelector('ne-content');
|
|
95
|
+
if (!neContent) {
|
|
96
|
+
throw new Error('LinkHighlightNode: ne-content not found');
|
|
97
|
+
}
|
|
98
|
+
return _get(_getPrototypeOf(LinkHighlightNode.prototype), "getDOMSlot", this).call(this, element).withElement(neContent);
|
|
99
|
+
}
|
|
100
|
+
}, {
|
|
101
|
+
key: "canBeEmpty",
|
|
102
|
+
value: function canBeEmpty() {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}, {
|
|
106
|
+
key: "isCardLike",
|
|
107
|
+
value: function isCardLike() {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
}, {
|
|
111
|
+
key: "isInline",
|
|
112
|
+
value: function isInline() {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
}, {
|
|
116
|
+
key: "canIndent",
|
|
117
|
+
value: function canIndent() {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
}, {
|
|
121
|
+
key: "canInsertTextBefore",
|
|
122
|
+
value: function canInsertTextBefore() {
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
}, {
|
|
126
|
+
key: "canInsertTextAfter",
|
|
127
|
+
value: function canInsertTextAfter() {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
}, {
|
|
131
|
+
key: "updateDOM",
|
|
132
|
+
value: function updateDOM(prevNode, dom, config) {
|
|
133
|
+
// Update the class names if theme has changed
|
|
134
|
+
var prevTheme = prevNode ? prevNode : null;
|
|
135
|
+
if (prevTheme !== this) {
|
|
136
|
+
addClassNamesToElement(dom, config.theme.linkHighlight);
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Get the URL from the text content
|
|
143
|
+
*/
|
|
144
|
+
}, {
|
|
145
|
+
key: "getURL",
|
|
146
|
+
value: function getURL() {
|
|
147
|
+
return this.getTextContent().trim();
|
|
148
|
+
}
|
|
149
|
+
}], [{
|
|
150
|
+
key: "getType",
|
|
151
|
+
value: function getType() {
|
|
152
|
+
return 'linkHighlight';
|
|
153
|
+
}
|
|
154
|
+
}, {
|
|
155
|
+
key: "clone",
|
|
156
|
+
value: function clone(node) {
|
|
157
|
+
return new LinkHighlightNode(node.__key);
|
|
158
|
+
}
|
|
159
|
+
}, {
|
|
160
|
+
key: "importJSON",
|
|
161
|
+
value: function importJSON(serializedNode) {
|
|
162
|
+
return $createLinkHighlightNode().updateFromJSON(serializedNode);
|
|
163
|
+
}
|
|
164
|
+
}]);
|
|
165
|
+
return LinkHighlightNode;
|
|
166
|
+
}(CardLikeElementNode);
|
|
167
|
+
export function $createLinkHighlightNode(textContent) {
|
|
168
|
+
var linkHighlightNode = $applyNodeReplacement(new LinkHighlightNode());
|
|
169
|
+
var cursorNode = $createCursorNode();
|
|
170
|
+
linkHighlightNode.append(cursorNode);
|
|
171
|
+
if (textContent) {
|
|
172
|
+
linkHighlightNode.append($createTextNode(textContent));
|
|
173
|
+
}
|
|
174
|
+
return linkHighlightNode;
|
|
175
|
+
}
|
|
176
|
+
export function $isLinkHighlightNode(node) {
|
|
177
|
+
return node instanceof LinkHighlightNode;
|
|
178
|
+
}
|
|
179
|
+
export function getLinkHighlightNode(node) {
|
|
180
|
+
if ($isCursorNode(node)) {
|
|
181
|
+
var parent = node.getParent();
|
|
182
|
+
if ($isLinkHighlightNode(parent)) {
|
|
183
|
+
return parent;
|
|
184
|
+
}
|
|
185
|
+
if ($isLinkHighlightNode(node.getNextSibling())) {
|
|
186
|
+
return node.getNextSibling();
|
|
187
|
+
}
|
|
188
|
+
if ($isLinkHighlightNode(node.getPreviousSibling())) {
|
|
189
|
+
return node.getPreviousSibling();
|
|
190
|
+
}
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
if ($isLinkHighlightNode(node.getParent())) {
|
|
194
|
+
return node.getParent();
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
export function $isSelectionInLinkHighlight(editor) {
|
|
199
|
+
return editor.read(function () {
|
|
200
|
+
var selection = $getSelection();
|
|
201
|
+
if (!selection) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
if ($isRangeSelection(selection)) {
|
|
205
|
+
var focusNode = selection.focus.getNode();
|
|
206
|
+
var anchorNode = selection.anchor.getNode();
|
|
207
|
+
var linkHighlight = getLinkHighlightNode(focusNode);
|
|
208
|
+
if (linkHighlight !== getLinkHighlightNode(anchorNode)) {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
if ($isLinkHighlightNode(linkHighlight)) {
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
return false;
|
|
215
|
+
} else if ($isNodeSelection(selection)) {
|
|
216
|
+
var nodes = selection.getNodes();
|
|
217
|
+
if (nodes.length === 1 && $isLinkHighlightNode(nodes[0])) {
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
});
|
|
223
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { IEditorPluginConstructor } from "../../../types";
|
|
2
|
+
export interface LinkHighlightPluginOptions {
|
|
3
|
+
enableHotkey?: boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Enable auto-highlight when pasting URLs
|
|
6
|
+
* @default true
|
|
7
|
+
*/
|
|
8
|
+
enablePasteAutoHighlight?: boolean;
|
|
9
|
+
theme?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Custom URL validation regex
|
|
12
|
+
*/
|
|
13
|
+
urlRegex?: RegExp;
|
|
14
|
+
}
|
|
15
|
+
export declare const LinkHighlightPlugin: IEditorPluginConstructor<LinkHighlightPluginOptions>;
|