type TextSearchResult = { content: string quads: quad[] pageNum: number pageSearchIndex: number searchValue: string } type quad = { bottom: number left: number right: number top: number } export default class TextSearch { searchContainer: HTMLDivElement | null = null activeIndex = 0 container: HTMLDivElement | null = null viewport: any scale: number = 0 pageIndex: number = 0 _searchResults: TextSearchResult[] = [] constructor({ container, viewport, scale, pageIndex, results, }: { container: HTMLDivElement, viewport: any, scale: number, pageIndex: number, results: TextSearchResult[] }) { this.container = container this.viewport = viewport this.scale = scale this.pageIndex = pageIndex this._searchResults = results if (results && results.length) { this.renderSearchResults() } } get searchResults() { return this._searchResults } set searchResults(results) { this._searchResults = results this.renderSearchResults() } setActiveSearchResult(search: TextSearchResult) { const { pageNum } = search if (search) { if (this.searchContainer) { const searchEles = this.searchContainer.querySelectorAll('.searchItems') searchEles[search.pageSearchIndex].classList.add('selected') } this.activeIndex = pageNum - 1 } } clearActiveSearchResult(result: TextSearchResult) { if (this.searchContainer) { const index = result.pageSearchIndex const searchEle = this.searchContainer.querySelectorAll('.searchItems')[index] searchEle.classList.remove('selected') } } renderSearchResults() { const scale = this.scale if (!this.searchContainer) { const searchContainer = document.createElement('div') searchContainer.className = 'searchContainer' this.container!.appendChild(searchContainer) this.searchContainer = searchContainer } this.searchContainer.textContent = '' for (let i = 0; i < this.searchResults.length; i++) { if (this.searchResults[i].pageNum !== this.pageIndex + 1) { continue } const result = this.searchResults[i] const searchItems = document.createElement('div') searchItems.className = 'searchItems' for (let j = 0; j < result.quads.length; j++) { const { left, top, right, bottom } = result.quads[j] const bounds = { left: left * scale, top: top * scale, width: right * scale - left * scale, height: bottom * scale - top * scale } const div = document.createElement('div') div.className = 'highlight' div.style.position = 'absolute' div.style.left = `${bounds.left}px` div.style.top = `${bounds.top}px` div.style.width = `${bounds.width}px` div.style.height = `${bounds.height}px` searchItems.appendChild(div) } this.searchContainer!.appendChild(searchItems) } } destroy() { if (this.searchContainer) { this.searchContainer.parentNode!.removeChild(this.searchContainer) this.searchContainer = null } } }