feat(IMP-14): A-4 — slide_base embedded vs standalone mode contract
Step 13 owns iframe-vs-standalone CSS contract in slide_base.html via
3-valued embedded_mode enum (auto / embedded / standalone). Removes
SlideCanvas.tsx runtime CSS injection workaround; frontend now passes
?embedded=1 query so auto-mode script attaches html.embedded class and
scopes the standalone body centering/min-height/padding reset.
- templates/phase_z2/slide_base.html: conditional html.embedded class +
CSP-safe auto-mode <script> + additive html.embedded body/.slide rules
- src/phase_z2_pipeline.py: render_slide gains keyword-only embedded_mode
("auto" default) + ValueError guard; 3 existing call sites unchanged
- Front/client/src/components/SlideCanvas.tsx: derive embeddedSrc with
?embedded=1 (query-preserving), drop reset CSS injection block
- tests/phase_z2/test_slide_base_embedded_mode.py: 6 cases — auto script,
CSS rules, embedded/standalone explicit modes, byte-determinism,
invalid-mode guard
This commit is contained in:
@@ -186,6 +186,12 @@ export default function SlideCanvas({
|
||||
// 슬라이드 박스 표시 조건 — final.html 있거나 pendingLayout 모드.
|
||||
const showSlideBox = (finalHtmlUrl || isPendingLayout) && !isPipelineRunning;
|
||||
|
||||
// IMP-14 (Step 13 A-4) — backend slide_base.html 가 embedded vs standalone CSS
|
||||
// contract 를 `?embedded=1` query 로 소유. 기존 query string 보존하면서 flag 만 추가.
|
||||
const embeddedSrc = finalHtmlUrl
|
||||
? `${finalHtmlUrl}${finalHtmlUrl.includes("?") ? "&" : "?"}embedded=1`
|
||||
: undefined;
|
||||
|
||||
// wrapper 는 scaled 크기를 가지므로 layout 상 fit. 안의 슬라이드는 1280×720 으로
|
||||
// top-left origin scale 후 wrapper 안에 정확히 맞춤.
|
||||
const W_SCALED = SLIDE_W * scale;
|
||||
@@ -283,37 +289,21 @@ export default function SlideCanvas({
|
||||
>
|
||||
<iframe
|
||||
ref={iframeRef}
|
||||
src={finalHtmlUrl}
|
||||
src={embeddedSrc}
|
||||
title="Phase Z 렌더 결과"
|
||||
className="w-full h-full border-0 block"
|
||||
scrolling="no"
|
||||
sandbox="allow-same-origin"
|
||||
style={{ pointerEvents: isEditMode ? "auto" : "none" }}
|
||||
onLoad={(e) => {
|
||||
// final.html 은 standalone 표시용으로 body 에 padding / flex center /
|
||||
// min-height: 100vh 가 있어서, iframe 안에서는 슬라이드가 잘림.
|
||||
// .slide (1280×720) 만 보이도록 reset CSS 를 contentDocument 에 주입.
|
||||
// IMP-14 (Step 13 A-4) — embedded vs standalone CSS reset 은 backend
|
||||
// slide_base.html 가 `?embedded=1` query 로 소유. frontend 가 더 이상
|
||||
// reset CSS 를 contentDocument 에 inject 하지 않음. embedded query 가
|
||||
// backend auto-mode detection script 를 trigger 해서 html.embedded
|
||||
// class 를 붙이고 standalone-only body 규칙을 reset.
|
||||
try {
|
||||
const doc = (e.currentTarget as HTMLIFrameElement).contentDocument;
|
||||
if (!doc) return;
|
||||
const style = doc.createElement("style");
|
||||
style.textContent = `
|
||||
html, body {
|
||||
margin: 0 !important;
|
||||
padding: 0 !important;
|
||||
min-height: 0 !important;
|
||||
height: 720px !important;
|
||||
width: 1280px !important;
|
||||
background: transparent !important;
|
||||
display: block !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
.slide {
|
||||
box-shadow: none !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
`;
|
||||
doc.head.appendChild(style);
|
||||
|
||||
// 2026-05-14 — slide-level override CSS (catalog/template 무변).
|
||||
// Home 이 mdx 별 default visual 보완 (bullet 간격 / zone 비율 등) 지정.
|
||||
|
||||
Reference in New Issue
Block a user