98 lines
6.7 KiB
Markdown
98 lines
6.7 KiB
Markdown
# 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`. Структура:
|
||
|
||
```javascript
|
||
{
|
||
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.onMessage` → `CONFIG_UPDATED`
|
||
- Строки: все тексты UI только в `js/strings.js`, доступ через `getStr('options.key')`
|
||
|
||
## Деплой
|
||
|
||
См. [DEPLOY.md](DEPLOY.md). Кратко: упаковать `.crx` → загрузить на сервер → обновить `update.xml` с новой версией → версия в `manifest.json`.
|