» → « />»). * В статичной разметке нет данных — экранировать нечего. * * По правилам набора: сетка 24×24, живая зона 20×20, штрих 2, концы круглые, * только currentColor — значок берёт цвет кнопки и живёт на светлом и тёмном * фоне без второй версии. Мелкая деталь (голова) залита, потому что штриховой * контур такого размера на 16 px схлопнулся бы в кляксу. */ /** * Нужен ли виджет на этой странице. * * В админке он не нужен, и в гостевом прогоне сканера тоже: иначе сканер * находил бы нарушения в нашей же панели вместо сайта клиента. А память * режимов в прогоне сканера и вовсе вредна: у админа, щёлкнувшего контраст на * своём сайте, сканер мерил бы контраст нашего режима, а не темы. */ function onsite_a11y_vidzhet_nuzhen() { return ! is_admin() && ! onsite_a11y_est_metka_gostya(); } /** Режимы виджета: ключ — окончание класса на корне страницы, значение — подпись. */ function onsite_a11y_vidzhet_rezhimy() { return array( 'shrift' => __( 'Bigger text', 'finalwork-accessibility' ), 'kontrast' => __( 'High contrast', 'finalwork-accessibility' ), 'ssylki' => __( 'Highlight links', 'finalwork-accessibility' ), 'animacia' => __( 'Stop animations', 'finalwork-accessibility' ), ); } /** * Память выбора: включённые режимы ставятся на корень ДО первой отрисовки. * * Отдельный крошечный скрипт в самом начале
, а не код в vidzhet.js: * тот грузится в подвале, и человек видел бы мигание «сначала обычный вид, * потом крупный». Синхронный скрипт в head отрабатывает раньше, чем браузер * нарисует body, а стили режимов тоже лежат в head — первый кадр уже в режиме. * * Выбор хранится только в браузере посетителя (localStorage), на сервер не * уходит. Из памяти берём лишь известные режимы: вешать на корень что попало * из хранилища незачем. Хранилище недоступно (запрет cookie, приватный режим, * чужой скрипт его подменил) — молча работаем без памяти, консоль чиста. */ function onsite_a11y_vidzhet_pamyat() { if ( ! onsite_a11y_vidzhet_nuzhen() ) { return; } $js = str_replace( '/*REZHIMY*/ []', wp_json_encode( array_keys( onsite_a11y_vidzhet_rezhimy() ) ), onsite_a11y_vstroennyy_js( 'pamyat.js' ) ); wp_print_inline_script_tag( $js, onsite_a11y_ne_otkladyvat() ); } /** * Текст встроенного скрипта из файла плагина. * * Скрипты памяти и двойников обязаны стоять ВНУТРИ (иначе мигание), но * держать их блоками HEREDOC/NOWDOC нельзя: каталог WordPress такой синтаксис не * допускает. Поэтому код лежит обычными файлами в assets/, а сюда читается с * диска плагина — наружу ничего не ходит. Путь через plugin_dir_path, чтобы * проверка каталога видела, что файл локальный. */ function onsite_a11y_vstroennyy_js( $fayl ) { return rtrim( (string) file_get_contents( plugin_dir_path( __FILE__ ) . 'assets/' . $fayl ) ); } /** * Атрибуты, которые запрещают ускорителям откладывать наш скрипт. * * Ускорители («отложить JS до первого движения») переписывают теги скриптов, и * наши три перестают работать как задуманы: память и двойники из * срабатывают только после движения мыши — страница мигает, крупный текст * Elementor первые секунды мелкий; vidzhet.js грузится по первому щелчку, и этот * щелчок по значку пропадает. Замер на LiteSpeed Cache «Delayed»: h1 44 px вместо * 55, смена класса после body, значок со второго щелчка. * * Владелец сайта про исключения не знает, поэтому защищаемся сами — штатными * атрибутами самих ускорителей, без их настроек: * - data-no-defer — LiteSpeed Cache (src/optimize.cls.php, проверка атрибута * перед отложением встроенных и внешних скриптов); * - nowprocket — WP Rocket, «Delay JavaScript execution» * (https://docs.wp-rocket.me/article/1349-delay-javascript-execution). * Скрипты крошечные и ничего не грузят, скорость сайта от этого не страдает. */ function onsite_a11y_ne_otkladyvat() { return array( 'data-no-defer' => '1', 'nowprocket' => true, ); } /** Те же атрибуты на подключаемом файле vidzhet.js — ему тег собирает WordPress. */ function onsite_a11y_vidzhet_js_ne_otkladyvat( $teg, $imya ) { if ( 'onsite-a11y-vidzhet' !== $imya ) { return $teg; } return str_replace( '