Skip to content

Fix search broken when HTML saved with different filename#106

Merged
cboos merged 2 commits intodaaain:mainfrom
moshethebeadle:fix/isIndexPage-detection
Apr 12, 2026
Merged

Fix search broken when HTML saved with different filename#106
cboos merged 2 commits intodaaain:mainfrom
moshethebeadle:fix/isIndexPage-detection

Conversation

@moshethebeadle
Copy link
Copy Markdown
Contributor

@moshethebeadle moshethebeadle commented Apr 1, 2026

Summary

  • The isIndexPage detection in search relied on window.location.pathname matching specific URL patterns (index.html, projects/, etc.)
  • When the generated HTML is saved/downloaded with a different filename (e.g. browser "Save As"), the detection fails and search indexes zero items, completely breaking search functionality
  • Replaced URL-based detection with DOM-based detection (document.querySelectorAll('.project-card').length > 0), which correctly identifies the page type regardless of filename or serving context

Test plan

  • Generate an index page and verify search works normally
  • Save the index page with a different filename (e.g. "My Projects.html") and verify search still works
  • Verify search still works on transcript pages (non-index pages)
  • Run existing snapshot tests (snapshot will need updating)

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • More reliable page detection for search so index pages show grouped project/session results and transcript pages highlight messages in-place; result-panel display, navigation, and transcript linking behave correctly.
    • Transcript pages now re-index when filters change, ensuring search results stay up to date and only when applicable.
  • Style

    • Minor snapshot/CSS adjustments affecting error/display formatting.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 1, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: bd6d3650-1008-4c26-8b3a-e4432e198d85

📥 Commits

Reviewing files that changed from the base of the PR and between be1e932 and e92f2c5.

📒 Files selected for processing (2)
  • claude_code_log/html/templates/components/search.html
  • test/__snapshots__/test_snapshot_html.ambr
🚧 Files skipped from review as they are similar to previous changes (2)
  • claude_code_log/html/templates/components/search.html
  • test/snapshots/test_snapshot_html.ambr

📝 Walkthrough

Walkthrough

Set page-type detection to runtime: searchState.isIndexPage is initialized as null and assigned in initSearch() using a DOM probe (document.querySelector('.project-list') !== null). Transcript filter re-index observer logic was extracted to setupTranscriptFilterObserver() and is registered from initSearch() for non-index pages.

Changes

Cohort / File(s) Summary
Search component
claude_code_log/html/templates/components/search.html
Initialize searchState.isIndexPage as null, set it during initSearch() via DOM check; move transcript filter MutationObserver setup into setupTranscriptFilterObserver() and invoke it only when isIndexPage is false.
Test snapshot
test/__snapshots__/test_snapshot_html.ambr
Updated snapshot to reflect isIndexPage: null initialization, DOM-based assignment in initSearch(), and presence of setupTranscriptFilterObserver(); snapshot contents adjusted accordingly.

Sequence Diagram(s)

