Skip to content

Add Advanced Search Overlay with Category Filters and Fuzzy Matching#2

Closed
Copilot wants to merge 2 commits into
mainfrom
copilot/add-advanced-search-overlay
Closed

Add Advanced Search Overlay with Category Filters and Fuzzy Matching#2
Copilot wants to merge 2 commits into
mainfrom
copilot/add-advanced-search-overlay

Conversation

Copilot AI commented Nov 20, 2025

Copy link
Copy Markdown

Implements a modal-based global search system for comprehensive queries across classes and members with ranked results, category toggles, type search mode, and fuzzy fallback.

Core Implementation

Search Engine (Latest/advanced-search.js)

  • Preprocessed indexes: classIndex (name/lowercase), memberIndex (className/name/type/offset with lowercase variants)
  • Scoring: Exact (100), Prefix (80), Substring (50); specialized offset hex matching (90/40); type matching (70/55/35)
  • Fuzzy fallback via Levenshtein (distance ≤ 2) when results < 15
  • Max 250 results rendered; performance logged to console

UI Components (Latest/index.html)

  • Trigger button with Ctrl+K shortcut adjacent to TopSearchInput
  • Overlay structure: search input, category checkboxes (Classes, Members, Functions*, Enums*, Type Search toggle), scrollable results, status footer
  • *Functions/Enums visually disabled (placeholder for future data)

Navigation

  • Classes: Calls existing SelectClass(name)
  • Members: Navigates to class + highlights member row with temporary yellow background (2s fade)
  • Keyboard: Up/Down cycle focus, Enter navigates, Escape closes

Integration (Latest/loader.js)

// After Classes loaded (line 207-210)
if (window.AdvancedSearch && window.AdvancedSearch.initIndex) {
    window.AdvancedSearch.initIndex(Classes);
}

Styling (Latest/styles.css)

Dark theme overlay with backdrop-filter: blur(12px), gradient borders, highlight spans (<span class="ASHighlight">), disabled checkbox states. Prevents body scroll when open.

Example Usage

Type Search Mode: Query AFortWeapon* returns members where type field matches (not name)

Offset Search: 0x990 prioritizes exact hex matches in member offsets

Fuzzy: AFortPlayrPawn suggests AFortPlayerPawn via approximate matching

Screenshots

Advanced Search Button
Advanced Search Button

Search Overlay in Action
Search Overlay

Preserved Behavior

Existing GlobalSearchDropdown and sidebar class filter remain unchanged and functional.

Original prompt

Advanced Global Search Overlay for Neptune SDK Browser

image1

Goal

Implement an "Advanced Search" feature similar to the Dumpspace global search panel while preserving the existing sidebar class filter and the current lightweight top search behavior. The new system should allow users to open a modal/overlay from the top-right search bar area and perform a comprehensive search across classes and members (and be extensible for functions/enums later) with category toggles, an optional "Type Search" mode, and better ranked results.

Scope

Add a modal overlay triggered by a button (or icon) adjacent to the existing TopSearchInput in Latest/index.html. The overlay should:

  1. Present a search input field.
  2. Provide selectable category checkboxes:
    • Classes (search class names)
    • Members (Structs) (search member names + offsets)
    • Functions (placeholder – no data yet, disabled visually)
    • Enums (placeholder – no data yet, disabled visually)
    • Type Search toggle (when enabled and Members selected, interpret the entered text as member type instead of member name)
  3. Display results in a scrollable panel with highlighted matches.
  4. Allow keyboard navigation (Up/Down/Enter/Escape) within the results list.
  5. Provide actions:
    • Clicking a class result jumps to and selects that class (existing SelectClass(name) logic).
    • Clicking a member result jumps to its class and highlights the member (we will add a lightweight highlight routine).
  6. Provide performance metrics in console (log build time and query time) and optional on-screen footer (small gray text) with counts and timing.
  7. Preserve existing basic top dropdown global search (for now). The overlay is an enhancement; the old dropdown remains functional until future refactor.
  8. Include initial ranking logic: Exact match > prefix > substring; offsets exact hex match > substring; type matches ranked similarly.
  9. Use a simple Levenshtein fuzzy fallback if results are fewer than a threshold (e.g., < 15) for classes and member names.
  10. Cache the preprocessed index in memory; no localStorage persistence required in this first iteration (later optional).

Implementation Plan

1. HTML Additions (Latest/index.html)

  • Add an Advanced Search trigger button (icon with tooltip) next to TopSearchInput.
  • Add overlay markup at end of body:
