|
@@ -0,0 +1,103 @@
|
|
|
+type TextSearchResult = {
|
|
|
+ bottom: number
|
|
|
+ content: string
|
|
|
+ left: number
|
|
|
+ pageNum: number
|
|
|
+ right: number
|
|
|
+ searchValue: string
|
|
|
+ top: number
|
|
|
+}
|
|
|
+
|
|
|
+export default class TextSearch {
|
|
|
+ searchContainer: HTMLDivElement | null = null
|
|
|
+ activeIndex = 0
|
|
|
+ activeSearchResult: TextSearchResult | null = null
|
|
|
+ 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, left, top, right, bottom} = search
|
|
|
+ const activeSearchResult = this.activeSearchResult
|
|
|
+ if (search && ((activeSearchResult && left !== activeSearchResult.left && top !== activeSearchResult.top && right !== activeSearchResult.right && bottom !== activeSearchResult.bottom) || !activeSearchResult)) {
|
|
|
+ if (!activeSearchResult) {
|
|
|
+
|
|
|
+ }
|
|
|
+ this.activeSearchResult = search
|
|
|
+ this.activeIndex = pageNum - 1
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ 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 { left, top, right, bottom } = result
|
|
|
+ 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`
|
|
|
+ this.searchContainer!.appendChild(div)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ destroy() {
|
|
|
+ if (this.searchContainer) {
|
|
|
+ this.searchContainer.parentNode!.removeChild(this.searchContainer)
|
|
|
+ this.searchContainer = null
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|