Skip to content

Add line numbers and permalink anchors to files#193

Merged
simonw merged 4 commits intomainfrom
claude/add-line-number-permalinks-FxgjG
Dec 30, 2025
Merged

Add line numbers and permalink anchors to files#193
simonw merged 4 commits intomainfrom
claude/add-line-number-permalinks-FxgjG

Conversation

@simonw
Copy link
Owner

@simonw simonw commented Dec 30, 2025

Upgrade zip-wheel-explorer so it shows line numbers for exery displayed text file, and each line number is a permalink which you can click that then adds #filename--L33 or similar to the URL, and when the page loads if that fragment is present the specified file is shown and the line number is jumped to and the line is highlighted.

Also make each filename have a # icon next to it which targets #filename and can also be used as a link like that

Actually no need for a # icon next to filenames, just make it so when the user selects a file to open and read that sets the #fragment in the URL for that file, and clicking a line number does that for that line too

make sure the line numbers do not intefere with the user's ability to copy and paste blocks of those files without including the line numbers in them

  • Display line numbers for all text files with a table-based layout
  • Each line number is a clickable permalink that updates URL fragment
  • Fragment format: #filename--L33 for specific lines, #filename for files
  • Clicking a file updates the URL fragment to that file
  • Page loads with fragment auto-open the file and highlight the line
  • Line numbers use user-select: none to prevent copy/paste interference
  • Highlighted lines have a yellow background for visibility

- Display line numbers for all text files with a table-based layout
- Each line number is a clickable permalink that updates URL fragment
- Fragment format: #filename--L33 for specific lines, #filename for files
- Clicking a file updates the URL fragment to that file
- Page loads with fragment auto-open the file and highlight the line
- Line numbers use user-select: none to prevent copy/paste interference
- Highlighted lines have a yellow background for visibility
@claude
Copy link
Contributor

claude bot commented Dec 30, 2025

Claude Code is working…

I'll analyze this and get back to you.

View job run

@simonw
Copy link
Owner Author

simonw commented Dec 30, 2025

It doesn't quite work - loading https://db59d83b.tools-b1q.pages.dev/zip-wheel-explorer?package=llm#llm/embeddings_migrations.py--L13 in a browser instantly redirects to https://db59d83b.tools-b1q.pages.dev/zip-wheel-explorer?package=llm when the package finishes loading, losing the fragment.

Also the line numbers need to be a tiny bit smaller and need a bit of right padding

- Preserve existing URL fragment when package finishes loading
- Make line numbers slightly smaller (0.75rem)
- Increase right padding on line numbers (1rem)
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Dec 30, 2025

Deploying tools with  Cloudflare Pages  Cloudflare Pages

Latest commit: a680f3f
Status: ✅  Deploy successful!
Preview URL: https://89031803.tools-b1q.pages.dev
Branch Preview URL: https://claude-add-line-number-perma.tools-b1q.pages.dev

View logs

@simonw
Copy link
Owner Author

simonw commented Dec 30, 2025

This is what I mean about the line numbers:

CleanShot 2025-12-30 at 13 59 02@2x

@claude
Copy link
Contributor

claude bot commented Dec 30, 2025

Claude finished @simonw's task —— View job


Code Review Results

  • Read repository guidelines (CLAUDE.md) - No repo-specific guidelines found
  • Analyze the modified zip-wheel-explorer.html file
  • Review code quality and best practices
  • Check for potential bugs and issues
  • Evaluate performance considerations
  • Assess security concerns
  • Review test coverage
  • Address specific issues mentioned in comments

Overall Assessment

The implementation successfully adds line number permalinks to the zip-wheel-explorer. The code is well-structured and follows good practices, but there are several important issues that need attention.

🐛 Critical Issues Found

1. Fragment Preservation Bug (zip-wheel-explorer.html:343-345)

The fragment gets lost on page load because updateUrl() is called during file loading:

// This overwrites the fragment during loading
const existingFragment = window.location.hash.slice(1);
updateUrl(input, existingFragment || null);

Fix: Only update URL if no fragment exists, or preserve it more carefully during the loading process.

2. Line Highlighting Logic Bug (zip-wheel-explorer.html:233)

The line highlighting selector is incorrect:

const row = document.querySelector(`.line-row:nth-child(${lineNum})`);

This should use the row ID for precision:

