fix(gamification): kill-switch не доходил до учебников (нет ls.css)
Учебники (frontend/textbooks/*.html, 112 шт.) грузят api.js, но НЕ ls.css. api.js ставил
класс .no-gamification на <html>, но сами правила kill-switch (`[data-gamified]`, попап XP)
живут в ls.css → до учебников не доходили, и встроенная XP-механика (бейдж/карточка XP,
ачивки, level-up попап #ach-popup) продолжала отображаться при выключенной геймификации.
Фикс — централизованно в _applyFeatureCss: при gamification=false дублируем правила
`.no-gamification [data-gamified],#ach-popup{display:none}` в инъектируемый <style>, поэтому
kill-switch работает на ЛЮБОЙ странице с api.js, без ls.css. Плюс на страницах без сайдбара
(учебники/embed) теперь авторитетно дёргаем loadFeatures() (только для залогиненных,
in-memory-дедуп) — кэш фич там не обновлялся. Админ по-прежнему видит всё (admin-override).
Verified vm-смоук на реальном api.js 7/7 (student+off → правило инъектится; student+on → нет;
admin → ничего).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -903,7 +903,14 @@ function _applyFeatureCss(feats) {
|
||||
JSON.parse(localStorage.getItem('ls_examhide') || '[]')
|
||||
.forEach(h => sels.push(`[href="${h}"]`));
|
||||
} catch { /* пусто */ }
|
||||
const css = sels.length ? sels.join(',') + '{display:none !important}' : '';
|
||||
let css = sels.length ? sels.join(',') + '{display:none !important}' : '';
|
||||
// Геймификация: дублируем kill-switch в инъекцию — для страниц БЕЗ ls.css.
|
||||
// Учебники (frontend/textbooks/*.html) грузят api.js, но НЕ ls.css, поэтому правила
|
||||
// .no-gamification из ls.css туда не доходят, и встроенная XP-механика (data-gamified,
|
||||
// #ach-popup) оставалась видимой. Инъекция работает на любой странице с api.js.
|
||||
if (feats && feats.gamification === false) {
|
||||
css += '.no-gamification [data-gamified],.no-gamification #ach-popup{display:none!important}';
|
||||
}
|
||||
let el = document.getElementById('ls-feat-hide');
|
||||
if (!el) {
|
||||
el = document.createElement('style');
|
||||
@@ -921,6 +928,14 @@ try {
|
||||
_applyFeatureCss(_cachedFeats); // применит и кэш фич, и кэш скрытых exam-prep ссылок
|
||||
} catch { /* нет кэша / приватный режим — просто ждём async */ }
|
||||
|
||||
/* Авторитетно подтянуть фичи на страницах БЕЗ сайдбара (учебники, embed): там
|
||||
sidebar.js/hideDisabledFeatures не вызывают loadFeatures, и кэш мог устареть.
|
||||
loadFeatures() кэширует in-memory (дубль-вызов = один fetch) и сам зовёт _applyFeatureCss.
|
||||
Только для залогиненных — иначе на /login apiFetch поймает 401 и зациклит редирект. */
|
||||
try {
|
||||
if (isLoggedIn()) { loadFeatures().catch(() => {}); }
|
||||
} catch { /* defensive */ }
|
||||
|
||||
/* Прячет группы сайдбара (.sb-group), у которых не осталось ни одного видимого пункта,
|
||||
чтобы не висел пустой заголовок-аккордеон (напр. «Практика и игры», когда все
|
||||
модули отключены). Зовётся после построения сайдбара и после hideDisabledFeatures. */
|
||||
|
||||
Reference in New Issue
Block a user