浏览代码

fix: 修改换行的文字搜索bug

liutian 1 年之前
父节点
当前提交
7d27ca79ca

+ 1 - 1
packages/core/rollup.config.js

@@ -6,7 +6,7 @@ import json from '@rollup/plugin-json'
 import ts from "rollup-plugin-typescript2"
 
 const extensions = [".js", ".ts"]
-const reserved = ['ComPDFKitJS', 'DataArray', 'LineType', 'PageSize', 'Rect', 'RGBColor', 'FontDa', 'PDFDestination', 'WidgetItem', 'WidgetItemsArray', 'TextFindItem', 'EditCharPlace', 'EndEditCharPlace', 'RectArray', 'CursorPoints', 'EditTextStyle', 'U8StringData', 'PDFRange', 'TextRectArray']
+const reserved = ['ComPDFKitJS', 'DataArray', 'LineType', 'PageSize', 'Rect', 'RGBColor', 'FontDa', 'PDFDestination', 'WidgetItem', 'WidgetItemsArray', 'TextFindItemArray', 'EditCharPlace', 'EndEditCharPlace', 'RectArray', 'CursorPoints', 'EditTextStyle', 'U8StringData', 'PDFRange', 'TextRectArray']
 
 const plugins = [
   json(),

+ 29 - 25
packages/core/src/TextSearch.ts

@@ -1,18 +1,20 @@
 type TextSearchResult = {
-  bottom: number
   content: string
-  left: number
+  quads: quad[]
   pageNum: number
-  right: 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
-  activeSearchResult: TextSearchResult | null = null
   container: HTMLDivElement | null = null
   viewport: any
   scale: number = 0
@@ -52,15 +54,13 @@ export default class TextSearch {
   }
 
   setActiveSearchResult(search: TextSearchResult) {
-    const { pageNum, left, top, right, bottom} = search
-    const activeSearchResult = this.activeSearchResult
+    const { pageNum } = search
 
-    if (search && ((activeSearchResult && (activeSearchResult.pageNum !== pageNum || left !== activeSearchResult.left || top !== activeSearchResult.top || right !== activeSearchResult.right || bottom !== activeSearchResult.bottom)) || !activeSearchResult)) {
+    if (search) {
       if (this.searchContainer) {
-        const searchEles = this.searchContainer.querySelectorAll('div')
+        const searchEles = this.searchContainer.querySelectorAll('.searchItems')
         searchEles[search.pageSearchIndex].classList.add('selected')
       }
-      this.activeSearchResult = search
       this.activeIndex = pageNum - 1
     }
   }
@@ -68,10 +68,9 @@ export default class TextSearch {
   clearActiveSearchResult(result: TextSearchResult) {
     if (this.searchContainer) {
       const index = result.pageSearchIndex
-      const searchEle = this.searchContainer.querySelectorAll('div')[index]
+      const searchEle = this.searchContainer.querySelectorAll('.searchItems')[index]
       searchEle.classList.remove('selected')
     }
-    this.activeSearchResult = null
   }
 
   renderSearchResults() {
@@ -88,21 +87,26 @@ export default class TextSearch {
         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 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)
       }
-      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)
+      this.searchContainer!.appendChild(searchItems)
     }
   }
 

+ 3 - 2
packages/core/src/index.js

@@ -515,8 +515,9 @@ class ComPDFKitViewer {
   setActiveSearchResult(result = null, activeSearchIndex = 0) {
     if (!this.searchResults) return
     const activeResult = result ? result : this.searchResults[0]
-    const left = activeResult.left * this.scale
-    const top = activeResult.top * this.scale
+    const quad = activeResult.quads[0]
+    const left = quad.left * this.scale
+    const top = quad.top * this.scale
 
     const pageView = this.pdfViewer._pages[activeResult.pageNum - 1]
     this.pdfViewer.currentPageNumber = activeResult.pageNum

+ 10 - 0
packages/core/src/pdf_page_view.js

@@ -72,6 +72,8 @@ class PDFPageView {
     regularAnnotations: true,
   };
 
+  #activeSearch = null
+
   /**
    * @param {PDFPageViewOptions} options
    */
@@ -579,6 +581,9 @@ class PDFPageView {
               container: div,
               results: this.searchResults,
             })
+            if (this.#activeSearch) {
+              this.textSearch.setActiveSearchResult(this.#activeSearch)
+            }
           }
       },
       error => {
@@ -1222,6 +1227,9 @@ class PDFPageView {
               container: div,
               results: this.searchResults,
             })
+            if (this.#activeSearch) {
+              this.textSearch.setActiveSearchResult(this.#activeSearch)
+            }
           }
         });
       },
