fix(pad): show saved-revision markers in in-pad history mode (#7946)#7948
Conversation
) When ether#7659 moved the timeslider into the pad as an embedded iframe, the user-facing control became the outer #history-slider-input range input. The saved-revision stars are still drawn by broadcast_slider.ts into the iframe's #ui-slider-bar, but that DOM is hidden in embed mode, and pad_mode.ts bridged rev/max/value/timer/authors to the outer slider but never the saved revisions. Result: clicking "Save Revision" appeared to work but no markers showed in the timeslider (regression in 3.3.x). Bridge the embedded timeslider's clientVars.savedRevisions onto the outer slider as percentage-positioned star markers, rendered on first sync and re-rendered when the slider max changes. Markers are a purely visual, aria-hidden overlay (keyboard/SR users already reach any revision via the slider + step buttons) with a click-to-seek convenience for mouse users. Adds a frontend-new Playwright spec exercising the real user flow (save a revision in the pad, enter in-pad history mode, assert a visible marker on the outer slider). The only prior coverage lived in the legacy mocha suite (src/tests/frontend/specs/timeslider_revisions.js) which no CI workflow runs, and the modern timeslider specs drive the ?embed=1 iframe directly and never exercise the outer history UI — so this regression was invisible to CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
Code Review by Qodo
1.
|
PR Summary by QodoFix saved-revision star markers in in-pad history timeslider WalkthroughsDescription• Restore saved-revision star markers on the in-pad history slider (regression in 3.3.x). • Bridge iframe savedRevisions to an outer-slider overlay with click-to-seek markers. • Add Playwright regression test covering save revision → history mode → marker render. Diagramgraph TD
user["User"] --> outer["Pad history controls"] --> bridge["pad_mode.ts bridge"] --> stars["#history-slider-stars overlay"]
iframe["Embedded timeslider iframe"] --> vars["clientVars.savedRevisions"] --> bridge
outer --> bs["BroadcastSlider API"] --> iframe
stars --> bs
High-Level AssessmentThe following are alternative approaches to this PR: 1. Unhide/render iframe star bar in embed mode
2. Bridge saved revisions via postMessage instead of direct iframe access
Recommendation: Current approach (outer overlay + reading File ChangesBug fix (3)
Tests (1)
|
Address Qodo review on ether#7948: - Live updates (bug 1): the server's SAVE_REVISION handler never broadcast NEW_SAVEDREV, so the client handler that adds a star was dead and no open timeslider ever updated live. Wire it up: Pad.addSavedRevision returns the new revision (undefined on duplicate); handleSaveRevisionMessage broadcasts NEW_SAVEDREV to the pad room. pad_mode.ts now sources outer markers from the embedded slider's live #ui-slider-bar .star DOM (labels from clientVars) and observes that bar so a revision saved by a collaborator appears on an already-open history slider. Live editors ignore the unknown message type. - Single-revision pad (bug 2): allow max === 0 so a revision saved at rev 0 still renders a marker instead of being cleared by the old max <= 0 guard. - Test rigor (bug 3): assert the marker's inline left percentage directly instead of falling back to a layout coordinate, which let left:0% pass. Adds a two-client Playwright test for the live path (verified it fails with the server broadcast removed). Backend Pad + pad API specs (88) still pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Addressed all three findings in 212c8c9: 1. Stars miss live updates — Verified, and the root cause was deeper:
2. Rev0 marker never renders — Verified. The 3. Test allows left=0 — Verified. The Added a two-client Playwright test for the live path (confirmed it fails when the server broadcast is removed). Backend |
…ned suite (#7949) * test(timeslider): port legacy mocha specs to Playwright, retire orphaned suite The legacy src/tests/frontend/specs/ mocha suite is run by no CI workflow, so its timeslider coverage was dead — a regression in the in-pad history UI (#7659/#7946) sailed through CI. Port the still-meaningful cases to frontend-new Playwright specs, re-targeted at the real in-pad UI (outer banner / slider / export links that pad_mode.ts drives) rather than the isolated ?embed=1 iframe the existing specs use: - timeslider_revision_labels.spec.ts (from timeslider_labels.js): the #history-banner shows 'Version N' + a valid (non-NaN) date and timer, and both update when scrubbing to revision 0. - timeslider_export_links.spec.ts (from timeslider_numeric_padID.js and the 'checks the export url' case of timeslider_revisions.js): the outer export hrefs target /p/<pad>/<rev>/export/<type> for the viewed revision, including a numeric pad id, and follow the slider to revision 0. - timeslider_deeplink.spec.ts (from the 'jumps to a revision given in the url' case): a #rev/N hash — and the legacy #N shortlink form — boots straight into history mode at that revision. Delete the three now-ported legacy specs. Verified passing on Chromium and Firefox. The star-marker case of timeslider_revisions.js is already covered by timeslider_saved_revisions.spec.ts (#7948). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(timeslider): make deep-link spec robust on Firefox Assert the canonical #rev/0 URL and the slider landing on revision 0 rather than the #history-banner-rev label text. The banner label is populated via a MutationObserver bridge that races the iframe load on the bootstrap path in Firefox (it is already covered for the normal button-entry flow by timeslider_revision_labels.spec.ts); the URL + slider value are the deterministic signals that the deep link entered history at the right revision. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(timeslider): address Qodo review on #7949 - Pin locale to en-US in the revision-labels spec so the localized 'Version N' label and 'Saved <Month> <day>, <year>' date assertions are deterministic and the date stays Date-parseable, instead of depending on the runner's locale. - Use a high-entropy numeric pad id (timestamp + random) in the export-links spec so reruns against a persistent DB can't collide on the same pad. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fixes #7946
What was broken
Saved revisions (the Save Revision star button) stopped appearing as markers in the timeslider in 3.3.x.
Root cause
When #7659 moved the timeslider into the pad as an embedded iframe, the user-facing control became the outer
#history-slider-inputrange input inpad.html. The saved-revision stars are still drawn bybroadcast_slider.tsinto the iframe's#ui-slider-bar, but that DOM is hidden inembedded-history-framemode.pad_mode.tsbridges rev / max / value / timer / authors onto the outer slider — but never the saved revisions. So saving worked, yet no markers ever showed.The underlying saved-revisions code path (server
getSavedRevisions,clientVars.savedRevisions,broadcast_slider.addSavedRevision) is byte-for-byte unchanged from 3.2.0 — the regression is purely the missing outer-slider bridge.The fix
pad.html: wrap#history-slider-inputin a positioned.history-slider-wrapwith a#history-slider-starsoverlay.pad.css: style.history-starmarkers (reusing the existing timeslider star glyph), inset to align with the native range thumb.pad_mode.ts: bridge the embedded timeslider'sclientVars.savedRevisionsonto the outer slider as percentage-positioned markers, rendered on first sync and re-rendered when the slider max changes. A signature guard keeps it cheap on every scrub; percentage positions reflow on resize for free.Markers are a purely visual,
aria-hiddenoverlay (keyboard / screen-reader users already reach any revision via the slider + step buttons, matching the legacy timeslider's mouse-only stars) with a click-to-seek convenience.Why CI didn't catch it (and how this PR closes that gap)
src/tests/frontend/specs/timeslider_revisions.js) lives in the legacy mocha suite, which no workflow runs —frontend-tests.ymlonly runs Playwright (tests/frontend-new/specs/).?embed=1iframe directly and never exercise the outer in-pad history UI where the bug lives.This PR adds
tests/frontend-new/specs/timeslider_saved_revisions.spec.ts, which exercises the real user flow: write content → click Save Revision → enter in-pad history mode via the toolbar → assert a visible, correctly-positioned marker on the outer slider. Verified TDD-style: the test fails ondevelop(.history-starnot found) and passes with the fix. All 15 existingtimeslider_*specs still pass.🤖 Generated with Claude Code