mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-23 10:53:34 +03:00
c722c83a6e
no issue - a change in Ember 3.10's rendering has resulting in the component's element being removed before the `{{gh-markdown-editor}}`'s cleanup action is run which meant that we were trying to run `.querySelector` on `undefined` - removes the code which moved toolbar elements around because it hasn't been used since we moved to Koenig, this meant that the cleanup action could also be removed
116 lines
3.2 KiB
JavaScript
116 lines
3.2 KiB
JavaScript
/* global SimpleMDE */
|
|
import TextArea from '@ember/component/text-area';
|
|
import config from 'ghost-admin/config/environment';
|
|
import {assign} from '@ember/polyfills';
|
|
import {computed} from '@ember/object';
|
|
import {isEmpty} from '@ember/utils';
|
|
import {inject as service} from '@ember/service';
|
|
import {task} from 'ember-concurrency';
|
|
|
|
export default TextArea.extend({
|
|
lazyLoader: service(),
|
|
|
|
// Public attributes
|
|
autofocus: false,
|
|
options: null,
|
|
value: null,
|
|
placeholder: '',
|
|
|
|
// Private
|
|
_editor: null,
|
|
|
|
// Closure actions
|
|
onChange() {},
|
|
onEditorInit() {},
|
|
onEditorDestroy() {},
|
|
|
|
// default SimpleMDE options, see docs for available config:
|
|
// https://github.com/sparksuite/simplemde-markdown-editor#configuration
|
|
defaultOptions: computed(function () {
|
|
return {
|
|
autofocus: this.autofocus,
|
|
indentWithTabs: false,
|
|
placeholder: this.placeholder,
|
|
tabSize: 4
|
|
};
|
|
}),
|
|
|
|
init() {
|
|
this._super(...arguments);
|
|
|
|
if (isEmpty(this.options)) {
|
|
this.set('options', {});
|
|
}
|
|
},
|
|
|
|
// update the editor when the value property changes from the outside
|
|
didReceiveAttrs() {
|
|
this._super(...arguments);
|
|
|
|
if (isEmpty(this._editor)) {
|
|
return;
|
|
}
|
|
|
|
// compare values before forcing a content reset to avoid clobbering
|
|
// the undo behaviour
|
|
if (this.value !== this._editor.value()) {
|
|
let cursor = this._editor.codemirror.getDoc().getCursor();
|
|
this._editor.value(this.value);
|
|
this._editor.codemirror.getDoc().setCursor(cursor);
|
|
}
|
|
},
|
|
|
|
// instantiate the editor with the contents of value
|
|
didInsertElement() {
|
|
this._super(...arguments);
|
|
this.initSimpleMDE.perform();
|
|
},
|
|
|
|
willDestroyElement() {
|
|
this._editor.toTextArea();
|
|
delete this._editor;
|
|
this._super(...arguments);
|
|
},
|
|
|
|
initSimpleMDE: task(function* () {
|
|
yield this.lazyLoader.loadScript('simplemde', 'assets/simplemde/simplemde.js');
|
|
|
|
let editorOptions = assign(
|
|
{element: document.getElementById(this.elementId)},
|
|
this.defaultOptions,
|
|
this.options
|
|
);
|
|
|
|
// disable spellchecker when testing so that the exterally loaded plugin
|
|
// doesn't fail
|
|
if (config.environment === 'test') {
|
|
editorOptions.spellChecker = false;
|
|
}
|
|
|
|
this._editor = new SimpleMDE(editorOptions);
|
|
this._editor.value(this.value || '');
|
|
|
|
this._editor.codemirror.on('change', (instance, changeObj) => {
|
|
// avoid a "modified x twice in a single render" error that occurs
|
|
// when the underlying value is completely swapped out
|
|
if (changeObj.origin !== 'setValue') {
|
|
this.onChange(this._editor.value());
|
|
}
|
|
});
|
|
|
|
this._editor.codemirror.on('focus', () => {
|
|
this.onFocus();
|
|
});
|
|
|
|
this._editor.codemirror.on('blur', () => {
|
|
this.onBlur();
|
|
});
|
|
|
|
if (this.autofocus) {
|
|
this._editor.codemirror.execCommand('goDocEnd');
|
|
}
|
|
|
|
this.onEditorInit(this._editor);
|
|
})
|
|
});
|