in packages/selector/src/text/code-point-seeker.ts [123:188]
private _readOrSeekTo(
read: true,
target: number,
roundUp?: boolean,
): string[];
private _readOrSeekTo(read: false, target: number, roundUp?: boolean): void;
private _readOrSeekTo(
read: boolean,
target: number,
roundUp = false,
): string[] | void {
let result: string[] = [];
if (this.position < target) {
let unpairedSurrogate = '';
let characters: string[] = [];
while (this.position < target) {
let s = unpairedSurrogate + this.raw.read(1, true);
if (endsWithinCharacter(s)) {
unpairedSurrogate = s.slice(-1); // consider this half-character part of the next string.
s = s.slice(0, -1);
} else {
unpairedSurrogate = '';
}
characters = [...s];
this.position += characters.length;
if (read) result = result.concat(characters);
}
if (unpairedSurrogate) this.raw.seekBy(-1); // align with the last complete character.
if (!roundUp && this.position > target) {
const overshootInCodePoints = this.position - target;
const overshootInCodeUnits = characters
.slice(-overshootInCodePoints)
.join('').length;
this.position -= overshootInCodePoints;
this.raw.seekBy(-overshootInCodeUnits);
}
} else {
// Nearly equal to the if-block, but moving backward in the text.
let unpairedSurrogate = '';
let characters: string[] = [];
while (this.position > target) {
let s = this.raw.read(-1, true) + unpairedSurrogate;
if (startsWithinCharacter(s)) {
unpairedSurrogate = s[0];
s = s.slice(1);
} else {
unpairedSurrogate = '';
}
characters = [...s];
this.position -= characters.length;
if (read) result = characters.concat(result);
}
if (unpairedSurrogate) this.raw.seekBy(1);
if (!roundUp && this.position < target) {
const overshootInCodePoints = target - this.position;
const overshootInCodeUnits = characters
.slice(0, overshootInCodePoints)
.join('').length;
this.position += overshootInCodePoints;
this.raw.seekBy(overshootInCodeUnits);
}
}
if (read) return result;
}