fix(docs): sync claude-structure accessibility improvements#1342
fix(docs): sync claude-structure accessibility improvements#1342Tenormusica2024 wants to merge 4 commits intoaffaan-m:mainfrom
Conversation
Add interactive ~/.claude directory structure visualization with Mermaid diagrams. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Jekyll was failing on Liquid syntax in markdown files. Static deployment doesn't need Jekyll. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ss improvements Mirrors fixes from claude-code-hooks: SRI, CDN fallback, aria-labels, classDef application, agent count correction, idempotent init. Co-Authored-By: Claude <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Greptile SummaryThis PR adds All previously raised concerns (touch/mobile support, window-level listener accumulation, and the global SVG retry check) remain open; no new P0/P1 issues were found in this iteration. Confidence Score: 5/5Safe to merge; all remaining findings are P2 suggestions that do not block correct rendering for the intended desktop audience. No P0 or P1 defects were found. The two new comments are P2: a reminder to verify the SRI hash and a defensive try/catch for getBBox(). The previously flagged concerns around touch support and window listeners are also P2 quality improvements, not correctness blockers. docs/claude-structure.html — confirm SRI hash matches the CDN file before the page goes live. Important Files Changed
Reviews (2): Last reviewed commit: "refactor(docs): sync CFG config object e..." | Re-trigger Greptile |
| this.vp.addEventListener('mousedown', e => { | ||
| if (e.button !== 0 || e.target.closest('.ztb')) return; | ||
| this.drag = true; | ||
| this.ox = e.clientX; this.oy = e.clientY; | ||
| this.sx = this.x; this.sy = this.y; | ||
| this.vp.classList.add('panning'); | ||
| e.preventDefault(); | ||
| }); | ||
| window.addEventListener('mousemove', e => { | ||
| if (!this.drag) return; | ||
| this.x = this.sx + (e.clientX - this.ox); | ||
| this.y = this.sy + (e.clientY - this.oy); | ||
| this._apply(); | ||
| }); | ||
| window.addEventListener('mouseup', () => { | ||
| if (!this.drag) return; | ||
| this.drag = false; | ||
| this.vp.classList.remove('panning'); | ||
| }); |
There was a problem hiding this comment.
Window event listeners accumulate across panel instances
_bind() attaches mousemove and mouseup listeners directly to window for each ZoomPan instance. With 6 panels all initialised, 12 window-level handlers fire on every single mouse move across the page. Each one only short-circuits via if (!this.drag) return, but the overhead compounds on lower-end devices.
Consider attaching these once at the class level, or moving them onto this.vp with setPointerCapture (which also solves the mobile gap above) so the listeners are scoped to the active viewport instead of the global window.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
docs/claude-structure.html (1)
627-636: Add guards inshowPanelto prevent runtime crashes on invalid inputs.
document.getElementById('panel-' + name)andbtnare dereferenced without checks; one bad call can break tab switching.Defensive guard
function showPanel(name, btn) { + const panel = document.getElementById('panel-' + name); + if (!panel || !btn) return; document.querySelectorAll('.panel').forEach(p => p.classList.remove('active')); document.querySelectorAll('.tab').forEach(t => t.classList.remove('active')); - document.getElementById('panel-' + name).classList.add('active'); + panel.classList.add('active'); btn.classList.add('active');🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/claude-structure.html` around lines 627 - 636, The showPanel function dereferences document.getElementById('panel-'+name) and btn without checks which can throw; add defensive guards at the start of showPanel to validate that name is a non-empty string, that document.getElementById('panel-'+name) returns a non-null element, and that btn is a DOM element before proceeding; if any check fails, return early (no-op) to avoid runtime crashes, and only instantiate zp[name] = new ZoomPan(name) and call zp[name].fit() after confirming the panel element exists.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/claude-structure.html`:
- Line 483: Replace the direct assignment to document.body.innerHTML
(document.body.innerHTML = '...') with safe DOM APIs: create the container
element via document.createElement, set its text via textContent (not
innerHTML), apply styles via element.style or classList, and append it to
document.body with appendChild; ensure any dynamic parts are escaped or
sanitized before setting textContent and remove usage of innerHTML to satisfy
XSS prevention requirements.
- Around line 7-10: The mermaid <script> currently sets
window.__mermaidFailed=true onerror but lacks a fallback and also uses innerHTML
to show the error; update the loader to attempt a secondary CDN (or local)
script when window.__mermaidFailed is true and only show the error banner if
both loads fail, and replace any use of innerHTML for that banner (the code that
writes the banner when window.__mermaidFailed is set) with safe DOM APIs (e.g.,
createElement/appendChild and setting textContent) so the failure is recoverable
and not vulnerable to XSS.
---
Nitpick comments:
In `@docs/claude-structure.html`:
- Around line 627-636: The showPanel function dereferences
document.getElementById('panel-'+name) and btn without checks which can throw;
add defensive guards at the start of showPanel to validate that name is a
non-empty string, that document.getElementById('panel-'+name) returns a non-null
element, and that btn is a DOM element before proceeding; if any check fails,
return early (no-op) to avoid runtime crashes, and only instantiate zp[name] =
new ZoomPan(name) and call zp[name].fit() after confirming the panel element
exists.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: d4bde6cf-5df6-48b6-82a6-58c05bd07cf2
📒 Files selected for processing (2)
docs/.nojekylldocs/claude-structure.html
| <script src="https://cdn.jsdelivr.net/npm/mermaid@10.9.3/dist/mermaid.min.js" | ||
| integrity="sha384-R63zfMfSwJF4xCR11wXii+QUsbiBIdiDzDbtxia72oGWfkT7WHJfmD/I/eeHPJyT" | ||
| crossorigin="anonymous" | ||
| onerror="window.__mermaidFailed=true"></script> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
file="docs/claude-structure.html"
echo "[Check 1] Mermaid include and fail branch:"
rg -n "mermaid.min.js|__mermaidFailed|onerror=" "$file"
echo "[Check 2] Fallback loader indicators (expected if fallback exists):"
rg -n "createElement\\(['\"]script['\"]\\)|appendChild\\(|unpkg|cdnjs|fallback" "$file" || trueRepository: affaan-m/everything-claude-code
Length of output: 468
🏁 Script executed:
cat -n docs/claude-structure.html | sed -n '480,490p'Repository: affaan-m/everything-claude-code
Length of output: 542
Mermaid fallback is not implemented; current path is hard failure.
Line 10 only sets a failure flag, and lines 481–485 render an error banner via innerHTML. There is no secondary CDN or local script load. Additionally, using innerHTML at line 483 violates XSS prevention guidelines; use textContent or DOM APIs instead.
Suggested fix (add secondary source and use safe DOM methods)
-if (window.__mermaidFailed || typeof mermaid === 'undefined') {
- document.addEventListener('DOMContentLoaded', () => {
- document.body.innerHTML = '<p style="color:`#f85149`;padding:2rem;font-family:sans-serif">Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。</p>';
- });
-} else {
-mermaid.initialize({
+function showMermaidLoadError() {
+ document.addEventListener('DOMContentLoaded', () => {
+ const p = document.createElement('p');
+ p.style.color = '#f85149';
+ p.style.padding = '2rem';
+ p.style.fontFamily = 'sans-serif';
+ p.textContent = 'Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。';
+ document.body.replaceChildren(p);
+ });
+}
+
+function initMermaid() {
+ mermaid.initialize({
startOnLoad: true,
theme: 'dark',
themeVariables: {
@@
flowchart: {
@@
}
-});
-} // end mermaid guard
+ });
+}
+
+if (window.__mermaidFailed || typeof mermaid === 'undefined') {
+ const fallback = document.createElement('script');
+ fallback.src = 'https://unpkg.com/mermaid@10.9.3/dist/mermaid.min.js';
+ fallback.crossOrigin = 'anonymous';
+ fallback.onload = () => (typeof mermaid !== 'undefined' ? initMermaid() : showMermaidLoadError());
+ fallback.onerror = showMermaidLoadError;
+ document.head.appendChild(fallback);
+} else {
+ initMermaid();
+} // end mermaid guard🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/claude-structure.html` around lines 7 - 10, The mermaid <script>
currently sets window.__mermaidFailed=true onerror but lacks a fallback and also
uses innerHTML to show the error; update the loader to attempt a secondary CDN
(or local) script when window.__mermaidFailed is true and only show the error
banner if both loads fail, and replace any use of innerHTML for that banner (the
code that writes the banner when window.__mermaidFailed is set) with safe DOM
APIs (e.g., createElement/appendChild and setting textContent) so the failure is
recoverable and not vulnerable to XSS.
| <script> | ||
| if (window.__mermaidFailed || typeof mermaid === 'undefined') { | ||
| document.addEventListener('DOMContentLoaded', () => { | ||
| document.body.innerHTML = '<p style="color:#f85149;padding:2rem;font-family:sans-serif">Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。</p>'; |
There was a problem hiding this comment.
Avoid innerHTML for error rendering; use safe DOM APIs.
Even with static content, this introduces an unsafe output pattern and bypasses sanitization discipline.
Safe replacement
- document.body.innerHTML = '<p style="color:`#f85149`;padding:2rem;font-family:sans-serif">Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。</p>';
+ const p = document.createElement('p');
+ p.style.color = '#f85149';
+ p.style.padding = '2rem';
+ p.style.fontFamily = 'sans-serif';
+ p.textContent = 'Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。';
+ document.body.replaceChildren(p);As per coding guidelines: "Implement XSS prevention by sanitizing HTML output".
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| document.body.innerHTML = '<p style="color:#f85149;padding:2rem;font-family:sans-serif">Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。</p>'; | |
| const p = document.createElement('p'); | |
| p.style.color = '#f85149'; | |
| p.style.padding = '2rem'; | |
| p.style.fontFamily = 'sans-serif'; | |
| p.textContent = 'Mermaid CDN の読み込みに失敗しました。ネットワーク接続を確認してリロードしてください。'; | |
| document.body.replaceChildren(p); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/claude-structure.html` at line 483, Replace the direct assignment to
document.body.innerHTML (document.body.innerHTML = '...') with safe DOM APIs:
create the container element via document.createElement, set its text via
textContent (not innerHTML), apply styles via element.style or classList, and
append it to document.body with appendChild; ensure any dynamic parts are
escaped or sanitized before setting textContent and remove usage of innerHTML to
satisfy XSS prevention requirements.
Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
docs/claude-structure.html (1)
7-10:⚠️ Potential issue | 🟠 MajorMermaid fallback CDN and safe error rendering remain unaddressed.
Both issues from the previous review are still present:
- No secondary CDN is attempted when the primary CDN fails at line 10
- Line 483 uses
innerHTMLfor the error message instead of safe DOM APIsAs per coding guidelines: "Implement XSS prevention by sanitizing HTML output".
Also applies to: 481-511
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/claude-structure.html` around lines 7 - 10, Add a resilient Mermaid loader: update the script onerror handler (where window.__mermaidFailed is set) to attempt loading a secondary CDN URL (and optionally a local copy) before giving up, and expose/consume that retry state in the existing Mermaid init logic so the page still initializes if a fallback succeeds. Replace any use of element.innerHTML in the error/display path (the block around lines 481–511 that currently writes the error message) with safe DOM APIs—use textContent or createTextNode for plain text and, if HTML markup is required, sanitize it with a trusted sanitizer (e.g., DOMPurify) before inserting via DOM methods; ensure you reference the same element/id the current code mutates and remove direct innerHTML assignments.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@docs/claude-structure.html`:
- Around line 569-570: The code incorrectly reads non-existent SVG properties
scrollWidth/scrollHeight from the svg variable; replace those checks with valid
SVG measurements (e.g., use svg.clientWidth/clientHeight for rendered sizes, or
for an <svg> element read svg.width.baseVal.value and svg.height.baseVal.value,
and fall back to svg.getBBox().width / svg.getBBox().height if needed) so that
the width/height calculations use actual SVG properties instead of always
falling back to getBBox().
---
Duplicate comments:
In `@docs/claude-structure.html`:
- Around line 7-10: Add a resilient Mermaid loader: update the script onerror
handler (where window.__mermaidFailed is set) to attempt loading a secondary CDN
URL (and optionally a local copy) before giving up, and expose/consume that
retry state in the existing Mermaid init logic so the page still initializes if
a fallback succeeds. Replace any use of element.innerHTML in the error/display
path (the block around lines 481–511 that currently writes the error message)
with safe DOM APIs—use textContent or createTextNode for plain text and, if HTML
markup is required, sanitize it with a trusted sanitizer (e.g., DOMPurify)
before inserting via DOM methods; ensure you reference the same element/id the
current code mutates and remove direct innerHTML assignments.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: e469a7dd-721e-462f-b159-cff2d0fb4f8e
📒 Files selected for processing (1)
docs/claude-structure.html
| const sw = svg.scrollWidth || svg.getBBox().width; | ||
| const sh = svg.scrollHeight || svg.getBBox().height; |
There was a problem hiding this comment.
SVG elements don't have scrollWidth/scrollHeight properties.
Lines 569-570 attempt to read scrollWidth and scrollHeight from an SVG element, but these properties only exist on HTML elements with scrollable overflow. The values will always be undefined, causing the fallback to getBBox() to always be used.
🔧 Clearer measurement approach
Use properties that actually exist on SVG elements:
- const sw = svg.scrollWidth || svg.getBBox().width;
- const sh = svg.scrollHeight || svg.getBBox().height;
+ const bbox = svg.getBBox();
+ const sw = bbox.width;
+ const sh = bbox.height;Or if you want to try clientWidth/clientHeight first:
- const sw = svg.scrollWidth || svg.getBBox().width;
- const sh = svg.scrollHeight || svg.getBBox().height;
+ const bbox = svg.getBBox();
+ const sw = svg.clientWidth || bbox.width;
+ const sh = svg.clientHeight || bbox.height;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const sw = svg.scrollWidth || svg.getBBox().width; | |
| const sh = svg.scrollHeight || svg.getBBox().height; | |
| const bbox = svg.getBBox(); | |
| const sw = bbox.width; | |
| const sh = bbox.height; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@docs/claude-structure.html` around lines 569 - 570, The code incorrectly
reads non-existent SVG properties scrollWidth/scrollHeight from the svg
variable; replace those checks with valid SVG measurements (e.g., use
svg.clientWidth/clientHeight for rendered sizes, or for an <svg> element read
svg.width.baseVal.value and svg.height.baseVal.value, and fall back to
svg.getBBox().width / svg.getBBox().height if needed) so that the width/height
calculations use actual SVG properties instead of always falling back to
getBBox().
|
Tip: Greploop — Automatically fix all review issues by running Use the Greptile plugin for Claude Code to query reviews, search comments, and manage custom context directly from your terminal. |
Summary
Test plan
🤖 Generated with Claude Code
Summary by cubic
Syncs
docs/claude-structure.htmlwith accessibility and robustness fixes fromclaude-code-hooks, plus a small config refactor for easier maintenance. Also adds.nojekyllso GitHub Pages serves static files without Jekyll.Bug Fixes
mermaidCDN and a graceful fallback if the CDN fails.aria-labels; ignore toolbar when panning.classDefstyles consistently across all panels.docs/.nojekyllto disable Jekyll on GitHub Pages.Refactors
CFGobject, synced withclaude-code-hooks.Written for commit 3f913ef. Summary will update on new commits.
Summary by CodeRabbit