From aecfce73ec3284fc986e68aee1227da53a75acce Mon Sep 17 00:00:00 2001 From: Thibaud Colas Date: Fri, 9 Feb 2018 12:09:53 +0200 Subject: [PATCH] Refactor Draftail exports to match exposed module --- client/src/components/Draftail/index.js | 30 ++++++++++++++----- client/src/components/Draftail/index.test.js | 27 ++++++++++++----- client/src/components/Draftail/registry.js | 14 --------- .../src/components/Draftail/registry.test.js | 15 ---------- .../wagtailadmin/app/draftail.entry.js | 8 ++--- .../wagtailadmin/app/draftail.entry.test.js | 5 +--- 6 files changed, 44 insertions(+), 55 deletions(-) delete mode 100644 client/src/components/Draftail/registry.js delete mode 100644 client/src/components/Draftail/registry.test.js diff --git a/client/src/components/Draftail/index.js b/client/src/components/Draftail/index.js index b0b7071ba1..2f4d94f147 100644 --- a/client/src/components/Draftail/index.js +++ b/client/src/components/Draftail/index.js @@ -6,10 +6,6 @@ import { IS_IE11, STRINGS } from '../../config/wagtailConfig'; import Icon from '../Icon/Icon'; -import registry from './registry'; - -export { registry }; - export { default as Link } from './decorators/Link'; export { default as Document } from './decorators/Document'; export { default as ImageBlock } from './blocks/ImageBlock'; @@ -17,6 +13,20 @@ export { default as EmbedBlock } from './blocks/EmbedBlock'; export { default as ModalWorkflowSource } from './sources/ModalWorkflowSource'; +/** + * Registry for client-side code of Draftail plugins. + */ +const PLUGINS = {}; + +const registerPlugin = (plugin) => { + PLUGINS[plugin.type] = plugin; + return PLUGINS; +}; + +/** + * Wraps a style/block/entity type’s icon with an icon font implementation, + * so Draftail can use icon fonts in its toolbar. + */ export const wrapWagtailIcon = type => { const isIconFont = type.icon && typeof type.icon === 'string'; if (isIconFont) { @@ -33,7 +43,7 @@ export const wrapWagtailIcon = type => { * @param {string} fieldName * @param {Object} options */ -export const initEditor = (fieldName, options) => { +const initEditor = (fieldName, options) => { const field = document.querySelector(`[name="${fieldName}"]`); const editorWrapper = document.createElement('div'); field.parentNode.appendChild(editorWrapper); @@ -47,9 +57,9 @@ export const initEditor = (fieldName, options) => { let entityTypes = options.entityTypes || []; entityTypes = entityTypes.map(wrapWagtailIcon).map((type) => { - const plugin = registry.getPlugin(type.type); - // Override the properties defined in the JS plugin: Python should be the source of truth. + const plugin = PLUGINS[type.type]; + // Override the properties defined in the JS plugin: Python should be the source of truth. return Object.assign({}, plugin, type); }); @@ -68,7 +78,6 @@ export const initEditor = (fieldName, options) => { enableLineBreak={{ description: STRINGS.LINE_BREAK }} showUndoControl={{ description: STRINGS.UNDO }} showRedoControl={{ description: STRINGS.REDO }} - // If increasing above 4, we will need to add styles for the extra nesting levels. maxListNesting={4} // Draft.js + IE 11 presents some issues with pasting rich text. Disable rich paste there. stripPastedStyles={IS_IE11} @@ -85,3 +94,8 @@ export const initEditor = (fieldName, options) => { // Bind editor instance to its field so it can be accessed imperatively elsewhere. field.draftailEditor = draftailEditor; }; + +export default { + initEditor, + registerPlugin, +}; diff --git a/client/src/components/Draftail/index.test.js b/client/src/components/Draftail/index.test.js index 09a3394370..1eee419b30 100644 --- a/client/src/components/Draftail/index.test.js +++ b/client/src/components/Draftail/index.test.js @@ -1,7 +1,5 @@ -import { +import draftail, { wrapWagtailIcon, - initEditor, - registry, ModalWorkflowSource, Link, Document, @@ -21,7 +19,7 @@ describe('Draftail', () => { field.value = 'null'; document.body.appendChild(field); - initEditor('test', {}); + draftail.initEditor('test', {}); expect(field.draftailEditor).toBeDefined(); }); @@ -32,7 +30,7 @@ describe('Draftail', () => { field.value = 'null'; document.body.appendChild(field); - initEditor('test', {}); + draftail.initEditor('test', {}); field.draftailEditor.saveState(); @@ -45,13 +43,13 @@ describe('Draftail', () => { field.value = 'null'; document.body.appendChild(field); - registry.registerPlugin({ + draftail.registerPlugin({ type: 'IMAGE', source: () => {}, block: () => {}, }); - initEditor('test', { + draftail.initEditor('test', { entityTypes: [ { type: 'IMAGE' }, ], @@ -78,7 +76,20 @@ describe('Draftail', () => { }); }); - it('#registry', () => expect(registry).toBeDefined()); + describe('#registerPlugin', () => { + it('works', () => { + const plugin = { + type: 'TEST', + source: null, + decorator: null, + }; + + expect(draftail.registerPlugin(plugin)).toMatchObject({ + TEST: plugin, + }); + }); + }); + it('#ModalWorkflowSource', () => expect(ModalWorkflowSource).toBeDefined()); it('#Link', () => expect(Link).toBeDefined()); it('#Document', () => expect(Document).toBeDefined()); diff --git a/client/src/components/Draftail/registry.js b/client/src/components/Draftail/registry.js deleted file mode 100644 index 17503985f0..0000000000 --- a/client/src/components/Draftail/registry.js +++ /dev/null @@ -1,14 +0,0 @@ -const plugins = {}; - -const registerPlugin = (plugin) => { - plugins[plugin.type] = plugin; - - return plugins; -}; - -const getPlugin = (type) => plugins[type]; - -export default { - registerPlugin, - getPlugin, -}; diff --git a/client/src/components/Draftail/registry.test.js b/client/src/components/Draftail/registry.test.js deleted file mode 100644 index 009a178630..0000000000 --- a/client/src/components/Draftail/registry.test.js +++ /dev/null @@ -1,15 +0,0 @@ -import registry from './registry'; - -describe('registry', () => { - it('works', () => { - const plugin = { - type: 'TEST', - source: null, - decorator: null, - }; - - expect(registry.getPlugin('TEST')).not.toBeDefined(); - registry.registerPlugin(plugin); - expect(registry.getPlugin('TEST')).toBe(plugin); - }); -}); diff --git a/wagtail/admin/static_src/wagtailadmin/app/draftail.entry.js b/wagtail/admin/static_src/wagtailadmin/app/draftail.entry.js index 4cacedf1b3..1664ba6f11 100644 --- a/wagtail/admin/static_src/wagtailadmin/app/draftail.entry.js +++ b/wagtail/admin/static_src/wagtailadmin/app/draftail.entry.js @@ -1,6 +1,4 @@ -import { - initEditor, - registry, +import draftail, { ModalWorkflowSource, Link, Document, @@ -11,10 +9,8 @@ import { /** * Entry point loaded when the Draftail editor is in use. */ -const draftail = registry; -// Expose Draftail as a global, with the initEditor function. -draftail.initEditor = initEditor; +// Expose module as a global. window.draftail = draftail; // Plugins for the built-in entities. diff --git a/wagtail/admin/static_src/wagtailadmin/app/draftail.entry.test.js b/wagtail/admin/static_src/wagtailadmin/app/draftail.entry.test.js index 48acdc73e7..93188906c3 100644 --- a/wagtail/admin/static_src/wagtailadmin/app/draftail.entry.test.js +++ b/wagtail/admin/static_src/wagtailadmin/app/draftail.entry.test.js @@ -6,9 +6,6 @@ describe('draftail.entry', () => { }); it('has defaults registered', () => { - expect(window.draftail.getPlugin('LINK')).toBeDefined(); - expect(window.draftail.getPlugin('DOCUMENT')).toBeDefined(); - expect(window.draftail.getPlugin('IMAGE')).toBeDefined(); - expect(window.draftail.getPlugin('EMBED')).toBeDefined(); + expect(Object.keys(window.draftail.registerPlugin({}))).toEqual(["DOCUMENT", "LINK", "IMAGE", "EMBED", "undefined"]); }); });