Record the visible line count for the text in value before selectionStart in the text area state

This commit is contained in:
Alex Dima
2022-10-19 15:44:23 +02:00
parent 88d40efb9d
commit d8493fe63c
9 changed files with 125 additions and 112 deletions
@@ -201,6 +201,9 @@ export class TextAreaHandler extends ViewPart {
},
getValueLengthInRange: (range: Range, eol: EndOfLinePreference): number => {
return this._context.viewModel.getValueLengthInRange(range, eol);
},
modifyPosition: (position: Position, offset: number): Position => {
return this._context.viewModel.modifyPosition(position, offset);
}
};
@@ -230,7 +233,7 @@ export class TextAreaHandler extends ViewPart {
mode
};
},
getScreenReaderContent: (currentState: TextAreaState): TextAreaState => {
getScreenReaderContent: (): TextAreaState => {
if (this._accessibilitySupport === AccessibilitySupport.Disabled) {
// We know for a fact that a screen reader is not attached
// On OSX, we write the character before the cursor to allow for "long-press" composition
@@ -245,7 +248,7 @@ export class TextAreaHandler extends ViewPart {
}
if (textBefore.length > 0) {
return new TextAreaState(textBefore, textBefore.length, textBefore.length, position, position);
return new TextAreaState(textBefore, textBefore.length, textBefore.length, Range.fromPositions(position), 0);
}
}
// on macOS, write current selection into textarea will allow system text services pick selected text,
@@ -255,7 +258,7 @@ export class TextAreaHandler extends ViewPart {
const LIMIT_CHARS = 500;
if (platform.isMacintosh && !selection.isEmpty() && simpleModel.getValueLengthInRange(selection, EndOfLinePreference.TextDefined) < LIMIT_CHARS) {
const text = simpleModel.getValueInRange(selection, EndOfLinePreference.TextDefined);
return new TextAreaState(text, 0, text.length, selection.getStartPosition(), selection.getEndPosition());
return new TextAreaState(text, 0, text.length, selection, 0);
}
// on Safari, document.execCommand('cut') and document.execCommand('copy') will just not work
@@ -263,7 +266,7 @@ export class TextAreaHandler extends ViewPart {
// is selected in the textarea.
if (browser.isSafari && !selection.isEmpty()) {
const placeholderText = 'vscode-placeholder';
return new TextAreaState(placeholderText, 0, placeholderText.length, null, null);
return new TextAreaState(placeholderText, 0, placeholderText.length, null, undefined);
}
return TextAreaState.EMPTY;
@@ -279,13 +282,13 @@ export class TextAreaHandler extends ViewPart {
const position = selection.getStartPosition();
const [wordAtPosition, positionOffsetInWord] = this._getAndroidWordAtPosition(position);
if (wordAtPosition.length > 0) {
return new TextAreaState(wordAtPosition, positionOffsetInWord, positionOffsetInWord, position, position);
return new TextAreaState(wordAtPosition, positionOffsetInWord, positionOffsetInWord, Range.fromPositions(position), 0);
}
}
return TextAreaState.EMPTY;
}
return PagedScreenReaderStrategy.fromEditorSelection(currentState, simpleModel, this._selections[0], this._accessibilityPageSize, this._accessibilitySupport === AccessibilitySupport.Unknown);
return PagedScreenReaderStrategy.fromEditorSelection(simpleModel, this._selections[0], this._accessibilityPageSize, this._accessibilitySupport === AccessibilitySupport.Unknown);
},
deduceModelPosition: (viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position => {
@@ -52,7 +52,7 @@ export interface ClipboardStoredMetadata {
export interface ITextAreaInputHost {
getDataToCopy(): ClipboardDataToCopy;
getScreenReaderContent(currentState: TextAreaState): TextAreaState;
getScreenReaderContent(): TextAreaState;
deduceModelPosition(viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position;
}
@@ -296,7 +296,7 @@ export class TextAreaInput extends Disposable {
// For example, if the cursor is in the middle of a word like Mic|osoft
// and Microsoft is chosen from the keyboard's suggestions, the e.data will contain "Microsoft".
// This is not really usable because it doesn't tell us where the edit began and where it ended.
const newState = TextAreaState.readFromTextArea(this._textArea);
const newState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState);
const typeInput = TextAreaState.deduceAndroidCompositionInput(this._textAreaState, newState);
this._textAreaState = newState;
this._onType.fire(typeInput);
@@ -304,7 +304,7 @@ export class TextAreaInput extends Disposable {
return;
}
const typeInput = currentComposition.handleCompositionUpdate(e.data);
this._textAreaState = TextAreaState.readFromTextArea(this._textArea);
this._textAreaState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState);
this._onType.fire(typeInput);
this._onCompositionUpdate.fire(e);
}));
@@ -326,7 +326,7 @@ export class TextAreaInput extends Disposable {
// For example, if the cursor is in the middle of a word like Mic|osoft
// and Microsoft is chosen from the keyboard's suggestions, the e.data will contain "Microsoft".
// This is not really usable because it doesn't tell us where the edit began and where it ended.
const newState = TextAreaState.readFromTextArea(this._textArea);
const newState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState);
const typeInput = TextAreaState.deduceAndroidCompositionInput(this._textAreaState, newState);
this._textAreaState = newState;
this._onType.fire(typeInput);
@@ -335,7 +335,7 @@ export class TextAreaInput extends Disposable {
}
const typeInput = currentComposition.handleCompositionUpdate(e.data);
this._textAreaState = TextAreaState.readFromTextArea(this._textArea);
this._textAreaState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState);
this._onType.fire(typeInput);
this._onCompositionEnd.fire();
}));
@@ -353,7 +353,7 @@ export class TextAreaInput extends Disposable {
return;
}
const newState = TextAreaState.readFromTextArea(this._textArea);
const newState = TextAreaState.readFromTextArea(this._textArea, this._textAreaState);
const typeInput = TextAreaState.deduceInput(this._textAreaState, newState, /*couldBeEmojiInput*/this._OS === OperatingSystem.Macintosh);
if (typeInput.replacePrevCharCnt === 0 && typeInput.text.length === 1 && strings.isHighSurrogate(typeInput.text.charCodeAt(0))) {
@@ -459,7 +459,7 @@ export class TextAreaInput extends Disposable {
_initializeFromTest(): void {
this._hasFocus = true;
this._textAreaState = TextAreaState.readFromTextArea(this._textArea);
this._textAreaState = TextAreaState.readFromTextArea(this._textArea, null);
}
private _installSelectionChangeListener(): IDisposable {
@@ -512,7 +512,7 @@ export class TextAreaInput extends Disposable {
return;
}
if (!this._textAreaState.selectionStartPosition || !this._textAreaState.selectionEndPosition) {
if (!this._textAreaState.selection) {
// Cannot correlate a position in the textarea with a position in the editor...
return;
}
@@ -611,7 +611,7 @@ export class TextAreaInput extends Disposable {
return;
}
this._setAndWriteTextAreaState(reason, this._host.getScreenReaderContent(this._textAreaState));
this._setAndWriteTextAreaState(reason, this._host.getScreenReaderContent());
}
private _ensureClipboardGetsEditorSelection(e: ClipboardEvent): void {
@@ -24,6 +24,7 @@ export interface ISimpleModel {
getLineMaxColumn(lineNumber: number): number;
getValueInRange(range: Range, eol: EndOfLinePreference): string;
getValueLengthInRange(range: Range, eol: EndOfLinePreference): number;
modifyPosition(position: Position, offset: number): Position;
}
export interface ITypeData {
@@ -35,32 +36,44 @@ export interface ITypeData {
export class TextAreaState {
public static readonly EMPTY = new TextAreaState('', 0, 0, null, null);
public static readonly EMPTY = new TextAreaState('', 0, 0, null, undefined);
public readonly value: string;
public readonly selectionStart: number;
public readonly selectionEnd: number;
public readonly selectionStartPosition: Position | null;
public readonly selectionEndPosition: Position | null;
constructor(value: string, selectionStart: number, selectionEnd: number, selectionStartPosition: Position | null, selectionEndPosition: Position | null) {
this.value = value;
this.selectionStart = selectionStart;
this.selectionEnd = selectionEnd;
this.selectionStartPosition = selectionStartPosition;
this.selectionEndPosition = selectionEndPosition;
}
constructor(
public readonly value: string,
/** the offset where selection starts inside `value` */
public readonly selectionStart: number,
/** the offset where selection ends inside `value` */
public readonly selectionEnd: number,
/** the editor range in the view coordinate system that matches the selection inside `value` */
public readonly selection: Range | null,
/** the visible line count (wrapped, not necessarily matching \n characters) for the text in `value` before `selectionStart` */
public readonly newlineCountBeforeSelection: number | undefined,
) { }
public toString(): string {
return `[ <${this.value}>, selectionStart: ${this.selectionStart}, selectionEnd: ${this.selectionEnd}]`;
}
public static readFromTextArea(textArea: ITextAreaWrapper): TextAreaState {
return new TextAreaState(textArea.getValue(), textArea.getSelectionStart(), textArea.getSelectionEnd(), null, null);
public static readFromTextArea(textArea: ITextAreaWrapper, previousState: TextAreaState | null): TextAreaState {
const value = textArea.getValue();
const selectionStart = textArea.getSelectionStart();
const selectionEnd = textArea.getSelectionEnd();
let newlineCountBeforeSelection: number | undefined = undefined;
if (previousState) {
const valueBeforeSelectionStart = value.substring(0, selectionStart);
const previousValueBeforeSelectionStart = previousState.value.substring(0, previousState.selectionStart);
if (valueBeforeSelectionStart === previousValueBeforeSelectionStart) {
newlineCountBeforeSelection = previousState.newlineCountBeforeSelection;
}
}
return new TextAreaState(value, selectionStart, selectionEnd, null, newlineCountBeforeSelection);
}
public collapseSelection(): TextAreaState {
return new TextAreaState(this.value, this.value.length, this.value.length, null, null);
if (this.selectionStart === this.value.length) {
return this;
}
return new TextAreaState(this.value, this.value.length, this.value.length, null, undefined);
}
public writeToTextArea(reason: string, textArea: ITextAreaWrapper, select: boolean): void {
@@ -76,18 +89,18 @@ export class TextAreaState {
public deduceEditorPosition(offset: number): [Position | null, number, number] {
if (offset <= this.selectionStart) {
const str = this.value.substring(offset, this.selectionStart);
return this._finishDeduceEditorPosition(this.selectionStartPosition, str, -1);
return this._finishDeduceEditorPosition(this.selection?.getStartPosition() ?? null, str, -1);
}
if (offset >= this.selectionEnd) {
const str = this.value.substring(this.selectionEnd, offset);
return this._finishDeduceEditorPosition(this.selectionEndPosition, str, 1);
return this._finishDeduceEditorPosition(this.selection?.getEndPosition() ?? null, str, 1);
}
const str1 = this.value.substring(this.selectionStart, offset);
if (str1.indexOf(String.fromCharCode(8230)) === -1) {
return this._finishDeduceEditorPosition(this.selectionStartPosition, str1, 1);
return this._finishDeduceEditorPosition(this.selection?.getStartPosition() ?? null, str1, 1);
}
const str2 = this.value.substring(offset, this.selectionEnd);
return this._finishDeduceEditorPosition(this.selectionEndPosition, str2, -1);
return this._finishDeduceEditorPosition(this.selection?.getEndPosition() ?? null, str2, -1);
}
private _finishDeduceEditorPosition(anchor: Position | null, deltaText: string, signum: number): [Position | null, number, number] {
@@ -224,7 +237,10 @@ export class PagedScreenReaderStrategy {
return new Range(startLineNumber, 1, endLineNumber + 1, 1);
}
public static fromEditorSelection(previousState: TextAreaState, model: ISimpleModel, selection: Range, linesPerPage: number, trimLongText: boolean): TextAreaState {
public static fromEditorSelection(model: ISimpleModel, selection: Range, linesPerPage: number, trimLongText: boolean): TextAreaState {
// Chromium handles very poorly text even of a few thousand chars
// Cut text to avoid stalling the entire UI
const LIMIT_CHARS = 500;
const selectionStartPage = PagedScreenReaderStrategy._getPageOfLine(selection.startLineNumber, linesPerPage);
const selectionStartPageRange = PagedScreenReaderStrategy._getRangeForPage(selectionStartPage, linesPerPage);
@@ -232,13 +248,21 @@ export class PagedScreenReaderStrategy {
const selectionEndPage = PagedScreenReaderStrategy._getPageOfLine(selection.endLineNumber, linesPerPage);
const selectionEndPageRange = PagedScreenReaderStrategy._getRangeForPage(selectionEndPage, linesPerPage);
const pretextRange = selectionStartPageRange.intersectRanges(new Range(1, 1, selection.startLineNumber, selection.startColumn))!;
let pretext = model.getValueInRange(pretextRange, EndOfLinePreference.LF);
let pretextRange = selectionStartPageRange.intersectRanges(new Range(1, 1, selection.startLineNumber, selection.startColumn))!;
if (trimLongText && model.getValueLengthInRange(pretextRange, EndOfLinePreference.LF) > LIMIT_CHARS) {
const pretextStart = model.modifyPosition(pretextRange.getEndPosition(), -LIMIT_CHARS);
pretextRange = Range.fromPositions(pretextStart, pretextRange.getEndPosition());
}
const pretext = model.getValueInRange(pretextRange, EndOfLinePreference.LF);
const lastLine = model.getLineCount();
const lastLineMaxColumn = model.getLineMaxColumn(lastLine);
const posttextRange = selectionEndPageRange.intersectRanges(new Range(selection.endLineNumber, selection.endColumn, lastLine, lastLineMaxColumn))!;
let posttext = model.getValueInRange(posttextRange, EndOfLinePreference.LF);
let posttextRange = selectionEndPageRange.intersectRanges(new Range(selection.endLineNumber, selection.endColumn, lastLine, lastLineMaxColumn))!;
if (trimLongText && model.getValueLengthInRange(posttextRange, EndOfLinePreference.LF) > LIMIT_CHARS) {
const posttextEnd = model.modifyPosition(posttextRange.getStartPosition(), LIMIT_CHARS);
posttextRange = Range.fromPositions(posttextRange.getStartPosition(), posttextEnd);
}
const posttext = model.getValueInRange(posttextRange, EndOfLinePreference.LF);
let text: string;
@@ -254,22 +278,10 @@ export class PagedScreenReaderStrategy {
+ model.getValueInRange(selectionRange2, EndOfLinePreference.LF)
);
}
// Chromium handles very poorly text even of a few thousand chars
// Cut text to avoid stalling the entire UI
if (trimLongText) {
const LIMIT_CHARS = 500;
if (pretext.length > LIMIT_CHARS) {
pretext = pretext.substring(pretext.length - LIMIT_CHARS, pretext.length);
}
if (posttext.length > LIMIT_CHARS) {
posttext = posttext.substring(0, LIMIT_CHARS);
}
if (text.length > 2 * LIMIT_CHARS) {
text = text.substring(0, LIMIT_CHARS) + String.fromCharCode(8230) + text.substring(text.length - LIMIT_CHARS, text.length);
}
if (trimLongText && text.length > 2 * LIMIT_CHARS) {
text = text.substring(0, LIMIT_CHARS) + String.fromCharCode(8230) + text.substring(text.length - LIMIT_CHARS, text.length);
}
return new TextAreaState(pretext + text + posttext, pretext.length, pretext.length + text.length, new Position(selection.startLineNumber, selection.startColumn), new Position(selection.endLineNumber, selection.endColumn));
return new TextAreaState(pretext + text + posttext, pretext.length, pretext.length + text.length, selection, pretextRange.endLineNumber - pretextRange.startLineNumber);
}
}
+3
View File
@@ -267,6 +267,9 @@ export class Range {
* Test if range `a` equals `b`.
*/
public static equalsRange(a: IRange | null, b: IRange | null): boolean {
if (!a && !b) {
return true;
}
return (
!!a &&
!!b &&
+1
View File
@@ -63,6 +63,7 @@ export interface IViewModel extends ICursorSimpleModel {
getAllOverviewRulerDecorations(theme: EditorTheme): OverviewRulerDecorationsGroup[];
getValueInRange(range: Range, eol: EndOfLinePreference): string;
getValueLengthInRange(range: Range, eol: EndOfLinePreference): number;
modifyPosition(position: Position, offset: number): Position;
getInjectedTextAt(viewPosition: Position): InjectedText | null;
@@ -788,6 +788,11 @@ export class ViewModel extends Disposable implements IViewModel {
return this.model.getValueLengthInRange(modelRange, eol);
}
public modifyPosition(position: Position, offset: number): Position {
const modelPosition = this.coordinatesConverter.convertViewPositionToModelPosition(position);
return this.model.modifyPosition(modelPosition, offset);
}
public deduceModelPositionRelativeToViewPosition(viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position {
const modelAnchor = this.coordinatesConverter.convertViewPositionToModelPosition(viewAnchorPosition);
if (this.model.getEOL().length === 2) {
@@ -38,6 +38,11 @@ class SingleLineTestModel implements ISimpleModel {
return this.getValueInRange(range, eol).length;
}
modifyPosition(position: Position, offset: number): Position {
const column = Math.min(this.getLineMaxColumn(position.lineNumber), Math.max(1, position.column + offset));
return new Position(position.lineNumber, column);
}
getModelLineContent(lineNumber: number): string {
return this._line;
}
@@ -106,10 +111,10 @@ function doCreateTest(description: string, inputStr: string, expectedStr: string
mode: null
};
},
getScreenReaderContent: (currentState: TextAreaState): TextAreaState => {
getScreenReaderContent: (): TextAreaState => {
const selection = new Range(1, 1 + cursorOffset, 1, 1 + cursorOffset + cursorLength);
return PagedScreenReaderStrategy.fromEditorSelection(currentState, model, selection, 10, true);
return PagedScreenReaderStrategy.fromEditorSelection(model, selection, 10, true);
},
deduceModelPosition: (viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position => {
return null!;
@@ -46,8 +46,8 @@ suite('TextAreaInput', () => {
getDataToCopy: function (): ClipboardDataToCopy {
throw new Error('Function not implemented.');
},
getScreenReaderContent: function (currentState: TextAreaState): TextAreaState {
return new TextAreaState('', 0, 0, null, null);
getScreenReaderContent: function (): TextAreaState {
return new TextAreaState('', 0, 0, null, undefined);
},
deduceModelPosition: function (viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position {
throw new Error('Function not implemented.');
@@ -6,7 +6,7 @@
import * as assert from 'assert';
import { Disposable } from 'vs/base/common/lifecycle';
import { ITextAreaWrapper, PagedScreenReaderStrategy, TextAreaState } from 'vs/editor/browser/controller/textAreaState';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { createTextModel } from 'vs/editor/test/common/testTextModel';
@@ -64,15 +64,15 @@ function equalsTextAreaState(a: TextAreaState, b: TextAreaState): boolean {
a.value === b.value
&& a.selectionStart === b.selectionStart
&& a.selectionEnd === b.selectionEnd
&& Position.equals(a.selectionStartPosition, b.selectionStartPosition)
&& Position.equals(a.selectionEndPosition, b.selectionEndPosition)
&& Range.equalsRange(a.selection, b.selection)
&& a.newlineCountBeforeSelection === b.newlineCountBeforeSelection
);
}
suite('TextAreaState', () => {
function assertTextAreaState(actual: TextAreaState, value: string, selectionStart: number, selectionEnd: number): void {
const desired = new TextAreaState(value, selectionStart, selectionEnd, null, null);
const desired = new TextAreaState(value, selectionStart, selectionEnd, null, undefined);
assert.ok(equalsTextAreaState(desired, actual), desired.toString() + ' == ' + actual.toString());
}
@@ -81,7 +81,7 @@ suite('TextAreaState', () => {
textArea._value = 'Hello world!';
textArea._selectionStart = 1;
textArea._selectionEnd = 12;
let actual = TextAreaState.readFromTextArea(textArea);
let actual = TextAreaState.readFromTextArea(textArea, null);
assertTextAreaState(actual, 'Hello world!', 1, 12);
assert.strictEqual(actual.value, 'Hello world!');
@@ -99,21 +99,21 @@ suite('TextAreaState', () => {
textArea._selectionStart = 1;
textArea._selectionEnd = 12;
let state = new TextAreaState('Hi world!', 2, 2, null, null);
let state = new TextAreaState('Hi world!', 2, 2, null, undefined);
state.writeToTextArea('test', textArea, false);
assert.strictEqual(textArea._value, 'Hi world!');
assert.strictEqual(textArea._selectionStart, 9);
assert.strictEqual(textArea._selectionEnd, 9);
state = new TextAreaState('Hi world!', 3, 3, null, null);
state = new TextAreaState('Hi world!', 3, 3, null, undefined);
state.writeToTextArea('test', textArea, false);
assert.strictEqual(textArea._value, 'Hi world!');
assert.strictEqual(textArea._selectionStart, 9);
assert.strictEqual(textArea._selectionEnd, 9);
state = new TextAreaState('Hi world!', 0, 2, null, null);
state = new TextAreaState('Hi world!', 0, 2, null, undefined);
state.writeToTextArea('test', textArea, true);
assert.strictEqual(textArea._value, 'Hi world!');
@@ -131,7 +131,7 @@ suite('TextAreaState', () => {
textArea._selectionStart = selectionStart;
textArea._selectionEnd = selectionEnd;
const newState = TextAreaState.readFromTextArea(textArea);
const newState = TextAreaState.readFromTextArea(textArea, null);
const actual = TextAreaState.deduceInput(prevState, newState, couldBeEmojiInput);
assert.deepStrictEqual(actual, {
@@ -155,7 +155,7 @@ suite('TextAreaState', () => {
test('issue #2586: Replacing selected end-of-line with newline locks up the document', () => {
testDeduceInput(
new TextAreaState(']\n', 1, 2, null, null),
new TextAreaState(']\n', 1, 2, null, undefined),
']\n',
2, 2, true,
'\n', 0
@@ -191,7 +191,7 @@ suite('TextAreaState', () => {
test('extractNewText - had the entire line selected', () => {
testDeduceInput(
new TextAreaState('Hello world!', 0, 12, null, null),
new TextAreaState('Hello world!', 0, 12, null, undefined),
'H',
1, 1, true,
'H', 0
@@ -200,7 +200,7 @@ suite('TextAreaState', () => {
test('extractNewText - had previous text 1', () => {
testDeduceInput(
new TextAreaState('Hello world!', 12, 12, null, null),
new TextAreaState('Hello world!', 12, 12, null, undefined),
'Hello world!a',
13, 13, true,
'a', 0
@@ -209,7 +209,7 @@ suite('TextAreaState', () => {
test('extractNewText - had previous text 2', () => {
testDeduceInput(
new TextAreaState('Hello world!', 0, 0, null, null),
new TextAreaState('Hello world!', 0, 0, null, undefined),
'aHello world!',
1, 1, true,
'a', 0
@@ -218,7 +218,7 @@ suite('TextAreaState', () => {
test('extractNewText - had previous text 3', () => {
testDeduceInput(
new TextAreaState('Hello world!', 6, 11, null, null),
new TextAreaState('Hello world!', 6, 11, null, undefined),
'Hello other!',
11, 11, true,
'other', 0
@@ -236,7 +236,7 @@ suite('TextAreaState', () => {
test('extractNewText - isInOverwriteMode', () => {
testDeduceInput(
new TextAreaState('Hello world!', 0, 0, null, null),
new TextAreaState('Hello world!', 0, 0, null, undefined),
'Aello world!',
1, 1, true,
'A', 0
@@ -245,7 +245,7 @@ suite('TextAreaState', () => {
test('extractMacReplacedText - does nothing if there is selection', () => {
testDeduceInput(
new TextAreaState('Hello world!', 5, 5, null, null),
new TextAreaState('Hello world!', 5, 5, null, undefined),
'Hellö world!',
4, 5, true,
'ö', 0
@@ -254,7 +254,7 @@ suite('TextAreaState', () => {
test('extractMacReplacedText - does nothing if there is more than one extra char', () => {
testDeduceInput(
new TextAreaState('Hello world!', 5, 5, null, null),
new TextAreaState('Hello world!', 5, 5, null, undefined),
'Hellöö world!',
5, 5, true,
'öö', 1
@@ -263,7 +263,7 @@ suite('TextAreaState', () => {
test('extractMacReplacedText - does nothing if there is more than one changed char', () => {
testDeduceInput(
new TextAreaState('Hello world!', 5, 5, null, null),
new TextAreaState('Hello world!', 5, 5, null, undefined),
'Helöö world!',
5, 5, true,
'öö', 2
@@ -272,7 +272,7 @@ suite('TextAreaState', () => {
test('extractMacReplacedText', () => {
testDeduceInput(
new TextAreaState('Hello world!', 5, 5, null, null),
new TextAreaState('Hello world!', 5, 5, null, undefined),
'Hellö world!',
5, 5, true,
'ö', 1
@@ -281,7 +281,7 @@ suite('TextAreaState', () => {
test('issue #25101 - First key press ignored', () => {
testDeduceInput(
new TextAreaState('a', 0, 1, null, null),
new TextAreaState('a', 0, 1, null, undefined),
'a',
1, 1, true,
'a', 0
@@ -290,7 +290,7 @@ suite('TextAreaState', () => {
test('issue #16520 - Cmd-d of single character followed by typing same character as has no effect', () => {
testDeduceInput(
new TextAreaState('x x', 0, 1, null, null),
new TextAreaState('x x', 0, 1, null, undefined),
'x x',
1, 1, true,
'x', 0
@@ -308,7 +308,7 @@ suite('TextAreaState', () => {
textArea._selectionStart = selectionStart;
textArea._selectionEnd = selectionEnd;
const newState = TextAreaState.readFromTextArea(textArea);
const newState = TextAreaState.readFromTextArea(textArea, null);
const actual = TextAreaState.deduceAndroidCompositionInput(prevState, newState);
assert.deepStrictEqual(actual, {
@@ -323,11 +323,7 @@ suite('TextAreaState', () => {
test('Android composition input 1', () => {
testDeduceAndroidCompositionInput(
new TextAreaState(
'Microsoft',
4, 4,
null, null
),
new TextAreaState('Microsoft', 4, 4, null, undefined),
'Microsoft',
4, 4,
'', 0, 0, 0,
@@ -336,11 +332,7 @@ suite('TextAreaState', () => {
test('Android composition input 2', () => {
testDeduceAndroidCompositionInput(
new TextAreaState(
'Microsoft',
4, 4,
null, null
),
new TextAreaState('Microsoft', 4, 4, null, undefined),
'Microsoft',
0, 9,
'', 0, 0, 5,
@@ -349,11 +341,7 @@ suite('TextAreaState', () => {
test('Android composition input 3', () => {
testDeduceAndroidCompositionInput(
new TextAreaState(
'Microsoft',
0, 9,
null, null
),
new TextAreaState('Microsoft', 0, 9, null, undefined),
'Microsoft\'s',
11, 11,
'\'s', 0, 0, 0,
@@ -362,11 +350,7 @@ suite('TextAreaState', () => {
test('Android backspace', () => {
testDeduceAndroidCompositionInput(
new TextAreaState(
'undefinedVariable',
2, 2,
null, null
),
new TextAreaState('undefinedVariable', 2, 2, null, undefined),
'udefinedVariable',
1, 1,
'', 1, 0, 0,
@@ -377,7 +361,7 @@ suite('TextAreaState', () => {
function testPagedScreenReaderStrategy(lines: string[], selection: Selection, expected: TextAreaState): void {
const model = createTextModel(lines.join('\n'));
const actual = PagedScreenReaderStrategy.fromEditorSelection(TextAreaState.EMPTY, model, selection, 10, true);
const actual = PagedScreenReaderStrategy.fromEditorSelection(model, selection, 10, true);
assert.ok(equalsTextAreaState(actual, expected));
model.dispose();
}
@@ -388,7 +372,7 @@ suite('TextAreaState', () => {
'Hello world!'
],
new Selection(1, 13, 1, 13),
new TextAreaState('Hello world!', 12, 12, new Position(1, 13), new Position(1, 13))
new TextAreaState('Hello world!', 12, 12, new Range(1, 13, 1, 13), 0)
);
testPagedScreenReaderStrategy(
@@ -396,7 +380,7 @@ suite('TextAreaState', () => {
'Hello world!'
],
new Selection(1, 1, 1, 1),
new TextAreaState('Hello world!', 0, 0, new Position(1, 1), new Position(1, 1))
new TextAreaState('Hello world!', 0, 0, new Range(1, 1, 1, 1), 0)
);
testPagedScreenReaderStrategy(
@@ -404,7 +388,7 @@ suite('TextAreaState', () => {
'Hello world!'
],
new Selection(1, 1, 1, 6),
new TextAreaState('Hello world!', 0, 5, new Position(1, 1), new Position(1, 6))
new TextAreaState('Hello world!', 0, 5, new Range(1, 1, 1, 6), 0)
);
});
@@ -415,7 +399,7 @@ suite('TextAreaState', () => {
'How are you?'
],
new Selection(1, 1, 1, 1),
new TextAreaState('Hello world!\nHow are you?', 0, 0, new Position(1, 1), new Position(1, 1))
new TextAreaState('Hello world!\nHow are you?', 0, 0, new Range(1, 1, 1, 1), 0)
);
testPagedScreenReaderStrategy(
@@ -424,7 +408,7 @@ suite('TextAreaState', () => {
'How are you?'
],
new Selection(2, 1, 2, 1),
new TextAreaState('Hello world!\nHow are you?', 13, 13, new Position(2, 1), new Position(2, 1))
new TextAreaState('Hello world!\nHow are you?', 13, 13, new Range(2, 1, 2, 1), 1)
);
});
@@ -434,7 +418,7 @@ suite('TextAreaState', () => {
'L1\nL2\nL3\nL4\nL5\nL6\nL7\nL8\nL9\nL10\nL11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\nL21'
],
new Selection(1, 1, 1, 1),
new TextAreaState('L1\nL2\nL3\nL4\nL5\nL6\nL7\nL8\nL9\nL10\n', 0, 0, new Position(1, 1), new Position(1, 1))
new TextAreaState('L1\nL2\nL3\nL4\nL5\nL6\nL7\nL8\nL9\nL10\n', 0, 0, new Range(1, 1, 1, 1), 0)
);
testPagedScreenReaderStrategy(
@@ -442,7 +426,7 @@ suite('TextAreaState', () => {
'L1\nL2\nL3\nL4\nL5\nL6\nL7\nL8\nL9\nL10\nL11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\nL21'
],
new Selection(11, 1, 11, 1),
new TextAreaState('L11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\n', 0, 0, new Position(11, 1), new Position(11, 1))
new TextAreaState('L11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\n', 0, 0, new Range(11, 1, 11, 1), 0)
);
testPagedScreenReaderStrategy(
@@ -450,7 +434,7 @@ suite('TextAreaState', () => {
'L1\nL2\nL3\nL4\nL5\nL6\nL7\nL8\nL9\nL10\nL11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\nL21'
],
new Selection(12, 1, 12, 1),
new TextAreaState('L11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\n', 4, 4, new Position(12, 1), new Position(12, 1))
new TextAreaState('L11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\n', 4, 4, new Range(12, 1, 12, 1), 1)
);
testPagedScreenReaderStrategy(
@@ -458,7 +442,7 @@ suite('TextAreaState', () => {
'L1\nL2\nL3\nL4\nL5\nL6\nL7\nL8\nL9\nL10\nL11\nL12\nL13\nL14\nL15\nL16\nL17\nL18\nL19\nL20\nL21'
],
new Selection(21, 1, 21, 1),
new TextAreaState('L21', 0, 0, new Position(21, 1), new Position(21, 1))
new TextAreaState('L21', 0, 0, new Range(21, 1, 21, 1), 0)
);
});