瀏覽代碼

fix: 优化 outline

liutian 1 年之前
父節點
當前提交
6cb0bb2b9b

+ 36 - 0
packages/core/src/Outline.ts

@@ -0,0 +1,36 @@
+export default class Outline {
+  doc: number
+  messageHandler: any
+  outline: any
+  index: number
+  children: Outline[] | []
+  parent: Outline | null
+
+  constructor(options: {
+    doc: number,
+    messageHandler: any,
+    outline: any,
+    index: number,
+    children: Outline[] | [],
+    parent: Outline | null
+  }) {
+    this.doc = options.doc
+    this.messageHandler = options.messageHandler
+    this.outline = options.outline
+    this.index = options.index
+    this.children = options.children || []
+    this.parent = options.parent
+  }
+
+  get pageNumber() {
+    return this.outline.pageNumber
+  }
+
+  get title() {
+    return this.outline.title
+  }
+
+  getOutline() {
+    return this.outline
+  }
+}

+ 0 - 25
packages/core/src/Outlines.ts

@@ -1,25 +0,0 @@
-export default class Outlines {
-  doc: number
-  messageHandler: any
-  outlines: any
-
-  constructor(options: {
-    doc: number,
-    messageHandler: any
-  }) {
-    this.doc = options.doc
-    this.messageHandler = options.messageHandler
-  }
-
-  async init() {
-    const outlines = await this.messageHandler.sendWithPromise('GetOutlines', {
-      doc: this.doc
-    })
-    console.log('outlines', outlines)
-    this.outlines = outlines
-  }
-
-  getOutlines() {
-    return this.outlines
-  }
-}

+ 28 - 12
packages/core/src/index.js

@@ -21,8 +21,8 @@ import { PDFPresentationMode } from "./pdf_presentation_mode.js";
 import annotationStore from "./annotation_store"
 import { InkSign } from "./ink_sign"
 import MessageHandler from "./message_handler"
-import JSZip from 'jszip';
-import Outlines from './Outlines'
+import JSZip from 'jszip'
+import Outline from './Outline'
 
 GlobalWorkerOptions.workerSrc = './lib/pdf.worker.min.js'
 const CMAP_URL = './cmaps/'
@@ -37,7 +37,7 @@ class ComPDFKitViewer {
     this.printService = null
     this.pdfSidebar = null
     this.pdfOutlineViewer = null
-    this.outlines = null
+    this.outlines = []
     this.pdfLayerViewer = null
     this.pdfDocument = null
     this.downloadComplete = false
@@ -433,7 +433,7 @@ class ComPDFKitViewer {
 
   getOutlines() {
     if (this.outlines) {
-      return this.outlines.getOutlines()
+      return this.outlines
     }
   }
 
@@ -770,10 +770,32 @@ class ComPDFKitViewer {
       pdfThumbnailViewer.setDocument(pdfDocument);
     }
 
-    if (this.outlines) {
-      await this.outlines.init()
+    const doc = this.doc
+    const messageHandler = this.messageHandler
+    const outlines = await messageHandler.sendWithPromise('GetOutlines', {
+      doc
+    })
+
+    function generateOutline(outline, index, parent) {
+      const outlineItem = new Outline({
+        outline,
+        index,
+        doc,
+        messageHandler,
+        parent
+      })
+      outline.children.forEach(function (outline, index) {
+        outlineItem.children.push(generateOutline(outline, index, outlineItem))
+      })
+
+      return outlineItem
     }
 
+    outlines.forEach((outline, index) => {
+      const outlineItem = generateOutline(outline, index, null)
+      this.outlines.push(outlineItem)
+    })
+
     firstPagePromise.then(pdfPage => {
       let hash = null;
 
@@ -1372,14 +1394,8 @@ class ComPDFKitViewer {
       });
       this.pdfSidebar.onToggled = this.forceRendering.bind(this);
     }
-
-    this.outlines = new Outlines({
-      doc: this.doc,
-      messageHandler: this.messageHandler
-    })
   }
 
-
   setInitialView(
     storedHash,
     { rotation, sidebarView, scrollMode, spreadMode } = {}

+ 1 - 1
packages/core/src/worker/compdfkit_worker.js

@@ -1266,7 +1266,7 @@ function getOutlineAction(doc, outlinePtr, actionType, outline) {
   if (actionType === 1) {
     PDFDestination = {}
     Module._GetOutlineDestination(doc, outlinePtr)
-    outline.destPage = PDFDestination.PageIndex
+    outline.pageNumber = PDFDestination.PageIndex + 1
     outline.posX = PDFDestination.PosX < 0 ? 0 : PDFDestination.PosX
     outline.posY = PDFDestination.PosY < 0 ? 0 : PDFDestination.PosY
   } else if (actionType === 6) {

+ 33 - 2
packages/webview/src/components/Outlines/Outlines.vue

@@ -1,8 +1,8 @@
 <template>
   <div class="outline-container">
-    <div class="outline-item" :class="isOutlineActive && 'selected'" @click="toggleOutline">
+    <div class="outline-item" :class="isOutlineActive && 'selected'" @click="goToOutline">
       <div class="outline-item-toggle" :style="{ marginLeft: 12 * outline.level + 'px' }">
-        <TreeArrow v-if="outline.children.length" @click="isExpanded = !isExpanded" />
+        <TreeArrow v-if="outline.children.length" @click="toggleOutline" />
       </div>
       <div class="outline-item-title">{{ outline.title }}</div>
     </div>
@@ -27,9 +27,40 @@ const { outline, activeOutline } = defineProps({
   }
 })
 
+const splitter = '-'
+
+console.log(outline)
+const getOutlineId = (outline) => {
+  const name = outline.getName();
+  const path = this.getPath(outline);
+
+  return `${path}${splitter}${name}`;
+}
+
+const getPath = (outline) => {
+  return getPathArray(outline).reverse().join(splitter);
+}
+
+const getPathArray = (outline) => {
+  const paths = [];
+
+  let curr = outline;
+  while (curr) {
+    paths.push(curr.getIndex());
+    curr = curr.getParent();
+  }
+
+  return paths;
+}
+
 const isExpanded = ref(false)
 const isOutlineActive = computed(() => activeOutline === outline)
 
+const goToOutline = (e) => {
+  e.stopPropagation()
+  isExpanded.value = !isExpanded.value
+}
+
 const toggleOutline = () => {
   emits('update:activeOutline', outline)
 }

+ 2 - 6
packages/webview/src/components/Outlines/OutlinesPanel.vue

@@ -1,20 +1,16 @@
 <template>
   <div class="outline">
     <div class="outline-title">{{ $t('leftPanel.outlines') }}</div>
-    <Outlines v-for="outline in outlines" :outline="outline" :activeOutline="activeOutline" @update:activeOutline="handleUpdateActiveOutline" />
+    <Outlines v-for="outline in outlines" :outline="outline" />
   </div>
 </template>
 
 <script setup>
-import { ref, computed } from 'vue'
+import { computed } from 'vue'
 import { useDocumentStore } from '@/stores/modules/document'
 const useDocument = useDocumentStore()
 
 const outlines = computed(() => useDocument.getOutlines)
-const activeOutline = ref(null)
-const handleUpdateActiveOutline = (outline) => {
-  activeOutline.value = outline
-}
 </script>
 
 <style lang="scss">