2 İşlemeler e6a03327ab ... 9efea87ca8

Yazar SHA1 Mesaj Tarih
  wzl 9efea87ca8 fix: 三轮测试修复 1 ay önce
  wzl 6e16ada19f fix: 二轮测试修复 1 ay önce
31 değiştirilmiş dosya ile 124 ekleme ve 99 silme
  1. 1 1
      packages/core/src/annotation/freetext.js
  2. 1 1
      packages/core/src/annotation/ink.js
  3. 4 6
      packages/core/src/annotation/layer.js
  4. 1 1
      packages/core/src/annotation/line.js
  5. 1 1
      packages/core/src/annotation/link.js
  6. 1 1
      packages/core/src/annotation/shape.js
  7. 1 1
      packages/core/src/annotation/stamp.js
  8. 1 1
      packages/core/src/annotation/text.js
  9. 8 4
      packages/core/src/editor/content_container.js
  10. 1 1
      packages/core/src/form/check_box.js
  11. 1 1
      packages/core/src/form/combo_box.js
  12. 1 1
      packages/core/src/form/list_box.js
  13. 1 1
      packages/core/src/form/push_button.js
  14. 1 1
      packages/core/src/form/radio_button.js
  15. 2 2
      packages/core/src/form/signature_fields.js
  16. 3 2
      packages/core/src/form/text_field.js
  17. 45 37
      packages/core/src/index.js
  18. 2 2
      packages/core/src/markup/text_annotation.js
  19. 4 0
      packages/core/src/pdf_page_view.js
  20. 3 2
      packages/webview/locales/en.json
  21. 3 2
      packages/webview/locales/zh-CN.json
  22. 1 0
      packages/webview/src/components/AnnotationContainer/AnnotationContent.vue
  23. 5 7
      packages/webview/src/components/Dialogs/SignatureAppearanceDialog.vue
  24. 4 5
      packages/webview/src/components/DocumentContainer/DocumentContainer.vue
  25. 1 7
      packages/webview/src/components/Header/Header.vue
  26. 1 0
      packages/webview/src/components/RightPanel/RightPanel.vue
  27. 0 1
      packages/webview/src/components/SecurityToolbar/RedactionConfirmDialog.vue
  28. 15 1
      packages/webview/src/components/SecurityToolbar/SecurityApplyBar.vue
  29. 9 7
      packages/webview/src/components/SecurityToolbar/SecurityToolbar.vue
  30. 1 1
      packages/webview/src/components/Toolbar/Toolbar.vue
  31. 1 1
      packages/webview/src/components/ZoomOverlay/ZoomOverlay.vue

+ 1 - 1
packages/core/src/annotation/freetext.js

