Fixes #2586: Both model content change event strategies should reach the same versionId; Do not guess composition case in textareaState if text contains new line
This commit is contained in:
parent
db2464fa4c
commit
dd751e45ee
|
@ -163,7 +163,13 @@ export abstract class TextAreaState {
|
|||
if (currentSelectionStart === currentSelectionEnd) {
|
||||
// composition accept case
|
||||
// [blahblah] => blahblah|
|
||||
if (previousValue === currentValue && previousSelectionStart === 0 && previousSelectionEnd === previousValue.length && currentSelectionStart === currentValue.length) {
|
||||
if (
|
||||
previousValue === currentValue
|
||||
&& previousSelectionStart === 0
|
||||
&& previousSelectionEnd === previousValue.length
|
||||
&& currentSelectionStart === currentValue.length
|
||||
&& currentValue.indexOf('\n') === -1
|
||||
) {
|
||||
return {
|
||||
text: '',
|
||||
replaceCharCnt: 0
|
||||
|
|
|
@ -334,6 +334,9 @@ export class EditableTextModel extends TextModelWithDecorations implements Edito
|
|||
currentLineEdits: ILineEdit[] = [],
|
||||
currentLineNumber = 0;
|
||||
|
||||
var lastContentChangedVersionId = this.getVersionId();
|
||||
let lastContentChanged2VersionId = this.getVersionId();
|
||||
|
||||
var adjustLineNumbers = (toLineNumber:number, delta:number): void => {
|
||||
// console.log('adjustLineNumbers: ' + toLineNumber + ' by ' + delta + ', lines.length: ' + this._lines.length);
|
||||
if (delta !== 0) {
|
||||
|
@ -351,6 +354,7 @@ export class EditableTextModel extends TextModelWithDecorations implements Edito
|
|||
if (editLineNumber !== currentLineNumber) {
|
||||
if (currentLineEdits.length > 0) {
|
||||
this._applyLineEdits(deferredEventsBuilder, currentLineNumber, currentLineEdits);
|
||||
lastContentChangedVersionId = this.getVersionId();
|
||||
currentLineEdits = [];
|
||||
}
|
||||
currentLineNumber = editLineNumber;
|
||||
|
@ -374,14 +378,13 @@ export class EditableTextModel extends TextModelWithDecorations implements Edito
|
|||
var r = 0;
|
||||
if (currentLineEdits.length > 0) {
|
||||
r = this._applyLineEdits(deferredEventsBuilder, currentLineNumber, currentLineEdits);
|
||||
lastContentChangedVersionId = this.getVersionId();
|
||||
currentLineEdits = [];
|
||||
}
|
||||
currentLineNumber = 0;
|
||||
return r;
|
||||
};
|
||||
|
||||
let lastContentChanged2VersionId = this.getVersionId();
|
||||
|
||||
let lastRealOpIndex = 0;
|
||||
for (let i = operations.length - 1; i >= 0; i--) {
|
||||
if (!operations[i].isNoOp) {
|
||||
|
@ -483,6 +486,7 @@ export class EditableTextModel extends TextModelWithDecorations implements Edito
|
|||
this.emitModelContentChangedLineChangedEvent(spliceStart);
|
||||
|
||||
this.emitModelContentChangedLinesDeletedEvent(spliceStart + 1, spliceStart + spliceCnt);
|
||||
lastContentChangedVersionId = this.getVersionId();
|
||||
// this.emitModelContentChangedLinesInsertedEvent(startLineNumber + editingLinesCnt + 1, startLineNumber + insertingLinesCnt, newLinesContent.join('\n'));
|
||||
}
|
||||
|
||||
|
@ -521,6 +525,7 @@ export class EditableTextModel extends TextModelWithDecorations implements Edito
|
|||
this._lines[startLineNumber + insertingLinesCnt - 1].append(deferredEventsBuilder.changedMarkers, leftoverLine);
|
||||
|
||||
this.emitModelContentChangedLinesInsertedEvent(startLineNumber + editingLinesCnt + 1, startLineNumber + insertingLinesCnt, newLinesContent.join('\n'));
|
||||
lastContentChangedVersionId = this.getVersionId();
|
||||
}
|
||||
|
||||
// console.log('~~~');
|
||||
|
@ -548,6 +553,10 @@ export class EditableTextModel extends TextModelWithDecorations implements Edito
|
|||
this._emitContentChanged2(seqEdit.range.startLineNumber, seqEdit.range.startColumn, seqEdit.range.endLineNumber, seqEdit.range.endColumn, seqEdit.rangeLength, seqEdit.text, this._isUndoing, this._isRedoing);
|
||||
}
|
||||
|
||||
if (this.getVersionId() > lastContentChangedVersionId) {
|
||||
// TODO@Alex: need to rewrite the eventing logic
|
||||
this.emitModelContentChangedLineChangedEventNoVersionBump(baseLineNumber);
|
||||
}
|
||||
|
||||
adjustLineNumbers(this._lines.length, deltaLines);
|
||||
});
|
||||
|
@ -687,8 +696,7 @@ export class EditableTextModel extends TextModelWithDecorations implements Edito
|
|||
}
|
||||
}
|
||||
|
||||
private emitModelContentChangedLineChangedEvent(lineNumber: number): void {
|
||||
this._increaseVersionId();
|
||||
private emitModelContentChangedLineChangedEventNoVersionBump(lineNumber: number): void {
|
||||
var e:EditorCommon.IModelContentChangedLineChangedEvent = {
|
||||
changeType: EditorCommon.EventType.ModelContentChangedLineChanged,
|
||||
lineNumber: lineNumber,
|
||||
|
@ -702,6 +710,11 @@ export class EditableTextModel extends TextModelWithDecorations implements Edito
|
|||
}
|
||||
}
|
||||
|
||||
private emitModelContentChangedLineChangedEvent(lineNumber: number): void {
|
||||
this._increaseVersionId();
|
||||
this.emitModelContentChangedLineChangedEventNoVersionBump(lineNumber);
|
||||
}
|
||||
|
||||
private emitModelContentChangedLinesDeletedEvent(fromLineNumber: number, toLineNumber: number): void {
|
||||
this._increaseVersionId();
|
||||
var e:EditorCommon.IModelContentChangedLinesDeletedEvent = {
|
||||
|
|
|
@ -230,6 +230,15 @@ suite('TextAreaState', () => {
|
|||
);
|
||||
});
|
||||
|
||||
test('issue #2586: Replacing selected end-of-line with newline locks up the document', () => {
|
||||
testDeduceInput(
|
||||
new IENarratorTextAreaState(null, ']\n', 1, 2, false, 0),
|
||||
']\n',
|
||||
2, 2, false,
|
||||
'\n', 0
|
||||
);
|
||||
});
|
||||
|
||||
test('extractNewText - no previous state without selection', () => {
|
||||
testDeduceInput(
|
||||
null,
|
||||
|
|
|
@ -1174,6 +1174,22 @@ suite('EditorModel - EditableTextModel.applyEdits', () => {
|
|||
);
|
||||
});
|
||||
|
||||
test('issue #2586 Replacing selected end-of-line with newline locks up the document', () => {
|
||||
testApplyEdits(
|
||||
[
|
||||
'something',
|
||||
'interesting'
|
||||
],
|
||||
[
|
||||
editOp(1, 10, 2, 1, ['', ''])
|
||||
],
|
||||
[
|
||||
'something',
|
||||
'interesting'
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
function assertSyncedModels(text:string, callback:(model:EditableTextModel, assertMirrorModels:()=>void)=>void, setup:(model:EditableTextModel)=>void = null): void {
|
||||
var model = new EditableTextModel([], TextModel.toRawText(text), null);
|
||||
model.setEOL(EditorCommon.EndOfLineSequence.LF);
|
||||
|
|
Loading…
Reference in a new issue