Skip to content

Commit 251675e

Browse files
committed
[BUGFIX] Do not handle key events when the editor has no cursor
It is possible for the editor's element to be focused but not have a cursor (selection). In this case, key events will fire on the editor's element but the editor will not be able to determine a logical `Position` (since there is no selection). When this happens, we abort handling the key event. fixes #344
1 parent 61adff6 commit 251675e

File tree

4 files changed

+48
-11
lines changed

4 files changed

+48
-11
lines changed

src/js/editor/editor.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ class Editor {
258258
}
259259

260260
handleNewline(event) {
261-
if (!this.cursor.hasCursor()) { return; }
261+
if (!this.hasCursor()) { return; }
262262

263263
event.preventDefault();
264264

@@ -503,9 +503,20 @@ class Editor {
503503
this._views = [];
504504
}
505505

506+
/**
507+
* Whether the editor has a cursor (or a selected range).
508+
* It is possible for the editor to be focused but not have a selection.
509+
* In this case, key events will fire but the editor will not be able to
510+
* determine a cursor position.
511+
* @return {bool}
512+
*/
513+
hasCursor() {
514+
return this.cursor.hasCursor();
515+
}
516+
506517
destroy() {
507518
this._isDestroyed = true;
508-
if (this.cursor.hasCursor()) {
519+
if (this.hasCursor()) {
509520
this.cursor.clearSelection();
510521
this.element.blur(); // FIXME This doesn't blur the element on IE11
511522
}

src/js/editor/event-manager.js

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,16 @@ export default class EventManager {
8383
}
8484

8585
keypress(event) {
86+
let { editor } = this;
87+
if (!editor.hasCursor()) { return; }
88+
8689
let key = Key.fromEvent(event);
8790
if (!key.isPrintable()) {
8891
return;
92+
} else {
93+
event.preventDefault();
8994
}
9095

91-
event.preventDefault();
92-
93-
let { editor } = this;
9496
if (editor.handleExpansion(event)) {
9597
return;
9698
} else {
@@ -100,17 +102,15 @@ export default class EventManager {
100102

101103
keydown(event) {
102104
let { editor } = this;
103-
if (!editor.isEditable) {
104-
return;
105-
}
105+
if (!editor.hasCursor()) { return; }
106+
if (!editor.isEditable) { return; }
107+
106108
let key = Key.fromEvent(event);
107109
if (key.isShiftKey()) {
108110
this.isShift = true;
109111
}
110112

111-
if (editor.handleKeyCommand(event)) {
112-
return;
113-
}
113+
if (editor.handleKeyCommand(event)) { return; }
114114

115115
if (editor.post.isBlank) {
116116
editor._insertEmptyMarkupSectionAtCursor();
@@ -145,6 +145,8 @@ export default class EventManager {
145145
}
146146

147147
keyup(event) {
148+
let { editor } = this;
149+
if (!editor.hasCursor()) { return; }
148150
let key = Key.fromEvent(event);
149151
if (key.isShiftKey()) {
150152
this.isShift = false;

tests/acceptance/basic-editor-test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,22 @@ test('adding/removing bold text between two bold markers works', (assert) => {
265265
assert.hasElement('#editor b:contains(def)', 'removes B from middle, leaves def');
266266
assert.hasNoElement('#editor b:contains(123)', 'removes B from middle');
267267
});
268+
269+
test('keypress events when the editor does not have selection are ignored', (assert) => {
270+
let expected;
271+
editor = Helpers.mobiledoc.renderInto(editorElement, ({post, markupSection, marker}) => {
272+
expected = post([markupSection('p', [marker('abc')])]);
273+
return post([
274+
markupSection('p', [marker('abc')])
275+
]);
276+
});
277+
278+
Helpers.dom.clearSelection();
279+
280+
assert.ok(document.activeElement === editorElement, 'precond - editor is focused');
281+
assert.equal(window.getSelection().rangeCount, 0, 'nothing selected');
282+
283+
Helpers.dom.insertText(editor, 'v');
284+
285+
assert.postIsSimilar(editor.post, expected, 'post is not changed');
286+
});

tests/helpers/dom.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@ function triggerKeyCommand(editor, string, modifiers=[]) {
247247
_triggerEditorEvent(editor, keyEvent);
248248
}
249249

250+
function triggerKeyEvent(editor, type, options) {
251+
let event = createMockEvent(type, editor.element, options);
252+
_triggerEditorEvent(editor, event);
253+
}
254+
250255
function triggerRightArrowKey(editor, modifier) {
251256
if (!(editor instanceof Editor)) {
252257
throw new Error('Must pass editor to triggerRightArrowKey');

0 commit comments

Comments
 (0)