Merge branch 'main' into kenclary/TNL-9943
This commit is contained in:
@@ -56,6 +56,7 @@ exports[`TextEditor snapshots block failed to load, Toast is shown 1`] = `
|
||||
"openModal": [MockFunction modal.openModal],
|
||||
"setEditorRef": [MockFunction hooks.prepareEditorRef.setEditorRef],
|
||||
"setSelection": [MockFunction hooks.selectedImage.setSelection],
|
||||
"studioEndpointUrl": "sOmEoThERvaLue.cOm",
|
||||
}
|
||||
}
|
||||
/>
|
||||
@@ -174,6 +175,7 @@ exports[`TextEditor snapshots renders as expected with default behavior 1`] = `
|
||||
"openModal": [MockFunction modal.openModal],
|
||||
"setEditorRef": [MockFunction hooks.prepareEditorRef.setEditorRef],
|
||||
"setSelection": [MockFunction hooks.selectedImage.setSelection],
|
||||
"studioEndpointUrl": "sOmEoThERvaLue.cOm",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -20,11 +20,13 @@ export const setupCustomBehavior = ({ openModal, setImage }) => (editor) => {
|
||||
// image upload button
|
||||
editor.ui.registry.addButton(tinyMCE.buttons.imageUploadButton, {
|
||||
icon: 'image',
|
||||
tooltip: 'Add Image',
|
||||
onAction: openModal,
|
||||
});
|
||||
// editing an existing image
|
||||
editor.ui.registry.addButton(tinyMCE.buttons.editImageSettings, {
|
||||
icon: 'image',
|
||||
tooltip: 'Edit Image Settings',
|
||||
onAction: module.openModalWithSelectedImage({ editor, setImage, openModal }),
|
||||
});
|
||||
// overriding the code plugin's icon with 'HTML' text
|
||||
@@ -34,14 +36,32 @@ export const setupCustomBehavior = ({ openModal, setImage }) => (editor) => {
|
||||
tooltip: 'Source code',
|
||||
onAction: openCodeEditor,
|
||||
});
|
||||
// add a custom simple inline code block formatter.
|
||||
const toggleCodeFormatting = () => editor.formatter.toggle('code');
|
||||
editor.ui.registry.addButton(tinyMCE.buttons.codeBlock, {
|
||||
icon: 'sourcecode',
|
||||
tooltip: 'Code Block',
|
||||
onAction: toggleCodeFormatting,
|
||||
});
|
||||
const toggleBlockQuoteFormatting = () => editor.formatter.toggle('blockquote');
|
||||
editor.ui.registry.addButton(tinyMCE.buttons.blockQuote, {
|
||||
icon: 'quote',
|
||||
tooltip: 'Block Quote',
|
||||
onAction: toggleBlockQuoteFormatting,
|
||||
});
|
||||
};
|
||||
|
||||
// imagetools_cors_hosts needs a protocol-sanatized url
|
||||
export const removeProtocolFromUrl = (url) => url.replace(/^https?:\/\//, '');
|
||||
|
||||
export const editorConfig = ({
|
||||
setEditorRef,
|
||||
blockValue,
|
||||
openModal,
|
||||
initializeEditor,
|
||||
setSelection,
|
||||
lmsEndpointUrl,
|
||||
studioEndpointUrl,
|
||||
}) => ({
|
||||
onInit: (evt, editor) => {
|
||||
setEditorRef(editor);
|
||||
@@ -58,6 +78,7 @@ export const editorConfig = ({
|
||||
...pluginConfig.config,
|
||||
valid_elements: '*[*]',
|
||||
valid_children: '+body[style]',
|
||||
imagetools_cors_hosts: [removeProtocolFromUrl(lmsEndpointUrl), removeProtocolFromUrl(studioEndpointUrl)],
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -65,13 +65,17 @@ describe('TextEditor hooks', () => {
|
||||
const mockOpenModalWithImage = args => ({ openModalWithSelectedImage: args });
|
||||
const expectedSettingsAction = mockOpenModalWithImage({ editor, setImage, openModal });
|
||||
const openCodeEditor = expect.any(Function);
|
||||
const toggleCodeFormatting = expect.any(Function);
|
||||
const toggleBlockQuoteFormatting = expect.any(Function);
|
||||
jest.spyOn(module, moduleKeys.openModalWithSelectedImage)
|
||||
.mockImplementationOnce(mockOpenModalWithImage);
|
||||
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.imageUploadButton, { icon: 'image', tooltip: 'Add Image', onAction: openModal }],
|
||||
[tinyMCE.buttons.editImageSettings, { icon: 'image', tooltip: 'Edit Image Settings', onAction: expectedSettingsAction }],
|
||||
[tinyMCE.buttons.code, { text: 'HTML', tooltip: 'Source code', onAction: openCodeEditor }],
|
||||
[tinyMCE.buttons.codeBlock, { icon: 'sourcecode', tooltip: 'Code Block', onAction: toggleCodeFormatting }],
|
||||
[tinyMCE.buttons.blockQuote, { icon: 'quote', tooltip: 'Block Quote', onAction: toggleBlockQuoteFormatting }],
|
||||
]);
|
||||
expect(openModal).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -80,7 +84,8 @@ describe('TextEditor hooks', () => {
|
||||
describe('editorConfig', () => {
|
||||
const props = {
|
||||
blockValue: null,
|
||||
// lmsEndpointUrl: 'sOmEuRl.cOm',
|
||||
lmsEndpointUrl: 'sOmEuRl.cOm',
|
||||
studioEndpointUrl: 'sOmEoThEruRl.cOm',
|
||||
};
|
||||
const evt = 'fakeEvent';
|
||||
const editor = 'myEditor';
|
||||
|
||||
@@ -39,6 +39,7 @@ export const TextEditor = ({
|
||||
// redux
|
||||
blockValue,
|
||||
lmsEndpointUrl,
|
||||
studioEndpointUrl,
|
||||
blockFailed,
|
||||
blockFinished,
|
||||
initializeEditor,
|
||||
@@ -86,6 +87,7 @@ export const TextEditor = ({
|
||||
openModal,
|
||||
initializeEditor,
|
||||
lmsEndpointUrl,
|
||||
studioEndpointUrl,
|
||||
setSelection: imageSelection.setSelection,
|
||||
clearSelection: imageSelection.clearSelection,
|
||||
})}
|
||||
@@ -99,6 +101,7 @@ export const TextEditor = ({
|
||||
TextEditor.defaultProps = {
|
||||
blockValue: null,
|
||||
lmsEndpointUrl: null,
|
||||
studioEndpointUrl: null,
|
||||
};
|
||||
TextEditor.propTypes = {
|
||||
onClose: PropTypes.func.isRequired,
|
||||
@@ -107,6 +110,7 @@ TextEditor.propTypes = {
|
||||
data: PropTypes.shape({ data: PropTypes.string }),
|
||||
}),
|
||||
lmsEndpointUrl: PropTypes.string,
|
||||
studioEndpointUrl: PropTypes.string,
|
||||
blockFailed: PropTypes.bool.isRequired,
|
||||
blockFinished: PropTypes.bool.isRequired,
|
||||
initializeEditor: PropTypes.func.isRequired,
|
||||
@@ -117,6 +121,7 @@ TextEditor.propTypes = {
|
||||
export const mapStateToProps = (state) => ({
|
||||
blockValue: selectors.app.blockValue(state),
|
||||
lmsEndpointUrl: selectors.app.lmsEndpointUrl(state),
|
||||
studioEndpointUrl: selectors.app.studioEndpointUrl(state),
|
||||
blockFailed: selectors.requests.isFailed(state, { requestKey: RequestKeys.fetchBlock }),
|
||||
blockFinished: selectors.requests.isFinished(state, { requestKey: RequestKeys.fetchBlock }),
|
||||
});
|
||||
|
||||
@@ -61,6 +61,7 @@ jest.mock('../../data/redux', () => ({
|
||||
app: {
|
||||
blockValue: jest.fn(state => ({ blockValue: state })),
|
||||
lmsEndpointUrl: jest.fn(state => ({ lmsEndpointUrl: state })),
|
||||
studioEndpointUrl: jest.fn(state => ({ lmsEndpointUrl: state })),
|
||||
},
|
||||
requests: {
|
||||
isFailed: jest.fn((state, params) => ({ isFailed: { state, params } })),
|
||||
@@ -75,6 +76,7 @@ describe('TextEditor', () => {
|
||||
// redux
|
||||
blockValue: { data: { some: 'eDiTablE Text' } },
|
||||
lmsEndpointUrl: 'sOmEvaLue.cOm',
|
||||
studioEndpointUrl: 'sOmEoThERvaLue.cOm',
|
||||
blockFailed: false,
|
||||
blockFinished: true,
|
||||
initializeEditor: jest.fn().mockName('args.intializeEditor'),
|
||||
|
||||
@@ -34,8 +34,8 @@ export default StrictDict({
|
||||
buttons.outdent,
|
||||
buttons.indent,
|
||||
],
|
||||
[buttons.imageUploadButton, buttons.link, buttons.unlink, buttons.table],
|
||||
[buttons.emoticons, buttons.charmap, buttons.hr],
|
||||
[buttons.imageUploadButton, buttons.link, buttons.unlink, buttons.blockQuote, buttons.codeBlock],
|
||||
[buttons.table, buttons.emoticons, buttons.charmap, buttons.hr],
|
||||
[buttons.removeFormat, buttons.code],
|
||||
]),
|
||||
imageToolbar: mapToolbars([
|
||||
|
||||
@@ -10,6 +10,8 @@ export const commands = StrictDict({
|
||||
|
||||
export const buttons = StrictDict({
|
||||
addImageButton: 'addimagebutton',
|
||||
blockQuote: 'blockQuote',
|
||||
codeBlock: 'codeBlock',
|
||||
align: StrictDict({
|
||||
center: 'aligncenter',
|
||||
justify: 'alignjustify',
|
||||
|
||||
Reference in New Issue
Block a user