ct-rich-text-editor 1.3.20 → 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.
@@ -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, $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";
@@ -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-8bcb5b47.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
  }
@@ -15337,7 +15337,7 @@ const EmbedComponent = ({ url, displayType, alignment, nodeKey }) => {
15337
15337
  }
15338
15338
  );
15339
15339
  };
15340
- const FileComponent = React$1.lazy(() => import("./index-9505418d.js"));
15340
+ const FileComponent = React$1.lazy(() => import("./index-68135c09.js"));
15341
15341
  function convertFileElement(domNode) {
15342
15342
  if (domNode instanceof HTMLDivElement) {
15343
15343
  const dataUrl = domNode.getAttribute("data-lexical-file-src");
@@ -20360,10 +20360,10 @@ const PDF_CONFIG = {
20360
20360
  };
20361
20361
  const loadHtml2Pdf = async () => {
20362
20362
  try {
20363
- const mod = await import("./html2pdf.bundle.min-d830ece3.js").then((n) => n.h);
20363
+ const mod = await import("./html2pdf.bundle.min-08b31c1f.js").then((n) => n.h);
20364
20364
  return (mod == null ? void 0 : mod.default) || mod;
20365
20365
  } catch {
20366
- const mod2 = await import("./html2pdf.bundle-dea9d834.js").then((n) => n.h);
20366
+ const mod2 = await import("./html2pdf.bundle-0b180070.js").then((n) => n.h);
20367
20367
  return (mod2 == null ? void 0 : mod2.default) || mod2;
20368
20368
  }
20369
20369
  };
@@ -26288,6 +26288,15 @@ const Toolbar = ({
26288
26288
  if ($isRangeSelection(selection))
26289
26289
  selection.insertRawText(textContent);
26290
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
+ }
26291
26300
  }
26292
26301
  });
26293
26302
  }, [editor]);
@@ -27455,6 +27464,196 @@ const Toolbar = ({
27455
27464
  )
27456
27465
  ] });
