Textarea и табуляции

Наверняка многим из вас часто приходится редактировать HTML-документы и PHP-скрипты из различных веб-админок. В чем-то это возможно даже удобнее. Например не надо лезть по FTP чтобы подправить шаблон свего WordPress’а и так далее.

Но любая веб-форма ограничена возможностями браузера, хоткеями и тому подобным. С одной такой проблемой мы сейчас и попробуем справиться.

Первая вещь, которая меня сильно доставала – невозможность вставить в textarea обыкновенную табуляцию, без которой невозможно нормально «оформить» любой код. Что-ж, исправляем:

var tab = "    ";

function checkTab(evt) {
    var t = evt.target;
    var ss = t.selectionStart;
    var se = t.selectionEnd;

    // Tab key - insert tab expansion
    if (evt.keyCode == 9) {
        evt.preventDefault();
        // Special case of multi line selection
        if (ss != se && t.value.slice(ss,se).indexOf("\n") != -1) {
            // In case selection was not of entire lines
            // (e.g. selection begins in the middle of a line)
            // we ought to tab at the beginning as well as
            // at the start of every following line.
            var pre = t.value.slice(0,ss);
            var sel = t.value.slice(ss,se).replace(/\n/g,"\n"+tab);
            var post = t.value.slice(se,t.value.length);
            t.value = pre.concat(tab).concat(sel).concat(post);
            t.selectionStart = ss + tab.length;
            t.selectionEnd = se + tab.length;
        }
        // "Normal" case (no selection or selection on one line only)
        else {
            t.value = t.value.slice (0,ss).concat (tab).concat (t.value.slice (ss,t.value.length));
            if (ss == se) {
                t.selectionStart = t.selectionEnd = ss + tab.length;
            }
            else {
                t.selectionStart = ss + tab.length;
                t.selectionEnd = se + tab.length;
            }
        }
    }

    // Backspace key - delete preceding tab expansion, if exists
   else if (evt.keyCode==8 && t.value.slice(ss - 4,ss) == tab) {
        evt.preventDefault();
        t.value = t.value.slice(0,ss - 4).concat(t.value.slice(ss,t.value.length));
        t.selectionStart = t.selectionEnd = ss - tab.length;
    }

    // Delete key - delete following tab expansion, if exists
    else if (evt.keyCode==46 && t.value.slice(se,se + 4) == tab) {
        evt.preventDefault();
        t.value = t.value.slice(0,ss).concat(t.value.slice(ss + 4,t.value.length));
        t.selectionStart = t.selectionEnd = ss;
    }

    // Left/right arrow keys - move across the tab in one go
    else if (evt.keyCode == 37 && t.value.slice(ss - 4,ss) == tab) {
        evt.preventDefault();
        t.selectionStart = t.selectionEnd = ss - 4;
    }
    else if (evt.keyCode == 39 && t.value.slice(ss,ss + 4) == tab) {
        evt.preventDefault();
        t.selectionStart = t.selectionEnd = ss + 4;
    }
}

Остается только добавить onkeypress=»checkTab(event);» к элементу textarea и проблема решена.

Неправда-ли великоват код для такой маленькой проблемы? Но искусство требует жертв. И больших. Во первых если вы привыкли использовать кнопку Tab для переключения между элементами форм, то придется выбирать. Во-вторых код не работает в IE, так что настоятельно советую пересаживаться на Firefox. И наконец это просто дополнительный траф.

Следовательно… решайте сами. А в следующий раз мы поговорим о перехвате моего любимого хоткея Ctrl+S

Продолжение следует…

Запись опубликована в рубрике Микро-хаки. Добавьте в закладки постоянную ссылку.

7 комментариев: Textarea и табуляции

  1. Лёха zloy и красивый говорит:

    Как я понял он «правильную» для скриптов табуляцию делает? В 4 пробела?

  2. kolo говорит:

    Да, но по ощущениям нормальная табуляция. Если надо, то можно приделать server-side замену 4 пробелов на \t.

  3. Sergey 'drgr' Korolev говорит:

    >Но любая веб-форма ограничена возможностями браузера,
    >хоткеями и тому подобным.
    Пиздёж! Пиздёж и провокация! Нормальные браузеры умеют перенаправлять ввод в любимый текстовый редакторъ (будь то имакс, вим или нано какой) и текст ловить! Ныне же говорю это, невозбранно набрав сей текст в кастумизируемом редакторе вим (со спелчекером и подсветкой кода, генерацией хтмл для подсвеченго кода), что вызвал православный браузёр w3mmee (кстати, твой сцайт в нём смотрится не очень приятно, т.к. навигации на целый экран получается, а текст где-то ниже только).

  4. kolo говорит:

    Покажи мне браузер под винду, который умеет перенаправлять textarea в редактор и ловить оттуда.

    Что касается внешнего вида – хз. В ФФ и ИЕ под виндой все намано.

  5. Sergey 'drgr' Korolev говорит:

    On which platforms does w3m work?
    It runs on various versions of Unix, since version 990226 on OS/2 and since version 990303 also on MS-Windows with Cygwin32.

  6. kolo говорит:

    Cygwin32? Иннах! Речь идет о нэйтивных виндовских браузерах, а не о всяком изврате.

    Тыб еще ВМварю предложил, тоже способ.

  7. Sergey 'drgr' Korolev говорит:

    Цыгвин – не эмулятор и не виртуальная машина. Там всё довольно нативно.

    (что-то я по привычке ответил сначала на нотификаторное письмо)