Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: image and paste insert #490

Merged
merged 3 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/editors/sharedComponents/ImageUploadModal/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export const hooks = {
updateReactState({ settings, ...args });

close();
args.setSelection(null);
},
onClose: ({ clearSelection, close }) => () => {
clearSelection();
Expand Down Expand Up @@ -130,7 +131,7 @@ export const ImageUploadModal = ({
<ImageSettingsModal
{...{
isOpen,
close: module.hooks.onClose({ editorRef, clearSelection, close }),
close: module.hooks.onClose({ clearSelection, close }),
selection,
images,
saveToEditor: module.hooks.createSaveCallback({
Expand All @@ -141,6 +142,7 @@ export const ImageUploadModal = ({
selection,
setSelection,
lmsEndpointUrl,
clearSelection,
}),
returnToSelection: clearSelection,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ describe('ImageUploadModal', () => {
expect(updateImageDimensionsSpy.mock.results[0].value.foundMatch).toBe(false);
expect(images.current).toEqual([mockImage, newImage]);
expect(close).toBeCalled();
expect(setSelection).toBeCalledWith(null);
},
);
});
Expand Down
62 changes: 32 additions & 30 deletions src/editors/sharedComponents/TinyMceWidget/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,38 +77,40 @@ export const replaceStaticWithAsset = ({
lmsEndpointUrl,
}) => {
let content = initialContent;
let hasChanges = false;
const srcs = content.split(/(src="|src=&quot;|href="|href=&quot)/g).filter(
src => src.startsWith('/static') || src.startsWith('/asset'),
);
if (isEmpty(srcs)) {
return initialContent;
}
srcs.forEach(src => {
const currentContent = content;
let staticFullUrl;
const isStatic = src.startsWith('/static/');
const assetSrc = src.substring(0, src.indexOf('"'));
const staticName = assetSrc.substring(8);
const assetName = assetSrc.replace(/\/assets\/.+[^/]\//g, '');
const displayName = isStatic ? staticName : assetName;
const isCorrectAssetFormat = assetSrc.match(/\/asset-v1:\S+[+]\S+[@]\S+[+]\S+[@]/g)?.length >= 1;
// assets in expandable text areas so not support relative urls so all assets must have the lms
// endpoint prepended to the relative url
if (editorType === 'expandable') {
if (isCorrectAssetFormat) {
staticFullUrl = `${lmsEndpointUrl}${assetSrc}`;
} else {
staticFullUrl = `${lmsEndpointUrl}${getRelativeUrl({ courseId: learningContextId, displayName })}`;
if (!isEmpty(srcs)) {
srcs.forEach(src => {
const currentContent = content;
let staticFullUrl;
const isStatic = src.startsWith('/static/');
const assetSrc = src.substring(0, src.indexOf('"'));
const staticName = assetSrc.substring(8);
const assetName = assetSrc.replace(/\/assets\/.+[^/]\//g, '');
const displayName = isStatic ? staticName : assetName;
const isCorrectAssetFormat = assetSrc.match(/\/asset-v1:\S+[+]\S+[@]\S+[+]\S+[@]/g)?.length >= 1;
// assets in expandable text areas so not support relative urls so all assets must have the lms
// endpoint prepended to the relative url
if (editorType === 'expandable') {
if (isCorrectAssetFormat) {
staticFullUrl = `${lmsEndpointUrl}${assetSrc}`;
} else {
staticFullUrl = `${lmsEndpointUrl}${getRelativeUrl({ courseId: learningContextId, displayName })}`;
}
} else if (!isCorrectAssetFormat) {
staticFullUrl = getRelativeUrl({ courseId: learningContextId, displayName });
}
} else if (!isCorrectAssetFormat) {
staticFullUrl = getRelativeUrl({ courseId: learningContextId, displayName });
}
if (staticFullUrl) {
const currentSrc = src.substring(0, src.indexOf('"'));
content = currentContent.replace(currentSrc, staticFullUrl);
}
});
return content;
if (staticFullUrl) {
const currentSrc = src.substring(0, src.indexOf('"'));
content = currentContent.replace(currentSrc, staticFullUrl);
hasChanges = true;
}
});
if (hasChanges) { return content; }
}
return false;
};

export const getImageResizeHandler = ({ editor, imagesRef, setImage }) => () => {
Expand Down Expand Up @@ -196,7 +198,7 @@ export const setupCustomBehavior = ({
lmsEndpointUrl,
learningContextId,
});
updateContent(newContent);
if (newContent) { updateContent(newContent); }
});
}
editor.on('ExecCommand', (e) => {
Expand All @@ -206,7 +208,7 @@ export const setupCustomBehavior = ({
initialContent,
learningContextId,
});
editor.setContent(newContent);
if (newContent) { editor.setContent(newContent); }
}
if (e.command === 'RemoveFormat') {
editor.formatter.remove('blockquote');
Expand Down
17 changes: 11 additions & 6 deletions src/editors/sharedComponents/TinyMceWidget/hooks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,17 @@ describe('TinyMceEditor hooks', () => {
});

describe('replaceStaticWithAsset', () => {
const initialContent = '<img src="/static/soMEImagEURl1.jpeg"/><a href="/assets/v1/some-key/test.pdf">test</a>';
const learningContextId = 'course+test+run';
const initialContent = '<img src="/static/soMEImagEURl1.jpeg"/><a href="/assets/v1/some-key/test.pdf">test</a><img src="/asset-v1:org+test+run+type@[email protected]" />';
const learningContextId = 'course-v1:org+test+run';
const lmsEndpointUrl = 'sOmEvaLue.cOm';
it('it returns updated src for text editor to update content', () => {
const expected = '<img src="/asset+test+run+type@[email protected]"/><a href="/asset+test+run+type@[email protected]">test</a>';
it('returns updated src for text editor to update content', () => {
const expected = '<img src="/asset-v1:org+test+run+type@[email protected]"/><a href="/asset-v1:org+test+run+type@[email protected]">test</a><img src="/asset-v1:org+test+run+type@[email protected]" />';
const actual = module.replaceStaticWithAsset({ initialContent, learningContextId });
expect(actual).toEqual(expected);
});
it('it returs updated src with absolute url for expandable editor to update content', () => {
it('returns updated src with absolute url for expandable editor to update content', () => {
const editorType = 'expandable';
const expected = `<img src="${lmsEndpointUrl}/asset+test+run+type@[email protected]"/><a href="${lmsEndpointUrl}/asset+test+run+type@[email protected]">test</a>`;
const expected = `<img src="${lmsEndpointUrl}/asset-v1:org+test+run+type@[email protected]"/><a href="${lmsEndpointUrl}/asset-v1:org+test+run+type@[email protected]">test</a><img src="${lmsEndpointUrl}/asset-v1:org+test+run+type@[email protected]" />`;
const actual = module.replaceStaticWithAsset({
initialContent,
editorType,
Expand All @@ -201,6 +201,11 @@ describe('TinyMceEditor hooks', () => {
});
expect(actual).toEqual(expected);
});
it('returns false when there are no srcs to update', () => {
const content = '<div>Hello world!</div>';
const actual = module.replaceStaticWithAsset({ initialContent: content, learningContextId });
expect(actual).toBeFalsy();
});
});
describe('setAssetToStaticUrl', () => {
it('returns content with updated img links', () => {
Expand Down
Loading