Skip to content

Commit 937bb49

Browse files
authored
using correct selection direction (microsoft#259042)
1 parent ccd083f commit 937bb49

File tree

4 files changed

+56
-28
lines changed

4 files changed

+56
-28
lines changed

src/vs/editor/browser/controller/editContext/native/screenReaderContentRich.ts

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -235,14 +235,13 @@ export class RichScreenReaderContent extends Disposable implements IScreenReader
235235
if (!startRenderedLine || !endRenderedLine) {
236236
return;
237237
}
238-
const range = new globalThis.Range();
239238
const viewModel = context.viewModel;
240239
const model = viewModel.model;
241240
const coordinatesConverter = viewModel.coordinatesConverter;
242-
const startRange = new Range(startLineNumber, 1, startLineNumber, viewSelection.startColumn);
241+
const startRange = new Range(startLineNumber, 1, startLineNumber, viewSelection.selectionStartColumn);
243242
const modelStartRange = coordinatesConverter.convertViewRangeToModelRange(startRange);
244243
const characterCountForStart = model.getCharacterCountInRange(modelStartRange);
245-
const endRange = new Range(endLineNumber, 1, endLineNumber, viewSelection.endColumn);
244+
const endRange = new Range(endLineNumber, 1, endLineNumber, viewSelection.positionColumn);
246245
const modelEndRange = coordinatesConverter.convertViewRangeToModelRange(endRange);
247246
const characterCountForEnd = model.getCharacterCountInRange(modelEndRange);
248247
const startDomPosition = startRenderedLine.characterMapping.getDomPosition(characterCountForStart);
@@ -256,10 +255,13 @@ export class RichScreenReaderContent extends Disposable implements IScreenReader
256255
if (!startNode.firstChild || !endNode.firstChild) {
257256
return;
258257
}
259-
range.setStart(startNode.firstChild, viewSelection.startColumn === 1 ? 0 : startDomPosition.charIndex + 1);
260-
range.setEnd(endNode.firstChild, viewSelection.endColumn === 1 ? 0 : endDomPosition.charIndex + 1);
261258
this._setIgnoreSelectionChangeTime('setRange');
262-
activeDocumentSelection.setBaseAndExtent(range.startContainer, range.startOffset, range.endContainer, range.endOffset);
259+
activeDocumentSelection.setBaseAndExtent(
260+
startNode.firstChild,
261+
viewSelection.startColumn === 1 ? 0 : startDomPosition.charIndex + 1,
262+
endNode.firstChild,
263+
viewSelection.endColumn === 1 ? 0 : endDomPosition.charIndex + 1
264+
);
263265
}
264266

265267
private _getScreenReaderContentLineIntervals(primarySelection: Selection): RichScreenReaderState {
@@ -305,12 +307,21 @@ export class RichScreenReaderContent extends Disposable implements IScreenReader
305307
}
306308
const startColumn = getColumnOfNodeOffset(startMapping, startSpanElement, range.startOffset);
307309
const endColumn = getColumnOfNodeOffset(endMapping, endSpanElement, range.endOffset);
308-
return new Selection(
309-
startLineNumber,
310-
startColumn,
311-
endLineNumber,
312-
endColumn
313-
);
310+
if (selection.direction === 'forward') {
311+
return new Selection(
312+
startLineNumber,
313+
startColumn,
314+
endLineNumber,
315+
endColumn
316+
);
317+
} else {
318+
return new Selection(
319+
endLineNumber,
320+
endColumn,
321+
startLineNumber,
322+
startColumn
323+
);
324+
}
314325
}
315326
}
316327

src/vs/editor/browser/controller/editContext/native/screenReaderContentSimple.ts

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,16 @@ export class SimpleScreenReaderContent extends Disposable implements IScreenRead
5454
if (!selection) {
5555
return;
5656
}
57-
const range = this._getScreenReaderRange(this._state.selectionStart, this._state.selectionEnd);
58-
if (!range) {
57+
const data = this._getScreenReaderRange(this._state.selectionStart, this._state.selectionEnd);
58+
if (!data) {
5959
return;
6060
}
6161
this._setIgnoreSelectionChangeTime('setRange');
6262
selection.setBaseAndExtent(
63-
range.startContainer,
64-
range.startOffset,
65-
range.endContainer,
66-
range.endOffset
63+
data.anchorNode,
64+
data.anchorOffset,
65+
data.focusNode,
66+
data.focusOffset
6767
);
6868
} else {
6969
this._state = undefined;
@@ -153,7 +153,7 @@ export class SimpleScreenReaderContent extends Disposable implements IScreenRead
153153
return;
154154
}
155155

156-
this._viewController.setSelection(this._getEditorSelectionFromDomRange(this._context, this._state, range));
156+
this._viewController.setSelection(this._getEditorSelectionFromDomRange(this._context, this._state, selection.direction, range));
157157
});
158158
}
159159

@@ -173,18 +173,23 @@ export class SimpleScreenReaderContent extends Disposable implements IScreenRead
173173
return state;
174174
}
175175

