diff --git a/client/src/components/Draftail/sources/ModalWorkflowSource.js b/client/src/components/Draftail/sources/ModalWorkflowSource.js index c43d8bb410..ab888c8825 100644 --- a/client/src/components/Draftail/sources/ModalWorkflowSource.js +++ b/client/src/components/Draftail/sources/ModalWorkflowSource.js @@ -119,7 +119,7 @@ class ModalWorkflowSource extends Component { $(document.body).on('hidden.bs.modal', this.onClose); // eslint-disable-next-line new-cap - global.ModalWorkflow({ + this.workflow = global.ModalWorkflow({ url, urlParams, responses: { @@ -138,6 +138,8 @@ class ModalWorkflowSource extends Component { } componentWillUnmount() { + this.workflow = null; + $(document.body).off('hidden.bs.modal', this.onClose); } @@ -172,6 +174,11 @@ class ModalWorkflowSource extends Component { } } + // IE11 crashes when rendering the new entity in contenteditable if the modal is still open. + // Other browsers do not mind. This is probably a focus management problem. + // From the user's perspective, this is all happening too fast to notice either way. + this.workflow.close(); + onComplete(nextState); } diff --git a/client/src/components/Draftail/sources/ModalWorkflowSource.test.js b/client/src/components/Draftail/sources/ModalWorkflowSource.test.js index 0f807b0aaf..fa9f980faa 100644 --- a/client/src/components/Draftail/sources/ModalWorkflowSource.test.js +++ b/client/src/components/Draftail/sources/ModalWorkflowSource.test.js @@ -210,6 +210,7 @@ describe('ModalWorkflowSource', () => { jest.spyOn(RichUtils, 'toggleLink'); const onComplete = jest.fn(); + const close = jest.fn(); let editorState = EditorState.createWithContent(convertFromRaw({ entityMap: {}, @@ -235,10 +236,12 @@ describe('ModalWorkflowSource', () => { /> )); + wrapper.instance().workflow = { close }; wrapper.instance().onChosen({}); expect(onComplete).toHaveBeenCalled(); expect(RichUtils.toggleLink).toHaveBeenCalled(); + expect(close).toHaveBeenCalled(); RichUtils.toggleLink.mockRestore(); }); @@ -247,6 +250,7 @@ describe('ModalWorkflowSource', () => { jest.spyOn(AtomicBlockUtils, 'insertAtomicBlock'); const onComplete = jest.fn(); + const close = jest.fn(); let editorState = EditorState.createWithContent(convertFromRaw({ entityMap: {}, @@ -274,10 +278,12 @@ describe('ModalWorkflowSource', () => { /> )); + wrapper.instance().workflow = { close }; wrapper.instance().onChosen({}); expect(onComplete).toHaveBeenCalled(); expect(AtomicBlockUtils.insertAtomicBlock).toHaveBeenCalled(); + expect(close).toHaveBeenCalled(); AtomicBlockUtils.insertAtomicBlock.mockRestore(); }); @@ -286,6 +292,7 @@ describe('ModalWorkflowSource', () => { jest.spyOn(Modifier, 'replaceText'); const onComplete = jest.fn(); + const close = jest.fn(); let editorState = EditorState.createWithContent(convertFromRaw({ entityMap: {}, @@ -310,6 +317,7 @@ describe('ModalWorkflowSource', () => { /> )); + wrapper.instance().workflow = { close }; wrapper.instance().onChosen({ url: 'example.com', prefer_this_title_as_link_text: true, @@ -317,6 +325,7 @@ describe('ModalWorkflowSource', () => { expect(onComplete).toHaveBeenCalled(); expect(Modifier.replaceText).toHaveBeenCalled(); + expect(close).toHaveBeenCalled(); Modifier.replaceText.mockRestore(); });