pure_JS_tab_editor
HTML
<textarea
rows="16"
cols="132"
spellcheck="false"
tabindex="1">This is a normal textarea input where tab is not handled.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit
amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
deserunt mollit anim id est laborum.</textarea>
<br>
<br>
<textarea
rows="16"
cols="132"
tabindex="2"
spellcheck="false"
onkeydown="tab_editor(this);">This is a textarea input using tab_editor.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu
fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit
amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore
et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint...
CSS
textarea {
tab-size: 4;
}
JavaScript
// Found this:
// https://stackoverflow.com/questions/6637341/use-tab-to-indent-in-textarea
// ... then this:
// https://jsfiddle.net/2wkrhxLt/8/
// ... then this:
// https://extendsclass.com/typescript-to-javascript.html
// Now works with more than one textarea, and fully preserves the undo
// stack. Behaviour closely matches common text editors like Pluma:
// - obeys computed tab-size style attribute
// - inserts when Tab key used without selection
// - can be configured to insert spaces instead of tabs
// - obeys tab positions i.e. modulo tab-size
// - block indenting
// - outdents with SHIFT-Tab key (with or without selection)
// - auto-indents
// - Home/End bouncing
// - preserves selection/cursor
// - scrolls to cursor or selection start
// Begin enabled.
var tab_editor_enabled = true;
function tab_editor(target, use_spaces)
{
// Abort if other modifier keys are pressed.
if (event.ctrlKey || event.altKey)
{ return; }
// Preserve original selection points.
original_start = target.selectionStart;
original_end = target.selectionEnd;
// Prepare.
selection_start = original_start;
selection_end = original_end;
selection = (selection_start != selection_end);
text = target.value;
tab_sz = window.getComputedStyle(target).tabSize;
next_enabled_state = true;
// Key handler.
switch (event.key)
{
// Esc restores default Tab functionality i.e. move to next field.
// Acts as a toggle so an even-number of ESC recaptures the Tab key.
case 'Escape':
event.preventDefault();
tab_editor_enabled = !tab_editor_enabled;
next_enabled_state = false;
break;
// Shift by itself preserves enabled state so that a prior Esc also
// restores default SHIFT-Tab functionality i.e. move to previous field.
case 'Shift':
next_enabled_state = tab_editor_enabled;
break;
// Auto-indent.
case 'Enter':
// Only without selection.
if...