Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | 22x 22x 22x 22x 22x 31x 31x 31x 31x 31x 31x 17x 17x 17x 17x 17x 31x 31x 6x 6x 27x 27x 3x 3x 6x 2x 2x 2x 2x 2x 3x 1x 1x 1x 1x 2x 3x 5x 3x 3x 3x 3x 3x 3x 1x 3x 6x 19x 19x | export class SelectionText {
elm: HTMLTextAreaElement;
start: number;
end: number;
value: string;
constructor(elm: HTMLTextAreaElement) {
const { selectionStart, selectionEnd } = elm;
this.elm = elm;
this.start = selectionStart;
this.end = selectionEnd;
this.value = this.elm.value;
}
position(start?: number, end?: number) {
const { selectionStart, selectionEnd } = this.elm;
this.start = typeof start === 'number' && !isNaN(start) ? start : selectionStart;
this.end = typeof end === 'number' && !isNaN(end) ? end : selectionEnd;
this.elm.selectionStart = this.start;
this.elm.selectionEnd = this.end;
return this;
}
insertText(text: string) {
// Most of the used APIs only work with the field selected
this.elm.focus();
this.elm.setRangeText(text);
this.value = this.elm.value;
this.position();
return this;
}
getSelectedValue(start?: number, end?: number) {
const { selectionStart, selectionEnd } = this.elm;
return this.value.slice(
typeof start === 'number' && !isNaN(start) ? start : selectionStart,
typeof end === 'number' && !isNaN(end) ? start : selectionEnd,
);
}
getLineStartNumber() {
let start = this.start;
while (start > 0) {
start--;
if (this.value.charAt(start) === '\n') {
start++;
break;
}
}
return start;
}
/** Indent on new lines */
getIndentText() {
const start = this.getLineStartNumber();
const str = this.getSelectedValue(start);
let indent = '';
str.replace(/(^(\s)+)/, (str, old) => (indent = old));
return indent;
}
lineStarInstert(text: string) {
if (text) {
const oldStart = this.start;
const start = this.getLineStartNumber();
const str = this.getSelectedValue(start);
this.position(start, this.end)
.insertText(
str
.split('\n')
.map((txt) => text + txt)
.join('\n'),
)
.position(oldStart + text.length, this.end);
}
return this;
}
lineStarRemove(text: string) {
if (text) {
const oldStart = this.start;
const start = this.getLineStartNumber();
const str = this.getSelectedValue(start);
const reg = new RegExp(`^${text}`, 'g');
let newStart = oldStart - text.length;
if (!reg.test(str)) {
newStart = oldStart;
}
this.position(start, this.end)
.insertText(
str
.split('\n')
.map((txt) => txt.replace(reg, ''))
.join('\n'),
)
.position(newStart, this.end);
}
}
/** Notify any possible listeners of the change */
notifyChange() {
const event = new Event('input', { bubbles: true, cancelable: false });
this.elm.dispatchEvent(event);
}
}
|