/
docNemo
/
hex-map-editor
Обзор
Документация
Войти
/
docNemo
/
hex-map-editor
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
5
CI/CD
Аналитика
Безопасность
main
src/ui/application.ts
81 строка
3 KB
docNemo
feat(ui): окна генератора, инспектора, атласа и панели обзора
01 авг 2026, 06:24
01 авг 2026, 06:24
9e56105
Код
Авторство
О чём код?
import { MODULE_ID } from '@core/constants'; /** * Общее основание окон модуля поверх ApplicationV2. * * Содержимое отдаётся простой строкой разметки, а не шаблоном Handlebars. * Шаблоны потребовали бы отдельных файлов, регистрации при запуске и загрузки * по сети; выигрыш от них появляется на больших формах со сложной логикой, * которых у модуля нет. Взамен разметка окна лежит рядом с его данными. * * Базовый класс ApplicationV2 оставляет `_renderHTML` и `_replaceHTML` пустыми * именно для такого случая, а щелчки по `data-action` и изменения полей формы * приходят в `_onClickAction` и `_onChangeForm` даже при пустом списке действий. * Проверено на живом Foundry 14.365 — см. docs/FOUNDRY-COMPATIBILITY.md. */ /** Экранирование текста, попадающего в разметку. */ export function escapeHtml(value: string): string { return value .replace(/&/g, '&') .replace(/</g, '<') .replace(/>/g, '>') .replace(/"/g, '"') .replace(/'/g, '''); } /** Разметка выпадающего списка. */ export function selectOptions( options: readonly { value: string; label: string }[], selected: string, ): string { return options .map( ({ value, label }) => `<option value="${escapeHtml(value)}"${value === selected ? ' selected' : ''}>` + `${escapeHtml(label)}</option>`, ) .join(''); } export abstract class HexMapApplication extends foundry.applications.api.ApplicationV2 { static override DEFAULT_OPTIONS: ApplicationConfiguration = { // Класс модуля на корне окна: за него цепляются стили из styles/. classes: [MODULE_ID], window: { resizable: true, contentClasses: ['hme-window'] }, }; /** Разметка содержимого окна. */ protected abstract content(): string; protected override async _renderHTML(): Promise<string> { return this.content(); } protected override _replaceHTML(result: unknown, content: HTMLElement): void { content.innerHTML = String(result); } protected override _onClickAction(event: PointerEvent, target: HTMLElement): void { const action = target.dataset['action']; if (action === undefined) return; this.onAction(action, target, event); } protected override _onChangeForm(_config: ApplicationFormConfiguration, event: Event): void { const form = this.form; if (form === null) return; this.onFormChange(new foundry.applications.ux.FormDataExtended(form).object, event); } /** Щелчок по элементу с атрибутом `data-action`. */ protected onAction(_action: string, _target: HTMLElement, _event: PointerEvent): void {} /** Изменение любого поля формы. Значения уже приведены к типам по разметке. */ protected onFormChange(_data: Record<string, unknown>, _event: Event): void {} /** Перерисовка окна после изменения его данных. */ protected refresh(): void { if (this.rendered) void this.render(); } }