processCodeRender.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import {setSelectionFocus} from "../editor/setSelection";
  2. import {abcRender} from "../markdown/abcRender";
  3. import {chartRender} from "../markdown/chartRender";
  4. import {codeRender} from "../markdown/codeRender";
  5. import {highlightRender} from "../markdown/highlightRender";
  6. import {mathRenderByLute} from "../markdown/mathRenderByLute";
  7. import {mermaidRender} from "../markdown/mermaidRender";
  8. // html, math, math-inline, code block, abc, chart, mermaid
  9. export const processCodeRender = (blockElement: HTMLElement, vditor: IVditor) => {
  10. const blockType = blockElement.getAttribute("data-type");
  11. if (!blockType) {
  12. return;
  13. }
  14. const tagName = blockType.indexOf("block") > -1 ? "div" : "span";
  15. let previewPanel: HTMLElement = blockElement.querySelector(".vditor-wysiwyg__preview");
  16. if (!previewPanel) {
  17. blockElement.insertAdjacentHTML("beforeend", `<${tagName} class="vditor-wysiwyg__preview"></${tagName}>`);
  18. previewPanel = blockElement.querySelector(".vditor-wysiwyg__preview");
  19. previewPanel.setAttribute("data-render", "false");
  20. const showCode = () => {
  21. const range = codeElement.ownerDocument.createRange();
  22. if (codeElement.parentElement.tagName !== "PRE") {
  23. codeElement.style.display = "inline";
  24. range.selectNodeContents(codeElement);
  25. } else {
  26. codeElement.parentElement.style.display = "block";
  27. if (!codeElement.firstChild) {
  28. codeElement.appendChild(document.createTextNode(""));
  29. }
  30. range.setStart(codeElement.firstChild, 0);
  31. }
  32. range.collapse(true);
  33. setSelectionFocus(range);
  34. };
  35. previewPanel.addEventListener("click", () => {
  36. showCode();
  37. });
  38. }
  39. let codeElement = previewPanel.previousElementSibling as HTMLElement;
  40. if (codeElement.tagName === "PRE") {
  41. codeElement = codeElement.firstElementChild as HTMLElement;
  42. }
  43. const innerHTML = codeElement.innerHTML || "";
  44. if (blockType === "code-block") {
  45. const language = codeElement.className.replace("language-", "");
  46. previewPanel.innerHTML = `<pre><code class="${codeElement.className}">${innerHTML}</code></pre>`;
  47. if (language === "abc") {
  48. previewPanel.style.marginTop = "1em";
  49. abcRender(previewPanel, vditor.options.cdn);
  50. } else if (language === "mermaid") {
  51. mermaidRender(previewPanel, ".vditor-wysiwyg__preview .language-mermaid",
  52. vditor.options.cdn);
  53. } else if (language === "echarts") {
  54. chartRender(previewPanel, vditor.options.cdn);
  55. } else {
  56. highlightRender(Object.assign({}, vditor.options.preview.hljs, {enable: true}),
  57. previewPanel, vditor.options.cdn);
  58. codeRender(previewPanel, vditor.options.lang);
  59. }
  60. } else if (blockType.indexOf("html") > -1) {
  61. previewPanel.innerHTML = innerHTML.replace(/&amp;/g, "&")
  62. .replace(/&lt;/g, "<") .replace(/&gt;/g, ">");
  63. } else if (blockType.indexOf("math") > -1) {
  64. previewPanel.innerHTML = `<${tagName} class="vditor-math">${innerHTML}</${tagName}>`;
  65. mathRenderByLute(previewPanel, vditor.options.cdn);
  66. }
  67. };