Skip to content

fix(history-mode): lay the history iframe in the editor's flex slot so side panels render#7903

Merged
JohnMcLear merged 1 commit into
developfrom
fix/history-mode-side-panel-layout
Jun 5, 2026
Merged

fix(history-mode): lay the history iframe in the editor's flex slot so side panels render#7903
JohnMcLear merged 1 commit into
developfrom
fix/history-mode-side-panel-layout

Conversation

@JohnMcLear
Copy link
Copy Markdown
Member

Problem

In-pad history mode (#7659) mounts the timeslider iframe (#history-frame-mount) as an absolute, inset:0 overlay over #editorcontainerbox. That fills the editor area, but takes the iframe out of flow, so any in-flow side panel inside #editorcontainerbox — e.g. ep_webrtc's video column (#rtcbox) — ends up hidden beneath the overlay. In live mode that panel sits beside the editor, so the two modes disagree. This is why ep_webrtc renders nothing in the timeslider (ether/ep_webrtc).

Fix

Make the history iframe occupy the same in-flow flex slot the live editor uses (flex: 1 1 auto inside the row-flex #editorcontainerbox) instead of an absolute overlay. Side panels then lay out identically in both modes.

This surfaced a latent cascade bug: body.history-mode #editorcontainer { display: none } (specificity 0-1-1) was outranked by the two-id layout rule #editorcontainerbox #editorcontainer { display: flex } (0-2-0), so the live editor was never actually removed from flow — the absolute overlay just painted over it. With the iframe now in normal flow, that no longer masks the editor, so the hide rule is given matching specificity (body.history-mode #editorcontainerbox #editorcontainer) to win the cascade.

Before / after (history mode, with a left side panel)

BEFORE: iframe absolute inset:0 (z-index:4) ── overlays panel
  [panel]   ← hidden underneath
  ╔════════════════════════╗
  ║  history iframe (full)  ║  ← covers panel + editor
  ╚════════════════════════╝

AFTER: iframe is an in-flow flex item beside the panel
  [panel] ║  history iframe (fills the rest)  ║

Tests

Added a padmode.spec.ts regression test: injects a left-pinned in-flow side panel, enters history mode, and asserts (1) the live editor is display:none, (2) #history-frame-mount is not absolutely positioned, and (3) the iframe lays out beside the panel and fills the editor's remaining width with no overlap. Verified passing against a dev server on this branch.

No behavioural change for pads without a side panel: when the iframe is the only in-flow child it fills the full editor width exactly as before.

🤖 Generated with Claude Code

In-pad history mode positioned the timeslider iframe (#history-frame-mount)
as an absolute, inset:0 overlay over #editorcontainerbox. That filled the
editor area but took the iframe out of flow, so any in-flow side panel in
#editorcontainerbox — e.g. ep_webrtc's video column (#rtcbox) — ended up
hidden beneath the overlay. In live mode the same panel sits beside the
editor, so the two modes disagreed (ether/ep_webrtc rendered nothing in the
timeslider).

Make the iframe occupy the same in-flow flex slot the live editor uses
(flex: 1 1 auto in the row-flex #editorcontainerbox) so side panels lay out
identically in both modes.

This surfaced a latent bug: `body.history-mode #editorcontainer { display:
none }` (specificity 0-1-1) was being outranked by the two-id layout rule
`#editorcontainerbox #editorcontainer { display: flex }` (0-2-0), so the live
editor was never actually removed from flow — the absolute overlay merely
painted over it. With the iframe now in normal flow that no longer hides the
editor, so the hide rule is given matching specificity
(body.history-mode #editorcontainerbox #editorcontainer) to win the cascade.

Added a padmode.spec.ts regression test that injects a left-pinned in-flow
side panel, enters history mode, and asserts the live editor is display:none,
the iframe is not absolutely positioned, and the iframe lays out beside the
panel filling the editor's remaining width (no overlap).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@qodo-code-review
Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@qodo-free-for-open-source-projects
Copy link
Copy Markdown

Review Summary by Qodo

Fix history mode iframe layout to sit beside side panels

🐞 Bug fix 🧪 Tests

Grey Divider

Walkthroughs

Description
• Fix history iframe layout to occupy flex slot instead of absolute overlay
• Prevents side panels from being hidden beneath history iframe
• Corrects CSS specificity cascade to properly hide live editor in history mode
• Add regression test verifying side panel and iframe layout without overlap
Diagram
flowchart LR
  A["Live Mode<br/>Editor + Side Panel<br/>in flex row"] -->|"History Mode"| B["History Iframe<br/>+ Side Panel<br/>in flex row"]
  C["Old: Absolute<br/>Overlay Iframe"] -->|"Issue"| D["Side Panel<br/>Hidden Beneath"]
  E["New: In-flow<br/>Flex Iframe"] -->|"Fix"| F["Side Panel<br/>Visible Beside"]

Loading

Grey Divider

File Changes

1. src/tests/frontend-new/specs/padmode.spec.ts 🧪 Tests +51/-0

Add history mode side panel layout regression test

• Added comprehensive regression test for history mode with side panels
• Test injects a left-pinned in-flow side panel simulating ep_webrtc's video column
• Verifies live editor is display:none and iframe is not absolutely positioned
• Asserts iframe and side panel layout without overlap and fills remaining width

src/tests/frontend-new/specs/padmode.spec.ts


2. src/static/css/pad.css 🐞 Bug fix +20/-8

Convert history iframe to in-flow flex layout

• Changed .history-frame-mount from position: absolute; inset: 0 to flex: 1 1 auto
• Added min-width: 0 to allow iframe to shrink for side panels
• Removed z-index: 4 as no longer needed for overlay
• Updated CSS rule specificity for body.history-mode #editorcontainerbox #editorcontainer to match
 two-id layout rule and win cascade
• Removed position: relative from body.history-mode #editorcontainerbox
• Enhanced comments explaining flex slot approach and cascade fix

src/static/css/pad.css


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects
Copy link
Copy Markdown

qodo-free-for-open-source-projects Bot commented Jun 5, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0)

Context used

Grey Divider


Remediation recommended

1. Flaky fixed waits 🐞 Bug ☼ Reliability
Description
The new Playwright test uses hard-coded waitForTimeout delays to space edits, which can
intermittently fail on slower CI/plugin-heavy runs and unnecessarily slows the suite. Prefer waiting
on an observable readiness signal (e.g., history iframe load + slider max/rev count) or remove the
sleeps if revisions aren’t required for the layout assertions.
Code

src/tests/frontend-new/specs/padmode.spec.ts[R350-356]

+    await goToNewPad(page);
+    await clearPadContent(page);
+    await writeToPad(page, 'one');
+    await page.waitForTimeout(300);
+    await writeToPad(page, ' two');
+    await page.waitForTimeout(500);
+
Evidence
The test uses arbitrary sleeps rather than waiting for a specific UI/DOM condition, while the test
helpers elsewhere already demonstrate a deterministic readiness pattern for the editor (waiting for
#editorcontainer.initialized and innerdocbody contenteditable=true).

src/tests/frontend-new/specs/padmode.spec.ts[349-356]
src/tests/frontend-new/helper/padHelper.ts[117-133]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The test relies on fixed `waitForTimeout(300/500)` delays to create distinct revisions before entering history mode. Fixed sleeps are prone to CI flakiness and slow down the suite.

## Issue Context
This test is asserting layout (no overlap; iframe is in-flow), so it can either:
- remove the pre-history sleeps entirely if they are not required for the iframe to mount, or
- replace them with a deterministic wait after entering history mode (for example: wait for `#history-frame` load and/or `#history-slider-input` to have `max > 0`).

## Fix Focus Areas
- src/tests/frontend-new/specs/padmode.spec.ts[350-398]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@JohnMcLear JohnMcLear merged commit e1476cf into develop Jun 5, 2026
32 checks passed
@JohnMcLear JohnMcLear deleted the fix/history-mode-side-panel-layout branch June 5, 2026 14:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant