ct-rich-text-editor 1.3.26 → 1.3.27
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/dist/api/config/endpoints.d.ts +3 -0
- package/dist/api/linkPreview.d.ts +15 -0
- package/dist/assets/style.css +8 -0
- package/dist/{html2pdf.bundle-41a72ab2.js → html2pdf.bundle-08dfd2d4.js} +2 -2
- package/dist/{html2pdf.bundle-41a72ab2.js.map → html2pdf.bundle-08dfd2d4.js.map} +1 -1
- package/dist/{html2pdf.bundle.min-1f376935.js → html2pdf.bundle.min-382f2ad4.js} +2 -2
- package/dist/{html2pdf.bundle.min-1f376935.js.map → html2pdf.bundle.min-382f2ad4.js.map} +1 -1
- package/dist/{index-9b519a99.js → index-4edbb171.js} +2 -2
- package/dist/{index-9b519a99.js.map → index-4edbb171.js.map} +1 -1
- package/dist/{index-01a6d110.js → index-aa2e3927.js} +2 -2
- package/dist/{index-01a6d110.js.map → index-aa2e3927.js.map} +1 -1
- package/dist/{index-a2107b7c.js → index-d1d21414.js} +396 -217
- package/dist/index-d1d21414.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/plugins/LinkPreviewPlugin/index.d.ts +3 -1
- package/package.json +2 -2
- package/dist/index-a2107b7c.js.map +0 -1
|
@@ -24,7 +24,7 @@ import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
|
|
|
24
24
|
import { TableNode, TableCellNode, TableRowNode, $createTableNodeWithDimensions, $isTableRowNode, $isTableCellNode, TableCellHeaderStates, $isTableNode, $isTableSelection, $getTableCellNodeFromLexicalNode, $getTableNodeFromLexicalNodeOrThrow, getTableElement, getTableObserverFromTableElement, $getTableRowIndexFromTableCellNode, $getNodeTriplet, $insertTableRow__EXPERIMENTAL, $getTableColumnIndexFromTableCellNode, $insertTableColumn__EXPERIMENTAL, $deleteTableRow__EXPERIMENTAL, $deleteTableColumn__EXPERIMENTAL, $unmergeCell, $computeTableMapSkipCellCheck, getDOMCellFromTarget, $getTableAndElementByKey } from "@lexical/table";
|
|
25
25
|
import { mergeRegister, $wrapNodeInElement, $findMatchingParent, $getNearestNodeOfType, $getNearestBlockElementAncestorOrThrow, $insertNodeToNearestRoot, $isEditorIsNestedEditor, mediaFileReader, isMimeType, calculateZoomLevel, CAN_USE_DOM } from "@lexical/utils";
|
|
26
26
|
import Stack from "@mui/material/Stack";
|
|
27
|
-
import { createCommand, DecoratorNode, createEditor, $applyNodeReplacement, $
|
|
27
|
+
import { createCommand, DecoratorNode, createEditor, $applyNodeReplacement, $getSelection, $isRangeSelection, ElementNode, $isRootOrShadowRoot, $createParagraphNode, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_LOW, $insertNodes, $getNearestNodeFromDOMNode, isHTMLElement as isHTMLElement$1, TextNode, $getRoot, $createTextNode, $getNodeByKey, $isParagraphNode, $isTextNode, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND, KEY_DOWN_COMMAND, COMMAND_PRIORITY_CRITICAL, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, $isElementNode, SELECTION_CHANGE_COMMAND, UNDO_COMMAND, REDO_COMMAND, KEY_SPACE_COMMAND, $isLineBreakNode, $createRangeSelection, $setSelection, COMMAND_PRIORITY_HIGH, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, $createNodeSelection, $isNodeSelection, getDOMSelection, CLICK_COMMAND, PASTE_COMMAND, ParagraphNode, $createLineBreakNode, isDOMNode } from "lexical";
|
|
28
28
|
import * as ReactDOM from "react-dom";
|
|
29
29
|
import ReactDOM__default, { createPortal } from "react-dom";
|
|
30
30
|
import { $isCodeNode, CodeNode, normalizeCodeLang, getLanguageFriendlyName, CodeHighlightNode, CODE_LANGUAGE_MAP, $createCodeNode, registerCodeHighlighting, $isCodeHighlightNode } from "@lexical/code";
|
|
@@ -1395,6 +1395,9 @@ const apiEndpoints = {
|
|
|
1395
1395
|
},
|
|
1396
1396
|
transcript: {
|
|
1397
1397
|
voiceTranscript: "/api/transcript/get-assemblyai-token"
|
|
1398
|
+
},
|
|
1399
|
+
linkPreview: {
|
|
1400
|
+
getPreview: "/api/link-preview"
|
|
1398
1401
|
}
|
|
1399
1402
|
};
|
|
1400
1403
|
const AiJsonResponse = async ({ content }) => {
|
|
@@ -1478,7 +1481,7 @@ const AiTextTransform = async ({ content, apiKey }) => {
|
|
|
1478
1481
|
const AI_ACTION_COMMAND = createCommand(
|
|
1479
1482
|
"AI_ACTION_COMMAND"
|
|
1480
1483
|
);
|
|
1481
|
-
const ImageView = React__default.lazy(() => import("./index-
|
|
1484
|
+
const ImageView = React__default.lazy(() => import("./index-aa2e3927.js"));
|
|
1482
1485
|
function isGoogleDocCheckboxImg(img) {
|
|
1483
1486
|
return img.parentElement != null && img.parentElement.tagName === "LI" && img.previousSibling === null && img.getAttribute("aria-roledescription") === "checkbox";
|
|
1484
1487
|
}
|
|
@@ -1738,7 +1741,37 @@ const ImagePlugin = ({
|
|
|
1738
1741
|
INSERT_IMAGE_COMMAND,
|
|
1739
1742
|
(payload) => {
|
|
1740
1743
|
const imageNode = $createImageNode(payload);
|
|
1741
|
-
$
|
|
1744
|
+
const selection = $getSelection();
|
|
1745
|
+
if ($isRangeSelection(selection)) {
|
|
1746
|
+
const anchorNode = selection.anchor.getNode();
|
|
1747
|
+
const anchorParent = anchorNode.getParent();
|
|
1748
|
+
if (anchorParent instanceof ElementNode && !$isRootOrShadowRoot(anchorParent)) {
|
|
1749
|
+
const parentType = anchorParent.getType();
|
|
1750
|
+
if (parentType === "paragraph" || parentType === "listitem") {
|
|
1751
|
+
const hasContent = anchorParent.getTextContent().trim().length > 0;
|
|
1752
|
+
const isAtEnd = selection.anchor.offset === anchorNode.getTextContentSize();
|
|
1753
|
+
const isAtStart = selection.anchor.offset === 0;
|
|
1754
|
+
if (hasContent) {
|
|
1755
|
+
const imageParagraph = $createParagraphNode();
|
|
1756
|
+
imageParagraph.append(imageNode);
|
|
1757
|
+
if (isAtEnd) {
|
|
1758
|
+
anchorParent.insertAfter(imageParagraph);
|
|
1759
|
+
} else if (isAtStart) {
|
|
1760
|
+
anchorParent.insertBefore(imageParagraph);
|
|
1761
|
+
} else {
|
|
1762
|
+
anchorParent.insertAfter(imageParagraph);
|
|
1763
|
+
}
|
|
1764
|
+
const emptyParagraph = $createParagraphNode();
|
|
1765
|
+
imageParagraph.insertAfter(emptyParagraph);
|
|
1766
|
+
emptyParagraph.selectEnd();
|
|
1767
|
+
return true;
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
if ($isRangeSelection(selection)) {
|
|
1773
|
+
selection.insertNodes([imageNode]);
|
|
1774
|
+
}
|
|
1742
1775
|
if ($isRootOrShadowRoot(imageNode.getParentOrThrow())) {
|
|
1743
1776
|
$wrapNodeInElement(imageNode, $createParagraphNode).selectEnd();
|
|
1744
1777
|
}
|
|
@@ -2111,20 +2144,20 @@ const createLruCache = (maxCacheSize) => {
|
|
|
2111
2144
|
};
|
|
2112
2145
|
}
|
|
2113
2146
|
let cacheSize = 0;
|
|
2114
|
-
let
|
|
2147
|
+
let cache2 = /* @__PURE__ */ Object.create(null);
|
|
2115
2148
|
let previousCache = /* @__PURE__ */ Object.create(null);
|
|
2116
2149
|
const update = (key, value) => {
|
|
2117
|
-
|
|
2150
|
+
cache2[key] = value;
|
|
2118
2151
|
cacheSize++;
|
|
2119
2152
|
if (cacheSize > maxCacheSize) {
|
|
2120
2153
|
cacheSize = 0;
|
|
2121
|
-
previousCache =
|
|
2122
|
-
|
|
2154
|
+
previousCache = cache2;
|
|
2155
|
+
cache2 = /* @__PURE__ */ Object.create(null);
|
|
2123
2156
|
}
|
|
2124
2157
|
};
|
|
2125
2158
|
return {
|
|
2126
2159
|
get(key) {
|
|
2127
|
-
let value =
|
|
2160
|
+
let value = cache2[key];
|
|
2128
2161
|
if (value !== void 0) {
|
|
2129
2162
|
return value;
|
|
2130
2163
|
}
|
|
@@ -2134,8 +2167,8 @@ const createLruCache = (maxCacheSize) => {
|
|
|
2134
2167
|
}
|
|
2135
2168
|
},
|
|
2136
2169
|
set(key, value) {
|
|
2137
|
-
if (key in
|
|
2138
|
-
|
|
2170
|
+
if (key in cache2) {
|
|
2171
|
+
cache2[key] = value;
|
|
2139
2172
|
} else {
|
|
2140
2173
|
update(key, value);
|
|
2141
2174
|
}
|
|
@@ -12665,8 +12698,8 @@ function hasFixedPositionAncestor(element, stopNode) {
|
|
|
12665
12698
|
}
|
|
12666
12699
|
return getComputedStyle$1(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode);
|
|
12667
12700
|
}
|
|
12668
|
-
function getClippingElementAncestors(element,
|
|
12669
|
-
const cachedResult =
|
|
12701
|
+
function getClippingElementAncestors(element, cache2) {
|
|
12702
|
+
const cachedResult = cache2.get(element);
|
|
12670
12703
|
if (cachedResult) {
|
|
12671
12704
|
return cachedResult;
|
|
12672
12705
|
}
|
|
@@ -12688,7 +12721,7 @@ function getClippingElementAncestors(element, cache) {
|
|
|
12688
12721
|
}
|
|
12689
12722
|
currentNode = getParentNode(currentNode);
|
|
12690
12723
|
}
|
|
12691
|
-
|
|
12724
|
+
cache2.set(element, result);
|
|
12692
12725
|
return result;
|
|
12693
12726
|
}
|
|
12694
12727
|
function getClippingRect(_ref) {
|
|
@@ -12986,14 +13019,14 @@ const hide$1 = hide$2;
|
|
|
12986
13019
|
const arrow$2 = arrow$3;
|
|
12987
13020
|
const limitShift$1 = limitShift$2;
|
|
12988
13021
|
const computePosition = (reference, floating, options) => {
|
|
12989
|
-
const
|
|
13022
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
12990
13023
|
const mergedOptions = {
|
|
12991
13024
|
platform,
|
|
12992
13025
|
...options
|
|
12993
13026
|
};
|
|
12994
13027
|
const platformWithCache = {
|
|
12995
13028
|
...mergedOptions.platform,
|
|
12996
|
-
_c:
|
|
13029
|
+
_c: cache2
|
|
12997
13030
|
};
|
|
12998
13031
|
return computePosition$1(reference, floating, {
|
|
12999
13032
|
...mergedOptions,
|
|
@@ -15370,7 +15403,7 @@ const EmbedComponent = ({ url, displayType, alignment, nodeKey }) => {
|
|
|
15370
15403
|
}
|
|
15371
15404
|
);
|
|
15372
15405
|
};
|
|
15373
|
-
const FileComponent = React$1.lazy(() => import("./index-
|
|
15406
|
+
const FileComponent = React$1.lazy(() => import("./index-4edbb171.js"));
|
|
15374
15407
|
function convertFileElement(domNode) {
|
|
15375
15408
|
if (domNode instanceof HTMLDivElement) {
|
|
15376
15409
|
const dataUrl = domNode.getAttribute("data-lexical-file-src");
|
|
@@ -19160,6 +19193,7 @@ function AIChatDialog({
|
|
|
19160
19193
|
selectedTextForInline
|
|
19161
19194
|
}) {
|
|
19162
19195
|
const [inputValue, setInputValue] = useState$1("");
|
|
19196
|
+
const [selectedText, setSelectedText] = useState$1("");
|
|
19163
19197
|
const [isLoading, setIsLoading] = useState$1(false);
|
|
19164
19198
|
const [errorMessage, setErrorMessage] = useState$1(null);
|
|
19165
19199
|
const [provider, setProvider] = useState$1("chatgpt");
|
|
@@ -19168,7 +19202,11 @@ function AIChatDialog({
|
|
|
19168
19202
|
const [purchasedCredits, setPurchasedCredits] = useState$1(0);
|
|
19169
19203
|
useEffect$1(() => {
|
|
19170
19204
|
if (open && initialText) {
|
|
19171
|
-
|
|
19205
|
+
setSelectedText(initialText);
|
|
19206
|
+
setInputValue("");
|
|
19207
|
+
} else if (!open) {
|
|
19208
|
+
setSelectedText("");
|
|
19209
|
+
setInputValue("");
|
|
19172
19210
|
}
|
|
19173
19211
|
}, [open, initialText]);
|
|
19174
19212
|
const {
|
|
@@ -19243,8 +19281,26 @@ function AIChatDialog({
|
|
|
19243
19281
|
setIsLoading(true);
|
|
19244
19282
|
setErrorMessage(null);
|
|
19245
19283
|
const isImageRequest = isImageGenerationRequest(inputValue);
|
|
19284
|
+
let finalPrompt;
|
|
19285
|
+
const hasSelectedText = selectedText && selectedText.trim() !== "";
|
|
19286
|
+
if (isImageRequest) {
|
|
19287
|
+
if (hasSelectedText) {
|
|
19288
|
+
finalPrompt = `${inputValue}: ${selectedText}`;
|
|
19289
|
+
} else {
|
|
19290
|
+
finalPrompt = inputValue;
|
|
19291
|
+
}
|
|
19292
|
+
} else if (hasSelectedText) {
|
|
19293
|
+
finalPrompt = `${inputValue}
|
|
19294
|
+
|
|
19295
|
+
IMPORTANT: Return ONLY the modified/transformed text. Do NOT include any labels, prefixes, explanations, or formatting like "Simplified:", "Result:", "Here is", etc. Just return the pure result text.
|
|
19296
|
+
|
|
19297
|
+
Text to transform:
|
|
19298
|
+
"${selectedText}"`;
|
|
19299
|
+
} else {
|
|
19300
|
+
finalPrompt = inputValue;
|
|
19301
|
+
}
|
|
19246
19302
|
try {
|
|
19247
|
-
const response = await AiEditorAction({ content:
|
|
19303
|
+
const response = await AiEditorAction({ content: finalPrompt, provider, apiKey });
|
|
19248
19304
|
const htmlString = response.data;
|
|
19249
19305
|
const parser = new DOMParser();
|
|
19250
19306
|
const dom = parser.parseFromString(htmlString.trim(), "text/html");
|
|
@@ -19281,6 +19337,7 @@ function AIChatDialog({
|
|
|
19281
19337
|
const handleClose = () => {
|
|
19282
19338
|
if (!isLoading) {
|
|
19283
19339
|
setInputValue("");
|
|
19340
|
+
setSelectedText("");
|
|
19284
19341
|
setErrorMessage(null);
|
|
19285
19342
|
onOpenChange(false);
|
|
19286
19343
|
}
|
|
@@ -19345,9 +19402,26 @@ function AIChatDialog({
|
|
|
19345
19402
|
] })
|
|
19346
19403
|
] }) }),
|
|
19347
19404
|
/* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-4 ", children: [
|
|
19405
|
+
selectedText && selectedText.trim() !== "" && /* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-2", children: [
|
|
19406
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-justify-between", children: [
|
|
19407
|
+
/* @__PURE__ */ jsx(Label$2, { className: "cteditor-text-sm cteditor-font-medium cteditor-text-muted-foreground", children: "Selected Text" }),
|
|
19408
|
+
/* @__PURE__ */ jsx(
|
|
19409
|
+
"button",
|
|
19410
|
+
{
|
|
19411
|
+
type: "button",
|
|
19412
|
+
onClick: () => setSelectedText(""),
|
|
19413
|
+
className: "cteditor-text-xs cteditor-text-muted-foreground hover:cteditor-text-foreground cteditor-transition-colors",
|
|
19414
|
+
title: "Clear selected text",
|
|
19415
|
+
children: /* @__PURE__ */ jsx(X$1, { size: 14 })
|
|
19416
|
+
}
|
|
19417
|
+
)
|
|
19418
|
+
] }),
|
|
19419
|
+
/* @__PURE__ */ jsx("div", { className: "cteditor-p-3 cteditor-rounded-md cteditor-bg-accent/50 cteditor-border cteditor-border-foreground/10 cteditor-max-h-24 cteditor-overflow-y-auto", children: /* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-text-foreground/80 cteditor-whitespace-pre-wrap cteditor-break-words", children: selectedText.length > 300 ? selectedText.substring(0, 300) + "..." : selectedText }) }),
|
|
19420
|
+
/* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-text-muted-foreground", children: "Your prompt will be applied to this selected text" })
|
|
19421
|
+
] }),
|
|
19348
19422
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
19349
19423
|
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-justify-between cteditor-gap-1 cteditor-min-h-8 cteditor-items-center", children: [
|
|
19350
|
-
/* @__PURE__ */ jsx(Label$2, { htmlFor: "ai-prompt", className: "cteditor-text-sm cteditor-font-medium cteditor-mb-0 cteditor-block", children: "Your Question" }),
|
|
19424
|
+
/* @__PURE__ */ jsx(Label$2, { htmlFor: "ai-prompt", className: "cteditor-text-sm cteditor-font-medium cteditor-mb-0 cteditor-block", children: selectedText && selectedText.trim() !== "" ? "Your Instruction" : "Your Question" }),
|
|
19351
19425
|
!isRecording && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
19352
19426
|
"button",
|
|
19353
19427
|
{
|
|
@@ -19368,7 +19442,7 @@ function AIChatDialog({
|
|
|
19368
19442
|
{
|
|
19369
19443
|
ref: textareaRef,
|
|
19370
19444
|
id: "ai-prompt",
|
|
19371
|
-
placeholder: isVoiceLoading ? "Initializing microphone..." : isRecording ? isPaused ? "Paused..." : "Listening..." : "e.g., Improve this
|
|
19445
|
+
placeholder: isVoiceLoading ? "Initializing microphone..." : isRecording ? isPaused ? "Paused..." : "Listening..." : selectedText && selectedText.trim() !== "" ? "e.g., Improve this, translate to Spanish, summarize, fix grammar..." : "e.g., Write a paragraph about..., Generate an image of...",
|
|
19372
19446
|
value: inputValue,
|
|
19373
19447
|
onChange: (e) => setInputValue(e.target.value),
|
|
19374
19448
|
disabled: isLoading || isRecording || isVoiceLoading,
|
|
@@ -19423,7 +19497,7 @@ function AIChatDialog({
|
|
|
19423
19497
|
] }),
|
|
19424
19498
|
!isRecording && !voiceError && !isVoiceLoading && /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-text-xs cteditor-text-muted-foreground", children: [
|
|
19425
19499
|
/* @__PURE__ */ jsx("svg", { className: "cteditor-w-4 cteditor-h-4 cteditor-opacity-60", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }),
|
|
19426
|
-
/* @__PURE__ */ jsx("span", { children: "Type your question or click the microphone icon to use voice input" })
|
|
19500
|
+
/* @__PURE__ */ jsx("span", { children: selectedText && selectedText.trim() !== "" ? "Enter what you want to do with the selected text, or use voice input" : "Type your question or click the microphone icon to use voice input" })
|
|
19427
19501
|
] })
|
|
19428
19502
|
] }),
|
|
19429
19503
|
isVoiceLoading && /* @__PURE__ */ jsx("div", { className: "cteditor-p-3 cteditor-rounded-lg cteditor-bg-gray-100 dark:cteditor-bg-gray-900/50 cteditor-border cteditor-border-gray-300 dark:cteditor-border-gray-700", children: /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2", children: [
|
|
@@ -20486,10 +20560,10 @@ const PDF_CONFIG = {
|
|
|
20486
20560
|
};
|
|
20487
20561
|
const loadHtml2Pdf = async () => {
|
|
20488
20562
|
try {
|
|
20489
|
-
const mod = await import("./html2pdf.bundle.min-
|
|
20563
|
+
const mod = await import("./html2pdf.bundle.min-382f2ad4.js").then((n) => n.h);
|
|
20490
20564
|
return (mod == null ? void 0 : mod.default) || mod;
|
|
20491
20565
|
} catch {
|
|
20492
|
-
const mod2 = await import("./html2pdf.bundle-
|
|
20566
|
+
const mod2 = await import("./html2pdf.bundle-08dfd2d4.js").then((n) => n.h);
|
|
20493
20567
|
return (mod2 == null ? void 0 : mod2.default) || mod2;
|
|
20494
20568
|
}
|
|
20495
20569
|
};
|
|
@@ -27805,7 +27879,7 @@ const STATIC_SUGGESTIONS = [
|
|
|
27805
27879
|
"programming"
|
|
27806
27880
|
];
|
|
27807
27881
|
const CACHE_MAX_AGE = 5 * 60 * 1e3;
|
|
27808
|
-
const MAX_CACHE_SIZE = 200;
|
|
27882
|
+
const MAX_CACHE_SIZE$1 = 200;
|
|
27809
27883
|
const REQUEST_TIMEOUT = 3e4;
|
|
27810
27884
|
const MENU_CONFIG = { width: 320, height: 200, padding: 8 };
|
|
27811
27885
|
const TOOLTIP_CONFIG = {
|
|
@@ -27977,7 +28051,7 @@ class GrammarAIService {
|
|
|
27977
28051
|
errors,
|
|
27978
28052
|
checkedAt: Date.now()
|
|
27979
28053
|
});
|
|
27980
|
-
if (this.sentenceCache.size > MAX_CACHE_SIZE) {
|
|
28054
|
+
if (this.sentenceCache.size > MAX_CACHE_SIZE$1) {
|
|
27981
28055
|
const oldestKey = this.sentenceCache.keys().next().value;
|
|
27982
28056
|
if (oldestKey)
|
|
27983
28057
|
this.sentenceCache.delete(oldestKey);
|
|
@@ -31361,7 +31435,51 @@ function LinkPlugin({
|
|
|
31361
31435
|
}
|
|
31362
31436
|
);
|
|
31363
31437
|
}
|
|
31364
|
-
|
|
31438
|
+
const cache = /* @__PURE__ */ new Map();
|
|
31439
|
+
const CACHE_TTL = 30 * 60 * 1e3;
|
|
31440
|
+
const MAX_CACHE_SIZE = 100;
|
|
31441
|
+
function getCached(url) {
|
|
31442
|
+
const entry = cache.get(url);
|
|
31443
|
+
if (!entry)
|
|
31444
|
+
return null;
|
|
31445
|
+
if (Date.now() - entry.timestamp > CACHE_TTL) {
|
|
31446
|
+
cache.delete(url);
|
|
31447
|
+
return null;
|
|
31448
|
+
}
|
|
31449
|
+
return entry.data;
|
|
31450
|
+
}
|
|
31451
|
+
function setCache(url, data) {
|
|
31452
|
+
if (cache.size >= MAX_CACHE_SIZE) {
|
|
31453
|
+
const oldestKey = cache.keys().next().value;
|
|
31454
|
+
if (oldestKey)
|
|
31455
|
+
cache.delete(oldestKey);
|
|
31456
|
+
}
|
|
31457
|
+
cache.set(url, { data, timestamp: Date.now() });
|
|
31458
|
+
}
|
|
31459
|
+
async function fetchLinkPreview({
|
|
31460
|
+
url,
|
|
31461
|
+
apiKey
|
|
31462
|
+
}) {
|
|
31463
|
+
const cached = getCached(url);
|
|
31464
|
+
if (cached)
|
|
31465
|
+
return cached;
|
|
31466
|
+
try {
|
|
31467
|
+
const response = await backendAPI.post(
|
|
31468
|
+
apiEndpoints.linkPreview.getPreview,
|
|
31469
|
+
{ url },
|
|
31470
|
+
apiKey ? { headers: { "X-API-Key": apiKey } } : void 0
|
|
31471
|
+
);
|
|
31472
|
+
if (response.data.success && response.data.data) {
|
|
31473
|
+
setCache(url, response.data.data);
|
|
31474
|
+
return response.data.data;
|
|
31475
|
+
}
|
|
31476
|
+
return null;
|
|
31477
|
+
} catch (error) {
|
|
31478
|
+
console.error("Error fetching link preview:", error);
|
|
31479
|
+
return null;
|
|
31480
|
+
}
|
|
31481
|
+
}
|
|
31482
|
+
function LinkPreviewPlugin({ apiKey }) {
|
|
31365
31483
|
const [editor] = useLexicalComposerContext();
|
|
31366
31484
|
const [hoveredLink, setHoveredLink] = useState$1(null);
|
|
31367
31485
|
useEffect$1(() => {
|
|
@@ -31385,20 +31503,14 @@ function LinkPreviewPlugin() {
|
|
|
31385
31503
|
if (linkElement && editorElement.contains(linkElement)) {
|
|
31386
31504
|
const href = linkElement.getAttribute("href");
|
|
31387
31505
|
if (href && href !== "https://" && href !== "http://" && href !== "#") {
|
|
31388
|
-
if (showTimeout)
|
|
31506
|
+
if (showTimeout)
|
|
31389
31507
|
clearTimeout(showTimeout);
|
|
31390
|
-
}
|
|
31391
31508
|
if (hideTimeout) {
|
|
31392
31509
|
clearTimeout(hideTimeout);
|
|
31393
31510
|
hideTimeout = null;
|
|
31394
31511
|
}
|
|
31395
31512
|
showTimeout = window.setTimeout(() => {
|
|
31396
|
-
|
|
31397
|
-
setHoveredLink({
|
|
31398
|
-
url: href,
|
|
31399
|
-
text: linkElement.textContent || "",
|
|
31400
|
-
rect
|
|
31401
|
-
});
|
|
31513
|
+
setHoveredLink({ url: href, rect: linkElement.getBoundingClientRect() });
|
|
31402
31514
|
}, 500);
|
|
31403
31515
|
}
|
|
31404
31516
|
}
|
|
@@ -31408,12 +31520,10 @@ function LinkPreviewPlugin() {
|
|
|
31408
31520
|
const relatedTarget = event.relatedTarget;
|
|
31409
31521
|
if (target.closest(".link-preview-card")) {
|
|
31410
31522
|
isOverPreview = false;
|
|
31411
|
-
|
|
31412
|
-
if (!movingToLink) {
|
|
31523
|
+
if (!(relatedTarget == null ? void 0 : relatedTarget.closest("a"))) {
|
|
31413
31524
|
hideTimeout = window.setTimeout(() => {
|
|
31414
|
-
if (!isOverPreview)
|
|
31525
|
+
if (!isOverPreview)
|
|
31415
31526
|
setHoveredLink(null);
|
|
31416
|
-
}
|
|
31417
31527
|
}, 300);
|
|
31418
31528
|
}
|
|
31419
31529
|
return;
|
|
@@ -31424,19 +31534,16 @@ function LinkPreviewPlugin() {
|
|
|
31424
31534
|
clearTimeout(showTimeout);
|
|
31425
31535
|
showTimeout = null;
|
|
31426
31536
|
}
|
|
31427
|
-
|
|
31428
|
-
if (!movingToPreview) {
|
|
31537
|
+
if (!(relatedTarget == null ? void 0 : relatedTarget.closest(".link-preview-card"))) {
|
|
31429
31538
|
hideTimeout = window.setTimeout(() => {
|
|
31430
|
-
if (!isOverPreview)
|
|
31539
|
+
if (!isOverPreview)
|
|
31431
31540
|
setHoveredLink(null);
|
|
31432
|
-
}
|
|
31433
31541
|
}, 300);
|
|
31434
31542
|
}
|
|
31435
31543
|
}
|
|
31436
31544
|
};
|
|
31437
31545
|
const handlePreviewMouseOver = (event) => {
|
|
31438
|
-
|
|
31439
|
-
if (target.closest(".link-preview-card")) {
|
|
31546
|
+
if (event.target.closest(".link-preview-card")) {
|
|
31440
31547
|
isOverPreview = true;
|
|
31441
31548
|
if (hideTimeout) {
|
|
31442
31549
|
clearTimeout(hideTimeout);
|
|
@@ -31449,12 +31556,10 @@ function LinkPreviewPlugin() {
|
|
|
31449
31556
|
const relatedTarget = event.relatedTarget;
|
|
31450
31557
|
if (target.closest(".link-preview-card")) {
|
|
31451
31558
|
isOverPreview = false;
|
|
31452
|
-
|
|
31453
|
-
if (!movingToLink || !editorElement.contains(movingToLink)) {
|
|
31559
|
+
if (!(relatedTarget == null ? void 0 : relatedTarget.closest("a")) || !editorElement.contains(relatedTarget)) {
|
|
31454
31560
|
hideTimeout = window.setTimeout(() => {
|
|
31455
|
-
if (!isOverPreview)
|
|
31561
|
+
if (!isOverPreview)
|
|
31456
31562
|
setHoveredLink(null);
|
|
31457
|
-
}
|
|
31458
31563
|
}, 300);
|
|
31459
31564
|
}
|
|
31460
31565
|
}
|
|
@@ -31464,216 +31569,241 @@ function LinkPreviewPlugin() {
|
|
|
31464
31569
|
document.body.addEventListener("mouseover", handlePreviewMouseOver);
|
|
31465
31570
|
document.body.addEventListener("mouseout", handlePreviewMouseOut);
|
|
31466
31571
|
return () => {
|
|
31467
|
-
if (showTimeout)
|
|
31572
|
+
if (showTimeout)
|
|
31468
31573
|
clearTimeout(showTimeout);
|
|
31469
|
-
|
|
31470
|
-
if (hideTimeout) {
|
|
31574
|
+
if (hideTimeout)
|
|
31471
31575
|
clearTimeout(hideTimeout);
|
|
31472
|
-
}
|
|
31473
31576
|
editorElement.removeEventListener("mouseover", handleMouseOver);
|
|
31474
31577
|
editorElement.removeEventListener("mouseout", handleMouseOut);
|
|
31475
31578
|
document.body.removeEventListener("mouseover", handlePreviewMouseOver);
|
|
31476
31579
|
document.body.removeEventListener("mouseout", handlePreviewMouseOut);
|
|
31477
31580
|
};
|
|
31478
31581
|
}, [editor]);
|
|
31479
|
-
if (!hoveredLink)
|
|
31582
|
+
if (!hoveredLink)
|
|
31480
31583
|
return null;
|
|
31481
|
-
}
|
|
31482
31584
|
return createPortal(
|
|
31483
31585
|
/* @__PURE__ */ jsx(
|
|
31484
31586
|
LinkPreview,
|
|
31485
31587
|
{
|
|
31486
31588
|
url: hoveredLink.url,
|
|
31487
31589
|
rect: hoveredLink.rect,
|
|
31590
|
+
apiKey,
|
|
31488
31591
|
onClose: () => setHoveredLink(null)
|
|
31489
31592
|
}
|
|
31490
31593
|
),
|
|
31491
31594
|
document.body
|
|
31492
31595
|
);
|
|
31493
31596
|
}
|
|
31494
|
-
|
|
31597
|
+
const PREVIEW_WIDTH = 320;
|
|
31598
|
+
function LinkPreview({ url, rect, apiKey, onClose }) {
|
|
31495
31599
|
const [position, setPosition] = useState$1({ top: 0, left: 0 });
|
|
31600
|
+
const [previewData, setPreviewData] = useState$1(null);
|
|
31601
|
+
const [isLoading, setIsLoading] = useState$1(true);
|
|
31602
|
+
const [hasError, setHasError] = useState$1(false);
|
|
31603
|
+
const fetchedRef = useRef(false);
|
|
31496
31604
|
useEffect$1(() => {
|
|
31497
|
-
|
|
31498
|
-
|
|
31605
|
+
if (fetchedRef.current)
|
|
31606
|
+
return;
|
|
31607
|
+
fetchedRef.current = true;
|
|
31608
|
+
setIsLoading(true);
|
|
31609
|
+
setHasError(false);
|
|
31610
|
+
fetchLinkPreview({ url, apiKey }).then((data) => {
|
|
31611
|
+
if (data)
|
|
31612
|
+
setPreviewData(data);
|
|
31613
|
+
else
|
|
31614
|
+
setHasError(true);
|
|
31615
|
+
}).catch(() => setHasError(true)).finally(() => setIsLoading(false));
|
|
31616
|
+
}, [url, apiKey]);
|
|
31617
|
+
useEffect$1(() => {
|
|
31618
|
+
const previewHeight = (previewData == null ? void 0 : previewData.image) ? 280 : 160;
|
|
31499
31619
|
let top = rect.top + window.scrollY - previewHeight - 10;
|
|
31500
31620
|
if (rect.top - previewHeight - 10 < 0) {
|
|
31501
31621
|
top = rect.bottom + window.scrollY + 10;
|
|
31502
31622
|
}
|
|
31503
|
-
let left = rect.left + window.scrollX + rect.width / 2 -
|
|
31623
|
+
let left = rect.left + window.scrollX + rect.width / 2 - PREVIEW_WIDTH / 2;
|
|
31504
31624
|
const viewportWidth = window.innerWidth;
|
|
31505
|
-
if (left < 10)
|
|
31625
|
+
if (left < 10)
|
|
31506
31626
|
left = 10;
|
|
31507
|
-
|
|
31508
|
-
left = viewportWidth -
|
|
31509
|
-
}
|
|
31627
|
+
else if (left + PREVIEW_WIDTH > viewportWidth - 10)
|
|
31628
|
+
left = viewportWidth - PREVIEW_WIDTH - 10;
|
|
31510
31629
|
setPosition({ top, left });
|
|
31511
|
-
}, [rect]);
|
|
31630
|
+
}, [rect, previewData]);
|
|
31512
31631
|
const getDomain = (urlString) => {
|
|
31513
31632
|
try {
|
|
31514
|
-
|
|
31515
|
-
return urlObj.hostname.replace("www.", "");
|
|
31633
|
+
return new URL(urlString).hostname.replace("www.", "");
|
|
31516
31634
|
} catch {
|
|
31517
31635
|
return urlString;
|
|
31518
31636
|
}
|
|
31519
31637
|
};
|
|
31520
31638
|
const domain = getDomain(url);
|
|
31521
|
-
const
|
|
31522
|
-
|
|
31523
|
-
|
|
31524
|
-
|
|
31525
|
-
|
|
31526
|
-
|
|
31639
|
+
const TypeIcon = ({ type }) => {
|
|
31640
|
+
const iconProps = { style: { width: "14px", height: "14px" }, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" };
|
|
31641
|
+
const pathProps = { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2 };
|
|
31642
|
+
switch (type) {
|
|
31643
|
+
case "image":
|
|
31644
|
+
return /* @__PURE__ */ jsx("svg", { ...iconProps, children: /* @__PURE__ */ jsx("path", { ...pathProps, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) });
|
|
31645
|
+
case "video":
|
|
31646
|
+
return /* @__PURE__ */ jsxs("svg", { ...iconProps, children: [
|
|
31647
|
+
/* @__PURE__ */ jsx("path", { ...pathProps, d: "M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z" }),
|
|
31648
|
+
/* @__PURE__ */ jsx("path", { ...pathProps, d: "M21 12a9 9 0 11-18 0 9 9 0 0118 0z" })
|
|
31649
|
+
] });
|
|
31650
|
+
case "pdf":
|
|
31651
|
+
return /* @__PURE__ */ jsx("svg", { ...iconProps, children: /* @__PURE__ */ jsx("path", { ...pathProps, d: "M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" }) });
|
|
31652
|
+
default:
|
|
31653
|
+
return /* @__PURE__ */ jsx("svg", { ...iconProps, children: /* @__PURE__ */ jsx("path", { ...pathProps, d: "M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9" }) });
|
|
31527
31654
|
}
|
|
31528
31655
|
};
|
|
31529
|
-
const
|
|
31530
|
-
|
|
31531
|
-
|
|
31532
|
-
{
|
|
31533
|
-
|
|
31534
|
-
|
|
31535
|
-
|
|
31536
|
-
|
|
31537
|
-
|
|
31538
|
-
|
|
31539
|
-
|
|
31540
|
-
|
|
31541
|
-
|
|
31542
|
-
|
|
31543
|
-
|
|
31544
|
-
|
|
31545
|
-
|
|
31546
|
-
|
|
31547
|
-
|
|
31548
|
-
|
|
31549
|
-
|
|
31550
|
-
|
|
31551
|
-
|
|
31552
|
-
|
|
31553
|
-
|
|
31554
|
-
|
|
31555
|
-
|
|
31556
|
-
|
|
31557
|
-
|
|
31558
|
-
|
|
31559
|
-
|
|
31560
|
-
|
|
31561
|
-
|
|
31562
|
-
|
|
31563
|
-
|
|
31564
|
-
|
|
31565
|
-
|
|
31566
|
-
|
|
31567
|
-
|
|
31568
|
-
|
|
31569
|
-
|
|
31570
|
-
|
|
31571
|
-
|
|
31572
|
-
|
|
31573
|
-
|
|
31574
|
-
|
|
31575
|
-
|
|
31576
|
-
|
|
31577
|
-
|
|
31578
|
-
|
|
31579
|
-
|
|
31580
|
-
|
|
31581
|
-
|
|
31582
|
-
|
|
31583
|
-
|
|
31584
|
-
|
|
31585
|
-
|
|
31586
|
-
|
|
31587
|
-
|
|
31588
|
-
|
|
31589
|
-
|
|
31590
|
-
|
|
31591
|
-
|
|
31592
|
-
|
|
31593
|
-
|
|
31594
|
-
|
|
31595
|
-
|
|
31596
|
-
|
|
31597
|
-
|
|
31598
|
-
|
|
31599
|
-
|
|
31600
|
-
|
|
31601
|
-
|
|
31602
|
-
|
|
31603
|
-
|
|
31656
|
+
const cardStyle = {
|
|
31657
|
+
position: "absolute",
|
|
31658
|
+
top: `${position.top}px`,
|
|
31659
|
+
left: `${position.left}px`,
|
|
31660
|
+
zIndex: 1e4,
|
|
31661
|
+
pointerEvents: "auto",
|
|
31662
|
+
animation: "linkPreviewFadeIn 0.2s ease-out"
|
|
31663
|
+
};
|
|
31664
|
+
const containerStyle = {
|
|
31665
|
+
width: `${PREVIEW_WIDTH}px`,
|
|
31666
|
+
backgroundColor: "#1e1e1e",
|
|
31667
|
+
borderRadius: "12px",
|
|
31668
|
+
boxShadow: "0 10px 40px rgba(0, 0, 0, 0.4)",
|
|
31669
|
+
overflow: "hidden",
|
|
31670
|
+
position: "relative",
|
|
31671
|
+
border: "1px solid #333"
|
|
31672
|
+
};
|
|
31673
|
+
const closeButtonStyle = {
|
|
31674
|
+
position: "absolute",
|
|
31675
|
+
top: "8px",
|
|
31676
|
+
right: "8px",
|
|
31677
|
+
width: "24px",
|
|
31678
|
+
height: "24px",
|
|
31679
|
+
borderRadius: "6px",
|
|
31680
|
+
backgroundColor: "rgba(0,0,0,0.5)",
|
|
31681
|
+
border: "none",
|
|
31682
|
+
cursor: "pointer",
|
|
31683
|
+
display: "flex",
|
|
31684
|
+
alignItems: "center",
|
|
31685
|
+
justifyContent: "center",
|
|
31686
|
+
zIndex: 10
|
|
31687
|
+
};
|
|
31688
|
+
return /* @__PURE__ */ jsxs("div", { className: "link-preview-card", style: cardStyle, children: [
|
|
31689
|
+
/* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
|
|
31690
|
+
/* @__PURE__ */ jsx(
|
|
31691
|
+
"button",
|
|
31692
|
+
{
|
|
31693
|
+
onClick: (e) => {
|
|
31694
|
+
e.preventDefault();
|
|
31695
|
+
e.stopPropagation();
|
|
31696
|
+
onClose();
|
|
31697
|
+
},
|
|
31698
|
+
style: closeButtonStyle,
|
|
31699
|
+
onMouseEnter: (e) => {
|
|
31700
|
+
e.currentTarget.style.backgroundColor = "rgba(0,0,0,0.7)";
|
|
31701
|
+
},
|
|
31702
|
+
onMouseLeave: (e) => {
|
|
31703
|
+
e.currentTarget.style.backgroundColor = "rgba(0,0,0,0.5)";
|
|
31704
|
+
},
|
|
31705
|
+
title: "Close preview",
|
|
31706
|
+
children: /* @__PURE__ */ jsx("svg", { style: { width: "14px", height: "14px", color: "#fff" }, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
31707
|
+
}
|
|
31708
|
+
),
|
|
31709
|
+
isLoading && /* @__PURE__ */ jsxs("div", { style: { padding: "40px", textAlign: "center" }, children: [
|
|
31710
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
31711
|
+
width: "24px",
|
|
31712
|
+
height: "24px",
|
|
31713
|
+
border: "2px solid #444",
|
|
31714
|
+
borderTopColor: "#fff",
|
|
31715
|
+
borderRadius: "50%",
|
|
31716
|
+
animation: "linkPreviewSpin 1s linear infinite",
|
|
31717
|
+
margin: "0 auto 12px"
|
|
31718
|
+
} }),
|
|
31719
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: "12px", color: "#888" }, children: "Loading preview..." })
|
|
31720
|
+
] }),
|
|
31721
|
+
!isLoading && hasError && /* @__PURE__ */ jsxs("div", { style: { padding: "16px" }, children: [
|
|
31722
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "12px" }, children: [
|
|
31723
|
+
/* @__PURE__ */ jsx("svg", { style: { width: "16px", height: "16px", color: "#fff" }, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" }) }),
|
|
31724
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "14px", fontWeight: "600", color: "#fff" }, children: domain })
|
|
31725
|
+
] }),
|
|
31726
|
+
/* @__PURE__ */ jsx("div", { style: { backgroundColor: "#2a2a2a", padding: "10px", borderRadius: "6px" }, children: /* @__PURE__ */ jsx("p", { style: { fontSize: "12px", color: "#ccc", wordBreak: "break-all", lineHeight: "1.5" }, children: url }) })
|
|
31727
|
+
] }),
|
|
31728
|
+
!isLoading && !hasError && previewData && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31729
|
+
previewData.image && /* @__PURE__ */ jsx("div", { style: {
|
|
31730
|
+
width: "100%",
|
|
31731
|
+
height: "140px",
|
|
31732
|
+
backgroundColor: "#2a2a2a",
|
|
31733
|
+
backgroundImage: `url(${previewData.image})`,
|
|
31734
|
+
backgroundSize: "cover",
|
|
31735
|
+
backgroundPosition: "center"
|
|
31736
|
+
} }),
|
|
31737
|
+
/* @__PURE__ */ jsxs("div", { style: { padding: "14px" }, children: [
|
|
31738
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "10px" }, children: [
|
|
31739
|
+
previewData.favicon ? /* @__PURE__ */ jsx(
|
|
31740
|
+
"img",
|
|
31741
|
+
{
|
|
31742
|
+
src: previewData.favicon,
|
|
31743
|
+
alt: "",
|
|
31744
|
+
style: { width: "16px", height: "16px", borderRadius: "2px", objectFit: "contain" },
|
|
31745
|
+
onError: (e) => {
|
|
31746
|
+
e.currentTarget.style.display = "none";
|
|
31604
31747
|
}
|
|
31605
|
-
|
|
31606
|
-
|
|
31607
|
-
|
|
31608
|
-
|
|
31609
|
-
|
|
31610
|
-
|
|
31611
|
-
|
|
31612
|
-
|
|
31613
|
-
|
|
31614
|
-
|
|
31615
|
-
|
|
31616
|
-
|
|
31617
|
-
|
|
31618
|
-
|
|
31619
|
-
|
|
31620
|
-
|
|
31621
|
-
|
|
31622
|
-
|
|
31623
|
-
|
|
31624
|
-
|
|
31625
|
-
|
|
31626
|
-
|
|
31627
|
-
|
|
31628
|
-
|
|
31629
|
-
|
|
31630
|
-
|
|
31631
|
-
|
|
31632
|
-
|
|
31633
|
-
|
|
31634
|
-
|
|
31635
|
-
|
|
31636
|
-
|
|
31637
|
-
|
|
31638
|
-
|
|
31639
|
-
|
|
31640
|
-
|
|
31641
|
-
|
|
31642
|
-
|
|
31643
|
-
|
|
31644
|
-
|
|
31645
|
-
|
|
31646
|
-
|
|
31647
|
-
|
|
31648
|
-
|
|
31649
|
-
|
|
31650
|
-
|
|
31651
|
-
|
|
31652
|
-
|
|
31653
|
-
|
|
31654
|
-
@keyframes
|
|
31655
|
-
from {
|
|
31656
|
-
|
|
31657
|
-
transform: translateY(5px);
|
|
31658
|
-
}
|
|
31659
|
-
to {
|
|
31660
|
-
opacity: 1;
|
|
31661
|
-
transform: translateY(0);
|
|
31662
|
-
}
|
|
31748
|
+
}
|
|
31749
|
+
) : /* @__PURE__ */ jsx("span", { style: { color: "#888" }, children: /* @__PURE__ */ jsx(TypeIcon, { type: previewData.type }) }),
|
|
31750
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "12px", color: "#888", flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: previewData.siteName || domain }),
|
|
31751
|
+
/* @__PURE__ */ jsx("span", { style: {
|
|
31752
|
+
fontSize: "10px",
|
|
31753
|
+
color: "#666",
|
|
31754
|
+
padding: "2px 6px",
|
|
31755
|
+
backgroundColor: "#333",
|
|
31756
|
+
borderRadius: "4px",
|
|
31757
|
+
textTransform: "uppercase"
|
|
31758
|
+
}, children: previewData.type })
|
|
31759
|
+
] }),
|
|
31760
|
+
previewData.title && /* @__PURE__ */ jsx("h4", { style: {
|
|
31761
|
+
fontSize: "14px",
|
|
31762
|
+
fontWeight: "600",
|
|
31763
|
+
color: "#fff",
|
|
31764
|
+
marginBottom: "6px",
|
|
31765
|
+
lineHeight: "1.4",
|
|
31766
|
+
display: "-webkit-box",
|
|
31767
|
+
WebkitLineClamp: 2,
|
|
31768
|
+
WebkitBoxOrient: "vertical",
|
|
31769
|
+
overflow: "hidden"
|
|
31770
|
+
}, children: previewData.title }),
|
|
31771
|
+
previewData.description && /* @__PURE__ */ jsx("p", { style: {
|
|
31772
|
+
fontSize: "12px",
|
|
31773
|
+
color: "#999",
|
|
31774
|
+
lineHeight: "1.5",
|
|
31775
|
+
display: "-webkit-box",
|
|
31776
|
+
WebkitLineClamp: 2,
|
|
31777
|
+
WebkitBoxOrient: "vertical",
|
|
31778
|
+
overflow: "hidden",
|
|
31779
|
+
marginBottom: "10px"
|
|
31780
|
+
}, children: previewData.description }),
|
|
31781
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
31782
|
+
display: "flex",
|
|
31783
|
+
alignItems: "center",
|
|
31784
|
+
gap: "6px",
|
|
31785
|
+
padding: "8px 10px",
|
|
31786
|
+
backgroundColor: "#252525",
|
|
31787
|
+
borderRadius: "6px",
|
|
31788
|
+
marginTop: "8px"
|
|
31789
|
+
}, children: [
|
|
31790
|
+
/* @__PURE__ */ jsx("svg", { style: { width: "12px", height: "12px", color: "#666", flexShrink: 0 }, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1" }) }),
|
|
31791
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: "#888", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: url })
|
|
31792
|
+
] })
|
|
31793
|
+
] })
|
|
31794
|
+
] })
|
|
31795
|
+
] }),
|
|
31796
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
31797
|
+
@keyframes linkPreviewFadeIn {
|
|
31798
|
+
from { opacity: 0; transform: translateY(5px); }
|
|
31799
|
+
to { opacity: 1; transform: translateY(0); }
|
|
31663
31800
|
}
|
|
31664
|
-
|
|
31665
|
-
|
|
31666
|
-
|
|
31667
|
-
opacity: 1;
|
|
31668
|
-
}
|
|
31669
|
-
50% {
|
|
31670
|
-
opacity: 0.6;
|
|
31671
|
-
}
|
|
31801
|
+
@keyframes linkPreviewSpin {
|
|
31802
|
+
from { transform: rotate(0deg); }
|
|
31803
|
+
to { transform: rotate(360deg); }
|
|
31672
31804
|
}
|
|
31673
31805
|
` })
|
|
31674
|
-
|
|
31675
|
-
}
|
|
31676
|
-
);
|
|
31806
|
+
] });
|
|
31677
31807
|
}
|
|
31678
31808
|
const debounce = (fn, delay) => {
|
|
31679
31809
|
let timeoutID;
|
|
@@ -32887,7 +33017,56 @@ function RichTextPastePlugin() {
|
|
|
32887
33017
|
return true;
|
|
32888
33018
|
});
|
|
32889
33019
|
if (filteredNodes.length > 0) {
|
|
32890
|
-
selection.
|
|
33020
|
+
const anchorNode = selection.anchor.getNode();
|
|
33021
|
+
const anchorParent = anchorNode.getParent();
|
|
33022
|
+
const isInsideParagraphWithContent = anchorParent instanceof ElementNode && anchorParent.getType() === "paragraph" && anchorParent.getTextContent().trim().length > 0;
|
|
33023
|
+
if (isInsideParagraphWithContent) {
|
|
33024
|
+
for (const node of filteredNodes) {
|
|
33025
|
+
if ($isImageNode(node)) {
|
|
33026
|
+
const currentSelection = $getSelection();
|
|
33027
|
+
if ($isRangeSelection(currentSelection)) {
|
|
33028
|
+
const currentAnchor = currentSelection.anchor.getNode();
|
|
33029
|
+
const currentParent = currentAnchor.getParent();
|
|
33030
|
+
if (currentParent instanceof ElementNode && currentParent.getType() === "paragraph") {
|
|
33031
|
+
const imageParagraph = $createParagraphNode();
|
|
33032
|
+
imageParagraph.append(node);
|
|
33033
|
+
currentParent.insertAfter(imageParagraph);
|
|
33034
|
+
imageParagraph.selectEnd();
|
|
33035
|
+
} else {
|
|
33036
|
+
currentSelection.insertNodes([node]);
|
|
33037
|
+
}
|
|
33038
|
+
}
|
|
33039
|
+
} else if (node instanceof ParagraphNode) {
|
|
33040
|
+
const children = node.getChildren();
|
|
33041
|
+
const hasOnlyImage = children.length === 1 && $isImageNode(children[0]);
|
|
33042
|
+
if (hasOnlyImage) {
|
|
33043
|
+
const currentSelection = $getSelection();
|
|
33044
|
+
if ($isRangeSelection(currentSelection)) {
|
|
33045
|
+
const currentAnchor = currentSelection.anchor.getNode();
|
|
33046
|
+
const currentParent = currentAnchor.getParent();
|
|
33047
|
+
if (currentParent instanceof ElementNode && currentParent.getType() === "paragraph") {
|
|
33048
|
+
currentParent.insertAfter(node);
|
|
33049
|
+
node.selectEnd();
|
|
33050
|
+
} else {
|
|
33051
|
+
currentSelection.insertNodes([node]);
|
|
33052
|
+
}
|
|
33053
|
+
}
|
|
33054
|
+
} else {
|
|
33055
|
+
const currentSelection = $getSelection();
|
|
33056
|
+
if ($isRangeSelection(currentSelection)) {
|
|
33057
|
+
currentSelection.insertNodes([node]);
|
|
33058
|
+
}
|
|
33059
|
+
}
|
|
33060
|
+
} else {
|
|
33061
|
+
const currentSelection = $getSelection();
|
|
33062
|
+
if ($isRangeSelection(currentSelection)) {
|
|
33063
|
+
currentSelection.insertNodes([node]);
|
|
33064
|
+
}
|
|
33065
|
+
}
|
|
33066
|
+
}
|
|
33067
|
+
} else {
|
|
33068
|
+
selection.insertNodes(filteredNodes);
|
|
33069
|
+
}
|
|
32891
33070
|
}
|
|
32892
33071
|
}
|
|
32893
33072
|
} catch (error) {
|
|
@@ -38608,4 +38787,4 @@ export {
|
|
|
38608
38787
|
useHtmlView as u,
|
|
38609
38788
|
verifyApiKey as v
|
|
38610
38789
|
};
|
|
38611
|
-
//# sourceMappingURL=index-
|
|
38790
|
+
//# sourceMappingURL=index-d1d21414.js.map
|