mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-22 18:31:57 +03:00
2151d8a49f
closes #2426, closes #2781, closes #2913 - Concatenate vendor files on change of js in core/shared/ - Add all the markerManager stuff to its own mixin - make markers a shared object for all that mix it in. makes it easier to use helper functions in different modules - add getMarkdown method, returns object with two keys holding the markdown: one with markers, the other without - Clear markers when codemirror is destroyed - make Editor subcomponents communicate through the Editor Controller - Set Codemirror and html preview shared scrolling - Set CodeMirror, html preview css scroll class with util - Create 'scratch' property in Editor controller; prevents a model save wiping image markers due to markdown bindings - Add editor and html preview actions to handle img upload start/finish - disable codemirror when an image is being uploaded, enables on success or failure - Fix editor wordcount when there are 0 words - Add modal dialog when transitioning out of the editor with an unsaved post - Add window.onbeforeunload handling with `.unloadDirtyMessage()` on editor controller - and various other things
115 lines
3.5 KiB
JavaScript
115 lines
3.5 KiB
JavaScript
/* global CodeMirror*/
|
|
import MarkerManager from 'ghost/mixins/marker-manager';
|
|
import setScrollClassName from 'ghost/utils/set-scroll-classname';
|
|
|
|
var onChangeHandler = function (cm, changeObj) {
|
|
var line,
|
|
component = cm.component,
|
|
checkLine = component.checkLine.bind(component),
|
|
checkMarkers = component.checkMarkers.bind(component);
|
|
|
|
// fill array with a range of numbers
|
|
for (line = changeObj.from.line; line < changeObj.from.line + changeObj.text.length; line += 1) {
|
|
checkLine(line, changeObj.origin);
|
|
}
|
|
|
|
// Is this a line which may have had a marker on it?
|
|
checkMarkers();
|
|
|
|
cm.component.set('value', cm.getDoc().getValue());
|
|
};
|
|
|
|
var onScrollHandler = function (cm) {
|
|
var scrollInfo = cm.getScrollInfo(),
|
|
component = cm.component;
|
|
|
|
scrollInfo.codemirror = cm;
|
|
|
|
// throttle scroll updates
|
|
component.throttle = Ember.run.throttle(component, function () {
|
|
this.set('scrollInfo', scrollInfo);
|
|
}, 10);
|
|
};
|
|
|
|
var Codemirror = Ember.TextArea.extend(MarkerManager, {
|
|
didInsertElement: function () {
|
|
Ember.run.scheduleOnce('afterRender', this, this.afterRenderEvent);
|
|
},
|
|
|
|
afterRenderEvent: function () {
|
|
var initMarkers = this.initMarkers.bind(this);
|
|
|
|
this.initCodemirror();
|
|
this.codemirror.eachLine(initMarkers);
|
|
this.sendAction('action', this);
|
|
},
|
|
|
|
// this needs to be placed on the 'afterRender' queue otherwise CodeMirror gets wonky
|
|
initCodemirror: function () {
|
|
// create codemirror
|
|
var codemirror = CodeMirror.fromTextArea(this.get('element'), {
|
|
mode: 'gfm',
|
|
tabMode: 'indent',
|
|
tabindex: '2',
|
|
cursorScrollMargin: 10,
|
|
lineWrapping: true,
|
|
dragDrop: false,
|
|
extraKeys: {
|
|
Home: 'goLineLeft',
|
|
End: 'goLineRight'
|
|
}
|
|
});
|
|
|
|
codemirror.component = this; // save reference to this
|
|
|
|
// propagate changes to value property
|
|
codemirror.on('change', onChangeHandler);
|
|
|
|
// on scroll update scrollPosition property
|
|
codemirror.on('scroll', onScrollHandler);
|
|
|
|
codemirror.on('scroll', Ember.run.bind(Ember.$('.CodeMirror-scroll'), setScrollClassName, {
|
|
target: Ember.$('.entry-markdown'),
|
|
offset: 10
|
|
}));
|
|
|
|
this.set('codemirror', codemirror);
|
|
},
|
|
|
|
disableCodeMirror: function () {
|
|
var codemirror = this.get('codemirror');
|
|
|
|
codemirror.setOption('readOnly', 'nocursor');
|
|
codemirror.off('change', onChangeHandler);
|
|
},
|
|
|
|
enableCodeMirror: function () {
|
|
var codemirror = this.get('codemirror');
|
|
|
|
codemirror.setOption('readOnly', false);
|
|
|
|
// clicking the trash button on an image dropzone causes this function to fire.
|
|
// this line is a hack to prevent multiple event handlers from being attached.
|
|
codemirror.off('change', onChangeHandler);
|
|
|
|
codemirror.on('change', onChangeHandler);
|
|
},
|
|
|
|
removeThrottle: function () {
|
|
Ember.run.cancel(this.throttle);
|
|
}.on('willDestroyElement'),
|
|
|
|
removeCodemirrorHandlers: function () {
|
|
// not sure if this is needed.
|
|
var codemirror = this.get('codemirror');
|
|
codemirror.off('change', onChangeHandler);
|
|
codemirror.off('scroll');
|
|
}.on('willDestroyElement'),
|
|
|
|
clearMarkerManagerMarkers: function () {
|
|
this.clearMarkers();
|
|
}.on('willDestroyElement')
|
|
});
|
|
|
|
export default Codemirror;
|