<div id="AdvancedSearchOverlay" class="AdvancedSearchOverlay" style="display:none;">
  <div class="AdvancedSearchPanel">
    <div class="ASHeader">
      <h2>Global Search</h2>
      <button id="ASClose" class="ASClose">×</button>
    </div>
    <div class="ASControls">
      <div class="ASSearchInputWrapper">
        <input id="ASQuery" type="text" placeholder="Search..." autocomplete="off" />
      </div>
      <div class="ASFilters">
        <label><input type="checkbox" id="ASClasses" checked /> Classes</label>
        <label><input type="checkbox" id="ASMembers" checked /> Members</label>
        <label title="Not yet implemented" class="Disabled"><input type="checkbox" disabled /> Functions</label>
        <label title="Not yet implemented" class="Disabled"><input type="checkbox" disabled /> Enums</label>
        <label><input type="checkbox" id="ASTypeSearch" /> Type Search <span class="Hint">Search member type instead of name.</span></label>
      </div>
    </div>
    <div id="ASResults" class="ASResults"></div>
    <div id="ASStatus" class="ASStatus"></div>
  </div>
</div>

2. CSS (Latest/styles.css)

Add styles for overlay, panel, filters, results items, highlight spans, status footer. Ensure dark theme consistent with existing variables. Provide transitions and use backdrop-filter where available.

3. JS Organization

Create new file: Latest/advanced-search.js.
Responsibilities:

  • Build index after sdk_data.json is loaded (hook into existing initialization; if window.Classes already exists, run immediately).
  • Index data:
    • classIndex: array of {name, lower}
    • memberIndex: array of {className, name, lower, type, typeLower, offset, offsetLower}
  • Search pipeline:
    1. Gather active categories.
    2. For Members: choose field (name vs type) depending on Type Search checkbox.
    3. Collect candidates using substring matches.
    4. Score results: exact (100), prefix (80), substring (50); offsets exact (90), offset substring (40); type exact/prefix/sub (70/55/35).
    5. If fewer than 15 class/member results, perform fuzzy pass (Levenshtein distance ≤ 2) adding approximate matches with lower scores.
    6. Sort by score desc then by result kind priority (class > member).
    7. Render top N (initially 250) with virtual scroll if performance is an issue.
  • Keyboard navigation: maintain focusedIndex; arrow keys cycle; Enter triggers navigation.
  • Highlighting: wrap matched query portion with <span class="ASHighlight">...</span>.
  • Jumping:
    • For class: call existing SelectClass(name).
    • For member: SelectClass(className) then apply a t...

This pull request was created as a result of the following prompt from Copilot chat.

Advanced Global Search Overlay for Neptune SDK Browser

image1

Goal

Implement an "Advanced Search" feature similar to the Dumpspace global search panel while preserving the existing sidebar class filter and the current lightweight top search behavior. The new system should allow users to open a modal/overlay from the top-right search bar area and perform a comprehensive search across classes and members (and be extensible for functions/enums later) with category toggles, an optional "Type Search" mode, and better ranked results.

Scope

Add a modal overlay triggered by a button (or icon) adjacent to the existing TopSearchInput in Latest/index.html. The overlay should:

  1. Present a search input field.
  2. Provide selectable category checkboxes:
    • Classes (search class names)
    • Members (Structs) (search member names + offsets)
    • Functions (placeholder – no data yet, disabled visually)
    • Enums (placeholder – no data yet, disabled visually)
    • Type Search toggle (when enabled and Members selected, interpret the entered text as member type instead of member name)
  3. Display results in a scrollable panel with highlighted matches.
  4. Allow keyboard navigation (Up/Down/Enter/Escape) within the results list.
  5. Provide actions:
    • Clicking a class result jumps to and selects that class (existing SelectClass(name) logic).
    • Clicking a member result jumps to its class and highlights the member (we will add a lightweight highlight routine).
  6. Provide performance metrics in console (log build time and query time) and optional on-screen footer (small gray text) with counts and timing.
  7. Preserve existing basic top dropdown global search (for now). The overlay is an enhancement; the old dropdown remains functional until future refactor.
  8. Include initial ranking logic: Exact match > prefix > substring; offsets exact hex match > substring; type matches ranked similarly.
  9. Use a simple Levenshtein fuzzy fallback if results are fewer than a threshold (e.g., < 15) for classes and member names.
  10. Cache the preprocessed index in memory; no localStorage persistence required in this first iteration (later optional).

Implementation Plan

1. HTML Additions (Latest/index.html)

  • Add an Advanced Search trigger button (icon with tooltip) next to TopSearchInput.
  • Add overlay markup at end of body:
<div id="AdvancedSearchOverlay" class="AdvancedSearchOverlay" style="display:none;">
  <div class="AdvancedSearchPanel">
    <div class="ASHeader">
      <h2>Global Search</h2>
      <button id="ASClose" class="ASClose">×</button>
    </div>
    <div class="ASControls">
      <div class="ASSearchInputWrapper">
        <input id="ASQuery" type="text" placeholder="Search..." autocomplete="off" />
      </div>
      <div class="ASFilters">
        <label><input type="checkbox" id="ASClasses" checked /> Classes</label>
        <label><input type="checkbox" id="ASMembers" checked /> Members</label>
        <label title="Not yet implemented" class="Disabled"><input type="checkbox" disabled /> Functions</label>
        <label title="Not yet implemented" class="Disabled"><input type="checkbox" disabled /> Enums</label>
        <label><input type="checkbox" id="ASTypeSearch" /> Type Search <span class="Hint">Search member type instead of name.</span></label>
      </div>
    </div>
    <div id="ASResults" class="ASResults"></div>
    <div id="ASStatus" class="ASStatus"></div>
  </div>
