mirror of
https://github.com/flarum/framework.git
synced 2024-11-26 02:10:09 +08:00
Attach oninput, inputListeners, onsubmit via mdarea extension
Recent versions of mdarea are quite powerful, and have internal state data structures. As a result, updating current editor value via `oninput` event listeners isn't reliable. Instead, we can use the mdarea extension API to handle keypresses exactly when markdownarea wants us to. This also removes the `super` call from `build`, and directly creates/configures the applicable DOM elements. Since the mdarea editor driver's initialization is already quite different from BasicEditorDriver, it should fully own this step.
This commit is contained in:
parent
aa62e69dab
commit
09b14b980a
|
@ -1,23 +1,72 @@
|
||||||
import MarkdownArea from 'mdarea';
|
import MarkdownArea from 'mdarea';
|
||||||
import BasicEditorDriver from 'flarum/utils/BasicEditorDriver';
|
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 without a time 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.
|
||||||
|
setTimeout(() => {
|
||||||
|
this.oninput(evt.target.value);
|
||||||
|
|
||||||
|
if ((evt.metaKey || evt.ctrlKey) && evt.key === 'Enter') {
|
||||||
|
return this.onsubmit();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.callInputListeners(evt);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default class MarkdownAreaEditorDriver extends BasicEditorDriver {
|
export default class MarkdownAreaEditorDriver extends BasicEditorDriver {
|
||||||
build(dom, params) {
|
build(dom, params) {
|
||||||
super.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;
|
this.el.id = params.textareaId;
|
||||||
|
|
||||||
|
dom.append(this.el);
|
||||||
|
|
||||||
// We can't bind shortcutHandler directly in case `build`
|
// We can't bind shortcutHandler directly in case `build`
|
||||||
// runs before MarkdownToolbar's `oninit`.
|
// runs before MarkdownToolbar's `oninit`.
|
||||||
this.el.addEventListener('keydown', function (e) {
|
this.el.addEventListener('keydown', function (e) {
|
||||||
return params.shortcutHandler(...arguments);
|
return params.shortcutHandler(...arguments);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const callInputListeners = (e) => {
|
||||||
|
params.inputListeners.forEach((listener) => {
|
||||||
|
listener();
|
||||||
|
});
|
||||||
|
|
||||||
|
e.redraw = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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, {
|
this.mdarea = new MarkdownArea(this.el, {
|
||||||
keyMap: {
|
keyMap: {
|
||||||
indent: ['Ctrl+m'],
|
indent: ['Ctrl+m'],
|
||||||
outdent: ['Ctrl+M'],
|
outdent: ['Ctrl+M'],
|
||||||
inline: []
|
inline: []
|
||||||
}
|
},
|
||||||
|
extensions: [
|
||||||
|
new MarkdownEditorFlarumExtension(params.oninput, callInputListeners, params.onsubmit)
|
||||||
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user