diff --git a/client/src/entrypoints/admin/draftail.js b/client/src/entrypoints/admin/draftail.js index 5ceb905191..6534c43c7a 100644 --- a/client/src/entrypoints/admin/draftail.js +++ b/client/src/entrypoints/admin/draftail.js @@ -45,3 +45,18 @@ const entityTypes = [ ]; entityTypes.forEach((type) => draftail.registerPlugin(type, 'entityTypes')); + +/** + * Initialize a Draftail editor on a given element when the w-draftail:init event is fired. + */ +document.addEventListener('w-draftail:init', ({ detail = {}, target }) => { + const id = target.id; + + if (!id) { + // eslint-disable-next-line no-console + console.error('`w-draftail:init` event must have a target with an id.'); + return; + } + + window.draftail.initEditor(`#${id}`, detail, document.currentScript); +}); diff --git a/client/src/entrypoints/admin/draftail.test.js b/client/src/entrypoints/admin/draftail.test.js index 86eb1a3b1a..2484e85740 100644 --- a/client/src/entrypoints/admin/draftail.test.js +++ b/client/src/entrypoints/admin/draftail.test.js @@ -47,3 +47,65 @@ describe('draftail', () => { ).toEqual(['DOCUMENT', 'LINK', 'IMAGE', 'EMBED', 'undefined']); }); }); + +describe('Calling initEditor via event dispatching', () => { + const initEditor = window.draftail.initEditor; + + beforeAll(() => { + /* eslint-disable no-console */ + // mock console.error to ensure it does not bubble to the logs + jest.spyOn(console, 'error').mockImplementation(() => {}); + jest.spyOn(window.draftail, 'initEditor').mockImplementation(() => {}); + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + it.only('should support creating a new editor with event dispatching', async () => { + expect(window.draftail.initEditor).not.toHaveBeenCalled(); + + document.body.innerHTML = '
'; + + document.getElementById('editor').dispatchEvent( + new CustomEvent('w-draftail:init', { + bubbles: true, + cancelable: false, + detail: { some: 'detail' }, + }), + ); + + expect(console.error).toHaveBeenCalledTimes(0); + expect(window.draftail.initEditor).toHaveBeenCalledTimes(1); + expect(window.draftail.initEditor).toHaveBeenLastCalledWith( + '#editor', + { some: 'detail' }, + null, + ); + }); + + it('should not call initEditor & show an error in the console if the event has been dispatched incorrectly', async () => { + expect(window.draftail.initEditor).not.toHaveBeenCalled(); + + document.dispatchEvent( + new CustomEvent('w-draftail:init', { + bubbles: true, + cancelable: false, + detail: { some: 'detail' }, + }), + ); + + expect(console.error).toHaveBeenCalledTimes(1); + expect(console.error).toHaveBeenCalledWith( + '`w-draftail:init` event must have a target with an id.', + ); + + expect(window.draftail.initEditor).not.toHaveBeenCalled(); + }); + + afterAll(() => { + console.error.mockRestore(); + window.draftail.initEditor.mockRestore(); + /* eslint-enable no-console */ + }); +});