sequenceDiagram
    participant Init as initSearch()
    participant DOM as Document
    participant State as searchState
    participant Index as IndexBuilder/Results
    participant Observer as setupTranscriptFilterObserver()

    Init->>DOM: querySelector('.project-list')
    DOM-->>Init: element or null
    Init->>State: set isIndexPage = (found)
    alt isIndexPage == true
        Init->>Index: build index / initialize search UI
        Index-->>State: index ready
    else isIndexPage == false
        Init->>Observer: call setupTranscriptFilterObserver()
        Observer->>Observer: attach MutationObserver (filters/classes)
        Observer->>Index: trigger rebuild index + performSearch() on filter changes
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐇 I nudged the DOM with a gentle paw,
I check for lists instead of reading law,
When transcripts shift I watch and hop,
Rebuild the index — then never stop,
Tiny hops, big finds, a searcher’s awe.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main fix: replacing URL-based page type detection with DOM-based detection to enable search to work when HTML is saved with different filenames.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ 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

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@claude_code_log/html/templates/components/search.html`:
- Line 57: The isIndexPage detection currently uses
document.querySelectorAll('.project-card').length > 0 which fails when the index
contains zero projects; update the logic in the code that sets isIndexPage to
check for a stable container marker (for example
document.querySelector('.project-list') !== null) or combine both checks (e.g.,
document.querySelector('.project-list') !== null ||
document.querySelectorAll('.project-card').length > 0) so an empty index still
returns true; modify the assignment where isIndexPage is defined to use the new
combined/stable check.
🪄 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: e869cd67-b737-4481-8a62-105f0e599a0a

📥 Commits

Reviewing files that changed from the base of the PR and between f38e228 and af47fa1.

📒 Files selected for processing (1)
  • claude_code_log/html/templates/components/search.html

@moshethebeadle moshethebeadle force-pushed the fix/isIndexPage-detection branch from af47fa1 to 5ac133d Compare April 1, 2026 16:31
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
claude_code_log/html/templates/components/search.html (1)

77-79: ⚠️ Potential issue | 🟠 Major

.project-card-only detection still breaks empty index pages

Line 78 still treats an empty index page as non-index, so search falls into transcript logic when there are zero projects. Use a stable marker that exists even when the project list is empty.

Proposed fix
-        searchState.isIndexPage = document.querySelectorAll('.project-card').length > 0;
+        // Works for both populated and empty index pages
+        searchState.isIndexPage = !!document.querySelector('.project-list, .project-card');
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@claude_code_log/html/templates/components/search.html` around lines 77 - 79,
The detection using document.querySelectorAll('.project-card') fails on empty
index pages; update the assignment to searchState.isIndexPage in the search.html
snippet to check for a stable container or marker that exists even when there
are zero projects (e.g., a wrapper element like '.project-list' or an
ID/data-attribute added to the index template) instead of '.project-card' so
empty indexes are still recognized as index pages; modify the selector used in
the searchState.isIndexPage line accordingly (replace '.project-card' with the
stable marker you have in the templates).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@claude_code_log/html/templates/components/search.html`:
- Line 57: The pre-init check runs because searchState.isIndexPage is
initialized to null, so the top-level condition if (!searchState.isIndexPage)
triggers before initSearch() sets the real value; change the initialization of
isIndexPage from null to undefined (or remove the explicit null) and update the
top-level check to explicitly test for false (e.g., if (searchState.isIndexPage
=== false)) so the transcript-only observers only register when the page is
known to be a non-index page; adjust references to isIndexPage, the searchState
object, and the initSearch() flow accordingly.

---

Duplicate comments:
In `@claude_code_log/html/templates/components/search.html`:
- Around line 77-79: The detection using
document.querySelectorAll('.project-card') fails on empty index pages; update
the assignment to searchState.isIndexPage in the search.html snippet to check
for a stable container or marker that exists even when there are zero projects
(e.g., a wrapper element like '.project-list' or an ID/data-attribute added to
the index template) instead of '.project-card' so empty indexes are still
recognized as index pages; modify the selector used in the
searchState.isIndexPage line accordingly (replace '.project-card' with the
stable marker you have in the templates).
🪄 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: 9b746aaf-7d96-4cef-8b84-2444b171f724

📥 Commits

Reviewing files that changed from the base of the PR and between af47fa1 and 5ac133d.

📒 Files selected for processing (1)
  • claude_code_log/html/templates/components/search.html

The isIndexPage detection relied on window.location.pathname matching
specific patterns (index.html, projects/, etc.). When the generated HTML
is downloaded or saved with a different filename, the detection fails and
search indexes zero items, breaking search entirely.

Replace URL-based detection with DOM-based detection by checking for the
.project-list container element. The check is deferred to initSearch()
(which runs on DOMContentLoaded) so the DOM elements exist by the time
it executes. Using .project-list rather than .project-card ensures it
works even when the index has zero projects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@moshethebeadle moshethebeadle force-pushed the fix/isIndexPage-detection branch from 5ac133d to d1e814e Compare April 1, 2026 16:36
@daaain
Copy link
Copy Markdown
Owner

daaain commented Apr 1, 2026

Hey @moshethebeadle, thanks a lot for this fix!

I had a look and all the other usage of isIndexPage happens after (or invoked by) initSearch except the if (!searchState.isIndexPage) the bunny highlighted, so once you fix that we should be good.

I approved the tests and the snapshots will need to be updated once you're ready to get them green.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/__snapshots__/test_snapshot_html.ambr`:
- Around line 10928-10937: The snapshot contains corrupted/truncated JavaScript
in the ancestor filtering logic: restore the truncated method call on classList
to use cls.startsWith('d-') when building ancestorIds and remove the duplicated
lines so the filter callback returns lastAncestor === targetId exactly once;
specifically fix the code around the ancestorIds computation and the isFolded
check (refer to symbols classList, cls.startsWith, ancestorIds, lastAncestor,
targetId, isFolded) to match the original template logic from transcript.html so
the snapshot parses correctly.
- Around line 7300-7305: The snapshot test file test_snapshot_html.ambr contains
corrupted CSS around the .system-error rule (unclosed comments and stray brace);
regenerate the failing snapshot so it matches the source template's correct CSS
(ensure the comment blocks are closed and the .system-error rule is intact as in
the template), then run the snapshot update command (e.g., the test runner's
snapshot update) to replace the corrupted lines with the correct content.
🪄 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: d2f762f3-bf6a-4101-b82c-4417bd67d353