const rowId = `${encodeURIComponent(filename)}--L${lineNum}`;
const row = document.getElementById(rowId);

🎨 Styling Issues

1. Line Number Font Size (zip-wheel-explorer.html:125)

As noted in the screenshot, line numbers need to be smaller:

.line-num {
    font-size: 0.75rem; /* Current - too large */
    /* Should be: font-size: 0.7rem; */
}

2. Missing Right Padding (zip-wheel-explorer.html:122)

Line numbers need more right padding for better visual separation:

.line-num {
    padding: 0 1rem 0 0.5rem; /* Current */
    /* Should be: padding: 0 1.2rem 0 0.5rem; */
}

✅ Code Quality Highlights

  1. Clean Architecture: Good separation between URL handling, fragment parsing, and content rendering
  2. Accessibility: Proper use of user-select: none prevents line numbers from interfering with copy/paste (zip-wheel-explorer.html:124)
  3. Responsive Design: Table layout preserves formatting across different screen sizes
  4. URL Encoding: Proper handling of special characters in filenames (zip-wheel-explorer.html:188-195)

📊 Performance Considerations

  1. Efficient DOM Updates: Smart toggling logic avoids unnecessary DOM manipulation (zip-wheel-explorer.html:248-260)
  2. Event Delegation: Line number click handlers are added efficiently after content insertion
  3. Smooth Scrolling: Good UX with behavior: 'smooth' for navigation

🔒 Security Assessment

  1. XSS Protection: Consistent use of escapeHtml() for user content (zip-wheel-explorer.html:372-376)
  2. CSS Escaping: Proper CSS.escape() usage for selectors (zip-wheel-explorer.html:245)
  3. URL Safety: Safe encoding/decoding of URL fragments

🧪 Test Coverage

Missing: No automated tests detected. Consider adding:

  • Unit tests for fragment parsing/encoding functions
  • Integration tests for line number clicking behavior
  • Tests for edge cases (special characters in filenames, long files)

📋 Recommended Fixes

  1. High Priority: Fix fragment preservation during page load
  2. High Priority: Correct line highlighting selector logic
  3. Medium Priority: Adjust line number font size and padding
  4. Low Priority: Add error boundaries for malformed fragments

💡 Enhancement Suggestions

  1. Keyboard Navigation: Add arrow key support for line-by-line navigation
  2. Range Selection: Support #file--L10-L20 syntax for line ranges
  3. Syntax Highlighting: Consider adding basic syntax highlighting for common file types

The implementation demonstrates solid engineering practices with good attention to UX details like copy/paste behavior and smooth scrolling. The main issues are fixable bugs rather than architectural problems.


@simonw
Copy link
Owner Author

simonw commented Dec 30, 2025

Tweaked it in the developer tools:

Add padding-right: 4px; to the .line-num a in the CSS

@claude
Copy link
Contributor

claude bot commented Dec 30, 2025

Claude finished @simonw's task —— View job


Code Review Results

  • Read and analyze zip-wheel-explorer.html changes
  • Review code quality and best practices
  • Check for potential bugs and issues
  • Evaluate performance considerations
  • Assess security concerns
  • Review test coverage
  • Address specific issues mentioned in comments

Overall Assessment

The implementation successfully adds line number permalinks to the zip-wheel-explorer with a clean table-based layout. The code follows good practices overall, but there are several critical issues that need attention, particularly around fragment preservation and the recent styling feedback.

🐛 Critical Issues Found

1. Fragment Preservation Bug (zip-wheel-explorer.html:344-346)

The main issue reported by the user - fragment gets lost during page load because updateUrl() overwrites the fragment:

// This preserves fragment but updateUrl call in selectFile still overwrites it
const existingFragment = window.location.hash.slice(1);
updateUrl(input, existingFragment || null);

Root cause: selectFile() calls updateUrl() at line 285 which overwrites the preserved fragment during file loading.

Fix needed: Modify selectFile() to preserve existing fragments when updateHash is false, or delay URL updates until after fragment handling is complete.

2. Line Highlighting Selector Bug (zip-wheel-explorer.html:234)

The line highlighting uses an incorrect CSS selector:

const row = document.querySelector(`.line-row:nth-child(${lineNum})`);

Issue: nth-child counts from 1 but doesn't account for table structure. Should use the row ID instead:

const rowId = `${encodeURIComponent(filename)}--L${lineNum}`;
const row = document.getElementById(rowId);

