Skip to content

fix(modal): sub-anchor click closes the umbrella modal (E2E regression)#567

Merged
rdmueller merged 1 commit into
LLM-Coding:mainfrom
raifdmueller:fix/subanchor-modal-close
Jun 2, 2026
Merged

fix(modal): sub-anchor click closes the umbrella modal (E2E regression)#567
rdmueller merged 1 commit into
LLM-Coding:mainfrom
raifdmueller:fix/subanchor-modal-close

Conversation

@raifdmueller
Copy link
Copy Markdown
Contributor

@raifdmueller raifdmueller commented Jun 2, 2026

Problem

main's E2E suite is red: the "Umbrella Anchors › navigate to sub-anchor / show back button" tests fail because clicking a sub-anchor inside an umbrella modal closes the whole modal.

Root cause (two bugs combine)

  1. Latent: sub-anchor links render as <a href="#" data-sub-anchor>, which the AsciiDoc cross-reference handler (a[href^="#"]) also matched. A sub-anchor click thus fired both its own handler and a bogus navigate('/anchor/') (empty id).
  2. feat(analytics): count anchor opens via card click + fix modal back-button #565: the modal now closes when a non-anchor route resolves. handleRoute strips the trailing slash so '/anchor/''/anchor', which is not an anchor route → closeOpenAnchorModal() closed the umbrella modal.

Before #565 the bogus navigation was harmless, so this only surfaced now.

Fix

Exclude [data-sub-anchor] links from the cross-reference handler and ignore empty ids. Sub-anchor clicks now only load the sub-anchor; the modal and its back button stay put.

contentEl.querySelectorAll('a[href^="#"]:not([data-sub-anchor])').forEach(...)
// + skip empty anchorId

Verification

  • Reproduced the exact failure, then confirmed the fix in a preview: after a sub-anchor click the URL stays /anchor/gof-design-patterns, the modal stays open, the back button is visible.
  • Full E2E suite green locally (35/35), including the two tests that regressed. 98 unit tests pass; lint + prettier clean.

Priority: unblocks main (E2E currently failing) and the open analytics PR #566.

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Verbesserte Behandlung von internen Anker-Links beim DOM-Scanning, um Konflikte mit separaten Sub-Anchor-Links zu vermeiden.
    • Verfeinerte Validierung von Anker-ID-Ausdrücken mit zusätzlichen Sicherheitsmechanismen gegen ungültige oder leere Werte.

Sub-anchor links render as <a href="#" data-sub-anchor>, which were also
matched by the AsciiDoc cross-reference handler (a[href^="#"]). Clicking a
sub-anchor therefore fired both its own handler AND a bogus
navigate('/anchor/') with an empty id. Harmless before, but since the
modal now closes when a non-anchor route resolves (LLM-Coding#565), handleRoute
normalizes '/anchor/' → '/anchor' (not an anchor route) and closed the
umbrella modal — breaking the "navigate to sub-anchor / show back button"
E2E tests.

Exclude data-sub-anchor links from the cross-reference handler and ignore
empty ids, so sub-anchor clicks only load the sub-anchor and the modal +
back button stay put.

Verified: full E2E suite (35) green locally, incl. the two umbrella tests
that regressed.

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

coderabbitai Bot commented Jun 2, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 8f3a88bb-faf9-49ad-94d1-4fe00cb95100

📥 Commits

Reviewing files that changed from the base of the PR and between 55ce9e7 and 1baa45c.

📒 Files selected for processing (1)
  • website/src/components/anchor-modal.js

Walkthrough

Der PR verfeinert die Logik zum Umwandeln interner AsciiDoc-Cross-Reference-Links in Router-Navigation. Der DOM-Selektor wird um einen Filter erweitert, der Sub-Anchor-Elemente ausschließt, und die Validierung wird verschärft, um leere oder Hash-Route-Format-Links zu ignorieren.

Änderungen

Anchor-Link-Verarbeitung

Layer / Datei(en) Zusammenfassung
Anchor-Link-Selector und Validierungsguards
website/src/components/anchor-modal.js
Der CSS-Selektor wird von a[href^="#"] auf a[href^="#"]:not([data-sub-anchor]) verfeinert, um Sub-Anchor-Elemente auszuschließen. Validierungsguards werden hinzugefügt, die nur nicht-leere echte Anchor-IDs (nicht Hash-Routen #/...) verarbeiten.

Geschätzter Code-Review-Aufwand

🎯 2 (Einfach) | ⏱️ ~8 Minuten

Möglicherweise verwandte PRs

  • LLM-Coding/Semantic-Anchors#107: Beide PRs modifizieren website/src/components/anchor-modal.js an derselben Stelle bezüglich der Extrahierung und Validierung von Anchor-IDs aus Anchor-Links.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Der Titel beschreibt präzise die Hauptänderung: Behebung eines E2E-Regressions-Bugs, bei dem Sub-Anchor-Klicks die modale Umbrella-Komponente falsch schlossen.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Collaborator

@JensGrote JensGrote left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Nice root-cause analysis in the description. The double-guard (:not([data-sub-anchor]) selector + if (!anchorId) return) is solid defensive coding — even if one mechanism is bypassed, the other catches it.

Verified that data-sub-anchor is set internally in renderSubAnchorList() (line 150) and handled in the same file (line 258), so the coupling is tight and unlikely to break silently.

@rdmueller rdmueller merged commit 36433af into LLM-Coding:main Jun 2, 2026
7 checks passed
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.

3 participants