ct-rich-text-editor 1.3.18 → 1.3.19
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/assets/style.css +144 -3
- package/dist/components/ImageView/index.d.ts +3 -1
- package/dist/{html2pdf.bundle-0a42a49f.js → html2pdf.bundle-a30dde70.js} +2 -2
- package/dist/{html2pdf.bundle-0a42a49f.js.map → html2pdf.bundle-a30dde70.js.map} +1 -1
- package/dist/{html2pdf.bundle.min-db02af80.js → html2pdf.bundle.min-f1b4a78e.js} +2 -2
- package/dist/{html2pdf.bundle.min-db02af80.js.map → html2pdf.bundle.min-f1b4a78e.js.map} +1 -1
- package/dist/{index-dbb526cd.js → index-23abcbd9.js} +1569 -289
- package/dist/index-23abcbd9.js.map +1 -0
- package/dist/{index-2bc5ccbc.js → index-913b3634.js} +26 -4
- package/dist/index-913b3634.js.map +1 -0
- package/dist/{index-7ddd4fcc.js → index-afa4eda8.js} +2 -2
- package/dist/{index-7ddd4fcc.js.map → index-afa4eda8.js.map} +1 -1
- package/dist/index.js +1 -1
- package/dist/nodes/ImageNode.d.ts +9 -3
- package/dist/plugins/AIChatPlugin.d.ts +6 -0
- package/dist/plugins/RichTextPastePlugin/index.d.ts +14 -0
- package/dist/plugins/UsageTrackingPlugin.d.ts +15 -0
- package/dist/utils/editorStyleConverter.d.ts +4 -2
- package/package.json +1 -1
- package/dist/index-2bc5ccbc.js.map +0 -1
- package/dist/index-dbb526cd.js.map +0 -1
|
@@ -24,14 +24,14 @@ 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, $setSelection, isHTMLElement as isHTMLElement$1, TextNode, $getRoot, $createTextNode, $getNodeByKey, $isParagraphNode, $isTextNode, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, $isElementNode, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_CRITICAL, UNDO_COMMAND, REDO_COMMAND, $createRangeSelection, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, $createNodeSelection, $isNodeSelection, getDOMSelection, CLICK_COMMAND, COMMAND_PRIORITY_HIGH, $isLineBreakNode, PASTE_COMMAND, isDOMNode } from "lexical";
|
|
27
|
+
import { createCommand, DecoratorNode, createEditor, $applyNodeReplacement, $insertNodes, $isRootOrShadowRoot, $createParagraphNode, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_LOW, $getSelection, $isRangeSelection, $getNearestNodeFromDOMNode, $setSelection, isHTMLElement as isHTMLElement$1, TextNode, $getRoot, $createTextNode, $getNodeByKey, $isParagraphNode, $isTextNode, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, $isElementNode, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_CRITICAL, UNDO_COMMAND, REDO_COMMAND, $createRangeSelection, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, $createNodeSelection, $isNodeSelection, getDOMSelection, CLICK_COMMAND, COMMAND_PRIORITY_HIGH, $isLineBreakNode, 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
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";
|
|
33
33
|
import { HeadingNode, QuoteNode, $isHeadingNode, $createHeadingNode, $createQuoteNode, DRAG_DROP_PASTE } from "@lexical/rich-text";
|
|
34
|
-
import { $isAtNodeEnd, $selectAll, $patchStyleText, $setBlocksType, $
|
|
34
|
+
import { $isAtNodeEnd, $selectAll, $patchStyleText, $setBlocksType, $getSelectionStyleValueForProperty, $isParentElementRTL } from "@lexical/selection";
|
|
35
35
|
import { HorizontalRuleNode } from "@lexical/react/LexicalHorizontalRuleNode";
|
|
36
36
|
import DescriptionIcon from "@mui/icons-material/Description";
|
|
37
37
|
import FolderZipIcon from "@mui/icons-material/FolderZip";
|
|
@@ -1479,7 +1479,7 @@ const AiTextTransform = async ({ content, apiKey }) => {
|
|
|
1479
1479
|
const AI_ACTION_COMMAND = createCommand(
|
|
1480
1480
|
"AI_ACTION_COMMAND"
|
|
1481
1481
|
);
|
|
1482
|
-
const ImageView = React__default.lazy(() => import("./index-
|
|
1482
|
+
const ImageView = React__default.lazy(() => import("./index-913b3634.js"));
|
|
1483
1483
|
function isGoogleDocCheckboxImg(img) {
|
|
1484
1484
|
return img.parentElement != null && img.parentElement.tagName === "LI" && img.previousSibling === null && img.getAttribute("aria-roledescription") === "checkbox";
|
|
1485
1485
|
}
|
|
@@ -1489,11 +1489,16 @@ function $convertImageElement(domNode) {
|
|
|
1489
1489
|
return null;
|
|
1490
1490
|
}
|
|
1491
1491
|
const { alt: altText, src, width, height } = img;
|
|
1492
|
-
const
|
|
1492
|
+
const positionAttr = img.getAttribute("data-position");
|
|
1493
|
+
let position = "none";
|
|
1494
|
+
if (positionAttr === "left" || positionAttr === "right" || positionAttr === "full") {
|
|
1495
|
+
position = positionAttr;
|
|
1496
|
+
}
|
|
1497
|
+
const node = $createImageNode({ altText, height, src, width, position });
|
|
1493
1498
|
return { node };
|
|
1494
1499
|
}
|
|
1495
1500
|
class ImageNode extends DecoratorNode {
|
|
1496
|
-
constructor(src, altText, maxWidth, width, height, showCaption, caption, captionsEnabled, originalPrompt, key) {
|
|
1501
|
+
constructor(src, altText, maxWidth, width, height, showCaption, caption, captionsEnabled, originalPrompt, position, key) {
|
|
1497
1502
|
super(key);
|
|
1498
1503
|
__publicField(this, "__src");
|
|
1499
1504
|
__publicField(this, "__altText");
|
|
@@ -1505,6 +1510,7 @@ class ImageNode extends DecoratorNode {
|
|
|
1505
1510
|
// Captions cannot yet be used within editor cells
|
|
1506
1511
|
__publicField(this, "__captionsEnabled");
|
|
1507
1512
|
__publicField(this, "__originalPrompt");
|
|
1513
|
+
__publicField(this, "__position");
|
|
1508
1514
|
this.__src = src;
|
|
1509
1515
|
this.__altText = altText;
|
|
1510
1516
|
this.__maxWidth = maxWidth;
|
|
@@ -1516,6 +1522,7 @@ class ImageNode extends DecoratorNode {
|
|
|
1516
1522
|
});
|
|
1517
1523
|
this.__captionsEnabled = captionsEnabled || captionsEnabled === void 0;
|
|
1518
1524
|
this.__originalPrompt = originalPrompt || "";
|
|
1525
|
+
this.__position = position || "none";
|
|
1519
1526
|
}
|
|
1520
1527
|
// to identify the image node and must unique too
|
|
1521
1528
|
static getType() {
|
|
@@ -1533,12 +1540,13 @@ class ImageNode extends DecoratorNode {
|
|
|
1533
1540
|
node.__caption,
|
|
1534
1541
|
node.__captionsEnabled,
|
|
1535
1542
|
node.__originalPrompt,
|
|
1543
|
+
node.__position,
|
|
1536
1544
|
node.__key
|
|
1537
1545
|
);
|
|
1538
1546
|
}
|
|
1539
1547
|
// importing to json format
|
|
1540
1548
|
static importJSON(serializedNode) {
|
|
1541
|
-
const { altText, height, width, maxWidth, caption, src, showCaption, originalPrompt } = serializedNode;
|
|
1549
|
+
const { altText, height, width, maxWidth, caption, src, showCaption, originalPrompt, position } = serializedNode;
|
|
1542
1550
|
const node = $createImageNode({
|
|
1543
1551
|
altText,
|
|
1544
1552
|
height,
|
|
@@ -1546,8 +1554,9 @@ class ImageNode extends DecoratorNode {
|
|
|
1546
1554
|
showCaption,
|
|
1547
1555
|
src,
|
|
1548
1556
|
width,
|
|
1549
|
-
originalPrompt: originalPrompt || ""
|
|
1557
|
+
originalPrompt: originalPrompt || "",
|
|
1550
1558
|
// Default to empty string if undefined
|
|
1559
|
+
position: position || "none"
|
|
1551
1560
|
});
|
|
1552
1561
|
const nestedEditor = node.__caption;
|
|
1553
1562
|
const editorState = nestedEditor.parseEditorState(caption.editorState);
|
|
@@ -1558,12 +1567,15 @@ class ImageNode extends DecoratorNode {
|
|
|
1558
1567
|
}
|
|
1559
1568
|
// Exports this node as an actual <img> tag in the DOM when needed
|
|
1560
1569
|
exportDOM() {
|
|
1561
|
-
const
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1570
|
+
const img = document.createElement("img");
|
|
1571
|
+
img.setAttribute("src", this.__src);
|
|
1572
|
+
img.setAttribute("alt", this.__altText);
|
|
1573
|
+
img.setAttribute("width", this.__width.toString());
|
|
1574
|
+
img.setAttribute("height", this.__height.toString());
|
|
1575
|
+
if (this.__position && this.__position !== "none") {
|
|
1576
|
+
img.setAttribute("data-position", this.__position);
|
|
1577
|
+
}
|
|
1578
|
+
return { element: img };
|
|
1567
1579
|
}
|
|
1568
1580
|
// convert img tag into image node in the editor using convertImageElement func
|
|
1569
1581
|
static importDOM() {
|
|
@@ -1585,7 +1597,8 @@ class ImageNode extends DecoratorNode {
|
|
|
1585
1597
|
type: "image",
|
|
1586
1598
|
version: 1,
|
|
1587
1599
|
width: this.__width === "inherit" ? 0 : this.__width,
|
|
1588
|
-
originalPrompt: this.__originalPrompt
|
|
1600
|
+
originalPrompt: this.__originalPrompt,
|
|
1601
|
+
position: this.__position
|
|
1589
1602
|
};
|
|
1590
1603
|
}
|
|
1591
1604
|
// setting width and height when resizing
|
|
@@ -1607,9 +1620,26 @@ class ImageNode extends DecoratorNode {
|
|
|
1607
1620
|
if (className !== void 0) {
|
|
1608
1621
|
span.className = className;
|
|
1609
1622
|
}
|
|
1623
|
+
if (this.__position === "left") {
|
|
1624
|
+
span.style.cssText = "float: left; margin-right: 1em; margin-bottom: 0.5em; max-width: 50%; display: block;";
|
|
1625
|
+
} else if (this.__position === "right") {
|
|
1626
|
+
span.style.cssText = "float: right; margin-left: 1em; margin-bottom: 0.5em; max-width: 50%; display: block;";
|
|
1627
|
+
} else if (this.__position === "full") {
|
|
1628
|
+
span.style.cssText = "display: block; width: 100%; margin: 1em 0;";
|
|
1629
|
+
}
|
|
1610
1630
|
return span;
|
|
1611
1631
|
}
|
|
1612
|
-
updateDOM() {
|
|
1632
|
+
updateDOM(prevNode, dom) {
|
|
1633
|
+
if (prevNode.__position !== this.__position) {
|
|
1634
|
+
dom.style.cssText = "";
|
|
1635
|
+
if (this.__position === "left") {
|
|
1636
|
+
dom.style.cssText = "float: left; margin-right: 1em; margin-bottom: 0.5em; max-width: 50%; display: block;";
|
|
1637
|
+
} else if (this.__position === "right") {
|
|
1638
|
+
dom.style.cssText = "float: right; margin-left: 1em; margin-bottom: 0.5em; max-width: 50%; display: block;";
|
|
1639
|
+
} else if (this.__position === "full") {
|
|
1640
|
+
dom.style.cssText = "display: block; width: 100%; margin: 1em 0;";
|
|
1641
|
+
}
|
|
1642
|
+
}
|
|
1613
1643
|
return false;
|
|
1614
1644
|
}
|
|
1615
1645
|
// to get the image src
|
|
@@ -1633,6 +1663,15 @@ class ImageNode extends DecoratorNode {
|
|
|
1633
1663
|
const writable = this.getWritable();
|
|
1634
1664
|
writable.__originalPrompt = prompt;
|
|
1635
1665
|
}
|
|
1666
|
+
// to get the image position (float)
|
|
1667
|
+
getPosition() {
|
|
1668
|
+
return this.__position;
|
|
1669
|
+
}
|
|
1670
|
+
// to set the image position (float)
|
|
1671
|
+
setPosition(position) {
|
|
1672
|
+
const writable = this.getWritable();
|
|
1673
|
+
writable.__position = position;
|
|
1674
|
+
}
|
|
1636
1675
|
// to render the image tag
|
|
1637
1676
|
decorate() {
|
|
1638
1677
|
return /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(
|
|
@@ -1648,7 +1687,8 @@ class ImageNode extends DecoratorNode {
|
|
|
1648
1687
|
caption: this.__caption,
|
|
1649
1688
|
captionsEnabled: this.__captionsEnabled,
|
|
1650
1689
|
resizable: true,
|
|
1651
|
-
originalPrompt: this.__originalPrompt
|
|
1690
|
+
originalPrompt: this.__originalPrompt,
|
|
1691
|
+
position: this.__position
|
|
1652
1692
|
}
|
|
1653
1693
|
) });
|
|
1654
1694
|
}
|
|
@@ -1663,7 +1703,8 @@ function $createImageNode({
|
|
|
1663
1703
|
showCaption,
|
|
1664
1704
|
caption,
|
|
1665
1705
|
key,
|
|
1666
|
-
originalPrompt
|
|
1706
|
+
originalPrompt,
|
|
1707
|
+
position
|
|
1667
1708
|
}) {
|
|
1668
1709
|
return $applyNodeReplacement(
|
|
1669
1710
|
new ImageNode(
|
|
@@ -1676,6 +1717,7 @@ function $createImageNode({
|
|
|
1676
1717
|
caption,
|
|
1677
1718
|
captionsEnabled,
|
|
1678
1719
|
originalPrompt,
|
|
1720
|
+
position,
|
|
1679
1721
|
key
|
|
1680
1722
|
)
|
|
1681
1723
|
);
|
|
@@ -7551,6 +7593,17 @@ const Minimize2 = createLucideIcon("Minimize2", [
|
|
|
7551
7593
|
* See the LICENSE file in the root directory of this source tree.
|
|
7552
7594
|
*/
|
|
7553
7595
|
const Minus = createLucideIcon("Minus", [["path", { d: "M5 12h14", key: "1ays0h" }]]);
|
|
7596
|
+
/**
|
|
7597
|
+
* @license lucide-react v0.344.0 - ISC
|
|
7598
|
+
*
|
|
7599
|
+
* This source code is licensed under the ISC license.
|
|
7600
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
7601
|
+
*/
|
|
7602
|
+
const PanelBottomOpen = createLucideIcon("PanelBottomOpen", [
|
|
7603
|
+
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }],
|
|
7604
|
+
["path", { d: "M3 15h18", key: "5xshup" }],
|
|
7605
|
+
["path", { d: "m9 10 3-3 3 3", key: "11gsxs" }]
|
|
7606
|
+
]);
|
|
7554
7607
|
/**
|
|
7555
7608
|
* @license lucide-react v0.344.0 - ISC
|
|
7556
7609
|
*
|
|
@@ -7660,6 +7713,16 @@ const Search = createLucideIcon("Search", [
|
|
|
7660
7713
|
["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }],
|
|
7661
7714
|
["path", { d: "m21 21-4.3-4.3", key: "1qie3q" }]
|
|
7662
7715
|
]);
|
|
7716
|
+
/**
|
|
7717
|
+
* @license lucide-react v0.344.0 - ISC
|
|
7718
|
+
*
|
|
7719
|
+
* This source code is licensed under the ISC license.
|
|
7720
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
7721
|
+
*/
|
|
7722
|
+
const Send = createLucideIcon("Send", [
|
|
7723
|
+
["path", { d: "m22 2-7 20-4-9-9-4Z", key: "1q3vgg" }],
|
|
7724
|
+
["path", { d: "M22 2 11 13", key: "nzbqef" }]
|
|
7725
|
+
]);
|
|
7663
7726
|
/**
|
|
7664
7727
|
* @license lucide-react v0.344.0 - ISC
|
|
7665
7728
|
*
|
|
@@ -15282,7 +15345,7 @@ const EmbedComponent = ({ url, displayType, alignment, nodeKey }) => {
|
|
|
15282
15345
|
}
|
|
15283
15346
|
);
|
|
15284
15347
|
};
|
|
15285
|
-
const FileComponent = React$1.lazy(() => import("./index-
|
|
15348
|
+
const FileComponent = React$1.lazy(() => import("./index-afa4eda8.js"));
|
|
15286
15349
|
function convertFileElement(domNode) {
|
|
15287
15350
|
if (domNode instanceof HTMLDivElement) {
|
|
15288
15351
|
const dataUrl = domNode.getAttribute("data-lexical-file-src");
|
|
@@ -18577,7 +18640,7 @@ const formatMenuItems = [
|
|
|
18577
18640
|
}
|
|
18578
18641
|
];
|
|
18579
18642
|
const LOWEST_PRIORITY = 1;
|
|
18580
|
-
const DEFAULT_FONT_SIZE = 15;
|
|
18643
|
+
const DEFAULT_FONT_SIZE$1 = 15;
|
|
18581
18644
|
const INITIAL_TOOLBAR_STATE = {
|
|
18582
18645
|
bgColor: "#fff",
|
|
18583
18646
|
blockType: "paragraph",
|
|
@@ -18588,9 +18651,9 @@ const INITIAL_TOOLBAR_STATE = {
|
|
|
18588
18651
|
fontColor: "#000",
|
|
18589
18652
|
fontFamily: "Arial",
|
|
18590
18653
|
// Current font size in px
|
|
18591
|
-
fontSize: `${DEFAULT_FONT_SIZE}px`,
|
|
18654
|
+
fontSize: `${DEFAULT_FONT_SIZE$1}px`,
|
|
18592
18655
|
// Font size input value - for controlled input
|
|
18593
|
-
fontSizeInputValue: `${DEFAULT_FONT_SIZE}`,
|
|
18656
|
+
fontSizeInputValue: `${DEFAULT_FONT_SIZE$1}`,
|
|
18594
18657
|
isBold: false,
|
|
18595
18658
|
isCode: false,
|
|
18596
18659
|
isHighlight: false,
|
|
@@ -19061,12 +19124,15 @@ const useVoiceToText = ({ onTranscriptUpdate }) => {
|
|
|
19061
19124
|
};
|
|
19062
19125
|
};
|
|
19063
19126
|
const TOGGLE_AI_CHAT_COMMAND = createCommand();
|
|
19127
|
+
const SHOW_INLINE_AI_PROMPT_COMMAND = createCommand();
|
|
19064
19128
|
function AIChatDialog({
|
|
19065
19129
|
open,
|
|
19066
19130
|
onOpenChange,
|
|
19067
19131
|
editor,
|
|
19068
19132
|
apiKey,
|
|
19069
|
-
initialText
|
|
19133
|
+
initialText,
|
|
19134
|
+
onShowInEditor,
|
|
19135
|
+
selectedTextForInline
|
|
19070
19136
|
}) {
|
|
19071
19137
|
const [inputValue, setInputValue] = useState$1("");
|
|
19072
19138
|
const [isLoading, setIsLoading] = useState$1(false);
|
|
@@ -19330,6 +19396,24 @@ function AIChatDialog({
|
|
|
19330
19396
|
children: "Cancel"
|
|
19331
19397
|
}
|
|
19332
19398
|
),
|
|
19399
|
+
/* @__PURE__ */ jsxs(
|
|
19400
|
+
Button,
|
|
19401
|
+
{
|
|
19402
|
+
variant: "outline",
|
|
19403
|
+
onClick: () => {
|
|
19404
|
+
if (onShowInEditor) {
|
|
19405
|
+
onShowInEditor(provider, selectedTextForInline);
|
|
19406
|
+
handleClose();
|
|
19407
|
+
}
|
|
19408
|
+
},
|
|
19409
|
+
disabled: isLoading,
|
|
19410
|
+
title: "Show AI prompt in the editor text area",
|
|
19411
|
+
children: [
|
|
19412
|
+
/* @__PURE__ */ jsx(PanelBottomOpen, { size: 16 }),
|
|
19413
|
+
"Show in Editor"
|
|
19414
|
+
]
|
|
19415
|
+
}
|
|
19416
|
+
),
|
|
19333
19417
|
/* @__PURE__ */ jsx(
|
|
19334
19418
|
Button,
|
|
19335
19419
|
{
|
|
@@ -19347,10 +19431,257 @@ function AIChatDialog({
|
|
|
19347
19431
|
] })
|
|
19348
19432
|
] }) }) });
|
|
19349
19433
|
}
|
|
19350
|
-
function
|
|
19434
|
+
function InlineAIPrompt({
|
|
19435
|
+
editor,
|
|
19436
|
+
apiKey,
|
|
19437
|
+
initialProvider,
|
|
19438
|
+
selectedText: initialSelectedText,
|
|
19439
|
+
onClose,
|
|
19440
|
+
anchorElem
|
|
19441
|
+
}) {
|
|
19442
|
+
const [provider, setProvider] = useState$1(initialProvider);
|
|
19443
|
+
const [inputValue, setInputValue] = useState$1("");
|
|
19444
|
+
const [isLoading, setIsLoading] = useState$1(false);
|
|
19445
|
+
const inputRef = useRef(null);
|
|
19446
|
+
const [selectedText, setSelectedText] = useState$1(initialSelectedText);
|
|
19447
|
+
useEffect$1(() => {
|
|
19448
|
+
const unregister = editor.registerUpdateListener(({ editorState }) => {
|
|
19449
|
+
editorState.read(() => {
|
|
19450
|
+
const selection = $getSelection();
|
|
19451
|
+
if (selection && selection.getTextContent().trim()) {
|
|
19452
|
+
const newSelectedText = selection.getTextContent();
|
|
19453
|
+
if (newSelectedText.trim() !== "") {
|
|
19454
|
+
setSelectedText(newSelectedText);
|
|
19455
|
+
}
|
|
19456
|
+
}
|
|
19457
|
+
});
|
|
19458
|
+
});
|
|
19459
|
+
return () => {
|
|
19460
|
+
unregister();
|
|
19461
|
+
};
|
|
19462
|
+
}, [editor]);
|
|
19463
|
+
useEffect$1(() => {
|
|
19464
|
+
if (inputRef.current) {
|
|
19465
|
+
inputRef.current.focus();
|
|
19466
|
+
}
|
|
19467
|
+
}, []);
|
|
19468
|
+
const handleSubmit = async () => {
|
|
19469
|
+
var _a, _b;
|
|
19470
|
+
if (!inputValue.trim() || isLoading)
|
|
19471
|
+
return;
|
|
19472
|
+
if (!selectedText || selectedText.trim() === "") {
|
|
19473
|
+
toast.error("Please select some text first");
|
|
19474
|
+
return;
|
|
19475
|
+
}
|
|
19476
|
+
setIsLoading(true);
|
|
19477
|
+
const fullPrompt = `${inputValue}
|
|
19478
|
+
|
|
19479
|
+
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.
|
|
19480
|
+
|
|
19481
|
+
Text to transform:
|
|
19482
|
+
"${selectedText}"`;
|
|
19483
|
+
try {
|
|
19484
|
+
const response = await AiEditorAction({ content: fullPrompt, provider, apiKey });
|
|
19485
|
+
let htmlString = response.data;
|
|
19486
|
+
if (typeof htmlString === "string") {
|
|
19487
|
+
htmlString = htmlString.trim();
|
|
19488
|
+
if (htmlString.startsWith('"') && htmlString.endsWith('"') || htmlString.startsWith("'") && htmlString.endsWith("'")) {
|
|
19489
|
+
htmlString = htmlString.slice(1, -1);
|
|
19490
|
+
}
|
|
19491
|
+
}
|
|
19492
|
+
editor.update(() => {
|
|
19493
|
+
const parser = new DOMParser();
|
|
19494
|
+
const dom = parser.parseFromString(htmlString.trim(), "text/html");
|
|
19495
|
+
const nodes = $generateNodesFromDOM(editor, dom);
|
|
19496
|
+
const currentSelection = $getSelection();
|
|
19497
|
+
if (currentSelection) {
|
|
19498
|
+
$insertNodes(nodes);
|
|
19499
|
+
}
|
|
19500
|
+
});
|
|
19501
|
+
setInputValue("");
|
|
19502
|
+
setSelectedText("");
|
|
19503
|
+
} catch (error) {
|
|
19504
|
+
console.error("Error processing AI action:", error);
|
|
19505
|
+
const apiMessage = ((_b = (_a = error == null ? void 0 : error.response) == null ? void 0 : _a.data) == null ? void 0 : _b.message) ?? (error instanceof Error ? error.message : null);
|
|
19506
|
+
const safeMessage = apiMessage && !/^Request failed with status code \d+/.test(apiMessage) ? apiMessage : "Error processing your request. Please try again.";
|
|
19507
|
+
toast.error(safeMessage);
|
|
19508
|
+
} finally {
|
|
19509
|
+
setIsLoading(false);
|
|
19510
|
+
}
|
|
19511
|
+
};
|
|
19512
|
+
const handleKeyDown = (e) => {
|
|
19513
|
+
if (e.key === "Enter" && !e.shiftKey && !isLoading && inputValue.trim()) {
|
|
19514
|
+
e.preventDefault();
|
|
19515
|
+
handleSubmit();
|
|
19516
|
+
}
|
|
19517
|
+
if (e.key === "Escape") {
|
|
19518
|
+
onClose();
|
|
19519
|
+
}
|
|
19520
|
+
};
|
|
19521
|
+
const hasSelectedText = selectedText && selectedText.trim() !== "";
|
|
19522
|
+
const displayText = hasSelectedText ? selectedText.length > 50 ? selectedText.substring(0, 50) + "..." : selectedText : "";
|
|
19523
|
+
return /* @__PURE__ */ jsxs(
|
|
19524
|
+
"div",
|
|
19525
|
+
{
|
|
19526
|
+
style: {
|
|
19527
|
+
position: "absolute",
|
|
19528
|
+
bottom: "12px",
|
|
19529
|
+
left: "50%",
|
|
19530
|
+
transform: "translateX(-50%)",
|
|
19531
|
+
display: "flex",
|
|
19532
|
+
flexDirection: "column",
|
|
19533
|
+
gap: "8px",
|
|
19534
|
+
backgroundColor: "#1a1a1a",
|
|
19535
|
+
padding: "12px 16px",
|
|
19536
|
+
borderRadius: "12px",
|
|
19537
|
+
border: "1px solid #333",
|
|
19538
|
+
boxShadow: "0 8px 24px rgba(0,0,0,0.4)",
|
|
19539
|
+
zIndex: 10,
|
|
19540
|
+
maxWidth: "500px"
|
|
19541
|
+
},
|
|
19542
|
+
children: [
|
|
19543
|
+
/* @__PURE__ */ jsx(
|
|
19544
|
+
"div",
|
|
19545
|
+
{
|
|
19546
|
+
style: {
|
|
19547
|
+
display: "flex",
|
|
19548
|
+
alignItems: "center",
|
|
19549
|
+
gap: "8px",
|
|
19550
|
+
padding: "6px 10px",
|
|
19551
|
+
backgroundColor: hasSelectedText ? "#2a2a2a" : "#3a2a2a",
|
|
19552
|
+
borderRadius: "6px",
|
|
19553
|
+
fontSize: "12px",
|
|
19554
|
+
color: "#999",
|
|
19555
|
+
border: hasSelectedText ? "none" : "1px solid #5a3a3a"
|
|
19556
|
+
},
|
|
19557
|
+
children: hasSelectedText ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
19558
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#666" }, children: "Selected:" }),
|
|
19559
|
+
/* @__PURE__ */ jsxs("span", { style: { color: "#ccc", fontStyle: "italic" }, children: [
|
|
19560
|
+
'"',
|
|
19561
|
+
displayText,
|
|
19562
|
+
'"'
|
|
19563
|
+
] })
|
|
19564
|
+
] }) : /* @__PURE__ */ jsx("span", { style: { color: "#f87171" }, children: "⚠ Please select some text in the editor first" })
|
|
19565
|
+
}
|
|
19566
|
+
),
|
|
19567
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: "10px" }, children: [
|
|
19568
|
+
/* @__PURE__ */ jsx(Sparkles, { size: 16, style: { color: "#fff", flexShrink: 0 } }),
|
|
19569
|
+
/* @__PURE__ */ jsxs(
|
|
19570
|
+
"select",
|
|
19571
|
+
{
|
|
19572
|
+
value: provider,
|
|
19573
|
+
onChange: (e) => setProvider(e.target.value),
|
|
19574
|
+
style: {
|
|
19575
|
+
width: "100px",
|
|
19576
|
+
height: "32px",
|
|
19577
|
+
padding: "0 8px",
|
|
19578
|
+
fontSize: "13px",
|
|
19579
|
+
fontWeight: 500,
|
|
19580
|
+
border: "1px solid #444",
|
|
19581
|
+
borderRadius: "6px",
|
|
19582
|
+
outline: "none",
|
|
19583
|
+
backgroundColor: "#2a2a2a",
|
|
19584
|
+
color: "#fff",
|
|
19585
|
+
cursor: "pointer"
|
|
19586
|
+
},
|
|
19587
|
+
children: [
|
|
19588
|
+
/* @__PURE__ */ jsx("option", { value: "chatgpt", children: "ChatGPT" }),
|
|
19589
|
+
/* @__PURE__ */ jsx("option", { value: "claude", children: "Claude" }),
|
|
19590
|
+
/* @__PURE__ */ jsx("option", { value: "grok", children: "Grok" })
|
|
19591
|
+
]
|
|
19592
|
+
}
|
|
19593
|
+
),
|
|
19594
|
+
/* @__PURE__ */ jsx(
|
|
19595
|
+
"input",
|
|
19596
|
+
{
|
|
19597
|
+
ref: inputRef,
|
|
19598
|
+
type: "text",
|
|
19599
|
+
value: inputValue,
|
|
19600
|
+
onChange: (e) => setInputValue(e.target.value),
|
|
19601
|
+
onKeyDown: handleKeyDown,
|
|
19602
|
+
placeholder: hasSelectedText ? "What do you want to do with this text?" : "Select text first...",
|
|
19603
|
+
disabled: isLoading,
|
|
19604
|
+
style: {
|
|
19605
|
+
width: "280px",
|
|
19606
|
+
height: "32px",
|
|
19607
|
+
padding: "0 12px",
|
|
19608
|
+
fontSize: "13px",
|
|
19609
|
+
border: "1px solid #444",
|
|
19610
|
+
borderRadius: "6px",
|
|
19611
|
+
outline: "none",
|
|
19612
|
+
backgroundColor: "#2a2a2a",
|
|
19613
|
+
color: "#fff"
|
|
19614
|
+
}
|
|
19615
|
+
}
|
|
19616
|
+
),
|
|
19617
|
+
/* @__PURE__ */ jsx(
|
|
19618
|
+
"button",
|
|
19619
|
+
{
|
|
19620
|
+
type: "button",
|
|
19621
|
+
onClick: handleSubmit,
|
|
19622
|
+
disabled: isLoading || !inputValue.trim(),
|
|
19623
|
+
style: {
|
|
19624
|
+
height: "32px",
|
|
19625
|
+
width: "32px",
|
|
19626
|
+
backgroundColor: "#fff",
|
|
19627
|
+
color: "#1a1a1a",
|
|
19628
|
+
borderRadius: "6px",
|
|
19629
|
+
border: "none",
|
|
19630
|
+
display: "flex",
|
|
19631
|
+
alignItems: "center",
|
|
19632
|
+
justifyContent: "center",
|
|
19633
|
+
cursor: isLoading || !inputValue.trim() ? "not-allowed" : "pointer",
|
|
19634
|
+
opacity: isLoading || !inputValue.trim() ? 0.5 : 1,
|
|
19635
|
+
flexShrink: 0,
|
|
19636
|
+
transition: "background-color 0.2s"
|
|
19637
|
+
},
|
|
19638
|
+
children: isLoading ? /* @__PURE__ */ jsx("div", { style: {
|
|
19639
|
+
height: "14px",
|
|
19640
|
+
width: "14px",
|
|
19641
|
+
border: "2px solid #1a1a1a",
|
|
19642
|
+
borderTopColor: "transparent",
|
|
19643
|
+
borderRadius: "50%",
|
|
19644
|
+
animation: "spin 1s linear infinite"
|
|
19645
|
+
} }) : /* @__PURE__ */ jsx(Send, { size: 14 })
|
|
19646
|
+
}
|
|
19647
|
+
),
|
|
19648
|
+
/* @__PURE__ */ jsx(
|
|
19649
|
+
"button",
|
|
19650
|
+
{
|
|
19651
|
+
type: "button",
|
|
19652
|
+
onClick: onClose,
|
|
19653
|
+
style: {
|
|
19654
|
+
height: "32px",
|
|
19655
|
+
width: "32px",
|
|
19656
|
+
backgroundColor: "transparent",
|
|
19657
|
+
color: "#888",
|
|
19658
|
+
borderRadius: "6px",
|
|
19659
|
+
border: "none",
|
|
19660
|
+
display: "flex",
|
|
19661
|
+
alignItems: "center",
|
|
19662
|
+
justifyContent: "center",
|
|
19663
|
+
cursor: "pointer",
|
|
19664
|
+
flexShrink: 0,
|
|
19665
|
+
transition: "color 0.2s"
|
|
19666
|
+
},
|
|
19667
|
+
title: "Close (Esc)",
|
|
19668
|
+
onMouseEnter: (e) => e.currentTarget.style.color = "#fff",
|
|
19669
|
+
onMouseLeave: (e) => e.currentTarget.style.color = "#888",
|
|
19670
|
+
children: /* @__PURE__ */ jsx(X$1, { size: 16 })
|
|
19671
|
+
}
|
|
19672
|
+
)
|
|
19673
|
+
] })
|
|
19674
|
+
]
|
|
19675
|
+
}
|
|
19676
|
+
);
|
|
19677
|
+
}
|
|
19678
|
+
function useAIChatToolbar(editor, apiKey, anchorElem) {
|
|
19351
19679
|
const [isVisible, setIsVisible] = useState$1(false);
|
|
19352
19680
|
const [selectedText, setSelectedText] = useState$1(void 0);
|
|
19353
19681
|
const savedSelectionRef = useRef(null);
|
|
19682
|
+
const [showInlinePrompt, setShowInlinePrompt] = useState$1(false);
|
|
19683
|
+
const [inlineProvider, setInlineProvider] = useState$1("chatgpt");
|
|
19684
|
+
const [inlineSelectedText, setInlineSelectedText] = useState$1("");
|
|
19354
19685
|
const toggleAIChat = useCallback((text) => {
|
|
19355
19686
|
editor.getEditorState().read(() => {
|
|
19356
19687
|
const selection = $getSelection();
|
|
@@ -19361,8 +19692,17 @@ function useAIChatToolbar(editor, apiKey) {
|
|
|
19361
19692
|
setSelectedText(text);
|
|
19362
19693
|
setIsVisible((prevState) => !prevState);
|
|
19363
19694
|
}, [editor]);
|
|
19695
|
+
const handleShowInEditor = useCallback((provider, textFromDialog) => {
|
|
19696
|
+
setInlineProvider(provider);
|
|
19697
|
+
setInlineSelectedText(textFromDialog || selectedText || "");
|
|
19698
|
+
setShowInlinePrompt(true);
|
|
19699
|
+
}, [selectedText]);
|
|
19700
|
+
const handleCloseInlinePrompt = useCallback(() => {
|
|
19701
|
+
setShowInlinePrompt(false);
|
|
19702
|
+
setInlineSelectedText("");
|
|
19703
|
+
}, []);
|
|
19364
19704
|
useEffect$1(() => {
|
|
19365
|
-
|
|
19705
|
+
const unregisterToggle = editor.registerCommand(
|
|
19366
19706
|
TOGGLE_AI_CHAT_COMMAND,
|
|
19367
19707
|
(text) => {
|
|
19368
19708
|
toggleAIChat(text);
|
|
@@ -19370,18 +19710,55 @@ function useAIChatToolbar(editor, apiKey) {
|
|
|
19370
19710
|
},
|
|
19371
19711
|
COMMAND_PRIORITY_LOW
|
|
19372
19712
|
);
|
|
19713
|
+
const unregisterInline = editor.registerCommand(
|
|
19714
|
+
SHOW_INLINE_AI_PROMPT_COMMAND,
|
|
19715
|
+
(payload) => {
|
|
19716
|
+
let currentSelectedText = "";
|
|
19717
|
+
editor.getEditorState().read(() => {
|
|
19718
|
+
const selection = $getSelection();
|
|
19719
|
+
if (selection) {
|
|
19720
|
+
currentSelectedText = selection.getTextContent();
|
|
19721
|
+
}
|
|
19722
|
+
});
|
|
19723
|
+
setInlineProvider((payload == null ? void 0 : payload.provider) || "chatgpt");
|
|
19724
|
+
setInlineSelectedText((payload == null ? void 0 : payload.initialText) || currentSelectedText);
|
|
19725
|
+
setShowInlinePrompt(true);
|
|
19726
|
+
return true;
|
|
19727
|
+
},
|
|
19728
|
+
COMMAND_PRIORITY_LOW
|
|
19729
|
+
);
|
|
19730
|
+
return () => {
|
|
19731
|
+
unregisterToggle();
|
|
19732
|
+
unregisterInline();
|
|
19733
|
+
};
|
|
19373
19734
|
}, [editor, toggleAIChat]);
|
|
19374
|
-
|
|
19375
|
-
|
|
19376
|
-
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
|
|
19381
|
-
|
|
19382
|
-
|
|
19383
|
-
|
|
19384
|
-
|
|
19735
|
+
const editorRootElement = editor.getRootElement();
|
|
19736
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
19737
|
+
isVisible && /* @__PURE__ */ jsx(
|
|
19738
|
+
AIChatDialog,
|
|
19739
|
+
{
|
|
19740
|
+
open: isVisible,
|
|
19741
|
+
onOpenChange: setIsVisible,
|
|
19742
|
+
editor,
|
|
19743
|
+
apiKey,
|
|
19744
|
+
initialText: selectedText,
|
|
19745
|
+
savedSelection: savedSelectionRef.current,
|
|
19746
|
+
onShowInEditor: handleShowInEditor,
|
|
19747
|
+
selectedTextForInline: selectedText
|
|
19748
|
+
}
|
|
19749
|
+
),
|
|
19750
|
+
showInlinePrompt && /* @__PURE__ */ jsx(
|
|
19751
|
+
InlineAIPrompt,
|
|
19752
|
+
{
|
|
19753
|
+
editor,
|
|
19754
|
+
apiKey,
|
|
19755
|
+
initialProvider: inlineProvider,
|
|
19756
|
+
selectedText: inlineSelectedText,
|
|
19757
|
+
onClose: handleCloseInlinePrompt,
|
|
19758
|
+
anchorElem: editorRootElement
|
|
19759
|
+
}
|
|
19760
|
+
)
|
|
19761
|
+
] });
|
|
19385
19762
|
}
|
|
19386
19763
|
function AIChatPlugin({
|
|
19387
19764
|
apiKey
|
|
@@ -19991,10 +20368,10 @@ const PDF_CONFIG = {
|
|
|
19991
20368
|
};
|
|
19992
20369
|
const loadHtml2Pdf = async () => {
|
|
19993
20370
|
try {
|
|
19994
|
-
const mod = await import("./html2pdf.bundle.min-
|
|
20371
|
+
const mod = await import("./html2pdf.bundle.min-f1b4a78e.js").then((n) => n.h);
|
|
19995
20372
|
return (mod == null ? void 0 : mod.default) || mod;
|
|
19996
20373
|
} catch {
|
|
19997
|
-
const mod2 = await import("./html2pdf.bundle-
|
|
20374
|
+
const mod2 = await import("./html2pdf.bundle-a30dde70.js").then((n) => n.h);
|
|
19998
20375
|
return (mod2 == null ? void 0 : mod2.default) || mod2;
|
|
19999
20376
|
}
|
|
20000
20377
|
};
|
|
@@ -23236,92 +23613,123 @@ const FontFamilyMenu = ({
|
|
|
23236
23613
|
activeEditor
|
|
23237
23614
|
}) => {
|
|
23238
23615
|
const [selectedFont, setSelectedFont] = useState$1("Arial");
|
|
23616
|
+
const [detectedFonts, setDetectedFonts] = useState$1(/* @__PURE__ */ new Set());
|
|
23617
|
+
const allFonts = useMemo(() => {
|
|
23618
|
+
const fontSet = new Set(fonts);
|
|
23619
|
+
detectedFonts.forEach((font) => fontSet.add(font));
|
|
23620
|
+
return Array.from(fontSet);
|
|
23621
|
+
}, [fonts, detectedFonts]);
|
|
23239
23622
|
useEffect$1(() => {
|
|
23240
23623
|
return activeEditor.registerUpdateListener(({ editorState }) => {
|
|
23241
23624
|
editorState.read(() => {
|
|
23242
|
-
var _a;
|
|
23243
23625
|
const selection = $getSelection();
|
|
23244
23626
|
if ($isRangeSelection(selection)) {
|
|
23245
|
-
const
|
|
23246
|
-
|
|
23247
|
-
|
|
23248
|
-
|
|
23249
|
-
|
|
23250
|
-
|
|
23627
|
+
const fontFamily = $getSelectionStyleValueForProperty(
|
|
23628
|
+
selection,
|
|
23629
|
+
"font-family",
|
|
23630
|
+
"Arial"
|
|
23631
|
+
);
|
|
23632
|
+
const cleanedFont = fontFamily.replace(/^["']|["']$/g, "").trim();
|
|
23633
|
+
setSelectedFont(cleanedFont);
|
|
23634
|
+
if (cleanedFont && cleanedFont !== "Arial" && !fonts.includes(cleanedFont)) {
|
|
23635
|
+
setDetectedFonts((prev) => {
|
|
23636
|
+
if (prev.has(cleanedFont))
|
|
23637
|
+
return prev;
|
|
23638
|
+
const newSet = new Set(prev);
|
|
23639
|
+
newSet.add(cleanedFont);
|
|
23640
|
+
return newSet;
|
|
23641
|
+
});
|
|
23251
23642
|
}
|
|
23252
23643
|
}
|
|
23253
23644
|
});
|
|
23254
23645
|
});
|
|
23255
|
-
}, [activeEditor]);
|
|
23256
|
-
const applyFontFamily = (
|
|
23257
|
-
|
|
23258
|
-
|
|
23259
|
-
|
|
23260
|
-
$
|
|
23261
|
-
|
|
23262
|
-
|
|
23263
|
-
|
|
23646
|
+
}, [activeEditor, fonts]);
|
|
23647
|
+
const applyFontFamily = useCallback(
|
|
23648
|
+
(fontFamily) => {
|
|
23649
|
+
activeEditor.update(() => {
|
|
23650
|
+
const selection = $getSelection();
|
|
23651
|
+
if ($isRangeSelection(selection)) {
|
|
23652
|
+
$patchStyleText(selection, { "font-family": fontFamily });
|
|
23653
|
+
}
|
|
23654
|
+
});
|
|
23655
|
+
},
|
|
23656
|
+
[activeEditor]
|
|
23657
|
+
);
|
|
23264
23658
|
const handleFontChange = (value) => {
|
|
23265
23659
|
setSelectedFont(value);
|
|
23266
23660
|
applyFontFamily(value);
|
|
23267
23661
|
};
|
|
23268
23662
|
return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Select, { value: selectedFont, onValueChange: handleFontChange, children: [
|
|
23269
23663
|
/* @__PURE__ */ jsx(SelectTrigger, { className: "!cteditor-h-7 md:!cteditor-bg-secondary !cteditor-bg-foreground/5 cteditor-text-foreground md:!cteditor-w-[120px] cteditor-text-xs max-md:cteditor-w-full", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select font" }) }),
|
|
23270
|
-
/* @__PURE__ */ jsx(SelectContent, { children:
|
|
23664
|
+
/* @__PURE__ */ jsx(SelectContent, { children: allFonts.map((font) => /* @__PURE__ */ jsx(SelectItem, { value: font, style: { fontFamily: font }, children: font }, font)) })
|
|
23271
23665
|
] }) });
|
|
23272
23666
|
};
|
|
23273
23667
|
const MIN_FONT_SIZE = 8;
|
|
23274
23668
|
const MAX_FONT_SIZE = 72;
|
|
23669
|
+
const DEFAULT_FONT_SIZE = 16;
|
|
23275
23670
|
const STEP_SIZE = 2;
|
|
23276
23671
|
const FontSizeControl = () => {
|
|
23277
23672
|
const [editor] = useLexicalComposerContext();
|
|
23278
|
-
const [fontSize, setFontSize] = useState$1(
|
|
23279
|
-
const [inputValue, setInputValue] = useState$1(
|
|
23673
|
+
const [fontSize, setFontSize] = useState$1(DEFAULT_FONT_SIZE);
|
|
23674
|
+
const [inputValue, setInputValue] = useState$1(DEFAULT_FONT_SIZE.toString());
|
|
23675
|
+
const pendingFontSizeRef = React__default.useRef(null);
|
|
23280
23676
|
useEffect$1(() => {
|
|
23281
23677
|
return editor.registerUpdateListener(({ editorState }) => {
|
|
23282
23678
|
editorState.read(() => {
|
|
23283
|
-
var _a;
|
|
23284
23679
|
const selection = $getSelection();
|
|
23285
|
-
if ($isRangeSelection(selection)
|
|
23286
|
-
const
|
|
23287
|
-
|
|
23288
|
-
|
|
23289
|
-
|
|
23290
|
-
|
|
23291
|
-
|
|
23292
|
-
|
|
23293
|
-
|
|
23680
|
+
if ($isRangeSelection(selection)) {
|
|
23681
|
+
const fontSizeStr = $getSelectionStyleValueForProperty(
|
|
23682
|
+
selection,
|
|
23683
|
+
"font-size",
|
|
23684
|
+
`${DEFAULT_FONT_SIZE}px`
|
|
23685
|
+
);
|
|
23686
|
+
const size2 = parseInt(fontSizeStr, 10) || DEFAULT_FONT_SIZE;
|
|
23687
|
+
if (pendingFontSizeRef.current !== null && size2 === pendingFontSizeRef.current) {
|
|
23688
|
+
pendingFontSizeRef.current = null;
|
|
23689
|
+
}
|
|
23690
|
+
if (pendingFontSizeRef.current === null) {
|
|
23691
|
+
setFontSize(size2);
|
|
23692
|
+
setInputValue(size2.toString());
|
|
23294
23693
|
}
|
|
23295
23694
|
}
|
|
23296
23695
|
});
|
|
23297
23696
|
});
|
|
23298
23697
|
}, [editor]);
|
|
23698
|
+
useEffect$1(() => {
|
|
23699
|
+
const rootElement = editor.getRootElement();
|
|
23700
|
+
if (!rootElement)
|
|
23701
|
+
return;
|
|
23702
|
+
const handleFocus = () => {
|
|
23703
|
+
if (pendingFontSizeRef.current !== null) {
|
|
23704
|
+
const pendingSize = pendingFontSizeRef.current;
|
|
23705
|
+
editor.update(() => {
|
|
23706
|
+
const selection = $getSelection();
|
|
23707
|
+
if ($isRangeSelection(selection)) {
|
|
23708
|
+
$patchStyleText(selection, { "font-size": `${pendingSize}px` });
|
|
23709
|
+
}
|
|
23710
|
+
});
|
|
23711
|
+
}
|
|
23712
|
+
};
|
|
23713
|
+
rootElement.addEventListener("focus", handleFocus);
|
|
23714
|
+
return () => {
|
|
23715
|
+
rootElement.removeEventListener("focus", handleFocus);
|
|
23716
|
+
};
|
|
23717
|
+
}, [editor]);
|
|
23299
23718
|
const applyFontSize = useCallback(
|
|
23300
23719
|
(size2) => {
|
|
23720
|
+
pendingFontSizeRef.current = size2;
|
|
23301
23721
|
editor.update(() => {
|
|
23302
23722
|
const selection = $getSelection();
|
|
23303
23723
|
if ($isRangeSelection(selection)) {
|
|
23304
23724
|
$patchStyleText(selection, { "font-size": `${size2}px` });
|
|
23305
23725
|
}
|
|
23306
23726
|
});
|
|
23307
|
-
setFontSize(size2);
|
|
23308
|
-
setInputValue(size2.toString());
|
|
23309
23727
|
},
|
|
23310
23728
|
[editor]
|
|
23311
23729
|
);
|
|
23312
|
-
useEffect$1(() => {
|
|
23313
|
-
applyFontSize(fontSize);
|
|
23314
|
-
}, [fontSize, applyFontSize]);
|
|
23315
23730
|
const handleFontSizeChange = (event) => {
|
|
23316
23731
|
const value = event.target.value.replace(/\D/g, "");
|
|
23317
23732
|
setInputValue(value);
|
|
23318
|
-
if (value !== "") {
|
|
23319
|
-
const newSize = Math.max(
|
|
23320
|
-
MIN_FONT_SIZE,
|
|
23321
|
-
Math.min(Number(value), MAX_FONT_SIZE)
|
|
23322
|
-
);
|
|
23323
|
-
setFontSize(newSize);
|
|
23324
|
-
}
|
|
23325
23733
|
};
|
|
23326
23734
|
const handleFontSizeBlur = () => {
|
|
23327
23735
|
if (inputValue === "" || isNaN(Number(inputValue))) {
|
|
@@ -23332,15 +23740,28 @@ const FontSizeControl = () => {
|
|
|
23332
23740
|
Math.min(Number(inputValue), MAX_FONT_SIZE)
|
|
23333
23741
|
);
|
|
23334
23742
|
setFontSize(newSize);
|
|
23743
|
+
setInputValue(newSize.toString());
|
|
23744
|
+
applyFontSize(newSize);
|
|
23745
|
+
}
|
|
23746
|
+
};
|
|
23747
|
+
const handleKeyDown = (event) => {
|
|
23748
|
+
if (event.key === "Enter") {
|
|
23749
|
+
event.preventDefault();
|
|
23750
|
+
handleFontSizeBlur();
|
|
23751
|
+
editor.focus();
|
|
23335
23752
|
}
|
|
23336
23753
|
};
|
|
23337
23754
|
const increaseFontSize = () => {
|
|
23338
23755
|
const newSize = Math.min(fontSize + STEP_SIZE, MAX_FONT_SIZE);
|
|
23339
23756
|
setFontSize(newSize);
|
|
23757
|
+
setInputValue(newSize.toString());
|
|
23758
|
+
applyFontSize(newSize);
|
|
23340
23759
|
};
|
|
23341
23760
|
const decreaseFontSize = () => {
|
|
23342
23761
|
const newSize = Math.max(fontSize - STEP_SIZE, MIN_FONT_SIZE);
|
|
23343
23762
|
setFontSize(newSize);
|
|
23763
|
+
setInputValue(newSize.toString());
|
|
23764
|
+
applyFontSize(newSize);
|
|
23344
23765
|
};
|
|
23345
23766
|
return /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-1", children: [
|
|
23346
23767
|
/* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
@@ -23362,7 +23783,8 @@ const FontSizeControl = () => {
|
|
|
23362
23783
|
className: "!cteditor-w-9 !cteditor-h-6 !cteditor-p-0 !cteditor-text-center !cteditor-bg-secondary",
|
|
23363
23784
|
value: inputValue,
|
|
23364
23785
|
onChange: handleFontSizeChange,
|
|
23365
|
-
onBlur: handleFontSizeBlur
|
|
23786
|
+
onBlur: handleFontSizeBlur,
|
|
23787
|
+
onKeyDown: handleKeyDown
|
|
23366
23788
|
}
|
|
23367
23789
|
),
|
|
23368
23790
|
/* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
@@ -25735,7 +26157,15 @@ const Toolbar = ({
|
|
|
25735
26157
|
});
|
|
25736
26158
|
}, [editor]);
|
|
25737
26159
|
const toggleAIChat = useCallback(() => {
|
|
25738
|
-
editor.
|
|
26160
|
+
editor.getEditorState().read(() => {
|
|
26161
|
+
const selection = $getSelection();
|
|
26162
|
+
if ($isRangeSelection(selection)) {
|
|
26163
|
+
const selectedText = selection.getTextContent();
|
|
26164
|
+
editor.dispatchCommand(TOGGLE_AI_CHAT_COMMAND, selectedText || void 0);
|
|
26165
|
+
} else {
|
|
26166
|
+
editor.dispatchCommand(TOGGLE_AI_CHAT_COMMAND, void 0);
|
|
26167
|
+
}
|
|
26168
|
+
});
|
|
25739
26169
|
}, [editor]);
|
|
25740
26170
|
const createTodo = useCallback(() => {
|
|
25741
26171
|
editor.dispatchCommand(INSERT_CHECK_LIST_COMMAND, void 0);
|
|
@@ -28381,26 +28811,6 @@ function DragDropPaste() {
|
|
|
28381
28811
|
return;
|
|
28382
28812
|
}
|
|
28383
28813
|
}
|
|
28384
|
-
const html = clipboardData.getData("text/html");
|
|
28385
|
-
if (html) {
|
|
28386
|
-
const tempDiv = document.createElement("div");
|
|
28387
|
-
tempDiv.innerHTML = html;
|
|
28388
|
-
const images = tempDiv.querySelectorAll("img");
|
|
28389
|
-
if (images.length > 0) {
|
|
28390
|
-
e.preventDefault();
|
|
28391
|
-
images.forEach((img) => {
|
|
28392
|
-
if (img.src) {
|
|
28393
|
-
editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
|
|
28394
|
-
altText: img.alt || "Pasted image",
|
|
28395
|
-
src: img.src,
|
|
28396
|
-
width: img.width || void 0,
|
|
28397
|
-
height: img.height || void 0
|
|
28398
|
-
});
|
|
28399
|
-
}
|
|
28400
|
-
});
|
|
28401
|
-
return;
|
|
28402
|
-
}
|
|
28403
|
-
}
|
|
28404
28814
|
};
|
|
28405
28815
|
const editorElement = editor.getRootElement();
|
|
28406
28816
|
if (editorElement) {
|
|
@@ -31074,6 +31484,827 @@ function NewMentionsPlugin({
|
|
|
31074
31484
|
}
|
|
31075
31485
|
);
|
|
31076
31486
|
}
|
|
31487
|
+
function detectCSSAlignment(element) {
|
|
31488
|
+
let current = element;
|
|
31489
|
+
while (current && current !== document.body) {
|
|
31490
|
+
const style = current.style;
|
|
31491
|
+
const computedStyle = window.getComputedStyle(current);
|
|
31492
|
+
const textAlign = style.textAlign || computedStyle.textAlign;
|
|
31493
|
+
if (textAlign === "center")
|
|
31494
|
+
return "center";
|
|
31495
|
+
if (textAlign === "right")
|
|
31496
|
+
return "right";
|
|
31497
|
+
if (textAlign === "justify")
|
|
31498
|
+
return "justify";
|
|
31499
|
+
const display = computedStyle.display;
|
|
31500
|
+
const justifyContent = computedStyle.justifyContent;
|
|
31501
|
+
if (display === "flex" && (justifyContent === "center" || justifyContent === "space-around")) {
|
|
31502
|
+
return "center";
|
|
31503
|
+
}
|
|
31504
|
+
const marginLeft = computedStyle.marginLeft;
|
|
31505
|
+
const marginRight = computedStyle.marginRight;
|
|
31506
|
+
if (marginLeft === "auto" && marginRight === "auto") {
|
|
31507
|
+
return "center";
|
|
31508
|
+
}
|
|
31509
|
+
current = current.parentElement;
|
|
31510
|
+
}
|
|
31511
|
+
return null;
|
|
31512
|
+
}
|
|
31513
|
+
function getImageDimensions(imgElement) {
|
|
31514
|
+
let width = parseInt(imgElement.getAttribute("width") || "0");
|
|
31515
|
+
let height = parseInt(imgElement.getAttribute("height") || "0");
|
|
31516
|
+
if (width === 0) {
|
|
31517
|
+
const styleWidth = imgElement.style.width;
|
|
31518
|
+
if (styleWidth && styleWidth.endsWith("px")) {
|
|
31519
|
+
width = parseInt(styleWidth);
|
|
31520
|
+
}
|
|
31521
|
+
}
|
|
31522
|
+
if (height === 0) {
|
|
31523
|
+
const styleHeight = imgElement.style.height;
|
|
31524
|
+
if (styleHeight && styleHeight.endsWith("px")) {
|
|
31525
|
+
height = parseInt(styleHeight);
|
|
31526
|
+
}
|
|
31527
|
+
}
|
|
31528
|
+
if (width === 0 || height === 0) {
|
|
31529
|
+
try {
|
|
31530
|
+
const computed = window.getComputedStyle(imgElement);
|
|
31531
|
+
if (width === 0 && computed.width && computed.width !== "auto") {
|
|
31532
|
+
width = parseInt(computed.width);
|
|
31533
|
+
}
|
|
31534
|
+
if (height === 0 && computed.height && computed.height !== "auto") {
|
|
31535
|
+
height = parseInt(computed.height);
|
|
31536
|
+
}
|
|
31537
|
+
} catch {
|
|
31538
|
+
}
|
|
31539
|
+
}
|
|
31540
|
+
if (imgElement instanceof HTMLImageElement) {
|
|
31541
|
+
if (width === 0 && imgElement.naturalWidth) {
|
|
31542
|
+
width = imgElement.naturalWidth;
|
|
31543
|
+
}
|
|
31544
|
+
if (height === 0 && imgElement.naturalHeight) {
|
|
31545
|
+
height = imgElement.naturalHeight;
|
|
31546
|
+
}
|
|
31547
|
+
}
|
|
31548
|
+
return { width, height };
|
|
31549
|
+
}
|
|
31550
|
+
function shouldCenterImage(imgElement) {
|
|
31551
|
+
var _a;
|
|
31552
|
+
const { width, height } = getImageDimensions(imgElement);
|
|
31553
|
+
if (width >= 500) {
|
|
31554
|
+
return true;
|
|
31555
|
+
}
|
|
31556
|
+
const parent = imgElement.parentElement;
|
|
31557
|
+
if (parent) {
|
|
31558
|
+
const siblings = Array.from(parent.childNodes);
|
|
31559
|
+
const meaningfulSiblings = siblings.filter((node) => {
|
|
31560
|
+
var _a2, _b;
|
|
31561
|
+
if (node === imgElement)
|
|
31562
|
+
return false;
|
|
31563
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
31564
|
+
return ((_a2 = node.textContent) == null ? void 0 : _a2.trim().length) !== 0;
|
|
31565
|
+
}
|
|
31566
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
31567
|
+
const el = node;
|
|
31568
|
+
if (el.tagName.toLowerCase() === "br")
|
|
31569
|
+
return false;
|
|
31570
|
+
return ((_b = el.textContent) == null ? void 0 : _b.trim().length) !== 0;
|
|
31571
|
+
}
|
|
31572
|
+
return false;
|
|
31573
|
+
});
|
|
31574
|
+
if (meaningfulSiblings.length === 0) {
|
|
31575
|
+
return true;
|
|
31576
|
+
}
|
|
31577
|
+
}
|
|
31578
|
+
if (width > 0 && height > 0 && width > height * 1.5 && width >= 300) {
|
|
31579
|
+
return true;
|
|
31580
|
+
}
|
|
31581
|
+
let current = imgElement.parentElement;
|
|
31582
|
+
while (current && current !== document.body) {
|
|
31583
|
+
const tagName = current.tagName.toLowerCase();
|
|
31584
|
+
if (tagName === "figure" || tagName === "article" || tagName === "section") {
|
|
31585
|
+
if (width >= 200 || width === 0) {
|
|
31586
|
+
return true;
|
|
31587
|
+
}
|
|
31588
|
+
}
|
|
31589
|
+
current = current.parentElement;
|
|
31590
|
+
}
|
|
31591
|
+
try {
|
|
31592
|
+
const computed = window.getComputedStyle(imgElement);
|
|
31593
|
+
if (computed.display === "block") {
|
|
31594
|
+
if (width >= 200 || width === 0) {
|
|
31595
|
+
return true;
|
|
31596
|
+
}
|
|
31597
|
+
}
|
|
31598
|
+
} catch {
|
|
31599
|
+
}
|
|
31600
|
+
if (width === 0) {
|
|
31601
|
+
const parentTag = parent == null ? void 0 : parent.tagName.toLowerCase();
|
|
31602
|
+
if (parentTag === "p" || parentTag === "div") {
|
|
31603
|
+
const textContent = ((_a = parent == null ? void 0 : parent.textContent) == null ? void 0 : _a.trim()) || "";
|
|
31604
|
+
if (textContent === "") {
|
|
31605
|
+
return true;
|
|
31606
|
+
}
|
|
31607
|
+
}
|
|
31608
|
+
}
|
|
31609
|
+
return false;
|
|
31610
|
+
}
|
|
31611
|
+
function detectClassBasedAlignment(element) {
|
|
31612
|
+
let current = element;
|
|
31613
|
+
while (current && current !== document.body) {
|
|
31614
|
+
const className = current.className || "";
|
|
31615
|
+
if (className.includes("image-style-align-right") || className.includes("image-style-side")) {
|
|
31616
|
+
return "right";
|
|
31617
|
+
}
|
|
31618
|
+
if (className.includes("image-style-align-left")) {
|
|
31619
|
+
return "left";
|
|
31620
|
+
}
|
|
31621
|
+
if (className.includes("image-style-align-center") || className.includes("image_resized") && !className.includes("align"))
|
|
31622
|
+
;
|
|
31623
|
+
if (className.includes("align-right")) {
|
|
31624
|
+
return "right";
|
|
31625
|
+
}
|
|
31626
|
+
if (className.includes("align-left")) {
|
|
31627
|
+
return "left";
|
|
31628
|
+
}
|
|
31629
|
+
if (className.includes("align-center")) {
|
|
31630
|
+
return "center";
|
|
31631
|
+
}
|
|
31632
|
+
if (className.includes("float-right") || className.includes("pull-right")) {
|
|
31633
|
+
return "right";
|
|
31634
|
+
}
|
|
31635
|
+
if (className.includes("float-left") || className.includes("pull-left")) {
|
|
31636
|
+
return "left";
|
|
31637
|
+
}
|
|
31638
|
+
try {
|
|
31639
|
+
const computed = window.getComputedStyle(current);
|
|
31640
|
+
if (computed.float === "right") {
|
|
31641
|
+
return "right";
|
|
31642
|
+
}
|
|
31643
|
+
if (computed.float === "left") {
|
|
31644
|
+
return "left";
|
|
31645
|
+
}
|
|
31646
|
+
} catch {
|
|
31647
|
+
}
|
|
31648
|
+
current = current.parentElement;
|
|
31649
|
+
}
|
|
31650
|
+
return null;
|
|
31651
|
+
}
|
|
31652
|
+
function detectImageAlignment(imgElement) {
|
|
31653
|
+
const classAlignment = detectClassBasedAlignment(imgElement);
|
|
31654
|
+
if (classAlignment) {
|
|
31655
|
+
return classAlignment;
|
|
31656
|
+
}
|
|
31657
|
+
const cssAlignment = detectCSSAlignment(imgElement);
|
|
31658
|
+
if (cssAlignment) {
|
|
31659
|
+
return cssAlignment;
|
|
31660
|
+
}
|
|
31661
|
+
if (shouldCenterImage(imgElement)) {
|
|
31662
|
+
return "center";
|
|
31663
|
+
}
|
|
31664
|
+
return "left";
|
|
31665
|
+
}
|
|
31666
|
+
function alignmentToPosition(alignment) {
|
|
31667
|
+
switch (alignment) {
|
|
31668
|
+
case "left":
|
|
31669
|
+
return "left";
|
|
31670
|
+
case "right":
|
|
31671
|
+
return "right";
|
|
31672
|
+
default:
|
|
31673
|
+
return "none";
|
|
31674
|
+
}
|
|
31675
|
+
}
|
|
31676
|
+
function isFloatAlignment(alignment) {
|
|
31677
|
+
return alignment === "left" || alignment === "right";
|
|
31678
|
+
}
|
|
31679
|
+
const IS_BOLD = 1;
|
|
31680
|
+
const IS_ITALIC = 2;
|
|
31681
|
+
const IS_STRIKETHROUGH = 4;
|
|
31682
|
+
const IS_UNDERLINE = 8;
|
|
31683
|
+
const IS_CODE = 16;
|
|
31684
|
+
const IS_SUBSCRIPT = 32;
|
|
31685
|
+
const IS_SUPERSCRIPT = 64;
|
|
31686
|
+
const IS_HIGHLIGHT = 128;
|
|
31687
|
+
function detectCKEditorSource(html) {
|
|
31688
|
+
return html.includes('class="image"') || // CKEditor's figure class for images
|
|
31689
|
+
html.includes('class="image ') || html.includes("image-style-") || // CKEditor's image alignment classes
|
|
31690
|
+
html.includes("ck-") || // CKEditor's internal classes
|
|
31691
|
+
html.includes("data-cke-");
|
|
31692
|
+
}
|
|
31693
|
+
const DEFAULT_HEADING_STYLES = {
|
|
31694
|
+
h1: { fontSize: "36px", lineHeight: "1.2" },
|
|
31695
|
+
h2: { fontSize: "29px", lineHeight: "1.25" },
|
|
31696
|
+
h3: { fontSize: "24px", lineHeight: "1.3" },
|
|
31697
|
+
h4: { fontSize: "20px", lineHeight: "1.35" },
|
|
31698
|
+
h5: { fontSize: "17px", lineHeight: "1.4" },
|
|
31699
|
+
h6: { fontSize: "15px", lineHeight: "1.45" }
|
|
31700
|
+
};
|
|
31701
|
+
const DEFAULT_PARAGRAPH_FONT_SIZE = "16px";
|
|
31702
|
+
const DEFAULT_PARAGRAPH_LINE_HEIGHT = "1.6";
|
|
31703
|
+
const MIN_HEADING_FONT_SIZES = {
|
|
31704
|
+
h1: 24,
|
|
31705
|
+
h2: 20,
|
|
31706
|
+
h3: 18,
|
|
31707
|
+
h4: 16,
|
|
31708
|
+
h5: 14,
|
|
31709
|
+
h6: 12
|
|
31710
|
+
};
|
|
31711
|
+
function parseStyleString(styleStr) {
|
|
31712
|
+
const result = {};
|
|
31713
|
+
if (!styleStr)
|
|
31714
|
+
return result;
|
|
31715
|
+
const parts = styleStr.split(";");
|
|
31716
|
+
for (const part of parts) {
|
|
31717
|
+
const colonIndex = part.indexOf(":");
|
|
31718
|
+
if (colonIndex > 0) {
|
|
31719
|
+
const key = part.substring(0, colonIndex).trim().toLowerCase();
|
|
31720
|
+
const value = part.substring(colonIndex + 1).trim();
|
|
31721
|
+
if (key && value) {
|
|
31722
|
+
result[key] = value;
|
|
31723
|
+
}
|
|
31724
|
+
}
|
|
31725
|
+
}
|
|
31726
|
+
return result;
|
|
31727
|
+
}
|
|
31728
|
+
function getStyleInfoFromElement(element) {
|
|
31729
|
+
const result = {
|
|
31730
|
+
format: 0,
|
|
31731
|
+
fontFamily: "",
|
|
31732
|
+
fontSize: "",
|
|
31733
|
+
lineHeight: "",
|
|
31734
|
+
letterSpacing: "",
|
|
31735
|
+
wordSpacing: "",
|
|
31736
|
+
color: "",
|
|
31737
|
+
backgroundColor: ""
|
|
31738
|
+
};
|
|
31739
|
+
let current = element;
|
|
31740
|
+
const elementsStack = [];
|
|
31741
|
+
while (current && current !== document.body) {
|
|
31742
|
+
elementsStack.push(current);
|
|
31743
|
+
current = current.parentElement;
|
|
31744
|
+
}
|
|
31745
|
+
for (let i2 = elementsStack.length - 1; i2 >= 0; i2--) {
|
|
31746
|
+
const el = elementsStack[i2];
|
|
31747
|
+
const tag = el.tagName.toLowerCase();
|
|
31748
|
+
if (tag === "strong" || tag === "b")
|
|
31749
|
+
result.format |= IS_BOLD;
|
|
31750
|
+
if (tag === "em" || tag === "i")
|
|
31751
|
+
result.format |= IS_ITALIC;
|
|
31752
|
+
if (tag === "u")
|
|
31753
|
+
result.format |= IS_UNDERLINE;
|
|
31754
|
+
if (tag === "s" || tag === "strike" || tag === "del")
|
|
31755
|
+
result.format |= IS_STRIKETHROUGH;
|
|
31756
|
+
if (tag === "code")
|
|
31757
|
+
result.format |= IS_CODE;
|
|
31758
|
+
if (tag === "sub")
|
|
31759
|
+
result.format |= IS_SUBSCRIPT;
|
|
31760
|
+
if (tag === "sup")
|
|
31761
|
+
result.format |= IS_SUPERSCRIPT;
|
|
31762
|
+
if (tag === "mark")
|
|
31763
|
+
result.format |= IS_HIGHLIGHT;
|
|
31764
|
+
const styleAttr = el.getAttribute("style") || "";
|
|
31765
|
+
const parsedStyle = parseStyleString(styleAttr);
|
|
31766
|
+
const style = el.style;
|
|
31767
|
+
const fontWeight = parsedStyle["font-weight"] || style.fontWeight;
|
|
31768
|
+
if (fontWeight === "bold" || fontWeight === "700" || parseInt(fontWeight || "0") >= 700) {
|
|
31769
|
+
result.format |= IS_BOLD;
|
|
31770
|
+
}
|
|
31771
|
+
const fontStyle = parsedStyle["font-style"] || style.fontStyle;
|
|
31772
|
+
if (fontStyle === "italic") {
|
|
31773
|
+
result.format |= IS_ITALIC;
|
|
31774
|
+
}
|
|
31775
|
+
const textDecoration = parsedStyle["text-decoration"] || style.textDecoration || "";
|
|
31776
|
+
if (textDecoration.includes("underline")) {
|
|
31777
|
+
result.format |= IS_UNDERLINE;
|
|
31778
|
+
}
|
|
31779
|
+
if (textDecoration.includes("line-through")) {
|
|
31780
|
+
result.format |= IS_STRIKETHROUGH;
|
|
31781
|
+
}
|
|
31782
|
+
const fontFamily = parsedStyle["font-family"] || style.fontFamily;
|
|
31783
|
+
if (fontFamily) {
|
|
31784
|
+
const family = fontFamily.split(",")[0].trim().replace(/["']/g, "");
|
|
31785
|
+
if (family && family !== "inherit" && family !== "initial") {
|
|
31786
|
+
result.fontFamily = family;
|
|
31787
|
+
}
|
|
31788
|
+
}
|
|
31789
|
+
const fontSize = parsedStyle["font-size"] || style.fontSize;
|
|
31790
|
+
if (fontSize && fontSize !== "inherit" && fontSize !== "initial") {
|
|
31791
|
+
result.fontSize = fontSize;
|
|
31792
|
+
}
|
|
31793
|
+
const lineHeight = parsedStyle["line-height"] || style.lineHeight;
|
|
31794
|
+
if (lineHeight && lineHeight !== "inherit" && lineHeight !== "initial" && lineHeight !== "normal") {
|
|
31795
|
+
result.lineHeight = lineHeight;
|
|
31796
|
+
}
|
|
31797
|
+
const letterSpacing = parsedStyle["letter-spacing"] || style.letterSpacing;
|
|
31798
|
+
if (letterSpacing && letterSpacing !== "inherit" && letterSpacing !== "initial" && letterSpacing !== "normal") {
|
|
31799
|
+
result.letterSpacing = letterSpacing;
|
|
31800
|
+
}
|
|
31801
|
+
const wordSpacing = parsedStyle["word-spacing"] || style.wordSpacing;
|
|
31802
|
+
if (wordSpacing && wordSpacing !== "inherit" && wordSpacing !== "initial" && wordSpacing !== "normal") {
|
|
31803
|
+
result.wordSpacing = wordSpacing;
|
|
31804
|
+
}
|
|
31805
|
+
const color = parsedStyle["color"] || style.color;
|
|
31806
|
+
if (color && color !== "inherit" && color !== "initial") {
|
|
31807
|
+
result.color = color;
|
|
31808
|
+
}
|
|
31809
|
+
const bgColor = parsedStyle["background-color"] || parsedStyle["background"] || style.backgroundColor;
|
|
31810
|
+
if (bgColor && bgColor !== "inherit" && bgColor !== "initial" && bgColor !== "transparent" && bgColor !== "rgba(0, 0, 0, 0)") {
|
|
31811
|
+
result.backgroundColor = bgColor;
|
|
31812
|
+
}
|
|
31813
|
+
}
|
|
31814
|
+
try {
|
|
31815
|
+
const computedStyle = window.getComputedStyle(element);
|
|
31816
|
+
if (!result.fontFamily && computedStyle.fontFamily) {
|
|
31817
|
+
const fontFamily = computedStyle.fontFamily.split(",")[0].trim().replace(/["']/g, "");
|
|
31818
|
+
const genericFonts = ["serif", "sans-serif", "monospace", "cursive", "fantasy", "system-ui", "-apple-system", "BlinkMacSystemFont"];
|
|
31819
|
+
if (fontFamily && !genericFonts.includes(fontFamily)) {
|
|
31820
|
+
result.fontFamily = fontFamily;
|
|
31821
|
+
}
|
|
31822
|
+
}
|
|
31823
|
+
if (!result.fontSize && computedStyle.fontSize && computedStyle.fontSize !== "16px") {
|
|
31824
|
+
result.fontSize = computedStyle.fontSize;
|
|
31825
|
+
}
|
|
31826
|
+
if (!result.lineHeight && computedStyle.lineHeight && computedStyle.lineHeight !== "normal") {
|
|
31827
|
+
const lineHeightValue = computedStyle.lineHeight;
|
|
31828
|
+
if (lineHeightValue && !lineHeightValue.endsWith("px")) {
|
|
31829
|
+
result.lineHeight = lineHeightValue;
|
|
31830
|
+
} else if (lineHeightValue && result.fontSize) {
|
|
31831
|
+
result.lineHeight = lineHeightValue;
|
|
31832
|
+
} else if (lineHeightValue) {
|
|
31833
|
+
result.lineHeight = lineHeightValue;
|
|
31834
|
+
}
|
|
31835
|
+
}
|
|
31836
|
+
if (!result.letterSpacing && computedStyle.letterSpacing && computedStyle.letterSpacing !== "normal" && computedStyle.letterSpacing !== "0px") {
|
|
31837
|
+
result.letterSpacing = computedStyle.letterSpacing;
|
|
31838
|
+
}
|
|
31839
|
+
if (!result.wordSpacing && computedStyle.wordSpacing && computedStyle.wordSpacing !== "normal" && computedStyle.wordSpacing !== "0px") {
|
|
31840
|
+
result.wordSpacing = computedStyle.wordSpacing;
|
|
31841
|
+
}
|
|
31842
|
+
if (!result.color && computedStyle.color) {
|
|
31843
|
+
const color = computedStyle.color;
|
|
31844
|
+
if (color !== "rgb(0, 0, 0)" && color !== "#000000" && color !== "black") {
|
|
31845
|
+
result.color = color;
|
|
31846
|
+
}
|
|
31847
|
+
}
|
|
31848
|
+
if (!result.backgroundColor && computedStyle.backgroundColor) {
|
|
31849
|
+
const bgColor = computedStyle.backgroundColor;
|
|
31850
|
+
if (bgColor !== "rgba(0, 0, 0, 0)" && bgColor !== "transparent") {
|
|
31851
|
+
result.backgroundColor = bgColor;
|
|
31852
|
+
}
|
|
31853
|
+
}
|
|
31854
|
+
} catch {
|
|
31855
|
+
}
|
|
31856
|
+
return result;
|
|
31857
|
+
}
|
|
31858
|
+
function buildStyleString(info) {
|
|
31859
|
+
const styles = [];
|
|
31860
|
+
if (info.fontFamily)
|
|
31861
|
+
styles.push(`font-family: ${info.fontFamily}`);
|
|
31862
|
+
if (info.fontSize)
|
|
31863
|
+
styles.push(`font-size: ${info.fontSize}`);
|
|
31864
|
+
if (info.lineHeight)
|
|
31865
|
+
styles.push(`line-height: ${info.lineHeight}`);
|
|
31866
|
+
if (info.letterSpacing)
|
|
31867
|
+
styles.push(`letter-spacing: ${info.letterSpacing}`);
|
|
31868
|
+
if (info.wordSpacing)
|
|
31869
|
+
styles.push(`word-spacing: ${info.wordSpacing}`);
|
|
31870
|
+
if (info.color)
|
|
31871
|
+
styles.push(`color: ${info.color}`);
|
|
31872
|
+
if (info.backgroundColor)
|
|
31873
|
+
styles.push(`background-color: ${info.backgroundColor}`);
|
|
31874
|
+
return styles.join("; ");
|
|
31875
|
+
}
|
|
31876
|
+
function createStyledTextNode(text, parentElement) {
|
|
31877
|
+
const textNode = $createTextNode(text);
|
|
31878
|
+
const styleInfo = getStyleInfoFromElement(parentElement);
|
|
31879
|
+
if (styleInfo.format) {
|
|
31880
|
+
textNode.setFormat(styleInfo.format);
|
|
31881
|
+
}
|
|
31882
|
+
const styleString = buildStyleString(styleInfo);
|
|
31883
|
+
if (styleString) {
|
|
31884
|
+
textNode.setStyle(styleString);
|
|
31885
|
+
}
|
|
31886
|
+
return textNode;
|
|
31887
|
+
}
|
|
31888
|
+
const defaultPasteContext = {
|
|
31889
|
+
isCKEditor: false
|
|
31890
|
+
};
|
|
31891
|
+
let currentPasteContext = defaultPasteContext;
|
|
31892
|
+
function processNode(domNode, parentElement = null) {
|
|
31893
|
+
var _a;
|
|
31894
|
+
const results = [];
|
|
31895
|
+
if (domNode.nodeType === Node.TEXT_NODE) {
|
|
31896
|
+
const text = domNode.textContent || "";
|
|
31897
|
+
if (text && parentElement) {
|
|
31898
|
+
const hasNonWhitespace = text.trim().length > 0;
|
|
31899
|
+
const isSignificantWhitespace = /\s/.test(text) && !hasNonWhitespace;
|
|
31900
|
+
if (hasNonWhitespace || isSignificantWhitespace) {
|
|
31901
|
+
const normalizedText = text.replace(/\s+/g, " ");
|
|
31902
|
+
const textNode = createStyledTextNode(normalizedText, parentElement);
|
|
31903
|
+
results.push(textNode);
|
|
31904
|
+
}
|
|
31905
|
+
}
|
|
31906
|
+
return results;
|
|
31907
|
+
}
|
|
31908
|
+
if (domNode.nodeType !== Node.ELEMENT_NODE) {
|
|
31909
|
+
return results;
|
|
31910
|
+
}
|
|
31911
|
+
const element = domNode;
|
|
31912
|
+
const tagName = element.tagName.toLowerCase();
|
|
31913
|
+
switch (tagName) {
|
|
31914
|
+
case "p":
|
|
31915
|
+
case "div": {
|
|
31916
|
+
const paragraph = $createParagraphNode();
|
|
31917
|
+
const styleInfo = getStyleInfoFromElement(element);
|
|
31918
|
+
const hasExplicitFontSize = styleInfo.fontSize && styleInfo.fontSize !== "16px";
|
|
31919
|
+
if (!hasExplicitFontSize && currentPasteContext.isCKEditor) {
|
|
31920
|
+
processChildrenWithStyle(element, paragraph, {
|
|
31921
|
+
fontSize: DEFAULT_PARAGRAPH_FONT_SIZE,
|
|
31922
|
+
lineHeight: DEFAULT_PARAGRAPH_LINE_HEIGHT
|
|
31923
|
+
});
|
|
31924
|
+
} else {
|
|
31925
|
+
processChildren(element, paragraph);
|
|
31926
|
+
}
|
|
31927
|
+
if (paragraph.getChildrenSize() > 0 || tagName === "p") {
|
|
31928
|
+
results.push(paragraph);
|
|
31929
|
+
}
|
|
31930
|
+
break;
|
|
31931
|
+
}
|
|
31932
|
+
case "h1":
|
|
31933
|
+
case "h2":
|
|
31934
|
+
case "h3":
|
|
31935
|
+
case "h4":
|
|
31936
|
+
case "h5":
|
|
31937
|
+
case "h6": {
|
|
31938
|
+
const heading = $createHeadingNode(tagName);
|
|
31939
|
+
const styleInfo = getStyleInfoFromElement(element);
|
|
31940
|
+
let hasAppropriateFontSize = false;
|
|
31941
|
+
if (styleInfo.fontSize) {
|
|
31942
|
+
const fontSizeValue = parseFloat(styleInfo.fontSize);
|
|
31943
|
+
const minExpectedSize = MIN_HEADING_FONT_SIZES[tagName] || 14;
|
|
31944
|
+
if (fontSizeValue >= minExpectedSize) {
|
|
31945
|
+
hasAppropriateFontSize = true;
|
|
31946
|
+
}
|
|
31947
|
+
}
|
|
31948
|
+
if (!hasAppropriateFontSize) {
|
|
31949
|
+
const defaultStyles = DEFAULT_HEADING_STYLES[tagName];
|
|
31950
|
+
if (defaultStyles) {
|
|
31951
|
+
processChildrenWithStyle(element, heading, defaultStyles);
|
|
31952
|
+
} else {
|
|
31953
|
+
processChildren(element, heading);
|
|
31954
|
+
}
|
|
31955
|
+
} else {
|
|
31956
|
+
processChildren(element, heading);
|
|
31957
|
+
}
|
|
31958
|
+
results.push(heading);
|
|
31959
|
+
break;
|
|
31960
|
+
}
|
|
31961
|
+
case "ul":
|
|
31962
|
+
case "ol": {
|
|
31963
|
+
const listType = tagName === "ul" ? "bullet" : "number";
|
|
31964
|
+
const list = $createListNode(listType);
|
|
31965
|
+
const listItems = element.querySelectorAll(":scope > li");
|
|
31966
|
+
listItems.forEach((li) => {
|
|
31967
|
+
const listItem = $createListItemNode();
|
|
31968
|
+
processChildren(li, listItem);
|
|
31969
|
+
list.append(listItem);
|
|
31970
|
+
});
|
|
31971
|
+
if (list.getChildrenSize() > 0) {
|
|
31972
|
+
results.push(list);
|
|
31973
|
+
}
|
|
31974
|
+
break;
|
|
31975
|
+
}
|
|
31976
|
+
case "li": {
|
|
31977
|
+
const list = $createListNode("bullet");
|
|
31978
|
+
const listItem = $createListItemNode();
|
|
31979
|
+
processChildren(element, listItem);
|
|
31980
|
+
list.append(listItem);
|
|
31981
|
+
results.push(list);
|
|
31982
|
+
break;
|
|
31983
|
+
}
|
|
31984
|
+
case "blockquote": {
|
|
31985
|
+
const quote = $createQuoteNode();
|
|
31986
|
+
processChildren(element, quote);
|
|
31987
|
+
results.push(quote);
|
|
31988
|
+
break;
|
|
31989
|
+
}
|
|
31990
|
+
case "a": {
|
|
31991
|
+
const href = element.getAttribute("href") || "";
|
|
31992
|
+
if (href) {
|
|
31993
|
+
const linkNode = $createLinkNode(href, { target: "_blank", rel: "noopener" });
|
|
31994
|
+
processChildren(element, linkNode);
|
|
31995
|
+
results.push(linkNode);
|
|
31996
|
+
} else {
|
|
31997
|
+
const children = processChildren(element);
|
|
31998
|
+
results.push(...children);
|
|
31999
|
+
}
|
|
32000
|
+
break;
|
|
32001
|
+
}
|
|
32002
|
+
case "img": {
|
|
32003
|
+
const src = element.getAttribute("src") || "";
|
|
32004
|
+
if (src && !src.startsWith("file:///")) {
|
|
32005
|
+
const alt = element.getAttribute("alt") || "";
|
|
32006
|
+
const width = parseInt(element.getAttribute("width") || "0") || void 0;
|
|
32007
|
+
const height = parseInt(element.getAttribute("height") || "0") || void 0;
|
|
32008
|
+
const alignment = detectImageAlignment(element);
|
|
32009
|
+
const position = alignmentToPosition(alignment);
|
|
32010
|
+
const imageNode = $createImageNode({
|
|
32011
|
+
src,
|
|
32012
|
+
altText: alt,
|
|
32013
|
+
width,
|
|
32014
|
+
height,
|
|
32015
|
+
position: isFloatAlignment(alignment) ? position : "none"
|
|
32016
|
+
});
|
|
32017
|
+
if (alignment === "center") {
|
|
32018
|
+
const paragraph = $createParagraphNode();
|
|
32019
|
+
paragraph.setFormat("center");
|
|
32020
|
+
paragraph.append(imageNode);
|
|
32021
|
+
results.push(paragraph);
|
|
32022
|
+
} else {
|
|
32023
|
+
results.push(imageNode);
|
|
32024
|
+
}
|
|
32025
|
+
}
|
|
32026
|
+
break;
|
|
32027
|
+
}
|
|
32028
|
+
case "br": {
|
|
32029
|
+
results.push($createLineBreakNode());
|
|
32030
|
+
break;
|
|
32031
|
+
}
|
|
32032
|
+
case "figure": {
|
|
32033
|
+
const img = element.querySelector("img");
|
|
32034
|
+
const figureAlignment = detectClassBasedAlignment(element);
|
|
32035
|
+
const alignment = figureAlignment || (img ? detectImageAlignment(img) : "left");
|
|
32036
|
+
const position = alignmentToPosition(alignment);
|
|
32037
|
+
const isFloat = isFloatAlignment(alignment);
|
|
32038
|
+
const figcaption = element.querySelector("figcaption");
|
|
32039
|
+
const captionText = ((_a = figcaption == null ? void 0 : figcaption.textContent) == null ? void 0 : _a.trim()) || "";
|
|
32040
|
+
if (img) {
|
|
32041
|
+
const src = img.getAttribute("src") || "";
|
|
32042
|
+
if (src && !src.startsWith("file:///")) {
|
|
32043
|
+
const alt = img.getAttribute("alt") || "";
|
|
32044
|
+
const width = parseInt(img.getAttribute("width") || "0") || void 0;
|
|
32045
|
+
const height = parseInt(img.getAttribute("height") || "0") || void 0;
|
|
32046
|
+
const imageNode = $createImageNode({
|
|
32047
|
+
src,
|
|
32048
|
+
altText: alt,
|
|
32049
|
+
width,
|
|
32050
|
+
height,
|
|
32051
|
+
position: isFloat ? position : "none"
|
|
32052
|
+
});
|
|
32053
|
+
if (alignment === "center") {
|
|
32054
|
+
const paragraph = $createParagraphNode();
|
|
32055
|
+
paragraph.setFormat("center");
|
|
32056
|
+
paragraph.append(imageNode);
|
|
32057
|
+
results.push(paragraph);
|
|
32058
|
+
if (captionText) {
|
|
32059
|
+
const captionPara = $createParagraphNode();
|
|
32060
|
+
captionPara.setFormat("center");
|
|
32061
|
+
const textNode = $createTextNode(captionText);
|
|
32062
|
+
textNode.setFormat(IS_ITALIC);
|
|
32063
|
+
captionPara.append(textNode);
|
|
32064
|
+
results.push(captionPara);
|
|
32065
|
+
}
|
|
32066
|
+
} else {
|
|
32067
|
+
if (captionText) {
|
|
32068
|
+
const paragraph = $createParagraphNode();
|
|
32069
|
+
paragraph.setFormat(alignment === "right" ? "right" : "left");
|
|
32070
|
+
paragraph.append(imageNode);
|
|
32071
|
+
paragraph.append($createLineBreakNode());
|
|
32072
|
+
const captionNode = $createTextNode(captionText);
|
|
32073
|
+
captionNode.setFormat(IS_ITALIC);
|
|
32074
|
+
paragraph.append(captionNode);
|
|
32075
|
+
results.push(paragraph);
|
|
32076
|
+
} else {
|
|
32077
|
+
results.push(imageNode);
|
|
32078
|
+
}
|
|
32079
|
+
}
|
|
32080
|
+
}
|
|
32081
|
+
}
|
|
32082
|
+
break;
|
|
32083
|
+
}
|
|
32084
|
+
case "strong":
|
|
32085
|
+
case "b":
|
|
32086
|
+
case "em":
|
|
32087
|
+
case "i":
|
|
32088
|
+
case "u":
|
|
32089
|
+
case "s":
|
|
32090
|
+
case "strike":
|
|
32091
|
+
case "del":
|
|
32092
|
+
case "code":
|
|
32093
|
+
case "sub":
|
|
32094
|
+
case "sup":
|
|
32095
|
+
case "mark":
|
|
32096
|
+
case "span":
|
|
32097
|
+
case "font": {
|
|
32098
|
+
const children = processChildren(element);
|
|
32099
|
+
results.push(...children);
|
|
32100
|
+
break;
|
|
32101
|
+
}
|
|
32102
|
+
case "script":
|
|
32103
|
+
case "style":
|
|
32104
|
+
case "meta":
|
|
32105
|
+
case "link":
|
|
32106
|
+
case "head":
|
|
32107
|
+
case "title":
|
|
32108
|
+
case "noscript":
|
|
32109
|
+
break;
|
|
32110
|
+
case "table":
|
|
32111
|
+
case "tbody":
|
|
32112
|
+
case "thead":
|
|
32113
|
+
case "tfoot":
|
|
32114
|
+
case "tr":
|
|
32115
|
+
case "td":
|
|
32116
|
+
case "th": {
|
|
32117
|
+
break;
|
|
32118
|
+
}
|
|
32119
|
+
default: {
|
|
32120
|
+
const children = processChildren(element);
|
|
32121
|
+
results.push(...children);
|
|
32122
|
+
}
|
|
32123
|
+
}
|
|
32124
|
+
return results;
|
|
32125
|
+
}
|
|
32126
|
+
function processChildren(element, parentNode) {
|
|
32127
|
+
const results = [];
|
|
32128
|
+
const childNodes = element.childNodes;
|
|
32129
|
+
for (let i2 = 0; i2 < childNodes.length; i2++) {
|
|
32130
|
+
const child = childNodes[i2];
|
|
32131
|
+
const nodes = processNode(child, element);
|
|
32132
|
+
if (parentNode) {
|
|
32133
|
+
nodes.forEach((node) => parentNode.append(node));
|
|
32134
|
+
} else {
|
|
32135
|
+
results.push(...nodes);
|
|
32136
|
+
}
|
|
32137
|
+
}
|
|
32138
|
+
return results;
|
|
32139
|
+
}
|
|
32140
|
+
function processChildrenWithStyle(element, parentNode, defaultStyles) {
|
|
32141
|
+
const childNodes = element.childNodes;
|
|
32142
|
+
for (let i2 = 0; i2 < childNodes.length; i2++) {
|
|
32143
|
+
const child = childNodes[i2];
|
|
32144
|
+
if (child.nodeType === Node.TEXT_NODE) {
|
|
32145
|
+
const text = child.textContent || "";
|
|
32146
|
+
if (text) {
|
|
32147
|
+
const hasNonWhitespace = text.trim().length > 0;
|
|
32148
|
+
const isSignificantWhitespace = /\s/.test(text) && !hasNonWhitespace;
|
|
32149
|
+
if (hasNonWhitespace || isSignificantWhitespace) {
|
|
32150
|
+
const normalizedText = text.replace(/\s+/g, " ");
|
|
32151
|
+
const textNode = $createTextNode(normalizedText);
|
|
32152
|
+
const styleInfo = getStyleInfoFromElement(element);
|
|
32153
|
+
if (styleInfo.format) {
|
|
32154
|
+
textNode.setFormat(styleInfo.format);
|
|
32155
|
+
}
|
|
32156
|
+
const styles = [];
|
|
32157
|
+
if (styleInfo.fontFamily) {
|
|
32158
|
+
styles.push(`font-family: ${styleInfo.fontFamily}`);
|
|
32159
|
+
}
|
|
32160
|
+
const usingDefaultFontSize = !styleInfo.fontSize && defaultStyles.fontSize;
|
|
32161
|
+
if (styleInfo.fontSize) {
|
|
32162
|
+
styles.push(`font-size: ${styleInfo.fontSize}`);
|
|
32163
|
+
} else if (defaultStyles.fontSize) {
|
|
32164
|
+
styles.push(`font-size: ${defaultStyles.fontSize}`);
|
|
32165
|
+
}
|
|
32166
|
+
if (styleInfo.lineHeight) {
|
|
32167
|
+
const isAbsoluteLineHeight = styleInfo.lineHeight.endsWith("px");
|
|
32168
|
+
if (usingDefaultFontSize && isAbsoluteLineHeight) {
|
|
32169
|
+
styles.push(`line-height: ${defaultStyles.lineHeight}`);
|
|
32170
|
+
} else {
|
|
32171
|
+
styles.push(`line-height: ${styleInfo.lineHeight}`);
|
|
32172
|
+
}
|
|
32173
|
+
} else if (defaultStyles.lineHeight) {
|
|
32174
|
+
styles.push(`line-height: ${defaultStyles.lineHeight}`);
|
|
32175
|
+
}
|
|
32176
|
+
if (styleInfo.letterSpacing) {
|
|
32177
|
+
styles.push(`letter-spacing: ${styleInfo.letterSpacing}`);
|
|
32178
|
+
}
|
|
32179
|
+
if (styleInfo.wordSpacing) {
|
|
32180
|
+
styles.push(`word-spacing: ${styleInfo.wordSpacing}`);
|
|
32181
|
+
}
|
|
32182
|
+
if (styleInfo.color) {
|
|
32183
|
+
styles.push(`color: ${styleInfo.color}`);
|
|
32184
|
+
}
|
|
32185
|
+
if (styleInfo.backgroundColor) {
|
|
32186
|
+
styles.push(`background-color: ${styleInfo.backgroundColor}`);
|
|
32187
|
+
}
|
|
32188
|
+
if (styles.length > 0) {
|
|
32189
|
+
textNode.setStyle(styles.join("; "));
|
|
32190
|
+
}
|
|
32191
|
+
parentNode.append(textNode);
|
|
32192
|
+
}
|
|
32193
|
+
}
|
|
32194
|
+
} else {
|
|
32195
|
+
const nodes = processNode(child, element);
|
|
32196
|
+
nodes.forEach((node) => {
|
|
32197
|
+
if ($isTextNode(node)) {
|
|
32198
|
+
const currentStyle = node.getStyle();
|
|
32199
|
+
const hasFontSize = currentStyle.includes("font-size");
|
|
32200
|
+
const hasLineHeight = currentStyle.includes("line-height");
|
|
32201
|
+
if (!hasFontSize || !hasLineHeight) {
|
|
32202
|
+
const newStyles = currentStyle ? [currentStyle] : [];
|
|
32203
|
+
if (!hasFontSize && defaultStyles.fontSize) {
|
|
32204
|
+
newStyles.push(`font-size: ${defaultStyles.fontSize}`);
|
|
32205
|
+
}
|
|
32206
|
+
if (!hasFontSize && hasLineHeight) {
|
|
32207
|
+
const lineHeightMatch = currentStyle.match(/line-height:\s*([^;]+)/);
|
|
32208
|
+
if (lineHeightMatch && lineHeightMatch[1].trim().endsWith("px")) {
|
|
32209
|
+
const filteredStyles = newStyles.filter((s2) => !s2.includes("line-height"));
|
|
32210
|
+
filteredStyles.push(`line-height: ${defaultStyles.lineHeight}`);
|
|
32211
|
+
node.setStyle(filteredStyles.join("; "));
|
|
32212
|
+
parentNode.append(node);
|
|
32213
|
+
return;
|
|
32214
|
+
}
|
|
32215
|
+
}
|
|
32216
|
+
if (!hasLineHeight && defaultStyles.lineHeight) {
|
|
32217
|
+
newStyles.push(`line-height: ${defaultStyles.lineHeight}`);
|
|
32218
|
+
}
|
|
32219
|
+
node.setStyle(newStyles.join("; "));
|
|
32220
|
+
}
|
|
32221
|
+
}
|
|
32222
|
+
parentNode.append(node);
|
|
32223
|
+
});
|
|
32224
|
+
}
|
|
32225
|
+
}
|
|
32226
|
+
}
|
|
32227
|
+
function wrapFloatedImagesInParagraphs(nodes) {
|
|
32228
|
+
return nodes.map((node) => {
|
|
32229
|
+
if ($isImageNode(node)) {
|
|
32230
|
+
const position = node.getPosition();
|
|
32231
|
+
if (position === "left" || position === "right") {
|
|
32232
|
+
const wrapper = $createParagraphNode();
|
|
32233
|
+
wrapper.append(node);
|
|
32234
|
+
return wrapper;
|
|
32235
|
+
}
|
|
32236
|
+
}
|
|
32237
|
+
return node;
|
|
32238
|
+
});
|
|
32239
|
+
}
|
|
32240
|
+
function createStyledDocument(html) {
|
|
32241
|
+
const container = document.createElement("div");
|
|
32242
|
+
container.style.cssText = "position: absolute; left: -9999px; top: -9999px; visibility: hidden;";
|
|
32243
|
+
const parser = new DOMParser();
|
|
32244
|
+
const doc = parser.parseFromString(html, "text/html");
|
|
32245
|
+
const styleTags = doc.querySelectorAll("style");
|
|
32246
|
+
const injectedStyles = [];
|
|
32247
|
+
styleTags.forEach((styleTag) => {
|
|
32248
|
+
const newStyle = document.createElement("style");
|
|
32249
|
+
newStyle.textContent = styleTag.textContent;
|
|
32250
|
+
document.head.appendChild(newStyle);
|
|
32251
|
+
injectedStyles.push(newStyle);
|
|
32252
|
+
});
|
|
32253
|
+
container.innerHTML = doc.body.innerHTML;
|
|
32254
|
+
document.body.appendChild(container);
|
|
32255
|
+
const cleanup = () => {
|
|
32256
|
+
injectedStyles.forEach((style) => style.remove());
|
|
32257
|
+
container.remove();
|
|
32258
|
+
};
|
|
32259
|
+
return { container, cleanup };
|
|
32260
|
+
}
|
|
32261
|
+
function convertHTMLToNodesWithStyles(html, editor) {
|
|
32262
|
+
const isCKEditor = detectCKEditorSource(html);
|
|
32263
|
+
currentPasteContext = {
|
|
32264
|
+
isCKEditor
|
|
32265
|
+
};
|
|
32266
|
+
const { container, cleanup } = createStyledDocument(html);
|
|
32267
|
+
try {
|
|
32268
|
+
const customNodes = processNode(container, null);
|
|
32269
|
+
const filteredCustomNodes = customNodes.filter((node) => {
|
|
32270
|
+
if (node instanceof ParagraphNode) {
|
|
32271
|
+
return node.getTextContent().trim().length > 0 || node.getChildrenSize() > 0;
|
|
32272
|
+
}
|
|
32273
|
+
return true;
|
|
32274
|
+
});
|
|
32275
|
+
if (filteredCustomNodes.length > 0) {
|
|
32276
|
+
const hasTables = html.includes("<table");
|
|
32277
|
+
if (hasTables) {
|
|
32278
|
+
const parser2 = new DOMParser();
|
|
32279
|
+
const doc2 = parser2.parseFromString(html, "text/html");
|
|
32280
|
+
const lexicalNodes = $generateNodesFromDOM(editor, doc2);
|
|
32281
|
+
const mergedNodes = [];
|
|
32282
|
+
let customIndex = 0;
|
|
32283
|
+
lexicalNodes.forEach((lexicalNode) => {
|
|
32284
|
+
const nodeType = lexicalNode.getType();
|
|
32285
|
+
if (nodeType === "table") {
|
|
32286
|
+
mergedNodes.push(lexicalNode);
|
|
32287
|
+
} else if (customIndex < filteredCustomNodes.length) {
|
|
32288
|
+
mergedNodes.push(filteredCustomNodes[customIndex]);
|
|
32289
|
+
customIndex++;
|
|
32290
|
+
}
|
|
32291
|
+
});
|
|
32292
|
+
while (customIndex < filteredCustomNodes.length) {
|
|
32293
|
+
mergedNodes.push(filteredCustomNodes[customIndex]);
|
|
32294
|
+
customIndex++;
|
|
32295
|
+
}
|
|
32296
|
+
return wrapFloatedImagesInParagraphs(mergedNodes.length > 0 ? mergedNodes : filteredCustomNodes);
|
|
32297
|
+
}
|
|
32298
|
+
return wrapFloatedImagesInParagraphs(filteredCustomNodes);
|
|
32299
|
+
}
|
|
32300
|
+
const parser = new DOMParser();
|
|
32301
|
+
const doc = parser.parseFromString(html, "text/html");
|
|
32302
|
+
return $generateNodesFromDOM(editor, doc);
|
|
32303
|
+
} finally {
|
|
32304
|
+
cleanup();
|
|
32305
|
+
currentPasteContext = defaultPasteContext;
|
|
32306
|
+
}
|
|
32307
|
+
}
|
|
31077
32308
|
function RichTextPastePlugin() {
|
|
31078
32309
|
const [editor] = useLexicalComposerContext();
|
|
31079
32310
|
useEffect$1(() => {
|
|
@@ -31083,192 +32314,55 @@ function RichTextPastePlugin() {
|
|
|
31083
32314
|
const clipboardData = event.clipboardData;
|
|
31084
32315
|
if (!clipboardData)
|
|
31085
32316
|
return false;
|
|
32317
|
+
const files = clipboardData.files;
|
|
32318
|
+
if (files && files.length > 0) {
|
|
32319
|
+
const hasImages = Array.from(files).some(
|
|
32320
|
+
(file) => file.type.startsWith("image/")
|
|
32321
|
+
);
|
|
32322
|
+
if (hasImages) {
|
|
32323
|
+
return false;
|
|
32324
|
+
}
|
|
32325
|
+
}
|
|
31086
32326
|
const htmlContent = clipboardData.getData("text/html");
|
|
31087
32327
|
const plainText = clipboardData.getData("text/plain");
|
|
31088
32328
|
if (htmlContent) {
|
|
31089
32329
|
event.preventDefault();
|
|
31090
|
-
|
|
31091
|
-
|
|
31092
|
-
|
|
31093
|
-
|
|
31094
|
-
|
|
31095
|
-
|
|
31096
|
-
|
|
31097
|
-
|
|
31098
|
-
|
|
31099
|
-
|
|
31100
|
-
|
|
31101
|
-
|
|
31102
|
-
|
|
31103
|
-
editor.update(() => {
|
|
31104
|
-
const selection = $getSelection();
|
|
31105
|
-
if ($isRangeSelection(selection)) {
|
|
31106
|
-
const tempDiv = document.createElement("div");
|
|
31107
|
-
tempDiv.innerHTML = htmlContent;
|
|
31108
|
-
const processNode = (node) => {
|
|
31109
|
-
if (node.nodeType === Node.TEXT_NODE) {
|
|
31110
|
-
const text = node.textContent || "";
|
|
31111
|
-
const textNode = $createTextNode(text);
|
|
31112
|
-
if (node.parentElement) {
|
|
31113
|
-
if (node.parentElement.tagName === "STRONG" || node.parentElement.tagName === "B") {
|
|
31114
|
-
textNode.setFormat("bold");
|
|
31115
|
-
}
|
|
31116
|
-
if (node.parentElement.tagName === "EM" || node.parentElement.tagName === "I") {
|
|
31117
|
-
textNode.setFormat("italic");
|
|
31118
|
-
}
|
|
31119
|
-
if (node.parentElement.tagName === "U") {
|
|
31120
|
-
textNode.setFormat("underline");
|
|
31121
|
-
}
|
|
31122
|
-
if (node.parentElement.tagName === "CODE") {
|
|
31123
|
-
textNode.setFormat("code");
|
|
31124
|
-
}
|
|
31125
|
-
if (node.parentElement.tagName === "STRIKE" || node.parentElement.tagName === "S") {
|
|
31126
|
-
textNode.setFormat("strikethrough");
|
|
31127
|
-
}
|
|
31128
|
-
if (node.parentElement.tagName === "SUB") {
|
|
31129
|
-
textNode.setFormat("subscript");
|
|
31130
|
-
}
|
|
31131
|
-
if (node.parentElement.tagName === "SUP") {
|
|
31132
|
-
textNode.setFormat("superscript");
|
|
31133
|
-
}
|
|
31134
|
-
}
|
|
31135
|
-
return textNode;
|
|
31136
|
-
}
|
|
31137
|
-
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
31138
|
-
const element = node;
|
|
31139
|
-
if (element.tagName === "UL" || element.tagName === "OL") {
|
|
31140
|
-
const listNode = $createListNode(
|
|
31141
|
-
element.tagName === "UL" ? "bullet" : "number"
|
|
31142
|
-
);
|
|
31143
|
-
Array.from(element.childNodes).forEach((child) => {
|
|
31144
|
-
if (child.nodeType === Node.ELEMENT_NODE && child.tagName === "LI") {
|
|
31145
|
-
const listItemNode = $createListItemNode();
|
|
31146
|
-
Array.from(child.childNodes).forEach((grandChild) => {
|
|
31147
|
-
const processedNode = processNode(grandChild);
|
|
31148
|
-
if (processedNode) {
|
|
31149
|
-
if (Array.isArray(processedNode)) {
|
|
31150
|
-
processedNode.forEach(
|
|
31151
|
-
(node2) => listItemNode.append(node2)
|
|
31152
|
-
);
|
|
31153
|
-
} else {
|
|
31154
|
-
listItemNode.append(processedNode);
|
|
31155
|
-
}
|
|
32330
|
+
editor.update(
|
|
32331
|
+
() => {
|
|
32332
|
+
const selection = $getSelection();
|
|
32333
|
+
if (!$isRangeSelection(selection))
|
|
32334
|
+
return;
|
|
32335
|
+
try {
|
|
32336
|
+
const nodes = convertHTMLToNodesWithStyles(htmlContent, editor);
|
|
32337
|
+
if (nodes.length > 0) {
|
|
32338
|
+
const filteredNodes = nodes.filter((node) => {
|
|
32339
|
+
if (node instanceof ParagraphNode) {
|
|
32340
|
+
const textContent = node.getTextContent();
|
|
32341
|
+
const hasChildren = node.getChildrenSize() > 0;
|
|
32342
|
+
return textContent.trim().length > 0 || hasChildren;
|
|
31156
32343
|
}
|
|
32344
|
+
return true;
|
|
31157
32345
|
});
|
|
31158
|
-
|
|
31159
|
-
|
|
31160
|
-
});
|
|
31161
|
-
return listNode;
|
|
31162
|
-
}
|
|
31163
|
-
if (element.tagName.match(/^H[1-6]$/)) {
|
|
31164
|
-
const headingNode = $createHeadingNode(
|
|
31165
|
-
element.tagName.toLowerCase()
|
|
31166
|
-
);
|
|
31167
|
-
Array.from(element.childNodes).forEach((child) => {
|
|
31168
|
-
const processedNode = processNode(child);
|
|
31169
|
-
if (processedNode) {
|
|
31170
|
-
if (Array.isArray(processedNode)) {
|
|
31171
|
-
processedNode.forEach((node2) => headingNode.append(node2));
|
|
31172
|
-
} else {
|
|
31173
|
-
headingNode.append(processedNode);
|
|
32346
|
+
if (filteredNodes.length > 0) {
|
|
32347
|
+
selection.insertNodes(filteredNodes);
|
|
31174
32348
|
}
|
|
31175
32349
|
}
|
|
31176
|
-
})
|
|
31177
|
-
|
|
31178
|
-
|
|
31179
|
-
|
|
31180
|
-
const paragraphNode = $createParagraphNode();
|
|
31181
|
-
Array.from(element.childNodes).forEach((child) => {
|
|
31182
|
-
const processedNode = processNode(child);
|
|
31183
|
-
if (processedNode) {
|
|
31184
|
-
if (Array.isArray(processedNode)) {
|
|
31185
|
-
processedNode.forEach((node2) => paragraphNode.append(node2));
|
|
31186
|
-
} else {
|
|
31187
|
-
paragraphNode.append(processedNode);
|
|
31188
|
-
}
|
|
31189
|
-
}
|
|
31190
|
-
});
|
|
31191
|
-
return paragraphNode;
|
|
31192
|
-
}
|
|
31193
|
-
const nodes = [];
|
|
31194
|
-
Array.from(element.childNodes).forEach((child) => {
|
|
31195
|
-
const processedNode = processNode(child);
|
|
31196
|
-
if (processedNode) {
|
|
31197
|
-
if (Array.isArray(processedNode)) {
|
|
31198
|
-
nodes.push(...processedNode);
|
|
31199
|
-
} else {
|
|
31200
|
-
nodes.push(processedNode);
|
|
32350
|
+
} catch (error) {
|
|
32351
|
+
console.error("Error during HTML paste:", error);
|
|
32352
|
+
if (plainText) {
|
|
32353
|
+
selection.insertRawText(plainText);
|
|
31201
32354
|
}
|
|
31202
32355
|
}
|
|
31203
|
-
}
|
|
31204
|
-
|
|
31205
|
-
|
|
31206
|
-
return
|
|
31207
|
-
};
|
|
31208
|
-
const processedNodes = processNode(tempDiv);
|
|
31209
|
-
if (processedNodes) {
|
|
31210
|
-
if (Array.isArray(processedNodes)) {
|
|
31211
|
-
selection.insertNodes(processedNodes);
|
|
31212
|
-
} else {
|
|
31213
|
-
selection.insertNodes([processedNodes]);
|
|
31214
|
-
}
|
|
32356
|
+
},
|
|
32357
|
+
{ tag: "paste" }
|
|
32358
|
+
);
|
|
32359
|
+
return true;
|
|
31215
32360
|
}
|
|
31216
|
-
|
|
31217
|
-
|
|
31218
|
-
|
|
31219
|
-
|
|
31220
|
-
|
|
31221
|
-
const selection = $getSelection();
|
|
31222
|
-
if ($isRangeSelection(selection)) {
|
|
31223
|
-
const lines = text.split("\n");
|
|
31224
|
-
const nodes = [];
|
|
31225
|
-
lines.forEach((line) => {
|
|
31226
|
-
const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
|
|
31227
|
-
if (headingMatch) {
|
|
31228
|
-
const level = headingMatch[1].length;
|
|
31229
|
-
const content = headingMatch[2];
|
|
31230
|
-
const headingNode = $createHeadingNode(
|
|
31231
|
-
`h${level}`
|
|
31232
|
-
);
|
|
31233
|
-
headingNode.append($createTextNode(content));
|
|
31234
|
-
nodes.push(headingNode);
|
|
31235
|
-
return;
|
|
31236
|
-
}
|
|
31237
|
-
const bulletMatch = line.match(/^-\s+(.+)$/);
|
|
31238
|
-
if (bulletMatch) {
|
|
31239
|
-
const listNode = $createListNode("bullet");
|
|
31240
|
-
const listItemNode = $createListItemNode();
|
|
31241
|
-
listItemNode.append($createTextNode(bulletMatch[1]));
|
|
31242
|
-
listNode.append(listItemNode);
|
|
31243
|
-
nodes.push(listNode);
|
|
31244
|
-
return;
|
|
31245
|
-
}
|
|
31246
|
-
const numberedMatch = line.match(/^\d+\.\s+(.+)$/);
|
|
31247
|
-
if (numberedMatch) {
|
|
31248
|
-
const listNode = $createListNode("number");
|
|
31249
|
-
const listItemNode = $createListItemNode();
|
|
31250
|
-
listItemNode.append($createTextNode(numberedMatch[1]));
|
|
31251
|
-
listNode.append(listItemNode);
|
|
31252
|
-
nodes.push(listNode);
|
|
31253
|
-
return;
|
|
31254
|
-
}
|
|
31255
|
-
const textNode = $createTextNode(line);
|
|
31256
|
-
if (line.includes("**") || line.includes("__")) {
|
|
31257
|
-
textNode.setFormat("bold");
|
|
31258
|
-
}
|
|
31259
|
-
if (line.includes("*") || line.includes("_")) {
|
|
31260
|
-
textNode.setFormat("italic");
|
|
31261
|
-
}
|
|
31262
|
-
if (line.includes("***") || line.includes("___")) {
|
|
31263
|
-
textNode.setFormat("bold");
|
|
31264
|
-
textNode.setFormat("italic");
|
|
31265
|
-
}
|
|
31266
|
-
nodes.push(textNode);
|
|
31267
|
-
});
|
|
31268
|
-
selection.insertNodes(nodes);
|
|
31269
|
-
}
|
|
31270
|
-
});
|
|
31271
|
-
};
|
|
32361
|
+
return false;
|
|
32362
|
+
},
|
|
32363
|
+
COMMAND_PRIORITY_HIGH
|
|
32364
|
+
);
|
|
32365
|
+
}, [editor]);
|
|
31272
32366
|
return null;
|
|
31273
32367
|
}
|
|
31274
32368
|
function getOptionMeta(label) {
|
|
@@ -35248,6 +36342,95 @@ function TableImageAutoResizePlugin() {
|
|
|
35248
36342
|
}, [editor]);
|
|
35249
36343
|
return null;
|
|
35250
36344
|
}
|
|
36345
|
+
const DEFAULT_SYNC_INTERVAL = 2 * 60 * 1e3;
|
|
36346
|
+
const UsageTrackingPlugin = ({
|
|
36347
|
+
licenseKey,
|
|
36348
|
+
syncIntervalMs = DEFAULT_SYNC_INTERVAL
|
|
36349
|
+
}) => {
|
|
36350
|
+
const [editor] = useLexicalComposerContext();
|
|
36351
|
+
const lastCountRef = useRef({ characters: 0, words: 0 });
|
|
36352
|
+
const pendingDeltaRef = useRef({ characters: 0, words: 0 });
|
|
36353
|
+
const isSyncingRef = useRef(false);
|
|
36354
|
+
const syncToBackend = useCallback(async () => {
|
|
36355
|
+
if (!licenseKey || isSyncingRef.current)
|
|
36356
|
+
return;
|
|
36357
|
+
const { characters, words } = pendingDeltaRef.current;
|
|
36358
|
+
if (characters === 0 && words === 0)
|
|
36359
|
+
return;
|
|
36360
|
+
isSyncingRef.current = true;
|
|
36361
|
+
try {
|
|
36362
|
+
await backendAPI.post("/api/analytics/track-usage", {
|
|
36363
|
+
licenseKey,
|
|
36364
|
+
characters,
|
|
36365
|
+
words
|
|
36366
|
+
});
|
|
36367
|
+
pendingDeltaRef.current = { characters: 0, words: 0 };
|
|
36368
|
+
} catch (error) {
|
|
36369
|
+
console.error("Failed to sync usage stats:", error);
|
|
36370
|
+
} finally {
|
|
36371
|
+
isSyncingRef.current = false;
|
|
36372
|
+
}
|
|
36373
|
+
}, [licenseKey]);
|
|
36374
|
+
useEffect$1(() => {
|
|
36375
|
+
if (!licenseKey)
|
|
36376
|
+
return;
|
|
36377
|
+
const unregister = editor.registerUpdateListener(({ editorState }) => {
|
|
36378
|
+
editorState.read(() => {
|
|
36379
|
+
const root2 = $getRoot();
|
|
36380
|
+
const text = root2.getTextContent();
|
|
36381
|
+
const currentWords = text.trim().split(/\s+/).filter((word) => word.length > 0).length;
|
|
36382
|
+
const currentCharacters = text.replace(/\s/g, "").length;
|
|
36383
|
+
const deltaCharacters = Math.max(
|
|
36384
|
+
0,
|
|
36385
|
+
currentCharacters - lastCountRef.current.characters
|
|
36386
|
+
);
|
|
36387
|
+
const deltaWords = Math.max(
|
|
36388
|
+
0,
|
|
36389
|
+
currentWords - lastCountRef.current.words
|
|
36390
|
+
);
|
|
36391
|
+
lastCountRef.current = {
|
|
36392
|
+
characters: currentCharacters,
|
|
36393
|
+
words: currentWords
|
|
36394
|
+
};
|
|
36395
|
+
if (deltaCharacters > 0 || deltaWords > 0) {
|
|
36396
|
+
pendingDeltaRef.current.characters += deltaCharacters;
|
|
36397
|
+
pendingDeltaRef.current.words += deltaWords;
|
|
36398
|
+
}
|
|
36399
|
+
});
|
|
36400
|
+
});
|
|
36401
|
+
const syncInterval = setInterval(syncToBackend, syncIntervalMs);
|
|
36402
|
+
const handleBeforeUnload = () => {
|
|
36403
|
+
const { characters, words } = pendingDeltaRef.current;
|
|
36404
|
+
if (characters > 0 || words > 0) {
|
|
36405
|
+
const data = JSON.stringify({
|
|
36406
|
+
licenseKey,
|
|
36407
|
+
characters,
|
|
36408
|
+
words
|
|
36409
|
+
});
|
|
36410
|
+
const baseURL = backendAPI.defaults.baseURL || "";
|
|
36411
|
+
navigator.sendBeacon(
|
|
36412
|
+
`${baseURL}/api/analytics/track-usage`,
|
|
36413
|
+
new Blob([data], { type: "application/json" })
|
|
36414
|
+
);
|
|
36415
|
+
}
|
|
36416
|
+
};
|
|
36417
|
+
const handleVisibilityChange = () => {
|
|
36418
|
+
if (document.visibilityState === "hidden") {
|
|
36419
|
+
syncToBackend();
|
|
36420
|
+
}
|
|
36421
|
+
};
|
|
36422
|
+
window.addEventListener("beforeunload", handleBeforeUnload);
|
|
36423
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
36424
|
+
return () => {
|
|
36425
|
+
unregister();
|
|
36426
|
+
clearInterval(syncInterval);
|
|
36427
|
+
syncToBackend();
|
|
36428
|
+
window.removeEventListener("beforeunload", handleBeforeUnload);
|
|
36429
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
36430
|
+
};
|
|
36431
|
+
}, [editor, licenseKey, syncToBackend, syncIntervalMs]);
|
|
36432
|
+
return null;
|
|
36433
|
+
};
|
|
35251
36434
|
const WordCountPlugin = () => {
|
|
35252
36435
|
const [editor] = useLexicalComposerContext();
|
|
35253
36436
|
const [stats, setStats] = useState$1({
|
|
@@ -35485,11 +36668,12 @@ function applyGenericSafeStyles(container) {
|
|
|
35485
36668
|
}
|
|
35486
36669
|
});
|
|
35487
36670
|
};
|
|
35488
|
-
const
|
|
35489
|
-
|
|
35490
|
-
|
|
35491
|
-
|
|
35492
|
-
);
|
|
36671
|
+
const defaultFontFamily = "Arial, sans-serif";
|
|
36672
|
+
const selectors = "table, p, span, li, td, th, div, h1, h2, h3, h4, h5, h6";
|
|
36673
|
+
addStyle(selectors, "line-height: 1.5;");
|
|
36674
|
+
addStyleIfNotSet(selectors, "font-family", defaultFontFamily);
|
|
36675
|
+
addStyleIfNotSet("table, p, span, li, td, th, div", "font-size", "16px");
|
|
36676
|
+
addStyle("p", "margin: 0 0 1em 0;");
|
|
35493
36677
|
addStyle("th p, td p", "margin: 0; padding: 0;");
|
|
35494
36678
|
addStyle(
|
|
35495
36679
|
"table",
|
|
@@ -35501,7 +36685,34 @@ function applyGenericSafeStyles(container) {
|
|
|
35501
36685
|
);
|
|
35502
36686
|
addStyleIfNotSet("th", "background-color", "#f8f9fa");
|
|
35503
36687
|
addStyle("th", "font-weight: 600;");
|
|
35504
|
-
|
|
36688
|
+
container.querySelectorAll("img").forEach((img) => {
|
|
36689
|
+
const position = img.getAttribute("data-position");
|
|
36690
|
+
const parent = img.parentElement;
|
|
36691
|
+
img.style.cssText += "; max-width: 100%; height: auto;";
|
|
36692
|
+
const hasCaption = parent && parent.tagName.toLowerCase() === "p" && parent.querySelector("em, i");
|
|
36693
|
+
if (position === "left" || position === "right") {
|
|
36694
|
+
const floatDir = position === "left" ? "left" : "right";
|
|
36695
|
+
const marginDir = position === "left" ? "right" : "left";
|
|
36696
|
+
if (hasCaption && parent) {
|
|
36697
|
+
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;`;
|
|
36698
|
+
img.style.cssText += "; display: block; margin: 0 auto;";
|
|
36699
|
+
const caption = parent.querySelector("em, i");
|
|
36700
|
+
if (caption) {
|
|
36701
|
+
caption.style.cssText += "; display: block; font-size: 0.85em; line-height: 1.4; color: #666; padding-top: 0.5em;";
|
|
36702
|
+
}
|
|
36703
|
+
} else {
|
|
36704
|
+
img.style.cssText += `; float: ${floatDir}; clear: ${floatDir}; margin-${marginDir}: 1em; margin-bottom: 0.5em; max-width: 50%;`;
|
|
36705
|
+
}
|
|
36706
|
+
} else if (position === "full") {
|
|
36707
|
+
img.style.cssText += "; display: block; width: 100%; margin: 1em 0;";
|
|
36708
|
+
} else {
|
|
36709
|
+
img.style.cssText += "; display: block;";
|
|
36710
|
+
if (parent && parent.style.textAlign === "center") {
|
|
36711
|
+
img.style.margin = "0 auto";
|
|
36712
|
+
}
|
|
36713
|
+
}
|
|
36714
|
+
img.removeAttribute("data-position");
|
|
36715
|
+
});
|
|
35505
36716
|
addStyle("h1", "font-size: 2em; font-weight: bold; margin: 0.67em 0;");
|
|
35506
36717
|
addStyle("h2", "font-size: 1.5em; font-weight: bold; margin: 0.75em 0;");
|
|
35507
36718
|
addStyle("h3", "font-size: 1.17em; font-weight: bold; margin: 0.83em 0;");
|
|
@@ -35696,7 +36907,7 @@ function detectTableStylesFromInline(table) {
|
|
|
35696
36907
|
return result;
|
|
35697
36908
|
}
|
|
35698
36909
|
function preprocessInitialContent(html) {
|
|
35699
|
-
if (!html
|
|
36910
|
+
if (!html) {
|
|
35700
36911
|
return html;
|
|
35701
36912
|
}
|
|
35702
36913
|
const parser = new DOMParser();
|
|
@@ -35729,6 +36940,72 @@ function preprocessInitialContent(html) {
|
|
|
35729
36940
|
table.classList.add("PlaygroundEditorTheme__table");
|
|
35730
36941
|
}
|
|
35731
36942
|
});
|
|
36943
|
+
const images = doc.querySelectorAll("img");
|
|
36944
|
+
images.forEach((img) => {
|
|
36945
|
+
const parent = img.parentElement;
|
|
36946
|
+
if (!parent)
|
|
36947
|
+
return;
|
|
36948
|
+
const imgFloat = img.style.float;
|
|
36949
|
+
const parentFloat = parent.style.float;
|
|
36950
|
+
const floatDir = imgFloat || parentFloat;
|
|
36951
|
+
if (floatDir === "left" || floatDir === "right") {
|
|
36952
|
+
img.setAttribute("data-position", floatDir);
|
|
36953
|
+
if (parentFloat && parent.tagName.toLowerCase() === "p") {
|
|
36954
|
+
parent.style.textAlign = floatDir;
|
|
36955
|
+
parent.style.removeProperty("float");
|
|
36956
|
+
parent.style.removeProperty("clear");
|
|
36957
|
+
parent.style.removeProperty("max-width");
|
|
36958
|
+
parent.style.removeProperty("background-color");
|
|
36959
|
+
parent.style.removeProperty("padding");
|
|
36960
|
+
parent.style.removeProperty("border-radius");
|
|
36961
|
+
}
|
|
36962
|
+
}
|
|
36963
|
+
});
|
|
36964
|
+
const styledElements = doc.querySelectorAll("span[style], b[style], strong[style], i[style], em[style]");
|
|
36965
|
+
styledElements.forEach((el) => {
|
|
36966
|
+
const htmlEl = el;
|
|
36967
|
+
const style = htmlEl.style;
|
|
36968
|
+
const relevantStyles = [];
|
|
36969
|
+
if (style.fontFamily) {
|
|
36970
|
+
const fontFamily = style.fontFamily.replace(/["']/g, "");
|
|
36971
|
+
relevantStyles.push(`font-family: ${fontFamily}`);
|
|
36972
|
+
}
|
|
36973
|
+
if (style.fontSize) {
|
|
36974
|
+
relevantStyles.push(`font-size: ${style.fontSize}`);
|
|
36975
|
+
}
|
|
36976
|
+
if (style.lineHeight) {
|
|
36977
|
+
relevantStyles.push(`line-height: ${style.lineHeight}`);
|
|
36978
|
+
}
|
|
36979
|
+
if (style.color && style.color !== "rgb(0, 0, 0)") {
|
|
36980
|
+
relevantStyles.push(`color: ${style.color}`);
|
|
36981
|
+
}
|
|
36982
|
+
if (style.backgroundColor && style.backgroundColor !== "rgba(0, 0, 0, 0)" && style.backgroundColor !== "transparent") {
|
|
36983
|
+
relevantStyles.push(`background-color: ${style.backgroundColor}`);
|
|
36984
|
+
}
|
|
36985
|
+
if (style.letterSpacing && style.letterSpacing !== "normal") {
|
|
36986
|
+
relevantStyles.push(`letter-spacing: ${style.letterSpacing}`);
|
|
36987
|
+
}
|
|
36988
|
+
if (style.wordSpacing && style.wordSpacing !== "normal") {
|
|
36989
|
+
relevantStyles.push(`word-spacing: ${style.wordSpacing}`);
|
|
36990
|
+
}
|
|
36991
|
+
if (relevantStyles.length > 0) {
|
|
36992
|
+
htmlEl.setAttribute("style", relevantStyles.join("; "));
|
|
36993
|
+
}
|
|
36994
|
+
});
|
|
36995
|
+
const headings = doc.querySelectorAll("h1, h2, h3, h4, h5, h6");
|
|
36996
|
+
headings.forEach((heading) => {
|
|
36997
|
+
const tagName = heading.tagName.toLowerCase();
|
|
36998
|
+
const className = `PlaygroundEditorTheme__${tagName}`;
|
|
36999
|
+
if (!heading.classList.contains(className)) {
|
|
37000
|
+
heading.classList.add(className);
|
|
37001
|
+
}
|
|
37002
|
+
});
|
|
37003
|
+
const paragraphs = doc.querySelectorAll("p");
|
|
37004
|
+
paragraphs.forEach((p2) => {
|
|
37005
|
+
if (!p2.classList.contains("PlaygroundEditorTheme__paragraph")) {
|
|
37006
|
+
p2.classList.add("PlaygroundEditorTheme__paragraph");
|
|
37007
|
+
}
|
|
37008
|
+
});
|
|
35732
37009
|
return doc.body.innerHTML;
|
|
35733
37010
|
}
|
|
35734
37011
|
const useAutoExpandingHeight = ({
|
|
@@ -35799,6 +37076,8 @@ const useStyles = () => ({
|
|
|
35799
37076
|
"cteditor-relative cteditor-min-h-[300px] cteditor-rounded-lg cteditor-p-3 !cteditor-h-auto cteditor-resize-none cteditor-outline-0 cteditor-content",
|
|
35800
37077
|
// Ensure strong contrast in both themes
|
|
35801
37078
|
"cteditor-text-foreground cteditor-bg-background",
|
|
37079
|
+
// Default font: Arial 16px to match toolbar defaults and ensure WYSIWYG output
|
|
37080
|
+
"cteditor-font-arial cteditor-text-base",
|
|
35802
37081
|
// Caret and spacing
|
|
35803
37082
|
"cteditor-caret-[#3b82f6] cteditor-p-0 cteditor-transition-all cteditor-duration-200",
|
|
35804
37083
|
"cteditor-w-full ",
|
|
@@ -36137,7 +37416,8 @@ const ConfigurableEditor = ({
|
|
|
36137
37416
|
ErrorBoundary: LexicalErrorBoundary
|
|
36138
37417
|
}
|
|
36139
37418
|
),
|
|
36140
|
-
/* @__PURE__ */ jsx(WordCountPlugin, {})
|
|
37419
|
+
/* @__PURE__ */ jsx(WordCountPlugin, {}),
|
|
37420
|
+
/* @__PURE__ */ jsx(UsageTrackingPlugin, { licenseKey: apiKey })
|
|
36141
37421
|
] }),
|
|
36142
37422
|
/* @__PURE__ */ jsx(HtmlViewDisplay, {}),
|
|
36143
37423
|
/* @__PURE__ */ jsx(AIRephrasePlugin, {}),
|
|
@@ -36227,9 +37507,9 @@ const ScopedEditorWrapper = ({
|
|
|
36227
37507
|
}) => {
|
|
36228
37508
|
return /* @__PURE__ */ jsx("div", { id: "ct-editor-f47ac10b", className: "cteditor-max-w-full", children: /* @__PURE__ */ jsx("div", { className: "cteditor-p-2 cteditor-w-full cteditor-relative", children }) });
|
|
36229
37509
|
};
|
|
36230
|
-
const trackEditorLoad = async () => {
|
|
37510
|
+
const trackEditorLoad = async (licenseKey) => {
|
|
36231
37511
|
try {
|
|
36232
|
-
await backendAPI.post("/api/analytics/editor-load", {});
|
|
37512
|
+
await backendAPI.post("/api/analytics/editor-load", { licenseKey });
|
|
36233
37513
|
} catch {
|
|
36234
37514
|
}
|
|
36235
37515
|
};
|
|
@@ -36312,11 +37592,11 @@ const ConfigurableEditorWithAuth = ({
|
|
|
36312
37592
|
}, [isAuthenticated, error]);
|
|
36313
37593
|
useEffect$1(() => {
|
|
36314
37594
|
console.log("isAuthenticated:", isAuthenticated);
|
|
36315
|
-
if (isAuthenticated && !hasTrackedLoadRef.current) {
|
|
37595
|
+
if (isAuthenticated && !hasTrackedLoadRef.current && apiKey) {
|
|
36316
37596
|
hasTrackedLoadRef.current = true;
|
|
36317
|
-
trackEditorLoad();
|
|
37597
|
+
trackEditorLoad(apiKey);
|
|
36318
37598
|
}
|
|
36319
|
-
}, [isAuthenticated]);
|
|
37599
|
+
}, [isAuthenticated, apiKey]);
|
|
36320
37600
|
if (isLoading) {
|
|
36321
37601
|
return /* @__PURE__ */ jsx(ScopedEditorWrapper, { children: /* @__PURE__ */ jsx(LoadingMessage, { children: /* @__PURE__ */ jsx("span", { children: "Loading editor..." }) }) });
|
|
36322
37602
|
}
|
|
@@ -36375,4 +37655,4 @@ export {
|
|
|
36375
37655
|
useHtmlView as u,
|
|
36376
37656
|
verifyApiKey as v
|
|
36377
37657
|
};
|
|
36378
|
-
//# sourceMappingURL=index-
|
|
37658
|
+
//# sourceMappingURL=index-23abcbd9.js.map
|