Приводим авторский контент (.ps1/.psm1/.py/.mjs/.md/.json, пин .bsl)
к единому LF и закрепляем политикой в .gitattributes. Инструмент правки
всегда пишет LF, поэтому единый LF убирает EOL-шум в диффах, ложные
срабатывания blame и налог на ручную синхронизацию CRLF-файлов.
BOM на .ps1 сохранён (git с eol=lf меняет только CR<->LF, BOM не трогает).
Данные 1С (*.xml) и бинарники под нормализацию не берём.
Гейт: PS-порт 459/459, Python-порт 459/459, web-test E2E 22/22 (с пересборкой стенда).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Tab-цикл не выходил сразу после заполнения последнего поля: ветки заполнения по
составному типу и по примитиву делали continue без проверки «все поля закрыты», и
цикл протабывал остаток строки до wrap-around. На широких строках с объединёнными
колонками (составной субконто) это заметно «бежало» табами до конца строки — холостые
итерации + риск ухода фокуса/создания лишней строки.
- row-fill v1.24: единая проверка в начале итерации `if (every filled) break`.
Значение последнего поля к этому моменту уже зафиксировано (commit-Tab примитива,
выбор из формы, либо end-of-row commit для choice-ячейки).
- 05-table: guard на количество строк после составного фила.
Проверено: полный регресс web-test 22/22; вживую на широкой ТЧ с составным субконто —
лишний хвост табов устранён.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
scanGridRowsScript целился в центр всей .gridLine; на широкой форме выбора (колонок
больше, чем влезает в окно) центр-X уезжает за вьюпорт в оверлей → клик мимо строки →
Enter не выбирает → форма не закрывается → ложное not_selectable «group/folder row».
- dom/grid v1.10: матч по ячейкам (строка: exact→startsWith→includes; объект {col:val}:
пер-колоночно, AND, предпочтение exact-all), точка клика — первая видимая текстовая
ячейка строки (не центр); возврат visibleSample/isGroup. scrollIntoView не нужен
(динсписок держит в DOM только видимые строки).
- forms/select-value v1.25: структурированный search в скан (без склейки значений
объекта), различение still_open vs реальная группа (isGroup), actionable not_found
со списком видимых кандидатов.
- tests: широкая (14 колонок, choiceMode) форма выбора Контрагентов + контрагент «Север»
рядом с «ООО Север» → детерминированный регресс центр-X + exact-preference;
selectValue (04-selectvalue) и fillTableRow составной ячейки (05-table).
Проверено: живой E2E на реальной форме выбора составного типа, red-green на синтетике,
полный регресс web-test.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Три проблемы объектного поиска (следствие рефакторинга на модули):
- импорт filterList отсутствовал — pickFromSelectionForm (Шаг 2) бросал
ReferenceError, который молча глотался catch'ем, поиск по полю не работал;
- dropdown-путь 3A падал на searchText.toLowerCase() (объект, не строка) —
теперь объектный search уходит в форму выбора, где обрабатывается per-field;
- сужен catch вокруг filterList: ReferenceError/TypeError пробрасываются,
чтобы будущие missing-import не маскировались как 'поле не найдено'.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
readSpreadsheet() в ветке allCells.size===0 (отчёт не сформирован) вызывал
checkForErrors() без импорта — падало с 'checkForErrors is not defined'
вместо осмысленного сообщения. Следствие рефакторинга на модули.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fillChoiceCell определял «прижился ли paste» через normYo(after).includes(text),
что ломалось на маск-инпутах: число/дата переформатируются (1234.56 → «1 234,56»,
группировка неразрывным пробелом, запятая) → includes давал false → ложный уход
в F4, где у числа открывался калькулятор и залипал (no_selection_form).
Заменил на поведенческий дискриминатор: появился EDD → ссылка (dropdown);
инпут изменился на непустое без EDD → редактируемая ячейка (direct); инпут
не изменился → НачалоВыбора → F4-форма. + страховка: если F4 открыл не форму
выбора (калькулятор/календарь) — Escape и спасение значения.
Также в EDD-ветке основного Tab-цикла убран слепой fallback items[0]: при
отсутствии exact/includes-совпадения возвращается not_found с очисткой поля,
а не подставляется произвольная первая запись автокомплита.
Регресс: в стенд (дерево) добавлены choice-колонки Число/Дата и булево-поле-ввода;
в 16-tree-form — шаги choice-number/choice-date/bool-input. Полный регресс: 22 passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fillTableRow теперь принимает row как объектный фильтр (одна/несколько колонок,
AND-матч) — как clickElement — и опцию scroll:true для строк за пределами
DOM-окна виртуализации. Фильтр резолвится в числовой индекс один раз в начале
через переиспользование resolveRowIndexByFilter из click-cell.mjs (без дублей
matching/reveal); дальше существующий код row-mode не тронут. row:<число> —
полная обратная совместимость.
Побочно починен баг в общем reveal-цикле (его же использует clickElement scroll):
детектор конца списка опирался на текст первой колонки + selIdx, поэтому на
табчасти с однотипной первой колонкой ложно срабатывал на втором PageDown.
Теперь основной признак конца — hasBelow===false, а сигнатура снимка строится
по всей строке (snapshotGridScript).
Версии: click-cell v1.4, dom/grid v1.9, row-fill v1.22.
Регресс tests/web-test: 22/22 зелёные (live E2E на синтетическом стенде).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Диалог выбора типа матчил по подстроке и падал «multiple types match»,
даже когда точное совпадение присутствовало в выдаче (напр. поиск
«Контрагент» давал «Банковская карта контрагента», «Договор с контрагентом»,
…, «Контрагент» — и движок ругался, хотя точная строка была видна).
pickFromTypeDialog теперь предпочитает точное совпадение (resolveExact:
единственный матч, либо единственная строка, равная искомому имени после
нормализации регистра/ё) — кликает именно её и жмёт OK. Применяется и в
scan-пути (мелкие списки), и после Ctrl+F (большие виртуальные списки).
Добавлен ограниченный скролл-скан (PageDown ×3) на случай, когда точная
строка чуть ниже первого окна. Ошибка неоднозначности остаётся, только если
единственного точного совпадения действительно нет.
Стенд: в СписокТипов добавлен подстрочный дубль «Дата документа» рядом с
«Дата» для детерминированной проверки exact-match. Тест 16-tree-form
покрывает scan-путь (выбирается точное «Дата»).
Проверено: регресс web-test 22/22, живой E2E на типовой Консоли запросов
(ссылочный тип через Ctrl+F + примитив без регресса).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ячейка грида с кнопкой выбора (iCB, buttonKind:'choice') бывает двух видов,
неразличимых в DOM (оба editInput, readOnly:false): редактируемое значение
(текст прилипает) и выбор из программного списка (РедактированиеТекста=Ложь —
текст отвергается, readOnly при этом не выставляется). Движок жал F4 на обе и
падал no_selection_form, если форма не открывалась.
Новый общий helper fillChoiceCell различает их поведенчески: пробует прямой
ввод, и если вставленный текст прилип — коммитит (method:'direct'), иначе
открывает форму по F4 (isTypeDialog → pickFromTypeDialog 'choice', иначе
pickFromSelectionForm 'form'). Вызывается из обоих мест (плоский Tab-цикл и
tree direct-edit) — плоский и tree гриды теперь ведут себя одинаково.
Стенд: ДеревоТипЗначения получает textEdit:false (модель выбора-из-списка),
добавлено поле ДеревоРедактируемаяСтрока (кнопка выбора + пустой НачалоВыбора,
модель редактируемой ячейки). Тест 16-tree-form покрывает оба плеча.
Проверено: полный регресс web-test 22/22, живой E2E на типовой Консоли запросов.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Поле с кнопкой выбора и обработчиком НачалоВыбора (значение выбирается из программного
списка — например колонка Тип в типовой Консоли запросов) раньше заполнялось plain-paste,
который молча откатывался → ok:true/method:direct (ложный успех). Теперь движок детектит
такую ячейку и выбирает значение из формы выбора.
- dom/grid-edit.mjs: readActiveGridCellScript отдаёт buttonKind активной ячейки
(ref/calc/date/choice по кнопке _DLB/_CB и её классу).
- engine/table/row-fill.mjs v1.20: для kind=choice — F4 → pickFromTypeDialog
(скан/Ctrl+F/OK) → method:choice; если после выбора открылась форма значения,
это составная ячейка (нужен {value,type}). Ветка добавлена в Tab-цикл и directEditPick.
- engine/forms/select-value.mjs v1.21: умный dismiss диалога типов на путях
not_found/multiple — Escape только пока диалог открыт, больше не закрывает
исходную форму слепым Escape×3.
- Стенд: строковая колонка-выбор ТипЗначения (НачалоВыбора → ПоказатьВыборЭлемента)
в ДеревоНоменклатуры; тест 16 покрывает method:choice и негатив not_found.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
fillFields классифицировал поля по кнопкам: _DLB → ссылка, _CB → pick (если
класс iCalendB → дата). Числовое поле формы (напр. «Цена») имеет _CB с классом
iCalcB (калькулятор) и isDate=false, поэтому уходило в ветку selectValue, которая
ждёт форму выбора → детерминированный фейл "DLB click did not open a popup or
selection form". Калькулятор формой выбора не является.
- dom/forms.mjs: распознаём iCalcB → флаг isCalc (по аналогии с isDate/iCalendB),
пробрасываем его в resolveFieldsScript.
- engine/forms/fill.mjs: ветку paste расширяем на hasPick && (isDate || isCalc) —
калькулятор заполняем через Ctrl+A + paste + Tab, как календарь. Ссылочный
fallback (hasPick без даты/калькулятора) не тронут.
Пробел покрытия: «Цена» в наборе заполнялась только через fillTableRow (Tab-путь),
а fillFields-ветка калькулятора не гонялась. Добавлен 'Цена' в 03-fillfields.test
с assert method=paste и значением 777,00. E2E: тест 03 зелёный.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
clickElement как последний fallback (без table) фокусирует одноимённое
поле ввода, не меняя значение — возвращает focused:{field,id,ok}.
Закрывает пробел: клавиши F4/Shift+F4 требовали сфокусированного поля,
но штатного примитива фокуса не было.
- dom/forms.mjs: резолв input.editInput/textarea по имени/заголовку
последним шагом findClickTargetScript; имена полей в available
- click-form.mjs: focusFormField (клик по инпуту + isInputFocused → ok)
- click.mjs: ветка диспетчера kind === field
- SKILL.md + docs/web-test-guide.md: focused в extras, пример focus→F4
- tests: 19-focus-field.test.mjs (focus/F4/регресс/негатив)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
readTable теперь отдаёт картиночные ячейки как 'pic:<N>' (есть иконка)
или '' (нет): N — индекс кадра спрайта, кодирующий состояние. Присутствие
читается как truthy, разные иконки различаются по индексу. Безымянные
картиночные колонки (напр. индикатор присоединённых файлов) больше не
выпадают — именуются по title-тултипу, fallback '(picture)'.
- dom/grid.mjs: helper picInfo (парсинг gx из pictureCollection url,
исключение декоративных иконок дерева/групп); ветка пустого заголовка
добавляет картиночные колонки; resolveCol резолвит колонку по тексту И
по title (клик по картиночной колонке).
- click-cell.mjs: fail-fast при попытке отбора строки по 'pic:N' —
понятная ошибка вместо row_not_found (картинки read/assert-only).
- SKILL.md: компактный раздел про картиночные колонки.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
После focus-click перед PageDown (reveal-loop) или ArrowRight/Left (horizontal
scroll) клавиатурная навигация ломалась если click попадал в Number/Date
ячейку — она автоматически входила в edit-mode, и стрелки начинали навигацию
внутри input вместо движения по гриду.
Два изменения:
1. findFocusCellScript generic mode (без direction) теперь берёт cells[0]
вместо cells.slice(1) — то есть первую видимую колонку. В document
tabular sections это типично Reference (Номенклатура), которая не
входит в edit-mode по single click. Защиту от tree-toggles оставил
точечно: для tree-гридов (presence of .gridBoxTree) пропускаем
первую колонку как и раньше.
2. В click-cell.mjs после focus-click в revealAndFindCell и scrollGridToCell
добавил тот же isInputFocusedInGrid + Escape страховочный фолбек,
что и в deleteTableRow — на случай если focus всё же попал в input.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Delete-клавиша в режиме редактирования ячейки очищает буфер ввода,
а не удаляет строку. Это становилось проблемой когда:
1. предыдущий fillTableRow закончил Tab-навигацией в input (например
в Number-ячейку соседней колонки), и фокус остался там;
2. сам click на Number/Date ячейку в deleteTableRow автоматически
входит в edit-mode (поведение 1С).
Фикс: в deleteTableRow проверяем isInputFocusedInGrid дважды — до и
после click — и шлём Escape если активен INPUT в целевом гриде. Строка
остаётся выделенной после Escape, Delete срабатывает.
Дополнительно: isInputFocusedInGridScript / isInputFocusedInGrid теперь
принимают опциональный gridSelector — чтобы можно было прицельно проверять
конкретный грид на многогрид-формах (а не любой `.grid` на странице).
Покрытие: новый шаг в 05-table проверяет сценарий «фокус снаружи грида
(Комментарий), потом delete» — гарантирует что post-click Escape ловит
автоматический вход в edit-mode при клике на Number-ячейку.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
clickElement({row,column}) теперь работает не только на SpreadsheetDocument,
но и на гридах формы (динамические списки, табчасти). Маршрутизация:
spreadsheet приоритет (backward-compat), без spreadsheet — первый видимый
грид; явный table='Имя' форсит конкретный грид.
Поддержка:
- row: number — индекс в текущем DOM окне (виртуализация — документировано)
- row: { Колонка: значение } — фильтр по нормализованному содержимому
- scroll: true | number — reveal-loop через PageDown пока строка не найдена
или DOM не перестал меняться (с лимитом)
- Автоматический горизонтальный скролл к колонке за viewport
(учитывает frozen-колонки .gridBoxFix)
- Post-scroll visibility check — throw вместо ложного success
readTable обогащён полем hasMore: { above?, below } — единственный
надёжный сигнал виртуализации. total/shown остаются как DOM-окно
(backward-compat) с честным описанием в SKILL.md.
Общий хелпер scrollHorizontallyByKey вынесен в engine/core/, переиспользуется
spreadsheet'ом и грид-click'ом. DOM-логика (findGridCellScript,
findFocusCellScript, snapshotGridScript, resolveCellTargetScript) живёт
в dom/grid.mjs — engine только оркестрирует.
Покрытие: новый 18-cell-click.test.mjs (7 шагов: spreadsheet
regression-guard, catalog dblclick, табчасть, hasMore, 2 error-paths,
cleanup). Расширен 05-table.test.mjs проверкой hasMore.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Раньше per-item shape в filled[] был heterogeneous:
- success: {field, ok: true, method, value}
- failure: {field, error, message} ← без ok!
Естественная проверка `item.ok === false` молча промахивалась (latent bug в
production-клиенте Titan C:\WS\projects\titan\tests\helpers\query.mjs:69).
И документация утверждала «все функции throw'ают на ошибке» (guide.md:352),
что для fillTableRow было неправдой.
Что изменено:
- engine/table/row-fill.mjs v1.18 → v1.19: 15 error-pushes теперь включают
ok: false. item.ok — единый дискриминатор success/failure.
- SKILL.md: fillFields раздел уточнён («throws on per-field failure — если
вернулся, всё заполнено»). fillTableRow раздел: документирует контракт
(НЕ throws на per-field), перечисляет error-коды и recovery hints
(composite_type → retry с {value, type}, column_not_found → проверить
readTable, и т.д.).
- docs/web-test-guide.md: строка 352 нюансирована (fillTableRow исключение
из «все throw'ают»); строка 296 (таблица) уточнена.
Контракт обеих функций теперь сознательно различается и явно описан:
- fillFields = fail-fast (throws на любую ошибку, удобно для fill-and-go)
- fillTableRow = partial-recovery (errors в filled[] как ok:false, модель
может retry'нуть селективно отдельную ячейку)
Бонус: query.mjs в Titan'е теперь работает корректно без правки клиентского
кода — cell.ok === false наконец-то дискриминирует error-items.
Полный регресс 19/19 зелёный.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Все action-функции теперь возвращают плоский form state с extras —
закрыта последняя аномалия API. Раньше:
- fillFields → {filled, form} (вложенный, документировано в SKILL.md)
- fillTableRow → 3 разных shape в 5 ветках (array | {filled, form} | {filled, notFilled, form}),
при этом документация заявляла плоский — код её игнорировал
Теперь обе функции используют returnFormState({filled, notFilled?}) — тот же
паттерн что у всех action-функций после Phase 1+2 (clickElement, selectValue,
closeForm, filterList и т.д.).
Что закрывает:
1. Тихий баг в production-клиенте C:\WS\projects\titan\tests\helpers\query.mjs
на res.filled?.find() — array-ветки fillTableRow возвращали [{...}] без .filled
→ ошибки заполнения параметров запросов молча пропускались. R1/R2-аналог.
2. Костыли r.filled || r в tests/web-test/05-table.test.mjs (2 места) —
убраны, поскольку polymorphism устранён.
3. Расхождение код ↔ документация в fillTableRow.
4. Внутренний polymorphism в row-fill.mjs: убраны два `if (Array.isArray(more))`
костыля в рекурсивных вызовах самого fillTableRow.
Файлы:
- engine/forms/fill.mjs v1.17 → v1.18 (1 ветка → returnFormState)
- engine/table/row-fill.mjs v1.17 → v1.18 (5 веток + 2 рекурсии)
- tests/web-test/05-table.test.mjs (r.filled || r → r.filled)
- .claude/skills/web-test/SKILL.md (сигнатуры fillFields/fillTableRow + общая
ремарка про плоский return shape в начале раздела Actions)
- docs/web-test-guide.md (строки fillFields/fillTableRow/navigateSection;
общая ремарка в начале раздела «Действия»)
В тестах ни один кейс не обращался к .form.X, blast radius нулевой.
Точечный регресс (03/05/06/07/10/16) и полный регресс 19/19 — зелёные.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
19 LOC inline cellCoords + 8 LOC inline row-count в engine/table/grid.mjs
deleteTableRow → новый findDeleteRowCoordsScript в dom/grid.mjs + переиспользован
существующий countGridRowsScript (dom/grid.mjs:268, добавлен в S5).
Engine-сторона deleteTableRow становится чистым оркестратором: resolve grid →
get coords → click → Delete → count rows.
DOM-extraction iter 2 / S10 из плана. Точечный регресс 05-table зелёный +
полный регресс 19/19 зелёный.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
25 LOC inline page.evaluate в forms/select-value.mjs:30 → новый экспорт
scanGridRowsScript(formNum, searchLower) в dom/grid.mjs (рядом с
readTableScript, getSelectedOrLastRowIndexScript). Engine-сторона —
тонкая обёртка одной строкой.
DOM-extraction iter 2 / S9 из плана. Точечный регресс 04-selectvalue зелёный.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
navigation.mjs: navigateSection (sections+commands ветка), switchTab, openFile
(оба success-сайта). Закрывает R1/R2 для навигационных action-функций.
grid.mjs: deleteTableRow — заодно унификация shape с SKILL.md ("→ form state"
плоский). До этого код возвращал {deleted, ..., form: formData} в нарушение
документации; теперь плоский state с extras. JSDoc обновлён.
spreadsheet.mjs: clickSpreadsheetCell. select-value.mjs: ветка clear-success
selectValue (search=null, method='clear').
Phase 1 / C3 (final) из плана upload/returnFormState-audit.md. Полный регресс 19/19
зелёный. Известный pre-existing test-isolation issue в одиночном прогоне
04-selectvalue (auto-history) — описан в backlog §0.8 #4 родительского плана.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Тяжёлые DOM-блоки row-fill (15–60 строк) вынесены в 8 именованных
функций dom/grid-edit.mjs. row-fill стал плоским orchestrator-ом.
Новое в dom/grid-edit.mjs:
- sortFieldKeysByColindexScript — сортировка keys по colindex (Tab-нав)
- findCellCoordsByFieldsScript — клетка по first matching header (multi)
- findNextCellCoordsByKeyScript — клетка по single key + no-space fuzzy
- findCheckboxAtPointScript — checkbox info по координатам elementFromPoint
- findRowCommitClickCoordsScript — клик OTHER row для commit-edit
- getGridEditCheckScript — { inEdit, tag?, hint? } диагностика
- readActiveGridCellScript — активная клетка (id, fullName, headerText)
- getElementCenterCoordsByIdScript — центр по id (дедуп 2 копий)
Метрики row-fill: 971 → 793 LOC (−178, S6 alone), inline page.evaluate
10 → 1 (значительно ниже плановой цели ≤10). Все табличные suite
зелёные (05/06/08/10/16), полный регресс зелёный (Checkpoint-2).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Новое в dom/grid.mjs (все принимают опциональный gridSelector):
- countGridRowsScript — кол-во .gridLine в body
- isTreeGridScript — тип grid'а (есть .gridBoxTree)
- findGridHeadCenterCoordsScript — центр .gridHead для commit-клика
- getSelectedOrLastRowIndexScript — selected row index, fallback на последний
Также:
- isInputFocusedInGrid wrapper (S1) применён в add-row "ready" поллинге
- isNotInListCloudVisibleScript (S3) применён вместо локального notInList
- clickShowAllInNotInListCloudScript — новая в dom/forms.mjs (клик
"Показать все" в "нет в списке" cloud popup через dispatchEvent)
Метрики row-fill: 1041 → 971 LOC (−70), evaluates 17 → 10. Регресс
05/08/16/10 — зелёный.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Новое в dom/edd.mjs:
- readEddScript — {visible, items:[{name,x,y}]}
- isEddVisibleScript — boolean, лёгкая проверка
- clickEddItemViaDispatchScript — клик по name через dispatchEvent (bypass
div.surface); fuzzy с NBSP/ё/bracket-strip
- clickShowAllInEddScript — "Показать все" в footer
Wrappers в helpers.mjs: readEdd, isEddVisible, clickEddItemViaDispatch,
clickShowAllInEdd. row-fill clickEddItem унифицирован с select-value
вариантом (NBSP/ё normalization теперь работает и для табличных строк).
Метрики: select-value 880 → 827 LOC (−53), row-fill 1065 → 1041 LOC
(−24); evaluates row-fill 20 → 17, select-value 7 → 5. Полный регресс
зелёный.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Все 17 inline page.evaluate в engine/table/filter.mjs вынесены в
именованные dom-генераторы. Engine-модуль стал чистым orchestrator-ом.
Новое в dom/forms.mjs (shared с будущим S3 select-value):
- findSearchInputScript(formNum) — поиск SearchString/ПоискаСтроки input
- findNamedButtonScript(text) — кнопка a.press по innerText (Найти, OK)
- findCompareTypeRadioScript(form, idx) — радио CompareType#N#radio
- isFormVisibleScript(form) — есть ли видимые элементы form{N}
Новое в dom/filter.mjs:
- findFirstGridCellCoordsScript — координаты первой клетки грида
- findColumnFirstCellCoordsScript — клетка по имени колонки (fuzzy header
match с needDlb-fallback)
- readFieldSelectorInfoScript — FieldSelector value + DLB coords
- pickFieldInSelectorDropdownScript — выбор поля в FieldSelector DLB-edd
- readFilterDialogInfoScript — Pattern id+value+isDate+isRef
- findFilterBadgeCloseScript — × badge по имени поля
- findFirstFilterBadgeCloseScript — × первого видимого badge (для clear-all)
Попутно: добавлен импорт readSubmenuScript (был pre-existing broken
import в Еще-fallback ветке Alt+F).
Метрики filter.mjs: 390 → 256 LOC (−134, −34%), inline page.evaluate
17 → 0. Регресс 09-filter / 02-crud / 05-table — зелёный.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
SpreadsheetDocument (отчёты, печатные формы) — другой домен, чем form-grid
(табличные части документов, списки). Раньше лежал внутри table/, что
было обманчиво.
engine/table/spreadsheet.mjs → engine/spreadsheet/spreadsheet.mjs
Структура engine/:
core/ плумбинг движка (state, wait, errors, session, click, ...)
forms/ работа с формами (fill, close, select-value, state)
nav/ навигация
table/ form-grid (grid, row-fill, filter, grid-toggle)
spreadsheet/ SpreadsheetDocument
recording/ запись + overlays
В будущем при росте spreadsheet можно распилить — engine/spreadsheet/cells.mjs,
engine/spreadsheet/scroll.mjs и т.д. без переименований.
11-report регресс зелёный.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
getFormState — высокоуровневая операция «прочитать состояние формы»,
семантически в forms/ ближе чем в core/ (foundational плумбинг движка).
engine/core/form-state.mjs → engine/forms/state.mjs
Все 11 importer'ов обновлены. Внутри state.mjs пути исправлены:
'./state.mjs' → '../core/state.mjs', './errors.mjs' → '../core/errors.mjs'.
03-fillfields регресс зелёный.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
После полной чистки cycle-импортов в E.13 остались комментарии типа
"getFormState still in browser.mjs", которые больше не верны (он переехал
в engine/core/form-state.mjs). Сметаем устаревшие "moved to / lives in
browser.mjs" комментарии в 8 файлах.
Дополнительно в engine/table/spreadsheet.mjs:
- убраны неиспользуемые импорты readTableScript, resolveGridScript, normYo
(остались с тех пор, как readTable жил в этом файле — до этапа D.12
rename'а в grid.mjs)
- заголовочный комментарий обновлён (без упоминания readTable)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>