From bad42ff09ab9307b8dc4e903ce22cd2c1d31825c Mon Sep 17 00:00:00 2001 From: Cory Forsyth Date: Wed, 6 Jan 2016 18:14:34 -0500 Subject: [PATCH] only find text expansion when at end of markup section fixes #280 --- src/js/editor/editor.js | 6 +++- src/js/editor/text-expansions.js | 11 +++---- src/js/models/_section.js | 9 ++---- .../acceptance/editor-text-expansions-test.js | 29 +++++++++++++++---- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/src/js/editor/editor.js b/src/js/editor/editor.js index 1cd90a0c0..e6cbd4808 100644 --- a/src/js/editor/editor.js +++ b/src/js/editor/editor.js @@ -98,7 +98,11 @@ class Editor { this._renderer = new Renderer(this, this.cards, this.unknownCardHandler, this.cardOptions); this._handleLastKeydownExpansion = () => { - this.handleExpansion(this._lastKeydownEvent); + // Chrome does not report cursor selection properly from a Mutation event + // until the next frame of JavaScript + setTimeout(() => { + this.handleExpansion(this._lastKeydownEvent); + }, 0); }; this.post = this.loadPost(); diff --git a/src/js/editor/text-expansions.js b/src/js/editor/text-expansions.js index 35d3758d9..990009018 100644 --- a/src/js/editor/text-expansions.js +++ b/src/js/editor/text-expansions.js @@ -1,7 +1,6 @@ import Keycodes from '../utils/keycodes'; import Key from '../utils/key'; import { detect } from '../utils/array-utils'; -import { MARKUP_SECTION_TYPE } from '../models/types'; import Range from '../utils/cursor/range'; const { SPACE } = Keycodes; @@ -15,7 +14,7 @@ function replaceWithListSection(editor, listTagName) { const listSection = builder.createListSection(listTagName, [listItem]); postEditor.replaceSection(section, listSection); - postEditor.setRange(Range.fromSection(listItem)); + postEditor.setRange(new Range(listSection.tailPosition())); }); } @@ -25,8 +24,9 @@ function replaceWithHeaderSection(editor, headingTagName) { editor.run(postEditor => { const {builder} = postEditor; const newSection = builder.createMarkupSection(headingTagName); + postEditor.replaceSection(section, newSection); - postEditor.setRange(Range.fromSection(newSection)); + postEditor.setRange(new Range(newSection.tailPosition())); }); } @@ -76,8 +76,9 @@ export function findExpansion(expansions, keyEvent, editor) { const key = Key.fromEvent(keyEvent); if (!key.isPrintable()) { return; } - const {head:{section, offset}} = editor.cursor.offsets; - if (section.type !== MARKUP_SECTION_TYPE) { return; } + const {head, head:{section, offset}} = editor.cursor.offsets; + if (!section.isMarkupSection) { return; } + if (!head.isEqual(section.tailPosition())) { return; } // FIXME this is potentially expensive to calculate and might be better // perf to first find expansions matching the trigger and only if matches diff --git a/src/js/models/_section.js b/src/js/models/_section.js index 493eb8fd7..0f93bd503 100644 --- a/src/js/models/_section.js +++ b/src/js/models/_section.js @@ -1,12 +1,7 @@ -import { LIST_ITEM_TYPE } from './types'; import { normalizeTagName } from '../utils/dom-utils'; import LinkedItem from '../utils/linked-item'; import assert from '../utils/assert'; -function isChild(section) { - return section.type === LIST_ITEM_TYPE; -} - function unimplementedMethod(methodName, me) { throw new Error(`\`${methodName}()\` must be implemented by ${me.constructor.name}`); } @@ -68,7 +63,7 @@ export default class Section extends LinkedItem { return next; } } else { - if (isChild(this)) { + if (this.isNested) { return this.parent.nextLeafSection(); } } @@ -92,7 +87,7 @@ export default class Section extends LinkedItem { return prev; } } else { - if (isChild(this)) { + if (this.isNested) { return this.parent.previousLeafSection(); } } diff --git a/tests/acceptance/editor-text-expansions-test.js b/tests/acceptance/editor-text-expansions-test.js index 20fdefd4f..6cd637337 100644 --- a/tests/acceptance/editor-text-expansions-test.js +++ b/tests/acceptance/editor-text-expansions-test.js @@ -39,7 +39,7 @@ test('typing "## " converts to h2', (assert) => { assert.hasElement('#editor h2:contains(X)', 'text is inserted correctly'); done(); }, 0); - }, 0); + }, 10); }); test('space is required to trigger "## " expansion', (assert) => { @@ -73,7 +73,7 @@ test('typing "### " converts to h3', (assert) => { assert.hasElement('#editor h3:contains(X)', 'text is inserted correctly'); done(); }, 0); - }, 0); + }, 10); }); test('typing "* " converts to ul > li', (assert) => { @@ -93,7 +93,24 @@ test('typing "* " converts to ul > li', (assert) => { assert.hasElement('#editor li:contains(X)', 'text is inserted correctly'); done(); }, 0); - }, 0); + }, 10); +}); + +// see https://github.com/bustlelabs/mobiledoc-kit/issues/280 +test('typing "* " at start of markup section does not remove it', (assert) => { + let done = assert.async(); + const mobiledoc = Helpers.mobiledoc.build(({post, marker, markupSection}) => { + return post([markupSection('p', [marker('abc')])]); + }); + + editor = new Editor({mobiledoc}); + editor.render(editorElement); + insertText('* '); + window.setTimeout(() => { + assert.hasElement('#editor p:contains(* abc)', 'p is still there'); + done(); + }, 10); + }); test('typing "* " inside of a list section does not create a new list section', (assert) => { @@ -133,7 +150,7 @@ test('typing "1 " converts to ol > li', (assert) => { assert.hasElement('#editor li:contains(X)', 'text is inserted correctly'); done(); }, 0); - }, 0); + }, 10); }); test('typing "1. " converts to ol > li', (assert) => { @@ -154,7 +171,7 @@ test('typing "1. " converts to ol > li', (assert) => { assert.hasElement('#editor li:contains(X)', 'text is inserted correctly'); done(); }, 0); - }, 0); + }, 10); }); test('a new expansion can be registered', (assert) => { @@ -174,5 +191,5 @@ test('a new expansion can be registered', (assert) => { window.setTimeout(() => { assert.ok(didExpand, 'expansion was run'); done(); - }, 0); + }, 10); });