@@ -1326,12 +1334,14 @@ class PDFPageView {
   }
 
   setActiveSearchResult(search) {
+    this.#activeSearch = search
     if (this.textSearch) {
       this.textSearch.setActiveSearchResult(search)
     }
   }
 
   clearActiveSearchResult(searchResult) {
+    this.#activeSearch = null
     if (this.textSearch) {
       this.textSearch.clearActiveSearchResult(searchResult)
     }

+ 16 - 8
packages/core/src/worker/compdfkit_worker.js

@@ -15,7 +15,7 @@ let PDFDestination = {}
 let WidgetItem = {}
 let WidgetItemsArray = {}
 let password = ''
-let TextFindItem = {}
+let TextFindItemArray = []
 let EditCharPlace = {}
 let EndEditCharPlace = {}
 let RectArray = []
@@ -518,18 +518,26 @@ class CPDFWorker {
         let resFind = 1
         let pageSearchIndex = 0
         do {
-          TextFindItem = {}
+          TextFindItemArray = []
           resFind = Module._FindNext(pagePtr, textPtr, textFindPtr)
 
           if (resFind) {
-            const { Left: left, Top: top, Right: right, Bottom: bottom, Content: content } = TextFindItem
+            const length = TextFindItemArray.length
+            const quads = []
+            for (let i = 0; i < length; i++) {
+              const item = TextFindItemArray[i]
+              const { Left: left, Top: top, Right: right, Bottom: bottom } = item
+              quads.push({
+                left,
+                top,
+                right,
+                bottom,
+              })
+            }
             searchResults.push({
               pageNum: i + 1,
-              left,
-              top,
-              right,
-              bottom,
-              content,
+              quads,
+              content: TextFindItemArray[0].Content.replace(/\r?\n/gm, ' '),
               pageSearchIndex,
               searchValue: value
             })

+ 4 - 2
packages/webview/src/components/DocumentContainer/DocumentContainer.vue

@@ -566,7 +566,9 @@ onMounted(async () => {
 }
 
 .searchContainer {
-  position: relative;
+  position: absolute;
+  top: 0;
+  left: 0;
   z-index: 3;
   pointer-events: none;
 }
@@ -575,7 +577,7 @@ onMounted(async () => {
   background-color: rgba(255, 255, 0, 0.25);
 }
 
-.searchContainer .highlight.selected {
+.searchContainer .selected .highlight {
   background-color: rgba(255, 255, 0, 0.7);
 }
 

+ 3 - 3
packages/webview/src/components/SearchContainer/SearchHeader.vue

@@ -31,7 +31,7 @@
 
 <script setup>
   import debounce from 'lodash.debounce'
-  import { ref, watch, computed } from "vue"
+  import { ref, watch, computed, toRaw } from "vue"
   import core from '@/core'
   import { useDocumentStore } from '@/stores/modules/document'
   import { useViewerStore } from '@/stores/modules/viewer'
@@ -49,7 +49,7 @@
     const activeIndex = rawActiveIndex.value
     if (reseults.length > 0) {
       const prevIndex = activeIndex <= 0 ? reseults.length - 1 : activeIndex - 1
-      core.setActiveSearchResult(reseults[prevIndex], prevIndex)
+      core.setActiveSearchResult(toRaw(reseults[prevIndex]), prevIndex)
       rawActiveIndex.value = prevIndex
     }
   }
@@ -59,7 +59,7 @@
     const activeIndex = rawActiveIndex.value
     if (reseults.length > 0) {
       const nextIndex = activeIndex === reseults.length - 1 ? 0 : activeIndex + 1
-      core.setActiveSearchResult(reseults[nextIndex], nextIndex)
+      core.setActiveSearchResult(toRaw(reseults[nextIndex]), nextIndex)
       rawActiveIndex.value = nextIndex
     }
   }