0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-24 23:48:13 -05:00

Koenig - Apply link to selected text when pasting a URL

refs https://github.com/TryGhost/Ghost/issues/9505
- add a `paste` event handler to the editor element so that we can override the default mobiledoc-kit paste handling when required
- detect a paste when we have a plain text selection and if it's a valid url convert the selection to a link using the pasted url as the `href`
This commit is contained in:
Kevin Ansfield 2018-04-13 17:53:40 +01:00
parent ff96eb019f
commit f5fb674804

View file

@ -12,12 +12,14 @@ import defaultCards from '../options/cards';
import layout from '../templates/components/koenig-editor'; import layout from '../templates/components/koenig-editor';
import registerKeyCommands from '../options/key-commands'; import registerKeyCommands from '../options/key-commands';
import registerTextExpansions from '../options/text-expansions'; import registerTextExpansions from '../options/text-expansions';
import validator from 'npm:validator';
import {A} from '@ember/array'; import {A} from '@ember/array';
import {MOBILEDOC_VERSION} from 'mobiledoc-kit/renderers/mobiledoc'; import {MOBILEDOC_VERSION} from 'mobiledoc-kit/renderers/mobiledoc';
import {assign} from '@ember/polyfills'; import {assign} from '@ember/polyfills';
import {camelize, capitalize} from '@ember/string'; import {camelize, capitalize} from '@ember/string';
import {computed} from '@ember/object'; import {computed} from '@ember/object';
import {copy} from '@ember/object/internals'; import {copy} from '@ember/object/internals';
import {getContentFromPasteEvent} from 'mobiledoc-kit/utils/parse-utils';
import {run} from '@ember/runloop'; import {run} from '@ember/runloop';
export const ADD_CARD_HOOK = 'addComponent'; export const ADD_CARD_HOOK = 'addComponent';
@ -327,6 +329,14 @@ export default Component.extend({
this.didCreateEditor(editor); this.didCreateEditor(editor);
}, },
didInsertElement() {
this._super(...arguments);
let editorElement = this.element.querySelector('.koenig-editor__editor');
this._pasteHandler = run.bind(this, this.handlePaste);
editorElement.addEventListener('paste', this._pasteHandler);
},
// our ember component has rendered, now we need to render the mobiledoc // our ember component has rendered, now we need to render the mobiledoc
// editor itself if necessary // editor itself if necessary
didRender() { didRender() {
@ -342,6 +352,9 @@ export default Component.extend({
willDestroyElement() { willDestroyElement() {
let editor = this.get('editor'); let editor = this.get('editor');
let editorElement = this.element.querySelector('.koenig-editor__editor');
editorElement.removeEventListener('paste', this._pasteHandler);
editor.destroy(); editor.destroy();
this._super(...arguments); this._super(...arguments);
}, },
@ -748,6 +761,27 @@ export default Component.extend({
return false; return false;
}, },
// if a URL is pasted and we have a selection, make that selection a link
handlePaste(event) {
let editor = this.get('editor');
let range = editor.range;
// only attempt link if we have a text selection in a single section
if (range && !range.isCollapsed && range.headSection === range.tailSection && range.headSection.isMarkerable) {
let {text} = getContentFromPasteEvent(event);
if (text && validator.isURL(text)) {
let linkMarkup = editor.builder.createMarkup('a', {href: text});
editor.run((postEditor) => {
postEditor.addMarkupToRange(range, linkMarkup);
});
editor.selectRange(range.tail);
// prevent mobiledoc's default paste event handler firing
event.preventDefault();
event.stopImmediatePropagation();
}
}
},
selectCard(card, isEditing = false) { selectCard(card, isEditing = false) {
// no-op if card is already selected // no-op if card is already selected
if (card === this._selectedCard && isEditing === card.isEditing) { if (card === this._selectedCard && isEditing === card.isEditing) {