feat(step14+step21): add zone_geometries_px artifact (IMP-01 #1)
- Add slide-relative bbox export of .zone elements via getBoundingClientRect
- Inline Selenium JS collects zone_geometries_px = [{position, template_id, x, y, w, h}]
- write_debug_json adds top-level additive zone_geometries_px field
- Existing visual_runtime_check / zones / frame_slot_metrics / PASS/FAIL logic unchanged
- AI/Kei/V4/frame selection paths not touched
Refs Gitea #1 (IMP-01 A-6 Zone DOM 좌표 export)
This commit is contained in:
@@ -850,11 +850,14 @@ def run_overflow_check(html_path: Path) -> dict:
|
|||||||
|
|
||||||
const slideM = measure(slide);
|
const slideM = measure(slide);
|
||||||
slideM.size_correct = slide.clientWidth === 1280 && slide.clientHeight === 720;
|
slideM.size_correct = slide.clientWidth === 1280 && slide.clientHeight === 720;
|
||||||
|
// A-6 (IMP-01 #1) — slide-relative bbox base
|
||||||
|
const slideRect = slide.getBoundingClientRect();
|
||||||
|
|
||||||
const body = document.querySelector('.slide-body');
|
const body = document.querySelector('.slide-body');
|
||||||
const bodyM = body ? measure(body) : null;
|
const bodyM = body ? measure(body) : null;
|
||||||
|
|
||||||
const zones = [];
|
const zones = [];
|
||||||
|
const zone_geometries_px = [];
|
||||||
slide.querySelectorAll('.zone').forEach((z) => {
|
slide.querySelectorAll('.zone').forEach((z) => {
|
||||||
const pos = z.getAttribute('data-zone-position') || 'unknown';
|
const pos = z.getAttribute('data-zone-position') || 'unknown';
|
||||||
const tid = z.getAttribute('data-template-id') || '?';
|
const tid = z.getAttribute('data-template-id') || '?';
|
||||||
@@ -862,6 +865,17 @@ def run_overflow_check(html_path: Path) -> dict:
|
|||||||
m.position = pos;
|
m.position = pos;
|
||||||
m.template_id = tid;
|
m.template_id = tid;
|
||||||
|
|
||||||
|
// A-6 (IMP-01 #1) — zone bbox in slide-relative px (additive trace, no layout side effect)
|
||||||
|
const zoneRect = z.getBoundingClientRect();
|
||||||
|
zone_geometries_px.push({
|
||||||
|
position: pos,
|
||||||
|
template_id: tid,
|
||||||
|
x: Math.round(zoneRect.left - slideRect.left),
|
||||||
|
y: Math.round(zoneRect.top - slideRect.top),
|
||||||
|
w: Math.round(zoneRect.width),
|
||||||
|
h: Math.round(zoneRect.height),
|
||||||
|
});
|
||||||
|
|
||||||
// 내부 clipping 검사 — frame-family root/cell 단위.
|
// 내부 clipping 검사 — frame-family root/cell 단위.
|
||||||
// tolerance / threshold 그대로. inner_content_signals 만 추가 보강 (detection 데이터 늘림).
|
// tolerance / threshold 그대로. inner_content_signals 만 추가 보강 (detection 데이터 늘림).
|
||||||
const clipped = [];
|
const clipped = [];
|
||||||
@@ -926,7 +940,7 @@ def run_overflow_check(html_path: Path) -> dict:
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return { slide: slideM, slide_body: bodyM, zones, frame_slot_metrics };
|
return { slide: slideM, slide_body: bodyM, zones, frame_slot_metrics, zone_geometries_px };
|
||||||
""")
|
""")
|
||||||
|
|
||||||
screenshot_path = html_path.parent / "preview.png"
|
screenshot_path = html_path.parent / "preview.png"
|
||||||
@@ -1228,6 +1242,8 @@ def write_debug_json(run_dir: Path, layout_preset: str,
|
|||||||
"composition_planner_debug": composition_debug,
|
"composition_planner_debug": composition_debug,
|
||||||
"zones": debug_zones,
|
"zones": debug_zones,
|
||||||
"visual_runtime_check": visual_runtime_check,
|
"visual_runtime_check": visual_runtime_check,
|
||||||
|
# A-6 (IMP-01 #1) — additive top-level zone bbox trace (slide-relative px)
|
||||||
|
"zone_geometries_px": (visual_runtime_check or {}).get("zone_geometries_px", []),
|
||||||
}
|
}
|
||||||
debug_path = run_dir / "debug.json"
|
debug_path = run_dir / "debug.json"
|
||||||
debug_path.write_text(json.dumps(debug, ensure_ascii=False, indent=2), encoding="utf-8")
|
debug_path.write_text(json.dumps(debug, ensure_ascii=False, indent=2), encoding="utf-8")
|
||||||
|
|||||||
Reference in New Issue
Block a user