Документ фиксирует текущий контракт работы модуля:
RectsPatchModule является window-realm модулем влияния на DOM/SVG layout и rendering inputs, которые затем измеряются нативным Chromium через DOMRect, DOMRectList, Element.getBoundingClientRect(), Element.getClientRects(), Range.getBoundingClientRect(), Range.getClientRects() и SVG layout/geometry APIs.
Модуль не является patch-модулем public Web IDL methods/accessors. Его задача - не заменить rect API, а подготовить controlled layout/rendering influence так, чтобы Chromium сам посчитал geometry через штатный native path.
Главная формула контракта:
seed/profile/state -> CSS/layout influence -> native Chromium layout -> native rect measurements
Модуль не должен превращаться в compatibility binding под один внешний стенд. Имена внутренних каналов описывают тип измеряемого источника layout/rendering, а не имена элементов конкретной страницы.
Приоритеты:
- Внешний нормативный контракт
ECMAScript,Web IDL, MDN, Chromium runtime fact. Policy_implement_reg.md:object/function/proxy/property/apply path.Hidden_State_FernwehContext_Contract.md: owner-state и hidden slots.DEGRADE_Contract.md: observed diagnostics и запрет silent-swallow.- Текущая прикладная логика
RectsPatchModule.
Ключевое следствие:
RectsPatchModule не имеет права ломать descriptor/receiver/apply/toString/proxy invariants public API.
Для rect surfaces нормативный внешний слой остаётся у Chromium:
- Web IDL methods остаются native built-in function objects;
- descriptors остаются на своих Chromium owners;
- bad receiver path остаётся native;
Function.prototype.toStringостаётся engine baseline;- Proxy exotic wrapper не должен появляться на public rect method surface;
DOMRect/DOMRectReadOnlyobject shape не подменяется модулем.
Модуль работает только в window realm.
Entrypoint:
RectsPatchModule(window);Файл подключается в main.py в bundle window-патчей и вызывается после bootstrap/core/screen/nav setup и до downstream graphics/media modules.
Текущий pipeline-order:
BootstrapHideModule(window)
set_log.js
prng_seed.js
core_window.js
...
ScreenPatchModule(window)
RectsPatchModule(window)
FontPatchModule(window)
CanvasPatchModule(window)
...RectsPatchModule ожидает, что bootstrap owner-space уже создан:
window.FernwehContext
window.FernwehContext.state
window.Core
Core.__internal.prng
Core.guardFlag
Core.releaseGuardFlag
FernwehContext.__logger.__DEGRADE__Если обязательная структура отсутствует, это pipeline missing data и fail-fast, а не soft-skip.
Модуль делает четыре вещи:
- Проверяет наличие обязательного owner-state и profile/state inputs.
- Строит детерминированный набор CSS/layout influence values из seed, screen metrics и fonts profile.
- Находит в текущем document измерительные fixture-candidates через широкие каналы layout/rendering, без id/class binding конкретного стенда.
- Применяет inline style influence к найденным candidates и повторяет scan через
MutationObserver,queueMicrotaskиsetTimeout.
Модуль влияет на измерения DOM/CSS inputs перед нативным layout calculation.
- патчить
Element.prototype.getBoundingClientRect; - патчить
Element.prototype.getClientRects; - патчить
Range.prototype.getBoundingClientRect; - патчить
Range.prototype.getClientRects; - патчить
DOMRect,DOMRectReadOnly,DOMRectList; - создавать callable
Proxyвокруг rect methods; - создавать JS-wrapper для native rect methods;
- менять descriptor shape public Web IDL operations;
- менять
Function.prototype.toString; - добавлять detector-specific selector binding в module logic;
- искать конкретные
id/classвроде measurement names отдельного стенда; - использовать
querySelector,getElementById,getElementsByClassNameкак binding path для rect influence; - создавать stylesheet с hardcoded page selectors под конкретный стенд;
- писать public service globals на
window; - использовать
Math.random; - использовать fallback values при отсутствии обязательного state.
5. Hidden owner-state
Canonical owner-state модуля:
FernwehContext.state.__RECTS__
__STATE__
__CONFIG__bootstrap_hide.js является owner создания hidden slots:
FernwehContext.state.__RECTS__.__STATE__
FernwehContext.state.__RECTS__.__CONFIG__RectsPatchModule является consumer и runtime owner значений внутри своего module slot. Он не создаёт root FernwehContext, не создаёт C.state и не пересоздаёт чужие module slots.
Текущая форма:
FernwehContext.state.__RECTS__.__STATE__ = {
ready: boolean,
status: string,
reason: string | null,
error: string | null,
applied: number,
targets: number
}Смысл полей:
| Поле | Назначение |
|---|---|
ready |
модуль завершил apply path без fatal error |
status |
bootstrap, applying, ready, error |
reason |
текущая причина состояния, для успешного path: layout_influence |
error |
текст ошибки при failure path или null |
applied |
количество style-property assignments, применённых модулем |
targets |
количество найденных measurement candidates по каналам |
ready: true означает, что observer установлен и apply path завершён. Это не означает, что на странице обязательно были найдены measurement candidates в момент первого scan.
Текущая форма:
FernwehContext.state.__RECTS__.__CONFIG__ = {
maxMeasurementScan: number
}maxMeasurementScan задаёт верхний предел сканирования ordinary DOM elements через document.getElementsByTagName('*').
Default создаётся в bootstrap_hide.js:
2048
Это не detector binding. Это safety bound для DOM scan, чтобы эвристика не превращалась в безлимитный обход страницы.
Если maxMeasurementScan отсутствует, не число или <= 0, RectsPatchModule обязан завершиться fail-fast:
rects:measurement_scan_limit_invalidМодуль берёт значения только из существующих owner-paths.
Canonical PRNG owner:
Core.__internal.prng
seed
strToSeed
mulberry32RectsPatchModule не читает window.__GLOBAL_SEED как consumer-path.
Seed derivation строится через:
__unit(label)Формула:
rects-layout | label | Core.__internal.prng.seedДопустимые seed labels текущего модуля:
html-layout-geometry-width
text-glyph-metrics-font-size
text-glyph-metrics-letter-spacing
font-familyЭти labels не являются именами DOM-целей. Это labels deterministic branches внутри rect layout influence.
Canonical source:
FernwehContext.state.__SCREEN__
width
height
dprwidth, height, dpr должны быть finite positive numbers. Для текущего rect influence непосредственно используется dpr, но preflight проверяет весь базовый screen metrics set, потому что это единый screen owner-state модуля.
Canonical source:
FernwehContext.state.__FONTS__.__CONFIG__.configsМодуль выбирает CSS family из fonts config. Если доступен FernwehContext.state.__ENV_PROFILE__.__PLATFORM__.domPlatform и font configs имеют platform_dom, список сужается до соответствующей platform group.
Допустимые поля font config для имени family:
cssFamily
family
full_name
postscript_nameВыбор family детерминирован seed branch font-family.
Если font config отсутствует или после нормализации не остаётся ни одного имени, это fail-fast:
rects:fonts_config_missing
rects:font_family_missingТекущий influence строится в __buildLayoutInfluence(fontFamily).
Выход:
{
fontFamily,
htmlLayoutGeometryWidth,
textGlyphMetricsFontSize,
textGlyphMetricsLetterSpacing
}CSS string quoted через __quoteCssString.
Назначение: влиять на text glyph metrics через штатный CSS font selection path.
Форма:
calc(1000.099% + <delta>px)delta детерминирован через seed и dpr.
Назначение: влиять на HTML layout geometry контейнера, который участвует в measurement.
Форма:
calc(200px + <delta>px)delta детерминирован через seed и dpr.
Назначение: влиять на glyph metric calculation без подмены rect API.
Форма:
<delta>pxdelta детерминирован через seed и dpr.
Назначение: влиять на spacing component text layout.
Текущее правило:
overflow: visibleНазначение: не скрывать SVG geometry при native SVG layout measurement.
Модуль использует четыре внутренние rule-группы. Это не нормативные имена Web IDL сущностей, а честные проектные labels фактических layout/rendering channels.
Канал HTML layout geometry.
Сущность: видимый HTML container/ancestor/offsetParent, который влияет на native rect calculation дочернего measurement node
Применяемые rules:
width
Источник candidates:
- ближайший parent/ancestor с visible layout rect;
offsetParent, если он имеет visible layout rect;- parent fallback, если он имеет visible layout rect.
Канал text glyph metrics.
Сущность: deepest visible element, whose textContent contains emoji/symbol glyphs
Применяемые rules:
font-family
font-size
letter-spacingИсточник candidates:
- elements from bounded scan;
textContentсодержит glyph по__glyphTextPattern;- элемент является deepest glyph element;
- элемент имеет visible layout rect.
Канал pixel/glyph rendering.
Сущность: тот же видимый glyph element, рассматриваемый как rendering metric source
Применяемые rules:
font-family
font-size
letter-spacingЭтот канал фиксирует, что текстовый glyph node может участвовать в pixel/rendering side measurements.
Канал SVG layout geometry.
Сущность: visible SVG node, measured by native SVG/layout geometry APIs
Применяемые rules:
overflow
Источник candidates:
document.getElementsByTagName('svg')SVG scan не ограничивается maxMeasurementScan, потому что SVG nodes сканируются отдельным tag route.
Discovery function:
__collectMeasurementFixtureCandidates()Обязательное browser capability:
document.getElementsByTagNameЕсли capability отсутствует:
rects:get_elements_by_tag_name_missingПорядок:
- Получить
document.getElementsByTagName('svg'). - Для каждого SVG node проверить visible layout rect.
- Добавить SVG node в
svgLayoutGeometry. - Добавить ближайший layout container в
htmlLayoutGeometry.
Счётчики:
svgScanned
scannedПорядок:
- Получить
document.getElementsByTagName('*'). - Идти по DOM order до
maxMeasurementScan. - Проверить deepest glyph element.
- Проверить visible layout rect.
- Добавить element в
textGlyphMetrics. - Добавить element в
pixelGlyphRendering. - Добавить nearest layout container в
htmlLayoutGeometry.
Счётчики:
elementScanned
scanned
Проверка:
el.getClientRects()Условие:
есть rect с width > 0 и height > 0
Это чтение нативного метода, а не patch этого метода. Оно используется только как discovery predicate.
Если чтение rects у candidate throws, модуль не должен silent-swallow. Он один раз эмитит:
rects:measurement_candidate_rect_read_failedПосле этого конкретный candidate считается непригодным.
Текущий glyph predicate:
/[\u00A9\u00AE\u203C-\u3299]|[\uD83C-\uDBFF][\uDC00-\uDFFF]/Назначение: широкий detection emoji/symbol glyph text, а не selector binding.
Ограничение: это эвристика. Она может поймать реальные видимые glyph nodes страницы. Это допустимый текущий риск layout influence модели, но не основание возвращаться к hardcoded detector selectors.
Apply function:
__applyLayoutInfluence(styles)Применение идёт только через inline style API:
el.style.setProperty(key, value, '')Priority всегда пустой:
без !important
Перед записью проверяется текущее значение:
style.getPropertyValue(key)
style.getPropertyPriority(key)Если property уже имеет нужное значение и пустой priority, повторная запись не считается applied.
htmlLayoutGeometry candidates -> styles.htmlLayoutGeometry
textGlyphMetrics candidates -> styles.textGlyphMetrics
pixelGlyphRendering candidates -> styles.textGlyphMetrics
svgLayoutGeometry candidates -> styles.svgLayoutGeometryМодуль не создаёт stylesheet node и не строит selector CSS. Это важно: текущая модель не привязана к именам DOM элементов.
После scan:
__rectsState.targets = measurementTargetCount;Если были реальные style assignments:
__rectsState.applied += applied;Если candidates найдены впервые, эмитится telemetry:
rects:measurement_fixtures_discoveredData shape:
{
outcome: 'return',
candidates: {
htmlLayoutGeometry,
textGlyphMetrics,
pixelGlyphRendering,
svgLayoutGeometry
},
channels,
scanned,
svgScanned,
elementScanned,
measurementTargetCount,
applied
}Observer installation:
__installLayoutObserver()Обязательное browser capability:
window.MutationObserverЕсли отсутствует:
rects:mutation_observer_missingПорядок:
- Выполнить initial scan/apply.
- Создать
new window.MutationObserver(...). - Observe target:
document.documentElement || documentOptions:
{ childList: true, subtree: true }- Запланировать дополнительный scan через
queueMicrotask, если capability существует. - Запланировать дополнительный scan через
setTimeout(..., 0), если capability существует.
Если observer callback throws при apply:
rects:layout_influence_apply_failedОшибка пробрасывается дальше. Это не soft-fail.
Если scheduling throws:
rects:layout_influence_schedule_failedОшибка пробрасывается дальше.
Guard key:
__PATCH_RECTS__Guard owner:
Core.__internal.guards
Core.guardFlag
Core.releaseGuardFlagМодуль берёт guard до preflight и write side effects.
Если Core.guardFlag отсутствует:
rects:guard_missingЕсли Core.guardFlag throws:
rects:guard_failedЕсли guard acquisition возвращает falsy token, модуль возвращает 0 и не выполняет apply.
Текущая реализация снимает guard после successful observer installation через:
__releaseGuard(true)Это означает, что guard в данном модуле используется как apply-entry lifecycle guard, а не как permanent patched-target lock. Такая форма допустима только потому, что модуль не заменяет public descriptors и не регистрирует persistent public API patch target.
При failure path:
__releaseGuard(false)Если release throws:
rects:guard_release_failedModule id:
rectsSurface label:
DOM/SVG layout influence for native rect measurements
Adapter:
FernwehContext.__logger.__DEGRADE__.diag(level, code, ctx, err)
fallback: FernwehContext.__logger.__DEGRADE__(code, err, extra).diag вызывается с bound receiver:
__D.diag.bind(__D)Logging-path failure не должен ломать модуль. Patch/apply/preflight failure при этом не становится success.
Модуль передаёт:
{
module: 'rects',
diagTag,
surface,
key,
stage,
message,
type,
data
}Допустимые текущие stages:
guard
preflight
apply
runtime
rollbackPreflight / missing data:
rects:fernweh_context_state_missing
rects:document_missing
rects:screen_state_missing
rects:screen_metrics_invalid
rects:prng_missing
rects:fonts_config_missing
rects:font_family_missing
rects:state_missing
rects:measurement_scan_limit_invalid
rects:get_elements_by_tag_name_missing
rects:mutation_observer_missingGuard:
rects:guard_missing
rects:guard_failed
rects:guard_release_failedRuntime/apply:
rects:measurement_candidate_rect_read_failed
rects:measurement_fixtures_discovered
rects:layout_influence_apply_failed
rects:layout_influence_schedule_failed
rects:layout_influence_appliedbootstrap_hide.js создаёт:
ready: false
status: 'bootstrap'
reason: null
error: null
applied: 0
targets: 0RectsPatchModule пишет:
ready = false
status = 'applying'
reason = 'layout_influence'
error = nullready = true
status = 'ready'
error = nullreason остаётся:
layout_influenceapplied и targets отражают фактическое runtime discovery/apply состояние.
ready = false
status = 'error'
reason = 'layout_influence_failed'
error = String(error)Ошибка пробрасывается дальше после state update и guard release attempt.
Обязательный acceptance для public rect surfaces:
Element.prototype.getBoundingClientRect
Element.prototype.getClientRects
Range.prototype.getBoundingClientRect
Range.prototype.getClientRects
DOMRect
DOMRectReadOnlyКонтроль:
- descriptors не изменены
RectsPatchModule; - method values остаются native Chromium function objects;
Function.prototype.toString.call(method)возвращает Chromium native source string;- bad receiver path остаётся native TypeError / Illegal invocation;
getClientRects()возвращает nativeDOMRectList;getBoundingClientRect()возвращает nativeDOMRect;- module diagnostics не подменяют native result/throw path;
- отсутствует public Proxy-observability defect на rect methods.
Если для достижения layout influence требуется изменить public descriptor, это считается неверным направлением. Правильный путь - менять DOM/CSS inputs или отказаться от конкретной цели с observed diagnostic, но не ломать Web IDL method surface.
Запрещены detector-specific строки в logic layer:
id/class конкретного теста
CSS selectors конкретного теста
названия DOM containers конкретного теста
Разрешены:
- стабильные project labels seed branches;
- стабильные project labels measurement channels;
- Web/platform generic tag name
svg; *для bounded generic element scan;- CSS property names (
width,font-family,font-size,letter-spacing,overflow); - numeric scan bound из
__RECTS__.__CONFIG__.maxMeasurementScan; - deterministic formulas, основанные на seed + DPR.
Разница:
htmlLayoutGeometry - это channel label.
именованный selector/page binding - это привязка к конкретной странице или стенду.
В module logic допустим первый тип, недопустим второй.
Текущая модель использует широкую эвристику по glyph/layout/SVG candidates. Поэтому на произвольной странице возможно влияние на реальные видимые элементы, если они подходят под predicate:
visible deepest emoji/symbol glyph element
visible SVG node
nearest visible layout container
Это не является silent failure: применённые targets считаются и диагностируются через __RECTS__.__STATE__ и rects:measurement_fixtures_discovered.
Если на конкретной странице будет доказан ущерб, править нужно эвристику канала или gating условий, а не возвращаться к hardcoded binding конкретного стенда.
Не доказано как универсальный факт без runtime-аудита каждой страницы:
- что эвристика не заденет пользовательский видимый контент;
- что bounded scan всегда успеет поймать transient measurement nodes;
- что все внешние detectors используют measurement patterns, покрытые текущими каналами.
Эти ограничения не меняют базовый контракт: public API не патчится, influence идёт через layout/rendering inputs.
Единственный текущий конфигурационный параметр:
FernwehContext.state.__RECTS__.__CONFIG__.maxMeasurementScanМенять его нужно через bootstrap/owner-state path, а не локальным hardcode в rects.js.
Любое изменение величин influence должно сохранять цепочку:
Core.__internal.prng.seed
-> __unit(stable label)
-> value normalized by screen DPR / font profile
-> CSS property assignment
Нельзя вводить значения, которые появляются "ниоткуда".
Новый канал допускается только если он описывает универсальный source layout/rendering measurement, например:
CSS box metrics
font/glyph metrics
SVG geometry
pixel/rendering metrics
transform/edge geometry
Новый канал не должен быть именем внешнего теста, id/class конкретной страницы или compatibility binding.
Модуль считается контрактно корректным, если:
rects.jsне меняет public descriptors/functions/accessors rect APIs.Element.*,Range.*,DOMRect*сохраняют native Chromium shape.Function.prototype.toStringrect methods не имеет wrapper/proxy symptoms.Core.__internal.prngявляется единственным seed consumer-path.FernwehContext.state.__SCREEN__является source screen metrics.FernwehContext.state.__FONTS__.__CONFIG__.configsявляется source font family material.FernwehContext.state.__RECTS__.__STATE__отражает lifecycle.FernwehContext.state.__RECTS__.__CONFIG__.maxMeasurementScanуправляет bounded scan.- Нет hardcoded id/class/selector binding конкретного стенда.
- Discovery идёт через каналы
htmlLayoutGeometry,textGlyphMetrics,pixelGlyphRendering,svgLayoutGeometry. - Style application идёт через
style.setProperty. MutationObserverиспользуется для runtime candidates, а не для public API patching.- Любой controlled failure виден через
__DEGRADE__.diag. - Нет silent
catch {}на patch/apply/runtime failure path. - Отсутствие обязательного state/capability ведёт к fail-fast, а не к soft-skip.
page_bundle.jsне является source of truth и не правится.
bootstrap_hide.js
creates FernwehContext.state.__RECTS__.__STATE__
creates FernwehContext.state.__RECTS__.__CONFIG__.maxMeasurementScan
rects.js
reads Core guard + PRNG
reads screen state
reads fonts config
builds deterministic CSS/layout influence
scans SVG and bounded DOM glyph/layout candidates
applies inline style rules to generic measurement channels
installs MutationObserver + microtask + timeout scans
writes __RECTS__.__STATE__
emits DEGRADE diagnosticsChromium
keeps native rect API
computes layout/geometry normally
returns native DOMRect / DOMRectList / SVG geometry results
Финальное правило:
RectsPatchModule управляет входами layout/rendering, а не выходами Web IDL rect API.