From ebc8cc8ed2260e0d4cee14798b09eae8cf5fbef5 Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Thu, 22 Jun 2017 13:02:38 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20ctrl/cmd-shift-i=20triggers=20image?= =?UTF-8?q?=20file=20dialog=20(#750)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes https://github.com/TryGhost/Ghost/issues/8523 - use shortcuts mixin to register `cmd-shift-i` shortcut in `gh-markdown-editor` that triggers the image insertion dialog - joins multiple uploaded images with new lines instead of a space for easier editing post-upload - add `captureSelection` option to `_openImageFileDialog` so that insertion shortcut triggered when editor doesn't have focus doesn't insert at the last focused char position - if image insertion happens with no cursor position add two newlines before the inserted image markdown for easier editing (previously it would be inserted immediately after the last char in the post) - removes unused `editor-shortcuts.js` file --- .../app/components/gh-markdown-editor.js | 44 +++++++++++++++---- ghost/admin/app/utils/editor-shortcuts.js | 31 ------------- 2 files changed, 35 insertions(+), 40 deletions(-) delete mode 100644 ghost/admin/app/utils/editor-shortcuts.js diff --git a/ghost/admin/app/components/gh-markdown-editor.js b/ghost/admin/app/components/gh-markdown-editor.js index 7ed8d78329..7d1efef17b 100644 --- a/ghost/admin/app/components/gh-markdown-editor.js +++ b/ghost/admin/app/components/gh-markdown-editor.js @@ -1,5 +1,7 @@ import Component from 'ember-component'; +import ShortcutsMixin from 'ghost-admin/mixins/shortcuts'; import computed from 'ember-computed'; +import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd'; import formatMarkdown from 'ghost-admin/utils/format-markdown'; import run from 'ember-runloop'; import {assign} from 'ember-platform'; @@ -21,7 +23,7 @@ export const BLANK_DOC = { sections: [[10, 0]] }; -export default Component.extend({ +export default Component.extend(ShortcutsMixin, { classNames: ['gh-markdown-editor'], classNameBindings: [ @@ -132,6 +134,15 @@ export default Component.extend({ return assign(defaultOptions, options); }), + shortcuts: {}, + + init() { + this._super(...arguments); + let shortcuts = this.get('shortcuts'); + + shortcuts[`${ctrlOrCmd}+shift+i`] = {action: 'insertImage'}; + }, + // extract markdown content from single markdown card didReceiveAttrs() { this._super(...arguments); @@ -165,6 +176,11 @@ export default Component.extend({ this._updateButtonState(); }, + didInsertElement() { + this._super(...arguments); + this.registerShortcuts(); + }, + _insertImages(urls) { let cm = this._editor.codemirror; @@ -180,7 +196,7 @@ export default Component.extend({ return `![${alt}](${url})`; }); - let text = images.join(' '); + let text = images.join('\n'); // clicking the image toolbar button will lose the selection so we use // the captured selection to re-select here @@ -200,6 +216,7 @@ export default Component.extend({ // focus editor and place cursor at end if not already focused if (!cm.hasFocus()) { this.send('focusEditor'); + text = `\n\n${text}`; } // insert at cursor or replace selection then position cursor at end @@ -293,13 +310,15 @@ export default Component.extend({ delete this._onEditorPaneScroll; }, - _openImageFileDialog() { - // capture the current selection before it's lost by clicking the - // file input button - this._imageInsertSelection = { - anchor: this._editor.codemirror.getCursor('anchor'), - head: this._editor.codemirror.getCursor('head') - }; + _openImageFileDialog({captureSelection = true}) { + if (captureSelection) { + // capture the current selection before it's lost by clicking the + // file input button + this._imageInsertSelection = { + anchor: this._editor.codemirror.getCursor('anchor'), + head: this._editor.codemirror.getCursor('head') + }; + } // trigger the dialog via gh-file-input, when a file is selected it will // trigger the onImageFilesSelected closure action @@ -330,6 +349,8 @@ export default Component.extend({ this._disconnectSplitPreview(); } + this.removeShortcuts(); + this._super(...arguments); }, @@ -377,6 +398,11 @@ export default Component.extend({ return false; }, + insertImage() { + let captureSelection = this._editor.codemirror.hasFocus(); + this._openImageFileDialog({captureSelection}); + }, + toggleFullScreen() { let isFullScreen = !this.get('_isFullScreen'); diff --git a/ghost/admin/app/utils/editor-shortcuts.js b/ghost/admin/app/utils/editor-shortcuts.js deleted file mode 100644 index 90b6a909b1..0000000000 --- a/ghost/admin/app/utils/editor-shortcuts.js +++ /dev/null @@ -1,31 +0,0 @@ -// # Editor shortcuts -// Loaded by gh-editor component -// This map is used to ensure the right action is called by each shortcut -import ctrlOrCmd from 'ghost-admin/utils/ctrl-or-cmd'; - -let shortcuts = {}; - -// Markdown Shortcuts - -// Text -shortcuts['ctrl+alt+u'] = {action: 'editorShortcut', options: {type: 'strike'}}; -shortcuts[`${ctrlOrCmd}+b`] = {action: 'editorShortcut', options: {type: 'bold'}}; -shortcuts[`${ctrlOrCmd}+i`] = {action: 'editorShortcut', options: {type: 'italic'}}; - -shortcuts['ctrl+u'] = {action: 'editorShortcut', options: {type: 'uppercase'}}; -shortcuts['ctrl+shift+u'] = {action: 'editorShortcut', options: {type: 'lowercase'}}; -shortcuts['ctrl+alt+shift+u'] = {action: 'editorShortcut', options: {type: 'titlecase'}}; -shortcuts[`${ctrlOrCmd}+shift+c`] = {action: 'editorShortcut', options: {type: 'copyHTML'}}; -shortcuts[`${ctrlOrCmd}+h`] = {action: 'editorShortcut', options: {type: 'cycleHeaderLevel'}}; - -// Formatting -shortcuts['ctrl+q'] = {action: 'editorShortcut', options: {type: 'blockquote'}}; -shortcuts['ctrl+l'] = {action: 'editorShortcut', options: {type: 'list'}}; - -// Insert content -shortcuts['ctrl+shift+1'] = {action: 'editorShortcut', options: {type: 'currentDate'}}; -shortcuts[`${ctrlOrCmd}+k`] = {action: 'editorShortcut', options: {type: 'link'}}; -shortcuts[`${ctrlOrCmd}+shift+i`] = {action: 'editorShortcut', options: {type: 'image'}}; -shortcuts[`${ctrlOrCmd}+shift+k`] = {action: 'editorShortcut', options: {type: 'code'}}; - -export default shortcuts;