fix: initialize MathJax correctly (#57321)

Co-authored-by: Naomi <accounts+github@nhcarrigan.com>
This commit is contained in:
Sem Bauke
2024-12-23 12:53:38 +01:00
committed by GitHub
parent d9f9eeba57
commit 68550ccbb4
10 changed files with 42 additions and 44 deletions
@@ -403,13 +403,11 @@ function ShowClassic({
}) => { }) => {
return ( return (
<SidePanel <SidePanel
block={block}
challengeDescription={ challengeDescription={
<ChallengeDescription <ChallengeDescription
description={description} description={description}
instructions={instructions} instructions={instructions}
superBlock={superBlock} superBlock={superBlock}
block={block}
/> />
} }
challengeTitle={ challengeTitle={
@@ -422,7 +420,6 @@ function ShowClassic({
} }
instructionsPanelRef={instructionsPanelRef} instructionsPanelRef={instructionsPanelRef}
toolPanel={toolPanel} toolPanel={toolPanel}
superBlock={superBlock}
hasDemo={hasDemo} hasDemo={hasDemo}
/> />
); );
@@ -1,25 +1,28 @@
import React from 'react'; import React, { useEffect } from 'react';
import { initializeMathJax, isMathJaxAllowed } from '../../../utils/math-jax';
import PrismFormatted from './prism-formatted'; import PrismFormatted from './prism-formatted';
import './challenge-description.css'; import './challenge-description.css';
type Props = { type Props = {
description?: string; description?: string;
instructions?: string; instructions?: string;
superBlock?: string; superBlock: string;
block?: string;
}; };
const ChallengeDescription = ({ const ChallengeDescription = ({
description, description,
instructions, instructions,
superBlock, superBlock
block
}: Props) => { }: Props) => {
const sbClass = superBlock ? superBlock : ''; useEffect(() => {
const bClass = block ? block : ''; if (isMathJaxAllowed(superBlock)) {
initializeMathJax();
}
}, [superBlock]);
return ( return (
<div <div
className={`challenge-instructions ${sbClass} ${bClass}`} className={'challenge-instructions mathjax-support'}
data-playwright-test-label='challenge-description' data-playwright-test-label='challenge-description'
> >
{description && <PrismFormatted text={description} />} {description && <PrismFormatted text={description} />}
@@ -1,12 +1,10 @@
import React, { useEffect, ReactElement, ReactNode } from 'react'; import React, { ReactElement, ReactNode } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { Trans } from 'react-i18next'; import { Trans } from 'react-i18next';
import { Spacer } from '@freecodecamp/ui'; import { Spacer } from '@freecodecamp/ui';
import { Test } from '../../../redux/prop-types'; import { Test } from '../../../redux/prop-types';
import { SuperBlocks } from '../../../../../shared/config/curriculum';
import { initializeMathJax } from '../../../utils/math-jax';
import { challengeTestsSelector } from '../redux/selectors'; import { challengeTestsSelector } from '../redux/selectors';
import { openModal } from '../redux/actions'; import { openModal } from '../redux/actions';
import TestSuite from './test-suite'; import TestSuite from './test-suite';
@@ -30,35 +28,23 @@ type StateProps = ReturnType<typeof mapStateToProps>;
type DispatchProps = typeof mapDispatchToProps; type DispatchProps = typeof mapDispatchToProps;
interface SidePanelProps extends DispatchProps, StateProps { interface SidePanelProps extends DispatchProps, StateProps {
block: string;
challengeDescription: ReactElement; challengeDescription: ReactElement;
challengeTitle: ReactElement; challengeTitle: ReactElement;
instructionsPanelRef: React.RefObject<HTMLDivElement>; instructionsPanelRef: React.RefObject<HTMLDivElement>;
hasDemo: boolean; hasDemo: boolean;
toolPanel: ReactNode; toolPanel: ReactNode;
superBlock: SuperBlocks;
tests: Test[]; tests: Test[];
} }
export function SidePanel({ export function SidePanel({
block,
challengeDescription, challengeDescription,
challengeTitle, challengeTitle,
instructionsPanelRef, instructionsPanelRef,
hasDemo, hasDemo,
toolPanel, toolPanel,
superBlock,
tests, tests,
openModal openModal
}: SidePanelProps): JSX.Element { }: SidePanelProps): JSX.Element {
useEffect(() => {
const mathJaxChallenge =
superBlock === SuperBlocks.RosettaCode ||
superBlock === SuperBlocks.ProjectEuler ||
block === 'intermediate-algorithm-scripting';
initializeMathJax(mathJaxChallenge);
}, [block, superBlock]);
return ( return (
<div <div
className='instructions-panel' className='instructions-panel'
@@ -217,7 +217,10 @@ const ShowGeneric = ({
{description && ( {description && (
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}> <Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
<ChallengeDescription description={description} /> <ChallengeDescription
description={description}
superBlock={superBlock}
/>
<Spacer size='m' /> <Spacer size='m' />
</Col> </Col>
)} )}
@@ -239,7 +242,10 @@ const ShowGeneric = ({
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}> <Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
{instructions && ( {instructions && (
<ChallengeDescription instructions={instructions} /> <ChallengeDescription
instructions={instructions}
superBlock={superBlock}
/>
)} )}
<Spacer size='m' /> <Spacer size='m' />
@@ -184,6 +184,7 @@ function MsTrophy(props: MsTrophyProps) {
{title} {title}
</ChallengeTitle> </ChallengeTitle>
<ChallengeDescription <ChallengeDescription
superBlock={superBlock}
description={description} description={description}
instructions={instructions} instructions={instructions}
/> />
@@ -189,6 +189,7 @@ const ShowBackEnd = (props: BackEndProps) => {
{title} {title}
</ChallengeTitle> </ChallengeTitle>
<ChallengeDescription <ChallengeDescription
superBlock={superBlock}
description={description} description={description}
instructions={instructions} instructions={instructions}
/> />
@@ -158,6 +158,7 @@ const ShowFrontEndProject = (props: ProjectProps) => {
{title} {title}
</ChallengeTitle> </ChallengeTitle>
<ChallengeDescription <ChallengeDescription
superBlock={superBlock}
description={description} description={description}
instructions={instructions} instructions={instructions}
/> />
@@ -313,7 +313,10 @@ const ShowQuiz = ({
<Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}> <Col md={8} mdOffset={2} sm={10} smOffset={1} xs={12}>
<Spacer size='m' /> <Spacer size='m' />
<ChallengeDescription description={description} /> <ChallengeDescription
description={description}
superBlock={superBlock}
/>
<Spacer size='l' /> <Spacer size='l' />
<ObserveKeys> <ObserveKeys>
<Quiz questions={quizData} disabled={hasSubmitted} /> <Quiz questions={quizData} disabled={hasSubmitted} />
+12 -12
View File
@@ -1,15 +1,19 @@
import { SuperBlocks } from '../../../shared/config/curriculum';
import { scriptLoader } from './script-loaders'; import { scriptLoader } from './script-loaders';
export const mathJaxSrc = export const mathJaxSrc =
'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-AMS_HTML'; 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.4/MathJax.js?config=TeX-AMS_HTML';
export const isMathJaxAllowed = (pathname: string) => export const isMathJaxAllowed = (pathname: string) =>
[ superBlocksWithMathJax.some(superBlock => pathname.includes(superBlock));
'/learn/javascript-algorithms-and-data-structures-v8',
'/learn/project-euler/', const superBlocksWithMathJax = [
'/learn/rosetta-code', SuperBlocks.JsAlgoDataStructNew,
'/learn/scientific-computing-with-python' SuperBlocks.JsAlgoDataStruct,
].some(allowedPath => pathname.includes(allowedPath)); SuperBlocks.ProjectEuler,
SuperBlocks.RosettaCode,
SuperBlocks.SciCompPy
];
const configure = () => { const configure = () => {
if (!global.MathJax) return; if (!global.MathJax) return;
@@ -21,17 +25,13 @@ const configure = () => {
['\\(', '\\)'] ['\\(', '\\)']
], ],
processEscapes: true, processEscapes: true,
processClass: processClass: 'mathjax-support'
'rosetta-code|project-euler|intermediate-algorithm-scripting|description-container'
} }
}); });
MathJax.Hub.Queue([ MathJax.Hub.Queue([
'Typeset', 'Typeset',
MathJax.Hub, MathJax.Hub,
document.querySelector('.intermediate-algorithm-scripting'), document.querySelector('.mathjax-support')
document.querySelector('.rosetta-code'),
document.querySelector('.project-euler'),
document.querySelector('.description-container')
]); ]);
}; };
+2 -2
View File
@@ -44,7 +44,7 @@ export function getheadTagComponents(): JSX.Element[] {
return headTags; return headTags;
} }
export function getPostBodyComponents(pathname: string): JSX.Element[] { export function getPostBodyComponents(superblock: string): JSX.Element[] {
const scripts = []; const scripts = [];
const mathJaxScriptElement = ( const mathJaxScriptElement = (
<script <script
@@ -56,7 +56,7 @@ export function getPostBodyComponents(pathname: string): JSX.Element[] {
/> />
); );
if (isMathJaxAllowed(pathname)) { if (isMathJaxAllowed(superblock)) {
scripts.push(mathJaxScriptElement); scripts.push(mathJaxScriptElement);
} }