🎨 Styling Issues

1. Line Number Right Padding (zip-wheel-explorer.html:134) ✅

Good news: The recent commit already implemented the requested padding-right: 4px; for .line-num a - this addresses the visual spacing issue shown in the screenshot.

2. Line Number Font Size Consideration

Current font-size is 0.75rem (line 125). From the screenshot, line numbers appear appropriately sized, but if further reduction is needed, consider 0.7rem.

✅ Code Quality Highlights

  1. Clean Architecture: Excellent separation between URL handling (encodeFragment, parseFragment), content rendering (formatContentWithLineNumbers), and user interaction (selectFile)

  2. Accessibility: Proper use of user-select: none prevents line numbers from interfering with copy/paste (zip-wheel-explorer.html:124)

  3. Semantic HTML: Table-based layout appropriately preserves text structure and formatting

  4. URL Encoding: Robust handling of special characters in filenames with proper encoding/decoding (zip-wheel-explorer.html:191-195)

  5. Event Handling: Clean event delegation with onclick handlers added after DOM insertion (zip-wheel-explorer.html:272-280)

🚀 Performance Considerations

Strengths:

  • Efficient DOM updates with smart toggling logic to avoid unnecessary operations (zip-wheel-explorer.html:249-261)
  • Minimal DOM queries using CSS.escape() for safe selectors (zip-wheel-explorer.html:246)
  • Smooth scrolling for better UX (zip-wheel-explorer.html:237, 289)

Potential Optimizations:

  • Line number generation could be optimized for very large files using document fragments
  • Consider virtualization for files with >1000 lines

🔒 Security Assessment

Strong Security Practices:

  • Consistent XSS protection using escapeHtml() for all user content (zip-wheel-explorer.html:221-223, 324, 328, 368)
  • Safe CSS selector handling with CSS.escape() (zip-wheel-explorer.html:246)
  • Proper URL encoding prevents injection through filename manipulation

No Security Concerns Identified: The implementation properly sanitizes all user inputs and dynamic content.

🧪 Test Coverage

Missing: No automated tests detected. Critical test scenarios needed:

  • Fragment parsing with special characters in filenames
  • Line number clicking behavior across different browsers
  • URL preservation during page navigation
  • Copy/paste functionality verification
  • Large file performance testing

📋 Priority Fixes Needed

  1. 🔥 High Priority: Fix fragment preservation during file loading - modify the URL update logic in selectFile() to preserve existing fragments
  2. 🔥 High Priority: Fix line highlighting to use row ID instead of nth-child selector
  3. Medium Priority: Consider adding error boundaries for malformed fragments
  4. Low Priority: Add automated tests for core functionality

💡 Enhancement Suggestions

  1. Keyboard Navigation: Add arrow key support for line-by-line navigation
  2. Range Selection: Support #file--L10-L20 syntax for highlighting line ranges
  3. Syntax Highlighting: Consider basic syntax highlighting for common file types
  4. Performance: Implement virtualization for very large files

📝 Implementation Notes

The core implementation is architecturally sound with good separation of concerns. The main issues are fixable bugs rather than fundamental design problems. The recent padding fix shows the styling is heading in the right direction.

The fragment preservation issue is the most critical as it breaks the core permalink functionality. Once fixed, this will be a robust and user-friendly file browser with excellent accessibility features.

@simonw
Copy link
Owner Author

simonw commented Dec 30, 2025

Pasted in some feedback from the Claude code review:

Should use this:

const rowId = `${encodeURIComponent(filename)}--L${lineNum}`;
const row = document.getElementById(rowId);

@claude
Copy link
Contributor

claude bot commented Dec 30, 2025

Claude finished @simonw's task —— View job


Code Review Results

  • Read and analyze zip-wheel-explorer.html changes
  • Review code quality and best practices
  • Check for potential bugs and issues
  • Evaluate performance considerations
  • Assess security concerns
  • Review test coverage
  • Address specific issues mentioned in comments

Overall Assessment

The implementation successfully adds line number permalinks to the zip-wheel-explorer with a clean table-based layout. The code follows good practices overall, but there are several critical issues that need attention, particularly around fragment preservation and the line highlighting bug mentioned in recent comments.

🐛 Critical Issues Found

1. Fragment Preservation Bug (zip-wheel-explorer.html:345-347)