</div>

2. CSS (Latest/styles.css)

Add styles for overlay, panel, filters, results items, highlight spans, status footer. Ensure dark theme consistent with existing variables. Provide transitions and use backdrop-filter where available.

3. JS Organization

Create new file: Latest/advanced-search.js.
Responsibilities:

  • Build index after sdk_data.json is loaded (hook into existing initialization; if window.Classes already exists, run immediately).
  • Index data:
    • classIndex: array of {name, lower}
    • memberIndex: array of {className, name, lower, type, typeLower, offset, offsetLower}
  • Search pipeline:
    1. Gather active categories.
    2. For Members: choose field (name vs type) depending on Type Search checkbox.
    3. Collect candidates using substring matches.
    4. Score results: exact (100), prefix (80), substring (50); offsets exact (90), offset substring (40); type exact/prefix/sub (70/55/35).
    5. If fewer than 15 class/member results, perform fuzzy pass (Levenshtein distance ≤ 2) adding approximate matches with lower scores.
    6. Sort by score desc then by result kind priority (class > member).
    7. Render top N (initially 250) with virtual scroll if performance is an issue.
  • Keyboard navigation: maintain focusedIndex; arrow keys cycle; Enter triggers navigation.
  • Highlighting: wrap matched query portion with <span class="ASHighlight">...</span>.
  • Jumping:
    • For class: call existing SelectClass(name).
    • For member: SelectClass(className) then apply a temporary CSS highlight to the member row (add a data-offset or data-name attribute match logic in existing member rendering; fallback scroll into view).
  • Status footer: show "42 results in 23ms".
  • Expose global OpenAdvancedSearch() / CloseAdvancedSearch().

4. Integrate Loader

Modify Latest/loader.js:

  • After classes are loaded and assigned to Classes, call if (window.AdvancedSearch && window.AdvancedSearch.initIndex) window.AdvancedSearch.initIndex(Classes);.
  • Ensure no race conditions: if advanced-search script loads after, it can detect window.Classes and build.

5. Accessibility & UX

  • Overlay closes with ESC, clicking outside panel, or X button.
  • Prevent body scroll while overlay open (document.body.style.overflow = 'hidden').
  • Focus the search input when opened.

6. Non-Destructive Existing Features

  • Do NOT remove or heavily alter current GlobalSearchDropdown logic; leave as is.
  • Keep sidebar search unchanged.

7. Code Quality

  • Vanilla JS only, no external libs.
  • Fuzzy (Levenshtein) implemented locally (reuse existing or implement small function).
  • Comment non-obvious logic thoroughly.

8. Acceptance Criteria

  • Clicking new Advanced Search button opens overlay.
  • Searching with default (Classes + Members) returns ranked list immediately (<100ms typical desktop).
  • Type Search toggled: searching for AFortWeapon* returns members whose T matches.
  • Offset hex search: 0x990 yields CurrentWeapon member results above generic substring matches.
  • Fuzzy: Typing AFortPlayrPawn still suggests AFortPlayerPawn.
  • Enter key on highlighted result navigates to class and closes overlay.
  • ESC closes overlay and restores focus to TopSearchInput.
  • No errors in console; logs show index build and query times.

9. Future Extensibility (design guidance for implementer)

While functions/enums are placeholders now, leave stubs in index structure so future JSON expansions can plug in without major refactor.

10. Files to Add / Modify

Add:

  • Latest/advanced-search.js
    Modify:
  • Latest/index.html
  • Latest/styles.css
  • Latest/loader.js

11. Security & Performance Considerations

  • Avoid rendering extremely large result sets: cap and allow scrolling.
  • Sanitize text insertions via textContent except for controlled highlight spans; construct highlight HTML with basic string replace (query substring) ensuring no injection (source data is trusted, coming from static JSON). For safety, escape characters outside highlight handling.

12. Testing Notes

Manual test in Chrome & Firefox. Confirm overlay reflows properly at small viewport widths. Confirm that member highlighting does not break existing class rendering.


Please implement the above in a new branch (e.g., feature/advanced-search-overlay).


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: paysonism <79509967+paysonism@users.noreply.github.com>
Copilot AI changed the title [WIP] Add advanced search overlay for Neptune SDK browser Add Advanced Search Overlay with Category Filters and Fuzzy Matching Nov 20, 2025
Copilot AI requested a review from paysonism November 20, 2025 04:31
@paysonism paysonism marked this pull request as ready for review November 21, 2025 17:44

@paysonism paysonism left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

a

@paysonism paysonism closed this Nov 23, 2025
@paysonism paysonism deleted the copilot/add-advanced-search-overlay branch November 23, 2025 23:48
Copilot AI requested a review from paysonism November 23, 2025 23:48
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