Use MathJax v3 on the editor page (#11330)

GitOrigin-RevId: 5e51404c54e49735988f399ea080b6cb4be726d3
This commit is contained in:
Alf Eaton 2023-01-23 11:41:24 +00:00 committed by Copybot
parent 78360b7358
commit 8b610d2d1c
10 changed files with 100 additions and 60 deletions

13
package-lock.json generated
View file

@ -22595,6 +22595,12 @@
"resolved": "https://registry.npmjs.org/mathjax/-/mathjax-2.7.9.tgz", "resolved": "https://registry.npmjs.org/mathjax/-/mathjax-2.7.9.tgz",
"integrity": "sha512-NOGEDTIM9+MrsqnjPEjVGNx4q0GQxqm61yQwSK+/5S59i26wId5IC5gNu9/bu8+CCVl5p9G2IHcAl/wJa+5+BQ==" "integrity": "sha512-NOGEDTIM9+MrsqnjPEjVGNx4q0GQxqm61yQwSK+/5S59i26wId5IC5gNu9/bu8+CCVl5p9G2IHcAl/wJa+5+BQ=="
}, },
"node_modules/mathjax-3": {
"name": "mathjax",
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/mathjax/-/mathjax-3.2.2.tgz",
"integrity": "sha512-Bt+SSVU8eBG27zChVewOicYs7Xsdt40qm4+UpHyX7k0/O9NliPc+x77k1/FEsPsjKPZGJvtRZM1vO+geW0OhGw=="
},
"node_modules/maxmind": { "node_modules/maxmind": {
"version": "4.3.6", "version": "4.3.6",
"resolved": "https://registry.npmjs.org/maxmind/-/maxmind-4.3.6.tgz", "resolved": "https://registry.npmjs.org/maxmind/-/maxmind-4.3.6.tgz",
@ -35778,6 +35784,7 @@
"marked": "^4.1.0", "marked": "^4.1.0",
"match-sorter": "^6.2.0", "match-sorter": "^6.2.0",
"mathjax": "^2.7.9", "mathjax": "^2.7.9",
"mathjax-3": "npm:mathjax@^3.2.2",
"method-override": "^2.3.3", "method-override": "^2.3.3",
"minimist": "^1.2.7", "minimist": "^1.2.7",
"mmmagic": "^0.5.3", "mmmagic": "^0.5.3",
@ -46297,6 +46304,7 @@
"marked": "^4.1.0", "marked": "^4.1.0",
"match-sorter": "^6.2.0", "match-sorter": "^6.2.0",
"mathjax": "^2.7.9", "mathjax": "^2.7.9",
"mathjax-3": "npm:mathjax@^3.2.2",
"mensch": "^0.3.4", "mensch": "^0.3.4",
"method-override": "^2.3.3", "method-override": "^2.3.3",
"mini-css-extract-plugin": "^2.6.0", "mini-css-extract-plugin": "^2.6.0",
@ -60482,6 +60490,11 @@
"resolved": "https://registry.npmjs.org/mathjax/-/mathjax-2.7.9.tgz", "resolved": "https://registry.npmjs.org/mathjax/-/mathjax-2.7.9.tgz",
"integrity": "sha512-NOGEDTIM9+MrsqnjPEjVGNx4q0GQxqm61yQwSK+/5S59i26wId5IC5gNu9/bu8+CCVl5p9G2IHcAl/wJa+5+BQ==" "integrity": "sha512-NOGEDTIM9+MrsqnjPEjVGNx4q0GQxqm61yQwSK+/5S59i26wId5IC5gNu9/bu8+CCVl5p9G2IHcAl/wJa+5+BQ=="
}, },
"mathjax-3": {
"version": "npm:mathjax@3.2.2",
"resolved": "https://registry.npmjs.org/mathjax/-/mathjax-3.2.2.tgz",
"integrity": "sha512-Bt+SSVU8eBG27zChVewOicYs7Xsdt40qm4+UpHyX7k0/O9NliPc+x77k1/FEsPsjKPZGJvtRZM1vO+geW0OhGw=="
},
"maxmind": { "maxmind": {
"version": "4.3.6", "version": "4.3.6",
"resolved": "https://registry.npmjs.org/maxmind/-/maxmind-4.3.6.tgz", "resolved": "https://registry.npmjs.org/maxmind/-/maxmind-4.3.6.tgz",

View file

@ -179,6 +179,12 @@ module.exports = function (webRouter, privateApiRouter, publicApiRouter) {
} }
)}` )}`
res.locals.mathJax3Path = `/js/libs/mathjax3/es5/tex-svg-full.js?${querystring.stringify(
{
v: require('mathjax-3/package.json').version,
}
)}`
res.locals.lib = PackageVersions.lib res.locals.lib = PackageVersions.lib
res.locals.moment = moment res.locals.moment = moment