📥 Commits

Reviewing files that changed from the base of the PR and between d1e814e and be1e932.

📒 Files selected for processing (2)
  • claude_code_log/html/templates/components/search.html
  • test/__snapshots__/test_snapshot_html.ambr
🚧 Files skipped from review as they are similar to previous changes (1)
  • claude_code_log/html/templates/components/search.html

Comment on lines 7300 to 7305
/* System error messages }

/* Left-aligned m .system-error {
margin-left: 0;
margin-right: 8em;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check the source template for the .system-error CSS to verify it's not corrupted there
rg -n -A3 -B3 'system-error' --type html

Repository: daaain/claude-code-log

Length of output: 6076


🏁 Script executed:

sed -n '7295,7310p' test/__snapshots__/test_snapshot_html.ambr

Repository: daaain/claude-code-log

Length of output: 454


Regenerate snapshot - corrupted CSS content

The snapshot file contains malformed CSS at these lines. Source templates show correct content (e.g., line 426 in transcript_style_guide.html has properly formatted .system-error rule with closed comment), but the snapshot captured corrupted/truncated versions:

  • Line 7300: Unclosed comment /* System error messages } with stray }
  • Line 7302: Truncated comment text /* Left-aligned m followed by .system-error {

Regenerate this snapshot to fix the corruption.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/__snapshots__/test_snapshot_html.ambr` around lines 7300 - 7305, The
snapshot test file test_snapshot_html.ambr contains corrupted CSS around the
.system-error rule (unclosed comments and stray brace); regenerate the failing
snapshot so it matches the source template's correct CSS (ensure the comment
blocks are closed and the .system-error rule is intact as in the template), then
run the snapshot update command (e.g., the test runner's snapshot update) to
replace the corrupted lines with the correct content.

The `if (!searchState.isIndexPage)` block ran at parse time when
isIndexPage was still null, causing transcript-only MutationObservers
to register on index pages too.

Extract the observer setup into setupTranscriptFilterObserver() and
call it from initSearch() after isIndexPage is properly determined.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cboos cboos force-pushed the fix/isIndexPage-detection branch from be1e932 to e92f2c5 Compare April 11, 2026 16:46
@cboos
Copy link
Copy Markdown
Collaborator

cboos commented Apr 11, 2026

I apologize for the confusion with Git. I didn't intend to push to the branch moshethebeadle:fix/isIndexPage-detection, so I created PR #108. However, it seems that the command gh pr checkout set things up in a way that led me here anyway. And Claude Code is just too trigger happy with push these days ;-)

I tested everything locally, and it appears to be working fine.

@cboos cboos merged commit 6daa89b into daaain:main Apr 12, 2026
11 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