From 1738957af7bd37e8b5f53d75b3b6858f3ca1d45d Mon Sep 17 00:00:00 2001 From: David Wheatley <hi@davwheat.dev> Date: Thu, 30 Dec 2021 22:02:25 +0100 Subject: [PATCH] feat: make markdown toolbar extensible (#33) --- extensions/markdown/js/src/forum/index.js | 63 ++++++++++++++++------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/extensions/markdown/js/src/forum/index.js b/extensions/markdown/js/src/forum/index.js index 9ee2c8ab4..1cb9a8f46 100644 --- a/extensions/markdown/js/src/forum/index.js +++ b/extensions/markdown/js/src/forum/index.js @@ -8,13 +8,14 @@ */ import app from 'flarum/forum/app'; -import { extend } from 'flarum/common/extend'; +import { extend, override } from 'flarum/common/extend'; import TextEditor from 'flarum/common/components/TextEditor'; import BasicEditorDriver from 'flarum/common/utils/BasicEditorDriver'; import styleSelectedText from 'flarum/common/utils/styleSelectedText'; import MarkdownToolbar from './components/MarkdownToolbar'; import MarkdownButton from './components/MarkdownButton'; +import ItemList from 'flarum/common/utils/ItemList'; const modifierKey = navigator.userAgent.match(/Macintosh/) ? '⌘' : 'ctrl'; @@ -48,35 +49,57 @@ function makeShortcut(id, key, editorDriver) { }; } +function markdownToolbarItems(oldFunc) { + const items = typeof oldFunc === 'function' ? oldFunc() : new ItemList(); + + function tooltip(name, hotkey) { + return app.translator.trans(`flarum-markdown.forum.composer.${name}_tooltip`) + (hotkey ? ` <${modifierKey}-${hotkey}>` : ''); + } + + const makeApplyStyle = (id) => { + return () => applyStyle(id, this.attrs.composer.editor); + }; + + items.add('header', <MarkdownButton title={tooltip('header')} icon="fas fa-heading" onclick={makeApplyStyle('header')} />, 1000); + items.add('bold', <MarkdownButton title={tooltip('bold', 'b')} icon="fas fa-bold" onclick={makeApplyStyle('bold')} />, 900); + items.add('italic', <MarkdownButton title={tooltip('italic', 'i')} icon="fas fa-italic" onclick={makeApplyStyle('italic')} />, 800); + items.add( + 'strikethrough', + <MarkdownButton title={tooltip('strikethrough')} icon="fas fa-strikethrough" onclick={makeApplyStyle('strikethrough')} />, + 700 + ); + items.add('quote', <MarkdownButton title={tooltip('quote')} icon="fas fa-quote-left" onclick={makeApplyStyle('quote')} />, 600); + items.add('spoiler', <MarkdownButton title={tooltip('spoiler')} icon="fas fa-exclamation-triangle" onclick={makeApplyStyle('spoiler')} />, 500); + items.add('code', <MarkdownButton title={tooltip('code')} icon="fas fa-code" onclick={makeApplyStyle('code')} />, 400); + items.add('link', <MarkdownButton title={tooltip('link')} icon="fas fa-link" onclick={makeApplyStyle('link')} />, 300); + items.add('image', <MarkdownButton title={tooltip('image')} icon="fas fa-image" onclick={makeApplyStyle('image')} />, 200); + items.add( + 'unordered_list', + <MarkdownButton title={tooltip('unordered_list')} icon="fas fa-list-ul" onclick={makeApplyStyle('unordered_list')} />, + 100 + ); + items.add('ordered_list', <MarkdownButton title={tooltip('ordered_list')} icon="fas fa-list-ol" onclick={makeApplyStyle('ordered_list')} />, 0); + + return items; +} + app.initializers.add('flarum-markdown', function (app) { extend(BasicEditorDriver.prototype, 'keyHandlers', function (items) { items.add('bold', makeShortcut('bold', 'b', this)); items.add('italic', makeShortcut('italic', 'i', this)); }); + if (TextEditor.prototype.markdownToolbarItems) { + override(TextEditor.prototype, 'markdownToolbarItems', markdownToolbarItems); + } else { + TextEditor.prototype.markdownToolbarItems = markdownToolbarItems; + } + extend(TextEditor.prototype, 'toolbarItems', function (items) { - const tooltip = (name, hotkey) => { - return app.translator.trans(`flarum-markdown.forum.composer.${name}_tooltip`) + (hotkey ? ` <${modifierKey}-${hotkey}>` : ''); - }; - - const makeApplyStyle = (id) => { - return () => applyStyle(id, this.attrs.composer.editor); - }; - items.add( 'markdown', <MarkdownToolbar for={this.textareaId} setShortcutHandler={(handler) => (shortcutHandler = handler)}> - <MarkdownButton title={tooltip('header')} icon="fas fa-heading" onclick={makeApplyStyle('header')} /> - <MarkdownButton title={tooltip('bold', 'b')} icon="fas fa-bold" onclick={makeApplyStyle('bold')} /> - <MarkdownButton title={tooltip('italic', 'i')} icon="fas fa-italic" onclick={makeApplyStyle('italic')} /> - <MarkdownButton title={tooltip('strikethrough')} icon="fas fa-strikethrough" onclick={makeApplyStyle('strikethrough')} /> - <MarkdownButton title={tooltip('quote')} icon="fas fa-quote-left" onclick={makeApplyStyle('quote')} /> - <MarkdownButton title={tooltip('spoiler')} icon="fas fa-exclamation-triangle" onclick={makeApplyStyle('spoiler')} /> - <MarkdownButton title={tooltip('code')} icon="fas fa-code" onclick={makeApplyStyle('code')} /> - <MarkdownButton title={tooltip('link')} icon="fas fa-link" onclick={makeApplyStyle('link')} /> - <MarkdownButton title={tooltip('image')} icon="fas fa-image" onclick={makeApplyStyle('image')} /> - <MarkdownButton title={tooltip('unordered_list')} icon="fas fa-list-ul" onclick={makeApplyStyle('unordered_list')} /> - <MarkdownButton title={tooltip('ordered_list')} icon="fas fa-list-ol" onclick={makeApplyStyle('ordered_list')} /> + {this.markdownToolbarItems().toArray()} </MarkdownToolbar>, 100 );