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 | 16x 16x 16x 16x 16x 26x 26x 26x 26x 26x 26x 15x 15x 15x 15x 15x 25x 25x 5x 5x 23x 23x 3x 3x 5x 2x 2x 2x 2x 2x 1x 1x 1x 1x 1x 2x 1x 2x 2x 2x 2x 2x 2x 2x 1x 2x 5x 15x 15x | 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) { Eif (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) { Eif (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); } } |