Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
Koenig - Parse pasted plain text as markdown
Browse files Browse the repository at this point in the history
refs TryGhost/Ghost#9623
- plain text that's pasted will be run through our markdown parser then mobiledoc-kit will perform it's usual rich-text paste handling on the resulting HTML
- add a <kbd>Cmd/Ctrl+V+Shift</kbd> escape valve that will skip markdown parsing so mobiledoc-kit's default plain text parsing is invoked
- will not work with IE or Edge <= 16 due to missing browser support for distinguishing plain text vs html pastes
  • Loading branch information
kevinansfield committed May 16, 2018
1 parent 6353d71 commit e1b4209
Showing 1 changed file with 62 additions and 2 deletions.
64 changes: 62 additions & 2 deletions lib/koenig-editor/addon/components/koenig-editor.js
Expand Up @@ -6,9 +6,11 @@
import Component from '@ember/component';
import Editor from 'mobiledoc-kit/editor/editor';
import EmberObject, {computed} from '@ember/object';
import Key from 'mobiledoc-kit/utils/key';
import MobiledocRange from 'mobiledoc-kit/utils/cursor/range';
import defaultAtoms from '../options/atoms';
import defaultCards from '../options/cards';
import formatMarkdown from 'ghost-admin/utils/format-markdown';
import layout from '../templates/components/koenig-editor';
import registerKeyCommands from '../options/key-commands';
import registerTextExpansions from '../options/text-expansions';
Expand Down Expand Up @@ -109,6 +111,7 @@ export default Component.extend({
_lastIsEditingDisabled: false,
_isRenderingEditor: false,
_skipCursorChange: false,
_modifierKeys: null,

// closure actions
willCreateEditor() {},
Expand Down Expand Up @@ -156,6 +159,12 @@ export default Component.extend({
this.set('activeMarkupTagNames', {});
this.set('activeSectionTagNames', {});

this._modifierKeys = {
shift: false,
alt: false,
ctrl: false
};

this._startedRunLoop = false;
},

Expand Down Expand Up @@ -605,12 +614,11 @@ export default Component.extend({

/* custom event handlers ------------------------------------------------ */

// if a URL is pasted and we have a selection, make that selection a link
handlePaste(event) {
let editor = this.editor;
let range = editor.range;

// only attempt link if we have a text selection in a single section
// if a URL is pasted and we have a selection, make that selection a link
if (range && !range.isCollapsed && range.headSection === range.tailSection && range.headSection.isMarkerable) {
let {text} = getContentFromPasteEvent(event);
if (text && validator.isURL(text)) {
Expand All @@ -622,8 +630,37 @@ export default Component.extend({
// prevent mobiledoc's default paste event handler firing
event.preventDefault();
event.stopImmediatePropagation();
return;
}
}

// if plain text is pasted we run it through our markdown parser so that
// we get better output than mobiledoc's default text parsing and we can
// provide an easier MD->Mobiledoc conversion route
// NOTE: will not work in IE/Edge which only ever expose `html`
let {html, text} = getContentFromPasteEvent(event);
if (text && !html && !this._modifierKeys.shift) {
// prevent mobiledoc's default paste event handler firing
event.preventDefault();
event.stopImmediatePropagation();

// we can't modify the paste event itself so we trigger a mock
// paste event with our own data
let pasteEvent = {
type: 'paste',
preventDefault() {},
target: editor.element,
clipboardData: {
getData(type) {
if (type === 'text/html') {
return formatMarkdown(text, false);
}
}
}
};

editor.triggerEvent(editor.element, 'paste', pasteEvent);
}
},

/* Ember event handlers ------------------------------------------------- */
Expand All @@ -634,6 +671,19 @@ export default Component.extend({
event.preventDefault();
},

// we keep track of the modifier keys that are pressed so that in other event
// handlers we can adjust the behaviour. Necessary because the browser doesn't
// natively provide any info on non-key events about which keys are pressed
keyDown(event) {
let key = Key.fromEvent(event);
this._updateModifiersFromKey(key, {isDown: true});
},

keyUp(event) {
let key = Key.fromEvent(event);
this._updateModifiersFromKey(key, {isDown: false});
},

/* public methods ------------------------------------------------------- */

selectCard(card, isEditing = false) {
Expand Down Expand Up @@ -767,6 +817,16 @@ export default Component.extend({
this.editor.element.style.caretColor = 'auto';
},

_updateModifiersFromKey(key, {isDown}) {
if (key.isShiftKey()) {
this._modifierKeys.shift = isDown;
} else if (key.isAltKey()) {
this._modifierKeys.alt = isDown;
} else if (key.isCtrlKey()) {
this._modifierKeys.ctrl = isDown;
}
},

// store a reference to the editor for the acceptance test helpers
_setExpandoProperty(editor) {
let config = getOwner(this).resolveRegistration('config:environment');
Expand Down

0 comments on commit e1b4209

Please sign in to comment.