Skip to content

Commit 64c0e33

Browse files
committed
refactor: add custom hook to manage static replacement
1 parent 3b0be94 commit 64c0e33

5 files changed

Lines changed: 56 additions & 18 deletions

File tree

src/editors/containers/ProblemEditor/components/EditProblemView/ExplanationWidget/index.jsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { getConfig } from '@edx/frontend-platform';
77
import { selectors } from '../../../../../data/redux';
88
import messages from './messages';
99
import TinyMceWidget from '../../../../../sharedComponents/TinyMceWidget';
10-
import { prepareEditorRef, replaceStaticWithAsset } from '../../../../../sharedComponents/TinyMceWidget/hooks';
10+
import { prepareEditorRef, useProcessedEditorContent } from '../../../../../sharedComponents/TinyMceWidget/hooks';
1111

1212
const ExplanationWidget = ({
1313
// redux
@@ -19,12 +19,11 @@ const ExplanationWidget = ({
1919
}) => {
2020
const intl = useIntl();
2121
const { editorRef, refReady, setEditorRef } = prepareEditorRef();
22-
const initialContent = settings?.solutionExplanation || '';
23-
const newContent = replaceStaticWithAsset({
24-
initialContent,
22+
23+
const solutionContent = useProcessedEditorContent({
24+
initialContent: settings?.solutionExplanation || '',
2525
learningContextId,
2626
});
27-
const solutionContent = newContent || initialContent;
2827
let staticRootUrl;
2928
if (isLibrary) {
3029
staticRootUrl = `${getConfig().STUDIO_BASE_URL }/library_assets/blocks/${ blockId }/`;

src/editors/containers/ProblemEditor/components/EditProblemView/QuestionWidget/index.jsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { getConfig } from '@edx/frontend-platform';
77
import { selectors } from '../../../../../data/redux';
88
import messages from './messages';
99
import TinyMceWidget from '../../../../../sharedComponents/TinyMceWidget';
10-
import { prepareEditorRef, replaceStaticWithAsset } from '../../../../../sharedComponents/TinyMceWidget/hooks';
10+
import { prepareEditorRef, useProcessedEditorContent } from '../../../../../sharedComponents/TinyMceWidget/hooks';
1111

1212
const QuestionWidget = ({
1313
// redux
@@ -19,12 +19,11 @@ const QuestionWidget = ({
1919
}) => {
2020
const intl = useIntl();
2121
const { editorRef, refReady, setEditorRef } = prepareEditorRef();
22-
const initialContent = question;
23-
const newContent = replaceStaticWithAsset({
24-
initialContent,
22+
23+
const questionContent = useProcessedEditorContent({
24+
initialContent: question,
2525
learningContextId,
2626
});
27-
const questionContent = newContent || initialContent;
2827
let staticRootUrl;
2928
if (isLibrary) {
3029
staticRootUrl = `${getConfig().STUDIO_BASE_URL }/library_assets/blocks/${ blockId }/`;

src/editors/containers/TextEditor/index.jsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import RawEditor from '../../sharedComponents/RawEditor';
1717
import * as hooks from './hooks';
1818
import messages from './messages';
1919
import TinyMceWidget from '../../sharedComponents/TinyMceWidget';
20-
import { prepareEditorRef, replaceStaticWithAsset } from '../../sharedComponents/TinyMceWidget/hooks';
20+
import { prepareEditorRef, useProcessedEditorContent } from '../../sharedComponents/TinyMceWidget/hooks';
2121

2222
const TextEditor = ({
2323
onClose,
@@ -36,13 +36,12 @@ const TextEditor = ({
3636
}) => {
3737
const intl = useIntl();
3838
const { editorRef, refReady, setEditorRef } = prepareEditorRef();
39-
const initialContent = blockValue ? blockValue.data.data : '';
40-
const newContent = replaceStaticWithAsset({
41-
initialContent,
39+
40+
const editorContent = useProcessedEditorContent({
41+
initialContent: blockValue ? blockValue.data.data : '',
4242
learningContextId,
4343
validateAssetUrl,
4444
});
45-
const editorContent = newContent || initialContent;
4645
let staticRootUrl;
4746
if (isLibrary) {
4847
staticRootUrl = `${getConfig().STUDIO_BASE_URL }/library_assets/blocks/${ blockId }/`;

src/editors/containers/TextEditor/index.test.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import React from 'react';
2-
import { render, screen, initializeMocks } from '@src/testUtils';
2+
import {
3+
render, screen, initializeMocks, waitFor,
4+
} from '@src/testUtils';
35
import { actions, selectors } from '../../data/redux';
46
import { RequestKeys } from '../../data/constants/requests';
57
import { TextEditorInternal as TextEditor, mapStateToProps, mapDispatchToProps } from '.';
@@ -67,7 +69,7 @@ describe('TextEditor', () => {
6769
expect(element?.getAttribute('editorcontenthtml')).toBe('eDiTablE Text');
6870
});
6971

70-
test('renders static images with relative paths', () => {
72+
test('renders static images with relative paths', async () => {
7173
const updatedProps = {
7274
...props,
7375
validateAssetUrl: false,
@@ -76,7 +78,11 @@ describe('TextEditor', () => {
7678
const { container } = render(<TextEditor {...updatedProps} />);
7779
const element = container.querySelector('tinymcewidget');
7880
expect(element).toBeInTheDocument();
79-
expect(element?.getAttribute('editorcontenthtml')).toBe('eDiTablE Text with <img src="/asset+org+run+type@[email protected]" />');
81+
await waitFor(() => {
82+
expect(element?.getAttribute('editorcontenthtml')).toBe(
83+
'eDiTablE Text with <img src="/asset+org+run+type@[email protected]" />',
84+
);
85+
});
8086
});
8187
test('not yet loaded, Spinner appears', () => {
8288
const { container } = render(<TextEditor {...props} blockFinished={false} />);

src/editors/sharedComponents/TinyMceWidget/hooks.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,3 +577,38 @@ export const selectedImage = (val) => {
577577
setSelection,
578578
};
579579
};
580+
581+
export const useProcessedEditorContent = ({
582+
initialContent,
583+
learningContextId,
584+
editorType,
585+
validateAssetUrl = false,
586+
}) => {
587+
const [content, setContent] = useState(initialContent);
588+
589+
useEffect(() => {
590+
let mounted = true;
591+
592+
const process = async () => {
593+
const newContent = await replaceStaticWithAsset({
594+
initialContent,
595+
learningContextId,
596+
editorType,
597+
lmsEndpointUrl: getConfig().LMS_BASE_URL,
598+
validateAssetUrl,
599+
});
600+
601+
if (mounted) {
602+
setContent(newContent || initialContent);
603+
}
604+
};
605+
606+
process();
607+
608+
return () => {
609+
mounted = false;
610+
};
611+
}, [initialContent, learningContextId, editorType, validateAssetUrl]);
612+
613+
return content;
614+
};

0 commit comments

Comments
 (0)