Confirmed Issue: The main problem reported - fragments get lost during page load because updateUrl() overwrites the fragment:

// This preserves fragment but updateUrl call in selectFile still overwrites it
const existingFragment = window.location.hash.slice(1);
updateUrl(input, existingFragment || null);

Root cause: selectFile() calls updateUrl() at lines 285-286 which overwrites the preserved fragment during file loading.

Fix needed: The selectFile() function should check if updateHash is false and avoid calling updateUrl() in that case, or modify the URL update logic to preserve existing fragments when called from handleFragment().

2. Line Highlighting Selector Issue (zip-wheel-explorer.html:234-235)

Confirmed Critical Bug: As mentioned in the comments, the line highlighting uses getElementById(rowId) correctly, but this is actually fixed in the current code. The comment was about an older version that used nth-child. The current implementation at lines 234-235 is correct:

const rowId = `${encodeURIComponent(filename)}--L${lineNum}`;
const row = document.getElementById(rowId);

✅ Code Quality Highlights

  1. Clean Architecture: Excellent separation between URL handling (encodeFragment, parseFragment), content rendering (formatContentWithLineNumbers), and user interaction (selectFile)

  2. Accessibility: Proper use of user-select: none prevents line numbers from interfering with copy/paste (zip-wheel-explorer.html:124)

  3. Semantic HTML: Table-based layout appropriately preserves text structure and formatting

  4. URL Encoding: Robust handling of special characters in filenames with proper encoding/decoding (zip-wheel-explorer.html:189-195, 220)

  5. Event Handling: Clean event delegation with onclick handlers added after DOM insertion (zip-wheel-explorer.html:272-281)

  6. Styling: Recent padding fix padding-right: 4px addresses visual spacing concerns (zip-wheel-explorer.html:134)

🚀 Performance Considerations

Strengths:

  • Efficient DOM updates with smart toggling logic to avoid unnecessary operations (zip-wheel-explorer.html:250-262)
  • Minimal DOM queries using CSS.escape() for safe selectors (zip-wheel-explorer.html:247)
  • Smooth scrolling for better UX (zip-wheel-explorer.html:238, 290)

Potential Optimizations:

  • Line number generation could be optimized for very large files using document fragments
  • Consider virtualization for files with >1000 lines

🔒 Security Assessment

Strong Security Practices:

  • Consistent XSS protection using escapeHtml() for all user content (zip-wheel-explorer.html:221-223, 325, 329, 335, 340, 369)
  • Safe CSS selector handling with CSS.escape() (zip-wheel-explorer.html:247)
  • Proper URL encoding prevents injection through filename manipulation

No Security Concerns Identified: The implementation properly sanitizes all user inputs and dynamic content.

🧪 Test Coverage

Missing: No automated tests detected. Critical test scenarios needed:

  • Fragment parsing with special characters in filenames
  • Line number clicking behavior across different browsers
  • URL preservation during page navigation
  • Copy/paste functionality verification (ensuring line numbers aren't copied)
  • Large file performance testing

📋 Priority Fixes Needed

  1. 🔥 High Priority: Fix fragment preservation during file loading - the main bug causing fragments to be lost
  2. Medium Priority: Consider adding error boundaries for malformed fragments
  3. Low Priority: Add automated tests for core functionality

💡 Enhancement Suggestions

  1. Keyboard Navigation: Add arrow key support for line-by-line navigation
  2. Range Selection: Support #file--L10-L20 syntax for highlighting line ranges
  3. Syntax Highlighting: Consider basic syntax highlighting for common file types
  4. Performance: Implement virtualization for very large files

📝 Implementation Notes

The core implementation is architecturally sound with good separation of concerns. The line highlighting selector is actually correct in the current code (contrary to the comment which referenced an older version). The main issue is the fragment preservation bug during page load, which is breaking the permalink functionality when users load URLs with fragments directly.

The recent styling improvements show attention to UX details. Once the fragment preservation issue is resolved, this will be a robust and accessible file browser.


Analysis completed for PR #193: Add line numbers and permalink anchors to files

@simonw
Copy link
Owner Author

simonw commented Dec 30, 2025

@simonw simonw merged commit c934e96 into main Dec 30, 2025
2 of 4 checks passed
@simonw simonw deleted the claude/add-line-number-permalinks-FxgjG branch December 30, 2025 22:06
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.

2 participants