mirror of https://github.com/vector-im/riot-web
basic support for non-editable parts
e.g. pills, they get deleted when any character of them is removed later on we also shouldn't allow the caret to be set inside of thempull/21833/head
parent
fc87a27c5d
commit
5e6367ab57
|
@ -20,7 +20,6 @@ export default class EditorModel {
|
|||
constructor(parts, partCreator) {
|
||||
this._parts = parts;
|
||||
this._partCreator = partCreator;
|
||||
this._previousValue = parts.reduce((text, p) => text + p.text, "");
|
||||
this._activePartIdx = null;
|
||||
this._autoComplete = null;
|
||||
this._autoCompletePartIdx = null;
|
||||
|
@ -68,19 +67,19 @@ export default class EditorModel {
|
|||
_diff(newValue, inputType, caret) {
|
||||
// handle deleteContentForward (Delete key)
|
||||
// and deleteContentBackward (Backspace)
|
||||
|
||||
const previousValue = this.parts.reduce((text, p) => text + p.text, "");
|
||||
// can't use caret position with drag and drop
|
||||
if (inputType === "deleteByDrag") {
|
||||
return diffDeletion(this._previousValue, newValue);
|
||||
return diffDeletion(previousValue, newValue);
|
||||
} else {
|
||||
return diffAtCaret(this._previousValue, newValue, caret.offset);
|
||||
return diffAtCaret(previousValue, newValue, caret.offset);
|
||||
}
|
||||
}
|
||||
|
||||
update(newValue, inputType, caret) {
|
||||
const diff = this._diff(newValue, inputType, caret);
|
||||
const position = this._positionForOffset(diff.at, caret.atNodeEnd);
|
||||
console.log("update at", {position, diff, newValue, prevValue: this._previousValue});
|
||||
console.log("update at", {position, diff, newValue, prevValue: this.parts.reduce((text, p) => text + p.text, "")});
|
||||
if (diff.removed) {
|
||||
this._removeText(position, diff.removed.length);
|
||||
}
|
||||
|
@ -88,7 +87,6 @@ export default class EditorModel {
|
|||
this._addText(position, diff.added);
|
||||
}
|
||||
this._mergeAdjacentParts();
|
||||
this._previousValue = newValue;
|
||||
const caretOffset = diff.at + (diff.added ? diff.added.length : 0);
|
||||
const newPosition = this._positionForOffset(caretOffset, true);
|
||||
this._setActivePart(newPosition);
|
||||
|
@ -141,23 +139,28 @@ export default class EditorModel {
|
|||
|
||||
_removeText(pos, len) {
|
||||
let {index, offset} = pos;
|
||||
while (len !== 0) {
|
||||
while (len > 0) {
|
||||
// part might be undefined here
|
||||
let part = this._parts[index];
|
||||
const amount = Math.min(len, part.text.length - offset);
|
||||
const replaceWith = part.remove(offset, amount);
|
||||
if (typeof replaceWith === "string") {
|
||||
this._replacePart(index, this._partCreator.createDefaultPart(replaceWith));
|
||||
}
|
||||
part = this._parts[index];
|
||||
// remove empty part
|
||||
if (!part.text.length) {
|
||||
this._removePart(index);
|
||||
if (part.canEdit) {
|
||||
const amount = Math.min(len, part.text.length - offset);
|
||||
const replaceWith = part.remove(offset, amount);
|
||||
if (typeof replaceWith === "string") {
|
||||
this._replacePart(index, this._partCreator.createDefaultPart(replaceWith));
|
||||
}
|
||||
part = this._parts[index];
|
||||
// remove empty part
|
||||
if (!part.text.length) {
|
||||
this._removePart(index);
|
||||
} else {
|
||||
index += 1;
|
||||
}
|
||||
len -= amount;
|
||||
offset = 0;
|
||||
} else {
|
||||
index += 1;
|
||||
len = part.length - (offset + len);
|
||||
this._removePart(index);
|
||||
}
|
||||
len -= amount;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -91,6 +91,10 @@ class BasePart {
|
|||
get text() {
|
||||
return this._text;
|
||||
}
|
||||
|
||||
get canEdit() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class PlainPart extends BasePart {
|
||||
|
@ -165,6 +169,10 @@ class PillPart extends BasePart {
|
|||
node.childNodes.length === 1 &&
|
||||
node.childNodes[0].nodeType === Node.TEXT_NODE;
|
||||
}
|
||||
|
||||
get canEdit() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export class RoomPillPart extends PillPart {
|
||||
|
|
Loading…
Reference in New Issue