update last caret from update callback instead of input event
many editor updates are not caused by an input event, so the last caret wasn't always up to date. Updating the caret from the update callback ensures that every time the editor contents is changed, the last caret is updated.
This commit is contained in:
parent
124b7135cd
commit
2596281a7c
2 changed files with 23 additions and 7 deletions
|
@ -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 = () => {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue