bring insert method inline with transform callback, add docs

before the insertPartsAt method would call the update callback
on its own, but now we have the concept of a transformation session,
so lets bring the API in line
This commit is contained in:
Bruno Windels 2019-08-27 16:37:04 +02:00
parent 8e66d382de
commit d8bb9ecedf
3 changed files with 31 additions and 11 deletions

View file

@ -279,22 +279,33 @@ export default class SendMessageComposer extends React.Component {
};
_insertMention(userId) {
const {model} = this;
const {partCreator} = model;
const member = this.props.room.getMember(userId);
const displayName = member ?
member.rawDisplayName : userId;
const userPillPart = this.model.partCreator.userPill(displayName, userId);
this.model.insertPartsAt([userPillPart], this._editorRef.getCaret());
const userPillPart = partCreator.userPill(displayName, userId);
const caret = this._editorRef.getCaret();
const position = model.positionForOffset(caret.offset, caret.atNodeEnd);
model.transform(() => {
const addedLen = model.insert([userPillPart], position);
return model.positionForOffset(caret.offset + addedLen, true);
});
// refocus on composer, as we just clicked "Mention"
this._editorRef && this._editorRef.focus();
}
_insertQuotedMessage(event) {
const {partCreator} = this.model;
const {model} = this;
const {partCreator} = model;
const quoteParts = parseEvent(event, partCreator, { isQuotedMessage: true });
// add two newlines
quoteParts.push(partCreator.newline());
quoteParts.push(partCreator.newline());
this.model.insertPartsAt(quoteParts, {offset: 0});
model.transform(() => {
const addedLen = model.insert(quoteParts, model.positionForOffset(0));
return model.positionForOffset(addedLen, true);
});
// refocus on composer, as we just clicked "Quote"
this._editorRef && this._editorRef.focus();
}

View file

@ -158,8 +158,14 @@ export default class EditorModel {
this._updateCallback(caret, inputType);
}
insertPartsAt(parts, caret) {
const position = this.positionForOffset(caret.offset, caret.atNodeEnd);
/**
* Inserts the given parts at the given position.
* Should be run inside a `model.transform()` callback.
* @param {Part[]} parts the parts to replace the range with
* @param {DocumentPosition} position the position to start inserting at
* @return {Number} the amount of characters added
*/
insert(parts, position) {
const insertIndex = this._splitAt(position);
let newTextLength = 0;
for (let i = 0; i < parts.length; ++i) {
@ -167,10 +173,7 @@ export default class EditorModel {
newTextLength += part.text.length;
this._insertPart(insertIndex + i, part);
}
// put caret after new part
const lastPartIndex = insertIndex + parts.length - 1;
const newPosition = new DocumentPosition(lastPartIndex, newTextLength);
this._updateCallback(newPosition);
return newTextLength;
}
update(newValue, inputType, caret) {
@ -403,7 +406,7 @@ export default class EditorModel {
return new Range(this, position);
}
// called from Range.replace
//mostly internal, called from Range.replace
replaceRange(startPosition, endPosition, parts) {
const newStartPartIndex = this._splitAt(startPosition);
const idxDiff = newStartPartIndex - startPosition.index;

View file

@ -41,6 +41,12 @@ export default class Range {
return text;
}
/**
* Splits the model at the range boundaries and replaces with the given parts.
* Should be run inside a `model.transform()` callback.
* @param {Part[]} parts the parts to replace the range with
* @return {Number} the net amount of characters added, can be negative.
*/
replace(parts) {
const newLength = parts.reduce((sum, part) => sum + part.text.length, 0);
let oldLength = 0;