Skip to content

fix(file-annotator): fix upward autoscroll on search previous navigation#76

Merged
jansaldo merged 1 commit into
developfrom
fix/69-search-previous-autoscroll
May 22, 2026
Merged

fix(file-annotator): fix upward autoscroll on search previous navigation#76
jansaldo merged 1 commit into
developfrom
fix/69-search-previous-autoscroll

Conversation

@jansaldo
Copy link
Copy Markdown
Contributor

@jansaldo jansaldo commented May 20, 2026

Problema

Al buscar una palabra y navegar entre las ocurrencias, el botón de "subir" no hacía nada, solo el botón de "bajar" disparaba el autoscroll hacia la ocurrencia correspondiente.

La causa raíz tenía dos partes:

  1. La lógica de scroll usaba element.scrollIntoView(), que puede fallar silenciosamente al desplazarse hacia arriba dentro de un contenedor overflow-y: scroll en el renderer de Electron/Chromium.
  2. El paragraph.id usa el texto completo del párrafo como identificador, por lo que querySelector('[data-search-match-id="..."]') lanzaba un SyntaxError cuando el texto contenía caracteres especiales de CSS (", /, ,, etc.).

Solución

  • Se reemplazó scrollIntoView por un cálculo explícito con container.scrollBy() usando fileRef, garantizando un scroll confiable en ambas direcciones.
  • Se reemplazó la búsqueda por selector CSS por una comparación de atributo en el DOM (querySelectorAll + getAttribute), haciendo la búsqueda robusta sin importar los caracteres especiales en el ID del match.

Issue relacionado

Issue #69

Summary by Sourcery

Ensure the file annotator reliably auto-scrolls to the active search match when navigating between occurrences.

Bug Fixes:

  • Fix upward auto-scroll when navigating to the previous search match in the file annotator search results.
  • Handle search match lookup robustly when match IDs contain characters that break CSS attribute selectors.

@jansaldo jansaldo requested review from conrabeatriz and Copilot May 20, 2026 19:52
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented May 20, 2026

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adjusts the FileAnnotator search navigation autoscroll to work reliably in both directions by replacing scrollIntoView with explicit scrollBy math and making match lookup robust to special characters in IDs.

Sequence diagram for updated FileAnnotator search autoscroll

sequenceDiagram
  participant FileAnnotator
  participant Window
  participant Container
  participant Element

  FileAnnotator->>Window: setTimeout
  Window->>Container: querySelectorAll
  Window->>Element: getAttribute
  opt [no matching element or container]
    Window-->>FileAnnotator: return
  end
  Window->>Container: getBoundingClientRect
  Window->>Element: getBoundingClientRect
  Window->>Container: scrollBy
Loading

File-Level Changes

Change Details Files
Make search result autoscroll reliable in both directions within the file annotator container.
  • Replace a global CSS selector lookup for the active search match with a search limited to the file container using querySelectorAll and attribute comparison, avoiding CSS selector SyntaxError for special characters.
  • Guard against missing container or element before scrolling to prevent runtime errors.
  • Compute the vertical scroll offset manually based on container and element bounding rects so that the target element is centered in the container.
  • Use container.scrollBy with a smooth behavior instead of element.scrollIntoView to ensure consistent scrolling up and down in the Electron/Chromium renderer.
src/renderer/src/components/file-annotator/index.tsx

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • Instead of querying all [data-search-match-id] elements and filtering in JS, you could use CSS.escape(activeSearchMatchId) with the attribute selector (e.g. document.querySelector(`[data-search-match-id="${CSS.escape(activeSearchMatchId)}"]`)) to keep the lookup O(1) while safely handling special characters.
  • The scroll offset calculation assumes no transforms or padding on the scroll container; if those can vary, consider using element.offsetTop relative to the container’s scrollTop to compute the target position more robustly within the scrolling context.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Instead of querying all `[data-search-match-id]` elements and filtering in JS, you could use `CSS.escape(activeSearchMatchId)` with the attribute selector (e.g. ``document.querySelector(`[data-search-match-id="${CSS.escape(activeSearchMatchId)}"]`)``) to keep the lookup O(1) while safely handling special characters.
- The scroll offset calculation assumes no transforms or padding on the scroll container; if those can vary, consider using `element.offsetTop` relative to the container’s scrollTop to compute the target position more robustly within the scrolling context.

## Individual Comments

### Comment 1
<location path="src/renderer/src/components/file-annotator/index.tsx" line_range="187-188" />
<code_context>
+        containerRect.height / 2 +
+        elementRect.height / 2;
+
+      container.scrollBy({
+        top: scrollOffset,
         behavior: "smooth",
-        block: "center",
</code_context>
<issue_to_address>
**question (bug_risk):** Dropping horizontal scroll alignment may change behavior for horizontally scrollable content.

Previously, `scrollIntoView({ inline: "nearest" })` could adjust horizontal scroll for overflowed content. Now we only scroll vertically via `top`, so matches near the left/right edges may remain partially hidden in horizontally scrollable annotators. If horizontal overflow can occur here, consider adding horizontal alignment or confirm that this behavior change is acceptable.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +187 to +188
container.scrollBy({
top: scrollOffset,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

question (bug_risk): Dropping horizontal scroll alignment may change behavior for horizontally scrollable content.

Previously, scrollIntoView({ inline: "nearest" }) could adjust horizontal scroll for overflowed content. Now we only scroll vertically via top, so matches near the left/right edges may remain partially hidden in horizontally scrollable annotators. If horizontal overflow can occur here, consider adding horizontal alignment or confirm that this behavior change is acceptable.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes auto-scrolling in the file annotator search navigation so that moving to the previous match reliably scrolls upward, and match lookup no longer breaks when match IDs contain CSS-special characters.

Changes:

  • Replaced element.scrollIntoView() with an explicit scroll offset calculation and container.scrollBy() to reliably scroll both up and down in Electron/Chromium.
  • Replaced CSS attribute selector lookup with a DOM attribute comparison (querySelectorAll + getAttribute) to avoid SyntaxError when IDs contain characters that invalidate CSS selectors.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jansaldo jansaldo merged commit 046f8ab into develop May 22, 2026
2 checks passed
@jansaldo jansaldo deleted the fix/69-search-previous-autoscroll branch May 22, 2026 17:56
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