mirror of
https://github.com/flarum/framework.git
synced 2024-11-25 17:57:04 +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 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 {
|
||||
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;
|
||||
|
||||
dom.append(this.el);
|
||||
|
||||
// We can't bind shortcutHandler directly in case `build`
|
||||
// runs before MarkdownToolbar's `oninit`.
|
||||
this.el.addEventListener('keydown', function (e) {
|
||||
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, {
|
||||
keyMap: {
|
||||
indent: ['Ctrl+m'],
|
||||
outdent: ['Ctrl+M'],
|
||||
inline: []
|
||||
}
|
||||
},
|
||||
extensions: [
|
||||
new MarkdownEditorFlarumExtension(params.oninput, callInputListeners, params.onsubmit)
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user