ct-rich-text-editor 1.3.19 → 1.3.21
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 +8 -7
- package/dist/{html2pdf.bundle-a30dde70.js → html2pdf.bundle-0b180070.js} +2 -2
- package/dist/{html2pdf.bundle-a30dde70.js.map → html2pdf.bundle-0b180070.js.map} +1 -1
- package/dist/{html2pdf.bundle.min-f1b4a78e.js → html2pdf.bundle.min-08b31c1f.js} +2 -2
- package/dist/{html2pdf.bundle.min-f1b4a78e.js.map → html2pdf.bundle.min-08b31c1f.js.map} +1 -1
- package/dist/{index-23abcbd9.js → index-6360d552.js} +963 -73
- package/dist/index-6360d552.js.map +1 -0
- package/dist/{index-afa4eda8.js → index-68135c09.js} +3 -11
- package/dist/{index-afa4eda8.js.map → index-68135c09.js.map} +1 -1
- package/dist/{index-913b3634.js → index-8bcb5b47.js} +3 -11
- package/dist/{index-913b3634.js.map → index-8bcb5b47.js.map} +1 -1
- package/dist/index.js +2 -10
- package/dist/index.js.map +1 -1
- package/dist/plugins/AndroidKeyboardFixPlugin.d.ts +16 -0
- package/dist/plugins/CodeBlockNormalizerPlugin.d.ts +8 -0
- package/dist/plugins/CodeBlockSelectAllPlugin.d.ts +8 -0
- package/dist/utils/editorStyleConverter.d.ts +1 -0
- package/package.json +1 -1
- package/dist/index-23abcbd9.js.map +0 -1
|
@@ -24,7 +24,7 @@ import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
|
|
|
24
24
|
import { TableNode, TableCellNode, TableRowNode, $createTableNodeWithDimensions, $isTableRowNode, $isTableCellNode, TableCellHeaderStates, $isTableNode, $isTableSelection, $getTableCellNodeFromLexicalNode, $getTableNodeFromLexicalNodeOrThrow, getTableElement, getTableObserverFromTableElement, $getTableRowIndexFromTableCellNode, $getNodeTriplet, $insertTableRow__EXPERIMENTAL, $getTableColumnIndexFromTableCellNode, $insertTableColumn__EXPERIMENTAL, $deleteTableRow__EXPERIMENTAL, $deleteTableColumn__EXPERIMENTAL, $unmergeCell, $computeTableMapSkipCellCheck, getDOMCellFromTarget, $getTableAndElementByKey } from "@lexical/table";
|
|
25
25
|
import { mergeRegister, $wrapNodeInElement, $findMatchingParent, $getNearestNodeOfType, $getNearestBlockElementAncestorOrThrow, $insertNodeToNearestRoot, $isEditorIsNestedEditor, mediaFileReader, isMimeType, calculateZoomLevel, CAN_USE_DOM } from "@lexical/utils";
|
|
26
26
|
import Stack from "@mui/material/Stack";
|
|
27
|
-
import { createCommand, DecoratorNode, createEditor, $applyNodeReplacement, $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,
|
|
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, KEY_DOWN_COMMAND, COMMAND_PRIORITY_CRITICAL, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, $isElementNode, SELECTION_CHANGE_COMMAND, UNDO_COMMAND, REDO_COMMAND, KEY_SPACE_COMMAND, $isLineBreakNode, $createRangeSelection, COMMAND_PRIORITY_HIGH, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, $createNodeSelection, $isNodeSelection, getDOMSelection, CLICK_COMMAND, PASTE_COMMAND, ParagraphNode, $createLineBreakNode, isDOMNode } from "lexical";
|
|
28
28
|
import * as ReactDOM from "react-dom";
|
|
29
29
|
import ReactDOM__default, { createPortal } from "react-dom";
|
|
30
30
|
import { $isCodeNode, CodeNode, normalizeCodeLang, getLanguageFriendlyName, CodeHighlightNode, CODE_LANGUAGE_MAP, $createCodeNode, registerCodeHighlighting, $isCodeHighlightNode } from "@lexical/code";
|
|
@@ -40,15 +40,7 @@ import InsertDriveFileIcon from "@mui/icons-material/InsertDriveFile";
|
|
|
40
40
|
import PictureAsPdfIcon from "@mui/icons-material/PictureAsPdf";
|
|
41
41
|
import { $isDecoratorBlockNode } from "@lexical/react/LexicalDecoratorBlockNode";
|
|
42
42
|
import EmojiPicker from "emoji-picker-react";
|
|
43
|
-
import
|
|
44
|
-
import ContentCopyIcon from "@mui/icons-material/ContentCopy";
|
|
45
|
-
import CropOriginalIcon from "@mui/icons-material/CropOriginal";
|
|
46
|
-
import DeleteIcon from "@mui/icons-material/Delete";
|
|
47
|
-
import FormatAlignCenterIcon from "@mui/icons-material/FormatAlignCenter";
|
|
48
|
-
import FormatAlignLeftIcon from "@mui/icons-material/FormatAlignLeft";
|
|
49
|
-
import FormatAlignRightIcon from "@mui/icons-material/FormatAlignRight";
|
|
50
|
-
import LinkIcon$1 from "@mui/icons-material/Link";
|
|
51
|
-
import OpenInNewIcon from "@mui/icons-material/OpenInNew";
|
|
43
|
+
import { Link as Link$1, CropOriginal, Code as Code$1, FormatAlignLeft, FormatAlignCenter, FormatAlignRight, OpenInNew, Delete, ContentCopy } from "@mui/icons-material";
|
|
52
44
|
import { LinkPlugin as LinkPlugin$1 } from "@lexical/react/LexicalLinkPlugin";
|
|
53
45
|
import { useBasicTypeaheadTriggerMatch, LexicalTypeaheadMenuPlugin, MenuOption } from "@lexical/react/LexicalTypeaheadMenuPlugin";
|
|
54
46
|
import { useLexicalEditable } from "@lexical/react/useLexicalEditable";
|
|
@@ -1479,7 +1471,7 @@ const AiTextTransform = async ({ content, apiKey }) => {
|
|
|
1479
1471
|
const AI_ACTION_COMMAND = createCommand(
|
|
1480
1472
|
"AI_ACTION_COMMAND"
|
|
1481
1473
|
);
|
|
1482
|
-
const ImageView = React__default.lazy(() => import("./index-
|
|
1474
|
+
const ImageView = React__default.lazy(() => import("./index-8bcb5b47.js"));
|
|
1483
1475
|
function isGoogleDocCheckboxImg(img) {
|
|
1484
1476
|
return img.parentElement != null && img.parentElement.tagName === "LI" && img.previousSibling === null && img.getAttribute("aria-roledescription") === "checkbox";
|
|
1485
1477
|
}
|
|
@@ -15345,7 +15337,7 @@ const EmbedComponent = ({ url, displayType, alignment, nodeKey }) => {
|
|
|
15345
15337
|
}
|
|
15346
15338
|
);
|
|
15347
15339
|
};
|
|
15348
|
-
const FileComponent = React$1.lazy(() => import("./index-
|
|
15340
|
+
const FileComponent = React$1.lazy(() => import("./index-68135c09.js"));
|
|
15349
15341
|
function convertFileElement(domNode) {
|
|
15350
15342
|
if (domNode instanceof HTMLDivElement) {
|
|
15351
15343
|
const dataUrl = domNode.getAttribute("data-lexical-file-src");
|
|
@@ -20368,10 +20360,10 @@ const PDF_CONFIG = {
|
|
|
20368
20360
|
};
|
|
20369
20361
|
const loadHtml2Pdf = async () => {
|
|
20370
20362
|
try {
|
|
20371
|
-
const mod = await import("./html2pdf.bundle.min-
|
|
20363
|
+
const mod = await import("./html2pdf.bundle.min-08b31c1f.js").then((n) => n.h);
|
|
20372
20364
|
return (mod == null ? void 0 : mod.default) || mod;
|
|
20373
20365
|
} catch {
|
|
20374
|
-
const mod2 = await import("./html2pdf.bundle-
|
|
20366
|
+
const mod2 = await import("./html2pdf.bundle-0b180070.js").then((n) => n.h);
|
|
20375
20367
|
return (mod2 == null ? void 0 : mod2.default) || mod2;
|
|
20376
20368
|
}
|
|
20377
20369
|
};
|
|
@@ -23614,6 +23606,8 @@ const FontFamilyMenu = ({
|
|
|
23614
23606
|
}) => {
|
|
23615
23607
|
const [selectedFont, setSelectedFont] = useState$1("Arial");
|
|
23616
23608
|
const [detectedFonts, setDetectedFonts] = useState$1(/* @__PURE__ */ new Set());
|
|
23609
|
+
const pendingFontRef = React__default.useRef(null);
|
|
23610
|
+
const userJustSetFontRef = React__default.useRef(false);
|
|
23617
23611
|
const allFonts = useMemo(() => {
|
|
23618
23612
|
const fontSet = new Set(fonts);
|
|
23619
23613
|
detectedFonts.forEach((font) => fontSet.add(font));
|
|
@@ -23630,22 +23624,73 @@ const FontFamilyMenu = ({
|
|
|
23630
23624
|
"Arial"
|
|
23631
23625
|
);
|
|
23632
23626
|
const cleanedFont = fontFamily.replace(/^["']|["']$/g, "").trim();
|
|
23633
|
-
|
|
23634
|
-
|
|
23635
|
-
|
|
23636
|
-
|
|
23637
|
-
|
|
23638
|
-
|
|
23639
|
-
|
|
23640
|
-
|
|
23641
|
-
|
|
23627
|
+
if (userJustSetFontRef.current) {
|
|
23628
|
+
userJustSetFontRef.current = false;
|
|
23629
|
+
return;
|
|
23630
|
+
}
|
|
23631
|
+
if (!selection.isCollapsed() && pendingFontRef.current !== null) {
|
|
23632
|
+
pendingFontRef.current = null;
|
|
23633
|
+
}
|
|
23634
|
+
if (pendingFontRef.current !== null && cleanedFont !== pendingFontRef.current && cleanedFont !== "Arial") {
|
|
23635
|
+
pendingFontRef.current = null;
|
|
23636
|
+
}
|
|
23637
|
+
if (pendingFontRef.current === null) {
|
|
23638
|
+
setSelectedFont(cleanedFont);
|
|
23639
|
+
if (cleanedFont && cleanedFont !== "Arial" && !fonts.includes(cleanedFont)) {
|
|
23640
|
+
setDetectedFonts((prev) => {
|
|
23641
|
+
if (prev.has(cleanedFont))
|
|
23642
|
+
return prev;
|
|
23643
|
+
const newSet = new Set(prev);
|
|
23644
|
+
newSet.add(cleanedFont);
|
|
23645
|
+
return newSet;
|
|
23646
|
+
});
|
|
23647
|
+
}
|
|
23642
23648
|
}
|
|
23643
23649
|
}
|
|
23644
23650
|
});
|
|
23645
23651
|
});
|
|
23646
23652
|
}, [activeEditor, fonts]);
|
|
23653
|
+
useEffect$1(() => {
|
|
23654
|
+
return activeEditor.registerCommand(
|
|
23655
|
+
KEY_DOWN_COMMAND,
|
|
23656
|
+
(event) => {
|
|
23657
|
+
if (pendingFontRef.current !== null && event.key.length === 1 && !event.ctrlKey && !event.metaKey) {
|
|
23658
|
+
const pendingFont = pendingFontRef.current;
|
|
23659
|
+
const selection = $getSelection();
|
|
23660
|
+
if ($isRangeSelection(selection) && selection.isCollapsed()) {
|
|
23661
|
+
$patchStyleText(selection, { "font-family": pendingFont });
|
|
23662
|
+
}
|
|
23663
|
+
}
|
|
23664
|
+
return false;
|
|
23665
|
+
},
|
|
23666
|
+
COMMAND_PRIORITY_CRITICAL
|
|
23667
|
+
);
|
|
23668
|
+
}, [activeEditor]);
|
|
23669
|
+
useEffect$1(() => {
|
|
23670
|
+
const rootElement = activeEditor.getRootElement();
|
|
23671
|
+
if (!rootElement)
|
|
23672
|
+
return;
|
|
23673
|
+
const handleFocus = () => {
|
|
23674
|
+
if (pendingFontRef.current !== null) {
|
|
23675
|
+
const pendingFont = pendingFontRef.current;
|
|
23676
|
+
activeEditor.update(() => {
|
|
23677
|
+
const selection = $getSelection();
|
|
23678
|
+
if ($isRangeSelection(selection) && selection.isCollapsed()) {
|
|
23679
|
+
userJustSetFontRef.current = true;
|
|
23680
|
+
$patchStyleText(selection, { "font-family": pendingFont });
|
|
23681
|
+
}
|
|
23682
|
+
});
|
|
23683
|
+
}
|
|
23684
|
+
};
|
|
23685
|
+
rootElement.addEventListener("focus", handleFocus);
|
|
23686
|
+
return () => {
|
|
23687
|
+
rootElement.removeEventListener("focus", handleFocus);
|
|
23688
|
+
};
|
|
23689
|
+
}, [activeEditor]);
|
|
23647
23690
|
const applyFontFamily = useCallback(
|
|
23648
23691
|
(fontFamily) => {
|
|
23692
|
+
pendingFontRef.current = fontFamily;
|
|
23693
|
+
userJustSetFontRef.current = true;
|
|
23649
23694
|
activeEditor.update(() => {
|
|
23650
23695
|
const selection = $getSelection();
|
|
23651
23696
|
if ($isRangeSelection(selection)) {
|
|
@@ -23659,10 +23704,20 @@ const FontFamilyMenu = ({
|
|
|
23659
23704
|
setSelectedFont(value);
|
|
23660
23705
|
applyFontFamily(value);
|
|
23661
23706
|
};
|
|
23662
|
-
|
|
23663
|
-
|
|
23664
|
-
|
|
23665
|
-
|
|
23707
|
+
const handleMouseDown = (e) => {
|
|
23708
|
+
e.preventDefault();
|
|
23709
|
+
};
|
|
23710
|
+
return /* @__PURE__ */ jsxs(Select, { value: selectedFont, onValueChange: handleFontChange, children: [
|
|
23711
|
+
/* @__PURE__ */ jsx(
|
|
23712
|
+
SelectTrigger,
|
|
23713
|
+
{
|
|
23714
|
+
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",
|
|
23715
|
+
onMouseDown: handleMouseDown,
|
|
23716
|
+
children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select font" })
|
|
23717
|
+
}
|
|
23718
|
+
),
|
|
23719
|
+
/* @__PURE__ */ jsx(SelectContent, { onMouseDown: handleMouseDown, children: allFonts.map((font) => /* @__PURE__ */ jsx(SelectItem, { value: font, style: { fontFamily: font }, onMouseDown: handleMouseDown, children: font }, font)) })
|
|
23720
|
+
] });
|
|
23666
23721
|
};
|
|
23667
23722
|
const MIN_FONT_SIZE = 8;
|
|
23668
23723
|
const MAX_FONT_SIZE = 72;
|
|
@@ -23673,6 +23728,7 @@ const FontSizeControl = () => {
|
|
|
23673
23728
|
const [fontSize, setFontSize] = useState$1(DEFAULT_FONT_SIZE);
|
|
23674
23729
|
const [inputValue, setInputValue] = useState$1(DEFAULT_FONT_SIZE.toString());
|
|
23675
23730
|
const pendingFontSizeRef = React__default.useRef(null);
|
|
23731
|
+
const userJustSetSizeRef = React__default.useRef(false);
|
|
23676
23732
|
useEffect$1(() => {
|
|
23677
23733
|
return editor.registerUpdateListener(({ editorState }) => {
|
|
23678
23734
|
editorState.read(() => {
|
|
@@ -23684,7 +23740,14 @@ const FontSizeControl = () => {
|
|
|
23684
23740
|
`${DEFAULT_FONT_SIZE}px`
|
|
23685
23741
|
);
|
|
23686
23742
|
const size2 = parseInt(fontSizeStr, 10) || DEFAULT_FONT_SIZE;
|
|
23687
|
-
if (
|
|
23743
|
+
if (userJustSetSizeRef.current) {
|
|
23744
|
+
userJustSetSizeRef.current = false;
|
|
23745
|
+
return;
|
|
23746
|
+
}
|
|
23747
|
+
if (!selection.isCollapsed() && pendingFontSizeRef.current !== null) {
|
|
23748
|
+
pendingFontSizeRef.current = null;
|
|
23749
|
+
}
|
|
23750
|
+
if (pendingFontSizeRef.current !== null && size2 !== pendingFontSizeRef.current && size2 !== DEFAULT_FONT_SIZE) {
|
|
23688
23751
|
pendingFontSizeRef.current = null;
|
|
23689
23752
|
}
|
|
23690
23753
|
if (pendingFontSizeRef.current === null) {
|
|
@@ -23695,6 +23758,22 @@ const FontSizeControl = () => {
|
|
|
23695
23758
|
});
|
|
23696
23759
|
});
|
|
23697
23760
|
}, [editor]);
|
|
23761
|
+
useEffect$1(() => {
|
|
23762
|
+
return editor.registerCommand(
|
|
23763
|
+
KEY_DOWN_COMMAND,
|
|
23764
|
+
(event) => {
|
|
23765
|
+
if (pendingFontSizeRef.current !== null && event.key.length === 1 && !event.ctrlKey && !event.metaKey) {
|
|
23766
|
+
const pendingSize = pendingFontSizeRef.current;
|
|
23767
|
+
const selection = $getSelection();
|
|
23768
|
+
if ($isRangeSelection(selection) && selection.isCollapsed()) {
|
|
23769
|
+
$patchStyleText(selection, { "font-size": `${pendingSize}px` });
|
|
23770
|
+
}
|
|
23771
|
+
}
|
|
23772
|
+
return false;
|
|
23773
|
+
},
|
|
23774
|
+
COMMAND_PRIORITY_CRITICAL
|
|
23775
|
+
);
|
|
23776
|
+
}, [editor]);
|
|
23698
23777
|
useEffect$1(() => {
|
|
23699
23778
|
const rootElement = editor.getRootElement();
|
|
23700
23779
|
if (!rootElement)
|
|
@@ -23704,7 +23783,8 @@ const FontSizeControl = () => {
|
|
|
23704
23783
|
const pendingSize = pendingFontSizeRef.current;
|
|
23705
23784
|
editor.update(() => {
|
|
23706
23785
|
const selection = $getSelection();
|
|
23707
|
-
if ($isRangeSelection(selection)) {
|
|
23786
|
+
if ($isRangeSelection(selection) && selection.isCollapsed()) {
|
|
23787
|
+
userJustSetSizeRef.current = true;
|
|
23708
23788
|
$patchStyleText(selection, { "font-size": `${pendingSize}px` });
|
|
23709
23789
|
}
|
|
23710
23790
|
});
|
|
@@ -23718,6 +23798,7 @@ const FontSizeControl = () => {
|
|
|
23718
23798
|
const applyFontSize = useCallback(
|
|
23719
23799
|
(size2) => {
|
|
23720
23800
|
pendingFontSizeRef.current = size2;
|
|
23801
|
+
userJustSetSizeRef.current = true;
|
|
23721
23802
|
editor.update(() => {
|
|
23722
23803
|
const selection = $getSelection();
|
|
23723
23804
|
if ($isRangeSelection(selection)) {
|
|
@@ -23763,6 +23844,9 @@ const FontSizeControl = () => {
|
|
|
23763
23844
|
setInputValue(newSize.toString());
|
|
23764
23845
|
applyFontSize(newSize);
|
|
23765
23846
|
};
|
|
23847
|
+
const handleMouseDown = (e) => {
|
|
23848
|
+
e.preventDefault();
|
|
23849
|
+
};
|
|
23766
23850
|
return /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-1", children: [
|
|
23767
23851
|
/* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
23768
23852
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
@@ -23771,6 +23855,7 @@ const FontSizeControl = () => {
|
|
|
23771
23855
|
variant: "ghost",
|
|
23772
23856
|
size: "icon-sm",
|
|
23773
23857
|
onClick: decreaseFontSize,
|
|
23858
|
+
onMouseDown: handleMouseDown,
|
|
23774
23859
|
className: "cteditor-text-foreground/50",
|
|
23775
23860
|
children: /* @__PURE__ */ jsx(Minus, { className: "!cteditor-size-[18px]" })
|
|
23776
23861
|
}
|
|
@@ -23794,6 +23879,7 @@ const FontSizeControl = () => {
|
|
|
23794
23879
|
variant: "ghost",
|
|
23795
23880
|
size: "icon-sm",
|
|
23796
23881
|
onClick: increaseFontSize,
|
|
23882
|
+
onMouseDown: handleMouseDown,
|
|
23797
23883
|
className: "cteditor-text-foreground/50",
|
|
23798
23884
|
children: /* @__PURE__ */ jsx(Plus, { className: "!cteditor-size-[18px]" })
|
|
23799
23885
|
}
|
|
@@ -26202,6 +26288,15 @@ const Toolbar = ({
|
|
|
26202
26288
|
if ($isRangeSelection(selection))
|
|
26203
26289
|
selection.insertRawText(textContent);
|
|
26204
26290
|
}
|
|
26291
|
+
const newSelection = $getSelection();
|
|
26292
|
+
if ($isRangeSelection(newSelection)) {
|
|
26293
|
+
const anchorNode = newSelection.anchor.getNode();
|
|
26294
|
+
const codeNode = $findMatchingParent(anchorNode, $isCodeNode);
|
|
26295
|
+
if (codeNode) {
|
|
26296
|
+
const paragraphNode = $createParagraphNode();
|
|
26297
|
+
codeNode.insertAfter(paragraphNode);
|
|
26298
|
+
}
|
|
26299
|
+
}
|
|
26205
26300
|
}
|
|
26206
26301
|
});
|
|
26207
26302
|
}, [editor]);
|
|
@@ -27369,6 +27464,196 @@ const Toolbar = ({
|
|
|
27369
27464
|
)
|
|
27370
27465
|
] });
|
|
27371
27466
|
};
|
|
27467
|
+
const IS_ANDROID = typeof navigator !== "undefined" && /Android/i.test(navigator.userAgent);
|
|
27468
|
+
function AndroidKeyboardFixPlugin() {
|
|
27469
|
+
const [editor] = useLexicalComposerContext();
|
|
27470
|
+
useEffect$1(() => {
|
|
27471
|
+
if (!IS_ANDROID) {
|
|
27472
|
+
return;
|
|
27473
|
+
}
|
|
27474
|
+
const rootElement = editor.getRootElement();
|
|
27475
|
+
if (!rootElement) {
|
|
27476
|
+
return;
|
|
27477
|
+
}
|
|
27478
|
+
let compositionEndTimer = null;
|
|
27479
|
+
let lastCompositionEndTime = 0;
|
|
27480
|
+
let pendingSpaceInsertion = false;
|
|
27481
|
+
const handleCompositionStart = () => {
|
|
27482
|
+
if (compositionEndTimer) {
|
|
27483
|
+
clearTimeout(compositionEndTimer);
|
|
27484
|
+
compositionEndTimer = null;
|
|
27485
|
+
}
|
|
27486
|
+
pendingSpaceInsertion = false;
|
|
27487
|
+
};
|
|
27488
|
+
const handleCompositionEnd = () => {
|
|
27489
|
+
lastCompositionEndTime = Date.now();
|
|
27490
|
+
compositionEndTimer = setTimeout(() => {
|
|
27491
|
+
compositionEndTimer = null;
|
|
27492
|
+
}, 150);
|
|
27493
|
+
};
|
|
27494
|
+
const handleBeforeInput = (event) => {
|
|
27495
|
+
var _a;
|
|
27496
|
+
const timeSinceCompositionEnd = Date.now() - lastCompositionEndTime;
|
|
27497
|
+
if (event.inputType === "insertText" && event.data === " " && timeSinceCompositionEnd < 200) {
|
|
27498
|
+
pendingSpaceInsertion = true;
|
|
27499
|
+
event.preventDefault();
|
|
27500
|
+
requestAnimationFrame(() => {
|
|
27501
|
+
editor.update(
|
|
27502
|
+
() => {
|
|
27503
|
+
const selection = $getSelection();
|
|
27504
|
+
if ($isRangeSelection(selection)) {
|
|
27505
|
+
selection.insertText(" ");
|
|
27506
|
+
}
|
|
27507
|
+
},
|
|
27508
|
+
{ discrete: true }
|
|
27509
|
+
);
|
|
27510
|
+
pendingSpaceInsertion = false;
|
|
27511
|
+
});
|
|
27512
|
+
return;
|
|
27513
|
+
}
|
|
27514
|
+
if (event.inputType === "insertCompositionText" && ((_a = event.data) == null ? void 0 : _a.endsWith(" "))) {
|
|
27515
|
+
const timeSince = Date.now() - lastCompositionEndTime;
|
|
27516
|
+
if (timeSince < 50) {
|
|
27517
|
+
return;
|
|
27518
|
+
}
|
|
27519
|
+
}
|
|
27520
|
+
};
|
|
27521
|
+
const unregisterSpaceCommand = editor.registerCommand(
|
|
27522
|
+
KEY_SPACE_COMMAND,
|
|
27523
|
+
(event) => {
|
|
27524
|
+
const timeSinceCompositionEnd = Date.now() - lastCompositionEndTime;
|
|
27525
|
+
if (timeSinceCompositionEnd < 200 && !pendingSpaceInsertion) {
|
|
27526
|
+
event.preventDefault();
|
|
27527
|
+
requestAnimationFrame(() => {
|
|
27528
|
+
editor.update(
|
|
27529
|
+
() => {
|
|
27530
|
+
const selection = $getSelection();
|
|
27531
|
+
if ($isRangeSelection(selection)) {
|
|
27532
|
+
selection.insertText(" ");
|
|
27533
|
+
}
|
|
27534
|
+
},
|
|
27535
|
+
{ discrete: true }
|
|
27536
|
+
);
|
|
27537
|
+
});
|
|
27538
|
+
return true;
|
|
27539
|
+
}
|
|
27540
|
+
return false;
|
|
27541
|
+
},
|
|
27542
|
+
COMMAND_PRIORITY_CRITICAL
|
|
27543
|
+
);
|
|
27544
|
+
rootElement.addEventListener("compositionstart", handleCompositionStart);
|
|
27545
|
+
rootElement.addEventListener("compositionend", handleCompositionEnd);
|
|
27546
|
+
rootElement.addEventListener("beforeinput", handleBeforeInput);
|
|
27547
|
+
return () => {
|
|
27548
|
+
rootElement.removeEventListener(
|
|
27549
|
+
"compositionstart",
|
|
27550
|
+
handleCompositionStart
|
|
27551
|
+
);
|
|
27552
|
+
rootElement.removeEventListener("compositionend", handleCompositionEnd);
|
|
27553
|
+
rootElement.removeEventListener("beforeinput", handleBeforeInput);
|
|
27554
|
+
unregisterSpaceCommand();
|
|
27555
|
+
if (compositionEndTimer) {
|
|
27556
|
+
clearTimeout(compositionEndTimer);
|
|
27557
|
+
}
|
|
27558
|
+
};
|
|
27559
|
+
}, [editor]);
|
|
27560
|
+
return null;
|
|
27561
|
+
}
|
|
27562
|
+
function normalizeCodeNodeLineBreaks(codeNode) {
|
|
27563
|
+
const children = codeNode.getChildren();
|
|
27564
|
+
const nodesToRemove = [];
|
|
27565
|
+
for (let i2 = 0; i2 < children.length - 1; i2++) {
|
|
27566
|
+
const current = children[i2];
|
|
27567
|
+
const next = children[i2 + 1];
|
|
27568
|
+
if ($isLineBreakNode(current) && $isLineBreakNode(next)) {
|
|
27569
|
+
nodesToRemove.push(next.getKey());
|
|
27570
|
+
}
|
|
27571
|
+
}
|
|
27572
|
+
nodesToRemove.forEach((key) => {
|
|
27573
|
+
const node = $getNodeByKey(key);
|
|
27574
|
+
if (node) {
|
|
27575
|
+
node.remove();
|
|
27576
|
+
}
|
|
27577
|
+
});
|
|
27578
|
+
}
|
|
27579
|
+
function CodeBlockNormalizerPlugin() {
|
|
27580
|
+
const [editor] = useLexicalComposerContext();
|
|
27581
|
+
useEffect$1(() => {
|
|
27582
|
+
const unregisterMutation = editor.registerMutationListener(
|
|
27583
|
+
CodeNode,
|
|
27584
|
+
(mutations) => {
|
|
27585
|
+
requestAnimationFrame(() => {
|
|
27586
|
+
editor.update(() => {
|
|
27587
|
+
for (const [nodeKey, mutation] of mutations) {
|
|
27588
|
+
if (mutation === "created" || mutation === "updated") {
|
|
27589
|
+
const node = $getNodeByKey(nodeKey);
|
|
27590
|
+
if ($isCodeNode(node)) {
|
|
27591
|
+
normalizeCodeNodeLineBreaks(node);
|
|
27592
|
+
}
|
|
27593
|
+
}
|
|
27594
|
+
}
|
|
27595
|
+
});
|
|
27596
|
+
});
|
|
27597
|
+
}
|
|
27598
|
+
);
|
|
27599
|
+
return () => {
|
|
27600
|
+
unregisterMutation();
|
|
27601
|
+
};
|
|
27602
|
+
}, [editor]);
|
|
27603
|
+
return null;
|
|
27604
|
+
}
|
|
27605
|
+
function CodeBlockSelectAllPlugin() {
|
|
27606
|
+
const [editor] = useLexicalComposerContext();
|
|
27607
|
+
useEffect$1(() => {
|
|
27608
|
+
const unregister = editor.registerCommand(
|
|
27609
|
+
KEY_DOWN_COMMAND,
|
|
27610
|
+
(event) => {
|
|
27611
|
+
const isSelectAll = (event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "a" && !event.shiftKey && !event.altKey;
|
|
27612
|
+
if (!isSelectAll) {
|
|
27613
|
+
return false;
|
|
27614
|
+
}
|
|
27615
|
+
let codeNode = null;
|
|
27616
|
+
editor.getEditorState().read(() => {
|
|
27617
|
+
const selection = $getSelection();
|
|
27618
|
+
if ($isRangeSelection(selection)) {
|
|
27619
|
+
const anchorNode = selection.anchor.getNode();
|
|
27620
|
+
let currentNode = anchorNode;
|
|
27621
|
+
while (currentNode) {
|
|
27622
|
+
if ($isCodeNode(currentNode)) {
|
|
27623
|
+
codeNode = currentNode;
|
|
27624
|
+
break;
|
|
27625
|
+
}
|
|
27626
|
+
currentNode = currentNode.getParent();
|
|
27627
|
+
}
|
|
27628
|
+
}
|
|
27629
|
+
});
|
|
27630
|
+
if (!codeNode) {
|
|
27631
|
+
return false;
|
|
27632
|
+
}
|
|
27633
|
+
event.preventDefault();
|
|
27634
|
+
editor.update(() => {
|
|
27635
|
+
const code = codeNode;
|
|
27636
|
+
const children = code.getChildren();
|
|
27637
|
+
const childrenCount = children.length;
|
|
27638
|
+
if (childrenCount === 0) {
|
|
27639
|
+
code.select(0, 0);
|
|
27640
|
+
return;
|
|
27641
|
+
}
|
|
27642
|
+
const rangeSelection = $createRangeSelection();
|
|
27643
|
+
rangeSelection.anchor.set(code.getKey(), 0, "element");
|
|
27644
|
+
rangeSelection.focus.set(code.getKey(), childrenCount, "element");
|
|
27645
|
+
$setSelection(rangeSelection);
|
|
27646
|
+
});
|
|
27647
|
+
return true;
|
|
27648
|
+
},
|
|
27649
|
+
COMMAND_PRIORITY_HIGH
|
|
27650
|
+
);
|
|
27651
|
+
return () => {
|
|
27652
|
+
unregister();
|
|
27653
|
+
};
|
|
27654
|
+
}, [editor]);
|
|
27655
|
+
return null;
|
|
27656
|
+
}
|
|
27372
27657
|
const CodeHighlightPlugin = () => {
|
|
27373
27658
|
const [editor] = useLexicalComposerContext();
|
|
27374
27659
|
useEffect$1(() => {
|
|
@@ -27510,6 +27795,9 @@ const extractTextWithMap = (editorState) => {
|
|
|
27510
27795
|
editorState.read(() => {
|
|
27511
27796
|
const root2 = $getRoot();
|
|
27512
27797
|
const traverse = (node) => {
|
|
27798
|
+
if ($isCodeNode(node)) {
|
|
27799
|
+
return;
|
|
27800
|
+
}
|
|
27513
27801
|
if ($isTextNode(node)) {
|
|
27514
27802
|
const text = node.getTextContent();
|
|
27515
27803
|
const start = fullText.length;
|
|
@@ -29172,7 +29460,7 @@ function FloatingEmbedMenu({
|
|
|
29172
29460
|
handleDisplayTypeChange("url");
|
|
29173
29461
|
},
|
|
29174
29462
|
title: "URL",
|
|
29175
|
-
children: /* @__PURE__ */ jsx(
|
|
29463
|
+
children: /* @__PURE__ */ jsx(Link$1, { fontSize: "small" })
|
|
29176
29464
|
}
|
|
29177
29465
|
),
|
|
29178
29466
|
/* @__PURE__ */ jsx(
|
|
@@ -29184,7 +29472,7 @@ function FloatingEmbedMenu({
|
|
|
29184
29472
|
handleDisplayTypeChange("card");
|
|
29185
29473
|
},
|
|
29186
29474
|
title: "Card",
|
|
29187
|
-
children: /* @__PURE__ */ jsx(
|
|
29475
|
+
children: /* @__PURE__ */ jsx(CropOriginal, { fontSize: "small" })
|
|
29188
29476
|
}
|
|
29189
29477
|
),
|
|
29190
29478
|
/* @__PURE__ */ jsx(
|
|
@@ -29196,7 +29484,7 @@ function FloatingEmbedMenu({
|
|
|
29196
29484
|
handleDisplayTypeChange("embed");
|
|
29197
29485
|
},
|
|
29198
29486
|
title: "Embedded",
|
|
29199
|
-
children: /* @__PURE__ */ jsx(
|
|
29487
|
+
children: /* @__PURE__ */ jsx(Code$1, { fontSize: "small" })
|
|
29200
29488
|
}
|
|
29201
29489
|
)
|
|
29202
29490
|
] }) }),
|
|
@@ -29211,7 +29499,7 @@ function FloatingEmbedMenu({
|
|
|
29211
29499
|
handleAlignmentChange("left");
|
|
29212
29500
|
},
|
|
29213
29501
|
title: "Left",
|
|
29214
|
-
children: /* @__PURE__ */ jsx(
|
|
29502
|
+
children: /* @__PURE__ */ jsx(FormatAlignLeft, { fontSize: "small" })
|
|
29215
29503
|
}
|
|
29216
29504
|
),
|
|
29217
29505
|
/* @__PURE__ */ jsx(
|
|
@@ -29223,7 +29511,7 @@ function FloatingEmbedMenu({
|
|
|
29223
29511
|
handleAlignmentChange("center");
|
|
29224
29512
|
},
|
|
29225
29513
|
title: "Center",
|
|
29226
|
-
children: /* @__PURE__ */ jsx(
|
|
29514
|
+
children: /* @__PURE__ */ jsx(FormatAlignCenter, { fontSize: "small" })
|
|
29227
29515
|
}
|
|
29228
29516
|
),
|
|
29229
29517
|
/* @__PURE__ */ jsx(
|
|
@@ -29235,7 +29523,7 @@ function FloatingEmbedMenu({
|
|
|
29235
29523
|
handleAlignmentChange("right");
|
|
29236
29524
|
},
|
|
29237
29525
|
title: "Right",
|
|
29238
|
-
children: /* @__PURE__ */ jsx(
|
|
29526
|
+
children: /* @__PURE__ */ jsx(FormatAlignRight, { fontSize: "small" })
|
|
29239
29527
|
}
|
|
29240
29528
|
)
|
|
29241
29529
|
] }) }),
|
|
@@ -29247,7 +29535,7 @@ function FloatingEmbedMenu({
|
|
|
29247
29535
|
className: "embed-menu-button",
|
|
29248
29536
|
onClick: handleOpenInNewTab,
|
|
29249
29537
|
title: "Open in new tab",
|
|
29250
|
-
children: /* @__PURE__ */ jsx(
|
|
29538
|
+
children: /* @__PURE__ */ jsx(OpenInNew, { fontSize: "small" })
|
|
29251
29539
|
}
|
|
29252
29540
|
),
|
|
29253
29541
|
/* @__PURE__ */ jsx(
|
|
@@ -29256,7 +29544,7 @@ function FloatingEmbedMenu({
|
|
|
29256
29544
|
className: "embed-menu-button",
|
|
29257
29545
|
onClick: handleRemoveEmbed,
|
|
29258
29546
|
title: "Remove",
|
|
29259
|
-
children: /* @__PURE__ */ jsx(
|
|
29547
|
+
children: /* @__PURE__ */ jsx(Delete, { fontSize: "small" })
|
|
29260
29548
|
}
|
|
29261
29549
|
),
|
|
29262
29550
|
/* @__PURE__ */ jsx(
|
|
@@ -29265,7 +29553,7 @@ function FloatingEmbedMenu({
|
|
|
29265
29553
|
className: "embed-menu-button",
|
|
29266
29554
|
onClick: handleCopyUrl,
|
|
29267
29555
|
title: "Copy",
|
|
29268
|
-
children: /* @__PURE__ */ jsx(
|
|
29556
|
+
children: /* @__PURE__ */ jsx(ContentCopy, { fontSize: "small" })
|
|
29269
29557
|
}
|
|
29270
29558
|
)
|
|
29271
29559
|
] }) })
|
|
@@ -30518,6 +30806,15 @@ function TextFormatFloatingToolbar({
|
|
|
30518
30806
|
if ($isRangeSelection(selection))
|
|
30519
30807
|
selection.insertRawText(textContent);
|
|
30520
30808
|
}
|
|
30809
|
+
const newSelection = $getSelection();
|
|
30810
|
+
if ($isRangeSelection(newSelection)) {
|
|
30811
|
+
const anchorNode = newSelection.anchor.getNode();
|
|
30812
|
+
const codeNode = $findMatchingParent(anchorNode, $isCodeNode);
|
|
30813
|
+
if (codeNode) {
|
|
30814
|
+
const paragraphNode = $createParagraphNode();
|
|
30815
|
+
codeNode.insertAfter(paragraphNode);
|
|
30816
|
+
}
|
|
30817
|
+
}
|
|
30521
30818
|
}
|
|
30522
30819
|
});
|
|
30523
30820
|
}, [editor]);
|
|
@@ -31684,6 +31981,94 @@ const IS_CODE = 16;
|
|
|
31684
31981
|
const IS_SUBSCRIPT = 32;
|
|
31685
31982
|
const IS_SUPERSCRIPT = 64;
|
|
31686
31983
|
const IS_HIGHLIGHT = 128;
|
|
31984
|
+
function parseColor(color) {
|
|
31985
|
+
if (!color)
|
|
31986
|
+
return null;
|
|
31987
|
+
color = color.trim().toLowerCase();
|
|
31988
|
+
if (color.startsWith("#")) {
|
|
31989
|
+
let hex = color.slice(1);
|
|
31990
|
+
if (hex.length === 3) {
|
|
31991
|
+
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
|
|
31992
|
+
}
|
|
31993
|
+
if (hex.length === 6) {
|
|
31994
|
+
return {
|
|
31995
|
+
r: parseInt(hex.slice(0, 2), 16),
|
|
31996
|
+
g: parseInt(hex.slice(2, 4), 16),
|
|
31997
|
+
b: parseInt(hex.slice(4, 6), 16)
|
|
31998
|
+
};
|
|
31999
|
+
}
|
|
32000
|
+
}
|
|
32001
|
+
const rgbMatch = color.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/);
|
|
32002
|
+
if (rgbMatch) {
|
|
32003
|
+
return {
|
|
32004
|
+
r: parseInt(rgbMatch[1]),
|
|
32005
|
+
g: parseInt(rgbMatch[2]),
|
|
32006
|
+
b: parseInt(rgbMatch[3])
|
|
32007
|
+
};
|
|
32008
|
+
}
|
|
32009
|
+
const namedColors = {
|
|
32010
|
+
white: { r: 255, g: 255, b: 255 },
|
|
32011
|
+
black: { r: 0, g: 0, b: 0 },
|
|
32012
|
+
red: { r: 255, g: 0, b: 0 },
|
|
32013
|
+
green: { r: 0, g: 128, b: 0 },
|
|
32014
|
+
blue: { r: 0, g: 0, b: 255 },
|
|
32015
|
+
yellow: { r: 255, g: 255, b: 0 },
|
|
32016
|
+
transparent: { r: 0, g: 0, b: 0 }
|
|
32017
|
+
// Will be handled separately
|
|
32018
|
+
};
|
|
32019
|
+
return namedColors[color] || null;
|
|
32020
|
+
}
|
|
32021
|
+
function getLuminance(r2, g2, b2) {
|
|
32022
|
+
const sR = r2 / 255;
|
|
32023
|
+
const sG = g2 / 255;
|
|
32024
|
+
const sB = b2 / 255;
|
|
32025
|
+
const R = sR <= 0.03928 ? sR / 12.92 : Math.pow((sR + 0.055) / 1.055, 2.4);
|
|
32026
|
+
const G = sG <= 0.03928 ? sG / 12.92 : Math.pow((sG + 0.055) / 1.055, 2.4);
|
|
32027
|
+
const B = sB <= 0.03928 ? sB / 12.92 : Math.pow((sB + 0.055) / 1.055, 2.4);
|
|
32028
|
+
return 0.2126 * R + 0.7152 * G + 0.0722 * B;
|
|
32029
|
+
}
|
|
32030
|
+
function isLightColor(color) {
|
|
32031
|
+
const parsed = parseColor(color);
|
|
32032
|
+
if (!parsed)
|
|
32033
|
+
return null;
|
|
32034
|
+
return getLuminance(parsed.r, parsed.g, parsed.b) > 0.5;
|
|
32035
|
+
}
|
|
32036
|
+
function getEditorBackgroundColor(editor) {
|
|
32037
|
+
const rootElement = editor.getRootElement();
|
|
32038
|
+
if (!rootElement)
|
|
32039
|
+
return null;
|
|
32040
|
+
try {
|
|
32041
|
+
const computedStyle = window.getComputedStyle(rootElement);
|
|
32042
|
+
const bgColor = computedStyle.backgroundColor;
|
|
32043
|
+
if (bgColor === "transparent" || bgColor === "rgba(0, 0, 0, 0)") {
|
|
32044
|
+
let parent = rootElement.parentElement;
|
|
32045
|
+
while (parent) {
|
|
32046
|
+
const parentBg = window.getComputedStyle(parent).backgroundColor;
|
|
32047
|
+
if (parentBg && parentBg !== "transparent" && parentBg !== "rgba(0, 0, 0, 0)") {
|
|
32048
|
+
return parentBg;
|
|
32049
|
+
}
|
|
32050
|
+
parent = parent.parentElement;
|
|
32051
|
+
}
|
|
32052
|
+
return "rgb(255, 255, 255)";
|
|
32053
|
+
}
|
|
32054
|
+
return bgColor;
|
|
32055
|
+
} catch {
|
|
32056
|
+
return null;
|
|
32057
|
+
}
|
|
32058
|
+
}
|
|
32059
|
+
function isEditorDarkMode(editor) {
|
|
32060
|
+
const bgColor = getEditorBackgroundColor(editor);
|
|
32061
|
+
if (!bgColor)
|
|
32062
|
+
return false;
|
|
32063
|
+
const isLight = isLightColor(bgColor);
|
|
32064
|
+
return isLight === false;
|
|
32065
|
+
}
|
|
32066
|
+
function adjustColorsForTheme(styleInfo) {
|
|
32067
|
+
const adjusted = { ...styleInfo };
|
|
32068
|
+
adjusted.backgroundColor = "";
|
|
32069
|
+
adjusted.color = "";
|
|
32070
|
+
return adjusted;
|
|
32071
|
+
}
|
|
31687
32072
|
function detectCKEditorSource(html) {
|
|
31688
32073
|
return html.includes('class="image"') || // CKEditor's figure class for images
|
|
31689
32074
|
html.includes('class="image ') || html.includes("image-style-") || // CKEditor's image alignment classes
|
|
@@ -31875,7 +32260,8 @@ function buildStyleString(info) {
|
|
|
31875
32260
|
}
|
|
31876
32261
|
function createStyledTextNode(text, parentElement) {
|
|
31877
32262
|
const textNode = $createTextNode(text);
|
|
31878
|
-
|
|
32263
|
+
let styleInfo = getStyleInfoFromElement(parentElement);
|
|
32264
|
+
styleInfo = adjustColorsForTheme(styleInfo);
|
|
31879
32265
|
if (styleInfo.format) {
|
|
31880
32266
|
textNode.setFormat(styleInfo.format);
|
|
31881
32267
|
}
|
|
@@ -32149,7 +32535,8 @@ function processChildrenWithStyle(element, parentNode, defaultStyles) {
|
|
|
32149
32535
|
if (hasNonWhitespace || isSignificantWhitespace) {
|
|
32150
32536
|
const normalizedText = text.replace(/\s+/g, " ");
|
|
32151
32537
|
const textNode = $createTextNode(normalizedText);
|
|
32152
|
-
|
|
32538
|
+
let styleInfo = getStyleInfoFromElement(element);
|
|
32539
|
+
styleInfo = adjustColorsForTheme(styleInfo);
|
|
32153
32540
|
if (styleInfo.format) {
|
|
32154
32541
|
textNode.setFormat(styleInfo.format);
|
|
32155
32542
|
}
|
|
@@ -32263,6 +32650,11 @@ function convertHTMLToNodesWithStyles(html, editor) {
|
|
|
32263
32650
|
currentPasteContext = {
|
|
32264
32651
|
isCKEditor
|
|
32265
32652
|
};
|
|
32653
|
+
const editorBgColor = getEditorBackgroundColor(editor);
|
|
32654
|
+
({
|
|
32655
|
+
editorIsDark: isEditorDarkMode(editor),
|
|
32656
|
+
editorBgColor
|
|
32657
|
+
});
|
|
32266
32658
|
const { container, cleanup } = createStyledDocument(html);
|
|
32267
32659
|
try {
|
|
32268
32660
|
const customNodes = processNode(container, null);
|
|
@@ -32326,6 +32718,61 @@ function RichTextPastePlugin() {
|
|
|
32326
32718
|
const htmlContent = clipboardData.getData("text/html");
|
|
32327
32719
|
const plainText = clipboardData.getData("text/plain");
|
|
32328
32720
|
if (htmlContent) {
|
|
32721
|
+
let isInsideCodeBlock = false;
|
|
32722
|
+
editor.getEditorState().read(() => {
|
|
32723
|
+
const selection = $getSelection();
|
|
32724
|
+
if ($isRangeSelection(selection)) {
|
|
32725
|
+
const anchorNode = selection.anchor.getNode();
|
|
32726
|
+
let currentNode = anchorNode;
|
|
32727
|
+
while (currentNode) {
|
|
32728
|
+
if ($isCodeNode(currentNode)) {
|
|
32729
|
+
isInsideCodeBlock = true;
|
|
32730
|
+
break;
|
|
32731
|
+
}
|
|
32732
|
+
currentNode = currentNode.getParent();
|
|
32733
|
+
}
|
|
32734
|
+
}
|
|
32735
|
+
});
|
|
32736
|
+
if (isInsideCodeBlock) {
|
|
32737
|
+
if (plainText) {
|
|
32738
|
+
event.preventDefault();
|
|
32739
|
+
queueMicrotask(() => {
|
|
32740
|
+
editor.update(
|
|
32741
|
+
() => {
|
|
32742
|
+
const selection = $getSelection();
|
|
32743
|
+
if ($isRangeSelection(selection)) {
|
|
32744
|
+
selection.insertRawText(plainText);
|
|
32745
|
+
}
|
|
32746
|
+
},
|
|
32747
|
+
{
|
|
32748
|
+
tag: "paste"
|
|
32749
|
+
}
|
|
32750
|
+
);
|
|
32751
|
+
queueMicrotask(() => {
|
|
32752
|
+
editor.update(
|
|
32753
|
+
() => {
|
|
32754
|
+
const selection = $getSelection();
|
|
32755
|
+
if ($isRangeSelection(selection)) {
|
|
32756
|
+
let currentNode = selection.anchor.getNode();
|
|
32757
|
+
while (currentNode) {
|
|
32758
|
+
if ($isCodeNode(currentNode)) {
|
|
32759
|
+
currentNode.selectEnd();
|
|
32760
|
+
break;
|
|
32761
|
+
}
|
|
32762
|
+
currentNode = currentNode.getParent();
|
|
32763
|
+
}
|
|
32764
|
+
}
|
|
32765
|
+
},
|
|
32766
|
+
{
|
|
32767
|
+
tag: "history-merge"
|
|
32768
|
+
}
|
|
32769
|
+
);
|
|
32770
|
+
});
|
|
32771
|
+
});
|
|
32772
|
+
return true;
|
|
32773
|
+
}
|
|
32774
|
+
return false;
|
|
32775
|
+
}
|
|
32329
32776
|
event.preventDefault();
|
|
32330
32777
|
editor.update(
|
|
32331
32778
|
() => {
|
|
@@ -32560,7 +33007,10 @@ function SlashCommandPlugin() {
|
|
|
32560
33007
|
makeBlock(() => {
|
|
32561
33008
|
const selection = $getSelection();
|
|
32562
33009
|
if ($isRangeSelection(selection)) {
|
|
32563
|
-
|
|
33010
|
+
const codeNode = $createCodeNode();
|
|
33011
|
+
selection.insertNodes([codeNode]);
|
|
33012
|
+
const paragraphNode = $createParagraphNode();
|
|
33013
|
+
codeNode.insertAfter(paragraphNode);
|
|
32564
33014
|
}
|
|
32565
33015
|
});
|
|
32566
33016
|
}, [makeBlock]);
|
|
@@ -36479,11 +36929,96 @@ const WordCountPlugin = () => {
|
|
|
36479
36929
|
}
|
|
36480
36930
|
);
|
|
36481
36931
|
};
|
|
36932
|
+
function getEditorColors(rootElement) {
|
|
36933
|
+
try {
|
|
36934
|
+
const computedStyle = window.getComputedStyle(rootElement);
|
|
36935
|
+
let bgColor = computedStyle.backgroundColor;
|
|
36936
|
+
let textColor = computedStyle.color;
|
|
36937
|
+
if (bgColor === "transparent" || bgColor === "rgba(0, 0, 0, 0)") {
|
|
36938
|
+
let parent = rootElement.parentElement;
|
|
36939
|
+
while (parent) {
|
|
36940
|
+
const parentBg = window.getComputedStyle(parent).backgroundColor;
|
|
36941
|
+
if (parentBg && parentBg !== "transparent" && parentBg !== "rgba(0, 0, 0, 0)") {
|
|
36942
|
+
bgColor = parentBg;
|
|
36943
|
+
break;
|
|
36944
|
+
}
|
|
36945
|
+
parent = parent.parentElement;
|
|
36946
|
+
}
|
|
36947
|
+
if (bgColor === "transparent" || bgColor === "rgba(0, 0, 0, 0)") {
|
|
36948
|
+
bgColor = "rgb(255, 255, 255)";
|
|
36949
|
+
}
|
|
36950
|
+
}
|
|
36951
|
+
if (!textColor || textColor === "rgba(0, 0, 0, 0)") {
|
|
36952
|
+
textColor = "rgb(0, 0, 0)";
|
|
36953
|
+
}
|
|
36954
|
+
return { bgColor, textColor };
|
|
36955
|
+
} catch {
|
|
36956
|
+
return { bgColor: "rgb(255, 255, 255)", textColor: "rgb(0, 0, 0)" };
|
|
36957
|
+
}
|
|
36958
|
+
}
|
|
36482
36959
|
function exportEditorWithInlineStyle(editor) {
|
|
36483
36960
|
const rootElement = editor.getRootElement();
|
|
36484
36961
|
if (!rootElement)
|
|
36485
36962
|
return "";
|
|
36963
|
+
const { bgColor, textColor } = getEditorColors(rootElement);
|
|
36486
36964
|
const tableStyleMap = /* @__PURE__ */ new Map();
|
|
36965
|
+
const codeBlockStyles = {
|
|
36966
|
+
backgroundColor: "",
|
|
36967
|
+
textColor: "",
|
|
36968
|
+
gutterBackgroundColor: "",
|
|
36969
|
+
gutterTextColor: "",
|
|
36970
|
+
fontFamily: "Menlo, Consolas, Monaco, monospace",
|
|
36971
|
+
fontSize: "13px",
|
|
36972
|
+
lineHeight: "1.53",
|
|
36973
|
+
tokenColors: /* @__PURE__ */ new Map(),
|
|
36974
|
+
spanColors: /* @__PURE__ */ new Map()
|
|
36975
|
+
};
|
|
36976
|
+
const liveCodeBlocks = rootElement.querySelectorAll("code");
|
|
36977
|
+
if (liveCodeBlocks.length > 0) {
|
|
36978
|
+
liveCodeBlocks.forEach((codeBlock, codeBlockIndex) => {
|
|
36979
|
+
const htmlCodeBlock = codeBlock;
|
|
36980
|
+
if (codeBlockIndex === 0) {
|
|
36981
|
+
const computedStyle = window.getComputedStyle(htmlCodeBlock);
|
|
36982
|
+
codeBlockStyles.backgroundColor = computedStyle.backgroundColor;
|
|
36983
|
+
codeBlockStyles.textColor = computedStyle.color;
|
|
36984
|
+
codeBlockStyles.fontFamily = computedStyle.fontFamily;
|
|
36985
|
+
codeBlockStyles.fontSize = computedStyle.fontSize;
|
|
36986
|
+
codeBlockStyles.lineHeight = computedStyle.lineHeight;
|
|
36987
|
+
const gutterBgColor = window.getComputedStyle(htmlCodeBlock, "::before").backgroundColor;
|
|
36988
|
+
const gutterColor = window.getComputedStyle(htmlCodeBlock, "::before").color;
|
|
36989
|
+
codeBlockStyles.gutterBackgroundColor = gutterBgColor;
|
|
36990
|
+
codeBlockStyles.gutterTextColor = gutterColor;
|
|
36991
|
+
}
|
|
36992
|
+
const spanColorArray = [];
|
|
36993
|
+
const spans = htmlCodeBlock.querySelectorAll("span");
|
|
36994
|
+
spans.forEach((span) => {
|
|
36995
|
+
const htmlSpan = span;
|
|
36996
|
+
const spanComputedStyle = window.getComputedStyle(htmlSpan);
|
|
36997
|
+
const color = spanComputedStyle.color;
|
|
36998
|
+
const text = htmlSpan.textContent || "";
|
|
36999
|
+
spanColorArray.push({ text, color });
|
|
37000
|
+
});
|
|
37001
|
+
codeBlockStyles.spanColors.set(codeBlockIndex, spanColorArray);
|
|
37002
|
+
});
|
|
37003
|
+
const firstCodeBlock = liveCodeBlocks[0];
|
|
37004
|
+
const tokenClasses = [
|
|
37005
|
+
"PlaygroundEditorTheme__tokenComment",
|
|
37006
|
+
"PlaygroundEditorTheme__tokenPunctuation",
|
|
37007
|
+
"PlaygroundEditorTheme__tokenProperty",
|
|
37008
|
+
"PlaygroundEditorTheme__tokenSelector",
|
|
37009
|
+
"PlaygroundEditorTheme__tokenOperator",
|
|
37010
|
+
"PlaygroundEditorTheme__tokenAttr",
|
|
37011
|
+
"PlaygroundEditorTheme__tokenVariable",
|
|
37012
|
+
"PlaygroundEditorTheme__tokenFunction"
|
|
37013
|
+
];
|
|
37014
|
+
tokenClasses.forEach((tokenClass) => {
|
|
37015
|
+
const tokenSpan = firstCodeBlock.querySelector(`.${tokenClass}`);
|
|
37016
|
+
if (tokenSpan) {
|
|
37017
|
+
const tokenComputedStyle = window.getComputedStyle(tokenSpan);
|
|
37018
|
+
codeBlockStyles.tokenColors.set(tokenClass, tokenComputedStyle.color);
|
|
37019
|
+
}
|
|
37020
|
+
});
|
|
37021
|
+
}
|
|
36487
37022
|
const liveTables = rootElement.querySelectorAll("table");
|
|
36488
37023
|
liveTables.forEach((table, index2) => {
|
|
36489
37024
|
const colors = detectTableColorsFromVariables(table);
|
|
@@ -36493,9 +37028,9 @@ function exportEditorWithInlineStyle(editor) {
|
|
|
36493
37028
|
const headerBgColors = [];
|
|
36494
37029
|
headerCells.forEach((th) => {
|
|
36495
37030
|
const computed = window.getComputedStyle(th);
|
|
36496
|
-
const
|
|
36497
|
-
if (
|
|
36498
|
-
headerBgColors.push(
|
|
37031
|
+
const bgColor2 = computed.backgroundColor;
|
|
37032
|
+
if (bgColor2 && bgColor2 !== "rgba(0, 0, 0, 0)") {
|
|
37033
|
+
headerBgColors.push(bgColor2);
|
|
36499
37034
|
} else {
|
|
36500
37035
|
headerBgColors.push("");
|
|
36501
37036
|
}
|
|
@@ -36530,7 +37065,7 @@ function exportEditorWithInlineStyle(editor) {
|
|
|
36530
37065
|
editor.getEditorState().read(() => {
|
|
36531
37066
|
htmlString = $generateHtmlFromNodes(editor, null);
|
|
36532
37067
|
});
|
|
36533
|
-
return processHtmlForExport(htmlString, tableStyleMap);
|
|
37068
|
+
return processHtmlForExport(htmlString, tableStyleMap, bgColor, textColor, codeBlockStyles);
|
|
36534
37069
|
}
|
|
36535
37070
|
function normalizeColorForComparison(color) {
|
|
36536
37071
|
if (!color)
|
|
@@ -36580,7 +37115,7 @@ function detectTableColorsFromVariables(table) {
|
|
|
36580
37115
|
}
|
|
36581
37116
|
return null;
|
|
36582
37117
|
}
|
|
36583
|
-
function processHtmlForExport(html, tableStyleMap) {
|
|
37118
|
+
function processHtmlForExport(html, tableStyleMap, bgColor, textColor, codeBlockStyles) {
|
|
36584
37119
|
const parser = new DOMParser();
|
|
36585
37120
|
const doc = parser.parseFromString(html, "text/html");
|
|
36586
37121
|
const tables = doc.querySelectorAll("table");
|
|
@@ -36590,14 +37125,14 @@ function processHtmlForExport(html, tableStyleMap) {
|
|
|
36590
37125
|
return;
|
|
36591
37126
|
const headerCells = table.querySelectorAll("th");
|
|
36592
37127
|
headerCells.forEach((th, cellIndex) => {
|
|
36593
|
-
const
|
|
36594
|
-
if (
|
|
37128
|
+
const bgColor2 = styleInfo.headerBgColors[cellIndex];
|
|
37129
|
+
if (bgColor2) {
|
|
36595
37130
|
const el = th;
|
|
36596
|
-
el.style.setProperty("background-color",
|
|
36597
|
-
const
|
|
36598
|
-
el.style.color =
|
|
37131
|
+
el.style.setProperty("background-color", bgColor2, "important");
|
|
37132
|
+
const textColor2 = getContrastColor(bgColor2);
|
|
37133
|
+
el.style.color = textColor2;
|
|
36599
37134
|
el.querySelectorAll("*").forEach((nested) => {
|
|
36600
|
-
nested.style.color =
|
|
37135
|
+
nested.style.color = textColor2;
|
|
36601
37136
|
});
|
|
36602
37137
|
}
|
|
36603
37138
|
});
|
|
@@ -36612,27 +37147,37 @@ function processHtmlForExport(html, tableStyleMap) {
|
|
|
36612
37147
|
const el = cell;
|
|
36613
37148
|
const explicitColor = styleInfo.explicitCellColors.get(`${rowIndex}-${cellIndex}`);
|
|
36614
37149
|
if (explicitColor) {
|
|
36615
|
-
const
|
|
37150
|
+
const textColor2 = getContrastColor(explicitColor);
|
|
36616
37151
|
el.style.setProperty("background-color", explicitColor, "important");
|
|
36617
|
-
el.style.color =
|
|
37152
|
+
el.style.color = textColor2;
|
|
36618
37153
|
el.querySelectorAll("*").forEach((nested) => {
|
|
36619
|
-
nested.style.color =
|
|
37154
|
+
nested.style.color = textColor2;
|
|
36620
37155
|
});
|
|
36621
37156
|
} else if (stripingColor) {
|
|
36622
|
-
const
|
|
37157
|
+
const textColor2 = getContrastColor(stripingColor);
|
|
36623
37158
|
el.style.setProperty("background-color", stripingColor, "important");
|
|
36624
|
-
el.style.color =
|
|
37159
|
+
el.style.color = textColor2;
|
|
36625
37160
|
el.querySelectorAll("*").forEach((nested) => {
|
|
36626
|
-
nested.style.color =
|
|
37161
|
+
nested.style.color = textColor2;
|
|
36627
37162
|
});
|
|
36628
37163
|
}
|
|
36629
37164
|
});
|
|
36630
37165
|
});
|
|
36631
37166
|
});
|
|
36632
37167
|
cleanupHeaderCellStructure(doc.body);
|
|
36633
|
-
|
|
37168
|
+
applyCodeSyntaxHighlighting(doc.body, codeBlockStyles);
|
|
37169
|
+
processCodeBlocks(doc.body, codeBlockStyles);
|
|
37170
|
+
applyGenericSafeStyles(doc.body, codeBlockStyles);
|
|
36634
37171
|
cleanupClasses(doc.body);
|
|
36635
|
-
|
|
37172
|
+
const wrapper = doc.createElement("div");
|
|
37173
|
+
wrapper.style.backgroundColor = bgColor;
|
|
37174
|
+
wrapper.style.color = textColor;
|
|
37175
|
+
wrapper.style.padding = "1em";
|
|
37176
|
+
wrapper.style.minHeight = "100%";
|
|
37177
|
+
while (doc.body.firstChild) {
|
|
37178
|
+
wrapper.appendChild(doc.body.firstChild);
|
|
37179
|
+
}
|
|
37180
|
+
return wrapper.outerHTML;
|
|
36636
37181
|
}
|
|
36637
37182
|
function cleanupHeaderCellStructure(container) {
|
|
36638
37183
|
const allHeaderCells = container.querySelectorAll("th");
|
|
@@ -36654,12 +37199,25 @@ function cleanupHeaderCellStructure(container) {
|
|
|
36654
37199
|
});
|
|
36655
37200
|
});
|
|
36656
37201
|
}
|
|
36657
|
-
function applyGenericSafeStyles(container) {
|
|
37202
|
+
function applyGenericSafeStyles(container, codeBlockStyles) {
|
|
36658
37203
|
const addStyle = (selector, styles) => {
|
|
36659
37204
|
container.querySelectorAll(selector).forEach((el) => {
|
|
36660
37205
|
el.style.cssText += "; " + styles;
|
|
36661
37206
|
});
|
|
36662
37207
|
};
|
|
37208
|
+
const addStyleIfNotSetOnElementOrChildren = (selector, property, value) => {
|
|
37209
|
+
container.querySelectorAll(selector).forEach((el) => {
|
|
37210
|
+
const currentValue = el.style.getPropertyValue(property);
|
|
37211
|
+
if (currentValue && currentValue !== "initial" && currentValue !== "inherit") {
|
|
37212
|
+
return;
|
|
37213
|
+
}
|
|
37214
|
+
const childrenWithProperty = el.querySelectorAll(`[style*="${property}"]`);
|
|
37215
|
+
if (childrenWithProperty.length > 0) {
|
|
37216
|
+
return;
|
|
37217
|
+
}
|
|
37218
|
+
el.style.setProperty(property, value);
|
|
37219
|
+
});
|
|
37220
|
+
};
|
|
36663
37221
|
const addStyleIfNotSet = (selector, property, value) => {
|
|
36664
37222
|
container.querySelectorAll(selector).forEach((el) => {
|
|
36665
37223
|
const currentValue = el.style.getPropertyValue(property);
|
|
@@ -36669,10 +37227,11 @@ function applyGenericSafeStyles(container) {
|
|
|
36669
37227
|
});
|
|
36670
37228
|
};
|
|
36671
37229
|
const defaultFontFamily = "Arial, sans-serif";
|
|
36672
|
-
const
|
|
36673
|
-
|
|
36674
|
-
|
|
36675
|
-
|
|
37230
|
+
const blockSelectors = "table, p, li, td, th, div, h1, h2, h3, h4, h5, h6";
|
|
37231
|
+
const allSelectors = "table, p, span, li, td, th, div, h1, h2, h3, h4, h5, h6";
|
|
37232
|
+
addStyle(allSelectors, "line-height: 1.5;");
|
|
37233
|
+
addStyleIfNotSetOnElementOrChildren(blockSelectors, "font-family", defaultFontFamily);
|
|
37234
|
+
addStyleIfNotSet("table, p, li, td, th, div", "font-size", "16px");
|
|
36676
37235
|
addStyle("p", "margin: 0 0 1em 0;");
|
|
36677
37236
|
addStyle("th p, td p", "margin: 0; padding: 0;");
|
|
36678
37237
|
addStyle(
|
|
@@ -36722,13 +37281,12 @@ function applyGenericSafeStyles(container) {
|
|
|
36722
37281
|
addStyle("ul, ol", "margin: 1em 0; padding-left: 40px;");
|
|
36723
37282
|
addStyle("li", "margin: 0.5em 0;");
|
|
36724
37283
|
addStyle("a", "color: #0066cc; text-decoration: underline;");
|
|
37284
|
+
const codeBlockBg = codeBlockStyles.backgroundColor || "#f5f5f5";
|
|
37285
|
+
const codeBlockText = codeBlockStyles.textColor || "#333";
|
|
37286
|
+
const codeBlockFont = codeBlockStyles.fontFamily || "Menlo, Consolas, Monaco, monospace";
|
|
36725
37287
|
addStyle(
|
|
36726
|
-
"code",
|
|
36727
|
-
|
|
36728
|
-
);
|
|
36729
|
-
addStyle(
|
|
36730
|
-
"pre",
|
|
36731
|
-
'font-family: "Courier New", Courier, monospace; background-color: #f5f5f5; padding: 10px; border-radius: 5px; overflow-x: auto; margin: 1em 0;'
|
|
37288
|
+
"code:not(.code-line-numbers):not(.code-content):not([data-language]):not([data-highlight-language])",
|
|
37289
|
+
`font-family: ${codeBlockFont}; background-color: ${codeBlockBg}; color: ${codeBlockText}; padding: 2px 4px; border-radius: 3px;`
|
|
36732
37290
|
);
|
|
36733
37291
|
addStyle(
|
|
36734
37292
|
"blockquote",
|
|
@@ -36738,6 +37296,108 @@ function applyGenericSafeStyles(container) {
|
|
|
36738
37296
|
addStyle("em, i", "font-style: italic;");
|
|
36739
37297
|
addStyle("hr", "border: none; border-top: 1px solid #ddd; margin: 1em 0;");
|
|
36740
37298
|
}
|
|
37299
|
+
function applyCodeSyntaxHighlighting(container, codeBlockStyles) {
|
|
37300
|
+
const codeBlocks = container.querySelectorAll('code, pre[data-language], pre[data-highlight-language], pre[spellcheck="false"]');
|
|
37301
|
+
codeBlocks.forEach((codeBlock, codeBlockIndex) => {
|
|
37302
|
+
const capturedSpanColors = codeBlockStyles.spanColors.get(codeBlockIndex) || [];
|
|
37303
|
+
const spans = codeBlock.querySelectorAll("span");
|
|
37304
|
+
spans.forEach((span, spanIndex) => {
|
|
37305
|
+
const htmlSpan = span;
|
|
37306
|
+
if (spanIndex < capturedSpanColors.length) {
|
|
37307
|
+
const { color } = capturedSpanColors[spanIndex];
|
|
37308
|
+
if (color && color !== codeBlockStyles.textColor) {
|
|
37309
|
+
htmlSpan.style.color = color;
|
|
37310
|
+
}
|
|
37311
|
+
}
|
|
37312
|
+
});
|
|
37313
|
+
});
|
|
37314
|
+
}
|
|
37315
|
+
function processCodeBlocks(container, codeBlockStyles) {
|
|
37316
|
+
const codeBlocks = container.querySelectorAll('code, pre[data-language], pre[data-highlight-language], pre[spellcheck="false"]');
|
|
37317
|
+
codeBlocks.forEach((codeBlock) => {
|
|
37318
|
+
const htmlCodeBlock = codeBlock;
|
|
37319
|
+
const brElements = Array.from(htmlCodeBlock.querySelectorAll("br"));
|
|
37320
|
+
const toRemove = [];
|
|
37321
|
+
for (let i2 = 0; i2 < brElements.length - 1; i2++) {
|
|
37322
|
+
const currentBr = brElements[i2];
|
|
37323
|
+
const nextBr = brElements[i2 + 1];
|
|
37324
|
+
if (currentBr.nextSibling === nextBr) {
|
|
37325
|
+
toRemove.push(nextBr);
|
|
37326
|
+
i2++;
|
|
37327
|
+
}
|
|
37328
|
+
}
|
|
37329
|
+
toRemove.forEach((br) => br.remove());
|
|
37330
|
+
const brCount = htmlCodeBlock.querySelectorAll("br").length;
|
|
37331
|
+
const lineCount = brCount + 1;
|
|
37332
|
+
const lineNumbers = [];
|
|
37333
|
+
for (let i2 = 1; i2 <= lineCount; i2++) {
|
|
37334
|
+
lineNumbers.push(i2.toString());
|
|
37335
|
+
}
|
|
37336
|
+
const lineNumbersStr = lineNumbers.join("\n");
|
|
37337
|
+
const maxDigits = lineCount.toString().length;
|
|
37338
|
+
const gutterWidth = Math.max(40, 20 + maxDigits * 10);
|
|
37339
|
+
const gutter = container.ownerDocument.createElement("div");
|
|
37340
|
+
gutter.className = "code-line-numbers";
|
|
37341
|
+
gutter.textContent = lineNumbersStr;
|
|
37342
|
+
const fontFamily = codeBlockStyles.fontFamily || "Menlo, Consolas, Monaco, monospace";
|
|
37343
|
+
const fontSize = codeBlockStyles.fontSize || "13px";
|
|
37344
|
+
const lineHeight = codeBlockStyles.lineHeight || "1.53";
|
|
37345
|
+
const gutterBg = codeBlockStyles.gutterBackgroundColor || "rgba(0, 0, 0, 0.1)";
|
|
37346
|
+
const gutterColor = codeBlockStyles.gutterTextColor || "rgba(0, 0, 0, 0.5)";
|
|
37347
|
+
gutter.style.cssText = [
|
|
37348
|
+
"display: table-cell",
|
|
37349
|
+
"vertical-align: top",
|
|
37350
|
+
`width: ${gutterWidth}px`,
|
|
37351
|
+
`min-width: ${gutterWidth}px`,
|
|
37352
|
+
"padding: 10px 8px",
|
|
37353
|
+
`background-color: ${gutterBg}`,
|
|
37354
|
+
`color: ${gutterColor}`,
|
|
37355
|
+
"text-align: right",
|
|
37356
|
+
`font-family: ${fontFamily}`,
|
|
37357
|
+
`font-size: ${fontSize}`,
|
|
37358
|
+
`line-height: ${lineHeight}`,
|
|
37359
|
+
"border-right: 1px solid rgba(128, 128, 128, 0.3)",
|
|
37360
|
+
"border-top-left-radius: 5px",
|
|
37361
|
+
"border-bottom-left-radius: 5px",
|
|
37362
|
+
"user-select: none",
|
|
37363
|
+
"white-space: pre",
|
|
37364
|
+
"box-sizing: border-box"
|
|
37365
|
+
].join("; ");
|
|
37366
|
+
const codeContent = container.ownerDocument.createElement("div");
|
|
37367
|
+
codeContent.className = "code-content";
|
|
37368
|
+
codeContent.style.cssText = [
|
|
37369
|
+
"display: table-cell",
|
|
37370
|
+
"vertical-align: top",
|
|
37371
|
+
"padding: 10px 10px 10px 12px",
|
|
37372
|
+
`font-family: ${fontFamily}`,
|
|
37373
|
+
`font-size: ${fontSize}`,
|
|
37374
|
+
`line-height: ${lineHeight}`,
|
|
37375
|
+
"white-space: pre",
|
|
37376
|
+
"overflow-x: auto",
|
|
37377
|
+
"width: 100%"
|
|
37378
|
+
].join("; ");
|
|
37379
|
+
while (htmlCodeBlock.firstChild) {
|
|
37380
|
+
codeContent.appendChild(htmlCodeBlock.firstChild);
|
|
37381
|
+
}
|
|
37382
|
+
const codeBlockBg = codeBlockStyles.backgroundColor || "#f5f5f5";
|
|
37383
|
+
const codeBlockText = codeBlockStyles.textColor || "#333";
|
|
37384
|
+
htmlCodeBlock.style.cssText = [
|
|
37385
|
+
"display: table",
|
|
37386
|
+
"table-layout: fixed",
|
|
37387
|
+
"width: 100%",
|
|
37388
|
+
`background-color: ${codeBlockBg}`,
|
|
37389
|
+
`color: ${codeBlockText}`,
|
|
37390
|
+
"border-radius: 5px",
|
|
37391
|
+
"margin: 1em 0",
|
|
37392
|
+
"overflow: hidden"
|
|
37393
|
+
].join("; ");
|
|
37394
|
+
htmlCodeBlock.appendChild(gutter);
|
|
37395
|
+
htmlCodeBlock.appendChild(codeContent);
|
|
37396
|
+
htmlCodeBlock.removeAttribute("spellcheck");
|
|
37397
|
+
htmlCodeBlock.removeAttribute("data-gutter");
|
|
37398
|
+
htmlCodeBlock.removeAttribute("dir");
|
|
37399
|
+
});
|
|
37400
|
+
}
|
|
36741
37401
|
function cleanupClasses(container) {
|
|
36742
37402
|
const classesToRemove = [
|
|
36743
37403
|
"PlaygroundEditorTheme__",
|
|
@@ -36911,7 +37571,24 @@ function preprocessInitialContent(html) {
|
|
|
36911
37571
|
return html;
|
|
36912
37572
|
}
|
|
36913
37573
|
const parser = new DOMParser();
|
|
36914
|
-
|
|
37574
|
+
let doc = parser.parseFromString(html, "text/html");
|
|
37575
|
+
let body = doc.body;
|
|
37576
|
+
if (body.children.length === 1) {
|
|
37577
|
+
const firstChild = body.children[0];
|
|
37578
|
+
if (firstChild.tagName === "DIV" && firstChild.style.backgroundColor && firstChild.style.color && firstChild.style.padding) {
|
|
37579
|
+
const innerHtml = firstChild.innerHTML;
|
|
37580
|
+
doc = parser.parseFromString(innerHtml, "text/html");
|
|
37581
|
+
body = doc.body;
|
|
37582
|
+
}
|
|
37583
|
+
}
|
|
37584
|
+
const emptyParagraphs = body.querySelectorAll("p");
|
|
37585
|
+
emptyParagraphs.forEach((p2) => {
|
|
37586
|
+
var _a, _b;
|
|
37587
|
+
const hasOnlyBrOrWhitespace = !((_a = p2.textContent) == null ? void 0 : _a.trim()) && (p2.innerHTML.trim() === "" || p2.innerHTML.trim() === "<br>" || p2.querySelector("br") !== null && !((_b = p2.textContent) == null ? void 0 : _b.trim()));
|
|
37588
|
+
if (hasOnlyBrOrWhitespace) {
|
|
37589
|
+
p2.remove();
|
|
37590
|
+
}
|
|
37591
|
+
});
|
|
36915
37592
|
const tables = doc.querySelectorAll("table");
|
|
36916
37593
|
tables.forEach((table) => {
|
|
36917
37594
|
const styles = detectTableStylesFromInline(table);
|
|
@@ -36992,6 +37669,48 @@ function preprocessInitialContent(html) {
|
|
|
36992
37669
|
htmlEl.setAttribute("style", relevantStyles.join("; "));
|
|
36993
37670
|
}
|
|
36994
37671
|
});
|
|
37672
|
+
const codeBlocks = doc.querySelectorAll("code, pre");
|
|
37673
|
+
codeBlocks.forEach((codeBlock) => {
|
|
37674
|
+
const htmlCodeBlock = codeBlock;
|
|
37675
|
+
const lineNumbersGutter = htmlCodeBlock.querySelector(".code-line-numbers");
|
|
37676
|
+
const codeContent = htmlCodeBlock.querySelector(".code-content");
|
|
37677
|
+
if (lineNumbersGutter && codeContent) {
|
|
37678
|
+
lineNumbersGutter.remove();
|
|
37679
|
+
while (codeContent.firstChild) {
|
|
37680
|
+
htmlCodeBlock.appendChild(codeContent.firstChild);
|
|
37681
|
+
}
|
|
37682
|
+
codeContent.remove();
|
|
37683
|
+
htmlCodeBlock.style.removeProperty("display");
|
|
37684
|
+
htmlCodeBlock.style.removeProperty("table-layout");
|
|
37685
|
+
htmlCodeBlock.style.removeProperty("width");
|
|
37686
|
+
htmlCodeBlock.style.removeProperty("background-color");
|
|
37687
|
+
htmlCodeBlock.style.removeProperty("color");
|
|
37688
|
+
htmlCodeBlock.style.removeProperty("border-radius");
|
|
37689
|
+
htmlCodeBlock.style.removeProperty("margin");
|
|
37690
|
+
htmlCodeBlock.style.removeProperty("overflow");
|
|
37691
|
+
}
|
|
37692
|
+
const tableDisplayElements = htmlCodeBlock.querySelectorAll('[style*="display: table-cell"]');
|
|
37693
|
+
if (tableDisplayElements.length > 0) {
|
|
37694
|
+
tableDisplayElements.forEach((cell) => {
|
|
37695
|
+
const htmlCell = cell;
|
|
37696
|
+
const isGutter = htmlCell.style.textAlign === "right" && /^\s*(\d+\n?)+\s*$/.test(htmlCell.textContent || "");
|
|
37697
|
+
if (isGutter) {
|
|
37698
|
+
htmlCell.remove();
|
|
37699
|
+
} else {
|
|
37700
|
+
while (htmlCell.firstChild) {
|
|
37701
|
+
htmlCodeBlock.appendChild(htmlCell.firstChild);
|
|
37702
|
+
}
|
|
37703
|
+
htmlCell.remove();
|
|
37704
|
+
}
|
|
37705
|
+
});
|
|
37706
|
+
htmlCodeBlock.style.removeProperty("display");
|
|
37707
|
+
htmlCodeBlock.style.removeProperty("table-layout");
|
|
37708
|
+
htmlCodeBlock.style.removeProperty("width");
|
|
37709
|
+
}
|
|
37710
|
+
if (!htmlCodeBlock.classList.contains("PlaygroundEditorTheme__code")) {
|
|
37711
|
+
htmlCodeBlock.classList.add("PlaygroundEditorTheme__code");
|
|
37712
|
+
}
|
|
37713
|
+
});
|
|
36995
37714
|
const headings = doc.querySelectorAll("h1, h2, h3, h4, h5, h6");
|
|
36996
37715
|
headings.forEach((heading) => {
|
|
36997
37716
|
const tagName = heading.tagName.toLowerCase();
|
|
@@ -37128,6 +37847,172 @@ const OnChangeWrapper = ({
|
|
|
37128
37847
|
};
|
|
37129
37848
|
return /* @__PURE__ */ jsx(OnChangePlugin, { onChange: handleChange });
|
|
37130
37849
|
};
|
|
37850
|
+
function getStyleFromElement(element) {
|
|
37851
|
+
const styles = [];
|
|
37852
|
+
const style = element.style;
|
|
37853
|
+
if (style.fontFamily) {
|
|
37854
|
+
const fontFamily = style.fontFamily.replace(/["']/g, "").trim();
|
|
37855
|
+
if (fontFamily) {
|
|
37856
|
+
styles.push(`font-family: ${fontFamily}`);
|
|
37857
|
+
}
|
|
37858
|
+
}
|
|
37859
|
+
if (style.fontSize) {
|
|
37860
|
+
styles.push(`font-size: ${style.fontSize}`);
|
|
37861
|
+
}
|
|
37862
|
+
if (style.lineHeight) {
|
|
37863
|
+
styles.push(`line-height: ${style.lineHeight}`);
|
|
37864
|
+
}
|
|
37865
|
+
if (style.color && style.color !== "rgb(0, 0, 0)") {
|
|
37866
|
+
styles.push(`color: ${style.color}`);
|
|
37867
|
+
}
|
|
37868
|
+
if (style.backgroundColor && style.backgroundColor !== "rgba(0, 0, 0, 0)" && style.backgroundColor !== "transparent") {
|
|
37869
|
+
styles.push(`background-color: ${style.backgroundColor}`);
|
|
37870
|
+
}
|
|
37871
|
+
if (style.letterSpacing && style.letterSpacing !== "normal") {
|
|
37872
|
+
styles.push(`letter-spacing: ${style.letterSpacing}`);
|
|
37873
|
+
}
|
|
37874
|
+
if (style.wordSpacing && style.wordSpacing !== "normal") {
|
|
37875
|
+
styles.push(`word-spacing: ${style.wordSpacing}`);
|
|
37876
|
+
}
|
|
37877
|
+
return styles.join("; ");
|
|
37878
|
+
}
|
|
37879
|
+
function collectTextSegmentsFromElement(element) {
|
|
37880
|
+
const segments = [];
|
|
37881
|
+
function traverse(node, inheritedStyle) {
|
|
37882
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
37883
|
+
const text = node.textContent || "";
|
|
37884
|
+
if (text) {
|
|
37885
|
+
segments.push({ text, style: inheritedStyle });
|
|
37886
|
+
}
|
|
37887
|
+
} else if (node.nodeType === Node.ELEMENT_NODE) {
|
|
37888
|
+
const el = node;
|
|
37889
|
+
const tagName = el.tagName.toLowerCase();
|
|
37890
|
+
if (["br", "img", "hr"].includes(tagName)) {
|
|
37891
|
+
return;
|
|
37892
|
+
}
|
|
37893
|
+
const elementStyle = getStyleFromElement(el);
|
|
37894
|
+
const currentStyle = elementStyle || inheritedStyle;
|
|
37895
|
+
const children = el.childNodes;
|
|
37896
|
+
for (let i2 = 0; i2 < children.length; i2++) {
|
|
37897
|
+
traverse(children[i2], currentStyle);
|
|
37898
|
+
}
|
|
37899
|
+
}
|
|
37900
|
+
}
|
|
37901
|
+
traverse(element, "");
|
|
37902
|
+
return segments;
|
|
37903
|
+
}
|
|
37904
|
+
function splitAndStyleTextNode(textNode, segments) {
|
|
37905
|
+
if (!$isTextNode(textNode) || segments.length === 0) {
|
|
37906
|
+
return;
|
|
37907
|
+
}
|
|
37908
|
+
const nodeText = textNode.getTextContent();
|
|
37909
|
+
const format = textNode.getFormat();
|
|
37910
|
+
const styledSegments = segments.filter((s2) => s2.style);
|
|
37911
|
+
if (styledSegments.length <= 1) {
|
|
37912
|
+
const styledSegment = styledSegments[0];
|
|
37913
|
+
if (styledSegment) {
|
|
37914
|
+
textNode.setStyle(styledSegment.style);
|
|
37915
|
+
}
|
|
37916
|
+
return;
|
|
37917
|
+
}
|
|
37918
|
+
const splitPoints = [];
|
|
37919
|
+
let runningOffset = 0;
|
|
37920
|
+
for (const segment of segments) {
|
|
37921
|
+
const segmentLength = segment.text.length;
|
|
37922
|
+
if (segment.style) {
|
|
37923
|
+
splitPoints.push({
|
|
37924
|
+
offset: runningOffset,
|
|
37925
|
+
style: segment.style
|
|
37926
|
+
});
|
|
37927
|
+
}
|
|
37928
|
+
runningOffset += segmentLength;
|
|
37929
|
+
}
|
|
37930
|
+
if (splitPoints.length === 0) {
|
|
37931
|
+
return;
|
|
37932
|
+
}
|
|
37933
|
+
const offsetsToSplit = [];
|
|
37934
|
+
runningOffset = 0;
|
|
37935
|
+
for (let i2 = 0; i2 < segments.length - 1; i2++) {
|
|
37936
|
+
runningOffset += segments[i2].text.length;
|
|
37937
|
+
if (runningOffset > 0 && runningOffset < nodeText.length) {
|
|
37938
|
+
offsetsToSplit.push(runningOffset);
|
|
37939
|
+
}
|
|
37940
|
+
}
|
|
37941
|
+
if (offsetsToSplit.length === 0) {
|
|
37942
|
+
if (splitPoints[0]) {
|
|
37943
|
+
textNode.setStyle(splitPoints[0].style);
|
|
37944
|
+
}
|
|
37945
|
+
return;
|
|
37946
|
+
}
|
|
37947
|
+
try {
|
|
37948
|
+
const splitNodes = textNode.splitText(...offsetsToSplit);
|
|
37949
|
+
let segmentIndex = 0;
|
|
37950
|
+
for (const splitNode of splitNodes) {
|
|
37951
|
+
if ($isTextNode(splitNode) && segmentIndex < segments.length) {
|
|
37952
|
+
const segment = segments[segmentIndex];
|
|
37953
|
+
if (segment.style) {
|
|
37954
|
+
splitNode.setStyle(segment.style);
|
|
37955
|
+
}
|
|
37956
|
+
splitNode.setFormat(format);
|
|
37957
|
+
segmentIndex++;
|
|
37958
|
+
}
|
|
37959
|
+
}
|
|
37960
|
+
} catch {
|
|
37961
|
+
if (splitPoints[0]) {
|
|
37962
|
+
textNode.setStyle(splitPoints[0].style);
|
|
37963
|
+
}
|
|
37964
|
+
}
|
|
37965
|
+
}
|
|
37966
|
+
const BLOCK_SELECTORS = "p, h1, h2, h3, h4, h5, h6, li, blockquote";
|
|
37967
|
+
function collectBlockStyleMap(container) {
|
|
37968
|
+
const map = /* @__PURE__ */ new Map();
|
|
37969
|
+
const blocks = container.querySelectorAll(BLOCK_SELECTORS);
|
|
37970
|
+
blocks.forEach((block) => {
|
|
37971
|
+
const segments = collectTextSegmentsFromElement(block);
|
|
37972
|
+
const fullText = segments.map((s2) => s2.text).join("").trim();
|
|
37973
|
+
if (fullText && segments.some((s2) => s2.style)) {
|
|
37974
|
+
const normalizedText = fullText.replace(/\s+/g, " ").toLowerCase();
|
|
37975
|
+
map.set(normalizedText, segments);
|
|
37976
|
+
}
|
|
37977
|
+
});
|
|
37978
|
+
return map;
|
|
37979
|
+
}
|
|
37980
|
+
function applyStylesToBlockNodes(lexicalNodes, blockStyleMap) {
|
|
37981
|
+
for (const node of lexicalNodes) {
|
|
37982
|
+
if ($isElementNode(node)) {
|
|
37983
|
+
const nodeType = node.getType();
|
|
37984
|
+
const isBlockElement = [
|
|
37985
|
+
"paragraph",
|
|
37986
|
+
"heading",
|
|
37987
|
+
"listitem",
|
|
37988
|
+
"quote"
|
|
37989
|
+
].includes(nodeType);
|
|
37990
|
+
if (isBlockElement) {
|
|
37991
|
+
const nodeText = node.getTextContent().trim();
|
|
37992
|
+
if (nodeText) {
|
|
37993
|
+
const normalizedNodeText = nodeText.replace(/\s+/g, " ").toLowerCase();
|
|
37994
|
+
const segments = blockStyleMap.get(normalizedNodeText);
|
|
37995
|
+
if (segments && segments.length > 0) {
|
|
37996
|
+
const textChildren = node.getChildren().filter($isTextNode);
|
|
37997
|
+
if (textChildren.length === 1) {
|
|
37998
|
+
splitAndStyleTextNode(textChildren[0], segments);
|
|
37999
|
+
} else if (textChildren.length > 0) {
|
|
38000
|
+
for (let i2 = 0; i2 < textChildren.length && i2 < segments.length; i2++) {
|
|
38001
|
+
const textNode = textChildren[i2];
|
|
38002
|
+
const segment = segments[i2];
|
|
38003
|
+
if (segment.style) {
|
|
38004
|
+
textNode.setStyle(segment.style);
|
|
38005
|
+
}
|
|
38006
|
+
}
|
|
38007
|
+
}
|
|
38008
|
+
}
|
|
38009
|
+
}
|
|
38010
|
+
} else {
|
|
38011
|
+
applyStylesToBlockNodes(node.getChildren(), blockStyleMap);
|
|
38012
|
+
}
|
|
38013
|
+
}
|
|
38014
|
+
}
|
|
38015
|
+
}
|
|
37131
38016
|
const InitialContentPlugin = ({
|
|
37132
38017
|
initialContent
|
|
37133
38018
|
}) => {
|
|
@@ -37141,7 +38026,9 @@ const InitialContentPlugin = ({
|
|
|
37141
38026
|
editor.update(() => {
|
|
37142
38027
|
const parser = new DOMParser();
|
|
37143
38028
|
const dom = parser.parseFromString(processedHtml, "text/html");
|
|
38029
|
+
const blockStyleMap = collectBlockStyleMap(dom.body);
|
|
37144
38030
|
const nodes = $generateNodesFromDOM(editor, dom);
|
|
38031
|
+
applyStylesToBlockNodes(nodes, blockStyleMap);
|
|
37145
38032
|
const root2 = $getRoot();
|
|
37146
38033
|
root2.clear();
|
|
37147
38034
|
root2.append(...nodes);
|
|
@@ -37424,7 +38311,10 @@ const ConfigurableEditor = ({
|
|
|
37424
38311
|
/* @__PURE__ */ jsx(AIChatPlugin, { apiKey }),
|
|
37425
38312
|
/* @__PURE__ */ jsx(TextEnhancePlugin, { apiKey }),
|
|
37426
38313
|
/* @__PURE__ */ jsx(HtmlSyncPlugin, {}),
|
|
38314
|
+
/* @__PURE__ */ jsx(AndroidKeyboardFixPlugin, {}),
|
|
37427
38315
|
/* @__PURE__ */ jsx(CodeHighlightPlugin, {}),
|
|
38316
|
+
/* @__PURE__ */ jsx(CodeBlockNormalizerPlugin, {}),
|
|
38317
|
+
/* @__PURE__ */ jsx(CodeBlockSelectAllPlugin, {}),
|
|
37428
38318
|
/* @__PURE__ */ jsx(SlashCommandPlugin, {}),
|
|
37429
38319
|
/* @__PURE__ */ jsx(CombinedPluginWrapper, {}),
|
|
37430
38320
|
/* @__PURE__ */ jsx(OnChangeWrapper, { onChange }),
|
|
@@ -37655,4 +38545,4 @@ export {
|
|
|
37655
38545
|
useHtmlView as u,
|
|
37656
38546
|
verifyApiKey as v
|
|
37657
38547
|
};
|
|
37658
|
-
//# sourceMappingURL=index-
|
|
38548
|
+
//# sourceMappingURL=index-6360d552.js.map
|