Tom Adler’s blog

mx310, 6 buttons в линухе

— что в постновогодние каникулы делал?

— настроил мышь и клаву…

дисклеймер: пишу на самом деле больше для себя, чтоб не забыть : )

есть у меня любимая мыша Logitech mx310. Удобная, с 6 кнопками. Очень удобно на одну из них вешать Backspace, он же забой (забей : ), а на другую — F5. Хождение по интернету тогда становится буквально волшебным, а забой вообще часто пригождается.

по приходу © на линух я сравнительно быстро повесил забой на привычное место. А вот с f5 не задалось. И так, и этак пристраивался — не выходит каменный цветок. В конце концов надежно установил, что с точки зрения линукса у меня на мыше две левые кнопки. А зачем мне столько — то ему неведомо.

к счастью, упертость иногда приносит свои плоды, и обходной маневр был найден. Всего-то и нужно, что другой драйвер, рутовые права и немного шаманства.

/etc/X11/xorg.conf

Section "InputDevice"
Identifier "Configured Mouse"
Driver "evdev"
Option "CorePointer"
Option "Device" "/dev/input/by-id/usb-Logitech_USB-PS.2_Optical_Mouse-event-mouse"
EndSection

/etc/X11/imwheel/imwheelrc

".*"
None, Up, BackSpace
None, Down, F5

и в автозапуск

imwheel -k -b "68"

якоря и window.location = url

полезняшка, которая может сэкономить время поиска трудновоспроизводимого бага:

якоря в адресе — зло для яваскрипта. Вернее, они, конечно, хороши для многих вещей, но если в адресе есть якорь, то window.location.reload() не сделает того, чего вы ожидаете, а редирект браузера на ту же страницу (после логина, например) не сработает. Вам поможет .replace(/#.*$/, '')

кстати, писать document.location = url — глупо по вполне очевидной причине : )

gzip, статика и graceful degradation*

Придумал мазу. Если что, она из области «создать себе проблему и героически её забороть».

Кратко:

для приближения к нирване достаточно рядом с js|css контентом класть его .gz-копии и этот .htaccess

RewriteEngine on
RewriteRule ^(.*\.gz)$ $1 [L]
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteRule ^(.*)$ $1.gz
AddEncoding x-gzip .gz
AddType application/x-javascript .js
AddType text/css .css

Длинно:

Если вебмастер хочет экономить трафик свой и клиента, обычно он включает в своём апаче сжатие. То есть, берет mod_deflate или mod_gzip, и они сами всё за него делают: смотрят, умеет ли клиент gzip, если умеет, то сжимают данные и подставляют нужные заголовки. Все довольны, все смеются.

Но у такого подхода есть парочка минусов. Первый: сжатие производится динамически. То есть, каждый раз, когда сервер отдает, например, prototype.js, сжималка заново выполняет свою работу. Не то, чтобы это чрезмерно грузит сервер, но неаккуратненько как-то ©

Второй минус заключается в том, что в mod_deflate нельзя отключить режим передачи chunked (disclaimer: точнее, я пока что не нашел, как это сделать). Mod_gzip это как будто умеет, но он не так проверен временем. Чем грозен режим chunked? Да особенно ничем, кроме того, что всенародно нелюбимый браузер™ не всегда его понимает. Если протокол https, данные сжаты, а режим передачи chunked, IE может попытаться использовать файл, не разжимая его.

Первый вариант, который приходит в голову для решения проблемы — при отдаче грамотно сжимать данные скриптом так, чтобы аццкий режим не включался. Собственно, первые полчаса я именно так и бился. Однако, каюсь, ниасилил. При запросе самого файла он прекрасно открывается, но если он подключен к документу — фиг! Даже в опере. Скорее всего, я где-то неоднократно слажал, но это неважно, потому что я придумал способ получше.

Натолкнула меня на идею вот эта статейка. Именно там я увидел фразу «Here since the Javascript is static, which is true for most AJAX applications these days, we can pre-compress which will reduce latency and CPU overhead.» То есть, мы радостно отдаём браузеру уже готовый .gz файл и идём готовить что-то изысканное из двух зайцев.

Но как быть с теми клиентами, которые не понимают сжатия? Естественно, для них нужен свой, несжатый файл, который нужно отдавать убогим. Только непонятно, когда который из двух файлов подключать. Смотреть в шаблоне на заголовки HTTP? Не, так мешать уровень протокола и уровень отображения я не согласен : ) Разбираться с заголовками — это работа скорее апача. Конкретнее, mod_rewrite. Он, правда, не слышал о HTTP_ACCEPT_ENCODING, зато спокойно скушает такую конструкцию: %{HTTP:Accept-Encoding}. Немного мучений, и имеем на выходе такую конструкцию для .htaccess:

RewriteEngine on
RewriteRule ^(.*\.gz)$ $1 [L]
RewriteCond %{HTTP:Accept-Encoding} gzip
RewriteRule ^(.*)$ $1.gz

Человеческим языком говоря: при запросе не .gz файла приписывать к имени запрашиваемого .gz, если клиент понимает gzip.

Тут встает другая проблема: апач честно говорит клиенту, что отдает не яваскрипт и даже не css, а гзип. IE, конечно, заголовки Content-Type игнорирует, но это не повод расслабляться. Кроме того, откуда браузеру знать, что отправленные ему байты перед употреблением нужно разжать? («Сжатый файл» и «сжато при передаче» — разные вещи все-таки.) Тут нас выручит mod_mime:

AddEncoding x-gzip .gz
AddType application/x-javascript .js
AddType text/css .css

Небольшое пояснение: если вы не знали, в представлении апача у файла может быть несколько расширений. Например, у prototype.js.gz их два: js и gz. Этим мы и пользуемся: если у файла есть расширение gz, то отправляем заголовок Content-Encoding: gzip. А две другие строчки нужны для того, чтобы перекрыть апачевское умолчание «отдавать для .gz файлов Content-Type: application/x-gzip». Мы укажем верный Content-Type.

Естественно, удобнее всего будет, если вы автоматизируете процесс создания .gz-копий. Заодно очень полезно склеивать все однотипные файлы в один (значительно уменьшается число запросов к серверу), и вырезать оттуда всё лишнее: пробелы, комментарии и т.п. Это несложно, jsmin и Vitamin вам в руки.

В результате всех мучений имеем в пять раз меньший объём css+js.

*graceful degradation ~ нормальная работа в том случае, если клиент туп; например, не видит он картинок, но сайтом пользоваться может, или нет у него яваскрипта, но это ему почти не мешает.

,

Cross-domain XMLHttpRequest

собственно, сабж

суть: ифрейм на другой домен, данные передаются через document::postMessage(), который работает, как известно, не везде : )

xml tree (opera user js)

хотя штука узкоспецифическая, не могу не поделиться : )

знаете, когда в ie или ff открывается голый xml, браузеры отрисовывают его таким клевым деревом, которое можно удобно сворачивать-разворачивать для анализа. Опера этого не умеет. По крайней мере, от рождения. Но один умелец нарисовал для неё user javascript, который ровно этим и занимается. Брать его можно здесь

обсуждение в жж