View file

@ -120,6 +120,7 @@ block foot-scripts
each file in (useOpenTelemetry ? entrypointScripts("tracing") : []) each file in (useOpenTelemetry ? entrypointScripts("tracing") : [])
script(type="text/javascript", nonce=scriptNonce, src=file) script(type="text/javascript", nonce=scriptNonce, src=file)
script(type="text/javascript", nonce=scriptNonce, src=(wsUrl || '/socket.io') + '/socket.io.js') script(type="text/javascript", nonce=scriptNonce, src=(wsUrl || '/socket.io') + '/socket.io.js')
script(type="text/javascript", nonce=scriptNonce, src=mathJaxPath) if (richTextVariant !== 'cm6')
script(type="text/javascript", nonce=scriptNonce, src=mathJaxPath)
each file in entrypointScripts("ide") each file in entrypointScripts("ide")
script(type="text/javascript", nonce=scriptNonce, src=file) script(type="text/javascript", nonce=scriptNonce, src=file)

View file

@ -37,6 +37,8 @@ meta(name="ol-useOpenTelemetry" data-type="boolean" content=useOpenTelemetry)
meta(name="ol-showSupport", data-type="boolean" content=showSupport) meta(name="ol-showSupport", data-type="boolean" content=showSupport)
meta(name="ol-showCM6SwitchAwaySurvey", data-type="boolean" content=showCM6SwitchAwaySurvey) meta(name="ol-showCM6SwitchAwaySurvey", data-type="boolean" content=showCM6SwitchAwaySurvey)
meta(name="ol-richTextVariant" content=richTextVariant) meta(name="ol-richTextVariant" content=richTextVariant)
if (richTextVariant === 'cm6')
meta(name="ol-mathJax3Path" content=mathJax3Path)
- var fileActionI18n = ['edited', 'renamed', 'created', 'deleted'].reduce((acc, i) => {acc[i] = translate('file_action_' + i); return acc}, {}) - var fileActionI18n = ['edited', 'renamed', 'created', 'deleted'].reduce((acc, i) => {acc[i] = translate('file_action_' + i); return acc}, {})
meta(name="ol-fileActionI18n" data-type="json" content=fileActionI18n) meta(name="ol-fileActionI18n" data-type="json" content=fileActionI18n)

View file

@ -1,56 +0,0 @@
import { useRef, useEffect } from 'react'
import PropTypes from 'prop-types'
import Linkify from 'react-linkify'
function MessageContent({ content }) {
const root = useRef(null)
useEffect(() => {
if (!(window.MathJax && window.MathJax.Hub)) {
return
}
const MJHub = window.MathJax.Hub
const inlineMathConfig =
(MJHub.config &&
MJHub.config.tex2jax &&
MJHub.config.tex2jax.inlineMath) ||
[]
const alreadyConfigured = inlineMathConfig.some(
c => c[0] === '$' && c[1] === '$'
)
if (!alreadyConfigured) {
MJHub.Config({
tex2jax: {
inlineMath: inlineMathConfig.concat([['$', '$']]),
},
})
}
}, [])
useEffect(() => {
// adds attributes to all the links generated by <Linkify/>, required due to https://github.com/tasti/react-linkify/issues/99
for (const a of root.current.getElementsByTagName('a')) {
a.setAttribute('target', '_blank')
a.setAttribute('rel', 'noreferrer noopener')
}
// MathJax typesetting
const MJHub = window.MathJax.Hub
const timeoutHandler = setTimeout(() => {
MJHub.Queue(['Typeset', MJHub, root.current])
}, 0)
return () => clearTimeout(timeoutHandler)
}, [content])
return (
<p ref={root}>
<Linkify>{content}</Linkify>
</p>
)
}
MessageContent.propTypes = {
content: PropTypes.string.isRequired,
}
export default MessageContent

View file

