/
Starolat
/
DeepDive
Обзор
Документация
Войти
/
Starolat
/
DeepDive
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
js/services/CompactionController.js
107 строк
3 KB
Starolat Sergei
chore: sync project state for Gitverse
16 июн 2026, 16:06
16 июн 2026, 16:06
1cb951e
Код
Авторство
О чём код?
// @ts-check /** * @fileoverview CompactionController — ResizeObserver-based layout compaction * @version 1.0.0 * * Наблюдает за высотой целевого контейнера и диспатчит событие `compaction-change` * с одним из режимов: loose | compact | short. * * Также устанавливает `data-compaction` атрибут на целевом элементе для CSS в Light DOM. */ class CompactionController { constructor() { /** @type {ResizeObserver|null} */ this._observer = null; /** @type {HTMLElement|null} */ this._target = null; /** @type {string} */ this._currentMode = 'loose'; /** * Thresholds по высоте (px). * Порядок: от самого restrictive к least restrictive. */ this._thresholds = [ { mode: 'short', max: 500 }, { mode: 'compact', max: 700 }, { mode: 'loose', max: Infinity }, ]; } /** * Инициализация наблюдателя. * @param {HTMLElement} [target] — элемент за которым наблюдать (по умолчанию `.main-content`) */ init(target) { this._target = target || document.querySelector('.main-content'); if (!this._target) { console.warn('[CompactionController] Target not found, retrying in 500ms'); setTimeout(() => this.init(target), 500); return; } if (typeof ResizeObserver === 'undefined') { console.warn('[CompactionController] ResizeObserver not supported'); return; } this._observer = new ResizeObserver((entries) => { for (const entry of entries) { const h = entry.contentRect.height; this._update(h); } }); this._observer.observe(this._target); // Initial pass const rect = this._target.getBoundingClientRect(); this._update(rect.height); console.log('[CompactionController] Initialized on', this._target, 'mode=', this._currentMode); } /** * @param {number} height * @private */ _update(height) { const matched = this._thresholds.find((t) => height <= t.max); const mode = matched ? matched.mode : 'loose'; if (mode === this._currentMode) return; this._currentMode = mode; if (this._target) { this._target.setAttribute('data-compaction', mode); } document.dispatchEvent( new CustomEvent('compaction-change', { detail: { mode, previousMode: this._currentMode, target: this._target }, }) ); console.log('[CompactionController] Mode changed to', mode, 'height=', height); } /** Текущий режим compaction */ get mode() { return this._currentMode; } destroy() { if (this._observer) { this._observer.disconnect(); this._observer = null; } this._target = null; } } const compactionController = new CompactionController(); export { compactionController, CompactionController }; export default compactionController;