Skip to content

Commit

Permalink
[FEATURE] holding shift while pasting pastes plain text
Browse files Browse the repository at this point in the history
fixes #334
  • Loading branch information
bantic committed Mar 24, 2016
1 parent 734b334 commit a006366
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 5 deletions.
17 changes: 14 additions & 3 deletions src/js/editor/event-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default class EventManager {
constructor(editor) {
this.editor = editor;
this._listeners = [];
this.isShift = false;
}

init() {
Expand Down Expand Up @@ -102,6 +103,11 @@ export default class EventManager {
if (!editor.isEditable) {
return;
}
let key = Key.fromEvent(event);
if (key.isShiftKey()) {
this.isShift = true;
}

if (editor.handleKeyCommand(event)) {
return;
}
Expand All @@ -110,7 +116,6 @@ export default class EventManager {
editor._insertEmptyMarkupSectionAtCursor();
}

let key = Key.fromEvent(event);
let range = editor.range;

switch(true) {
Expand Down Expand Up @@ -139,7 +144,12 @@ export default class EventManager {
}
}

keyup(/* event */) {
keyup(event) {
let key = Key.fromEvent(event);
if (key.isShiftKey()) {
this.isShift = false;
}

setTimeout(() => this.editor._resetRange(), 0);
}

Expand Down Expand Up @@ -175,7 +185,8 @@ export default class EventManager {
editor.handleDeletion();
}
let position = editor.range.head;
let pastedPost = parsePostFromPaste(event, editor);
let targetFormat = this.isShift ? 'text' : 'html';
let pastedPost = parsePostFromPaste(event, editor, {targetFormat});

editor.run(postEditor => {
let nextPosition = postEditor.insertPost(position, pastedPost);
Expand Down
18 changes: 18 additions & 0 deletions src/js/utils/key.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,28 @@ const Key = class Key {
return this.keyCode === Keycodes.ENTER;
}

/**
* If the shift key is depressed.
* For example, while holding down meta+shift, pressing the "v"
* key would result in an event whose `Key` had `isShift()` with a truthy value,
* because the shift key is down when pressing the "v".
* @see {isShiftKey} which checks if the key is actually the shift key itself.
* @return {bool}
*/
isShift() {
return this.shiftKey;
}

/*
* If the key is the actual shift key. This is false when the shift key
* is held down and the source `event` is not the shift key.
* @see {isShift}
* @return {bool}
*/
isShiftKey() {
return this.keyCode === Keycodes.SHIFT;
}

hasModifier(modifier) {
return modifier & this.modifierMask;
}
Expand Down
1 change: 1 addition & 0 deletions src/js/utils/keycodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export default {
BACKSPACE: 8,
SPACE: 32,
ENTER: 13,
SHIFT: 16,
ESC: 27,
DELETE: 46,
'0': 48,
Expand Down
4 changes: 2 additions & 2 deletions src/js/utils/parse-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,10 @@ export function setClipboardData(event, {mobiledoc, html, text}, window) {
* @param {{builder: Builder, _parserPlugins: Array}} options
* @return {Post}
*/
export function parsePostFromPaste(pasteEvent, {builder, _parserPlugins: plugins}) {
export function parsePostFromPaste(pasteEvent, {builder, _parserPlugins: plugins}, {targetFormat}={targetFormat:'html'}) {
let { html, text } = getContentFromPasteEvent(pasteEvent, window);

if (html && html.length) {
if (targetFormat === 'html' && html && html.length) {
return parsePostFromHTML(html, builder, plugins);
} else if (text && text.length) {
return parsePostFromText(text, builder, plugins);
Expand Down
26 changes: 26 additions & 0 deletions tests/acceptance/editor-copy-paste-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
MIME_TEXT_PLAIN,
MIME_TEXT_HTML
} from 'mobiledoc-kit/utils/parse-utils';
import Keycodes from 'mobiledoc-kit/utils/keycodes';

const { module, test } = Helpers;

Expand Down Expand Up @@ -373,3 +374,28 @@ test('pasting when replacing a list item works', (assert) => {
assert.hasElement('#editor li:contains(X)', 'replaces Y with X in li');
assert.hasNoElement('#editor li:contains(Y)', 'li with Y is gone');
});

test('paste with shift key pastes plain text', (assert) => {
let expected;
editor = Helpers.mobiledoc.renderInto(editorElement, ({post, markupSection, marker, markup}) => {
expected = post([
markupSection('p', [
marker('a'), marker('b', [markup('b')]), marker('cabc')
])
]);
return post([
markupSection('p', [
marker('a'), marker('b', [markup('b')]), marker('c')
])
]);
});

editor.selectRange(new Range(editor.post.headPosition(), editor.post.tailPosition()));
Helpers.dom.triggerCopyEvent(editor);
editor.selectRange(new Range(editor.post.tailPosition()));

Helpers.dom.triggerKeyEvent(editor, 'keydown', { keyCode: Keycodes.SHIFT });
Helpers.dom.triggerPasteEvent(editor);

assert.postIsSimilar(editor.post, expected);
});
6 changes: 6 additions & 0 deletions tests/helpers/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,11 @@ function insertText(editor, string) {
});
}

function triggerKeyEvent(editor, eventName, options={}) {
let event = createMockEvent(eventName, editor.element, options);
_triggerEditorEvent(editor, event);
}

// triggers a key sequence like cmd-B on the editor, to test out
// registered keyCommands
function triggerKeyCommand(editor, string, modifiers=[]) {
Expand Down Expand Up @@ -376,6 +381,7 @@ const DOMHelper = {
triggerForwardDelete,
triggerEnter,
insertText,
triggerKeyEvent,
triggerKeyCommand,
triggerRightArrowKey,
triggerLeftArrowKey,
Expand Down

0 comments on commit a006366

Please sign in to comment.