mirror of
https://github.com/flarum/framework.git
synced 2025-03-24 15:45:18 +08:00
Allow disabling mdarea via admin setting (#27)
This commit is contained in:
parent
2ea6204dff
commit
61e61f5e8c
@ -11,6 +11,9 @@ use Flarum\Extend;
|
|||||||
use s9e\TextFormatter\Configurator;
|
use s9e\TextFormatter\Configurator;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
|
(new Extend\Frontend('admin'))
|
||||||
|
->js(__DIR__.'/js/dist/admin.js'),
|
||||||
|
|
||||||
(new Extend\Frontend('forum'))
|
(new Extend\Frontend('forum'))
|
||||||
->js(__DIR__.'/js/dist/forum.js')
|
->js(__DIR__.'/js/dist/forum.js')
|
||||||
->css(__DIR__.'/less/forum.less'),
|
->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>';
|
$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)
|
||||||
];
|
];
|
||||||
|
1
extensions/markdown/js/admin.js
Normal file
1
extensions/markdown/js/admin.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './src/admin';
|
@ -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';
|
export * from './src/forum';
|
||||||
|
12
extensions/markdown/js/src/admin/index.js
Normal file
12
extensions/markdown/js/src/admin/index.js
Normal 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')
|
||||||
|
});
|
||||||
|
});
|
@ -12,7 +12,7 @@ import TextEditor from 'flarum/components/TextEditor';
|
|||||||
|
|
||||||
import MarkdownToolbar from './components/MarkdownToolbar';
|
import MarkdownToolbar from './components/MarkdownToolbar';
|
||||||
import MarkdownButton from './components/MarkdownButton';
|
import MarkdownButton from './components/MarkdownButton';
|
||||||
import MarkdownAreaEditorDriver from './util/MarkdownAreaEditorDriver';
|
import MarkdownEditorDriver from './util/MarkdownEditorDriver';
|
||||||
|
|
||||||
let shortcutHandler = () => { };
|
let shortcutHandler = () => { };
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ app.initializers.add('flarum-markdown', function (app) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
override(TextEditor.prototype, 'buildEditor', function (_, dom) {
|
override(TextEditor.prototype, 'buildEditor', function (_, dom) {
|
||||||
return new MarkdownAreaEditorDriver(dom, this.buildEditorParams());
|
return new MarkdownEditorDriver(dom, this.buildEditorParams());
|
||||||
});
|
});
|
||||||
|
|
||||||
extend(TextEditor.prototype, 'buildEditorParams', function (params) {
|
extend(TextEditor.prototype, 'buildEditorParams', function (params) {
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +1,10 @@
|
|||||||
flarum-markdown:
|
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:
|
forum:
|
||||||
|
|
||||||
# These translations are used by the composer (emoji autocompletion function).
|
|
||||||
composer:
|
composer:
|
||||||
bold_tooltip: Add bold text
|
bold_tooltip: Add bold text
|
||||||
code_tooltip: Insert code
|
code_tooltip: Insert code
|
||||||
|
@ -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
|
||||||
|
]);
|
Loading…
x
Reference in New Issue
Block a user