diff --git a/src/editors/containers/TextEditor/hooks.js b/src/editors/containers/TextEditor/hooks.js index fa314be19..5a9b84ba3 100644 --- a/src/editors/containers/TextEditor/hooks.js +++ b/src/editors/containers/TextEditor/hooks.js @@ -16,15 +16,24 @@ export const state = StrictDict({ refReady: (val) => useState(val), }); -export const addImageUploadBehavior = ({ openModal, setImage }) => (editor) => { +export const setupCustomBehavior = ({ openModal, setImage }) => (editor) => { + // image upload button editor.ui.registry.addButton(tinyMCE.buttons.imageUploadButton, { icon: 'image', onAction: openModal, }); + // editing an existing image editor.ui.registry.addButton(tinyMCE.buttons.editImageSettings, { icon: 'image', onAction: module.openModalWithSelectedImage({ editor, setImage, openModal }), }); + // overriding the code plugin's icon with 'HTML' text + const openCodeEditor = () => editor.execCommand('mceCodeEditor'); + editor.ui.registry.addButton(tinyMCE.buttons.code, { + text: 'HTML', + tooltip: 'Source code', + onAction: openCodeEditor, + }); }; export const editorConfig = ({ @@ -40,7 +49,7 @@ export const editorConfig = ({ }, initialValue: blockValue ? blockValue.data.data : '', init: { - setup: module.addImageUploadBehavior({ openModal, setImage: setSelection }), + setup: module.setupCustomBehavior({ openModal, setImage: setSelection }), plugins: pluginConfig.plugins, imagetools_toolbar: pluginConfig.imageToolbar, toolbar: pluginConfig.toolbar, diff --git a/src/editors/containers/TextEditor/hooks.test.jsx b/src/editors/containers/TextEditor/hooks.test.jsx index 6d07eedad..8610dd446 100644 --- a/src/editors/containers/TextEditor/hooks.test.jsx +++ b/src/editors/containers/TextEditor/hooks.test.jsx @@ -54,7 +54,7 @@ describe('TextEditor hooks', () => { beforeEach(() => { state.mock(); }); afterEach(() => { state.restore(); }); - describe('addImageUploadBehavior', () => { + describe('setupCustomBehavior', () => { test('It calls addButton in the editor, but openModal is not called', () => { const addButton = jest.fn(); const openModal = jest.fn(); @@ -64,12 +64,14 @@ describe('TextEditor hooks', () => { }; const mockOpenModalWithImage = args => ({ openModalWithSelectedImage: args }); const expectedSettingsAction = mockOpenModalWithImage({ editor, setImage, openModal }); + const openCodeEditor = expect.any(Function); jest.spyOn(module, moduleKeys.openModalWithSelectedImage) .mockImplementationOnce(mockOpenModalWithImage); - output = module.addImageUploadBehavior({ openModal, setImage })(editor); + output = module.setupCustomBehavior({ openModal, setImage })(editor); expect(addButton.mock.calls).toEqual([ [tinyMCE.buttons.imageUploadButton, { icon: 'image', onAction: openModal }], [tinyMCE.buttons.editImageSettings, { icon: 'image', onAction: expectedSettingsAction }], + [tinyMCE.buttons.code, { text: 'HTML', tooltip: 'Source code', onAction: openCodeEditor }], ]); expect(openModal).not.toHaveBeenCalled(); }); @@ -82,13 +84,13 @@ describe('TextEditor hooks', () => { }; const evt = 'fakeEvent'; const editor = 'myEditor'; - const addImageUploadBehavior = args => ({ addImageUploadBehvaior: args }); + const setupCustomBehavior = args => ({ setupCustomBehavior: args }); beforeEach(() => { props.setEditorRef = jest.fn(); props.openModal = jest.fn(); props.initializeEditor = jest.fn(); - jest.spyOn(module, moduleKeys.addImageUploadBehavior) - .mockImplementationOnce(addImageUploadBehavior); + jest.spyOn(module, moduleKeys.setupCustomBehavior) + .mockImplementationOnce(setupCustomBehavior); output = module.editorConfig(props); }); test('It creates an onInit which calls initializeEditor and setEditorRef', () => { @@ -115,9 +117,9 @@ describe('TextEditor hooks', () => { // Commented out as we investigate whether this is only needed for image proxy // expect(output.init.imagetools_cors_hosts).toMatchObject([props.lmsEndpointUrl]); }); - it('calls addImageUploadBehavior on setup', () => { + it('calls setupCustomBehavior on setup', () => { expect(output.init.setup).toEqual( - addImageUploadBehavior({ openModal: props.openModal, setImage: props.setSelection }), + setupCustomBehavior({ openModal: props.openModal, setImage: props.setSelection }), ); }); }); diff --git a/src/editors/data/constants/tinyMCE.js b/src/editors/data/constants/tinyMCE.js index 05ad1bcc1..baeeb67b3 100644 --- a/src/editors/data/constants/tinyMCE.js +++ b/src/editors/data/constants/tinyMCE.js @@ -21,7 +21,7 @@ export const buttons = StrictDict({ bold: 'bold', bullist: 'bullist', charmap: 'charmap', - code: 'code', + code: 'code-modified', // use a custom button name, consistently, for our text-only button codesample: 'codesample', editImageSettings: 'editimagesettings', emoticons: 'emoticons',