ct-rich-text-editor 1.3.26 → 1.3.28
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 +86 -4
- package/dist/components/ImageView/index.d.ts +2 -1
- package/dist/{html2pdf.bundle-41a72ab2.js → html2pdf.bundle-0e71462c.js} +2 -2
- package/dist/{html2pdf.bundle-41a72ab2.js.map → html2pdf.bundle-0e71462c.js.map} +1 -1
- package/dist/{html2pdf.bundle.min-1f376935.js → html2pdf.bundle.min-d2f5d9cb.js} +2 -2
- package/dist/{html2pdf.bundle.min-1f376935.js.map → html2pdf.bundle.min-d2f5d9cb.js.map} +1 -1
- package/dist/{index-9b519a99.js → index-03cae849.js} +2 -15
- package/dist/index-03cae849.js.map +1 -0
- package/dist/{index-a2107b7c.js → index-0533674e.js} +2101 -276
- package/dist/index-0533674e.js.map +1 -0
- package/dist/{index-01a6d110.js → index-c26337f6.js} +216 -12
- package/dist/index-c26337f6.js.map +1 -0
- package/dist/index.js +5 -5
- package/dist/nodes/ImageNode.d.ts +9 -3
- package/dist/plugins/LinkPreviewPlugin/index.d.ts +3 -1
- package/dist/plugins/MarkdownShortcutsPlugin/index.d.ts +20 -0
- package/dist/plugins/PasteOptionsPlugin/index.d.ts +17 -0
- package/dist/plugins/RichTextPastePlugin/index.d.ts +3 -12
- package/package.json +1 -1
- package/dist/index-01a6d110.js.map +0 -1
- package/dist/index-9b519a99.js.map +0 -1
- package/dist/index-a2107b7c.js.map +0 -1
|
@@ -24,15 +24,15 @@ 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, $insertNodes, $isRootOrShadowRoot, $createParagraphNode, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_LOW, $getSelection, $isRangeSelection, $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";
|
|
27
|
+
import { createCommand, DecoratorNode, createEditor, $applyNodeReplacement, $insertNodes, $isRootOrShadowRoot, $createParagraphNode, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_LOW, $getSelection, $isRangeSelection, $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, KEY_BACKSPACE_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";
|
|
31
31
|
import { LinkNode, $isLinkNode, TOGGLE_LINK_COMMAND, $isAutoLinkNode, $createLinkNode } from "@lexical/link";
|
|
32
|
-
import { ListNode, ListItemNode, $isListNode, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, $createListNode, $createListItemNode } from "@lexical/list";
|
|
32
|
+
import { ListNode, ListItemNode, $isListNode, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, $isListItemNode, $createListNode, $createListItemNode } from "@lexical/list";
|
|
33
33
|
import { HeadingNode, QuoteNode, $isHeadingNode, $createHeadingNode, $createQuoteNode, DRAG_DROP_PASTE } from "@lexical/rich-text";
|
|
34
34
|
import { $isAtNodeEnd, $selectAll, $patchStyleText, $setBlocksType, $getSelectionStyleValueForProperty, $isParentElementRTL } from "@lexical/selection";
|
|
35
|
-
import { HorizontalRuleNode } from "@lexical/react/LexicalHorizontalRuleNode";
|
|
35
|
+
import { HorizontalRuleNode, INSERT_HORIZONTAL_RULE_COMMAND } from "@lexical/react/LexicalHorizontalRuleNode";
|
|
36
36
|
import DescriptionIcon from "@mui/icons-material/Description";
|
|
37
37
|
import FolderZipIcon from "@mui/icons-material/FolderZip";
|
|
38
38
|
import InsertChartIcon from "@mui/icons-material/InsertChart";
|
|
@@ -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-c26337f6.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
|
}
|
|
@@ -1490,14 +1493,14 @@ function $convertImageElement(domNode) {
|
|
|
1490
1493
|
const { alt: altText, src, width, height } = img;
|
|
1491
1494
|
const positionAttr = img.getAttribute("data-position");
|
|
1492
1495
|
let position = "none";
|
|
1493
|
-
if (positionAttr === "left" || positionAttr === "right" || positionAttr === "full") {
|
|
1496
|
+
if (positionAttr === "left" || positionAttr === "right" || positionAttr === "full" || positionAttr === "inline-left" || positionAttr === "inline-center" || positionAttr === "inline-right") {
|
|
1494
1497
|
position = positionAttr;
|
|
1495
1498
|
}
|
|
1496
1499
|
const node = $createImageNode({ altText, height, src, width, position });
|
|
1497
1500
|
return { node };
|
|
1498
1501
|
}
|
|
1499
1502
|
class ImageNode extends DecoratorNode {
|
|
1500
|
-
constructor(src, altText, maxWidth, width, height, showCaption, caption, captionsEnabled, originalPrompt, position, key) {
|
|
1503
|
+
constructor(src, altText, maxWidth, width, height, showCaption, caption, captionsEnabled, originalPrompt, position, linkUrl, key) {
|
|
1501
1504
|
super(key);
|
|
1502
1505
|
__publicField(this, "__src");
|
|
1503
1506
|
__publicField(this, "__altText");
|
|
@@ -1510,6 +1513,7 @@ class ImageNode extends DecoratorNode {
|
|
|
1510
1513
|
__publicField(this, "__captionsEnabled");
|
|
1511
1514
|
__publicField(this, "__originalPrompt");
|
|
1512
1515
|
__publicField(this, "__position");
|
|
1516
|
+
__publicField(this, "__linkUrl");
|
|
1513
1517
|
this.__src = src;
|
|
1514
1518
|
this.__altText = altText;
|
|
1515
1519
|
this.__maxWidth = maxWidth;
|
|
@@ -1522,6 +1526,7 @@ class ImageNode extends DecoratorNode {
|
|
|
1522
1526
|
this.__captionsEnabled = captionsEnabled || captionsEnabled === void 0;
|
|
1523
1527
|
this.__originalPrompt = originalPrompt || "";
|
|
1524
1528
|
this.__position = position || "none";
|
|
1529
|
+
this.__linkUrl = linkUrl || "";
|
|
1525
1530
|
}
|
|
1526
1531
|
// to identify the image node and must unique too
|
|
1527
1532
|
static getType() {
|
|
@@ -1540,12 +1545,13 @@ class ImageNode extends DecoratorNode {
|
|
|
1540
1545
|
node.__captionsEnabled,
|
|
1541
1546
|
node.__originalPrompt,
|
|
1542
1547
|
node.__position,
|
|
1548
|
+
node.__linkUrl,
|
|
1543
1549
|
node.__key
|
|
1544
1550
|
);
|
|
1545
1551
|
}
|
|
1546
1552
|
// importing to json format
|
|
1547
1553
|
static importJSON(serializedNode) {
|
|
1548
|
-
const { altText, height, width, maxWidth, caption, src, showCaption, originalPrompt, position } = serializedNode;
|
|
1554
|
+
const { altText, height, width, maxWidth, caption, src, showCaption, originalPrompt, position, linkUrl } = serializedNode;
|
|
1549
1555
|
const node = $createImageNode({
|
|
1550
1556
|
altText,
|
|
1551
1557
|
height,
|
|
@@ -1555,7 +1561,8 @@ class ImageNode extends DecoratorNode {
|
|
|
1555
1561
|
width,
|
|
1556
1562
|
originalPrompt: originalPrompt || "",
|
|
1557
1563
|
// Default to empty string if undefined
|
|
1558
|
-
position: position || "none"
|
|
1564
|
+
position: position || "none",
|
|
1565
|
+
linkUrl: linkUrl || ""
|
|
1559
1566
|
});
|
|
1560
1567
|
const nestedEditor = node.__caption;
|
|
1561
1568
|
const editorState = nestedEditor.parseEditorState(caption.editorState);
|
|
@@ -1597,7 +1604,8 @@ class ImageNode extends DecoratorNode {
|
|
|
1597
1604
|
version: 1,
|
|
1598
1605
|
width: this.__width === "inherit" ? 0 : this.__width,
|
|
1599
1606
|
originalPrompt: this.__originalPrompt,
|
|
1600
|
-
position: this.__position
|
|
1607
|
+
position: this.__position,
|
|
1608
|
+
linkUrl: this.__linkUrl
|
|
1601
1609
|
};
|
|
1602
1610
|
}
|
|
1603
1611
|
// setting width and height when resizing
|
|
@@ -1611,6 +1619,26 @@ class ImageNode extends DecoratorNode {
|
|
|
1611
1619
|
const writable = this.getWritable();
|
|
1612
1620
|
writable.__showCaption = showCaption;
|
|
1613
1621
|
}
|
|
1622
|
+
// Helper to get position-based CSS styles
|
|
1623
|
+
getPositionStyles() {
|
|
1624
|
+
const cursorStyle = "cursor: pointer;";
|
|
1625
|
+
switch (this.__position) {
|
|
1626
|
+
case "left":
|
|
1627
|
+
return `float: left; margin-right: 1em; margin-bottom: 0.5em; max-width: 50%; display: block; ${cursorStyle}`;
|
|
1628
|
+
case "right":
|
|
1629
|
+
return `float: right; margin-left: 1em; margin-bottom: 0.5em; max-width: 50%; display: block; ${cursorStyle}`;
|
|
1630
|
+
case "full":
|
|
1631
|
+
return `display: block; width: 100%; margin: 1em 0; text-align: center; ${cursorStyle}`;
|
|
1632
|
+
case "inline-left":
|
|
1633
|
+
return `display: block; margin: 1em 0; text-align: left; ${cursorStyle}`;
|
|
1634
|
+
case "inline-center":
|
|
1635
|
+
return `display: block; margin: 1em 0; text-align: center; ${cursorStyle}`;
|
|
1636
|
+
case "inline-right":
|
|
1637
|
+
return `display: block; margin: 1em 0; text-align: right; ${cursorStyle}`;
|
|
1638
|
+
default:
|
|
1639
|
+
return "";
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1614
1642
|
// To create a dom representation of image view
|
|
1615
1643
|
createDOM(config) {
|
|
1616
1644
|
const span = document.createElement("span");
|
|
@@ -1619,24 +1647,18 @@ class ImageNode extends DecoratorNode {
|
|
|
1619
1647
|
if (className !== void 0) {
|
|
1620
1648
|
span.className = className;
|
|
1621
1649
|
}
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
span.style.cssText = "float: right; margin-left: 1em; margin-bottom: 0.5em; max-width: 50%; display: block;";
|
|
1626
|
-
} else if (this.__position === "full") {
|
|
1627
|
-
span.style.cssText = "display: block; width: 100%; margin: 1em 0;";
|
|
1650
|
+
const positionStyles = this.getPositionStyles();
|
|
1651
|
+
if (positionStyles) {
|
|
1652
|
+
span.style.cssText = positionStyles;
|
|
1628
1653
|
}
|
|
1629
1654
|
return span;
|
|
1630
1655
|
}
|
|
1631
1656
|
updateDOM(prevNode, dom) {
|
|
1632
1657
|
if (prevNode.__position !== this.__position) {
|
|
1633
1658
|
dom.style.cssText = "";
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
dom.style.cssText = "float: right; margin-left: 1em; margin-bottom: 0.5em; max-width: 50%; display: block;";
|
|
1638
|
-
} else if (this.__position === "full") {
|
|
1639
|
-
dom.style.cssText = "display: block; width: 100%; margin: 1em 0;";
|
|
1659
|
+
const positionStyles = this.getPositionStyles();
|
|
1660
|
+
if (positionStyles) {
|
|
1661
|
+
dom.style.cssText = positionStyles;
|
|
1640
1662
|
}
|
|
1641
1663
|
}
|
|
1642
1664
|
return false;
|
|
@@ -1671,6 +1693,15 @@ class ImageNode extends DecoratorNode {
|
|
|
1671
1693
|
const writable = this.getWritable();
|
|
1672
1694
|
writable.__position = position;
|
|
1673
1695
|
}
|
|
1696
|
+
// to get the link URL (if image was wrapped in a link)
|
|
1697
|
+
getLinkUrl() {
|
|
1698
|
+
return this.__linkUrl;
|
|
1699
|
+
}
|
|
1700
|
+
// to set the link URL
|
|
1701
|
+
setLinkUrl(linkUrl) {
|
|
1702
|
+
const writable = this.getWritable();
|
|
1703
|
+
writable.__linkUrl = linkUrl;
|
|
1704
|
+
}
|
|
1674
1705
|
// to render the image tag
|
|
1675
1706
|
decorate() {
|
|
1676
1707
|
return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
@@ -1687,7 +1718,8 @@ class ImageNode extends DecoratorNode {
|
|
|
1687
1718
|
captionsEnabled: this.__captionsEnabled,
|
|
1688
1719
|
resizable: true,
|
|
1689
1720
|
originalPrompt: this.__originalPrompt,
|
|
1690
|
-
position: this.__position
|
|
1721
|
+
position: this.__position,
|
|
1722
|
+
linkUrl: this.__linkUrl
|
|
1691
1723
|
}
|
|
1692
1724
|
) });
|
|
1693
1725
|
}
|
|
@@ -1703,7 +1735,8 @@ function $createImageNode({
|
|
|
1703
1735
|
caption,
|
|
1704
1736
|
key,
|
|
1705
1737
|
originalPrompt,
|
|
1706
|
-
position
|
|
1738
|
+
position,
|
|
1739
|
+
linkUrl
|
|
1707
1740
|
}) {
|
|
1708
1741
|
return $applyNodeReplacement(
|
|
1709
1742
|
new ImageNode(
|
|
@@ -1717,6 +1750,7 @@ function $createImageNode({
|
|
|
1717
1750
|
captionsEnabled,
|
|
1718
1751
|
originalPrompt,
|
|
1719
1752
|
position,
|
|
1753
|
+
linkUrl,
|
|
1720
1754
|
key
|
|
1721
1755
|
)
|
|
1722
1756
|
);
|
|
@@ -2111,20 +2145,20 @@ const createLruCache = (maxCacheSize) => {
|
|
|
2111
2145
|
};
|
|
2112
2146
|
}
|
|
2113
2147
|
let cacheSize = 0;
|
|
2114
|
-
let
|
|
2148
|
+
let cache2 = /* @__PURE__ */ Object.create(null);
|
|
2115
2149
|
let previousCache = /* @__PURE__ */ Object.create(null);
|
|
2116
2150
|
const update = (key, value) => {
|
|
2117
|
-
|
|
2151
|
+
cache2[key] = value;
|
|
2118
2152
|
cacheSize++;
|
|
2119
2153
|
if (cacheSize > maxCacheSize) {
|
|
2120
2154
|
cacheSize = 0;
|
|
2121
|
-
previousCache =
|
|
2122
|
-
|
|
2155
|
+
previousCache = cache2;
|
|
2156
|
+
cache2 = /* @__PURE__ */ Object.create(null);
|
|
2123
2157
|
}
|
|
2124
2158
|
};
|
|
2125
2159
|
return {
|
|
2126
2160
|
get(key) {
|
|
2127
|
-
let value =
|
|
2161
|
+
let value = cache2[key];
|
|
2128
2162
|
if (value !== void 0) {
|
|
2129
2163
|
return value;
|
|
2130
2164
|
}
|
|
@@ -2134,8 +2168,8 @@ const createLruCache = (maxCacheSize) => {
|
|
|
2134
2168
|
}
|
|
2135
2169
|
},
|
|
2136
2170
|
set(key, value) {
|
|
2137
|
-
if (key in
|
|
2138
|
-
|
|
2171
|
+
if (key in cache2) {
|
|
2172
|
+
cache2[key] = value;
|
|
2139
2173
|
} else {
|
|
2140
2174
|
update(key, value);
|
|
2141
2175
|
}
|
|
@@ -7311,6 +7345,19 @@ const FileSearch = createLucideIcon("FileSearch", [
|
|
|
7311
7345
|
["circle", { cx: "5", cy: "14", r: "3", key: "ufru5t" }],
|
|
7312
7346
|
["path", { d: "m9 18-1.5-1.5", key: "1j6qii" }]
|
|
7313
7347
|
]);
|
|
7348
|
+
/**
|
|
7349
|
+
* @license lucide-react v0.344.0 - ISC
|
|
7350
|
+
*
|
|
7351
|
+
* This source code is licensed under the ISC license.
|
|
7352
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
7353
|
+
*/
|
|
7354
|
+
const FileText = createLucideIcon("FileText", [
|
|
7355
|
+
["path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z", key: "1rqfz7" }],
|
|
7356
|
+
["path", { d: "M14 2v4a2 2 0 0 0 2 2h4", key: "tnqrlb" }],
|
|
7357
|
+
["path", { d: "M10 9H8", key: "b1mrlr" }],
|
|
7358
|
+
["path", { d: "M16 13H8", key: "t4e002" }],
|
|
7359
|
+
["path", { d: "M16 17H8", key: "z1uh3a" }]
|
|
7360
|
+
]);
|
|
7314
7361
|
/**
|
|
7315
7362
|
* @license lucide-react v0.344.0 - ISC
|
|
7316
7363
|
*
|
|
@@ -7322,6 +7369,18 @@ const Globe = createLucideIcon("Globe", [
|
|
|
7322
7369
|
["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
|
|
7323
7370
|
["path", { d: "M2 12h20", key: "9i4pu4" }]
|
|
7324
7371
|
]);
|
|
7372
|
+
/**
|
|
7373
|
+
* @license lucide-react v0.344.0 - ISC
|
|
7374
|
+
*
|
|
7375
|
+
* This source code is licensed under the ISC license.
|
|
7376
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
7377
|
+
*/
|
|
7378
|
+
const Hash = createLucideIcon("Hash", [
|
|
7379
|
+
["line", { x1: "4", x2: "20", y1: "9", y2: "9", key: "4lhtct" }],
|
|
7380
|
+
["line", { x1: "4", x2: "20", y1: "15", y2: "15", key: "vyu0kd" }],
|
|
7381
|
+
["line", { x1: "10", x2: "8", y1: "3", y2: "21", key: "1ggp8o" }],
|
|
7382
|
+
["line", { x1: "16", x2: "14", y1: "3", y2: "21", key: "weycgp" }]
|
|
7383
|
+
]);
|
|
7325
7384
|
/**
|
|
7326
7385
|
* @license lucide-react v0.344.0 - ISC
|
|
7327
7386
|
*
|
|
@@ -12665,8 +12724,8 @@ function hasFixedPositionAncestor(element, stopNode) {
|
|
|
12665
12724
|
}
|
|
12666
12725
|
return getComputedStyle$1(parentNode).position === "fixed" || hasFixedPositionAncestor(parentNode, stopNode);
|
|
12667
12726
|
}
|
|
12668
|
-
function getClippingElementAncestors(element,
|
|
12669
|
-
const cachedResult =
|
|
12727
|
+
function getClippingElementAncestors(element, cache2) {
|
|
12728
|
+
const cachedResult = cache2.get(element);
|
|
12670
12729
|
if (cachedResult) {
|
|
12671
12730
|
return cachedResult;
|
|
12672
12731
|
}
|
|
@@ -12688,7 +12747,7 @@ function getClippingElementAncestors(element, cache) {
|
|
|
12688
12747
|
}
|
|
12689
12748
|
currentNode = getParentNode(currentNode);
|
|
12690
12749
|
}
|
|
12691
|
-
|
|
12750
|
+
cache2.set(element, result);
|
|
12692
12751
|
return result;
|
|
12693
12752
|
}
|
|
12694
12753
|
function getClippingRect(_ref) {
|
|
@@ -12986,14 +13045,14 @@ const hide$1 = hide$2;
|
|
|
12986
13045
|
const arrow$2 = arrow$3;
|
|
12987
13046
|
const limitShift$1 = limitShift$2;
|
|
12988
13047
|
const computePosition = (reference, floating, options) => {
|
|
12989
|
-
const
|
|
13048
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
12990
13049
|
const mergedOptions = {
|
|
12991
13050
|
platform,
|
|
12992
13051
|
...options
|
|
12993
13052
|
};
|
|
12994
13053
|
const platformWithCache = {
|
|
12995
13054
|
...mergedOptions.platform,
|
|
12996
|
-
_c:
|
|
13055
|
+
_c: cache2
|
|
12997
13056
|
};
|
|
12998
13057
|
return computePosition$1(reference, floating, {
|
|
12999
13058
|
...mergedOptions,
|
|
@@ -15370,7 +15429,7 @@ const EmbedComponent = ({ url, displayType, alignment, nodeKey }) => {
|
|
|
15370
15429
|
}
|
|
15371
15430
|
);
|
|
15372
15431
|
};
|
|
15373
|
-
const FileComponent = React$1.lazy(() => import("./index-
|
|
15432
|
+
const FileComponent = React$1.lazy(() => import("./index-03cae849.js"));
|
|
15374
15433
|
function convertFileElement(domNode) {
|
|
15375
15434
|
if (domNode instanceof HTMLDivElement) {
|
|
15376
15435
|
const dataUrl = domNode.getAttribute("data-lexical-file-src");
|
|
@@ -19160,6 +19219,7 @@ function AIChatDialog({
|
|
|
19160
19219
|
selectedTextForInline
|
|
19161
19220
|
}) {
|
|
19162
19221
|
const [inputValue, setInputValue] = useState$1("");
|
|
19222
|
+
const [selectedText, setSelectedText] = useState$1("");
|
|
19163
19223
|
const [isLoading, setIsLoading] = useState$1(false);
|
|
19164
19224
|
const [errorMessage, setErrorMessage] = useState$1(null);
|
|
19165
19225
|
const [provider, setProvider] = useState$1("chatgpt");
|
|
@@ -19168,7 +19228,11 @@ function AIChatDialog({
|
|
|
19168
19228
|
const [purchasedCredits, setPurchasedCredits] = useState$1(0);
|
|
19169
19229
|
useEffect$1(() => {
|
|
19170
19230
|
if (open && initialText) {
|
|
19171
|
-
|
|
19231
|
+
setSelectedText(initialText);
|
|
19232
|
+
setInputValue("");
|
|
19233
|
+
} else if (!open) {
|
|
19234
|
+
setSelectedText("");
|
|
19235
|
+
setInputValue("");
|
|
19172
19236
|
}
|
|
19173
19237
|
}, [open, initialText]);
|
|
19174
19238
|
const {
|
|
@@ -19243,8 +19307,26 @@ function AIChatDialog({
|
|
|
19243
19307
|
setIsLoading(true);
|
|
19244
19308
|
setErrorMessage(null);
|
|
19245
19309
|
const isImageRequest = isImageGenerationRequest(inputValue);
|
|
19310
|
+
let finalPrompt;
|
|
19311
|
+
const hasSelectedText = selectedText && selectedText.trim() !== "";
|
|
19312
|
+
if (isImageRequest) {
|
|
19313
|
+
if (hasSelectedText) {
|
|
19314
|
+
finalPrompt = `${inputValue}: ${selectedText}`;
|
|
19315
|
+
} else {
|
|
19316
|
+
finalPrompt = inputValue;
|
|
19317
|
+
}
|
|
19318
|
+
} else if (hasSelectedText) {
|
|
19319
|
+
finalPrompt = `${inputValue}
|
|
19320
|
+
|
|
19321
|
+
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.
|
|
19322
|
+
|
|
19323
|
+
Text to transform:
|
|
19324
|
+
"${selectedText}"`;
|
|
19325
|
+
} else {
|
|
19326
|
+
finalPrompt = inputValue;
|
|
19327
|
+
}
|
|
19246
19328
|
try {
|
|
19247
|
-
const response = await AiEditorAction({ content:
|
|
19329
|
+
const response = await AiEditorAction({ content: finalPrompt, provider, apiKey });
|
|
19248
19330
|
const htmlString = response.data;
|
|
19249
19331
|
const parser = new DOMParser();
|
|
19250
19332
|
const dom = parser.parseFromString(htmlString.trim(), "text/html");
|
|
@@ -19281,6 +19363,7 @@ function AIChatDialog({
|
|
|
19281
19363
|
const handleClose = () => {
|
|
19282
19364
|
if (!isLoading) {
|
|
19283
19365
|
setInputValue("");
|
|
19366
|
+
setSelectedText("");
|
|
19284
19367
|
setErrorMessage(null);
|
|
19285
19368
|
onOpenChange(false);
|
|
19286
19369
|
}
|
|
@@ -19345,9 +19428,26 @@ function AIChatDialog({
|
|
|
19345
19428
|
] })
|
|
19346
19429
|
] }) }),
|
|
19347
19430
|
/* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-4 ", children: [
|
|
19431
|
+
selectedText && selectedText.trim() !== "" && /* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-2", children: [
|
|
19432
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-justify-between", children: [
|
|
19433
|
+
/* @__PURE__ */ jsx(Label$2, { className: "cteditor-text-sm cteditor-font-medium cteditor-text-muted-foreground", children: "Selected Text" }),
|
|
19434
|
+
/* @__PURE__ */ jsx(
|
|
19435
|
+
"button",
|
|
19436
|
+
{
|
|
19437
|
+
type: "button",
|
|
19438
|
+
onClick: () => setSelectedText(""),
|
|
19439
|
+
className: "cteditor-text-xs cteditor-text-muted-foreground hover:cteditor-text-foreground cteditor-transition-colors",
|
|
19440
|
+
title: "Clear selected text",
|
|
19441
|
+
children: /* @__PURE__ */ jsx(X$1, { size: 14 })
|
|
19442
|
+
}
|
|
19443
|
+
)
|
|
19444
|
+
] }),
|
|
19445
|
+
/* @__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 }) }),
|
|
19446
|
+
/* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-text-muted-foreground", children: "Your prompt will be applied to this selected text" })
|
|
19447
|
+
] }),
|
|
19348
19448
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
19349
19449
|
/* @__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" }),
|
|
19450
|
+
/* @__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
19451
|
!isRecording && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(
|
|
19352
19452
|
"button",
|
|
19353
19453
|
{
|
|
@@ -19368,7 +19468,7 @@ function AIChatDialog({
|
|
|
19368
19468
|
{
|
|
19369
19469
|
ref: textareaRef,
|
|
19370
19470
|
id: "ai-prompt",
|
|
19371
|
-
placeholder: isVoiceLoading ? "Initializing microphone..." : isRecording ? isPaused ? "Paused..." : "Listening..." : "e.g., Improve this
|
|
19471
|
+
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
19472
|
value: inputValue,
|
|
19373
19473
|
onChange: (e) => setInputValue(e.target.value),
|
|
19374
19474
|
disabled: isLoading || isRecording || isVoiceLoading,
|
|
@@ -19423,7 +19523,7 @@ function AIChatDialog({
|
|
|
19423
19523
|
] }),
|
|
19424
19524
|
!isRecording && !voiceError && !isVoiceLoading && /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-text-xs cteditor-text-muted-foreground", children: [
|
|
19425
19525
|
/* @__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" })
|
|
19526
|
+
/* @__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
19527
|
] })
|
|
19428
19528
|
] }),
|
|
19429
19529
|
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 +20586,10 @@ const PDF_CONFIG = {
|
|
|
20486
20586
|
};
|
|
20487
20587
|
const loadHtml2Pdf = async () => {
|
|
20488
20588
|
try {
|
|
20489
|
-
const mod = await import("./html2pdf.bundle.min-
|
|
20589
|
+
const mod = await import("./html2pdf.bundle.min-d2f5d9cb.js").then((n) => n.h);
|
|
20490
20590
|
return (mod == null ? void 0 : mod.default) || mod;
|
|
20491
20591
|
} catch {
|
|
20492
|
-
const mod2 = await import("./html2pdf.bundle-
|
|
20592
|
+
const mod2 = await import("./html2pdf.bundle-0e71462c.js").then((n) => n.h);
|
|
20493
20593
|
return (mod2 == null ? void 0 : mod2.default) || mod2;
|
|
20494
20594
|
}
|
|
20495
20595
|
};
|
|
@@ -27805,7 +27905,7 @@ const STATIC_SUGGESTIONS = [
|
|
|
27805
27905
|
"programming"
|
|
27806
27906
|
];
|
|
27807
27907
|
const CACHE_MAX_AGE = 5 * 60 * 1e3;
|
|
27808
|
-
const MAX_CACHE_SIZE = 200;
|
|
27908
|
+
const MAX_CACHE_SIZE$1 = 200;
|
|
27809
27909
|
const REQUEST_TIMEOUT = 3e4;
|
|
27810
27910
|
const MENU_CONFIG = { width: 320, height: 200, padding: 8 };
|
|
27811
27911
|
const TOOLTIP_CONFIG = {
|
|
@@ -27977,7 +28077,7 @@ class GrammarAIService {
|
|
|
27977
28077
|
errors,
|
|
27978
28078
|
checkedAt: Date.now()
|
|
27979
28079
|
});
|
|
27980
|
-
if (this.sentenceCache.size > MAX_CACHE_SIZE) {
|
|
28080
|
+
if (this.sentenceCache.size > MAX_CACHE_SIZE$1) {
|
|
27981
28081
|
const oldestKey = this.sentenceCache.keys().next().value;
|
|
27982
28082
|
if (oldestKey)
|
|
27983
28083
|
this.sentenceCache.delete(oldestKey);
|
|
@@ -31361,7 +31461,51 @@ function LinkPlugin({
|
|
|
31361
31461
|
}
|
|
31362
31462
|
);
|
|
31363
31463
|
}
|
|
31364
|
-
|
|
31464
|
+
const cache = /* @__PURE__ */ new Map();
|
|
31465
|
+
const CACHE_TTL = 30 * 60 * 1e3;
|
|
31466
|
+
const MAX_CACHE_SIZE = 100;
|
|
31467
|
+
function getCached(url) {
|
|
31468
|
+
const entry = cache.get(url);
|
|
31469
|
+
if (!entry)
|
|
31470
|
+
return null;
|
|
31471
|
+
if (Date.now() - entry.timestamp > CACHE_TTL) {
|
|
31472
|
+
cache.delete(url);
|
|
31473
|
+
return null;
|
|
31474
|
+
}
|
|
31475
|
+
return entry.data;
|
|
31476
|
+
}
|
|
31477
|
+
function setCache(url, data) {
|
|
31478
|
+
if (cache.size >= MAX_CACHE_SIZE) {
|
|
31479
|
+
const oldestKey = cache.keys().next().value;
|
|
31480
|
+
if (oldestKey)
|
|
31481
|
+
cache.delete(oldestKey);
|
|
31482
|
+
}
|
|
31483
|
+
cache.set(url, { data, timestamp: Date.now() });
|
|
31484
|
+
}
|
|
31485
|
+
async function fetchLinkPreview({
|
|
31486
|
+
url,
|
|
31487
|
+
apiKey
|
|
31488
|
+
}) {
|
|
31489
|
+
const cached = getCached(url);
|
|
31490
|
+
if (cached)
|
|
31491
|
+
return cached;
|
|
31492
|
+
try {
|
|
31493
|
+
const response = await backendAPI.post(
|
|
31494
|
+
apiEndpoints.linkPreview.getPreview,
|
|
31495
|
+
{ url },
|
|
31496
|
+
apiKey ? { headers: { "X-API-Key": apiKey } } : void 0
|
|
31497
|
+
);
|
|
31498
|
+
if (response.data.success && response.data.data) {
|
|
31499
|
+
setCache(url, response.data.data);
|
|
31500
|
+
return response.data.data;
|
|
31501
|
+
}
|
|
31502
|
+
return null;
|
|
31503
|
+
} catch (error) {
|
|
31504
|
+
console.error("Error fetching link preview:", error);
|
|
31505
|
+
return null;
|
|
31506
|
+
}
|
|
31507
|
+
}
|
|
31508
|
+
function LinkPreviewPlugin({ apiKey }) {
|
|
31365
31509
|
const [editor] = useLexicalComposerContext();
|
|
31366
31510
|
const [hoveredLink, setHoveredLink] = useState$1(null);
|
|
31367
31511
|
useEffect$1(() => {
|
|
@@ -31385,20 +31529,14 @@ function LinkPreviewPlugin() {
|
|
|
31385
31529
|
if (linkElement && editorElement.contains(linkElement)) {
|
|
31386
31530
|
const href = linkElement.getAttribute("href");
|
|
31387
31531
|
if (href && href !== "https://" && href !== "http://" && href !== "#") {
|
|
31388
|
-
if (showTimeout)
|
|
31532
|
+
if (showTimeout)
|
|
31389
31533
|
clearTimeout(showTimeout);
|
|
31390
|
-
}
|
|
31391
31534
|
if (hideTimeout) {
|
|
31392
31535
|
clearTimeout(hideTimeout);
|
|
31393
31536
|
hideTimeout = null;
|
|
31394
31537
|
}
|
|
31395
31538
|
showTimeout = window.setTimeout(() => {
|
|
31396
|
-
|
|
31397
|
-
setHoveredLink({
|
|
31398
|
-
url: href,
|
|
31399
|
-
text: linkElement.textContent || "",
|
|
31400
|
-
rect
|
|
31401
|
-
});
|
|
31539
|
+
setHoveredLink({ url: href, rect: linkElement.getBoundingClientRect() });
|
|
31402
31540
|
}, 500);
|
|
31403
31541
|
}
|
|
31404
31542
|
}
|
|
@@ -31408,12 +31546,10 @@ function LinkPreviewPlugin() {
|
|
|
31408
31546
|
const relatedTarget = event.relatedTarget;
|
|
31409
31547
|
if (target.closest(".link-preview-card")) {
|
|
31410
31548
|
isOverPreview = false;
|
|
31411
|
-
|
|
31412
|
-
if (!movingToLink) {
|
|
31549
|
+
if (!(relatedTarget == null ? void 0 : relatedTarget.closest("a"))) {
|
|
31413
31550
|
hideTimeout = window.setTimeout(() => {
|
|
31414
|
-
if (!isOverPreview)
|
|
31551
|
+
if (!isOverPreview)
|
|
31415
31552
|
setHoveredLink(null);
|
|
31416
|
-
}
|
|
31417
31553
|
}, 300);
|
|
31418
31554
|
}
|
|
31419
31555
|
return;
|
|
@@ -31424,19 +31560,16 @@ function LinkPreviewPlugin() {
|
|
|
31424
31560
|
clearTimeout(showTimeout);
|
|
31425
31561
|
showTimeout = null;
|
|
31426
31562
|
}
|
|
31427
|
-
|
|
31428
|
-
if (!movingToPreview) {
|
|
31563
|
+
if (!(relatedTarget == null ? void 0 : relatedTarget.closest(".link-preview-card"))) {
|
|
31429
31564
|
hideTimeout = window.setTimeout(() => {
|
|
31430
|
-
if (!isOverPreview)
|
|
31565
|
+
if (!isOverPreview)
|
|
31431
31566
|
setHoveredLink(null);
|
|
31432
|
-
}
|
|
31433
31567
|
}, 300);
|
|
31434
31568
|
}
|
|
31435
31569
|
}
|
|
31436
31570
|
};
|
|
31437
31571
|
const handlePreviewMouseOver = (event) => {
|
|
31438
|
-
|
|
31439
|
-
if (target.closest(".link-preview-card")) {
|
|
31572
|
+
if (event.target.closest(".link-preview-card")) {
|
|
31440
31573
|
isOverPreview = true;
|
|
31441
31574
|
if (hideTimeout) {
|
|
31442
31575
|
clearTimeout(hideTimeout);
|
|
@@ -31449,12 +31582,10 @@ function LinkPreviewPlugin() {
|
|
|
31449
31582
|
const relatedTarget = event.relatedTarget;
|
|
31450
31583
|
if (target.closest(".link-preview-card")) {
|
|
31451
31584
|
isOverPreview = false;
|
|
31452
|
-
|
|
31453
|
-
if (!movingToLink || !editorElement.contains(movingToLink)) {
|
|
31585
|
+
if (!(relatedTarget == null ? void 0 : relatedTarget.closest("a")) || !editorElement.contains(relatedTarget)) {
|
|
31454
31586
|
hideTimeout = window.setTimeout(() => {
|
|
31455
|
-
if (!isOverPreview)
|
|
31587
|
+
if (!isOverPreview)
|
|
31456
31588
|
setHoveredLink(null);
|
|
31457
|
-
}
|
|
31458
31589
|
}, 300);
|
|
31459
31590
|
}
|
|
31460
31591
|
}
|
|
@@ -31464,216 +31595,241 @@ function LinkPreviewPlugin() {
|
|
|
31464
31595
|
document.body.addEventListener("mouseover", handlePreviewMouseOver);
|
|
31465
31596
|
document.body.addEventListener("mouseout", handlePreviewMouseOut);
|
|
31466
31597
|
return () => {
|
|
31467
|
-
if (showTimeout)
|
|
31598
|
+
if (showTimeout)
|
|
31468
31599
|
clearTimeout(showTimeout);
|
|
31469
|
-
|
|
31470
|
-
if (hideTimeout) {
|
|
31600
|
+
if (hideTimeout)
|
|
31471
31601
|
clearTimeout(hideTimeout);
|
|
31472
|
-
}
|
|
31473
31602
|
editorElement.removeEventListener("mouseover", handleMouseOver);
|
|
31474
31603
|
editorElement.removeEventListener("mouseout", handleMouseOut);
|
|
31475
31604
|
document.body.removeEventListener("mouseover", handlePreviewMouseOver);
|
|
31476
31605
|
document.body.removeEventListener("mouseout", handlePreviewMouseOut);
|
|
31477
31606
|
};
|
|
31478
31607
|
}, [editor]);
|
|
31479
|
-
if (!hoveredLink)
|
|
31608
|
+
if (!hoveredLink)
|
|
31480
31609
|
return null;
|
|
31481
|
-
}
|
|
31482
31610
|
return createPortal(
|
|
31483
31611
|
/* @__PURE__ */ jsx(
|
|
31484
31612
|
LinkPreview,
|
|
31485
31613
|
{
|
|
31486
31614
|
url: hoveredLink.url,
|
|
31487
31615
|
rect: hoveredLink.rect,
|
|
31616
|
+
apiKey,
|
|
31488
31617
|
onClose: () => setHoveredLink(null)
|
|
31489
31618
|
}
|
|
31490
31619
|
),
|
|
31491
31620
|
document.body
|
|
31492
31621
|
);
|
|
31493
31622
|
}
|
|
31494
|
-
|
|
31623
|
+
const PREVIEW_WIDTH = 320;
|
|
31624
|
+
function LinkPreview({ url, rect, apiKey, onClose }) {
|
|
31495
31625
|
const [position, setPosition] = useState$1({ top: 0, left: 0 });
|
|
31626
|
+
const [previewData, setPreviewData] = useState$1(null);
|
|
31627
|
+
const [isLoading, setIsLoading] = useState$1(true);
|
|
31628
|
+
const [hasError, setHasError] = useState$1(false);
|
|
31629
|
+
const fetchedRef = useRef(false);
|
|
31496
31630
|
useEffect$1(() => {
|
|
31497
|
-
|
|
31498
|
-
|
|
31631
|
+
if (fetchedRef.current)
|
|
31632
|
+
return;
|
|
31633
|
+
fetchedRef.current = true;
|
|
31634
|
+
setIsLoading(true);
|
|
31635
|
+
setHasError(false);
|
|
31636
|
+
fetchLinkPreview({ url, apiKey }).then((data) => {
|
|
31637
|
+
if (data)
|
|
31638
|
+
setPreviewData(data);
|
|
31639
|
+
else
|
|
31640
|
+
setHasError(true);
|
|
31641
|
+
}).catch(() => setHasError(true)).finally(() => setIsLoading(false));
|
|
31642
|
+
}, [url, apiKey]);
|
|
31643
|
+
useEffect$1(() => {
|
|
31644
|
+
const previewHeight = (previewData == null ? void 0 : previewData.image) ? 280 : 160;
|
|
31499
31645
|
let top = rect.top + window.scrollY - previewHeight - 10;
|
|
31500
31646
|
if (rect.top - previewHeight - 10 < 0) {
|
|
31501
31647
|
top = rect.bottom + window.scrollY + 10;
|
|
31502
31648
|
}
|
|
31503
|
-
let left = rect.left + window.scrollX + rect.width / 2 -
|
|
31649
|
+
let left = rect.left + window.scrollX + rect.width / 2 - PREVIEW_WIDTH / 2;
|
|
31504
31650
|
const viewportWidth = window.innerWidth;
|
|
31505
|
-
if (left < 10)
|
|
31651
|
+
if (left < 10)
|
|
31506
31652
|
left = 10;
|
|
31507
|
-
|
|
31508
|
-
left = viewportWidth -
|
|
31509
|
-
}
|
|
31653
|
+
else if (left + PREVIEW_WIDTH > viewportWidth - 10)
|
|
31654
|
+
left = viewportWidth - PREVIEW_WIDTH - 10;
|
|
31510
31655
|
setPosition({ top, left });
|
|
31511
|
-
}, [rect]);
|
|
31656
|
+
}, [rect, previewData]);
|
|
31512
31657
|
const getDomain = (urlString) => {
|
|
31513
31658
|
try {
|
|
31514
|
-
|
|
31515
|
-
return urlObj.hostname.replace("www.", "");
|
|
31659
|
+
return new URL(urlString).hostname.replace("www.", "");
|
|
31516
31660
|
} catch {
|
|
31517
31661
|
return urlString;
|
|
31518
31662
|
}
|
|
31519
31663
|
};
|
|
31520
31664
|
const domain = getDomain(url);
|
|
31521
|
-
const
|
|
31522
|
-
|
|
31523
|
-
|
|
31524
|
-
|
|
31525
|
-
|
|
31526
|
-
|
|
31665
|
+
const TypeIcon = ({ type }) => {
|
|
31666
|
+
const iconProps = { style: { width: "14px", height: "14px" }, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24" };
|
|
31667
|
+
const pathProps = { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2 };
|
|
31668
|
+
switch (type) {
|
|
31669
|
+
case "image":
|
|
31670
|
+
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" }) });
|
|
31671
|
+
case "video":
|
|
31672
|
+
return /* @__PURE__ */ jsxs("svg", { ...iconProps, children: [
|
|
31673
|
+
/* @__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" }),
|
|
31674
|
+
/* @__PURE__ */ jsx("path", { ...pathProps, d: "M21 12a9 9 0 11-18 0 9 9 0 0118 0z" })
|
|
31675
|
+
] });
|
|
31676
|
+
case "pdf":
|
|
31677
|
+
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" }) });
|
|
31678
|
+
default:
|
|
31679
|
+
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
31680
|
}
|
|
31528
31681
|
};
|
|
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
|
-
|
|
31682
|
+
const cardStyle = {
|
|
31683
|
+
position: "absolute",
|
|
31684
|
+
top: `${position.top}px`,
|
|
31685
|
+
left: `${position.left}px`,
|
|
31686
|
+
zIndex: 1e4,
|
|
31687
|
+
pointerEvents: "auto",
|
|
31688
|
+
animation: "linkPreviewFadeIn 0.2s ease-out"
|
|
31689
|
+
};
|
|
31690
|
+
const containerStyle = {
|
|
31691
|
+
width: `${PREVIEW_WIDTH}px`,
|
|
31692
|
+
backgroundColor: "#1e1e1e",
|
|
31693
|
+
borderRadius: "12px",
|
|
31694
|
+
boxShadow: "0 10px 40px rgba(0, 0, 0, 0.4)",
|
|
31695
|
+
overflow: "hidden",
|
|
31696
|
+
position: "relative",
|
|
31697
|
+
border: "1px solid #333"
|
|
31698
|
+
};
|
|
31699
|
+
const closeButtonStyle = {
|
|
31700
|
+
position: "absolute",
|
|
31701
|
+
top: "8px",
|
|
31702
|
+
right: "8px",
|
|
31703
|
+
width: "24px",
|
|
31704
|
+
height: "24px",
|
|
31705
|
+
borderRadius: "6px",
|
|
31706
|
+
backgroundColor: "rgba(0,0,0,0.5)",
|
|
31707
|
+
border: "none",
|
|
31708
|
+
cursor: "pointer",
|
|
31709
|
+
display: "flex",
|
|
31710
|
+
alignItems: "center",
|
|
31711
|
+
justifyContent: "center",
|
|
31712
|
+
zIndex: 10
|
|
31713
|
+
};
|
|
31714
|
+
return /* @__PURE__ */ jsxs("div", { className: "link-preview-card", style: cardStyle, children: [
|
|
31715
|
+
/* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
|
|
31716
|
+
/* @__PURE__ */ jsx(
|
|
31717
|
+
"button",
|
|
31718
|
+
{
|
|
31719
|
+
onClick: (e) => {
|
|
31720
|
+
e.preventDefault();
|
|
31721
|
+
e.stopPropagation();
|
|
31722
|
+
onClose();
|
|
31723
|
+
},
|
|
31724
|
+
style: closeButtonStyle,
|
|
31725
|
+
onMouseEnter: (e) => {
|
|
31726
|
+
e.currentTarget.style.backgroundColor = "rgba(0,0,0,0.7)";
|
|
31727
|
+
},
|
|
31728
|
+
onMouseLeave: (e) => {
|
|
31729
|
+
e.currentTarget.style.backgroundColor = "rgba(0,0,0,0.5)";
|
|
31730
|
+
},
|
|
31731
|
+
title: "Close preview",
|
|
31732
|
+
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" }) })
|
|
31733
|
+
}
|
|
31734
|
+
),
|
|
31735
|
+
isLoading && /* @__PURE__ */ jsxs("div", { style: { padding: "40px", textAlign: "center" }, children: [
|
|
31736
|
+
/* @__PURE__ */ jsx("div", { style: {
|
|
31737
|
+
width: "24px",
|
|
31738
|
+
height: "24px",
|
|
31739
|
+
border: "2px solid #444",
|
|
31740
|
+
borderTopColor: "#fff",
|
|
31741
|
+
borderRadius: "50%",
|
|
31742
|
+
animation: "linkPreviewSpin 1s linear infinite",
|
|
31743
|
+
margin: "0 auto 12px"
|
|
31744
|
+
} }),
|
|
31745
|
+
/* @__PURE__ */ jsx("p", { style: { fontSize: "12px", color: "#888" }, children: "Loading preview..." })
|
|
31746
|
+
] }),
|
|
31747
|
+
!isLoading && hasError && /* @__PURE__ */ jsxs("div", { style: { padding: "16px" }, children: [
|
|
31748
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "12px" }, children: [
|
|
31749
|
+
/* @__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" }) }),
|
|
31750
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "14px", fontWeight: "600", color: "#fff" }, children: domain })
|
|
31751
|
+
] }),
|
|
31752
|
+
/* @__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 }) })
|
|
31753
|
+
] }),
|
|
31754
|
+
!isLoading && !hasError && previewData && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31755
|
+
previewData.image && /* @__PURE__ */ jsx("div", { style: {
|
|
31756
|
+
width: "100%",
|
|
31757
|
+
height: "140px",
|
|
31758
|
+
backgroundColor: "#2a2a2a",
|
|
31759
|
+
backgroundImage: `url(${previewData.image})`,
|
|
31760
|
+
backgroundSize: "cover",
|
|
31761
|
+
backgroundPosition: "center"
|
|
31762
|
+
} }),
|
|
31763
|
+
/* @__PURE__ */ jsxs("div", { style: { padding: "14px" }, children: [
|
|
31764
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "10px" }, children: [
|
|
31765
|
+
previewData.favicon ? /* @__PURE__ */ jsx(
|
|
31766
|
+
"img",
|
|
31767
|
+
{
|
|
31768
|
+
src: previewData.favicon,
|
|
31769
|
+
alt: "",
|
|
31770
|
+
style: { width: "16px", height: "16px", borderRadius: "2px", objectFit: "contain" },
|
|
31771
|
+
onError: (e) => {
|
|
31772
|
+
e.currentTarget.style.display = "none";
|
|
31604
31773
|
}
|
|
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
|
-
}
|
|
31774
|
+
}
|
|
31775
|
+
) : /* @__PURE__ */ jsx("span", { style: { color: "#888" }, children: /* @__PURE__ */ jsx(TypeIcon, { type: previewData.type }) }),
|
|
31776
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "12px", color: "#888", flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: previewData.siteName || domain }),
|
|
31777
|
+
/* @__PURE__ */ jsx("span", { style: {
|
|
31778
|
+
fontSize: "10px",
|
|
31779
|
+
color: "#666",
|
|
31780
|
+
padding: "2px 6px",
|
|
31781
|
+
backgroundColor: "#333",
|
|
31782
|
+
borderRadius: "4px",
|
|
31783
|
+
textTransform: "uppercase"
|
|
31784
|
+
}, children: previewData.type })
|
|
31785
|
+
] }),
|
|
31786
|
+
previewData.title && /* @__PURE__ */ jsx("h4", { style: {
|
|
31787
|
+
fontSize: "14px",
|
|
31788
|
+
fontWeight: "600",
|
|
31789
|
+
color: "#fff",
|
|
31790
|
+
marginBottom: "6px",
|
|
31791
|
+
lineHeight: "1.4",
|
|
31792
|
+
display: "-webkit-box",
|
|
31793
|
+
WebkitLineClamp: 2,
|
|
31794
|
+
WebkitBoxOrient: "vertical",
|
|
31795
|
+
overflow: "hidden"
|
|
31796
|
+
}, children: previewData.title }),
|
|
31797
|
+
previewData.description && /* @__PURE__ */ jsx("p", { style: {
|
|
31798
|
+
fontSize: "12px",
|
|
31799
|
+
color: "#999",
|
|
31800
|
+
lineHeight: "1.5",
|
|
31801
|
+
display: "-webkit-box",
|
|
31802
|
+
WebkitLineClamp: 2,
|
|
31803
|
+
WebkitBoxOrient: "vertical",
|
|
31804
|
+
overflow: "hidden",
|
|
31805
|
+
marginBottom: "10px"
|
|
31806
|
+
}, children: previewData.description }),
|
|
31807
|
+
/* @__PURE__ */ jsxs("div", { style: {
|
|
31808
|
+
display: "flex",
|
|
31809
|
+
alignItems: "center",
|
|
31810
|
+
gap: "6px",
|
|
31811
|
+
padding: "8px 10px",
|
|
31812
|
+
backgroundColor: "#252525",
|
|
31813
|
+
borderRadius: "6px",
|
|
31814
|
+
marginTop: "8px"
|
|
31815
|
+
}, children: [
|
|
31816
|
+
/* @__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" }) }),
|
|
31817
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "11px", color: "#888", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: url })
|
|
31818
|
+
] })
|
|
31819
|
+
] })
|
|
31820
|
+
] })
|
|
31821
|
+
] }),
|
|
31822
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
31823
|
+
@keyframes linkPreviewFadeIn {
|
|
31824
|
+
from { opacity: 0; transform: translateY(5px); }
|
|
31825
|
+
to { opacity: 1; transform: translateY(0); }
|
|
31663
31826
|
}
|
|
31664
|
-
|
|
31665
|
-
|
|
31666
|
-
|
|
31667
|
-
opacity: 1;
|
|
31668
|
-
}
|
|
31669
|
-
50% {
|
|
31670
|
-
opacity: 0.6;
|
|
31671
|
-
}
|
|
31827
|
+
@keyframes linkPreviewSpin {
|
|
31828
|
+
from { transform: rotate(0deg); }
|
|
31829
|
+
to { transform: rotate(360deg); }
|
|
31672
31830
|
}
|
|
31673
31831
|
` })
|
|
31674
|
-
|
|
31675
|
-
}
|
|
31676
|
-
);
|
|
31832
|
+
] });
|
|
31677
31833
|
}
|
|
31678
31834
|
const debounce = (fn, delay) => {
|
|
31679
31835
|
let timeoutID;
|
|
@@ -31704,6 +31860,554 @@ const LocalStoragePlugin = ({ namespace }) => {
|
|
|
31704
31860
|
return null;
|
|
31705
31861
|
};
|
|
31706
31862
|
const LocalStoragePlugin$1 = LocalStoragePlugin;
|
|
31863
|
+
const HORIZONTAL_RULE_PATTERNS = /^(---|___|\*\*\*)$/;
|
|
31864
|
+
const HEADING_PATTERN = /^(#{1,6})\s$/;
|
|
31865
|
+
const BULLET_LIST_PATTERN = /^(\*|-|\+)\s$/;
|
|
31866
|
+
const NUMBERED_LIST_PATTERN = /^(\d+)[\.\)]\s$/;
|
|
31867
|
+
const CHECKLIST_PATTERN = /^\[(x|\s)?\]\s$/i;
|
|
31868
|
+
const QUOTE_PATTERN = /^>\s$/;
|
|
31869
|
+
const CODE_BLOCK_PATTERN = /^```$/;
|
|
31870
|
+
function getLineTextBeforeCursor(editor) {
|
|
31871
|
+
let text = null;
|
|
31872
|
+
editor.getEditorState().read(() => {
|
|
31873
|
+
const selection = $getSelection();
|
|
31874
|
+
if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
|
|
31875
|
+
return;
|
|
31876
|
+
}
|
|
31877
|
+
const anchor = selection.anchor;
|
|
31878
|
+
const anchorNode = anchor.getNode();
|
|
31879
|
+
if (!$isTextNode(anchorNode)) {
|
|
31880
|
+
return;
|
|
31881
|
+
}
|
|
31882
|
+
const textContent = anchorNode.getTextContent();
|
|
31883
|
+
const offset2 = anchor.offset;
|
|
31884
|
+
text = textContent.slice(0, offset2);
|
|
31885
|
+
});
|
|
31886
|
+
return text;
|
|
31887
|
+
}
|
|
31888
|
+
function isAtBlockStart(editor, triggerLength) {
|
|
31889
|
+
let result = false;
|
|
31890
|
+
editor.getEditorState().read(() => {
|
|
31891
|
+
const selection = $getSelection();
|
|
31892
|
+
if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
|
|
31893
|
+
return;
|
|
31894
|
+
}
|
|
31895
|
+
const anchor = selection.anchor;
|
|
31896
|
+
const anchorNode = anchor.getNode();
|
|
31897
|
+
const parent = anchorNode.getParent();
|
|
31898
|
+
if (!parent || parent.getType() !== "paragraph") {
|
|
31899
|
+
return;
|
|
31900
|
+
}
|
|
31901
|
+
const children = parent.getChildren();
|
|
31902
|
+
if (children.length === 1 && children[0] === anchorNode) {
|
|
31903
|
+
const textContent = anchorNode.getTextContent();
|
|
31904
|
+
if (textContent.length === triggerLength) {
|
|
31905
|
+
result = true;
|
|
31906
|
+
}
|
|
31907
|
+
}
|
|
31908
|
+
});
|
|
31909
|
+
return result;
|
|
31910
|
+
}
|
|
31911
|
+
function isInsideListItem(node) {
|
|
31912
|
+
let current = node.getParent();
|
|
31913
|
+
while (current !== null) {
|
|
31914
|
+
if ($isListItemNode(current)) {
|
|
31915
|
+
return true;
|
|
31916
|
+
}
|
|
31917
|
+
current = current.getParent();
|
|
31918
|
+
}
|
|
31919
|
+
return false;
|
|
31920
|
+
}
|
|
31921
|
+
function handleHorizontalRule(editor) {
|
|
31922
|
+
const text = getLineTextBeforeCursor(editor);
|
|
31923
|
+
if (!text || !HORIZONTAL_RULE_PATTERNS.test(text)) {
|
|
31924
|
+
return false;
|
|
31925
|
+
}
|
|
31926
|
+
if (!isAtBlockStart(editor, text.length)) {
|
|
31927
|
+
return false;
|
|
31928
|
+
}
|
|
31929
|
+
editor.update(() => {
|
|
31930
|
+
const selection = $getSelection();
|
|
31931
|
+
if (!$isRangeSelection(selection))
|
|
31932
|
+
return;
|
|
31933
|
+
const anchorNode = selection.anchor.getNode();
|
|
31934
|
+
const parent = anchorNode.getParent();
|
|
31935
|
+
if (parent && parent.getType() === "paragraph") {
|
|
31936
|
+
editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, void 0);
|
|
31937
|
+
parent.remove();
|
|
31938
|
+
}
|
|
31939
|
+
});
|
|
31940
|
+
return true;
|
|
31941
|
+
}
|
|
31942
|
+
function handleHeading(editor) {
|
|
31943
|
+
const text = getLineTextBeforeCursor(editor);
|
|
31944
|
+
if (!text)
|
|
31945
|
+
return false;
|
|
31946
|
+
const match = text.match(HEADING_PATTERN);
|
|
31947
|
+
if (!match)
|
|
31948
|
+
return false;
|
|
31949
|
+
let isValidContext = false;
|
|
31950
|
+
editor.getEditorState().read(() => {
|
|
31951
|
+
const selection = $getSelection();
|
|
31952
|
+
if (!$isRangeSelection(selection))
|
|
31953
|
+
return;
|
|
31954
|
+
const anchorNode = selection.anchor.getNode();
|
|
31955
|
+
if (!$isTextNode(anchorNode))
|
|
31956
|
+
return;
|
|
31957
|
+
const parent = anchorNode.getParent();
|
|
31958
|
+
if (!parent || parent.getType() !== "paragraph")
|
|
31959
|
+
return;
|
|
31960
|
+
if (isInsideListItem(parent))
|
|
31961
|
+
return;
|
|
31962
|
+
const children = parent.getChildren();
|
|
31963
|
+
if (children.length !== 1 || children[0] !== anchorNode)
|
|
31964
|
+
return;
|
|
31965
|
+
const fullText = anchorNode.getTextContent();
|
|
31966
|
+
const headingMatch = fullText.match(HEADING_PATTERN);
|
|
31967
|
+
if (headingMatch && headingMatch.index === 0) {
|
|
31968
|
+
isValidContext = true;
|
|
31969
|
+
}
|
|
31970
|
+
});
|
|
31971
|
+
if (!isValidContext) {
|
|
31972
|
+
return false;
|
|
31973
|
+
}
|
|
31974
|
+
const level = match[1].length;
|
|
31975
|
+
const tag = `h${level}`;
|
|
31976
|
+
editor.update(() => {
|
|
31977
|
+
const selection = $getSelection();
|
|
31978
|
+
if (!$isRangeSelection(selection))
|
|
31979
|
+
return;
|
|
31980
|
+
const anchorNode = selection.anchor.getNode();
|
|
31981
|
+
if (!$isTextNode(anchorNode))
|
|
31982
|
+
return;
|
|
31983
|
+
const parent = anchorNode.getParent();
|
|
31984
|
+
if (parent && parent.getType() === "paragraph") {
|
|
31985
|
+
const fullText = anchorNode.getTextContent();
|
|
31986
|
+
const remainingText = fullText.slice(match[0].length);
|
|
31987
|
+
const headingNode = $createHeadingNode(tag);
|
|
31988
|
+
if (remainingText) {
|
|
31989
|
+
headingNode.append($createTextNode(remainingText));
|
|
31990
|
+
}
|
|
31991
|
+
parent.replace(headingNode);
|
|
31992
|
+
headingNode.selectEnd();
|
|
31993
|
+
}
|
|
31994
|
+
});
|
|
31995
|
+
return true;
|
|
31996
|
+
}
|
|
31997
|
+
function handleBulletList(editor) {
|
|
31998
|
+
const text = getLineTextBeforeCursor(editor);
|
|
31999
|
+
if (!text || !BULLET_LIST_PATTERN.test(text)) {
|
|
32000
|
+
return false;
|
|
32001
|
+
}
|
|
32002
|
+
let isValidContext = false;
|
|
32003
|
+
editor.getEditorState().read(() => {
|
|
32004
|
+
const selection = $getSelection();
|
|
32005
|
+
if (!$isRangeSelection(selection))
|
|
32006
|
+
return;
|
|
32007
|
+
const anchorNode = selection.anchor.getNode();
|
|
32008
|
+
if (!$isTextNode(anchorNode))
|
|
32009
|
+
return;
|
|
32010
|
+
const parent = anchorNode.getParent();
|
|
32011
|
+
if (!parent || parent.getType() !== "paragraph")
|
|
32012
|
+
return;
|
|
32013
|
+
if (isInsideListItem(parent))
|
|
32014
|
+
return;
|
|
32015
|
+
const children = parent.getChildren();
|
|
32016
|
+
if (children.length !== 1 || children[0] !== anchorNode)
|
|
32017
|
+
return;
|
|
32018
|
+
const fullText = anchorNode.getTextContent();
|
|
32019
|
+
const match = fullText.match(BULLET_LIST_PATTERN);
|
|
32020
|
+
if (match && match.index === 0) {
|
|
32021
|
+
isValidContext = true;
|
|
32022
|
+
}
|
|
32023
|
+
});
|
|
32024
|
+
if (!isValidContext) {
|
|
32025
|
+
return false;
|
|
32026
|
+
}
|
|
32027
|
+
editor.update(() => {
|
|
32028
|
+
const selection = $getSelection();
|
|
32029
|
+
if (!$isRangeSelection(selection))
|
|
32030
|
+
return;
|
|
32031
|
+
const anchorNode = selection.anchor.getNode();
|
|
32032
|
+
if (!$isTextNode(anchorNode))
|
|
32033
|
+
return;
|
|
32034
|
+
const parent = anchorNode.getParent();
|
|
32035
|
+
if (parent && parent.getType() === "paragraph") {
|
|
32036
|
+
const fullText = anchorNode.getTextContent();
|
|
32037
|
+
const match = text.match(BULLET_LIST_PATTERN);
|
|
32038
|
+
const remainingText = match ? fullText.slice(match[0].length) : "";
|
|
32039
|
+
const listNode = $createListNode("bullet");
|
|
32040
|
+
const listItemNode = $createListItemNode();
|
|
32041
|
+
if (remainingText) {
|
|
32042
|
+
listItemNode.append($createTextNode(remainingText));
|
|
32043
|
+
}
|
|
32044
|
+
listNode.append(listItemNode);
|
|
32045
|
+
parent.replace(listNode);
|
|
32046
|
+
listItemNode.selectEnd();
|
|
32047
|
+
}
|
|
32048
|
+
});
|
|
32049
|
+
return true;
|
|
32050
|
+
}
|
|
32051
|
+
function handleNumberedList(editor) {
|
|
32052
|
+
const text = getLineTextBeforeCursor(editor);
|
|
32053
|
+
if (!text || !NUMBERED_LIST_PATTERN.test(text)) {
|
|
32054
|
+
return false;
|
|
32055
|
+
}
|
|
32056
|
+
let isValidContext = false;
|
|
32057
|
+
editor.getEditorState().read(() => {
|
|
32058
|
+
const selection = $getSelection();
|
|
32059
|
+
if (!$isRangeSelection(selection))
|
|
32060
|
+
return;
|
|
32061
|
+
const anchorNode = selection.anchor.getNode();
|
|
32062
|
+
if (!$isTextNode(anchorNode))
|
|
32063
|
+
return;
|
|
32064
|
+
const parent = anchorNode.getParent();
|
|
32065
|
+
if (!parent || parent.getType() !== "paragraph")
|
|
32066
|
+
return;
|
|
32067
|
+
if (isInsideListItem(parent))
|
|
32068
|
+
return;
|
|
32069
|
+
const children = parent.getChildren();
|
|
32070
|
+
if (children.length !== 1 || children[0] !== anchorNode)
|
|
32071
|
+
return;
|
|
32072
|
+
const fullText = anchorNode.getTextContent();
|
|
32073
|
+
const match = fullText.match(NUMBERED_LIST_PATTERN);
|
|
32074
|
+
if (match && match.index === 0) {
|
|
32075
|
+
isValidContext = true;
|
|
32076
|
+
}
|
|
32077
|
+
});
|
|
32078
|
+
if (!isValidContext) {
|
|
32079
|
+
return false;
|
|
32080
|
+
}
|
|
32081
|
+
editor.update(() => {
|
|
32082
|
+
const selection = $getSelection();
|
|
32083
|
+
if (!$isRangeSelection(selection))
|
|
32084
|
+
return;
|
|
32085
|
+
const anchorNode = selection.anchor.getNode();
|
|
32086
|
+
if (!$isTextNode(anchorNode))
|
|
32087
|
+
return;
|
|
32088
|
+
const parent = anchorNode.getParent();
|
|
32089
|
+
if (parent && parent.getType() === "paragraph") {
|
|
32090
|
+
const fullText = anchorNode.getTextContent();
|
|
32091
|
+
const match = text.match(NUMBERED_LIST_PATTERN);
|
|
32092
|
+
const remainingText = match ? fullText.slice(match[0].length) : "";
|
|
32093
|
+
const listNode = $createListNode("number");
|
|
32094
|
+
const listItemNode = $createListItemNode();
|
|
32095
|
+
if (remainingText) {
|
|
32096
|
+
listItemNode.append($createTextNode(remainingText));
|
|
32097
|
+
}
|
|
32098
|
+
listNode.append(listItemNode);
|
|
32099
|
+
parent.replace(listNode);
|
|
32100
|
+
listItemNode.selectEnd();
|
|
32101
|
+
}
|
|
32102
|
+
});
|
|
32103
|
+
return true;
|
|
32104
|
+
}
|
|
32105
|
+
function handleChecklist(editor) {
|
|
32106
|
+
const text = getLineTextBeforeCursor(editor);
|
|
32107
|
+
if (!text || !CHECKLIST_PATTERN.test(text)) {
|
|
32108
|
+
return false;
|
|
32109
|
+
}
|
|
32110
|
+
let isValidContext = false;
|
|
32111
|
+
editor.getEditorState().read(() => {
|
|
32112
|
+
const selection = $getSelection();
|
|
32113
|
+
if (!$isRangeSelection(selection))
|
|
32114
|
+
return;
|
|
32115
|
+
const anchorNode = selection.anchor.getNode();
|
|
32116
|
+
if (!$isTextNode(anchorNode))
|
|
32117
|
+
return;
|
|
32118
|
+
const parent = anchorNode.getParent();
|
|
32119
|
+
if (!parent || parent.getType() !== "paragraph")
|
|
32120
|
+
return;
|
|
32121
|
+
if (isInsideListItem(parent))
|
|
32122
|
+
return;
|
|
32123
|
+
const children = parent.getChildren();
|
|
32124
|
+
if (children.length !== 1 || children[0] !== anchorNode)
|
|
32125
|
+
return;
|
|
32126
|
+
const fullText = anchorNode.getTextContent();
|
|
32127
|
+
const match = fullText.match(CHECKLIST_PATTERN);
|
|
32128
|
+
if (match && match.index === 0) {
|
|
32129
|
+
isValidContext = true;
|
|
32130
|
+
}
|
|
32131
|
+
});
|
|
32132
|
+
if (!isValidContext) {
|
|
32133
|
+
return false;
|
|
32134
|
+
}
|
|
32135
|
+
editor.update(() => {
|
|
32136
|
+
const selection = $getSelection();
|
|
32137
|
+
if (!$isRangeSelection(selection))
|
|
32138
|
+
return;
|
|
32139
|
+
const anchorNode = selection.anchor.getNode();
|
|
32140
|
+
if (!$isTextNode(anchorNode))
|
|
32141
|
+
return;
|
|
32142
|
+
const parent = anchorNode.getParent();
|
|
32143
|
+
if (parent && parent.getType() === "paragraph") {
|
|
32144
|
+
const fullText = anchorNode.getTextContent();
|
|
32145
|
+
const match = text.match(CHECKLIST_PATTERN);
|
|
32146
|
+
const remainingText = match ? fullText.slice(match[0].length) : "";
|
|
32147
|
+
const listNode = $createListNode("check");
|
|
32148
|
+
const listItemNode = $createListItemNode();
|
|
32149
|
+
if (remainingText) {
|
|
32150
|
+
listItemNode.append($createTextNode(remainingText));
|
|
32151
|
+
}
|
|
32152
|
+
listNode.append(listItemNode);
|
|
32153
|
+
parent.replace(listNode);
|
|
32154
|
+
listItemNode.selectEnd();
|
|
32155
|
+
}
|
|
32156
|
+
});
|
|
32157
|
+
return true;
|
|
32158
|
+
}
|
|
32159
|
+
function handleQuote(editor) {
|
|
32160
|
+
const text = getLineTextBeforeCursor(editor);
|
|
32161
|
+
if (!text || !QUOTE_PATTERN.test(text)) {
|
|
32162
|
+
return false;
|
|
32163
|
+
}
|
|
32164
|
+
let isValidContext = false;
|
|
32165
|
+
editor.getEditorState().read(() => {
|
|
32166
|
+
const selection = $getSelection();
|
|
32167
|
+
if (!$isRangeSelection(selection))
|
|
32168
|
+
return;
|
|
32169
|
+
const anchorNode = selection.anchor.getNode();
|
|
32170
|
+
if (!$isTextNode(anchorNode))
|
|
32171
|
+
return;
|
|
32172
|
+
const parent = anchorNode.getParent();
|
|
32173
|
+
if (!parent || parent.getType() !== "paragraph")
|
|
32174
|
+
return;
|
|
32175
|
+
if (isInsideListItem(parent))
|
|
32176
|
+
return;
|
|
32177
|
+
const children = parent.getChildren();
|
|
32178
|
+
if (children.length !== 1 || children[0] !== anchorNode)
|
|
32179
|
+
return;
|
|
32180
|
+
const fullText = anchorNode.getTextContent();
|
|
32181
|
+
const match = fullText.match(QUOTE_PATTERN);
|
|
32182
|
+
if (match && match.index === 0) {
|
|
32183
|
+
isValidContext = true;
|
|
32184
|
+
}
|
|
32185
|
+
});
|
|
32186
|
+
if (!isValidContext) {
|
|
32187
|
+
return false;
|
|
32188
|
+
}
|
|
32189
|
+
editor.update(() => {
|
|
32190
|
+
const selection = $getSelection();
|
|
32191
|
+
if (!$isRangeSelection(selection))
|
|
32192
|
+
return;
|
|
32193
|
+
const anchorNode = selection.anchor.getNode();
|
|
32194
|
+
if (!$isTextNode(anchorNode))
|
|
32195
|
+
return;
|
|
32196
|
+
const parent = anchorNode.getParent();
|
|
32197
|
+
if (parent && parent.getType() === "paragraph") {
|
|
32198
|
+
const fullText = anchorNode.getTextContent();
|
|
32199
|
+
const match = text.match(QUOTE_PATTERN);
|
|
32200
|
+
const remainingText = match ? fullText.slice(match[0].length) : "";
|
|
32201
|
+
const quoteNode = $createQuoteNode();
|
|
32202
|
+
if (remainingText) {
|
|
32203
|
+
quoteNode.append($createTextNode(remainingText));
|
|
32204
|
+
}
|
|
32205
|
+
parent.replace(quoteNode);
|
|
32206
|
+
quoteNode.selectEnd();
|
|
32207
|
+
}
|
|
32208
|
+
});
|
|
32209
|
+
return true;
|
|
32210
|
+
}
|
|
32211
|
+
function handleCodeBlock(editor) {
|
|
32212
|
+
const text = getLineTextBeforeCursor(editor);
|
|
32213
|
+
if (!text || !CODE_BLOCK_PATTERN.test(text)) {
|
|
32214
|
+
return false;
|
|
32215
|
+
}
|
|
32216
|
+
if (!isAtBlockStart(editor, text.length)) {
|
|
32217
|
+
return false;
|
|
32218
|
+
}
|
|
32219
|
+
editor.update(() => {
|
|
32220
|
+
const selection = $getSelection();
|
|
32221
|
+
if (!$isRangeSelection(selection))
|
|
32222
|
+
return;
|
|
32223
|
+
const anchorNode = selection.anchor.getNode();
|
|
32224
|
+
const parent = anchorNode.getParent();
|
|
32225
|
+
if (parent && parent.getType() === "paragraph") {
|
|
32226
|
+
const codeNode = $createCodeNode();
|
|
32227
|
+
parent.replace(codeNode);
|
|
32228
|
+
const paragraphNode = $createParagraphNode();
|
|
32229
|
+
codeNode.insertAfter(paragraphNode);
|
|
32230
|
+
codeNode.selectEnd();
|
|
32231
|
+
}
|
|
32232
|
+
});
|
|
32233
|
+
return true;
|
|
32234
|
+
}
|
|
32235
|
+
function handleMarkdownShortcuts(editor) {
|
|
32236
|
+
if (handleHorizontalRule(editor))
|
|
32237
|
+
return true;
|
|
32238
|
+
if (handleHeading(editor))
|
|
32239
|
+
return true;
|
|
32240
|
+
if (handleBulletList(editor))
|
|
32241
|
+
return true;
|
|
32242
|
+
if (handleNumberedList(editor))
|
|
32243
|
+
return true;
|
|
32244
|
+
if (handleChecklist(editor))
|
|
32245
|
+
return true;
|
|
32246
|
+
if (handleQuote(editor))
|
|
32247
|
+
return true;
|
|
32248
|
+
if (handleCodeBlock(editor))
|
|
32249
|
+
return true;
|
|
32250
|
+
return false;
|
|
32251
|
+
}
|
|
32252
|
+
function MarkdownShortcutsPlugin() {
|
|
32253
|
+
const [editor] = useLexicalComposerContext();
|
|
32254
|
+
useEffect$1(() => {
|
|
32255
|
+
const removeTextListener = editor.registerTextContentListener(() => {
|
|
32256
|
+
const text = getLineTextBeforeCursor(editor);
|
|
32257
|
+
if (text && HORIZONTAL_RULE_PATTERNS.test(text)) {
|
|
32258
|
+
setTimeout(() => {
|
|
32259
|
+
handleHorizontalRule(editor);
|
|
32260
|
+
}, 0);
|
|
32261
|
+
}
|
|
32262
|
+
});
|
|
32263
|
+
const removeEnterListener = editor.registerCommand(
|
|
32264
|
+
KEY_ENTER_COMMAND,
|
|
32265
|
+
(event) => {
|
|
32266
|
+
const handled = handleMarkdownShortcuts(editor);
|
|
32267
|
+
if (handled && event) {
|
|
32268
|
+
event.preventDefault();
|
|
32269
|
+
return true;
|
|
32270
|
+
}
|
|
32271
|
+
return false;
|
|
32272
|
+
},
|
|
32273
|
+
COMMAND_PRIORITY_HIGH
|
|
32274
|
+
);
|
|
32275
|
+
const removeBackspaceListener = editor.registerCommand(
|
|
32276
|
+
KEY_BACKSPACE_COMMAND,
|
|
32277
|
+
(event) => {
|
|
32278
|
+
const selection = $getSelection();
|
|
32279
|
+
if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
|
|
32280
|
+
return false;
|
|
32281
|
+
}
|
|
32282
|
+
const anchor = selection.anchor;
|
|
32283
|
+
const anchorNode = anchor.getNode();
|
|
32284
|
+
if (anchor.offset !== 0) {
|
|
32285
|
+
return false;
|
|
32286
|
+
}
|
|
32287
|
+
let listItem = null;
|
|
32288
|
+
let current = anchorNode;
|
|
32289
|
+
while (current !== null) {
|
|
32290
|
+
if ($isListItemNode(current)) {
|
|
32291
|
+
listItem = current;
|
|
32292
|
+
break;
|
|
32293
|
+
}
|
|
32294
|
+
current = current.getParent();
|
|
32295
|
+
}
|
|
32296
|
+
if (!listItem) {
|
|
32297
|
+
return false;
|
|
32298
|
+
}
|
|
32299
|
+
const listItemChildren = listItem.getChildren();
|
|
32300
|
+
let isAtStart = false;
|
|
32301
|
+
if (listItemChildren.length === 0) {
|
|
32302
|
+
isAtStart = true;
|
|
32303
|
+
} else {
|
|
32304
|
+
const firstChild = listItemChildren[0];
|
|
32305
|
+
if (firstChild === anchorNode) {
|
|
32306
|
+
isAtStart = true;
|
|
32307
|
+
} else {
|
|
32308
|
+
const firstChildType = firstChild.getType();
|
|
32309
|
+
if (firstChildType === "paragraph" || firstChildType === "heading") {
|
|
32310
|
+
const parent = anchorNode.getParent();
|
|
32311
|
+
if (parent && parent === firstChild) {
|
|
32312
|
+
const siblings = parent.getChildren();
|
|
32313
|
+
if (siblings.length > 0 && siblings[0] === anchorNode) {
|
|
32314
|
+
isAtStart = true;
|
|
32315
|
+
} else if (siblings.length === 0) {
|
|
32316
|
+
isAtStart = true;
|
|
32317
|
+
}
|
|
32318
|
+
}
|
|
32319
|
+
}
|
|
32320
|
+
}
|
|
32321
|
+
}
|
|
32322
|
+
if (isAtStart) {
|
|
32323
|
+
const listNode = listItem.getParent();
|
|
32324
|
+
if (listNode && $isListNode(listNode)) {
|
|
32325
|
+
const paragraphNode = $createParagraphNode();
|
|
32326
|
+
const children = listItem.getChildren();
|
|
32327
|
+
for (const child of children) {
|
|
32328
|
+
const childType = child.getType();
|
|
32329
|
+
if (childType === "paragraph" || childType === "heading") {
|
|
32330
|
+
const elementChild = child;
|
|
32331
|
+
const innerChildren = elementChild.getChildren();
|
|
32332
|
+
for (const innerChild of innerChildren) {
|
|
32333
|
+
paragraphNode.append(innerChild);
|
|
32334
|
+
}
|
|
32335
|
+
} else {
|
|
32336
|
+
paragraphNode.append(child);
|
|
32337
|
+
}
|
|
32338
|
+
}
|
|
32339
|
+
const listChildren = listNode.getChildren();
|
|
32340
|
+
const isFirstItem = listChildren.length > 0 && listChildren[0] === listItem;
|
|
32341
|
+
if (isFirstItem) {
|
|
32342
|
+
listNode.insertBefore(paragraphNode);
|
|
32343
|
+
} else {
|
|
32344
|
+
listItem.insertBefore(paragraphNode);
|
|
32345
|
+
}
|
|
32346
|
+
listItem.remove();
|
|
32347
|
+
if (listNode.getChildrenSize() === 0) {
|
|
32348
|
+
listNode.remove();
|
|
32349
|
+
}
|
|
32350
|
+
paragraphNode.selectEnd();
|
|
32351
|
+
}
|
|
32352
|
+
if (event) {
|
|
32353
|
+
event.preventDefault();
|
|
32354
|
+
}
|
|
32355
|
+
return true;
|
|
32356
|
+
}
|
|
32357
|
+
return false;
|
|
32358
|
+
},
|
|
32359
|
+
COMMAND_PRIORITY_HIGH
|
|
32360
|
+
);
|
|
32361
|
+
const removeUpdateListener = editor.registerUpdateListener(
|
|
32362
|
+
({ editorState, tags }) => {
|
|
32363
|
+
if (tags.has("history-merge"))
|
|
32364
|
+
return;
|
|
32365
|
+
editorState.read(() => {
|
|
32366
|
+
const selection = $getSelection();
|
|
32367
|
+
if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
|
|
32368
|
+
return;
|
|
32369
|
+
}
|
|
32370
|
+
const text = getLineTextBeforeCursor(editor);
|
|
32371
|
+
if (!text)
|
|
32372
|
+
return;
|
|
32373
|
+
if (text.endsWith(" ")) {
|
|
32374
|
+
if (HEADING_PATTERN.test(text)) {
|
|
32375
|
+
setTimeout(() => handleHeading(editor), 0);
|
|
32376
|
+
return;
|
|
32377
|
+
}
|
|
32378
|
+
if (BULLET_LIST_PATTERN.test(text)) {
|
|
32379
|
+
setTimeout(() => handleBulletList(editor), 0);
|
|
32380
|
+
return;
|
|
32381
|
+
}
|
|
32382
|
+
if (NUMBERED_LIST_PATTERN.test(text)) {
|
|
32383
|
+
setTimeout(() => handleNumberedList(editor), 0);
|
|
32384
|
+
return;
|
|
32385
|
+
}
|
|
32386
|
+
if (CHECKLIST_PATTERN.test(text)) {
|
|
32387
|
+
setTimeout(() => handleChecklist(editor), 0);
|
|
32388
|
+
return;
|
|
32389
|
+
}
|
|
32390
|
+
if (QUOTE_PATTERN.test(text)) {
|
|
32391
|
+
setTimeout(() => handleQuote(editor), 0);
|
|
32392
|
+
return;
|
|
32393
|
+
}
|
|
32394
|
+
}
|
|
32395
|
+
if (CODE_BLOCK_PATTERN.test(text)) {
|
|
32396
|
+
setTimeout(() => handleCodeBlock(editor), 0);
|
|
32397
|
+
return;
|
|
32398
|
+
}
|
|
32399
|
+
});
|
|
32400
|
+
}
|
|
32401
|
+
);
|
|
32402
|
+
return () => {
|
|
32403
|
+
removeTextListener();
|
|
32404
|
+
removeEnterListener();
|
|
32405
|
+
removeBackspaceListener();
|
|
32406
|
+
removeUpdateListener();
|
|
32407
|
+
};
|
|
32408
|
+
}, [editor]);
|
|
32409
|
+
return null;
|
|
32410
|
+
}
|
|
31707
32411
|
const index$2 = "";
|
|
31708
32412
|
const PUNCTUATION = `\\.,\\+\\*\\?\\$\\@\\|#{}\\(\\)\\^\\-\\[\\]\\\\/!%'"~=<>_:;`;
|
|
31709
32413
|
const NAME = "\\b[A-Z][^\\s" + PUNCTUATION + "]";
|
|
@@ -31882,6 +32586,11 @@ function detectCSSAlignment(element) {
|
|
|
31882
32586
|
while (current && current !== document.body) {
|
|
31883
32587
|
const style = current.style;
|
|
31884
32588
|
const computedStyle = window.getComputedStyle(current);
|
|
32589
|
+
const floatValue = style.cssFloat || style.float || computedStyle.cssFloat || computedStyle.float;
|
|
32590
|
+
if (floatValue === "left")
|
|
32591
|
+
return "left";
|
|
32592
|
+
if (floatValue === "right")
|
|
32593
|
+
return "right";
|
|
31885
32594
|
const textAlign = style.textAlign || computedStyle.textAlign;
|
|
31886
32595
|
if (textAlign === "center")
|
|
31887
32596
|
return "center";
|
|
@@ -31903,29 +32612,52 @@ function detectCSSAlignment(element) {
|
|
|
31903
32612
|
}
|
|
31904
32613
|
return null;
|
|
31905
32614
|
}
|
|
32615
|
+
const DEFAULT_IMAGE_DIMENSIONS = {
|
|
32616
|
+
// For side-by-side/floated images - smaller default since they share space with text
|
|
32617
|
+
floated: { width: 300, height: 200 },
|
|
32618
|
+
// For centered/standalone images - larger default for prominence
|
|
32619
|
+
centered: { width: 600, height: 400 },
|
|
32620
|
+
// For inline images without explicit layout
|
|
32621
|
+
inline: { width: 400, height: 300 },
|
|
32622
|
+
// Maximum reasonable dimensions to cap oversized images
|
|
32623
|
+
maxWidth: 800,
|
|
32624
|
+
maxHeight: 600
|
|
32625
|
+
};
|
|
31906
32626
|
function getImageDimensions(imgElement) {
|
|
31907
32627
|
let width = parseInt(imgElement.getAttribute("width") || "0");
|
|
31908
32628
|
let height = parseInt(imgElement.getAttribute("height") || "0");
|
|
31909
32629
|
if (width === 0) {
|
|
31910
32630
|
const styleWidth = imgElement.style.width;
|
|
31911
|
-
if (styleWidth
|
|
31912
|
-
|
|
32631
|
+
if (styleWidth) {
|
|
32632
|
+
const parsed = parseInt(styleWidth);
|
|
32633
|
+
if (!isNaN(parsed) && parsed > 0) {
|
|
32634
|
+
width = parsed;
|
|
32635
|
+
}
|
|
31913
32636
|
}
|
|
31914
32637
|
}
|
|
31915
32638
|
if (height === 0) {
|
|
31916
32639
|
const styleHeight = imgElement.style.height;
|
|
31917
|
-
if (styleHeight
|
|
31918
|
-
|
|
32640
|
+
if (styleHeight) {
|
|
32641
|
+
const parsed = parseInt(styleHeight);
|
|
32642
|
+
if (!isNaN(parsed) && parsed > 0) {
|
|
32643
|
+
height = parsed;
|
|
32644
|
+
}
|
|
31919
32645
|
}
|
|
31920
32646
|
}
|
|
31921
32647
|
if (width === 0 || height === 0) {
|
|
31922
32648
|
try {
|
|
31923
32649
|
const computed = window.getComputedStyle(imgElement);
|
|
31924
32650
|
if (width === 0 && computed.width && computed.width !== "auto") {
|
|
31925
|
-
|
|
32651
|
+
const parsed = parseInt(computed.width);
|
|
32652
|
+
if (!isNaN(parsed) && parsed > 0) {
|
|
32653
|
+
width = parsed;
|
|
32654
|
+
}
|
|
31926
32655
|
}
|
|
31927
32656
|
if (height === 0 && computed.height && computed.height !== "auto") {
|
|
31928
|
-
|
|
32657
|
+
const parsed = parseInt(computed.height);
|
|
32658
|
+
if (!isNaN(parsed) && parsed > 0) {
|
|
32659
|
+
height = parsed;
|
|
32660
|
+
}
|
|
31929
32661
|
}
|
|
31930
32662
|
} catch {
|
|
31931
32663
|
}
|
|
@@ -31940,6 +32672,33 @@ function getImageDimensions(imgElement) {
|
|
|
31940
32672
|
}
|
|
31941
32673
|
return { width, height };
|
|
31942
32674
|
}
|
|
32675
|
+
function getImageDimensionsWithDefaults(imgElement, layoutContext = "inline") {
|
|
32676
|
+
const { width, height } = getImageDimensions(imgElement);
|
|
32677
|
+
if (width > 0 && height > 0) {
|
|
32678
|
+
const aspectRatio = width / height;
|
|
32679
|
+
let finalWidth = width;
|
|
32680
|
+
let finalHeight = height;
|
|
32681
|
+
if (finalWidth > DEFAULT_IMAGE_DIMENSIONS.maxWidth) {
|
|
32682
|
+
finalWidth = DEFAULT_IMAGE_DIMENSIONS.maxWidth;
|
|
32683
|
+
finalHeight = Math.round(finalWidth / aspectRatio);
|
|
32684
|
+
}
|
|
32685
|
+
if (finalHeight > DEFAULT_IMAGE_DIMENSIONS.maxHeight) {
|
|
32686
|
+
finalHeight = DEFAULT_IMAGE_DIMENSIONS.maxHeight;
|
|
32687
|
+
finalWidth = Math.round(finalHeight * aspectRatio);
|
|
32688
|
+
}
|
|
32689
|
+
return { width: finalWidth, height: finalHeight };
|
|
32690
|
+
}
|
|
32691
|
+
if (width > 0) {
|
|
32692
|
+
const cappedWidth = Math.min(width, DEFAULT_IMAGE_DIMENSIONS.maxWidth);
|
|
32693
|
+
return { width: cappedWidth, height: Math.round(cappedWidth * 0.625) };
|
|
32694
|
+
}
|
|
32695
|
+
if (height > 0) {
|
|
32696
|
+
const cappedHeight = Math.min(height, DEFAULT_IMAGE_DIMENSIONS.maxHeight);
|
|
32697
|
+
return { width: Math.round(cappedHeight * 1.6), height: cappedHeight };
|
|
32698
|
+
}
|
|
32699
|
+
const defaults = DEFAULT_IMAGE_DIMENSIONS[layoutContext];
|
|
32700
|
+
return { width: defaults.width, height: defaults.height };
|
|
32701
|
+
}
|
|
31943
32702
|
function shouldCenterImage(imgElement) {
|
|
31944
32703
|
var _a;
|
|
31945
32704
|
const { width, height } = getImageDimensions(imgElement);
|
|
@@ -32042,15 +32801,205 @@ function detectClassBasedAlignment(element) {
|
|
|
32042
32801
|
}
|
|
32043
32802
|
return null;
|
|
32044
32803
|
}
|
|
32804
|
+
function isImageContainerClass(className) {
|
|
32805
|
+
const imagePatterns = [
|
|
32806
|
+
"media",
|
|
32807
|
+
"image",
|
|
32808
|
+
"img",
|
|
32809
|
+
"photo",
|
|
32810
|
+
"picture",
|
|
32811
|
+
"thumbnail",
|
|
32812
|
+
"thumb",
|
|
32813
|
+
"visual",
|
|
32814
|
+
"graphic",
|
|
32815
|
+
"illustration",
|
|
32816
|
+
"figure",
|
|
32817
|
+
"avatar",
|
|
32818
|
+
"hero",
|
|
32819
|
+
"banner",
|
|
32820
|
+
"cover",
|
|
32821
|
+
"poster",
|
|
32822
|
+
"artwork",
|
|
32823
|
+
"gallery",
|
|
32824
|
+
"featured",
|
|
32825
|
+
"wp-block-image",
|
|
32826
|
+
"wp-image",
|
|
32827
|
+
"attachment",
|
|
32828
|
+
"featured-image"
|
|
32829
|
+
];
|
|
32830
|
+
const lowerClass = className.toLowerCase();
|
|
32831
|
+
return imagePatterns.some((pattern) => lowerClass.includes(pattern));
|
|
32832
|
+
}
|
|
32833
|
+
function detectWordPressAlignment(element) {
|
|
32834
|
+
const className = element.className || "";
|
|
32835
|
+
const lowerClass = className.toLowerCase();
|
|
32836
|
+
if (lowerClass.includes("alignleft") || lowerClass.includes("align-left")) {
|
|
32837
|
+
return "left";
|
|
32838
|
+
}
|
|
32839
|
+
if (lowerClass.includes("alignright") || lowerClass.includes("align-right")) {
|
|
32840
|
+
return "right";
|
|
32841
|
+
}
|
|
32842
|
+
if (lowerClass.includes("aligncenter") || lowerClass.includes("align-center")) {
|
|
32843
|
+
return "center";
|
|
32844
|
+
}
|
|
32845
|
+
if (lowerClass.includes("alignnone") || lowerClass.includes("align-none")) {
|
|
32846
|
+
return "left";
|
|
32847
|
+
}
|
|
32848
|
+
let parent = element.parentElement;
|
|
32849
|
+
let depth = 0;
|
|
32850
|
+
while (parent && depth < 5) {
|
|
32851
|
+
const parentClass = parent.className || "";
|
|
32852
|
+
const parentLower = parentClass.toLowerCase();
|
|
32853
|
+
if (parentLower.includes("alignleft") || parentLower.includes("align-left")) {
|
|
32854
|
+
return "left";
|
|
32855
|
+
}
|
|
32856
|
+
if (parentLower.includes("alignright") || parentLower.includes("align-right")) {
|
|
32857
|
+
return "right";
|
|
32858
|
+
}
|
|
32859
|
+
if (parentLower.includes("aligncenter") || parentLower.includes("align-center")) {
|
|
32860
|
+
return "center";
|
|
32861
|
+
}
|
|
32862
|
+
parent = parent.parentElement;
|
|
32863
|
+
depth++;
|
|
32864
|
+
}
|
|
32865
|
+
return null;
|
|
32866
|
+
}
|
|
32867
|
+
function isContentContainerClass(className) {
|
|
32868
|
+
const contentPatterns = [
|
|
32869
|
+
"content",
|
|
32870
|
+
"text",
|
|
32871
|
+
"body",
|
|
32872
|
+
"copy",
|
|
32873
|
+
"description",
|
|
32874
|
+
"details",
|
|
32875
|
+
"info",
|
|
32876
|
+
"meta",
|
|
32877
|
+
"caption",
|
|
32878
|
+
"excerpt",
|
|
32879
|
+
"summary",
|
|
32880
|
+
"article",
|
|
32881
|
+
"prose",
|
|
32882
|
+
"entry",
|
|
32883
|
+
"post",
|
|
32884
|
+
"main",
|
|
32885
|
+
"primary"
|
|
32886
|
+
];
|
|
32887
|
+
const lowerClass = className.toLowerCase();
|
|
32888
|
+
return contentPatterns.some((pattern) => lowerClass.includes(pattern));
|
|
32889
|
+
}
|
|
32890
|
+
function containsImage(element) {
|
|
32891
|
+
return element.querySelector("img") !== null || element.tagName.toLowerCase() === "img";
|
|
32892
|
+
}
|
|
32893
|
+
function hasSubstantialTextContent(element) {
|
|
32894
|
+
var _a;
|
|
32895
|
+
const text = ((_a = element.textContent) == null ? void 0 : _a.trim()) || "";
|
|
32896
|
+
return text.length > 30;
|
|
32897
|
+
}
|
|
32898
|
+
function detectBootstrapColumn(element) {
|
|
32899
|
+
const className = element.className || "";
|
|
32900
|
+
const colMatch = className.match(/\bcol(-[a-z]{2})?(-\d+)?\b/);
|
|
32901
|
+
if (!colMatch)
|
|
32902
|
+
return null;
|
|
32903
|
+
const parent = element.parentElement;
|
|
32904
|
+
if (!parent)
|
|
32905
|
+
return null;
|
|
32906
|
+
const parentClass = parent.className || "";
|
|
32907
|
+
if (!parentClass.includes("row"))
|
|
32908
|
+
return null;
|
|
32909
|
+
const siblings = Array.from(parent.children).filter((child) => {
|
|
32910
|
+
const cls = child.className || "";
|
|
32911
|
+
return cls.match(/\bcol(-[a-z]{2})?(-\d+)?\b/);
|
|
32912
|
+
});
|
|
32913
|
+
const index2 = siblings.indexOf(element);
|
|
32914
|
+
if (index2 === -1)
|
|
32915
|
+
return null;
|
|
32916
|
+
return index2 < siblings.length / 2 ? "left" : "right";
|
|
32917
|
+
}
|
|
32918
|
+
function detectSideBySideLayout(imgElement) {
|
|
32919
|
+
const ancestors = [];
|
|
32920
|
+
let current = imgElement;
|
|
32921
|
+
while (current && current !== document.body && ancestors.length < 10) {
|
|
32922
|
+
ancestors.push(current);
|
|
32923
|
+
current = current.parentElement;
|
|
32924
|
+
}
|
|
32925
|
+
for (let i2 = 0; i2 < ancestors.length; i2++) {
|
|
32926
|
+
const ancestor = ancestors[i2];
|
|
32927
|
+
const parent = ancestor.parentElement;
|
|
32928
|
+
if (!parent || parent === document.body)
|
|
32929
|
+
continue;
|
|
32930
|
+
const bootstrapPos = detectBootstrapColumn(ancestor);
|
|
32931
|
+
if (bootstrapPos) {
|
|
32932
|
+
const siblings2 = Array.from(parent.children);
|
|
32933
|
+
const hasContentSibling = siblings2.some((sibling) => {
|
|
32934
|
+
if (sibling === ancestor)
|
|
32935
|
+
return false;
|
|
32936
|
+
return hasSubstantialTextContent(sibling) && !containsImage(sibling);
|
|
32937
|
+
});
|
|
32938
|
+
if (hasContentSibling) {
|
|
32939
|
+
return bootstrapPos;
|
|
32940
|
+
}
|
|
32941
|
+
}
|
|
32942
|
+
const ancestorClass = ancestor.className || "";
|
|
32943
|
+
const isMediaContainer = isImageContainerClass(ancestorClass);
|
|
32944
|
+
if (isMediaContainer) {
|
|
32945
|
+
const siblings2 = Array.from(parent.children).filter((child) => {
|
|
32946
|
+
var _a;
|
|
32947
|
+
const tag = (_a = child.tagName) == null ? void 0 : _a.toLowerCase();
|
|
32948
|
+
return tag !== "script" && tag !== "style" && tag !== "noscript";
|
|
32949
|
+
});
|
|
32950
|
+
if (siblings2.length >= 2) {
|
|
32951
|
+
const ancestorIndex = siblings2.indexOf(ancestor);
|
|
32952
|
+
const contentSiblingIndex = siblings2.findIndex((sibling, index2) => {
|
|
32953
|
+
if (index2 === ancestorIndex)
|
|
32954
|
+
return false;
|
|
32955
|
+
const siblingClass = sibling.className || "";
|
|
32956
|
+
const hasContentClass = isContentContainerClass(siblingClass);
|
|
32957
|
+
const hasText = hasSubstantialTextContent(sibling);
|
|
32958
|
+
const hasNoImage = !containsImage(sibling);
|
|
32959
|
+
return (hasContentClass || hasText) && hasNoImage;
|
|
32960
|
+
});
|
|
32961
|
+
if (contentSiblingIndex !== -1) {
|
|
32962
|
+
return ancestorIndex < contentSiblingIndex ? "left" : "right";
|
|
32963
|
+
}
|
|
32964
|
+
}
|
|
32965
|
+
}
|
|
32966
|
+
const siblings = Array.from(parent.children).filter((child) => {
|
|
32967
|
+
var _a;
|
|
32968
|
+
const tag = (_a = child.tagName) == null ? void 0 : _a.toLowerCase();
|
|
32969
|
+
return tag !== "script" && tag !== "style" && tag !== "noscript" && tag !== "br";
|
|
32970
|
+
});
|
|
32971
|
+
if (siblings.length === 2) {
|
|
32972
|
+
const ancestorIndex = siblings.indexOf(ancestor);
|
|
32973
|
+
if (ancestorIndex !== -1) {
|
|
32974
|
+
const otherSibling = siblings[1 - ancestorIndex];
|
|
32975
|
+
const ancestorHasImage = containsImage(ancestor);
|
|
32976
|
+
const otherHasImage = containsImage(otherSibling);
|
|
32977
|
+
const otherHasText = hasSubstantialTextContent(otherSibling);
|
|
32978
|
+
if (ancestorHasImage && !otherHasImage && otherHasText) {
|
|
32979
|
+
return ancestorIndex === 0 ? "left" : "right";
|
|
32980
|
+
}
|
|
32981
|
+
}
|
|
32982
|
+
}
|
|
32983
|
+
}
|
|
32984
|
+
return null;
|
|
32985
|
+
}
|
|
32045
32986
|
function detectImageAlignment(imgElement) {
|
|
32046
32987
|
const classAlignment = detectClassBasedAlignment(imgElement);
|
|
32047
32988
|
if (classAlignment) {
|
|
32048
32989
|
return classAlignment;
|
|
32049
32990
|
}
|
|
32991
|
+
const wpAlignment = detectWordPressAlignment(imgElement);
|
|
32992
|
+
if (wpAlignment) {
|
|
32993
|
+
return wpAlignment;
|
|
32994
|
+
}
|
|
32050
32995
|
const cssAlignment = detectCSSAlignment(imgElement);
|
|
32051
32996
|
if (cssAlignment) {
|
|
32052
32997
|
return cssAlignment;
|
|
32053
32998
|
}
|
|
32999
|
+
const sideBySideAlignment = detectSideBySideLayout(imgElement);
|
|
33000
|
+
if (sideBySideAlignment) {
|
|
33001
|
+
return sideBySideAlignment;
|
|
33002
|
+
}
|
|
32054
33003
|
if (shouldCenterImage(imgElement)) {
|
|
32055
33004
|
return "center";
|
|
32056
33005
|
}
|
|
@@ -32372,7 +33321,7 @@ const defaultPasteContext = {
|
|
|
32372
33321
|
};
|
|
32373
33322
|
let currentPasteContext = defaultPasteContext;
|
|
32374
33323
|
function processNode(domNode, parentElement = null) {
|
|
32375
|
-
var _a;
|
|
33324
|
+
var _a, _b, _c;
|
|
32376
33325
|
const results = [];
|
|
32377
33326
|
if (domNode.nodeType === Node.TEXT_NODE) {
|
|
32378
33327
|
const text = domNode.textContent || "";
|
|
@@ -32398,17 +33347,22 @@ function processNode(domNode, parentElement = null) {
|
|
|
32398
33347
|
const paragraph = $createParagraphNode();
|
|
32399
33348
|
const styleInfo = getStyleInfoFromElement(element);
|
|
32400
33349
|
const hasExplicitFontSize = styleInfo.fontSize && styleInfo.fontSize !== "16px";
|
|
33350
|
+
let overflowNodes = [];
|
|
32401
33351
|
if (!hasExplicitFontSize && currentPasteContext.isCKEditor) {
|
|
32402
33352
|
processChildrenWithStyle(element, paragraph, {
|
|
32403
33353
|
fontSize: DEFAULT_PARAGRAPH_FONT_SIZE,
|
|
32404
33354
|
lineHeight: DEFAULT_PARAGRAPH_LINE_HEIGHT
|
|
32405
33355
|
});
|
|
32406
33356
|
} else {
|
|
32407
|
-
|
|
33357
|
+
const result = processChildrenWithImageSeparation(element, paragraph);
|
|
33358
|
+
overflowNodes = result.overflowNodes;
|
|
32408
33359
|
}
|
|
32409
33360
|
if (paragraph.getChildrenSize() > 0 || tagName === "p") {
|
|
32410
33361
|
results.push(paragraph);
|
|
32411
33362
|
}
|
|
33363
|
+
if (overflowNodes.length > 0) {
|
|
33364
|
+
results.push(...overflowNodes);
|
|
33365
|
+
}
|
|
32412
33366
|
break;
|
|
32413
33367
|
}
|
|
32414
33368
|
case "h1":
|
|
@@ -32471,7 +33425,41 @@ function processNode(domNode, parentElement = null) {
|
|
|
32471
33425
|
}
|
|
32472
33426
|
case "a": {
|
|
32473
33427
|
const href = element.getAttribute("href") || "";
|
|
32474
|
-
|
|
33428
|
+
const containedImg = element.querySelector("img");
|
|
33429
|
+
if (containedImg) {
|
|
33430
|
+
const src = containedImg.getAttribute("src") || "";
|
|
33431
|
+
if (src && !src.startsWith("file:///")) {
|
|
33432
|
+
const alt = containedImg.getAttribute("alt") || "";
|
|
33433
|
+
const alignment = detectImageAlignment(containedImg);
|
|
33434
|
+
const layoutContext = isFloatAlignment(alignment) ? "floated" : alignment === "center" ? "centered" : "inline";
|
|
33435
|
+
const { width, height } = getImageDimensionsWithDefaults(containedImg, layoutContext);
|
|
33436
|
+
const position = alignmentToPosition(alignment);
|
|
33437
|
+
const imageNode = $createImageNode({
|
|
33438
|
+
src,
|
|
33439
|
+
altText: alt,
|
|
33440
|
+
width,
|
|
33441
|
+
height,
|
|
33442
|
+
position: isFloatAlignment(alignment) ? position : "none",
|
|
33443
|
+
linkUrl: href
|
|
33444
|
+
// Store the original link URL
|
|
33445
|
+
});
|
|
33446
|
+
if (alignment === "center") {
|
|
33447
|
+
const paragraph = $createParagraphNode();
|
|
33448
|
+
paragraph.setFormat("center");
|
|
33449
|
+
paragraph.append(imageNode);
|
|
33450
|
+
results.push(paragraph);
|
|
33451
|
+
} else {
|
|
33452
|
+
results.push(imageNode);
|
|
33453
|
+
}
|
|
33454
|
+
}
|
|
33455
|
+
const textContent = (_a = element.textContent) == null ? void 0 : _a.replace(containedImg.alt || "", "").trim();
|
|
33456
|
+
if (textContent && textContent.length > 0) {
|
|
33457
|
+
const linkNode = $createLinkNode(href, { target: "_blank", rel: "noopener" });
|
|
33458
|
+
const textNode = $createTextNode(textContent);
|
|
33459
|
+
linkNode.append(textNode);
|
|
33460
|
+
results.push(linkNode);
|
|
33461
|
+
}
|
|
33462
|
+
} else if (href) {
|
|
32475
33463
|
const linkNode = $createLinkNode(href, { target: "_blank", rel: "noopener" });
|
|
32476
33464
|
processChildren(element, linkNode);
|
|
32477
33465
|
results.push(linkNode);
|
|
@@ -32485,9 +33473,9 @@ function processNode(domNode, parentElement = null) {
|
|
|
32485
33473
|
const src = element.getAttribute("src") || "";
|
|
32486
33474
|
if (src && !src.startsWith("file:///")) {
|
|
32487
33475
|
const alt = element.getAttribute("alt") || "";
|
|
32488
|
-
const width = parseInt(element.getAttribute("width") || "0") || void 0;
|
|
32489
|
-
const height = parseInt(element.getAttribute("height") || "0") || void 0;
|
|
32490
33476
|
const alignment = detectImageAlignment(element);
|
|
33477
|
+
const layoutContext = isFloatAlignment(alignment) ? "floated" : alignment === "center" ? "centered" : "inline";
|
|
33478
|
+
const { width, height } = getImageDimensionsWithDefaults(element, layoutContext);
|
|
32491
33479
|
const position = alignmentToPosition(alignment);
|
|
32492
33480
|
const imageNode = $createImageNode({
|
|
32493
33481
|
src,
|
|
@@ -32518,13 +33506,13 @@ function processNode(domNode, parentElement = null) {
|
|
|
32518
33506
|
const position = alignmentToPosition(alignment);
|
|
32519
33507
|
const isFloat = isFloatAlignment(alignment);
|
|
32520
33508
|
const figcaption = element.querySelector("figcaption");
|
|
32521
|
-
const captionText = ((
|
|
33509
|
+
const captionText = ((_b = figcaption == null ? void 0 : figcaption.textContent) == null ? void 0 : _b.trim()) || "";
|
|
32522
33510
|
if (img) {
|
|
32523
33511
|
const src = img.getAttribute("src") || "";
|
|
32524
33512
|
if (src && !src.startsWith("file:///")) {
|
|
32525
33513
|
const alt = img.getAttribute("alt") || "";
|
|
32526
|
-
const
|
|
32527
|
-
const height =
|
|
33514
|
+
const layoutContext = isFloat ? "floated" : alignment === "center" ? "centered" : "inline";
|
|
33515
|
+
const { width, height } = getImageDimensionsWithDefaults(img, layoutContext);
|
|
32528
33516
|
const imageNode = $createImageNode({
|
|
32529
33517
|
src,
|
|
32530
33518
|
altText: alt,
|
|
@@ -32563,6 +33551,43 @@ function processNode(domNode, parentElement = null) {
|
|
|
32563
33551
|
}
|
|
32564
33552
|
break;
|
|
32565
33553
|
}
|
|
33554
|
+
case "code": {
|
|
33555
|
+
const className = element.className || "";
|
|
33556
|
+
const isBlockCode = className.includes("PlaygroundEditorTheme__code") || className.includes("code-block") || element.hasAttribute("data-language") || element.hasAttribute("data-highlight-language");
|
|
33557
|
+
if (isBlockCode) {
|
|
33558
|
+
const language = element.getAttribute("data-language") || element.getAttribute("data-highlight-language") || void 0;
|
|
33559
|
+
const codeNode = $createCodeNode(language);
|
|
33560
|
+
const textContent = element.textContent || "";
|
|
33561
|
+
if (textContent) {
|
|
33562
|
+
codeNode.append($createTextNode(textContent));
|
|
33563
|
+
}
|
|
33564
|
+
results.push(codeNode);
|
|
33565
|
+
} else {
|
|
33566
|
+
const children = processChildren(element);
|
|
33567
|
+
results.push(...children);
|
|
33568
|
+
}
|
|
33569
|
+
break;
|
|
33570
|
+
}
|
|
33571
|
+
case "pre": {
|
|
33572
|
+
const codeChild = element.querySelector("code");
|
|
33573
|
+
if (codeChild) {
|
|
33574
|
+
const language = codeChild.getAttribute("data-language") || codeChild.getAttribute("data-highlight-language") || ((_c = codeChild.className.match(/language-(\w+)/)) == null ? void 0 : _c[1]) || void 0;
|
|
33575
|
+
const codeNode = $createCodeNode(language);
|
|
33576
|
+
const textContent = codeChild.textContent || "";
|
|
33577
|
+
if (textContent) {
|
|
33578
|
+
codeNode.append($createTextNode(textContent));
|
|
33579
|
+
}
|
|
33580
|
+
results.push(codeNode);
|
|
33581
|
+
} else {
|
|
33582
|
+
const codeNode = $createCodeNode();
|
|
33583
|
+
const textContent = element.textContent || "";
|
|
33584
|
+
if (textContent) {
|
|
33585
|
+
codeNode.append($createTextNode(textContent));
|
|
33586
|
+
}
|
|
33587
|
+
results.push(codeNode);
|
|
33588
|
+
}
|
|
33589
|
+
break;
|
|
33590
|
+
}
|
|
32566
33591
|
case "strong":
|
|
32567
33592
|
case "b":
|
|
32568
33593
|
case "em":
|
|
@@ -32571,7 +33596,6 @@ function processNode(domNode, parentElement = null) {
|
|
|
32571
33596
|
case "s":
|
|
32572
33597
|
case "strike":
|
|
32573
33598
|
case "del":
|
|
32574
|
-
case "code":
|
|
32575
33599
|
case "sub":
|
|
32576
33600
|
case "sup":
|
|
32577
33601
|
case "mark":
|
|
@@ -32619,6 +33643,60 @@ function processChildren(element, parentNode) {
|
|
|
32619
33643
|
}
|
|
32620
33644
|
return results;
|
|
32621
33645
|
}
|
|
33646
|
+
function processChildrenWithImageSeparation(element, parentNode) {
|
|
33647
|
+
const overflowNodes = [];
|
|
33648
|
+
let hasTextContent = false;
|
|
33649
|
+
const childNodes = element.childNodes;
|
|
33650
|
+
for (let i2 = 0; i2 < childNodes.length; i2++) {
|
|
33651
|
+
const child = childNodes[i2];
|
|
33652
|
+
if (child.nodeType === Node.ELEMENT_NODE) {
|
|
33653
|
+
const childElement = child;
|
|
33654
|
+
const tagName = childElement.tagName.toLowerCase();
|
|
33655
|
+
if (tagName === "img") {
|
|
33656
|
+
if (hasTextContent) {
|
|
33657
|
+
const nodes2 = processNode(child, element);
|
|
33658
|
+
nodes2.forEach((node) => {
|
|
33659
|
+
if ($isImageNode(node)) {
|
|
33660
|
+
const imageParagraph = $createParagraphNode();
|
|
33661
|
+
imageParagraph.append(node);
|
|
33662
|
+
overflowNodes.push(imageParagraph);
|
|
33663
|
+
} else if (node instanceof ParagraphNode) {
|
|
33664
|
+
overflowNodes.push(node);
|
|
33665
|
+
} else {
|
|
33666
|
+
overflowNodes.push(node);
|
|
33667
|
+
}
|
|
33668
|
+
});
|
|
33669
|
+
continue;
|
|
33670
|
+
}
|
|
33671
|
+
}
|
|
33672
|
+
}
|
|
33673
|
+
const nodes = processNode(child, element);
|
|
33674
|
+
nodes.forEach((node) => {
|
|
33675
|
+
if ($isTextNode(node) && node.getTextContent().trim().length > 0) {
|
|
33676
|
+
hasTextContent = true;
|
|
33677
|
+
}
|
|
33678
|
+
if ($isImageNode(node) && hasTextContent) {
|
|
33679
|
+
const imageParagraph = $createParagraphNode();
|
|
33680
|
+
imageParagraph.append(node);
|
|
33681
|
+
overflowNodes.push(imageParagraph);
|
|
33682
|
+
} else if (node instanceof ParagraphNode && hasTextContent) {
|
|
33683
|
+
const children = node.getChildren();
|
|
33684
|
+
const hasOnlyImage = children.length === 1 && $isImageNode(children[0]);
|
|
33685
|
+
if (hasOnlyImage) {
|
|
33686
|
+
overflowNodes.push(node);
|
|
33687
|
+
} else {
|
|
33688
|
+
parentNode.append(node);
|
|
33689
|
+
}
|
|
33690
|
+
} else {
|
|
33691
|
+
parentNode.append(node);
|
|
33692
|
+
if ($isTextNode(node) && node.getTextContent().trim().length > 0) {
|
|
33693
|
+
hasTextContent = true;
|
|
33694
|
+
}
|
|
33695
|
+
}
|
|
33696
|
+
});
|
|
33697
|
+
}
|
|
33698
|
+
return { overflowNodes };
|
|
33699
|
+
}
|
|
32622
33700
|
function processChildrenWithStyle(element, parentNode, defaultStyles) {
|
|
32623
33701
|
const childNodes = element.childNodes;
|
|
32624
33702
|
for (let i2 = 0; i2 < childNodes.length; i2++) {
|
|
@@ -32908,6 +33986,651 @@ function RichTextPastePlugin() {
|
|
|
32908
33986
|
}, [editor]);
|
|
32909
33987
|
return null;
|
|
32910
33988
|
}
|
|
33989
|
+
function htmlContainsImages(html) {
|
|
33990
|
+
if (!html)
|
|
33991
|
+
return false;
|
|
33992
|
+
return /<img\s/i.test(html) || /data:image\//i.test(html);
|
|
33993
|
+
}
|
|
33994
|
+
function PasteOptionsMenu({
|
|
33995
|
+
position,
|
|
33996
|
+
currentMode,
|
|
33997
|
+
onSelectMode,
|
|
33998
|
+
onClose,
|
|
33999
|
+
hasHtml
|
|
34000
|
+
}) {
|
|
34001
|
+
const menuRef = useRef(null);
|
|
34002
|
+
const [isOpen, setIsOpen] = useState$1(false);
|
|
34003
|
+
const [menuPosition, setMenuPosition] = useState$1(position);
|
|
34004
|
+
useEffect$1(() => {
|
|
34005
|
+
setMenuPosition(position);
|
|
34006
|
+
}, [position]);
|
|
34007
|
+
useEffect$1(() => {
|
|
34008
|
+
const handleClickOutside = (e) => {
|
|
34009
|
+
if (menuRef.current && !menuRef.current.contains(e.target)) {
|
|
34010
|
+
onClose();
|
|
34011
|
+
}
|
|
34012
|
+
};
|
|
34013
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
34014
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
34015
|
+
}, [onClose]);
|
|
34016
|
+
const allOptions = [
|
|
34017
|
+
{
|
|
34018
|
+
mode: "rich",
|
|
34019
|
+
label: "Use rich text",
|
|
34020
|
+
icon: /* @__PURE__ */ jsx(Type, { className: "cteditor-size-4" })
|
|
34021
|
+
},
|
|
34022
|
+
{
|
|
34023
|
+
mode: "markdown",
|
|
34024
|
+
label: "Use Markdown",
|
|
34025
|
+
icon: /* @__PURE__ */ jsx(Hash, { className: "cteditor-size-4" })
|
|
34026
|
+
},
|
|
34027
|
+
{
|
|
34028
|
+
mode: "plain",
|
|
34029
|
+
label: "Use plain text",
|
|
34030
|
+
icon: /* @__PURE__ */ jsx(FileText, { className: "cteditor-size-4" })
|
|
34031
|
+
}
|
|
34032
|
+
];
|
|
34033
|
+
const options = hasHtml ? allOptions : allOptions.filter((option) => option.mode !== "rich");
|
|
34034
|
+
const currentOption = options.find((o) => o.mode === currentMode);
|
|
34035
|
+
const menuStyle = {
|
|
34036
|
+
position: "fixed",
|
|
34037
|
+
left: Math.min(menuPosition.x, window.innerWidth - 200),
|
|
34038
|
+
top: Math.min(menuPosition.y + 5, window.innerHeight - 150),
|
|
34039
|
+
zIndex: 1e3
|
|
34040
|
+
};
|
|
34041
|
+
return /* @__PURE__ */ jsxs("div", { ref: menuRef, style: menuStyle, className: "cteditor-relative", children: [
|
|
34042
|
+
/* @__PURE__ */ jsxs(
|
|
34043
|
+
"button",
|
|
34044
|
+
{
|
|
34045
|
+
onClick: () => setIsOpen(!isOpen),
|
|
34046
|
+
className: "cteditor-flex cteditor-items-center cteditor-gap-1.5 cteditor-px-2 cteditor-py-1 cteditor-text-xs cteditor-bg-background cteditor-border cteditor-border-border cteditor-rounded-md cteditor-shadow-lg hover:cteditor-bg-accent cteditor-transition-colors",
|
|
34047
|
+
children: [
|
|
34048
|
+
currentOption == null ? void 0 : currentOption.icon,
|
|
34049
|
+
/* @__PURE__ */ jsx(
|
|
34050
|
+
ChevronDown,
|
|
34051
|
+
{
|
|
34052
|
+
className: `cteditor-size-3 cteditor-transition-transform ${isOpen ? "cteditor-rotate-180" : ""}`
|
|
34053
|
+
}
|
|
34054
|
+
)
|
|
34055
|
+
]
|
|
34056
|
+
}
|
|
34057
|
+
),
|
|
34058
|
+
isOpen && /* @__PURE__ */ jsx("div", { className: "cteditor-absolute cteditor-top-full cteditor-left-0 cteditor-mt-1 cteditor-w-44 cteditor-bg-background cteditor-border cteditor-border-border cteditor-rounded-md cteditor-shadow-xl cteditor-overflow-hidden", children: options.map((option) => /* @__PURE__ */ jsxs(
|
|
34059
|
+
"button",
|
|
34060
|
+
{
|
|
34061
|
+
onClick: () => {
|
|
34062
|
+
onSelectMode(option.mode);
|
|
34063
|
+
setIsOpen(false);
|
|
34064
|
+
},
|
|
34065
|
+
className: `cteditor-w-full cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-px-3 cteditor-py-2 cteditor-text-xs hover:cteditor-bg-accent cteditor-transition-colors ${currentMode === option.mode ? "cteditor-bg-primary/10 cteditor-text-primary" : ""}`,
|
|
34066
|
+
children: [
|
|
34067
|
+
option.icon,
|
|
34068
|
+
/* @__PURE__ */ jsx("span", { className: "cteditor-flex-1 cteditor-text-left", children: option.label }),
|
|
34069
|
+
currentMode === option.mode && /* @__PURE__ */ jsx(Check, { className: "cteditor-size-3 cteditor-text-primary" })
|
|
34070
|
+
]
|
|
34071
|
+
},
|
|
34072
|
+
option.mode
|
|
34073
|
+
)) })
|
|
34074
|
+
] });
|
|
34075
|
+
}
|
|
34076
|
+
function processInlineMarkdown(text) {
|
|
34077
|
+
if (!text) {
|
|
34078
|
+
return [];
|
|
34079
|
+
}
|
|
34080
|
+
const nodes = [];
|
|
34081
|
+
const tripleBacktickPattern = /```([^`]+)```/g;
|
|
34082
|
+
if (tripleBacktickPattern.test(text)) {
|
|
34083
|
+
tripleBacktickPattern.lastIndex = 0;
|
|
34084
|
+
let lastIndex = 0;
|
|
34085
|
+
let match;
|
|
34086
|
+
while ((match = tripleBacktickPattern.exec(text)) !== null) {
|
|
34087
|
+
if (match.index > lastIndex) {
|
|
34088
|
+
const beforeText = text.slice(lastIndex, match.index);
|
|
34089
|
+
const beforeNodes = processSimpleInlineMarkdown(beforeText);
|
|
34090
|
+
nodes.push(...beforeNodes);
|
|
34091
|
+
}
|
|
34092
|
+
const codeContent = match[1];
|
|
34093
|
+
const codeNode = $createTextNode(codeContent);
|
|
34094
|
+
codeNode.toggleFormat("code");
|
|
34095
|
+
nodes.push(codeNode);
|
|
34096
|
+
lastIndex = match.index + match[0].length;
|
|
34097
|
+
}
|
|
34098
|
+
if (lastIndex < text.length) {
|
|
34099
|
+
const afterText = text.slice(lastIndex);
|
|
34100
|
+
const afterNodes = processSimpleInlineMarkdown(afterText);
|
|
34101
|
+
nodes.push(...afterNodes);
|
|
34102
|
+
}
|
|
34103
|
+
return nodes;
|
|
34104
|
+
}
|
|
34105
|
+
return processSimpleInlineMarkdown(text);
|
|
34106
|
+
}
|
|
34107
|
+
function processSimpleInlineMarkdown(text) {
|
|
34108
|
+
if (!text) {
|
|
34109
|
+
return [];
|
|
34110
|
+
}
|
|
34111
|
+
let processedText = text;
|
|
34112
|
+
let hasBold = false;
|
|
34113
|
+
let hasItalic = false;
|
|
34114
|
+
let hasCode = false;
|
|
34115
|
+
let hasStrikethrough = false;
|
|
34116
|
+
if (/\*\*(.+?)\*\*/.test(processedText)) {
|
|
34117
|
+
hasBold = true;
|
|
34118
|
+
processedText = processedText.replace(/\*\*(.+?)\*\*/g, "$1");
|
|
34119
|
+
}
|
|
34120
|
+
if (/__(.+?)__/.test(processedText)) {
|
|
34121
|
+
hasBold = true;
|
|
34122
|
+
processedText = processedText.replace(/__(.+?)__/g, "$1");
|
|
34123
|
+
}
|
|
34124
|
+
if (!hasBold && /^\*([^*]+)\*$/.test(processedText)) {
|
|
34125
|
+
hasItalic = true;
|
|
34126
|
+
processedText = processedText.replace(/^\*([^*]+)\*$/, "$1");
|
|
34127
|
+
} else if (/(?:^|[^*])\*([^*]+)\*(?:[^*]|$)/.test(processedText)) {
|
|
34128
|
+
hasItalic = true;
|
|
34129
|
+
processedText = processedText.replace(/\*([^*]+)\*/g, "$1");
|
|
34130
|
+
}
|
|
34131
|
+
if (!hasBold && /^_([^_]+)_$/.test(processedText)) {
|
|
34132
|
+
hasItalic = true;
|
|
34133
|
+
processedText = processedText.replace(/^_([^_]+)_$/, "$1");
|
|
34134
|
+
} else if (/(?:^|[^_])_([^_]+)_(?:[^_]|$)/.test(processedText)) {
|
|
34135
|
+
hasItalic = true;
|
|
34136
|
+
processedText = processedText.replace(/_([^_]+)_/g, "$1");
|
|
34137
|
+
}
|
|
34138
|
+
if (new RegExp("(?<!`)`([^`]+)`(?!`)").test(processedText)) {
|
|
34139
|
+
hasCode = true;
|
|
34140
|
+
processedText = processedText.replace(new RegExp("(?<!`)`([^`]+)`(?!`)", "g"), "$1");
|
|
34141
|
+
}
|
|
34142
|
+
if (/~~(.+?)~~/.test(processedText)) {
|
|
34143
|
+
hasStrikethrough = true;
|
|
34144
|
+
processedText = processedText.replace(/~~(.+?)~~/g, "$1");
|
|
34145
|
+
}
|
|
34146
|
+
processedText = processedText.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
|
|
34147
|
+
const textNode = $createTextNode(processedText);
|
|
34148
|
+
if (hasBold)
|
|
34149
|
+
textNode.toggleFormat("bold");
|
|
34150
|
+
if (hasItalic)
|
|
34151
|
+
textNode.toggleFormat("italic");
|
|
34152
|
+
if (hasCode)
|
|
34153
|
+
textNode.toggleFormat("code");
|
|
34154
|
+
if (hasStrikethrough)
|
|
34155
|
+
textNode.toggleFormat("strikethrough");
|
|
34156
|
+
return [textNode];
|
|
34157
|
+
}
|
|
34158
|
+
function convertMarkdownToNodes(text, editor) {
|
|
34159
|
+
const nodes = [];
|
|
34160
|
+
const lines = text.split("\n");
|
|
34161
|
+
let i2 = 0;
|
|
34162
|
+
while (i2 < lines.length) {
|
|
34163
|
+
const line = lines[i2];
|
|
34164
|
+
if (line.trim() === "") {
|
|
34165
|
+
i2++;
|
|
34166
|
+
continue;
|
|
34167
|
+
}
|
|
34168
|
+
if (/^(---|___|\*\*\*)$/.test(line.trim())) {
|
|
34169
|
+
const placeholder = $createParagraphNode();
|
|
34170
|
+
placeholder.append($createTextNode("___MARKDOWN_HR___"));
|
|
34171
|
+
nodes.push(placeholder);
|
|
34172
|
+
i2++;
|
|
34173
|
+
continue;
|
|
34174
|
+
}
|
|
34175
|
+
const singleLineCodeMatch = line.trim().match(/^```(.+?)```$/);
|
|
34176
|
+
if (singleLineCodeMatch) {
|
|
34177
|
+
const codeContent = singleLineCodeMatch[1];
|
|
34178
|
+
const codeNode = $createCodeNode();
|
|
34179
|
+
codeNode.append($createTextNode(codeContent));
|
|
34180
|
+
nodes.push(codeNode);
|
|
34181
|
+
const afterParagraph = $createParagraphNode();
|
|
34182
|
+
nodes.push(afterParagraph);
|
|
34183
|
+
i2++;
|
|
34184
|
+
continue;
|
|
34185
|
+
}
|
|
34186
|
+
if (line.trim().startsWith("```")) {
|
|
34187
|
+
const codeLines = [];
|
|
34188
|
+
const langMatch = line.trim().match(/^```(\w*)$/);
|
|
34189
|
+
i2++;
|
|
34190
|
+
while (i2 < lines.length && !lines[i2].trim().startsWith("```")) {
|
|
34191
|
+
codeLines.push(lines[i2]);
|
|
34192
|
+
i2++;
|
|
34193
|
+
}
|
|
34194
|
+
if (i2 < lines.length)
|
|
34195
|
+
i2++;
|
|
34196
|
+
const codeNode = $createCodeNode((langMatch == null ? void 0 : langMatch[1]) || void 0);
|
|
34197
|
+
codeNode.append($createTextNode(codeLines.join("\n")));
|
|
34198
|
+
nodes.push(codeNode);
|
|
34199
|
+
const afterParagraph = $createParagraphNode();
|
|
34200
|
+
nodes.push(afterParagraph);
|
|
34201
|
+
continue;
|
|
34202
|
+
}
|
|
34203
|
+
const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
|
|
34204
|
+
if (headingMatch) {
|
|
34205
|
+
const level = headingMatch[1].length;
|
|
34206
|
+
const headingNode = $createHeadingNode(
|
|
34207
|
+
`h${level}`
|
|
34208
|
+
);
|
|
34209
|
+
const textNodes2 = processInlineMarkdown(headingMatch[2].trim());
|
|
34210
|
+
textNodes2.forEach((node) => headingNode.append(node));
|
|
34211
|
+
nodes.push(headingNode);
|
|
34212
|
+
i2++;
|
|
34213
|
+
continue;
|
|
34214
|
+
}
|
|
34215
|
+
if (/^[*\-+]\s+/.test(line)) {
|
|
34216
|
+
const listNode = $createListNode("bullet");
|
|
34217
|
+
while (i2 < lines.length && /^[*\-+]\s+/.test(lines[i2])) {
|
|
34218
|
+
const listItemNode = $createListItemNode();
|
|
34219
|
+
const itemText = lines[i2].replace(/^[*\-+]\s+/, "");
|
|
34220
|
+
if (itemText) {
|
|
34221
|
+
const textNodes2 = processInlineMarkdown(itemText);
|
|
34222
|
+
if (textNodes2.length > 0) {
|
|
34223
|
+
textNodes2.forEach((node) => listItemNode.append(node));
|
|
34224
|
+
} else {
|
|
34225
|
+
listItemNode.append($createTextNode(itemText));
|
|
34226
|
+
}
|
|
34227
|
+
}
|
|
34228
|
+
listNode.append(listItemNode);
|
|
34229
|
+
i2++;
|
|
34230
|
+
}
|
|
34231
|
+
nodes.push(listNode);
|
|
34232
|
+
continue;
|
|
34233
|
+
}
|
|
34234
|
+
if (/^\d+[.)]\s+/.test(line)) {
|
|
34235
|
+
const listNode = $createListNode("number");
|
|
34236
|
+
while (i2 < lines.length && /^\d+[.)]\s+/.test(lines[i2])) {
|
|
34237
|
+
const listItemNode = $createListItemNode();
|
|
34238
|
+
const itemText = lines[i2].replace(/^\d+[.)]\s+/, "");
|
|
34239
|
+
if (itemText) {
|
|
34240
|
+
const textNodes2 = processInlineMarkdown(itemText);
|
|
34241
|
+
if (textNodes2.length > 0) {
|
|
34242
|
+
textNodes2.forEach((node) => listItemNode.append(node));
|
|
34243
|
+
} else {
|
|
34244
|
+
listItemNode.append($createTextNode(itemText));
|
|
34245
|
+
}
|
|
34246
|
+
}
|
|
34247
|
+
listNode.append(listItemNode);
|
|
34248
|
+
i2++;
|
|
34249
|
+
}
|
|
34250
|
+
nodes.push(listNode);
|
|
34251
|
+
continue;
|
|
34252
|
+
}
|
|
34253
|
+
if (/^\[(x|\s)?\]\s+/i.test(line)) {
|
|
34254
|
+
const listNode = $createListNode("check");
|
|
34255
|
+
while (i2 < lines.length && /^\[(x|\s)?\]\s+/i.test(lines[i2])) {
|
|
34256
|
+
const listItemNode = $createListItemNode();
|
|
34257
|
+
const isChecked = /^\[x\]/i.test(lines[i2]);
|
|
34258
|
+
const itemText = lines[i2].replace(/^\[(x|\s)?\]\s+/i, "");
|
|
34259
|
+
if (itemText) {
|
|
34260
|
+
const textNodes2 = processInlineMarkdown(itemText);
|
|
34261
|
+
if (textNodes2.length > 0) {
|
|
34262
|
+
textNodes2.forEach((node) => listItemNode.append(node));
|
|
34263
|
+
} else {
|
|
34264
|
+
listItemNode.append($createTextNode(itemText));
|
|
34265
|
+
}
|
|
34266
|
+
}
|
|
34267
|
+
if (isChecked) {
|
|
34268
|
+
listItemNode.setChecked(true);
|
|
34269
|
+
}
|
|
34270
|
+
listNode.append(listItemNode);
|
|
34271
|
+
i2++;
|
|
34272
|
+
}
|
|
34273
|
+
nodes.push(listNode);
|
|
34274
|
+
continue;
|
|
34275
|
+
}
|
|
34276
|
+
if (/^>\s*/.test(line)) {
|
|
34277
|
+
const quoteNode = $createQuoteNode();
|
|
34278
|
+
const quoteLines = [];
|
|
34279
|
+
while (i2 < lines.length && /^>\s*/.test(lines[i2])) {
|
|
34280
|
+
quoteLines.push(lines[i2].replace(/^>\s*/, ""));
|
|
34281
|
+
i2++;
|
|
34282
|
+
}
|
|
34283
|
+
const quoteText = quoteLines.join("\n");
|
|
34284
|
+
if (quoteText) {
|
|
34285
|
+
const textNodes2 = processInlineMarkdown(quoteText);
|
|
34286
|
+
if (textNodes2.length > 0) {
|
|
34287
|
+
textNodes2.forEach((node) => quoteNode.append(node));
|
|
34288
|
+
} else {
|
|
34289
|
+
quoteNode.append($createTextNode(quoteText));
|
|
34290
|
+
}
|
|
34291
|
+
}
|
|
34292
|
+
nodes.push(quoteNode);
|
|
34293
|
+
continue;
|
|
34294
|
+
}
|
|
34295
|
+
const paragraph = $createParagraphNode();
|
|
34296
|
+
const textNodes = processInlineMarkdown(line);
|
|
34297
|
+
textNodes.forEach((node) => paragraph.append(node));
|
|
34298
|
+
nodes.push(paragraph);
|
|
34299
|
+
i2++;
|
|
34300
|
+
}
|
|
34301
|
+
return nodes;
|
|
34302
|
+
}
|
|
34303
|
+
function convertPlainTextToNodes(text) {
|
|
34304
|
+
const nodes = [];
|
|
34305
|
+
const paragraphs = text.split(/\n\n+/);
|
|
34306
|
+
for (const para of paragraphs) {
|
|
34307
|
+
if (para.trim() || para === "") {
|
|
34308
|
+
const paragraph = $createParagraphNode();
|
|
34309
|
+
const lines = para.split(/\n/);
|
|
34310
|
+
lines.forEach((line, index2) => {
|
|
34311
|
+
if (line) {
|
|
34312
|
+
paragraph.append($createTextNode(line));
|
|
34313
|
+
}
|
|
34314
|
+
if (index2 < lines.length - 1) {
|
|
34315
|
+
paragraph.append($createLineBreakNode());
|
|
34316
|
+
}
|
|
34317
|
+
});
|
|
34318
|
+
if (paragraph.getChildrenSize() > 0) {
|
|
34319
|
+
nodes.push(paragraph);
|
|
34320
|
+
}
|
|
34321
|
+
}
|
|
34322
|
+
}
|
|
34323
|
+
if (nodes.length === 0) {
|
|
34324
|
+
nodes.push($createParagraphNode());
|
|
34325
|
+
}
|
|
34326
|
+
return nodes;
|
|
34327
|
+
}
|
|
34328
|
+
function applyMarkdownToNodes(nodes, _editor) {
|
|
34329
|
+
const processTextNode = (node) => {
|
|
34330
|
+
const text = node.getTextContent();
|
|
34331
|
+
const style = node.getStyle();
|
|
34332
|
+
const format = node.getFormat();
|
|
34333
|
+
const markdownPattern = new RegExp("(```([^`]+)```)|(`([^`]+)`)|(\\*\\*(.+?)\\*\\*)|((?<!\\*)\\*([^*]+)\\*(?!\\*))|(~~(.+?)~~)", "g");
|
|
34334
|
+
if (!markdownPattern.test(text)) {
|
|
34335
|
+
return [node];
|
|
34336
|
+
}
|
|
34337
|
+
markdownPattern.lastIndex = 0;
|
|
34338
|
+
const resultNodes = [];
|
|
34339
|
+
let lastIndex = 0;
|
|
34340
|
+
let match;
|
|
34341
|
+
while ((match = markdownPattern.exec(text)) !== null) {
|
|
34342
|
+
if (match.index > lastIndex) {
|
|
34343
|
+
const beforeText = text.slice(lastIndex, match.index);
|
|
34344
|
+
const beforeNode = $createTextNode(beforeText);
|
|
34345
|
+
if (style)
|
|
34346
|
+
beforeNode.setStyle(style);
|
|
34347
|
+
if (format)
|
|
34348
|
+
beforeNode.setFormat(format);
|
|
34349
|
+
resultNodes.push(beforeNode);
|
|
34350
|
+
}
|
|
34351
|
+
let content = "";
|
|
34352
|
+
let nodeFormat = format;
|
|
34353
|
+
if (match[1]) {
|
|
34354
|
+
content = match[2];
|
|
34355
|
+
nodeFormat = format | 16;
|
|
34356
|
+
} else if (match[3]) {
|
|
34357
|
+
content = match[4];
|
|
34358
|
+
nodeFormat = format | 16;
|
|
34359
|
+
} else if (match[5]) {
|
|
34360
|
+
content = match[6];
|
|
34361
|
+
nodeFormat = format | 1;
|
|
34362
|
+
} else if (match[7]) {
|
|
34363
|
+
content = match[8];
|
|
34364
|
+
nodeFormat = format | 2;
|
|
34365
|
+
} else if (match[9]) {
|
|
34366
|
+
content = match[10];
|
|
34367
|
+
nodeFormat = format | 4;
|
|
34368
|
+
}
|
|
34369
|
+
if (content) {
|
|
34370
|
+
const formattedNode = $createTextNode(content);
|
|
34371
|
+
if (style)
|
|
34372
|
+
formattedNode.setStyle(style);
|
|
34373
|
+
formattedNode.setFormat(nodeFormat);
|
|
34374
|
+
resultNodes.push(formattedNode);
|
|
34375
|
+
}
|
|
34376
|
+
lastIndex = match.index + match[0].length;
|
|
34377
|
+
}
|
|
34378
|
+
if (lastIndex < text.length) {
|
|
34379
|
+
const afterText = text.slice(lastIndex);
|
|
34380
|
+
const afterNode = $createTextNode(afterText);
|
|
34381
|
+
if (style)
|
|
34382
|
+
afterNode.setStyle(style);
|
|
34383
|
+
if (format)
|
|
34384
|
+
afterNode.setFormat(format);
|
|
34385
|
+
resultNodes.push(afterNode);
|
|
34386
|
+
}
|
|
34387
|
+
return resultNodes.length > 0 ? resultNodes : [node];
|
|
34388
|
+
};
|
|
34389
|
+
const processNode2 = (node) => {
|
|
34390
|
+
if ($isElementNode(node)) {
|
|
34391
|
+
const children = node.getChildren();
|
|
34392
|
+
for (let i2 = children.length - 1; i2 >= 0; i2--) {
|
|
34393
|
+
const child = children[i2];
|
|
34394
|
+
if ($isTextNode(child)) {
|
|
34395
|
+
const replacementNodes = processTextNode(child);
|
|
34396
|
+
if (replacementNodes.length > 1 || replacementNodes[0] !== child) {
|
|
34397
|
+
for (const newNode of replacementNodes) {
|
|
34398
|
+
child.insertBefore(newNode);
|
|
34399
|
+
}
|
|
34400
|
+
child.remove();
|
|
34401
|
+
}
|
|
34402
|
+
} else if ($isElementNode(child)) {
|
|
34403
|
+
processNode2(child);
|
|
34404
|
+
}
|
|
34405
|
+
}
|
|
34406
|
+
}
|
|
34407
|
+
};
|
|
34408
|
+
nodes.forEach((node) => processNode2(node));
|
|
34409
|
+
return nodes;
|
|
34410
|
+
}
|
|
34411
|
+
function getNodeDOMPosition(editor) {
|
|
34412
|
+
const domSelection = window.getSelection();
|
|
34413
|
+
if (!domSelection || domSelection.rangeCount === 0) {
|
|
34414
|
+
return null;
|
|
34415
|
+
}
|
|
34416
|
+
const range = domSelection.getRangeAt(0);
|
|
34417
|
+
let rect = range.getBoundingClientRect();
|
|
34418
|
+
if (rect.width === 0 && rect.height === 0) {
|
|
34419
|
+
const anchorNode = domSelection.anchorNode;
|
|
34420
|
+
if (anchorNode) {
|
|
34421
|
+
const element = anchorNode.nodeType === Node.TEXT_NODE ? anchorNode.parentElement : anchorNode;
|
|
34422
|
+
if (element) {
|
|
34423
|
+
rect = element.getBoundingClientRect();
|
|
34424
|
+
}
|
|
34425
|
+
}
|
|
34426
|
+
}
|
|
34427
|
+
if (rect.right === 0 && rect.bottom === 0) {
|
|
34428
|
+
const rootElement = editor.getRootElement();
|
|
34429
|
+
if (rootElement) {
|
|
34430
|
+
const rootRect = rootElement.getBoundingClientRect();
|
|
34431
|
+
return {
|
|
34432
|
+
x: rootRect.left + 20,
|
|
34433
|
+
y: Math.min(rootRect.top + 100, window.innerHeight - 150)
|
|
34434
|
+
};
|
|
34435
|
+
}
|
|
34436
|
+
return null;
|
|
34437
|
+
}
|
|
34438
|
+
return {
|
|
34439
|
+
x: rect.right,
|
|
34440
|
+
y: rect.bottom
|
|
34441
|
+
};
|
|
34442
|
+
}
|
|
34443
|
+
function handleHorizontalRulePlaceholders(editor) {
|
|
34444
|
+
editor.update(
|
|
34445
|
+
() => {
|
|
34446
|
+
const root2 = $getRoot();
|
|
34447
|
+
const children = root2.getChildren();
|
|
34448
|
+
for (const child of children) {
|
|
34449
|
+
if ($isParagraphNode(child)) {
|
|
34450
|
+
const textContent = child.getTextContent();
|
|
34451
|
+
if (textContent === "___MARKDOWN_HR___") {
|
|
34452
|
+
editor.dispatchCommand(INSERT_HORIZONTAL_RULE_COMMAND, void 0);
|
|
34453
|
+
child.remove();
|
|
34454
|
+
}
|
|
34455
|
+
}
|
|
34456
|
+
}
|
|
34457
|
+
},
|
|
34458
|
+
{ tag: "paste-options" }
|
|
34459
|
+
);
|
|
34460
|
+
}
|
|
34461
|
+
function PasteOptionsPlugin() {
|
|
34462
|
+
const [editor] = useLexicalComposerContext();
|
|
34463
|
+
const [pasteData, setPasteData] = useState$1(null);
|
|
34464
|
+
const [currentMode, setCurrentMode] = useState$1("rich");
|
|
34465
|
+
const [showMenu, setShowMenu] = useState$1(false);
|
|
34466
|
+
const [menuPosition, setMenuPosition] = useState$1({ x: 0, y: 0 });
|
|
34467
|
+
useEffect$1(() => {
|
|
34468
|
+
if (!showMenu)
|
|
34469
|
+
return;
|
|
34470
|
+
const handleScroll2 = () => {
|
|
34471
|
+
const newPosition = getNodeDOMPosition(editor);
|
|
34472
|
+
if (newPosition) {
|
|
34473
|
+
setMenuPosition(newPosition);
|
|
34474
|
+
setPasteData(
|
|
34475
|
+
(prev) => prev ? { ...prev, position: newPosition } : null
|
|
34476
|
+
);
|
|
34477
|
+
}
|
|
34478
|
+
};
|
|
34479
|
+
window.addEventListener("scroll", handleScroll2, true);
|
|
34480
|
+
return () => window.removeEventListener("scroll", handleScroll2, true);
|
|
34481
|
+
}, [editor, showMenu]);
|
|
34482
|
+
useEffect$1(() => {
|
|
34483
|
+
return editor.registerCommand(
|
|
34484
|
+
KEY_ESCAPE_COMMAND,
|
|
34485
|
+
() => {
|
|
34486
|
+
if (showMenu) {
|
|
34487
|
+
setShowMenu(false);
|
|
34488
|
+
setPasteData(null);
|
|
34489
|
+
return true;
|
|
34490
|
+
}
|
|
34491
|
+
return false;
|
|
34492
|
+
},
|
|
34493
|
+
COMMAND_PRIORITY_CRITICAL
|
|
34494
|
+
);
|
|
34495
|
+
}, [editor, showMenu]);
|
|
34496
|
+
useEffect$1(() => {
|
|
34497
|
+
if (!showMenu)
|
|
34498
|
+
return;
|
|
34499
|
+
const removeListener = editor.registerUpdateListener(
|
|
34500
|
+
({ tags, dirtyElements, dirtyLeaves }) => {
|
|
34501
|
+
if (!tags.has("paste") && !tags.has("history-merge") && !tags.has("paste-options")) {
|
|
34502
|
+
if (dirtyElements.size > 0 || dirtyLeaves.size > 0) {
|
|
34503
|
+
setShowMenu(false);
|
|
34504
|
+
setPasteData(null);
|
|
34505
|
+
}
|
|
34506
|
+
}
|
|
34507
|
+
}
|
|
34508
|
+
);
|
|
34509
|
+
return removeListener;
|
|
34510
|
+
}, [editor, showMenu]);
|
|
34511
|
+
useEffect$1(() => {
|
|
34512
|
+
const handlePaste = (event) => {
|
|
34513
|
+
const clipboardData = event.clipboardData;
|
|
34514
|
+
if (!clipboardData)
|
|
34515
|
+
return;
|
|
34516
|
+
const html = clipboardData.getData("text/html");
|
|
34517
|
+
const plain = clipboardData.getData("text/plain");
|
|
34518
|
+
if (!html && !plain)
|
|
34519
|
+
return;
|
|
34520
|
+
if (htmlContainsImages(html)) {
|
|
34521
|
+
return;
|
|
34522
|
+
}
|
|
34523
|
+
const isPlainTextPaste = !html && plain;
|
|
34524
|
+
const initialMode = isPlainTextPaste ? "plain" : "rich";
|
|
34525
|
+
setTimeout(() => {
|
|
34526
|
+
editor.getEditorState().read(() => {
|
|
34527
|
+
const selection = $getSelection();
|
|
34528
|
+
if (!$isRangeSelection(selection))
|
|
34529
|
+
return;
|
|
34530
|
+
const position = getNodeDOMPosition(editor);
|
|
34531
|
+
if (!position)
|
|
34532
|
+
return;
|
|
34533
|
+
setPasteData({
|
|
34534
|
+
html,
|
|
34535
|
+
plain,
|
|
34536
|
+
position,
|
|
34537
|
+
initialMode
|
|
34538
|
+
});
|
|
34539
|
+
setCurrentMode(initialMode);
|
|
34540
|
+
setMenuPosition(position);
|
|
34541
|
+
setShowMenu(true);
|
|
34542
|
+
});
|
|
34543
|
+
}, 150);
|
|
34544
|
+
};
|
|
34545
|
+
const rootElement = editor.getRootElement();
|
|
34546
|
+
if (rootElement) {
|
|
34547
|
+
rootElement.addEventListener("paste", handlePaste);
|
|
34548
|
+
return () => rootElement.removeEventListener("paste", handlePaste);
|
|
34549
|
+
}
|
|
34550
|
+
}, [editor]);
|
|
34551
|
+
const handleSelectMode = useCallback(
|
|
34552
|
+
(mode) => {
|
|
34553
|
+
if (!pasteData) {
|
|
34554
|
+
return;
|
|
34555
|
+
}
|
|
34556
|
+
if (mode === currentMode) {
|
|
34557
|
+
setShowMenu(false);
|
|
34558
|
+
setPasteData(null);
|
|
34559
|
+
return;
|
|
34560
|
+
}
|
|
34561
|
+
editor.dispatchCommand(UNDO_COMMAND, void 0);
|
|
34562
|
+
setTimeout(() => {
|
|
34563
|
+
editor.update(
|
|
34564
|
+
() => {
|
|
34565
|
+
const selection = $getSelection();
|
|
34566
|
+
if (!$isRangeSelection(selection))
|
|
34567
|
+
return;
|
|
34568
|
+
let nodes = [];
|
|
34569
|
+
if (mode === "plain") {
|
|
34570
|
+
nodes = convertPlainTextToNodes(pasteData.plain);
|
|
34571
|
+
} else if (mode === "markdown") {
|
|
34572
|
+
if (pasteData.html) {
|
|
34573
|
+
nodes = convertHTMLToNodesWithStyles(pasteData.html, editor);
|
|
34574
|
+
nodes = applyMarkdownToNodes(nodes);
|
|
34575
|
+
} else {
|
|
34576
|
+
nodes = convertMarkdownToNodes(pasteData.plain);
|
|
34577
|
+
}
|
|
34578
|
+
} else if (mode === "rich") {
|
|
34579
|
+
if (pasteData.html) {
|
|
34580
|
+
const parser = new DOMParser();
|
|
34581
|
+
const doc = parser.parseFromString(pasteData.html, "text/html");
|
|
34582
|
+
nodes = $generateNodesFromDOM(editor, doc);
|
|
34583
|
+
} else {
|
|
34584
|
+
nodes = convertPlainTextToNodes(pasteData.plain);
|
|
34585
|
+
}
|
|
34586
|
+
}
|
|
34587
|
+
if (nodes.length > 0) {
|
|
34588
|
+
const filteredNodes = nodes.filter((node) => {
|
|
34589
|
+
const textContent = node.getTextContent();
|
|
34590
|
+
return textContent.trim().length > 0 || node.getType() !== "paragraph";
|
|
34591
|
+
});
|
|
34592
|
+
if (filteredNodes.length > 0) {
|
|
34593
|
+
selection.insertNodes(filteredNodes);
|
|
34594
|
+
} else if (nodes.length > 0) {
|
|
34595
|
+
selection.insertNodes(nodes);
|
|
34596
|
+
}
|
|
34597
|
+
}
|
|
34598
|
+
},
|
|
34599
|
+
{ tag: "paste-options" }
|
|
34600
|
+
);
|
|
34601
|
+
if (mode === "markdown") {
|
|
34602
|
+
setTimeout(() => {
|
|
34603
|
+
handleHorizontalRulePlaceholders(editor);
|
|
34604
|
+
}, 50);
|
|
34605
|
+
}
|
|
34606
|
+
}, 50);
|
|
34607
|
+
setCurrentMode(mode);
|
|
34608
|
+
setShowMenu(false);
|
|
34609
|
+
setPasteData(null);
|
|
34610
|
+
},
|
|
34611
|
+
[editor, pasteData, currentMode]
|
|
34612
|
+
);
|
|
34613
|
+
const handleClose = useCallback(() => {
|
|
34614
|
+
setShowMenu(false);
|
|
34615
|
+
setPasteData(null);
|
|
34616
|
+
}, []);
|
|
34617
|
+
if (!showMenu || !pasteData) {
|
|
34618
|
+
return null;
|
|
34619
|
+
}
|
|
34620
|
+
return createPortal(
|
|
34621
|
+
/* @__PURE__ */ jsx(
|
|
34622
|
+
PasteOptionsMenu,
|
|
34623
|
+
{
|
|
34624
|
+
position: menuPosition,
|
|
34625
|
+
currentMode,
|
|
34626
|
+
onSelectMode: handleSelectMode,
|
|
34627
|
+
onClose: handleClose,
|
|
34628
|
+
hasHtml: Boolean(pasteData.html)
|
|
34629
|
+
}
|
|
34630
|
+
),
|
|
34631
|
+
document.body
|
|
34632
|
+
);
|
|
34633
|
+
}
|
|
32911
34634
|
function getOptionMeta(label) {
|
|
32912
34635
|
const lower = label.toLowerCase();
|
|
32913
34636
|
if (lower.startsWith("paragraph"))
|
|
@@ -34542,6 +36265,7 @@ function TableActionMenu({
|
|
|
34542
36265
|
},
|
|
34543
36266
|
[editor, tableCellNode]
|
|
34544
36267
|
);
|
|
36268
|
+
const menuItemClass = " cteditor-group cteditor-flex cteditor-items-center cteditor-gap-1.5 cteditor-px-2 cteditor-py-1 cteditor-rounded-sm cteditor-transition-all cteditor-duration-200 cteditor-cursor-pointer cteditor-text-xs hover:cteditor-bg-foreground/10";
|
|
34545
36269
|
let mergeCellButton = null;
|
|
34546
36270
|
if (cellMerge) {
|
|
34547
36271
|
if (canMergeCells) {
|
|
@@ -34549,10 +36273,10 @@ function TableActionMenu({
|
|
|
34549
36273
|
"button",
|
|
34550
36274
|
{
|
|
34551
36275
|
type: "button",
|
|
34552
|
-
className:
|
|
36276
|
+
className: menuItemClass,
|
|
34553
36277
|
onClick: () => mergeTableCellsAtSelection(),
|
|
34554
36278
|
"data-test-id": "table-merge-cells",
|
|
34555
|
-
children: /* @__PURE__ */ jsx("span", { className: "
|
|
36279
|
+
children: /* @__PURE__ */ jsx("span", { className: "text", children: "Merge cells" })
|
|
34556
36280
|
}
|
|
34557
36281
|
);
|
|
34558
36282
|
} else if (canUnmergeCell) {
|
|
@@ -34560,15 +36284,14 @@ function TableActionMenu({
|
|
|
34560
36284
|
"button",
|
|
34561
36285
|
{
|
|
34562
36286
|
type: "button",
|
|
34563
|
-
className:
|
|
36287
|
+
className: menuItemClass,
|
|
34564
36288
|
onClick: () => unmergeTableCellsAtSelection(),
|
|
34565
36289
|
"data-test-id": "table-unmerge-cells",
|
|
34566
|
-
children: /* @__PURE__ */ jsx("span", { className: "
|
|
36290
|
+
children: /* @__PURE__ */ jsx("span", { className: "text", children: "Unmerge cells" })
|
|
34567
36291
|
}
|
|
34568
36292
|
);
|
|
34569
36293
|
}
|
|
34570
36294
|
}
|
|
34571
|
-
const menuItemClass = " cteditor-group cteditor-flex cteditor-items-center cteditor-gap-1.5 cteditor-px-2 cteditor-py-1 cteditor-rounded-sm cteditor-transition-all cteditor-duration-200 cteditor-cursor-pointer cteditor-text-xs hover:cteditor-bg-foreground/10";
|
|
34572
36295
|
return createPortal(
|
|
34573
36296
|
/* @__PURE__ */ jsxs(
|
|
34574
36297
|
"div",
|
|
@@ -37240,9 +38963,57 @@ function processHtmlForExport(html, tableStyleMap, codeBlockStyles) {
|
|
|
37240
38963
|
const wrapper = doc.createElement("div");
|
|
37241
38964
|
wrapper.style.padding = "1em";
|
|
37242
38965
|
wrapper.style.minHeight = "100%";
|
|
38966
|
+
wrapper.className = "editor-content-wrapper";
|
|
38967
|
+
const styleTag = doc.createElement("style");
|
|
38968
|
+
styleTag.textContent = `
|
|
38969
|
+
/* Responsive image styles - WYSIWYG for mobile */
|
|
38970
|
+
@media screen and (max-width: 768px) {
|
|
38971
|
+
/* Floated images stack on mobile - no text wrap */
|
|
38972
|
+
.image-float-left,
|
|
38973
|
+
.image-float-right,
|
|
38974
|
+
img[style*="float: left"],
|
|
38975
|
+
img[style*="float: right"] {
|
|
38976
|
+
float: none !important;
|
|
38977
|
+
clear: both !important;
|
|
38978
|
+
display: block !important;
|
|
38979
|
+
margin: 1em auto !important;
|
|
38980
|
+
max-width: 100% !important;
|
|
38981
|
+
/* On mobile, allow width to shrink but keep height proportional to width */
|
|
38982
|
+
width: auto !important;
|
|
38983
|
+
height: auto !important;
|
|
38984
|
+
}
|
|
38985
|
+
|
|
38986
|
+
/* Floated image containers (with captions) also stack */
|
|
38987
|
+
.image-float-container,
|
|
38988
|
+
.image-float-container-left,
|
|
38989
|
+
.image-float-container-right,
|
|
38990
|
+
p[style*="float: left"],
|
|
38991
|
+
p[style*="float: right"] {
|
|
38992
|
+
float: none !important;
|
|
38993
|
+
clear: both !important;
|
|
38994
|
+
max-width: 100% !important;
|
|
38995
|
+
margin: 1em 0 !important;
|
|
38996
|
+
}
|
|
38997
|
+
|
|
38998
|
+
/* Clear floats properly */
|
|
38999
|
+
.editor-content-wrapper::after {
|
|
39000
|
+
content: "";
|
|
39001
|
+
display: table;
|
|
39002
|
+
clear: both;
|
|
39003
|
+
}
|
|
39004
|
+
}
|
|
39005
|
+
|
|
39006
|
+
/* Clearfix for floated content */
|
|
39007
|
+
.editor-content-wrapper::after {
|
|
39008
|
+
content: "";
|
|
39009
|
+
display: table;
|
|
39010
|
+
clear: both;
|
|
39011
|
+
}
|
|
39012
|
+
`;
|
|
37243
39013
|
while (doc.body.firstChild) {
|
|
37244
39014
|
wrapper.appendChild(doc.body.firstChild);
|
|
37245
39015
|
}
|
|
39016
|
+
wrapper.insertBefore(styleTag, wrapper.firstChild);
|
|
37246
39017
|
return wrapper.outerHTML;
|
|
37247
39018
|
}
|
|
37248
39019
|
function cleanupHeaderCellStructure(container) {
|
|
@@ -37313,12 +39084,21 @@ function applyGenericSafeStyles(container, codeBlockStyles) {
|
|
|
37313
39084
|
container.querySelectorAll("img").forEach((img) => {
|
|
37314
39085
|
const position = img.getAttribute("data-position");
|
|
37315
39086
|
const parent = img.parentElement;
|
|
37316
|
-
img.
|
|
39087
|
+
const explicitWidth = img.getAttribute("width");
|
|
39088
|
+
const explicitHeight = img.getAttribute("height");
|
|
39089
|
+
const hasExplicitDimensions = explicitWidth && explicitHeight && explicitWidth !== "inherit" && explicitHeight !== "inherit";
|
|
39090
|
+
if (hasExplicitDimensions) {
|
|
39091
|
+
img.style.cssText += `; max-width: 100%; width: ${explicitWidth}px; height: ${explicitHeight}px;`;
|
|
39092
|
+
} else {
|
|
39093
|
+
img.style.cssText += "; max-width: 100%; height: auto;";
|
|
39094
|
+
}
|
|
37317
39095
|
const hasCaption = parent && parent.tagName.toLowerCase() === "p" && parent.querySelector("em, i");
|
|
37318
39096
|
if (position === "left" || position === "right") {
|
|
37319
39097
|
const floatDir = position === "left" ? "left" : "right";
|
|
37320
39098
|
const marginDir = position === "left" ? "right" : "left";
|
|
39099
|
+
img.classList.add("image-float-" + floatDir);
|
|
37321
39100
|
if (hasCaption && parent) {
|
|
39101
|
+
parent.classList.add("image-float-container", "image-float-container-" + floatDir);
|
|
37322
39102
|
parent.style.cssText += `; float: ${floatDir}; clear: ${floatDir}; max-width: 50%; margin-${marginDir}: 1em; margin-bottom: 0.5em; text-align: center; background-color: #f5f5f5; padding: 0.5em; border-radius: 4px;`;
|
|
37323
39103
|
img.style.cssText += "; display: block; margin: 0 auto;";
|
|
37324
39104
|
const caption = parent.querySelector("em, i");
|
|
@@ -37330,10 +39110,20 @@ function applyGenericSafeStyles(container, codeBlockStyles) {
|
|
|
37330
39110
|
}
|
|
37331
39111
|
} else if (position === "full") {
|
|
37332
39112
|
img.style.cssText += "; display: block; width: 100%; margin: 1em 0;";
|
|
39113
|
+
} else if (position === "inline-left") {
|
|
39114
|
+
img.classList.add("image-inline-left");
|
|
39115
|
+
img.style.cssText += "; display: block; margin: 1em 0; text-align: left;";
|
|
39116
|
+
} else if (position === "inline-center") {
|
|
39117
|
+
img.classList.add("image-inline-center");
|
|
39118
|
+
img.style.cssText += "; display: block; margin: 1em auto;";
|
|
39119
|
+
} else if (position === "inline-right") {
|
|
39120
|
+
img.classList.add("image-inline-right");
|
|
39121
|
+
img.style.cssText += "; display: block; margin: 1em 0 1em auto;";
|
|
37333
39122
|
} else {
|
|
37334
|
-
img.style.cssText += "; display: block;";
|
|
39123
|
+
img.style.cssText += "; display: inline-block; vertical-align: middle;";
|
|
37335
39124
|
if (parent && parent.style.textAlign === "center") {
|
|
37336
39125
|
img.style.margin = "0 auto";
|
|
39126
|
+
img.style.display = "block";
|
|
37337
39127
|
}
|
|
37338
39128
|
}
|
|
37339
39129
|
img.removeAttribute("data-position");
|
|
@@ -37685,24 +39475,52 @@ function preprocessInitialContent(html) {
|
|
|
37685
39475
|
});
|
|
37686
39476
|
const images = doc.querySelectorAll("img");
|
|
37687
39477
|
images.forEach((img) => {
|
|
39478
|
+
const htmlImg = img;
|
|
37688
39479
|
const parent = img.parentElement;
|
|
37689
39480
|
if (!parent)
|
|
37690
39481
|
return;
|
|
37691
|
-
|
|
37692
|
-
|
|
37693
|
-
|
|
37694
|
-
if (
|
|
37695
|
-
img.setAttribute("data-position",
|
|
37696
|
-
|
|
37697
|
-
|
|
37698
|
-
|
|
37699
|
-
|
|
37700
|
-
|
|
37701
|
-
|
|
37702
|
-
|
|
37703
|
-
|
|
39482
|
+
if (htmlImg.classList.contains("image-inline-left")) {
|
|
39483
|
+
img.setAttribute("data-position", "inline-left");
|
|
39484
|
+
htmlImg.classList.remove("image-inline-left");
|
|
39485
|
+
} else if (htmlImg.classList.contains("image-inline-center")) {
|
|
39486
|
+
img.setAttribute("data-position", "inline-center");
|
|
39487
|
+
htmlImg.classList.remove("image-inline-center");
|
|
39488
|
+
} else if (htmlImg.classList.contains("image-inline-right")) {
|
|
39489
|
+
img.setAttribute("data-position", "inline-right");
|
|
39490
|
+
htmlImg.classList.remove("image-inline-right");
|
|
39491
|
+
} else if (htmlImg.classList.contains("image-float-left")) {
|
|
39492
|
+
img.setAttribute("data-position", "left");
|
|
39493
|
+
htmlImg.classList.remove("image-float-left");
|
|
39494
|
+
} else if (htmlImg.classList.contains("image-float-right")) {
|
|
39495
|
+
img.setAttribute("data-position", "right");
|
|
39496
|
+
htmlImg.classList.remove("image-float-right");
|
|
39497
|
+
} else {
|
|
39498
|
+
const imgFloat = htmlImg.style.float;
|
|
39499
|
+
const parentFloat = parent.style.float;
|
|
39500
|
+
const floatDir = imgFloat || parentFloat;
|
|
39501
|
+
if (floatDir === "left" || floatDir === "right") {
|
|
39502
|
+
img.setAttribute("data-position", floatDir);
|
|
39503
|
+
if (parentFloat && parent.tagName.toLowerCase() === "p") {
|
|
39504
|
+
parent.style.textAlign = floatDir;
|
|
39505
|
+
parent.style.removeProperty("float");
|
|
39506
|
+
parent.style.removeProperty("clear");
|
|
39507
|
+
parent.style.removeProperty("max-width");
|
|
39508
|
+
parent.style.removeProperty("background-color");
|
|
39509
|
+
parent.style.removeProperty("padding");
|
|
39510
|
+
parent.style.removeProperty("border-radius");
|
|
39511
|
+
}
|
|
39512
|
+
} else {
|
|
39513
|
+
const margin = htmlImg.style.margin;
|
|
39514
|
+
if (margin === "1em auto" || htmlImg.style.marginLeft === "auto" && htmlImg.style.marginRight === "auto") {
|
|
39515
|
+
img.setAttribute("data-position", "inline-center");
|
|
39516
|
+
} else if (htmlImg.style.marginLeft === "auto" && htmlImg.style.marginRight !== "auto") {
|
|
39517
|
+
img.setAttribute("data-position", "inline-right");
|
|
39518
|
+
}
|
|
37704
39519
|
}
|
|
37705
39520
|
}
|
|
39521
|
+
if (parent.classList.contains("image-float-container")) {
|
|
39522
|
+
parent.classList.remove("image-float-container", "image-float-container-left", "image-float-container-right");
|
|
39523
|
+
}
|
|
37706
39524
|
});
|
|
37707
39525
|
const styledElements = doc.querySelectorAll("span[style], b[style], strong[style], i[style], em[style]");
|
|
37708
39526
|
styledElements.forEach((el) => {
|
|
@@ -38382,6 +40200,7 @@ const ConfigurableEditor = ({
|
|
|
38382
40200
|
/* @__PURE__ */ jsx(CodeBlockNormalizerPlugin, {}),
|
|
38383
40201
|
/* @__PURE__ */ jsx(CodeBlockSelectAllPlugin, {}),
|
|
38384
40202
|
/* @__PURE__ */ jsx(SlashCommandPlugin, {}),
|
|
40203
|
+
/* @__PURE__ */ jsx(MarkdownShortcutsPlugin, {}),
|
|
38385
40204
|
/* @__PURE__ */ jsx(CombinedPluginWrapper, {}),
|
|
38386
40205
|
/* @__PURE__ */ jsx(OnChangeWrapper, { onChange }),
|
|
38387
40206
|
/* @__PURE__ */ jsx(InitialContentPlugin, { initialContent }),
|
|
@@ -38392,6 +40211,7 @@ const ConfigurableEditor = ({
|
|
|
38392
40211
|
/* @__PURE__ */ jsx(LinkPreviewPlugin, {}),
|
|
38393
40212
|
/* @__PURE__ */ jsx(DragDropPaste, {}),
|
|
38394
40213
|
/* @__PURE__ */ jsx(RichTextPastePlugin, {}),
|
|
40214
|
+
/* @__PURE__ */ jsx(PasteOptionsPlugin, {}),
|
|
38395
40215
|
/* @__PURE__ */ jsx(FilePlugin, {}),
|
|
38396
40216
|
/* @__PURE__ */ jsx(HorizontalRulePlugin, {}),
|
|
38397
40217
|
/* @__PURE__ */ jsx(CustomHorizontalRulePlugin, {}),
|
|
@@ -38580,11 +40400,12 @@ const ConfigurableEditorWithAuth = ({
|
|
|
38580
40400
|
};
|
|
38581
40401
|
export {
|
|
38582
40402
|
$isFileNode as $,
|
|
38583
|
-
|
|
40403
|
+
AlignLeft as A,
|
|
38584
40404
|
Button as B,
|
|
38585
40405
|
ConfigurableEditorWithAuth as C,
|
|
38586
40406
|
Download as D,
|
|
38587
40407
|
ExternalLink as E,
|
|
40408
|
+
FileText as F,
|
|
38588
40409
|
HtmlViewProvider as H,
|
|
38589
40410
|
LocalStoragePlugin$1 as L,
|
|
38590
40411
|
Sparkles as S,
|
|
@@ -38600,12 +40421,16 @@ export {
|
|
|
38600
40421
|
DialogFooter as i,
|
|
38601
40422
|
initialConfig as j,
|
|
38602
40423
|
$isImageNode as k,
|
|
38603
|
-
|
|
38604
|
-
|
|
38605
|
-
|
|
38606
|
-
|
|
40424
|
+
AlignCenter as l,
|
|
40425
|
+
AlignRight as m,
|
|
40426
|
+
Type as n,
|
|
40427
|
+
AiJsonResponse as o,
|
|
40428
|
+
EditorProvider as p,
|
|
40429
|
+
useEditor as q,
|
|
40430
|
+
ConfigurableEditor as r,
|
|
40431
|
+
editorConfig as s,
|
|
38607
40432
|
toast as t,
|
|
38608
40433
|
useHtmlView as u,
|
|
38609
40434
|
verifyApiKey as v
|
|
38610
40435
|
};
|
|
38611
|
-
//# sourceMappingURL=index-
|
|
40436
|
+
//# sourceMappingURL=index-0533674e.js.map
|