diff --git a/src/components/views/rooms/BasicMessageComposer.js b/src/components/views/rooms/BasicMessageComposer.js index c5661e561c..2764a8da46 100644 --- a/src/components/views/rooms/BasicMessageComposer.js +++ b/src/components/views/rooms/BasicMessageComposer.js @@ -116,6 +116,9 @@ export default class BasicMessageEditor extends React.Component { } catch (err) { console.error(err); } + // if caret is a range, take the end position + const position = caret.end || caret; + this._setLastCaretFromPosition(position); } if (this.props.placeholder) { const {isEmpty} = this.props.model; @@ -165,7 +168,6 @@ export default class BasicMessageEditor extends React.Component { this._modifiedFlag = true; const sel = document.getSelection(); const {caret, text} = getCaretOffsetAndText(this._editorRef, sel); - this._setLastCaret(caret, text, sel); this.props.model.update(text, event.inputType, caret); } @@ -183,10 +185,11 @@ export default class BasicMessageEditor extends React.Component { // we don't need to. But if the user is navigating the caret without input // we need to recalculate it, to be able to know where to insert content after // losing focus - _setLastCaret(caret, text, selection) { - this._lastSelection = cloneSelection(selection); - this._lastCaret = caret; - this._lastTextLength = text.length; + _setLastCaretFromPosition(position) { + const {model} = this.props; + this._isCaretAtEnd = position.isAtEnd(model); + this._lastCaret = position.asOffset(model); + this._lastSelection = cloneSelection(document.getSelection()); } _refreshLastCaretIfNeeded() { @@ -201,7 +204,7 @@ export default class BasicMessageEditor extends React.Component { this._lastSelection = cloneSelection(selection); const {caret, text} = getCaretOffsetAndText(this._editorRef, selection); this._lastCaret = caret; - this._lastTextLength = text.length; + this._isCaretAtEnd = caret.offset === text.length; } return this._lastCaret; } @@ -223,7 +226,7 @@ export default class BasicMessageEditor extends React.Component { } isCaretAtEnd() { - return this.getCaret().offset === this._lastTextLength; + return this._isCaretAtEnd; } _onBlur = () => { diff --git a/src/editor/position.js b/src/editor/position.js index 98b158e547..4693f62999 100644 --- a/src/editor/position.js +++ b/src/editor/position.js @@ -120,4 +120,17 @@ export default class DocumentPosition { const atEnd = offset >= lastPart.text.length; return new DocumentOffset(offset, atEnd); } + + isAtEnd(model) { + if (model.parts.length === 0) { + return true; + } + const lastPartIdx = model.parts.length - 1; + const lastPart = model.parts[lastPartIdx]; + return this.index === lastPartIdx && this.offset === lastPart.text.length; + } + + isAtStart() { + return this.index === 0 && this.offset === 0; + } }