ext-apps/examples/pdf-server/mcp-app.html
Olivier Chafik 8cad9f04c0
Add PDF search feature to pdf-server (#445)
* Add PDF search feature to pdf-server

Adds full-text search functionality to the PDF viewer:

- Search button in toolbar (Ctrl/Cmd+F to open)
- Search bar with input, prev/next navigation, match count
- Text extraction and caching across all pages
- Highlight overlays using DOM Range API
- Case-insensitive search across entire document
- Keyboard shortcuts: Ctrl+F (open), Enter (next), Shift+Enter (prev), Escape (close)

Changes:
- mcp-app.html: Add search button, search bar, highlight layer
- src/mcp-app.css: Add search/highlight styles and PDF.js text layer rules
- src/mcp-app.ts: Add search state, functions, event listeners

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* update screenshots

* Add fullscreen button to threejs-server

* Fix prettier formatting

* Move search bar below toolbar, right-aligned

* Make search bar compact and right-aligned

* Float search bar over page content

* Ctrl/Cmd+F toggles search; pass through to browser when empty

* Hide search nav controls until query is entered

* Skip scroll when search highlight is already visible

* Fix search bar right-edge alignment with container border

* Prevent browser find when our search is open with text

* Cmd+F when search input is focused passes through to browser find

* Fix prettier formatting in README

* Remove unrelated formatting and threejs changes from PR

* prettier

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-19 18:56:40 +00:00

124 lines
3.7 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>PDF Viewer</title>
</head>
<body>
<div class="main">
<!-- Loading State -->
<div id="loading" class="loading">
<div class="spinner"></div>
<p id="loading-text">Loading PDF...</p>
<div
id="progress-container"
class="progress-container"
style="display: none"
>
<div id="progress-bar" class="progress-bar"></div>
</div>
<p id="progress-text" class="progress-text"></p>
</div>
<!-- Error State -->
<div id="error" class="error" style="display: none">
<div class="error-icon">⚠️</div>
<p id="error-message">An error occurred</p>
</div>
<!-- PDF Viewer -->
<div id="viewer" class="viewer" style="display: none">
<!-- Toolbar -->
<div class="toolbar">
<div class="toolbar-left">
<span id="pdf-title" class="pdf-title">Document</span>
</div>
<div class="toolbar-center">
<button id="prev-btn" class="nav-btn" title="Previous page (←)">
◀
</button>
<div class="page-nav">
<input
id="page-input"
type="number"
class="page-input"
min="1"
value="1"
title="Go to page"
/>
<span id="total-pages" class="total-pages">of 1</span>
</div>
<button id="next-btn" class="nav-btn" title="Next page (→)">
▶
</button>
</div>
<div class="toolbar-right">
<button id="zoom-out-btn" class="zoom-btn" title="Zoom out (-)">
−
</button>
<span id="zoom-level" class="zoom-level">100%</span>
<button id="zoom-in-btn" class="zoom-btn" title="Zoom in (+)">
+
</button>
<button
id="search-btn"
class="search-btn"
title="Search (Ctrl+F)"
></button>
<button
id="fullscreen-btn"
class="fullscreen-btn"
title="Toggle fullscreen"
>
⛶
</button>
</div>
</div>
<!-- Search bar below toolbar, right-aligned -->
<div id="search-bar" class="search-bar" style="display: none">
<input
id="search-input"
class="search-input"
type="text"
placeholder="Search..."
autocomplete="off"
/>
<span id="search-match-count" class="search-match-count"></span>
<button
id="search-prev-btn"
class="search-nav-btn"
title="Previous (Shift+Enter)"
>
&#x25B2;
</button>
<button
id="search-next-btn"
class="search-nav-btn"
title="Next (Enter)"
>
&#x25BC;
</button>
<button
id="search-close-btn"
class="search-nav-btn"
title="Close (Esc)"
>
&#x2715;
</button>
</div>
<!-- Single Page Canvas Container -->
<div class="canvas-container">
<div class="page-wrapper">
<canvas id="pdf-canvas"></canvas>
<div id="highlight-layer" class="highlight-layer"></div>
<div id="text-layer" class="text-layer"></div>
</div>
</div>
</div>
</div>
<script type="module" src="./src/mcp-app.ts"></script>
</body>
</html>