@ -0,0 +1,57 @@
import { useRef, useEffect, type FC } from 'react'
// @ts-ignore
import Linkify from 'react-linkify'
import { loadMathJax } from '../../../../../modules/source-editor/frontend/js/utils/mathjax'
import useIsMounted from '../../../shared/hooks/use-is-mounted'
import { configureMathJax } from '../../mathjax/configure'
const MessageContent: FC<{ content: string }> = ({ content }) => {
const root = useRef<HTMLDivElement | null>(null)
const mounted = useIsMounted()
useEffect(() => {
if (root.current) {
// adds attributes to all the links generated by <Linkify/>, required due to https://github.com/tasti/react-linkify/issues/99
for (const a of root.current.getElementsByTagName('a')) {
a.setAttribute('target', '_blank')
a.setAttribute('rel', 'noreferrer noopener')
}
// MathJax v2 typesetting
if (window.MathJax?.Hub) {
const timeout = setTimeout(() => {
configureMathJax()
window.MathJax.Hub.Queue([
'Typeset',
window.MathJax.Hub,
root.current,
])
}, 0)
return () => clearTimeout(timeout)
}
// MathJax v3 typesetting
loadMathJax()
.then(MathJax => {
if (mounted.current) {
MathJax.typesetPromise([root.current]).catch((error: Error) => {
console.error(error)
})
}
})
.catch(error => {
console.error(error)
})
}
}, [content, mounted])
return (
<p ref={root}>
<Linkify>{content}</Linkify>
</p>
)
}
export default MessageContent

View file

@ -7,6 +7,7 @@ let configured = false
export function configureMathJax() { export function configureMathJax() {
if (configured) return if (configured) return
if (getMeta('ol-mathJax3Path')) return
if (!mathJaxLoaded()) return if (!mathJaxLoaded()) return
const inlineMath = [['\\(', '\\)']] const inlineMath = [['\\(', '\\)']]

View file

@ -180,6 +180,7 @@
"marked": "^4.1.0", "marked": "^4.1.0",
"match-sorter": "^6.2.0", "match-sorter": "^6.2.0",
"mathjax": "^2.7.9", "mathjax": "^2.7.9",
"mathjax-3": "npm:mathjax@^3.2.2",
"method-override": "^2.3.3", "method-override": "^2.3.3",
"minimist": "^1.2.7", "minimist": "^1.2.7",
"mmmagic": "^0.5.3", "mmmagic": "^0.5.3",

View file

@ -29,9 +29,7 @@ declare global {
isRestrictedTokenMember: boolean isRestrictedTokenMember: boolean
_reportCM6Perf: () => void _reportCM6Perf: () => void
_reportAcePerf: () => void _reportAcePerf: () => void
MathJax: { MathJax: Record<string, any>
Hub: Record<string, any>
}
overallThemes: OverallThemeMeta[] overallThemes: OverallThemeMeta[]
} }
} }

View file

@ -58,6 +58,7 @@ function getModuleDirectory(moduleName) {
} }
const mathjaxDir = getModuleDirectory('mathjax') const mathjaxDir = getModuleDirectory('mathjax')
const mathjax3Dir = getModuleDirectory('mathjax-3')
const aceDir = getModuleDirectory('ace-builds') const aceDir = getModuleDirectory('ace-builds')
const pdfjsVersions = ['pdfjs-dist213', 'pdfjs-dist31'] const pdfjsVersions = ['pdfjs-dist213', 'pdfjs-dist31']
@ -257,6 +258,22 @@ module.exports = {
// Copy the required files for loading MathJax from MathJax NPM package // Copy the required files for loading MathJax from MathJax NPM package
new CopyPlugin({ new CopyPlugin({
patterns: [ patterns: [
// https://www.npmjs.com/package/mathjax#user-content-hosting-your-own-copy-of-the-mathjax-components
{
from: 'es5/tex-svg-full.js',
to: 'js/libs/mathjax3/es5',
context: mathjax3Dir,
},
{
from: 'es5/input/tex/extensions/**/*.js',
to: 'js/libs/mathjax3',
context: mathjax3Dir,
},
{
from: 'es5/ui/**/*',
to: 'js/libs/mathjax3',
context: mathjax3Dir,
},
{ from: 'MathJax.js', to: 'js/libs/mathjax', context: mathjaxDir }, { from: 'MathJax.js', to: 'js/libs/mathjax', context: mathjaxDir },
{ from: 'config/**/*', to: 'js/libs/mathjax', context: mathjaxDir }, { from: 'config/**/*', to: 'js/libs/mathjax', context: mathjaxDir },
{ {