176-
private _getScreenReaderRange(selectionOffsetStart: number, selectionOffsetEnd: number): globalThis.Range | undefined {
176+
private _getScreenReaderRange(selectionOffsetStart: number, selectionOffsetEnd: number): { anchorNode: Node; anchorOffset: number; focusNode: Node; focusOffset: number } | undefined {
177177
const textContent = this._domNode.domNode.firstChild;
178178
if (!textContent) {
179179
return;
180180
}
181181
const range = new globalThis.Range();
182182
range.setStart(textContent, selectionOffsetStart);
183183
range.setEnd(textContent, selectionOffsetEnd);
184-
return range;
184+
return {
185+
anchorNode: textContent,
186+
anchorOffset: selectionOffsetStart,
187+
focusNode: textContent,
188+
focusOffset: selectionOffsetEnd
189+
};
185190
}
186191

187-
private _getEditorSelectionFromDomRange(context: ViewContext, state: ISimpleScreenReaderContentState, range: globalThis.Range): Selection {
192+
private _getEditorSelectionFromDomRange(context: ViewContext, state: ISimpleScreenReaderContentState, direction: string, range: globalThis.Range): Selection {
188193
const viewModel = context.viewModel;
189194
const model = viewModel.model;
190195
const coordinatesConverter = viewModel.coordinatesConverter;
@@ -203,6 +208,8 @@ export class SimpleScreenReaderContent extends Disposable implements IScreenRead
203208
}
204209
const positionOfSelectionStart = model.getPositionAt(offsetOfSelectionStart);
205210
const positionOfSelectionEnd = model.getPositionAt(offsetOfSelectionEnd);
206-
return Selection.fromPositions(positionOfSelectionStart, positionOfSelectionEnd);
211+
const selectionStart = direction === 'forward' ? positionOfSelectionStart : positionOfSelectionEnd;
212+
const selectionEnd = direction === 'forward' ? positionOfSelectionEnd : positionOfSelectionStart;
213+
return Selection.fromPositions(selectionStart, selectionEnd);
207214
}
208215
}

src/vs/editor/browser/controller/editContext/screenReaderUtils.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import { EndOfLinePreference } from '../../../common/model.js';
77
import { Position } from '../../../common/core/position.js';
88
import { Range } from '../../../common/core/range.js';
9-
import { Selection } from '../../../common/core/selection.js';
9+
import { Selection, SelectionDirection } from '../../../common/core/selection.js';
1010
import { EditorOption, IComputedEditorOptions } from '../../../common/config/editorOptions.js';
1111
import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js';
1212
import { AccessibilitySupport } from '../../../../platform/accessibility/common/accessibility.js';
@@ -48,7 +48,7 @@ export class SimplePagedScreenReaderStrategy implements IPagedScreenReaderStrate
4848
return new Range(startLineNumber, 1, endLineNumber + 1, 1);
4949
}
5050

51-
public fromEditorSelection(model: ISimpleModel, selection: Range, linesPerPage: number, trimLongText: boolean): ISimpleScreenReaderContentState {
51+
public fromEditorSelection(model: ISimpleModel, selection: Selection, linesPerPage: number, trimLongText: boolean): ISimpleScreenReaderContentState {
5252
// Chromium handles very poorly text even of a few thousand chars
5353
// Cut text to avoid stalling the entire UI
5454
const LIMIT_CHARS = 500;
@@ -93,11 +93,20 @@ export class SimplePagedScreenReaderStrategy implements IPagedScreenReaderStrate
9393
text = text.substring(0, LIMIT_CHARS) + String.fromCharCode(8230) + text.substring(text.length - LIMIT_CHARS, text.length);
9494
}
9595

96+
let selectionStart: number;
97+
let selectionEnd: number;
98+
if (selection.getDirection() === SelectionDirection.LTR) {
99+
selectionStart = pretext.length;
100+
selectionEnd = pretext.length + text.length;
101+
} else {
102+
selectionEnd = pretext.length;
103+
selectionStart = pretext.length + text.length;
104+
}
96105
return {
97106
value: pretext + text + posttext,
98107
selection: selection,
99-
selectionStart: pretext.length,
100-
selectionEnd: pretext.length + text.length,
108+
selectionStart,
109+
selectionEnd,
101110
startPositionWithinEditor: pretextRange.getStartPosition(),
102111
newlineCountBeforeSelection: pretextRange.endLineNumber - pretextRange.startLineNumber,
103112
};

src/vs/editor/test/browser/controller/imeTester.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { SimplePagedScreenReaderStrategy } from '../../../browser/controller/edi
1616
import { ISimpleModel } from '../../../common/viewModel/screenReaderSimpleModel.js';
1717
import { TextAreaState } from '../../../browser/controller/editContext/textArea/textAreaEditContextState.js';
1818
import { ITextAreaInputHost, TextAreaInput, TextAreaWrapper } from '../../../browser/controller/editContext/textArea/textAreaEditContextInput.js';
19+
import { Selection } from '../../../common/core/selection.js';
1920

2021
// To run this test, open imeTester.html
2122

@@ -117,7 +118,7 @@ function doCreateTest(description: string, inputStr: string, expectedStr: string
117118
};
118119
},
119120
getScreenReaderContent: (): TextAreaState => {
120-
const selection = new Range(1, 1 + cursorOffset, 1, 1 + cursorOffset + cursorLength);
121+
const selection = new Selection(1, 1 + cursorOffset, 1, 1 + cursorOffset + cursorLength);
121122

122123
const screenReaderContentState = screenReaderStrategy.fromEditorSelection(model, selection, 10, true);
123124
return TextAreaState.fromScreenReaderContentState(screenReaderContentState);

0 commit comments

Comments
 (0)