caps_enhancer/CLAUDE.md

6.7 KiB
Raw Permalink Blame History

CAPS Enhancer — Chrome Extension

Chrome-расширение (Manifest V3) для улучшения интерфейса CAPS/UTP: навигационные кнопки, автологин, замена логотипа, редирект noVNC.

Архитектура

caps_enhancer-1/
├── manifest.json           # MV3, update URL, content scripts on <all_urls>
├── js/
│   ├── background.js       # Service worker: проверка обновлений (chrome.alarms)
│   ├── content.js          # Инициализация: роутинг по типу страницы
│   ├── popup.js            # Popup: быстрые переключатели
│   ├── options.js          # Страница настроек: загрузка/сохранение конфига
│   └── strings.js          # Все строки UI (русский)
├── modules/
│   ├── core.js             # CONFIG, утилиты, loadConfig(), updateConfig()
│   ├── mnemoschema.js      # Кнопки «Мнемосхема» и «Лещ» на главной странице
│   ├── video-window.js     # Кнопка с IP или «Лещ» в заголовке видео-окна
│   ├── novnc-redirect.js   # Редирект или кнопка на noVNC-странице
│   ├── auto-login.js       # Автологин с профилями и правилами подсетей
│   └── close-handler.js    # ESC закрывает видео-окна и карточки
├── options.html / popup.html
├── css/options.css / popup.css
└── server/                 # Деплой: .crx, nginx.conf, .reg, update.xml

Конфигурация (core.js CONFIG)

Хранится в chrome.storage.sync под ключом config. Структура:

{
  debug: { enabled, modules: { core, video, mnemo, close, content, novnc, autologin } },
  ports: { video: '5000', scheme: '8080' },
  videoWindow: {
    ipButtonMode: 'button'   // 'button' — кнопка «🔗 IP:порт», 'clickable-title' — кнопка «Лещ»
  },
  novnc: { mode: 'button'|'redirect', redirectDelay: 500 },
  mnemo: { mode: 'host-port'|'host-scheme', skipOnDomain, addVideoButton, addSchemeButton },
  autologin: { enabled, profilePage1, profilePage2, subnetRules, profiles },
  disabledSites: [],
  replaceLogo: true,
  uiVisible: true
}

При добавлении нового поля конфига: обновить CONFIG в core.js, updateConfig() в core.js, DEFAULT_CONFIG в options.js, добавить элемент в options.html, загрузку/сохранение в options.js, строки в strings.js.

Типы страниц (core.checkPageType)

Тип Признаки
isMainPage логотип CleverPark + noscript-маркер
isVideoPage noscript-маркер, нет логотипа
isNoVNCPage noscript "You need to enable JavaScript" + один из признаков ниже

Признаки noVNC (второй критерий):

  • div[class*="app_AppWindow__"] — старый тип страницы (CSS-модульный класс React-компонента)
  • document.title содержит "Платёжный терминал" — новый тип страницы (присутствует в HTML сразу при загрузке, до инициализации React)

Важно: не использовать DOM-элементы, которые появляются после загрузки React (например div#app.App, div.multi-find-menu-container) — они не существуют в момент первой проверки, что приводит к неверному определению типа страницы.

Модуль video-window.js

Добавляет ссылку на IP устройства в заголовок видео-окна. Два режима (настройка videoWindow.ipButtonMode):

  • button (по умолчанию): кнопка 🔗 IP:5000 после <p> в заголовке. Tooltip не задан.
  • clickable-title: кнопка «Лещ» с тем же стилем и тем же переходом. При наведении — нативный tooltip с полным URL (button.title).

Оба режима используют core.createStyledButton() — одинаковая стилизация. IP извлекается из src видео-элемента img[src*=":8888/screen"][src*="/getVideo/"] через regex /\/getVideo\/http:\/\/([^\/:?#]+)(?::(\d+))?/i.

Модуль novnc-redirect.js

Два режима (novnc.mode):

  • redirect: автоматический переход на http://<host>:<videoPort>. Редирект происходит если текущий порт не равен целевому (не жёсткая привязка к порту 80).
  • button: фиксированная кнопка в правом верхнем углу. После добавления следит за удалением через MutationObserver (15 сек) и добавляет кнопку снова — защита от React-рендеринга, который может очищать body.

Важно: у кнопки задан dataset.capsUiDisplay = 'inline-block', чтобы applyVisibility не сбрасывала её display в ''.

Видимость UI (Shift+F1)

  • data-caps-ui="true" — элементы расширения (скрываются при uiVisible=false)
  • data-caps-ui-display — исходное значение display, восстанавливается при uiVisible=true; обязательно задавать при создании кнопок с нестандартным display
  • data-caps-original="true" — оригинальные элементы (скрываются при uiVisible=true)
  • Логотип меняет src вместо display

Паттерны

  • Каждый модуль — IIFE, расширяет window.VideoIPRedirect
  • Общие утилиты: core.createStyledButton(), core.debugLog(), core.retryWithBackoff()
  • Конфиг обновляется через chrome.runtime.onMessageCONFIG_UPDATED
  • Строки: все тексты UI только в js/strings.js, доступ через getStr('options.key')

Деплой

См. DEPLOY.md. Кратко: упаковать .crx → загрузить на сервер → обновить update.xml с новой версией → версия в manifest.json.