ct-rich-text-editor 1.3.20 → 1.3.22

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.
@@ -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, KEY_DOWN_COMMAND, COMMAND_PRIORITY_CRITICAL, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, $isElementNode, SELECTION_CHANGE_COMMAND, 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";
27
+ import { createCommand, DecoratorNode, createEditor, $applyNodeReplacement, $insertNodes, $isRootOrShadowRoot, $createParagraphNode, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_LOW, $getSelection, $isRangeSelection, $getNearestNodeFromDOMNode, isHTMLElement as isHTMLElement$1, TextNode, $getRoot, $createTextNode, $getNodeByKey, $isParagraphNode, $isTextNode, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND, KEY_DOWN_COMMAND, COMMAND_PRIORITY_CRITICAL, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, $isElementNode, SELECTION_CHANGE_COMMAND, UNDO_COMMAND, REDO_COMMAND, KEY_SPACE_COMMAND, $isLineBreakNode, $createRangeSelection, $setSelection, COMMAND_PRIORITY_HIGH, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, $createNodeSelection, $isNodeSelection, getDOMSelection, CLICK_COMMAND, PASTE_COMMAND, ParagraphNode, $createLineBreakNode, isDOMNode } from "lexical";
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";
@@ -1471,7 +1471,7 @@ const AiTextTransform = async ({ content, apiKey }) => {
1471
1471
  const AI_ACTION_COMMAND = createCommand(
1472
1472
  "AI_ACTION_COMMAND"
1473
1473
  );
1474
- const ImageView = React__default.lazy(() => import("./index-d1931d92.js"));
1474
+ const ImageView = React__default.lazy(() => import("./index-84187412.js"));
1475
1475
  function isGoogleDocCheckboxImg(img) {
1476
1476
  return img.parentElement != null && img.parentElement.tagName === "LI" && img.previousSibling === null && img.getAttribute("aria-roledescription") === "checkbox";
1477
1477
  }
@@ -9178,19 +9178,19 @@ function CopyButton({ editor, getCodeDOMNode }) {
9178
9178
  const removeSuccessIcon = useDebounce$1(() => {
9179
9179
  setCopyCompleted(false);
9180
9180
  }, 1e3);
9181
- async function handleClick() {
9181
+ async function handleClick(e) {
9182
+ e.preventDefault();
9183
+ e.stopPropagation();
9182
9184
  const codeDOMNode = getCodeDOMNode();
9183
9185
  if (!codeDOMNode) {
9184
9186
  return;
9185
9187
  }
9186
9188
  let content = "";
9187
- editor.update(() => {
9189
+ editor.read(() => {
9188
9190
  const codeNode = $getNearestNodeFromDOMNode(codeDOMNode);
9189
9191
  if ($isCodeNode(codeNode)) {
9190
9192
  content = codeNode.getTextContent();
9191
9193
  }
9192
- const selection = $getSelection();
9193
- $setSelection(selection);
9194
9194
  });
9195
9195
  try {
9196
9196
  await navigator.clipboard.writeText(content);
@@ -9200,7 +9200,16 @@ function CopyButton({ editor, getCodeDOMNode }) {
9200
9200
  console.error("Failed to copy: ", err);
9201
9201
  }
9202
9202
  }
9203
- return /* @__PURE__ */ jsx("button", { className: "menu-item", onClick: handleClick, "aria-label": "copy", children: isCopyCompleted ? /* @__PURE__ */ jsx("i", { className: "format success" }) : /* @__PURE__ */ jsx("i", { className: "format copy" }) });
9203
+ return /* @__PURE__ */ jsx(
9204
+ "button",
9205
+ {
9206
+ className: "menu-item",
9207
+ onClick: handleClick,
9208
+ onMouseDown: (e) => e.preventDefault(),
9209
+ "aria-label": "copy",
9210
+ children: isCopyCompleted ? /* @__PURE__ */ jsx("i", { className: "format success" }) : /* @__PURE__ */ jsx("i", { className: "format copy" })
9211
+ }
9212
+ );
9204
9213
  }
9205
9214
  const index$7 = "";
9206
9215
  const PRETTIER_PARSER_MODULES = {
@@ -9250,13 +9259,15 @@ function getPrettierOptions(lang) {
9250
9259
  function PrettierButton({ lang, editor, getCodeDOMNode }) {
9251
9260
  const [syntaxError, setSyntaxError] = useState$1("");
9252
9261
  const [tipsVisible, setTipsVisible] = useState$1(false);
9253
- async function handleClick() {
9262
+ async function handleClick(e) {
9263
+ e.preventDefault();
9264
+ e.stopPropagation();
9254
9265
  const codeDOMNode = getCodeDOMNode();
9255
9266
  if (!codeDOMNode) {
9256
9267
  return;
9257
9268
  }
9258
9269
  let content = "";
9259
- editor.update(() => {
9270
+ editor.read(() => {
9260
9271
  const codeNode = $getNearestNodeFromDOMNode(codeDOMNode);
9261
9272
  if ($isCodeNode(codeNode)) {
9262
9273
  content = codeNode.getTextContent();
@@ -9267,12 +9278,26 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
9267
9278
  }
9268
9279
  try {
9269
9280
  const format = await loadPrettierFormat();
9270
- const options = getPrettierOptions(lang);
9271
- const prettierParsers = await loadPrettierParserByLang(lang);
9281
+ let options = getPrettierOptions(lang);
9282
+ let prettierParsers = await loadPrettierParserByLang(lang);
9272
9283
  options.plugins = prettierParsers.map(
9273
9284
  (parser) => parser.default || parser
9274
9285
  );
9275
- const formattedCode = await format(content, options);
9286
+ let formattedCode;
9287
+ try {
9288
+ formattedCode = await format(content, options);
9289
+ } catch (firstError) {
9290
+ if (lang === "js" && firstError instanceof Error && (firstError.message.includes("Unexpected token") || firstError.message.includes("expected"))) {
9291
+ options = getPrettierOptions("typescript");
9292
+ prettierParsers = await loadPrettierParserByLang("typescript");
9293
+ options.plugins = prettierParsers.map(
9294
+ (parser) => parser.default || parser
9295
+ );
9296
+ formattedCode = await format(content, options);
9297
+ } else {
9298
+ throw firstError;
9299
+ }
9300
+ }
9276
9301
  editor.update(() => {
9277
9302
  const codeNode = $getNearestNodeFromDOMNode(codeDOMNode);
9278
9303
  if ($isCodeNode(codeNode)) {
@@ -9281,7 +9306,7 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
9281
9306
  setSyntaxError("");
9282
9307
  setTipsVisible(false);
9283
9308
  }
9284
- });
9309
+ }, { discrete: true, tag: "prettier-format" });
9285
9310
  } catch (error) {
9286
9311
  setError(error);
9287
9312
  }
@@ -9310,6 +9335,7 @@ function PrettierButton({ lang, editor, getCodeDOMNode }) {
9310
9335
  {
9311
9336
  className: "menu-item",
9312
9337
  onClick: handleClick,
9338
+ onMouseDown: (e) => e.preventDefault(),
9313
9339
  onMouseEnter: handleMouseEnter,
9314
9340
  onMouseLeave: handleMouseLeave,
9315
9341
  "aria-label": "prettier",
@@ -15337,7 +15363,7 @@ const EmbedComponent = ({ url, displayType, alignment, nodeKey }) => {
15337
15363
  }
15338
15364
  );
15339
15365
  };
15340
- const FileComponent = React$1.lazy(() => import("./index-9505418d.js"));
15366
+ const FileComponent = React$1.lazy(() => import("./index-bf836d7a.js"));
15341
15367
  function convertFileElement(domNode) {
15342
15368
  if (domNode instanceof HTMLDivElement) {
15343
15369
  const dataUrl = domNode.getAttribute("data-lexical-file-src");
@@ -20360,10 +20386,10 @@ const PDF_CONFIG = {
20360
20386
  };
20361
20387
  const loadHtml2Pdf = async () => {
20362
20388
  try {
20363
- const mod = await import("./html2pdf.bundle.min-d830ece3.js").then((n) => n.h);
20389
+ const mod = await import("./html2pdf.bundle.min-83517dc2.js").then((n) => n.h);
20364
20390
  return (mod == null ? void 0 : mod.default) || mod;
20365
20391
  } catch {
20366
- const mod2 = await import("./html2pdf.bundle-dea9d834.js").then((n) => n.h);
20392
+ const mod2 = await import("./html2pdf.bundle-3699b235.js").then((n) => n.h);
20367
20393
  return (mod2 == null ? void 0 : mod2.default) || mod2;
20368
20394
  }
20369
20395
  };
@@ -26288,6 +26314,15 @@ const Toolbar = ({
26288
26314
  if ($isRangeSelection(selection))
26289
26315
  selection.insertRawText(textContent);
26290
26316
  }
26317
+ const newSelection = $getSelection();
26318
+ if ($isRangeSelection(newSelection)) {
26319
+ const anchorNode = newSelection.anchor.getNode();
26320
+ const codeNode = $findMatchingParent(anchorNode, $isCodeNode);
26321
+ if (codeNode) {
26322
+ const paragraphNode = $createParagraphNode();
26323
+ codeNode.insertAfter(paragraphNode);
26324
+ }
26325
+ }
26291
26326
  }
26292
26327
  });
26293
26328
  }, [editor]);
@@ -27455,6 +27490,196 @@ const Toolbar = ({
27455
27490
  )
27456
27491
  ] });
27457
27492
  };
27493
+ const IS_ANDROID = typeof navigator !== "undefined" && /Android/i.test(navigator.userAgent);
27494
+ function AndroidKeyboardFixPlugin() {
27495
+ const [editor] = useLexicalComposerContext();
27496
+ useEffect$1(() => {
27497
+ if (!IS_ANDROID) {
27498
+ return;
27499
+ }
27500
+ const rootElement = editor.getRootElement();
27501
+ if (!rootElement) {
27502
+ return;
27503
+ }
27504
+ let compositionEndTimer = null;
27505
+ let lastCompositionEndTime = 0;
27506
+ let pendingSpaceInsertion = false;
27507
+ const handleCompositionStart = () => {
27508
+ if (compositionEndTimer) {
27509
+ clearTimeout(compositionEndTimer);
27510
+ compositionEndTimer = null;
27511
+ }
27512
+ pendingSpaceInsertion = false;
27513
+ };
27514
+ const handleCompositionEnd = () => {
27515
+ lastCompositionEndTime = Date.now();
27516
+ compositionEndTimer = setTimeout(() => {
27517
+ compositionEndTimer = null;
27518
+ }, 150);
27519
+ };
27520
+ const handleBeforeInput = (event) => {
27521
+ var _a;
27522
+ const timeSinceCompositionEnd = Date.now() - lastCompositionEndTime;
27523
+ if (event.inputType === "insertText" && event.data === " " && timeSinceCompositionEnd < 200) {
27524
+ pendingSpaceInsertion = true;
27525
+ event.preventDefault();
27526
+ requestAnimationFrame(() => {
27527
+ editor.update(
27528
+ () => {
27529
+ const selection = $getSelection();
27530
+ if ($isRangeSelection(selection)) {
27531
+ selection.insertText(" ");
27532
+ }
27533
+ },
27534
+ { discrete: true }
27535
+ );
27536
+ pendingSpaceInsertion = false;
27537
+ });
27538
+ return;
27539
+ }
27540
+ if (event.inputType === "insertCompositionText" && ((_a = event.data) == null ? void 0 : _a.endsWith(" "))) {
27541
+ const timeSince = Date.now() - lastCompositionEndTime;
27542
+ if (timeSince < 50) {
27543
+ return;
27544
+ }
27545
+ }
27546
+ };
27547
+ const unregisterSpaceCommand = editor.registerCommand(
27548
+ KEY_SPACE_COMMAND,
27549
+ (event) => {
27550
+ const timeSinceCompositionEnd = Date.now() - lastCompositionEndTime;
27551
+ if (timeSinceCompositionEnd < 200 && !pendingSpaceInsertion) {
27552
+ event.preventDefault();
27553
+ requestAnimationFrame(() => {
27554
+ editor.update(
27555
+ () => {
27556
+ const selection = $getSelection();
27557
+ if ($isRangeSelection(selection)) {
27558
+ selection.insertText(" ");
27559
+ }
27560
+ },
27561
+ { discrete: true }
27562
+ );
27563
+ });
27564
+ return true;
27565
+ }
27566
+ return false;
27567
+ },
27568
+ COMMAND_PRIORITY_CRITICAL
27569
+ );
27570
+ rootElement.addEventListener("compositionstart", handleCompositionStart);
27571
+ rootElement.addEventListener("compositionend", handleCompositionEnd);
27572
+ rootElement.addEventListener("beforeinput", handleBeforeInput);
27573
+ return () => {
27574
+ rootElement.removeEventListener(
27575
+ "compositionstart",
27576
+ handleCompositionStart
27577
+ );
27578
+ rootElement.removeEventListener("compositionend", handleCompositionEnd);
27579
+ rootElement.removeEventListener("beforeinput", handleBeforeInput);
27580
+ unregisterSpaceCommand();
27581
+ if (compositionEndTimer) {
27582
+ clearTimeout(compositionEndTimer);
27583
+ }
27584
+ };
27585
+ }, [editor]);
27586
+ return null;
27587
+ }
27588
+ function normalizeCodeNodeLineBreaks(codeNode) {
27589
+ const children = codeNode.getChildren();
27590
+ const nodesToRemove = [];
27591
+ for (let i2 = 0; i2 < children.length - 1; i2++) {
27592
+ const current = children[i2];
27593
+ const next = children[i2 + 1];
27594
+ if ($isLineBreakNode(current) && $isLineBreakNode(next)) {
27595
+ nodesToRemove.push(next.getKey());
27596
+ }
27597
+ }
27598
+ nodesToRemove.forEach((key) => {
27599
+ const node = $getNodeByKey(key);
27600
+ if (node) {
27601
+ node.remove();
27602
+ }
27603
+ });
27604
+ }
27605
+ function CodeBlockNormalizerPlugin() {
27606
+ const [editor] = useLexicalComposerContext();
27607
+ useEffect$1(() => {
27608
+ const unregisterMutation = editor.registerMutationListener(
27609
+ CodeNode,
27610
+ (mutations) => {
27611
+ requestAnimationFrame(() => {
27612
+ editor.update(() => {
27613
+ for (const [nodeKey, mutation] of mutations) {
27614
+ if (mutation === "created" || mutation === "updated") {
27615
+ const node = $getNodeByKey(nodeKey);
27616
+ if ($isCodeNode(node)) {
27617
+ normalizeCodeNodeLineBreaks(node);
27618
+ }
27619
+ }
27620
+ }
27621
+ });
27622
+ });
27623
+ }
27624
+ );
27625
+ return () => {
27626
+ unregisterMutation();
27627
+ };
27628
+ }, [editor]);
27629
+ return null;
27630
+ }
27631
+ function CodeBlockSelectAllPlugin() {
27632
+ const [editor] = useLexicalComposerContext();
27633
+ useEffect$1(() => {
27634
+ const unregister = editor.registerCommand(
27635
+ KEY_DOWN_COMMAND,
27636
+ (event) => {
27637
+ const isSelectAll = (event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "a" && !event.shiftKey && !event.altKey;
27638
+ if (!isSelectAll) {
27639
+ return false;
27640
+ }
27641
+ let codeNode = null;
27642
+ editor.getEditorState().read(() => {
27643
+ const selection = $getSelection();
27644
+ if ($isRangeSelection(selection)) {
27645
+ const anchorNode = selection.anchor.getNode();
27646
+ let currentNode = anchorNode;
27647
+ while (currentNode) {
27648
+ if ($isCodeNode(currentNode)) {
27649
+ codeNode = currentNode;
27650
+ break;
27651
+ }
27652
+ currentNode = currentNode.getParent();
27653
+ }
27654
+ }
27655
+ });
27656
+ if (!codeNode) {
27657
+ return false;
27658
+ }
27659
+ event.preventDefault();
27660
+ editor.update(() => {
27661
+ const code = codeNode;
27662
+ const children = code.getChildren();
27663
+ const childrenCount = children.length;
27664
+ if (childrenCount === 0) {
27665
+ code.select(0, 0);
27666
+ return;
27667
+ }
27668
+ const rangeSelection = $createRangeSelection();
27669
+ rangeSelection.anchor.set(code.getKey(), 0, "element");
27670
+ rangeSelection.focus.set(code.getKey(), childrenCount, "element");
27671
+ $setSelection(rangeSelection);
27672
+ });
27673
+ return true;
27674
+ },
27675
+ COMMAND_PRIORITY_HIGH
27676
+ );
27677
+ return () => {
27678
+ unregister();
27679
+ };
27680
+ }, [editor]);
27681
+ return null;
27682
+ }
27458
27683
  const CodeHighlightPlugin = () => {
27459
27684
  const [editor] = useLexicalComposerContext();
27460
27685
  useEffect$1(() => {
@@ -27596,6 +27821,9 @@ const extractTextWithMap = (editorState) => {
27596
27821
  editorState.read(() => {
27597
27822
  const root2 = $getRoot();
27598
27823
  const traverse = (node) => {
27824
+ if ($isCodeNode(node)) {
27825
+ return;
27826
+ }
27599
27827
  if ($isTextNode(node)) {
27600
27828
  const text = node.getTextContent();
27601
27829
  const start = fullText.length;
@@ -30604,6 +30832,15 @@ function TextFormatFloatingToolbar({
30604
30832
  if ($isRangeSelection(selection))
30605
30833
  selection.insertRawText(textContent);
30606
30834
  }
30835
+ const newSelection = $getSelection();
30836
+ if ($isRangeSelection(newSelection)) {
30837
+ const anchorNode = newSelection.anchor.getNode();
30838
+ const codeNode = $findMatchingParent(anchorNode, $isCodeNode);
30839
+ if (codeNode) {
30840
+ const paragraphNode = $createParagraphNode();
30841
+ codeNode.insertAfter(paragraphNode);
30842
+ }
30843
+ }
30607
30844
  }
30608
30845
  });
30609
30846
  }, [editor]);
@@ -32507,6 +32744,61 @@ function RichTextPastePlugin() {
32507
32744
  const htmlContent = clipboardData.getData("text/html");
32508
32745
  const plainText = clipboardData.getData("text/plain");
32509
32746
  if (htmlContent) {
32747
+ let isInsideCodeBlock = false;
32748
+ editor.getEditorState().read(() => {
32749
+ const selection = $getSelection();
32750
+ if ($isRangeSelection(selection)) {
32751
+ const anchorNode = selection.anchor.getNode();
32752
+ let currentNode = anchorNode;
32753
+ while (currentNode) {
32754
+ if ($isCodeNode(currentNode)) {
32755
+ isInsideCodeBlock = true;
32756
+ break;
32757
+ }
32758
+ currentNode = currentNode.getParent();
32759
+ }
32760
+ }
32761
+ });
32762
+ if (isInsideCodeBlock) {
32763
+ if (plainText) {
32764
+ event.preventDefault();
32765
+ queueMicrotask(() => {
32766
+ editor.update(
32767
+ () => {
32768
+ const selection = $getSelection();
32769
+ if ($isRangeSelection(selection)) {
32770
+ selection.insertRawText(plainText);
32771
+ }
32772
+ },
32773
+ {
32774
+ tag: "paste"
32775
+ }
32776
+ );
32777
+ queueMicrotask(() => {
32778
+ editor.update(
32779
+ () => {
32780
+ const selection = $getSelection();
32781
+ if ($isRangeSelection(selection)) {
32782
+ let currentNode = selection.anchor.getNode();
32783
+ while (currentNode) {
32784
+ if ($isCodeNode(currentNode)) {
32785
+ currentNode.selectEnd();
32786
+ break;
32787
+ }
32788
+ currentNode = currentNode.getParent();
32789
+ }
32790
+ }
32791
+ },
32792
+ {
32793
+ tag: "history-merge"
32794
+ }
32795
+ );
32796
+ });
32797
+ });
32798
+ return true;
32799
+ }
32800
+ return false;
32801
+ }
32510
32802
  event.preventDefault();
32511
32803
  editor.update(
32512
32804
  () => {
@@ -32741,7 +33033,10 @@ function SlashCommandPlugin() {
32741
33033
  makeBlock(() => {
32742
33034
  const selection = $getSelection();
32743
33035
  if ($isRangeSelection(selection)) {
32744
- selection.insertNodes([$createCodeNode()]);
33036
+ const codeNode = $createCodeNode();
33037
+ selection.insertNodes([codeNode]);
33038
+ const paragraphNode = $createParagraphNode();
33039
+ codeNode.insertAfter(paragraphNode);
32745
33040
  }
32746
33041
  });
32747
33042
  }, [makeBlock]);
@@ -36693,6 +36988,63 @@ function exportEditorWithInlineStyle(editor) {
36693
36988
  return "";
36694
36989
  const { bgColor, textColor } = getEditorColors(rootElement);
36695
36990
  const tableStyleMap = /* @__PURE__ */ new Map();
36991
+ const codeBlockStyles = {
36992
+ backgroundColor: "",
36993
+ textColor: "",
36994
+ gutterBackgroundColor: "",
36995
+ gutterTextColor: "",
36996
+ fontFamily: "Menlo, Consolas, Monaco, monospace",
36997
+ fontSize: "13px",
36998
+ lineHeight: "1.53",
36999
+ tokenColors: /* @__PURE__ */ new Map(),
37000
+ spanColors: /* @__PURE__ */ new Map()
37001
+ };
37002
+ const liveCodeBlocks = rootElement.querySelectorAll("code");
37003
+ if (liveCodeBlocks.length > 0) {
37004
+ liveCodeBlocks.forEach((codeBlock, codeBlockIndex) => {
37005
+ const htmlCodeBlock = codeBlock;
37006
+ if (codeBlockIndex === 0) {
37007
+ const computedStyle = window.getComputedStyle(htmlCodeBlock);
37008
+ codeBlockStyles.backgroundColor = computedStyle.backgroundColor;
37009
+ codeBlockStyles.textColor = computedStyle.color;
37010
+ codeBlockStyles.fontFamily = computedStyle.fontFamily;
37011
+ codeBlockStyles.fontSize = computedStyle.fontSize;
37012
+ codeBlockStyles.lineHeight = computedStyle.lineHeight;
37013
+ const gutterBgColor = window.getComputedStyle(htmlCodeBlock, "::before").backgroundColor;
37014
+ const gutterColor = window.getComputedStyle(htmlCodeBlock, "::before").color;
37015
+ codeBlockStyles.gutterBackgroundColor = gutterBgColor;
37016
+ codeBlockStyles.gutterTextColor = gutterColor;
37017
+ }
37018
+ const spanColorArray = [];
37019
+ const spans = htmlCodeBlock.querySelectorAll("span");
37020
+ spans.forEach((span) => {
37021
+ const htmlSpan = span;
37022
+ const spanComputedStyle = window.getComputedStyle(htmlSpan);
37023
+ const color = spanComputedStyle.color;
37024
+ const text = htmlSpan.textContent || "";
37025
+ spanColorArray.push({ text, color });
37026
+ });
37027
+ codeBlockStyles.spanColors.set(codeBlockIndex, spanColorArray);
37028
+ });
37029
+ const firstCodeBlock = liveCodeBlocks[0];
37030
+ const tokenClasses = [
37031
+ "PlaygroundEditorTheme__tokenComment",
37032
+ "PlaygroundEditorTheme__tokenPunctuation",
37033
+ "PlaygroundEditorTheme__tokenProperty",
37034
+ "PlaygroundEditorTheme__tokenSelector",
37035
+ "PlaygroundEditorTheme__tokenOperator",
37036
+ "PlaygroundEditorTheme__tokenAttr",
37037
+ "PlaygroundEditorTheme__tokenVariable",
37038
+ "PlaygroundEditorTheme__tokenFunction"
37039
+ ];
37040
+ tokenClasses.forEach((tokenClass) => {
37041
+ const tokenSpan = firstCodeBlock.querySelector(`.${tokenClass}`);
37042
+ if (tokenSpan) {
37043
+ const tokenComputedStyle = window.getComputedStyle(tokenSpan);
37044
+ codeBlockStyles.tokenColors.set(tokenClass, tokenComputedStyle.color);
37045
+ }
37046
+ });
37047
+ }
36696
37048
  const liveTables = rootElement.querySelectorAll("table");
36697
37049
  liveTables.forEach((table, index2) => {
36698
37050
  const colors = detectTableColorsFromVariables(table);
@@ -36739,7 +37091,7 @@ function exportEditorWithInlineStyle(editor) {
36739
37091
  editor.getEditorState().read(() => {
36740
37092
  htmlString = $generateHtmlFromNodes(editor, null);
36741
37093
  });
36742
- return processHtmlForExport(htmlString, tableStyleMap, bgColor, textColor);
37094
+ return processHtmlForExport(htmlString, tableStyleMap, bgColor, textColor, codeBlockStyles);
36743
37095
  }
36744
37096
  function normalizeColorForComparison(color) {
36745
37097
  if (!color)
@@ -36789,7 +37141,7 @@ function detectTableColorsFromVariables(table) {
36789
37141
  }
36790
37142
  return null;
36791
37143
  }
36792
- function processHtmlForExport(html, tableStyleMap, bgColor, textColor) {
37144
+ function processHtmlForExport(html, tableStyleMap, bgColor, textColor, codeBlockStyles) {
36793
37145
  const parser = new DOMParser();
36794
37146
  const doc = parser.parseFromString(html, "text/html");
36795
37147
  const tables = doc.querySelectorAll("table");
@@ -36839,7 +37191,9 @@ function processHtmlForExport(html, tableStyleMap, bgColor, textColor) {
36839
37191
  });
36840
37192
  });
36841
37193
  cleanupHeaderCellStructure(doc.body);
36842
- applyGenericSafeStyles(doc.body);
37194
+ applyCodeSyntaxHighlighting(doc.body, codeBlockStyles);
37195
+ processCodeBlocks(doc.body, codeBlockStyles);
37196
+ applyGenericSafeStyles(doc.body, codeBlockStyles);
36843
37197
  cleanupClasses(doc.body);
36844
37198
  const wrapper = doc.createElement("div");
36845
37199
  wrapper.style.backgroundColor = bgColor;
@@ -36871,7 +37225,7 @@ function cleanupHeaderCellStructure(container) {
36871
37225
  });
36872
37226
  });
36873
37227
  }
36874
- function applyGenericSafeStyles(container) {
37228
+ function applyGenericSafeStyles(container, codeBlockStyles) {
36875
37229
  const addStyle = (selector, styles) => {
36876
37230
  container.querySelectorAll(selector).forEach((el) => {
36877
37231
  el.style.cssText += "; " + styles;
@@ -36904,7 +37258,7 @@ function applyGenericSafeStyles(container) {
36904
37258
  addStyle(allSelectors, "line-height: 1.5;");
36905
37259
  addStyleIfNotSetOnElementOrChildren(blockSelectors, "font-family", defaultFontFamily);
36906
37260
  addStyleIfNotSet("table, p, li, td, th, div", "font-size", "16px");
36907
- addStyle("p", "margin: 0 0 1em 0;");
37261
+ addStyle("p", "margin: 0;");
36908
37262
  addStyle("th p, td p", "margin: 0; padding: 0;");
36909
37263
  addStyle(
36910
37264
  "table",
@@ -36953,13 +37307,12 @@ function applyGenericSafeStyles(container) {
36953
37307
  addStyle("ul, ol", "margin: 1em 0; padding-left: 40px;");
36954
37308
  addStyle("li", "margin: 0.5em 0;");
36955
37309
  addStyle("a", "color: #0066cc; text-decoration: underline;");
37310
+ const codeBlockBg = codeBlockStyles.backgroundColor || "#f5f5f5";
37311
+ const codeBlockText = codeBlockStyles.textColor || "#333";
37312
+ const codeBlockFont = codeBlockStyles.fontFamily || "Menlo, Consolas, Monaco, monospace";
36956
37313
  addStyle(
36957
- "code",
36958
- 'font-family: "Courier New", Courier, monospace; background-color: #f5f5f5; padding: 2px 4px; border-radius: 3px;'
36959
- );
36960
- addStyle(
36961
- "pre",
36962
- 'font-family: "Courier New", Courier, monospace; background-color: #f5f5f5; padding: 10px; border-radius: 5px; overflow-x: auto; margin: 1em 0;'
37314
+ "code:not(.code-line-numbers):not(.code-content):not([data-language]):not([data-highlight-language])",
37315
+ `font-family: ${codeBlockFont}; background-color: ${codeBlockBg}; color: ${codeBlockText}; padding: 2px 4px; border-radius: 3px;`
36963
37316
  );
36964
37317
  addStyle(
36965
37318
  "blockquote",
@@ -36969,6 +37322,108 @@ function applyGenericSafeStyles(container) {
36969
37322
  addStyle("em, i", "font-style: italic;");
36970
37323
  addStyle("hr", "border: none; border-top: 1px solid #ddd; margin: 1em 0;");
36971
37324
  }
37325
+ function applyCodeSyntaxHighlighting(container, codeBlockStyles) {
37326
+ const codeBlocks = container.querySelectorAll('code, pre[data-language], pre[data-highlight-language], pre[spellcheck="false"]');
37327
+ codeBlocks.forEach((codeBlock, codeBlockIndex) => {
37328
+ const capturedSpanColors = codeBlockStyles.spanColors.get(codeBlockIndex) || [];
37329
+ const spans = codeBlock.querySelectorAll("span");
37330
+ spans.forEach((span, spanIndex) => {
37331
+ const htmlSpan = span;
37332
+ if (spanIndex < capturedSpanColors.length) {
37333
+ const { color } = capturedSpanColors[spanIndex];
37334
+ if (color && color !== codeBlockStyles.textColor) {
37335
+ htmlSpan.style.color = color;
37336
+ }
37337
+ }
37338
+ });
37339
+ });
37340
+ }
37341
+ function processCodeBlocks(container, codeBlockStyles) {
37342
+ const codeBlocks = container.querySelectorAll('code, pre[data-language], pre[data-highlight-language], pre[spellcheck="false"]');
37343
+ codeBlocks.forEach((codeBlock) => {
37344
+ const htmlCodeBlock = codeBlock;
37345
+ const brElements = Array.from(htmlCodeBlock.querySelectorAll("br"));
37346
+ const toRemove = [];
37347
+ for (let i2 = 0; i2 < brElements.length - 1; i2++) {
37348
+ const currentBr = brElements[i2];
37349
+ const nextBr = brElements[i2 + 1];
37350
+ if (currentBr.nextSibling === nextBr) {
37351
+ toRemove.push(nextBr);
37352
+ i2++;
37353
+ }
37354
+ }
37355
+ toRemove.forEach((br) => br.remove());
37356
+ const brCount = htmlCodeBlock.querySelectorAll("br").length;
37357
+ const lineCount = brCount + 1;
37358
+ const lineNumbers = [];
37359
+ for (let i2 = 1; i2 <= lineCount; i2++) {
37360
+ lineNumbers.push(i2.toString());
37361
+ }
37362
+ const lineNumbersStr = lineNumbers.join("\n");
37363
+ const maxDigits = lineCount.toString().length;
37364
+ const gutterWidth = Math.max(40, 20 + maxDigits * 10);
37365
+ const gutter = container.ownerDocument.createElement("div");
37366
+ gutter.className = "code-line-numbers";
37367
+ gutter.textContent = lineNumbersStr;
37368
+ const fontFamily = codeBlockStyles.fontFamily || "Menlo, Consolas, Monaco, monospace";
37369
+ const fontSize = codeBlockStyles.fontSize || "13px";
37370
+ const lineHeight = codeBlockStyles.lineHeight || "1.53";
37371
+ const gutterBg = codeBlockStyles.gutterBackgroundColor || "rgba(0, 0, 0, 0.1)";
37372
+ const gutterColor = codeBlockStyles.gutterTextColor || "rgba(0, 0, 0, 0.5)";
37373
+ gutter.style.cssText = [
37374
+ "display: table-cell",
37375
+ "vertical-align: top",
37376
+ `width: ${gutterWidth}px`,
37377
+ `min-width: ${gutterWidth}px`,
37378
+ "padding: 10px 8px",
37379
+ `background-color: ${gutterBg}`,
37380
+ `color: ${gutterColor}`,
37381
+ "text-align: right",
37382
+ `font-family: ${fontFamily}`,
37383
+ `font-size: ${fontSize}`,
37384
+ `line-height: ${lineHeight}`,
37385
+ "border-right: 1px solid rgba(128, 128, 128, 0.3)",
37386
+ "border-top-left-radius: 5px",
37387
+ "border-bottom-left-radius: 5px",
37388
+ "user-select: none",
37389
+ "white-space: pre",
37390
+ "box-sizing: border-box"
37391
+ ].join("; ");
37392
+ const codeContent = container.ownerDocument.createElement("div");
37393
+ codeContent.className = "code-content";
37394
+ codeContent.style.cssText = [
37395
+ "display: table-cell",
37396
+ "vertical-align: top",
37397
+ "padding: 10px 10px 10px 12px",
37398
+ `font-family: ${fontFamily}`,
37399
+ `font-size: ${fontSize}`,
37400
+ `line-height: ${lineHeight}`,
37401
+ "white-space: pre",
37402
+ "overflow-x: auto",
37403
+ "width: 100%"
37404
+ ].join("; ");
37405
+ while (htmlCodeBlock.firstChild) {
37406
+ codeContent.appendChild(htmlCodeBlock.firstChild);
37407
+ }
37408
+ const codeBlockBg = codeBlockStyles.backgroundColor || "#f5f5f5";
37409
+ const codeBlockText = codeBlockStyles.textColor || "#333";
37410
+ htmlCodeBlock.style.cssText = [
37411
+ "display: table",
37412
+ "table-layout: fixed",
37413
+ "width: 100%",
37414
+ `background-color: ${codeBlockBg}`,
37415
+ `color: ${codeBlockText}`,
37416
+ "border-radius: 5px",
37417
+ "margin: 1em 0",
37418
+ "overflow: hidden"
37419
+ ].join("; ");
37420
+ htmlCodeBlock.appendChild(gutter);
37421
+ htmlCodeBlock.appendChild(codeContent);
37422
+ htmlCodeBlock.removeAttribute("spellcheck");
37423
+ htmlCodeBlock.removeAttribute("data-gutter");
37424
+ htmlCodeBlock.removeAttribute("dir");
37425
+ });
37426
+ }
36972
37427
  function cleanupClasses(container) {
36973
37428
  const classesToRemove = [
36974
37429
  "PlaygroundEditorTheme__",
@@ -37240,6 +37695,48 @@ function preprocessInitialContent(html) {
37240
37695
  htmlEl.setAttribute("style", relevantStyles.join("; "));
37241
37696
  }
37242
37697
  });
37698
+ const codeBlocks = doc.querySelectorAll("code, pre");
37699
+ codeBlocks.forEach((codeBlock) => {
37700
+ const htmlCodeBlock = codeBlock;
37701
+ const lineNumbersGutter = htmlCodeBlock.querySelector(".code-line-numbers");
37702
+ const codeContent = htmlCodeBlock.querySelector(".code-content");
37703
+ if (lineNumbersGutter && codeContent) {
37704
+ lineNumbersGutter.remove();
37705
+ while (codeContent.firstChild) {
37706
+ htmlCodeBlock.appendChild(codeContent.firstChild);
37707
+ }
37708
+ codeContent.remove();
37709
+ htmlCodeBlock.style.removeProperty("display");
37710
+ htmlCodeBlock.style.removeProperty("table-layout");
37711
+ htmlCodeBlock.style.removeProperty("width");
37712
+ htmlCodeBlock.style.removeProperty("background-color");
37713
+ htmlCodeBlock.style.removeProperty("color");
37714
+ htmlCodeBlock.style.removeProperty("border-radius");
37715
+ htmlCodeBlock.style.removeProperty("margin");
37716
+ htmlCodeBlock.style.removeProperty("overflow");
37717
+ }
37718
+ const tableDisplayElements = htmlCodeBlock.querySelectorAll('[style*="display: table-cell"]');
37719
+ if (tableDisplayElements.length > 0) {
37720
+ tableDisplayElements.forEach((cell) => {
37721
+ const htmlCell = cell;
37722
+ const isGutter = htmlCell.style.textAlign === "right" && /^\s*(\d+\n?)+\s*$/.test(htmlCell.textContent || "");
37723
+ if (isGutter) {
37724
+ htmlCell.remove();
37725
+ } else {
37726
+ while (htmlCell.firstChild) {
37727
+ htmlCodeBlock.appendChild(htmlCell.firstChild);
37728
+ }
37729
+ htmlCell.remove();
37730
+ }
37731
+ });
37732
+ htmlCodeBlock.style.removeProperty("display");
37733
+ htmlCodeBlock.style.removeProperty("table-layout");
37734
+ htmlCodeBlock.style.removeProperty("width");
37735
+ }
37736
+ if (!htmlCodeBlock.classList.contains("PlaygroundEditorTheme__code")) {
37737
+ htmlCodeBlock.classList.add("PlaygroundEditorTheme__code");
37738
+ }
37739
+ });
37243
37740
  const headings = doc.querySelectorAll("h1, h2, h3, h4, h5, h6");
37244
37741
  headings.forEach((heading) => {
37245
37742
  const tagName = heading.tagName.toLowerCase();
@@ -37840,7 +38337,10 @@ const ConfigurableEditor = ({
37840
38337
  /* @__PURE__ */ jsx(AIChatPlugin, { apiKey }),
37841
38338
  /* @__PURE__ */ jsx(TextEnhancePlugin, { apiKey }),
37842
38339
  /* @__PURE__ */ jsx(HtmlSyncPlugin, {}),
38340
+ /* @__PURE__ */ jsx(AndroidKeyboardFixPlugin, {}),
37843
38341
  /* @__PURE__ */ jsx(CodeHighlightPlugin, {}),
38342
+ /* @__PURE__ */ jsx(CodeBlockNormalizerPlugin, {}),
38343
+ /* @__PURE__ */ jsx(CodeBlockSelectAllPlugin, {}),
37844
38344
  /* @__PURE__ */ jsx(SlashCommandPlugin, {}),
37845
38345
  /* @__PURE__ */ jsx(CombinedPluginWrapper, {}),
37846
38346
  /* @__PURE__ */ jsx(OnChangeWrapper, { onChange }),
@@ -38071,4 +38571,4 @@ export {
38071
38571
  useHtmlView as u,
38072
38572
  verifyApiKey as v
38073
38573
  };
38074
- //# sourceMappingURL=index-c4b49ec3.js.map
38574
+ //# sourceMappingURL=index-9a8a49b6.js.map