27457
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
+ }
27458
27657
  const CodeHighlightPlugin = () => {
27459
27658
  const [editor] = useLexicalComposerContext();
27460
27659
  useEffect$1(() => {
@@ -27596,6 +27795,9 @@ const extractTextWithMap = (editorState) => {
27596
27795
  editorState.read(() => {
27597
27796
  const root2 = $getRoot();
27598
27797
  const traverse = (node) => {
27798
+ if ($isCodeNode(node)) {
27799
+ return;
27800
+ }
27599
27801
  if ($isTextNode(node)) {
27600
27802
  const text = node.getTextContent();
27601
27803
  const start = fullText.length;
@@ -30604,6 +30806,15 @@ function TextFormatFloatingToolbar({
30604
30806
  if ($isRangeSelection(selection))
30605
30807
  selection.insertRawText(textContent);
30606
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
+ }
30607
30818
  }
30608
30819
  });
30609
30820
  }, [editor]);
@@ -32507,6 +32718,61 @@ function RichTextPastePlugin() {
32507
32718
  const htmlContent = clipboardData.getData("text/html");
32508
32719
  const plainText = clipboardData.getData("text/plain");
32509
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
+ }
32510
32776
  event.preventDefault();
32511
32777
  editor.update(
32512
32778
  () => {
@@ -32741,7 +33007,10 @@ function SlashCommandPlugin() {
32741
33007
  makeBlock(() => {
32742
33008
  const selection = $getSelection();
32743
33009
  if ($isRangeSelection(selection)) {
32744
- selection.insertNodes([$createCodeNode()]);
33010
+ const codeNode = $createCodeNode();
33011
+ selection.insertNodes([codeNode]);
33012
+ const paragraphNode = $createParagraphNode();
33013
+ codeNode.insertAfter(paragraphNode);
32745
33014
  }
32746
33015
  });
32747
33016
  }, [makeBlock]);
@@ -36693,6 +36962,63 @@ function exportEditorWithInlineStyle(editor) {
36693
36962
  return "";
36694
36963
  const { bgColor, textColor } = getEditorColors(rootElement);
36695
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
+ }
36696
37022
  const liveTables = rootElement.querySelectorAll("table");
36697
37023
  liveTables.forEach((table, index2) => {
36698
37024
  const colors = detectTableColorsFromVariables(table);
@@ -36739,7 +37065,7 @@ function exportEditorWithInlineStyle(editor) {
36739
37065
  editor.getEditorState().read(() => {
36740
37066
  htmlString = $generateHtmlFromNodes(editor, null);
36741
37067
  });
36742
- return processHtmlForExport(htmlString, tableStyleMap, bgColor, textColor);
37068
+ return processHtmlForExport(htmlString, tableStyleMap, bgColor, textColor, codeBlockStyles);
36743
37069
  }
36744
37070
  function normalizeColorForComparison(color) {
36745
37071
  if (!color)
@@ -36789,7 +37115,7 @@ function detectTableColorsFromVariables(table) {
36789
37115
  }
36790
37116
  return null;
36791
37117
  }
36792
- function processHtmlForExport(html, tableStyleMap, bgColor, textColor) {
37118
+ function processHtmlForExport(html, tableStyleMap, bgColor, textColor, codeBlockStyles) {
36793
37119
  const parser = new DOMParser();
36794
37120
  const doc = parser.parseFromString(html, "text/html");
36795
37121
  const tables = doc.querySelectorAll("table");
@@ -36839,7 +37165,9 @@ function processHtmlForExport(html, tableStyleMap, bgColor, textColor) {
36839
37165
  });
36840
37166
  });
36841
37167
  cleanupHeaderCellStructure(doc.body);
36842
- applyGenericSafeStyles(doc.body);
37168
+ applyCodeSyntaxHighlighting(doc.body, codeBlockStyles);
37169
+ processCodeBlocks(doc.body, codeBlockStyles);
37170
+ applyGenericSafeStyles(doc.body, codeBlockStyles);
36843
37171
  cleanupClasses(doc.body);
36844
37172
  const wrapper = doc.createElement("div");
36845
37173
  wrapper.style.backgroundColor = bgColor;
@@ -36871,7 +37199,7 @@ function cleanupHeaderCellStructure(container) {
36871
37199
  });
36872
37200
  });
36873
37201
  }
36874
- function applyGenericSafeStyles(container) {
37202
+ function applyGenericSafeStyles(container, codeBlockStyles) {
36875
37203
  const addStyle = (selector, styles) => {
36876
37204
  container.querySelectorAll(selector).forEach((el) => {
36877
37205
  el.style.cssText += "; " + styles;
@@ -36953,13 +37281,12 @@ function applyGenericSafeStyles(container) {
36953
37281
  addStyle("ul, ol", "margin: 1em 0; padding-left: 40px;");
36954
37282
  addStyle("li", "margin: 0.5em 0;");
36955
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";
36956
37287
  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;'
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;`
36963
37290
  );
36964
37291
  addStyle(
36965
37292
  "blockquote",
@@ -36969,6 +37296,108 @@ function applyGenericSafeStyles(container) {
36969
37296
  addStyle("em, i", "font-style: italic;");
36970
37297
  addStyle("hr", "border: none; border-top: 1px solid #ddd; margin: 1em 0;");
36971
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
+ }
36972
37401
  function cleanupClasses(container) {
36973
37402
  const classesToRemove = [
36974
37403
  "PlaygroundEditorTheme__",
@@ -37240,6 +37669,48 @@ function preprocessInitialContent(html) {
37240
37669
  htmlEl.setAttribute("style", relevantStyles.join("; "));
37241
37670
  }
37242
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
+ });
37243
37714
  const headings = doc.querySelectorAll("h1, h2, h3, h4, h5, h6");
37244
37715
  headings.forEach((heading) => {
37245
37716
  const tagName = heading.tagName.toLowerCase();
@@ -37840,7 +38311,10 @@ const ConfigurableEditor = ({
37840
38311
  /* @__PURE__ */ jsx(AIChatPlugin, { apiKey }),
37841
38312
  /* @__PURE__ */ jsx(TextEnhancePlugin, { apiKey }),
37842
38313
  /* @__PURE__ */ jsx(HtmlSyncPlugin, {}),
38314
+ /* @__PURE__ */ jsx(AndroidKeyboardFixPlugin, {}),
37843
38315
  /* @__PURE__ */ jsx(CodeHighlightPlugin, {}),
38316
+ /* @__PURE__ */ jsx(CodeBlockNormalizerPlugin, {}),
38317
+ /* @__PURE__ */ jsx(CodeBlockSelectAllPlugin, {}),
37844
38318
  /* @__PURE__ */ jsx(SlashCommandPlugin, {}),
37845
38319
  /* @__PURE__ */ jsx(CombinedPluginWrapper, {}),
37846
38320
  /* @__PURE__ */ jsx(OnChangeWrapper, { onChange }),
@@ -38071,4 +38545,4 @@ export {
38071
38545
  useHtmlView as u,
38072
38546
  verifyApiKey as v
38073
38547
  };
38074
- //# sourceMappingURL=index-c4b49ec3.js.map
38548
+ //# sourceMappingURL=index-6360d552.js.map