From d1f7effb594ebe253e893db28b018073fd020bf1 Mon Sep 17 00:00:00 2001 From: Ashish Tonse Date: Wed, 4 May 2016 15:26:25 -0400 Subject: [PATCH] Added support to CMD+Left/Right for Mac navigation In MacOS, in addition to CTRL+A and E for "Home" and "End", another commonly used combination is CMD+Left for Home, and CMD+Right for End. This commit adds those shortcuts, and pulls out the "getStartOfLine" and "getEndOfLine" functions out so they can respond to multiple command keys. Also fixed the triggerKeyCommand test method to accept non-alpha codes --- src/js/editor/key-commands.js | 45 ++++++++++++---- tests/acceptance/editor-key-commands-test.js | 55 +++++++++++++++++++- tests/helpers/dom.js | 2 +- 3 files changed, 89 insertions(+), 13 deletions(-) diff --git a/src/js/editor/key-commands.js b/src/js/editor/key-commands.js index da84f4108..ddc6dff06 100644 --- a/src/js/editor/key-commands.js +++ b/src/js/editor/key-commands.js @@ -11,6 +11,22 @@ function selectAll(editor) { editor.selectRange(allRange); } +function gotoStartOfLine(editor) { + let {range} = editor; + let {tail: {section}} = range; + editor.run(postEditor => { + postEditor.setRange(new Range(section.headPosition())); + }); +} + +function gotoEndOfLine(editor) { + let {range} = editor; + let {tail: {section}} = range; + editor.run(postEditor => { + postEditor.setRange(new Range(section.tailPosition())); + }); +} + export const DEFAULT_KEY_COMMANDS = [{ str: 'META+B', run(editor) { @@ -47,15 +63,18 @@ export const DEFAULT_KEY_COMMANDS = [{ str: 'CTRL+A', run(editor) { if (Browser.isMac) { - let {range} = editor; - let {head: {section}} = range; - editor.run(postEditor => { - postEditor.setRange(new Range(section.headPosition())); - }); + gotoStartOfLine(editor); } else { selectAll(editor); } } +}, { + str: 'META+LEFT', + run(editor) { + if (Browser.isMac) { + gotoStartOfLine(editor); + } + } }, { str: 'META+A', run(editor) { @@ -66,12 +85,16 @@ export const DEFAULT_KEY_COMMANDS = [{ }, { str: 'CTRL+E', run(editor) { - if (!Browser.isMac) { return false; } - let {range} = editor; - let {tail: {section}} = range; - editor.run(postEditor => { - postEditor.setRange(new Range(section.tailPosition())); - }); + if (Browser.isMac) { + gotoEndOfLine(editor); + } + } +}, { + str: 'META+RIGHT', + run(editor) { + if (Browser.isMac) { + gotoEndOfLine(editor); + } } }, { str: 'META+K', diff --git a/tests/acceptance/editor-key-commands-test.js b/tests/acceptance/editor-key-commands-test.js index b9bb9cfc6..15fb0ff19 100644 --- a/tests/acceptance/editor-key-commands-test.js +++ b/tests/acceptance/editor-key-commands-test.js @@ -1,6 +1,7 @@ import { Editor } from 'mobiledoc-kit'; import { MODIFIERS } from 'mobiledoc-kit/utils/key'; import Keycodes from 'mobiledoc-kit/utils/keycodes'; +import Browser from 'mobiledoc-kit/utils/browser'; import Helpers from '../test-helpers'; const { module, test } = Helpers; @@ -63,7 +64,7 @@ function testStatefulCommand({modifierName, key, command, markupName}) { editor.render(editorElement); assert.hasNoElement(`#editor ${markupName}`, `precond - no ${markupName} text`); - Helpers.dom.moveCursorTo(editor, + Helpers.dom.moveCursorTo(editor, editor.post.sections.head.markers.head.renderNode.element, initialText.length); Helpers.dom.triggerKeyCommand(editor, key, modifier); @@ -140,6 +141,58 @@ testStatefulCommand({ markupName: 'em' }); +test(`cmd-left goes to the beginning of a line (MacOS only)`, (assert) => { + let initialText = 'something'; + const mobiledoc = Helpers.mobiledoc.build( + ({post, markupSection, marker}) => post([ + markupSection('p', [marker(initialText)]) + ])); + + editor = new Editor({mobiledoc}); + editor.render(editorElement); + + let textElement = editor.post.sections.head.markers.head.renderNode.element; + + Helpers.dom.moveCursorTo(editor, textElement, 4); + let originalCursorPosition = Helpers.dom.getCursorPosition(); + Helpers.dom.triggerKeyCommand(editor, 'LEFT', MODIFIERS.META); + + let changedCursorPosition = Helpers.dom.getCursorPosition(); + let expectedCursorPosition = 0; // beginning of text + + if (Browser.isMac) { + assert.equal(changedCursorPosition.offset, expectedCursorPosition, 'cursor moved to the beginning of the line on MacOS'); + } else { + assert.equal(changedCursorPosition.offset, originalCursorPosition.offset, 'cursor not moved to the end of the line (non-MacOS)'); + } +}); + +test(`cmd-right goes to the end of a line (MacOS only)`, (assert) => { + let initialText = 'something'; + const mobiledoc = Helpers.mobiledoc.build( + ({post, markupSection, marker}) => post([ + markupSection('p', [marker(initialText)]) + ])); + + editor = new Editor({mobiledoc}); + editor.render(editorElement); + + let textElement = editor.post.sections.head.markers.head.renderNode.element; + + Helpers.dom.moveCursorTo(editor, textElement, 4); + let originalCursorPosition = Helpers.dom.getCursorPosition(); + Helpers.dom.triggerKeyCommand(editor, 'RIGHT', MODIFIERS.META); + + let changedCursorPosition = Helpers.dom.getCursorPosition(); + let expectedCursorPosition = initialText.length; // end of text + + if (Browser.isMac) { + assert.equal(changedCursorPosition.offset, expectedCursorPosition, 'cursor moved to the end of the line on MacOS'); + } else { + assert.equal(changedCursorPosition.offset, originalCursorPosition.offset, 'cursor not moved to the end of the line (non-MacOS)'); + } +}); + test(`ctrl-k clears to the end of a line`, (assert) => { let initialText = 'something'; const mobiledoc = Helpers.mobiledoc.build( diff --git a/tests/helpers/dom.js b/tests/helpers/dom.js index 90031e661..a301d0911 100644 --- a/tests/helpers/dom.js +++ b/tests/helpers/dom.js @@ -235,7 +235,7 @@ function triggerKeyCommand(editor, string, modifiers=[]) { if (typeof modifiers === "number") { modifiers = [modifiers]; // convert singular to array } - let charCode = string.toUpperCase().charCodeAt(0); + let charCode = (KEY_CODES[string] || string.toUpperCase().charCodeAt(0)); let keyCode = charCode; let keyEvent = createMockEvent('keydown', editor.element, { charCode,