From 7d5c0552fe7d3ea41b32744362917bf312938be9 Mon Sep 17 00:00:00 2001 From: Kevin Ansfield Date: Fri, 28 Jul 2017 17:21:09 +0400 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20hemingway=20editor=20mode?= =?UTF-8?q?=20(disable=20backspace)=20(#803)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit no issue - adds Hemmingway Mode toggle to the editor toolbar that disables backspace - shortcut is Ctrl+Alt+H --- .../app/components/gh-markdown-editor.js | 53 +++++++++++++++++++ .../app/styles/components/notifications.css | 8 ++- ghost/admin/yarn.lock | 2 +- 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/ghost/admin/app/components/gh-markdown-editor.js b/ghost/admin/app/components/gh-markdown-editor.js index af5a04bf98..7d9a97f5ba 100644 --- a/ghost/admin/app/components/gh-markdown-editor.js +++ b/ghost/admin/app/components/gh-markdown-editor.js @@ -3,9 +3,11 @@ 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 injectService from 'ember-service/inject'; import run from 'ember-runloop'; import {assign} from 'ember-platform'; import {copy} from 'ember-metal/utils'; +import {htmlSafe} from 'ember-string'; import {isEmpty} from 'ember-utils'; const MOBILEDOC_VERSION = '0.3.1'; @@ -25,6 +27,8 @@ export const BLANK_DOC = { export default Component.extend(ShortcutsMixin, { + notifications: injectService(), + classNames: ['gh-markdown-editor'], classNameBindings: [ '_isFullScreen:gh-markdown-editor-full-screen', @@ -55,6 +59,7 @@ export default Component.extend(ShortcutsMixin, { _editor: null, _isFullScreen: false, _isSplitScreen: false, + _isHemmingwayMode: false, _isUploading: false, _statusbar: null, _toolbar: null, @@ -108,6 +113,14 @@ export default Component.extend(ShortcutsMixin, { className: 'fa fa-check', title: 'Toggle Spellcheck' }, + { + name: 'hemmingway', + action: () => { + this._toggleHemmingway(); + }, + className: 'fa fa-h-square', + title: 'Toggle Hemmingway Mode' + }, { name: 'guide', action: () => { @@ -142,6 +155,7 @@ export default Component.extend(ShortcutsMixin, { let shortcuts = this.get('shortcuts'); shortcuts[`${ctrlOrCmd}+shift+i`] = {action: 'insertImage'}; + shortcuts['ctrl+alt+h'] = {action: 'toggleHemmingway'}; }, // extract markdown content from single markdown card @@ -230,6 +244,7 @@ export default Component.extend(ShortcutsMixin, { if (this._editor) { let sideBySideButton = this._editor.toolbarElements['side-by-side']; let spellcheckButton = this._editor.toolbarElements.spellcheck; + let hemmingwayButton = this._editor.toolbarElements.hemmingway; if (sideBySideButton) { if (this.get('_isSplitScreen')) { @@ -246,6 +261,14 @@ export default Component.extend(ShortcutsMixin, { spellcheckButton.classList.remove('active'); } } + + if (hemmingwayButton) { + if (this._isHemmingwayMode) { + hemmingwayButton.classList.add('active'); + } else { + hemmingwayButton.classList.remove('active'); + } + } } }, @@ -349,6 +372,32 @@ export default Component.extend(ShortcutsMixin, { this._updateButtonState(); }, + _toggleHemmingway() { + let cm = this._editor.codemirror; + let extraKeys = cm.getOption('extraKeys'); + let notificationText = ''; + + this._isHemmingwayMode = !this._isHemmingwayMode; + + if (this._isHemmingwayMode) { + notificationText = 'Hemingway Mode On: Write now; edit later. Backspace disabled.'; + extraKeys.Backspace = function () {}; + } else { + notificationText = 'Hemingway Mode Off: Normal editing restored.'; + delete extraKeys.Backspace; + } + + cm.setOption('extraKeys', extraKeys); + this._updateButtonState(); + + cm.focus(); + + this.get('notifications').showNotification( + htmlSafe(notificationText), + {key: 'editor.hemmingwaymode'} + ); + }, + willDestroyElement() { if (this.get('_isSplitScreen')) { this._disconnectSplitPreview(); @@ -460,6 +509,10 @@ export default Component.extend(ShortcutsMixin, { this.send('toggleFullScreen'); }, + toggleHemmingway() { + this._toggleHemmingway(); + }, + // put the toolbar/statusbar elements back so that SimpleMDE doesn't throw // errors when it tries to remove them destroyEditor() { diff --git a/ghost/admin/app/styles/components/notifications.css b/ghost/admin/app/styles/components/notifications.css index f5460b4a20..9f5c4d56ed 100644 --- a/ghost/admin/app/styles/components/notifications.css +++ b/ghost/admin/app/styles/components/notifications.css @@ -25,7 +25,7 @@ color: #fff; font-size: 1.2rem; line-height: 1.4em; - opacity: 0.8; + opacity: 0.88; transition: opacity 0.3s ease; } @@ -41,6 +41,12 @@ transition: background 0.2s ease; } +.gh-notification-title { + display: block; + margin-bottom: 5px; + font-weight: 600; +} + .gh-notification a { color: #fff; text-decoration: underline; diff --git a/ghost/admin/yarn.lock b/ghost/admin/yarn.lock index 22461e0f41..b383d3b807 100644 --- a/ghost/admin/yarn.lock +++ b/ghost/admin/yarn.lock @@ -7561,7 +7561,7 @@ simple-is@~0.2.0: "simplemde@https://github.com/kevinansfield/simplemde-markdown-editor.git#ghost": version "1.11.2" - resolved "https://github.com/kevinansfield/simplemde-markdown-editor.git#05ba8d8ff395b148258743a31ef7e07ae5579d3e" + resolved "https://github.com/kevinansfield/simplemde-markdown-editor.git#42971ea4d997f5bec519c1c68cf63bda6b278cb2" dependencies: codemirror "*" codemirror-spell-checker "*"