+ let cm = code.markdownEditor(element[0]);
+
+ // Custom key commands
+ let metaKey = code.getMetaKey();
+ const extraKeys = {};
+ // Insert Image shortcut
+ extraKeys[`${metaKey}-Alt-I`] = function(cm) {
+ let selectedText = cm.getSelection();
+ let newText = ``;
+ let cursorPos = cm.getCursor('from');
+ cm.replaceSelection(newText);
+ cm.setCursor(cursorPos.line, cursorPos.ch + newText.length -1);
+ };
+ // Save draft
+ extraKeys[`${metaKey}-S`] = function(cm) {scope.$emit('save-draft');};
+ // Show link selector
+ extraKeys[`Shift-${metaKey}-K`] = function(cm) {showLinkSelector()};
+ cm.setOption('extraKeys', extraKeys);
+
+ // Update data on content change
+ cm.on('change', (instance, changeObj) => {
+ update(instance);
+ });
+
+ // Handle scroll to sync display view
+ cm.on('scroll', instance => {
+ // Thanks to http://liuhao.im/english/2015/11/10/the-sync-scroll-of-markdown-editor-in-javascript.html
+ let scroll = instance.getScrollInfo();
+ let atEnd = scroll.top + scroll.clientHeight === scroll.height;
+ if (atEnd) {
+ scope.$emit('markdown-scroll', -1);
+ return;
+ }
+ let lineNum = instance.lineAtHeight(scroll.top, 'local');
+ let range = instance.getRange({line: 0, ch: null}, {line: lineNum, ch: null});
+ let parser = new DOMParser();
+ let doc = parser.parseFromString(md.render(range), 'text/html');
+ let totalLines = doc.documentElement.querySelectorAll('body > *');
+ scope.$emit('markdown-scroll', totalLines.length);
+ });
+
+ // Handle image paste
+ cm.on('paste', (cm, event) => {
+ if (!event.clipboardData || !event.clipboardData.items) return;
+ for (let i = 0; i < event.clipboardData.items.length; i++) {
+ uploadImage(event.clipboardData.items[i].getAsFile());
+ }
+ });
+
+ // Handle images on drag-drop
+ cm.on('drop', (cm, event) => {
+ event.stopPropagation();
+ event.preventDefault();
+ let cursorPos = cm.coordsChar({left: event.pageX, top: event.pageY});
+ cm.setCursor(cursorPos);
+ if (!event.dataTransfer || !event.dataTransfer.files) return;
+ for (let i = 0; i < event.dataTransfer.files.length; i++) {
+ uploadImage(event.dataTransfer.files[i]);
+ }
+ });
+
+ // Helper to replace editor content
+ function replaceContent(search, replace) {
+ let text = cm.getValue();
+ let cursor = cm.listSelections();
+ cm.setValue(text.replace(search, replace));
+ cm.setSelections(cursor);
+ }
+
+ // Handle image upload and add image into markdown content
+ function uploadImage(file) {
+ if (file === null || file.type.indexOf('image') !== 0) return;
+ let ext = 'png';