@@ -581,7 +581,7 @@ export default class Shape extends Base {
 
   handleContainerClick (event) {
     event && event.stopPropagation()
-    if (!this.hidden || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (!this.hidden || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     this.hidden = false
     this.updateTool()
     onClickOutside([this.outerLine, this.freetextElement, this.deletetButton, this.replyButton, document.querySelector('.toggle-button')], this.handleOutside.bind(this))

+ 1 - 1
packages/core/src/annotation/ink.js

@@ -115,7 +115,7 @@ export default class Ink extends Base {
     if (this.layer.tool) {
       event && event.stopPropagation()
     }
-    if (!this.hidden || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (!this.hidden || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     this.hidden = false
     this.updateTool()
     onClickOutside([this.svgElement, this.outerLine, this.deletetButton, this.replyButton, document.querySelector('.toggle-button')], this.handleOutside.bind(this))

+ 4 - 6
packages/core/src/annotation/layer.js

@@ -600,12 +600,10 @@ class ComPDFAnnotationLayer {
       }
     }
 
-    if (this.tool && this.color) {
-      this.handleTool({
-        tool: this.tool,
-        color: this.color
-      })
-    }
+    this.handleTool({
+      tool: this.tool,
+      color: this.color
+    })
 
     this.annotationStore.toSelectAnnotationName && this.pageViewer.selectAnnotation(this.annotationStore.toSelectAnnotationName)
   }

+ 1 - 1
packages/core/src/annotation/line.js

@@ -245,7 +245,7 @@ export default class Line extends Base {
   }
 
   handleClick () {
-    if (!this.hidden || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (!this.hidden || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     this.hidden = false
     this.updateTool()
     onClickOutside([this.svgElement, this.outerLine, this.deletetButton, this.replyButton, document.querySelector('.toggle-button')], this.handleOutside.bind(this))

+ 1 - 1
packages/core/src/annotation/link.js

@@ -415,7 +415,7 @@ export default class Link extends Base {
   }
 
   handleClick () {
-    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || this.layer.toolMode === 'editor') return
+    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target) || this.layer.toolMode === 'editor') return
     if (this.layer.toolMode === 'annotation' && this.layer.tool === 'link') {
       this.hidden = false
       this.updateTool()

+ 1 - 1
packages/core/src/annotation/shape.js

@@ -411,7 +411,7 @@ export default class Shape extends Base {
   }
 
   handleClick () {
-    if (!this.hidden || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (!this.hidden || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     this.hidden = false
     this.updateTool()
     onClickOutside([this.svgElement, this.outerLine, this.deletetButton, this.replyButton, document.querySelector('.toggle-button')], this.handleOutside.bind(this))

+ 1 - 1
packages/core/src/annotation/stamp.js

@@ -387,7 +387,7 @@ export default class Stamp extends Base {
     if (this.layer.tool) {
       event && event.preventDefault()
     }
-    if (!this.hidden || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (!this.hidden || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     this.hidden = false
     this.updateTool()
     onClickOutside([this.annotationContainer, this.outerLine, this.deletetButton, this.replyButton, document.querySelector('.toggle-button')], this.handleOutside.bind(this))

+ 1 - 1
packages/core/src/annotation/text.js

@@ -306,7 +306,7 @@ export default class Text extends Base {
   }
 
   handleClick (event) {
-    if (this.layer.addMode || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (this.layer.addMode || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     if (this.layer.tool) {
       event && event.stopPropagation()
     }

+ 8 - 4
packages/core/src/editor/content_container.js

@@ -29,6 +29,14 @@ export class ContentContainer {
   }
 
   async init() {
+    await this.update()
+
+    document.addEventListener('keydown', this.onKeydown)
+    this.eventBus._on('toolChanged', this.onHandleTool)
+    this.render()
+  }
+
+  async update() {
     const { editPagePtr } = await this.messageHandler.sendWithPromise('InitEditPage', {
       pagePtr: this.pagePtr
     })
@@ -45,10 +53,6 @@ export class ContentContainer {
     }
 
     this.tool = this.pageViewer.tool || ''
-
-    document.addEventListener('keydown', this.onKeydown)
-    this.eventBus._on('toolChanged', this.onHandleTool)
-    this.render()
   }
 
   async render () {

+ 1 - 1
packages/core/src/form/check_box.js

@@ -492,7 +492,7 @@ export default class CheckBox extends Base {
   }
 
   handleClick () {
-    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     if (this.layer.toolMode === 'form') {
       this.hidden = false
       this.updateTool()

+ 1 - 1
packages/core/src/form/combo_box.js

@@ -502,7 +502,7 @@ export default class ComboBox extends Base {
   }
 
   handleClick () {
-    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     if (this.layer.toolMode === 'form') {
       this.hidden = false
       this.updateTool()

+ 1 - 1
packages/core/src/form/list_box.js

@@ -467,7 +467,7 @@ export default class ListBox extends Base {
   }
 
   handleClick(event) {
-    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     if (this.layer.toolMode === 'form') {
       this.hidden = false
       this.updateTool()

+ 1 - 1
packages/core/src/form/push_button.js

@@ -445,7 +445,7 @@ export default class PushButton extends Base {
   }
 
   handleClick () {
-    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     if (this.layer.toolMode === 'form') {
       this.hidden = false
       this.updateTool()

+ 1 - 1
packages/core/src/form/radio_button.js

@@ -493,7 +493,7 @@ export default class RadioButton extends Base {
   }
 
   handleClick () {
-    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     if (this.layer.toolMode === 'form') {
       this.hidden = false
       this.updateTool()

+ 2 - 2
packages/core/src/form/signature_fields.js

@@ -373,7 +373,7 @@ export default class SignatureFields extends Base {
   }
 
   handleClick () {
-    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || this.layer.toolMode === 'editor' || document.getElementById("sign-image-save")) return
+    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target) || this.layer.toolMode === 'editor' || document.getElementById("sign-image-save")) return
     if (this.isDigital) return
     if (this.layer.pageDiv.querySelector('.annotationLayer svg').style.cursor === 'crosshair' && this.layer.toolMode !== 'sign') return
 
@@ -557,7 +557,7 @@ export default class SignatureFields extends Base {
   handleDelete (data) {
     const event = data instanceof Event ? data : null
     if (!this.annotationContainer) return
-    if (!event && data.signaturePtr !== this.annotation.signaturePtr) return
+    if (!event && data && data.signaturePtr !== this.annotation.signaturePtr) return
     if (this.layer.tool && event) {
       event.stopPropagation()
     }

+ 3 - 2
packages/core/src/form/text_field.js

@@ -426,7 +426,7 @@ export default class TextField extends Base {
   }
 
   handleClick () {
-    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool)) return
+    if (!this.hidden || document.fullscreenElement || this.layer.annotationStore.creating || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     if (this.layer.toolMode === 'form') {
       this.hidden = false
       this.updateTool()
@@ -444,7 +444,8 @@ export default class TextField extends Base {
       this.textContainer.style.cursor = 'pointer'
     } else {
       setTimeout(() => {
-        this.textContainer.focus();
+        this.textContainer.focus()
+        this.textContainer.setSelectionRange(this.textContainer.value.length, this.textContainer.value.length)
       }, 0);
       this.textContainer.style.pointerEvents = 'auto'
       this.textContainer.style.cursor = 'text'

+ 45 - 37
packages/core/src/index.js

@@ -1184,6 +1184,8 @@ class ComPDFKitViewer {
   }
 
   async reRenderAnnotations() {
+    const signaturePtrList = await this.getSignatures()
+
     this.annotations = null
     const annotations = []
     const pagesPtr = this.pagesPtr
@@ -1206,7 +1208,8 @@ class ComPDFKitViewer {
             doc: this.doc,
             annotPtr: annotation.annotPtr,
             pagePtr: annotation.pagePtr,
-            typeInt
+            typeInt,
+            signaturePtrList
           })
         } else {
           attr = await this.messageHandler.sendWithPromise('GetAnnotation', {
@@ -1784,6 +1787,8 @@ class ComPDFKitViewer {
       await this.#postAnnotations(annotateHandles)
     }
 
+    this.eventBus.dispatch('redactAnnotationChanged', this.redactionList.length)
+
     this.isAnnotationModified = true
     return true
   }
@@ -2926,7 +2931,7 @@ class ComPDFKitViewer {
 
     this.pdfViewer.pagesPtr = this.pagesPtr
     this.pdfViewer._pages.forEach(page => {
-      page.pagesPtr = this.pagesPtr
+      page.pagePtr = this.pagesPtr[page.pageIndex].pagePtr
     });
 
     this.pdfViewer.refresh()
@@ -4310,46 +4315,49 @@ class ComPDFKitViewer {
   }
 
   async applyRedactions(redaction) {
-    if (redaction) {
-      let redactionList
-      if (redaction === 'all') {
-        redactionList = [...this.redactionList]
-        this.redactionList.length = 0
-      } else {
-        const redactions = Array.isArray(redaction) ? redaction : [redaction]
-        redactionList = redactions
-      }
-      for (const item of redactionList) {
-        if (item.erasure) {
-          if (item.rects && item.rects.length) {
-            for (const rect of item.rects) {
-              await this.messageHandler.sendWithPromise('ErasureRedactionFromRect', { pagePtr: item.pagePtr, rect })
-            }
-          } else {
-            await this.messageHandler.sendWithPromise('ErasureRedactionFromRect', { pagePtr: item.pagePtr, rect: item.rect })
-          }
-        } else {
-          await this.messageHandler.sendWithPromise('ApplyRedaction', { annotPtr: item.annotPtr })
-        }
-      }
-      
-      await this.updateTextPtr()
-      this.emptyAnnotations()
+    if (!redaction) {
+      await this.delAnnotations(this.redactionList)
+      this.redactionList.length = 0
       this.pdfViewer.refresh()
-      this.reRenderAnnotations()
+      return
+    }
 
-      return new Promise((resolve) => {
-        const eventHandler = () => {
-          this.eventBus._off('annotationChanged', eventHandler)
-          resolve()
-        }
-        this.eventBus._on('annotationChanged', eventHandler)
-      })
+    let redactionList
+    if (redaction === 'all') {
+      redactionList = [...this.redactionList]
+      await this.delAnnotations(this.redactionList)
+      this.redactionList.length = 0
+    } else {
+      const redactions = Array.isArray(redaction) ? redaction : [redaction]
+      redactionList = redactions
     }
 
-    await this.delAnnotations(this.redactionList)
-    this.redactionList.length = 0
+    for (const item of redactionList.filter(item => !item.erasure)) {
+      await this.messageHandler.sendWithPromise('ApplyRedaction', { annotPtr: item.annotPtr })
+    }
+    for (const item of redactionList.filter(item => item.erasure)) {
+      if (item.rects && item.rects.length) {
+        for (const rect of item.rects) {
+          await this.messageHandler.sendWithPromise('ErasureRedactionFromRect', { pagePtr: item.pagePtr, rect })
+        }
+      } else {
+        await this.messageHandler.sendWithPromise('ErasureRedactionFromRect', { pagePtr: item.pagePtr, rect: item.rect })
+      }
+    }
+    
+    await this.updateTextPtr()
+    this.emptyAnnotations()
     this.pdfViewer.refresh()
+    this.reRenderAnnotations()
+
+    return new Promise((resolve) => {
+      const eventHandler = () => {
+        this.eventBus._off('annotationChanged', eventHandler)
+        this.pdfViewer.refresh()
+        resolve()
+      }
+      this.eventBus._on('annotationChanged', eventHandler)
+    })
   }
 }
 

+ 2 - 2
packages/core/src/markup/text_annotation.js

@@ -203,8 +203,8 @@ class TextAnnotation extends BaseAnnotation {
     this.handleClick()
   }
 
-  handleClick () {
-    if (!this.hidden || ['redaction', 'remove'].includes(this.layer.tool)) return
+  handleClick (event) {
+    if (!this.hidden || ['redaction', 'remove'].includes(this.layer.tool) || document.querySelector('.compare-document-container').contains(event.target)) return
     this.hidden = false
     this.updateTool()
     const data = [this.markupContainer, this.outerLineContainer, this.deletetButton, this.replyButton]

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

@@ -1258,6 +1258,10 @@ class PDFPageView {
           } else if (this.mode === 'editor') {
             await this.contentContainer.render()
           }
+          if (this.contentContainer && this.contentContainer.pagePtr !== this.pagesPtr[this.pageIndex].pagePtr) {
+            this.contentContainer.pagePtr = this.pagesPtr[this.pageIndex].pagePtr
+            await this.contentContainer.update()
+          }
 
           if (!this.textSelection) {
             this.textSelection = new TextSelection({

+ 3 - 2
packages/webview/locales/en.json

@@ -469,8 +469,9 @@
   "properties": "Properties",
 
   "security": {
-    "setPassword": "Set Password",
-    "removePassword": "Remove Password",
+    "pwdProtection": "Password Protection",
+    "encryption": "Encryption",
+    "decryption": "Decryption",
 
     "redaction": "Redaction",
     "fillBlack": "Fill Black",

+ 3 - 2
packages/webview/locales/zh-CN.json

@@ -469,8 +469,9 @@
   "properties": "属性",
 
   "security": {
-    "setPassword": "设置密码",
-    "removePassword": "移除密码",
+    "pwdProtection": "密码保护",
+    "encryption": "文档加密",
+    "decryption": "文档解密",
 
     "redaction": "标记密文",
     "fillBlack": "填充黑色",

+ 1 - 0
packages/webview/src/components/AnnotationContainer/AnnotationContent.vue

@@ -400,6 +400,7 @@ const openAnnotationReply = (annotation) => {
   }
   setTimeout(() => {
     const div = document.querySelector('.annotation-item.selected')
+    div.scrollIntoView({ behavior: 'smooth' })
     if (!div.classList.contains('flash-border')) {
       div.classList.add('flash-border')
       timeout = setTimeout(() => document.querySelector('.annotation-item.selected').classList.remove('flash-border'), 2000)

+ 5 - 7
packages/webview/src/components/Dialogs/SignatureAppearanceDialog.vue

@@ -226,7 +226,7 @@ const getValue = (key) => {
       break
     case 'version':
       text.title = $t('signatures.appearanceDialog.ComPDFKitVersion')
-      text.value = '2.4.0'
+      text.value = '2.5.0'
       break
     case 'location':
       text.title = $t('signatures.appearanceDialog.location')
@@ -262,6 +262,8 @@ const getParams = (content) => {
 }
 
 const changeActiveSignWay = (way) => {
+  if (way === activeSignWay.value && ['image', 'none'].includes(way)) return
+
   core.handleSign({ flag: 'create', type: 1 })
   useViewer.setActiveSignWay(way)
   if (way === 'trackpad') useViewer.openElement('digitalSignCreatePanel')
@@ -298,12 +300,8 @@ const closePanel = (flag) => {
 }
 
 const clearData = async () => {
-  if (activeSignWay.value === "image") {
-    imageData.value=''
-  }
-  if (activeSignWay.value === 'trackpad') {
-    core.handleSign({ flag: 'clear' })
-  }
+  imageData.value = ''
+  if (activeSignWay.value === 'trackpad') core.handleSign({ flag: 'clear' })
   const content = getContent()
   await getPreview(content)
 }

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

@@ -107,7 +107,10 @@ const toolMode = computed(() => useViewer.getToolMode)
 const compareStatus = computed(() => useViewer.getCompareStatus)
 const topSpace = computed(() => {
   if (isHeaderDisabled || ['view', 'document'].includes(useViewer.getToolMode) || (toolMode.value === 'compare' && compareStatus.value !== 'finished')) return 0
-  if (['redaction', 'remove'].includes(activeTool.value) && window.innerWidth > 500) return 44 + 48
+  if (['redaction', 'remove'].includes(activeTool.value)) {
+    if (window.innerWidth > 500) return 44 + 48
+    else return 44 + 88
+  }
   if (signatureVerify.value && toolMode.value === 'sign') return 44 + 44
   return 44
 })
@@ -661,10 +664,6 @@ window.instances.UI.loadDocument = async (file, {
   }
 }
 
-.compare-document-container .annotationLayer {
-  z-index: 2;
-}
-
 .textLayer {
   position: absolute;
   text-align: initial;

+ 1 - 7
packages/webview/src/components/Header/Header.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="header" :class="{ disabled: isDisabledHeader || ['redaction', 'remove'].includes(activeTool), 'redact-mobile-hidden': ['redaction', 'remove'].includes(activeTool) }" data-element="header">
+  <div class="header" :class="{ disabled: isDisabledHeader || ['redaction', 'remove'].includes(activeTool) }" data-element="header">
     <HeaderItems :items="items" :rightItems="rightItems" :toolMode="toolMode" />
   </div>
   <Toolbar />
@@ -49,10 +49,4 @@ const activeTool = computed(() => useDocument.getActiveTool)
     padding: 10px;
   }
 }
-
-@media screen and (max-width: 500px) {
-  .redact-mobile-hidden {
-    display: none !important;
-  }
-}
 </style>

+ 1 - 0
packages/webview/src/components/RightPanel/RightPanel.vue

@@ -395,6 +395,7 @@
 
   const updateProperty = (props) => {
     editItem.value = ''
+    selectedItemIndex.value = null
 
     if (!props) {
       selectedElement.value = null

+ 0 - 1
packages/webview/src/components/SecurityToolbar/RedactionConfirmDialog.vue

@@ -47,7 +47,6 @@ const confirm = async () => {
   await core.applyRedactions(flag)
   useDocument.setToolState('')
   useViewer.setActiveToolMode('view')
-  useViewer.closeElement('leftPanel')
   loading.value = false
 }
 </script>

+ 15 - 1
packages/webview/src/components/SecurityToolbar/SecurityApplyBar.vue

@@ -9,7 +9,6 @@
 </template>
 
 <script setup>
-import { ref, computed } from 'vue'
 import { useViewerStore } from '@/stores/modules/viewer'
 import { useDocumentStore } from '@/stores/modules/document'
 import core from '@/core'
@@ -17,10 +16,21 @@ import core from '@/core'
 const useViewer = useViewerStore()
 const useDocument = useDocumentStore()
 
+let redactionNumber = 0
+
 const showDialog = (type) => {
+  if (!redactionNumber) {
+    useDocument.setToolState('')
+    useViewer.setActiveToolMode('view')
+    return
+  }
   useViewer.setRedactionConfirmDialog(type)
 }
 
+const redactionChanged = (num) => {
+  redactionNumber = num
+}
+core.addEvent('redactAnnotationChanged', redactionChanged)
 </script>
 
 <style lang="scss">
@@ -79,6 +89,10 @@ const showDialog = (type) => {
     flex-direction: column;
     align-items: flex-end;
 
+    > span {
+      width: 100%;
+    }
+
     .buttons {
       margin-left: 0;
       margin-top: 8px;

+ 9 - 7
packages/webview/src/components/SecurityToolbar/SecurityToolbar.vue

@@ -2,7 +2,7 @@
   <div class="security-toolbar">
     <n-popover
       ref="securityPopover"
-      placement="bottom-start"
+      placement="bottom"
       trigger="click"
       :show-arrow="false"
       to="#outerContainer"
@@ -12,19 +12,19 @@
     >
       <template #trigger>
         <Button :class="{ active: showSecurityPopover, disabled: ['redaction', 'remove'].includes(activeTool) }">
-          <span>{{ $t('header.security') }}</span>
+          <span>{{ $t('security.pwdProtection') }}</span>
           <Arrow class="arrow-left" />
         </Button>
       </template>
       <div class="drop-down">
-        <div class="drop-item" @click="openSetPassword">{{ $t('security.setPassword') }}</div>
-        <div class="drop-item" :class="{ disabled: !filehasPwd && webviewerMode !== 'Standalone' }" @click="removePassword">{{ $t('security.removePassword') }}</div>
+        <div class="drop-item" @click="openSetPassword">{{ $t('security.encryption') }}</div>
+        <div class="drop-item" :class="{ disabled: !filehasPwd && webviewerMode !== 'Standalone' }" @click="removePassword">{{ $t('security.decryption') }}</div>
       </div>
     </n-popover>
 
     <n-popover
       ref="redactionPopover"
-      placement="bottom-start"
+      placement="bottom"
       trigger="click"
       :show-arrow="false"
       to="#outerContainer"
@@ -33,8 +33,8 @@
       class="security-popover"
     >
       <template #trigger>
-        <Button :class="{ active: showRedactionPopover }">
-          <span>{{ $t('security.redaction') }}</span>
+        <Button :class="{ active: showRedactionPopover || ['redaction', 'remove'].includes(activeTool) }">
+          <span>{{ activeTool === 'redaction' ? $t('security.fillBlack') : activeTool === 'remove' ? $t('security.fillWhite') : $t('security.redaction') }}</span>
           <Arrow class="arrow-left" />
         </Button>
       </template>
@@ -124,6 +124,7 @@ const handleTool = (tool) => {
     showTipDialog.value = true
   } else if (activeTool.value !== tool) {
     useDocument.setToolState(tool)
+    useViewer.resetPanels()
   }
   redactionPopover.value.setShow(false)
 }
@@ -133,6 +134,7 @@ const closeDialog = () => {
   useDocument.setRedactionPrompted(true)
   useDocument.setToolState(firstEnterTool)
   useViewer.setDisableHeader(true)
+  useViewer.resetPanels()
 }
 </script>
 

+ 1 - 1
packages/webview/src/components/Toolbar/Toolbar.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="toolbar" v-show="isShowToolbar" :class="{ security: toolMode === 'security', editor: toolMode === 'editor', disabled: isDisabledHeader, 'redact-mobile-hidden': ['redaction', 'remove'].includes(activeTool)}">
+  <div class="toolbar" v-show="isShowToolbar" :class="{ security: toolMode === 'security', editor: toolMode === 'editor', disabled: isDisabledHeader }">
     <div v-show="isMobileDevice && isShowLeftBtn" class="scroll-container left">
       <Button class="flip-button" @click="scrollLeft"><ArrowPrev /></Button>
     </div>

+ 1 - 1
packages/webview/src/components/ZoomOverlay/ZoomOverlay.vue

@@ -12,7 +12,7 @@
           :show-arrow="false"
           to="#outerContainer"
           :raw="true"
-          :z-index="3"
+          :z-index="4"
           :disabled="!load"
         >
           <template #trigger>