Allow disabling mdarea via admin setting (#27)

This commit is contained in:
Alexander Skvortsov 2021-03-25 13:51:21 -04:00 committed by GitHub
parent 2ea6204dff
commit 61e61f5e8c
9 changed files with 133 additions and 107 deletions

View File

@ -11,6 +11,9 @@ use Flarum\Extend;
use s9e\TextFormatter\Configurator;
return [
(new Extend\Frontend('admin'))
->js(__DIR__.'/js/dist/admin.js'),
(new Extend\Frontend('forum'))
->js(__DIR__.'/js/dist/forum.js')
->css(__DIR__.'/less/forum.less'),
@ -24,5 +27,7 @@ return [
$config->tags['ispoiler']->template = '<span class="spoiler" data-s9e-livepreview-ignore-attrs="class" onclick="removeAttribute(\'class\')"><xsl:apply-templates/></span>';
}),
new Extend\Locales(__DIR__.'/locale')
new Extend\Locales(__DIR__.'/locale'),
(new Extend\Settings)->serializeToForum('flarum-markdown.mdarea', 'flarum-markdown.mdarea', 'boolval', true)
];

View File

@ -0,0 +1 @@
export * from './src/admin';

View File

@ -1,10 +1 @@
/*
* This file is part of Flarum.
*
* (c) Toby Zerner <toby.zerner@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
export * from './src/forum';

View File

@ -0,0 +1,12 @@
import app from 'flarum/app';
app.initializers.add('flarum-markdown', () => {
app.extensionData
.for('flarum-markdown')
.registerSetting({
setting: 'flarum-markdown.mdarea',
type: 'boolean',
help: app.translator.trans('flarum-markdown.admin.settings.mdarea_help'),
label: app.translator.trans('flarum-markdown.admin.settings.mdarea_label')
});
});

View File

@ -12,7 +12,7 @@ import TextEditor from 'flarum/components/TextEditor';
import MarkdownToolbar from './components/MarkdownToolbar';
import MarkdownButton from './components/MarkdownButton';
import MarkdownAreaEditorDriver from './util/MarkdownAreaEditorDriver';
import MarkdownEditorDriver from './util/MarkdownEditorDriver';
let shortcutHandler = () => { };
@ -24,7 +24,7 @@ app.initializers.add('flarum-markdown', function (app) {
});
override(TextEditor.prototype, 'buildEditor', function (_, dom) {
return new MarkdownAreaEditorDriver(dom, this.buildEditorParams());
return new MarkdownEditorDriver(dom, this.buildEditorParams());
});
extend(TextEditor.prototype, 'buildEditorParams', function (params) {

View File

@ -1,88 +0,0 @@
import MarkdownArea from 'mdarea';
import BasicEditorDriver from 'flarum/utils/BasicEditorDriver';
export class MarkdownEditorFlarumExtension {
constructor(oninput, callInputListeners, onsubmit) {
this.oninput = oninput;
this.callInputListeners = callInputListeners;
this.onsubmit = onsubmit;
}
handleKey(
prefix,
selection,
postfix,
evt
) {
// setTimeout executes after the call stack has cleared,
// so any DOM changes originating from mdarea (e.g. executing an undo)
// will be finished by then. At that time, `e.target.value` will represent
// the updated value of the textarea in response to the keypress.
// Unfortunately, this doesn't work without a value for mobile safari,
// so we need to set 25ms as an arbitrary timeout.
setTimeout(() => {
this.oninput(evt.target.value);
if ((evt.metaKey || evt.ctrlKey) && evt.key === 'Enter') {
return this.onsubmit();
}
this.callInputListeners(evt);
}, 25);
}
}
export default class MarkdownAreaEditorDriver extends BasicEditorDriver {
build(dom, params) {
this.el.className = params.classNames.join(' ');
this.el.disabled = params.disabled;
this.el.placeholder = params.placeholder;
this.el.value = params.value;
this.el.id = params.textareaId;
dom.append(this.el);
const callInputListeners = (e) => {
params.inputListeners.forEach((listener) => {
listener();
});
e.redraw = false;
};
// We can't bind shortcutHandler directly in case `build`
// runs before MarkdownToolbar's `oninit`.
this.el.addEventListener('keydown', function (e) {
return params.shortcutHandler(...arguments);
});
// Our mdarea extension won't detect programmatic changes via
// the `app.composer.editor api.
this.el.addEventListener('input', function (e) {
if (e instanceof CustomEvent) {
params.oninput(e.target.value);
callInputListeners(e);
}
});
// This one can't be run through mdarea, but that doesn't matter
// because mdarea doesn't change value in response to clicks.
this.el.addEventListener('click', callInputListeners);
this.mdarea = new MarkdownArea(this.el, {
keyMap: {
indent: ['Ctrl+m'],
outdent: ['Ctrl+M'],
inline: []
},
extensions: [
new MarkdownEditorFlarumExtension(params.oninput, callInputListeners, params.onsubmit)
]
});
}
destroy() {
this.mdarea.destroy();
super.destroy();
}
}

View File

@ -0,0 +1,94 @@
import MarkdownArea from 'mdarea';
import BasicEditorDriver from 'flarum/utils/BasicEditorDriver';
export class MarkdownEditorFlarumExtension {
constructor(oninput, callInputListeners, onsubmit) {
this.oninput = oninput;
this.callInputListeners = callInputListeners;
this.onsubmit = onsubmit;
}
handleKey(
prefix,
selection,
postfix,
evt
) {
// setTimeout executes after the call stack has cleared,
// so any DOM changes originating from mdarea (e.g. executing an undo)
// will be finished by then. At that time, `e.target.value` will represent
// the updated value of the textarea in response to the keypress.
// Unfortunately, this doesn't work without a value for mobile safari,
// so we need to set 25ms as an arbitrary timeout.
setTimeout(() => {
this.oninput(evt.target.value);
if ((evt.metaKey || evt.ctrlKey) && evt.key === 'Enter') {
return this.onsubmit();
}
this.callInputListeners(evt);
}, 25);
}
}
export default class MarkdownEditorDriver extends BasicEditorDriver {
build(dom, params) {
if (app.forum.attribute('flarum-markdown.mdarea')) {
this.el.className = params.classNames.join(' ');
this.el.disabled = params.disabled;
this.el.placeholder = params.placeholder;
this.el.value = params.value;
dom.append(this.el);
const callInputListeners = (e) => {
params.inputListeners.forEach((listener) => {
listener();
});
e.redraw = false;
};
// Our mdarea extension won't detect programmatic changes via
// the `app.composer.editor api.
this.el.addEventListener('input', function (e) {
if (e instanceof CustomEvent) {
params.oninput(e.target.value);
callInputListeners(e);
}
});
// This one can't be run through mdarea, but that doesn't matter
// because mdarea doesn't change value in response to clicks.
this.el.addEventListener('click', callInputListeners);
this.mdarea = new MarkdownArea(this.el, {
keyMap: {
indent: ['Ctrl+m'],
outdent: ['Ctrl+M'],
inline: []
},
extensions: [
new MarkdownEditorFlarumExtension(params.oninput, callInputListeners, params.onsubmit)
]
});
} else {
super.build(dom, params);
}
this.el.id = params.textareaId;
// We can't bind shortcutHandler directly in case `build`
// runs before MarkdownToolbar's `oninit`.
this.el.addEventListener('keydown', function (e) {
return params.shortcutHandler(...arguments);
});
}
destroy() {
if (app.forum.attribute('flarum-markdown.mdarea')) {
this.mdarea.destroy();
}
super.destroy();
}
}

View File

@ -1,13 +1,10 @@
flarum-markdown:
admin:
settings:
mdarea_help: mdarea is a textarea util that auto-continues lists, helps with code formatting, and assists with indentation.
mdarea_label: Enable mdarea?
##
# UNIQUE KEYS - The following keys are used in only one location each.
##
# Translations in this namespace are used by the forum user interface.
forum:
# These translations are used by the composer (emoji autocompletion function).
composer:
bold_tooltip: Add bold text
code_tooltip: Insert code

View File

@ -0,0 +1,14 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
use Flarum\Database\Migration;
return Migration::addSettings([
'flarum-markdown.mdarea' => true
]);