diff --git a/package.json b/package.json index 1f1c4a04..96286d2d 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ "@vap/shiki": "0.10.5", "fflate": "^0.8.2", "gifenc": "github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3", - "katex": "^0.16.11", "monaco-editor": "^0.50.0", "nanoid": "^5.0.7", "virtual-merge": "^1.0.1" @@ -50,7 +49,6 @@ "@stylistic/eslint-plugin": "^2.6.1", "@types/chrome": "^0.0.269", "@types/diff": "^5.2.1", - "@types/katex": "^0.16.7", "@types/lodash": "^4.17.7", "@types/node": "^22.0.3", "@types/react": "^18.3.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c6bda454..a62c40cd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,9 +34,6 @@ importers: gifenc: specifier: github:mattdesl/gifenc#64842fca317b112a8590f8fef2bf3825da8f6fe3 version: https://codeload.github.com/mattdesl/gifenc/tar.gz/64842fca317b112a8590f8fef2bf3825da8f6fe3 - katex: - specifier: ^0.16.11 - version: 0.16.11 monaco-editor: specifier: ^0.50.0 version: 0.50.0 @@ -56,9 +53,6 @@ importers: '@types/diff': specifier: ^5.2.1 version: 5.2.1 - '@types/katex': - specifier: ^0.16.7 - version: 0.16.7 '@types/lodash': specifier: ^4.17.7 version: 4.17.7 @@ -655,9 +649,6 @@ packages: '@types/jsonfile@6.1.4': resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} - '@types/katex@0.16.7': - resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} - '@types/lodash@4.14.194': resolution: {integrity: sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g==} @@ -1004,10 +995,6 @@ packages: commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} - commander@8.3.0: - resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} - engines: {node: '>= 12'} - component-emitter@1.3.0: resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} @@ -1958,10 +1945,6 @@ packages: jszip@2.7.0: resolution: {integrity: sha512-JIsRKRVC3gTRo2vM4Wy9WBC3TRcfnIZU8k65Phi3izkvPH975FowRYtKGT6PxevA0XnJ/yO8b0QwV0ydVyQwfw==} - katex@0.16.11: - resolution: {integrity: sha512-RQrI8rlHY92OLf3rho/Ts8i/XvjgguEjOkO1BEXcU3N8BqPpSzBNwV/G0Ukr+P/l3ivvJUE/Fa/CwbS6HesGNQ==} - hasBin: true - keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} @@ -3097,8 +3080,6 @@ snapshots: dependencies: '@types/node': 18.16.3 - '@types/katex@0.16.7': {} - '@types/lodash@4.14.194': {} '@types/lodash@4.17.7': {} @@ -3513,8 +3494,6 @@ snapshots: commander@2.20.3: {} - commander@8.3.0: {} - component-emitter@1.3.0: {} concat-map@0.0.1: {} @@ -4524,10 +4503,6 @@ snapshots: dependencies: pako: 1.0.11 - katex@0.16.11: - dependencies: - commander: 8.3.0 - keyv@4.5.4: dependencies: json-buffer: 3.0.1 diff --git a/src/plugins/katex/components/ReactKatex.tsx b/src/plugins/katex/components/ReactKatex.tsx deleted file mode 100644 index 1d1b9503..00000000 --- a/src/plugins/katex/components/ReactKatex.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { React, useMemo } from '@webpack/common'; -import type { ReactNode } from "react"; -import KaTeX from 'katex'; - -type ErrorRenderer = (error: Error) => ReactNode; - -interface MathComponentProps { - math: string, - children?: ReactNode, - errorColor?: string, - renderError?: ErrorRenderer; -} - -const createMathComponent = (Component, { displayMode }) => { - const MathComponent = ({ children, errorColor, math, renderError }: MathComponentProps) => { - const formula = math ?? children; - - const { html, error } = useMemo(() => { - try { - const html = KaTeX.renderToString(formula, { - displayMode, - errorColor, - throwOnError: !!renderError, - }); - - return { html, error: undefined }; - } catch (error) { - if (error instanceof KaTeX.ParseError || error instanceof TypeError) { - return { error }; - } - - throw error; - } - }, [formula, errorColor, renderError]); - - if (error) { - return renderError ? renderError(error) : ; - } - - return ; - }; - - return MathComponent; -}; - -const InternalBlockMath = ({ html }) => { - return
; -}; - -const InternalInlineMath = ({ html }) => { - return ; -}; - -export const BlockMath = createMathComponent(InternalBlockMath, { displayMode: true }); -export const InlineMath = createMathComponent(InternalInlineMath, { displayMode: false }); \ No newline at end of file diff --git a/src/plugins/katex/index.tsx b/src/plugins/katex/index.tsx index ed851395..65764ea1 100644 --- a/src/plugins/katex/index.tsx +++ b/src/plugins/katex/index.tsx @@ -20,7 +20,33 @@ import "./katex.css"; import { Devs } from "@utils/constants"; import definePlugin, { ReporterTestable } from "@utils/types"; -import { BlockMath, InlineMath } from "./components/ReactKatex"; +import { makeLazy } from "@utils/lazy"; +import { classes } from "@utils/misc"; +import { React, useEffect, useMemo, useState } from "@webpack/common"; + +// @ts-expect-error +export const getKatex = /* #__PURE__*/ makeLazy(async () => (await import("https://unpkg.com/katex@0.16.9/dist/katex.mjs")).default); + +export function useKatex() { + const [katex, setKatex] = useState(); + useEffect(() => { + if (katex === undefined) + getKatex().then(setKatex); + }); + return katex; +} + +// @ts-expect-error +export const getDomPurify = /* #__PURE__*/ makeLazy(async () => (await import("https://unpkg.com/dompurify@3.1.7/dist/purify.es.mjs")).default); + +export function useDomPurify() { + const [domPurify, setDomPurify] = useState(); + useEffect(() => { + if (domPurify === undefined) + getDomPurify().then(setDomPurify); + }); + return domPurify; +} export interface HighlighterProps { lang?: string; @@ -52,14 +78,47 @@ export default definePlugin({ } ], start: async () => { + useKatex(); + useDomPurify(); }, stop: () => { }, createBlock: (props: HighlighterProps) => ( - + ), createInline: (props: HighlighterProps) => ( - + ), -}); \ No newline at end of file +}); + +function LazyLatex(props) { + const { formula } = props; + const katex = useKatex(); + const domPurify = useDomPurify(); + return katex + ? + : {formula}; +} + +function Latex({ katex, formula, displayMode, domPurify }) { + const result = useMemo(() => { + const html = katex.renderToString(formula, { + displayMode, + throwOnError: false + }); + return domPurify.sanitize(html); + }, [formula, displayMode]); + + return displayMode + ?
+ : ; +} + +function LatexPlaceholder({ className, children, ...props }) { + return ( + + {children} + + ); +} \ No newline at end of file diff --git a/src/plugins/katex/katex.css b/src/plugins/katex/katex.css index 53f986ff..fbc06b44 100644 --- a/src/plugins/katex/katex.css +++ b/src/plugins/katex/katex.css @@ -1,4 +1,4 @@ -@import url("https://cdn.jsdelivr.net/npm/katex@0.16.11/dist/katex.min.css"); +@import url("https://unpkg.com/katex@0.16.9/dist/katex.min.css"); .katex-display { width: min-content;