Малоконтрастный текст (например, светло-серый на белом) плохо читается, как, впрочем, и белый на светло-сером или вовсе голубом. В борьбу за право читать с комфортом даже поисковые системы вступили — насколько помню, и Google, и Bing (про Яндекс не уверен, но возможно) учитывают доступность сайтов при поиске — сайты с хорошей доступностью (в смысле accessibility как возможность воспринять) занимают в нём позиции ближе к началу. Аналогичная ситуация и с мобильной доступностью — вес сайта, скорость загрузки и его отображение на телефонах тоже важны.
Есть разные инструменты для подбора хороших цветов и некоторые совсем рядом — в отладчике браузера — в случае Хрома на Линуксе и Windows он открывается клавишей F12. Отладчик Google Chrome показывает предупреждение, если в паре цветов контраст недостаточен и позволяет исправить цвет текста для соответствия уровням AA и AAA (см. стандарты WCAG 2.0 или ГОСТ Р 52872-2019). Но оно не может подобрать допустимый цвет, когда фон светлый, а текст белый — предлагает лишь поменять белый на точно такой же цвет, не трогая фон. Выход — поменять цвета местами — тогда подбор будет доступен.
Время от времени помогаю знакомым старта́перам в части, относящейся к вебу. В процессе обнаруживаю странное: есть сайты, которыми не сильно можно порулить, даже если и хочется: хостинг-провайдер предоставляет лишь возможность править апачный конфигурационный файл .htaccess. Всё бы ничего, но между файлами и посетителем сайта не только Apache — там ещё и Nginx, чья конфигурация вообще недоступна.
Сейчас в 2023 году редко какой сайт не использует HTTPS (этот — один из них, но сейчас не о нём речь). Если сайт сделан на какой-нибудь CMS, там вполне может существовать возможность указать в настройках основной адрес сайта и включить перенаправление на него — так можно перенаправляться на использование HTTPS и в WordPress, и в Open Journal Systems.
Но что делать, если сайт — статичный? Вроде бы, можно обойтись средствами самого́ Апача, а точнее, его модуля mod_rewrite — напишем в .htaccess:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>
Этот код включает механизм перенаправлений, проверяет, используется ли HTTPS и если нет — перенаправляет посетителя. Только в нашем случае условие RewriteCond всегда истинно, что вызывает циклические перенаправления. Причина — Apache в конкретном случае работает всегда по HTTP, поэтому значение переменной HTTPS — всегда off. С другими переменными аналогично — например, SERVER_PORT всегда равен 80.
В случае, когда есть доступ к настройкам Nginx, проблем нет — всё настраивается там. Но если нет, приходится искать другие переменные, которые однозначно покажут, как именно посетитель обращается к сайту. Nginx, передавая запрос Апачу, добавляет в него поля, чьи имена начинаются с X-Forwarded — среди них есть и X-Forwarded-Proto, где хранится запрашиваемый посетителем протокол — http или https. В итоге работоспособным оказался такой код:
Может возникнуть вопрос — нельзя ли в условии вместо !https написать более короткое http? Оказалось, что нет — сама по себе строка без знака равенства не проверяется на совпадение, а сопоставляется с образцом, то есть, происходит pattern matching. А такому условию удовлетворяли бы оба рассмотренных значения и условие всегда оказывалось бы истинным, что снова бы вызвало циклические перенаправления.
Open Journal Systems 3 вышла уже шесть лет назад — в 2016 году, но за всё это время русское меню, отображаемое администратору в шапке страниц в теме оформления, включенной по умолчанию (Manuscript), слишком узкое:
Когда пулл-реквест будет принят и это изменение появится в новых версиях OJS, пока не знаю, но кому не терпится, может добавить собственное стилевое правило:
Переводы для темы оформления Manuscript лежат в plugins/themes/default/locale — можно найти слово «Администрирование» на разных языках и сравнить ширину:
grep -R 'msgid "navigation.admin"' -A 1 \
| sort \
| perl -nle 'print qq{<li title="$1">$2</li>} if m{^(.+)/.*msgstr "(.*)"}'
Ширина голубой части — 10em
Оказывается русское слово — самое длинное. И самое широкое, потому что буква и шире, чем i.
Метод console.log достаточно популярен у пишущих на JavaScript — он позволяет выводить отладочную информацию, справляясь как со скалярными данными, так и с объектами.
Недавно выяснил, что иногда console.log ведёт себя подобно функции printf из си-подобных языков: первый свой аргумент воспринимает как описание формата, где ищет начинающиеся с процента последовательности, а выводимые по описанному формату данные начинаются со второго аргумента. Так, например,
console.log('%d', 77/64)
выведет целое число 1, а
console.log('%f', 77/64)
выдаст 1.203125, что получилось бы и без '%f'. При этом бо́льшая часть знакомых по Си или Перлу форматов вообще не работает — встретив такое, console.log посчитает первый аргумент обычной строкой, которую надо вывести — так
console.log('%x', 48879)
выведет %x 48879 вместо ожидаемого слова beef.
Но зато у console.log нашёлся формат %c, позволяющий применить к выводимому тексту стили, заданные вторым параметром — так можно раскрашивать вывод
Если что-то в интернете можно посмотреть, значит, это можно и скачать, хоть это и не всегда удобно.
Вот, например, челябинский провайдер «Интерсвязь» всюду развесил камеры видеонаблюдения да видеодомофоны и даёт возможность своим абонентам смотреть не только то, что происходит прямо сейчас, но и архив за последнюю неделю. При этом архивную запись с общедоступной камеры скачать можно — на странице есть соответствующая кнопка, но вот с камеры домофона — нельзя.
Как известно, если нельзя, но очень хочется, то можно.
Метод
1. Заходим на страницу с архивом, находим нужный фрагмент, открываем отладчик (клавишей F12), переключаемся на вкладку Network — так и в Google Chrome, и в Mozilla Firefox.
3. Когда запросы перестанут идти (то есть, всё нужно, уже скачалось), можно, щёлкнув по ним правой кнопкой, выбрать пункт “Save all as HAR” — запросы и ответы на них будут сохранены единым файлом с расширением HAR — на самом деле это JSON.
В отладчике открыта вкладка Network
4. Берём какой-нибудь HAR-extractor (есть всякие варианты — мне подошёл первый попавшийся, написанный на Node.JS), натравливаем его на HAR-файл, получаем папку, в одной из подпапок которой будут лежать видеофайлы с расширением TS.
5. Смотрим эти видеофайлы — под линуксом с гномом можно использовать стандартный видеоплеер totem или всеядный mpv (ну или mplayer, из которого он и вырос).
6. Создаём текстовый файл, каждая строка которого состоит из слова file, пробела и имени файла в апострофах:
Аналогичный способ — сохранение кучи мелких файликов через HAR — можно использовать для того, чтоб добыть тайлы — небольшие квадратные картинки из которых состоят интерактивные карты на сайтах, а потом, делая свою карту, разместить эти тайлы где-нибудь у себя, чтоб не создавать лишнюю нагрузку на тайлопровайдера — они этого не любят: OpenStreetMap просит не брать тайлы непосредственно у них, а фонд ВикиМедиа всё время клянчит денег на поддержку функционирования Википедии. Реальный пример такого подхода — карта Global SUSU на сайте Южно-Уральского университета: тайлы там сгенерированы Википедией из общедоступных данных OpenStreetMap, но хранятся на одном из университетских серверов.
где α, β и γ — углы, на которые проводится скос элементов.
Суть метода: картинка помещается в пару контейнеров, затем и картинка, и контейнеры подвергаются перекосу, при котором пропадают углы, вышедшие за границы родительского элемента. При перекосе самой картинки отрезаются два противоположных угла, при перекосе элемента с классом in в другую сторону и с большей амплитудой — оставшиеся углы, после чего перекосом элемента с классом out картинка возвращается к нормальному положению.
Для углов α = 20° (20deg в CSS), β = −30°, γ = 40° и картинки, состоящей из квадратов результат будет таким:
Можно заметить, что для возвращения картинки к нормальному положению углы α и γ должны совпадать. Угол β больше, чем α, но не в два раза — меньше. Для того, чтобы углы картинки обрезались симметрично, надо, чтобы тангенсы углов α и β относились как 1 к −2.
Можно CSS-правило трансформации записать в виде матрицы, где указывается тангенс: transform: matrix(1, 0, тангенс, 1, 0, 0) — тогда вместо вычисления углов путём взятия арктангенса, который есть, например, в дополнительных пакетах к Sass, но не в нём самом (и уж тем более не в CSS), можно будет пользоваться простым умножением:
Результат — группа из стоя́щих друг на друге квадратов режется по диагонали:
Для $tan: .577350269 (tg 30°) углы будут кратны тридцати градусам:
В обоих случаях Google Chrome режет неидеально: углы правильные, но некоторые линии разреза параллельно перенесены на несколько точек. Firefox рисует аналогично. Хотя если не заниматься пиксельхантингом рассматривать придирчиво каждую точку, результат выходит вполне приемлемым.
Дополнение/: если наружному элементу .out задать нулевую высоту строки line-height: 0, то линии разреза переноситься не будут ни в Хроме, ни в Файрфоксе — станет как надо.
Модуль Test::Mojo позволяет проверить, нашлось ли нужное количество DOM-элементов:
$t = $t->element_count_is('div.foo[x=y]',5);
$t = $t->element_count_is('html body div',30,'thirty elements');
Но так можно проверить лишь равенство ожидаемого и полученного, в то время как иногда нужны другие операции.
$t->get_ok("$ROOT/some.xml");my@items= $t->tx->res->dom->find('rss channel item')->each;
ok scalar @items>42,'More than 42 items in some.xml';
Перловый микрофреймворк Mojolicious::Lite умеет сам выдавать существующие файлы, но при этом не все из них получают верный тип содержимого Content-type: некоторые файлы прикидываются обычными текстовыми (text/plain), другие же вообще не имеют никакого типа — браузер такие файлы может воспринимать как угодно. В состав фреймворка входит модуль Mojolicious::Types, в котором определены MIME-типы для наиболее популярных (most common) расширений файлов:
странно, но среди них нет ни одного, относящегося к офисным пакетам. На сайте Microsoft | Developer можно найти список типов — Office 2007 File Format MIME Types for HTTP Content Streaming. Чтобы не задумываться, какие же из этих типов брать, можно сохранить все — если есть какой-нибудь конфигурационный файл, он вполне подойдёт для хранения такого списка. В моём случае конфигурационные файлы обычно в формате YAML — это удобно.
---
# ... ещё какие-нибудь параметры# MS Office typestypes:
rtf: application/rtf
doc: application/msword
dot: application/msword
docx: application/vnd.openxmlformats-officedocument.wordprocessingml.document
Где-нибудь перед запуском приложения надо добавить типы (допустим, конфигурация приложения доступна через $config)
while(my( $ext, $type )= each %{ $config->{'types'}}){
app->types->type($ext => $type);}
Правда, при выдаче файла тип его содержимого придётся всё-таки указать явно, иначе Mojolicious вернёт тип только для знакомых файлов, а для офисных будет undef
В состав перлового микрофреймворка Mojolicious::Lite входит класс Mojo::Log, который не просто пишет сообщения в лог, а ещё и учитывает важность сообщений — в отладочном режиме пишет много, а боевом — мало. Обнаружилось, что сообщения об ошибках имеют тот же класс debug, что и остальные сообщения
[Tue Nov 13 12:25:51 2018] [debug] Format html
[Tue Nov 13 12:25:51 2018] [debug] 200 OK (0.076118s, 13.137/s)
[Tue Nov 13 12:25:53 2018] [debug] GET "/some/url"
[Tue Nov 13 12:25:53 2018] [debug] Template "not_found.development.html.ep" not found
[Tue Nov 13 12:25:53 2018] [debug] Rendering template "not_found.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Rendering template "layouts/error.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Rendering cached template "layouts/admin.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Rendering cached template "search_form_navbar.html.ep"
[Tue Nov 13 12:25:53 2018] [debug] Format html
[Tue Nov 13 12:25:53 2018] [debug] 404 Not Found (0.004841s, 206.569/s)
из-за чего при запуске в продакшне под реальной нагрузкой в лог не попадает почти ничего — например, там нет сообщения об ошибках 404 Not Found.
Возможно, где-нибудь во внутренностях Mojo можно исправить такую ситуацию, но мы пойдём другим путём — применим хук after_dispatch: