liutian 1 год назад
Родитель
Сommit
155562094b

+ 14 - 1
packages/core/src/Outline.ts

@@ -5,6 +5,7 @@ export default class Outline {
   index: number
   children: Outline[] | []
   parent: Outline | null
+  document: any
 
   constructor(options: {
     doc: number,
@@ -12,7 +13,8 @@ export default class Outline {
     outline: any,
     index: number,
     children: Outline[] | [],
-    parent: Outline | null
+    parent: Outline | null,
+    document: any
   }) {
     this.doc = options.doc
     this.messageHandler = options.messageHandler
@@ -20,6 +22,7 @@ export default class Outline {
     this.index = options.index
     this.children = options.children || []
     this.parent = options.parent
+    this.document = options.document
   }
 
   get pageNumber() {
@@ -30,6 +33,16 @@ export default class Outline {
     return this.outline.title
   }
 
+  get level() {
+    return this.outline.level
+  }
+
+  goTo() {
+    this.document.scrollPageIntoView({
+      pageNumber: this.pageNumber,
+    })
+  }
+
   getOutline() {
     return this.outline
   }

+ 17 - 162
packages/core/src/index.js

@@ -2,20 +2,18 @@ import { getDocument, GlobalWorkerOptions, InvalidPDFException, MissingPDFExcept
 import CryptoJS from 'crypto-js';
 import printJS from 'print-js';
 import { saveAs } from 'file-saver';
-import { LinkTarget, PDFLinkService } from "./pdf_link_service"
-import { PDFPrint, PDFPrintServiceFactory } from "./pdf_print_service"
+import { PDFLinkService } from "./pdf_link_service"
 import { PasswordPrompt } from "./password_prompt.js";
 import { PDFFindBar } from "./pdf_find_bar.js";
 import { PDFFindController } from "./pdf_find_controller.js";
 import { PDFViewer } from './pdf_viewer'
 import { PDFOutlineViewer } from "./pdf_outline_viewer.js";
-import { PDFLayerViewer } from "./pdf_layer_viewer.js";
 import { PDFThumbnailViewer } from './pdf_thumbnail_viewer'
 import { PDFRenderingQueue } from "./pdf_rendering_queue";
 import { PDFSidebar } from "./pdf_sidebar.js";
 import { GenericExternalServices } from "./genericcom.js";
-import { CursorTool, PDFCursorTools } from "./pdf_cursor_tools.js";
-import { EventBus, isValidRotation, isValidScrollMode, shadow, isValidSpreadMode, toDateObject, findIndex, scrollIntoView, getElementsByTagName, DEFAULT_SCALE_VALUE, SidebarView, parseAnnotationFromXml, PromiseExt } from './ui_utils'
+import {  PDFCursorTools } from "./pdf_cursor_tools.js";
+import { EventBus, isValidRotation, isValidScrollMode, shadow, isValidSpreadMode, toDateObject, findIndex, scrollIntoView, DEFAULT_SCALE_VALUE, SidebarView, parseAnnotationFromXml, PromiseExt } from './ui_utils'
 import { RenderingStates, AnnotationType, AnnotationTypeString } from "../constants";
 import { PDFPresentationMode } from "./pdf_presentation_mode.js";
 import annotationStore from "./annotation_store"
@@ -100,12 +98,12 @@ class ComPDFKitViewer {
     this.pdfViewer.currentPageNumber = val;
   }
 
-  get scale() {
-    return this.pdfViewer.currentScale;
+  get currentPageNumber() {
+    return this.pdfViewer.currentPageNumber
   }
 
-  get supportsPrinting() {
-    return PDFPrintServiceFactory.instance.supportsPrinting;
+  get scale() {
+    return this.pdfViewer.currentScale;
   }
 
   initConfig(options) {
@@ -167,10 +165,8 @@ class ComPDFKitViewer {
     thumbnailView,
     annotationView,
     outlineView,
-    layerView,
     findbarView,
     toggleButton,
-    annotationMode = 0
   }) {
     this._initializeViewerComponents({
       container,
@@ -178,10 +174,8 @@ class ComPDFKitViewer {
       thumbnailView,
       annotationView,
       outlineView,
-      layerView,
       findbarView,
       toggleButton,
-      annotationMode
     })
     this.initBindEvents()
     if (thumbnailView && annotationView) {
@@ -437,6 +431,12 @@ class ComPDFKitViewer {
     }
   }
 
+  scrollPageIntoView({
+    pageNumber,
+  }) {
+    // if (this.currentPage)
+  }
+
   async search(value) {
     const searchResults = await this.messageHandler.sendWithPromise('Search', {
       pagesPtr: this.pagesPtr,
@@ -782,7 +782,8 @@ class ComPDFKitViewer {
         index,
         doc,
         messageHandler,
-        parent
+        parent,
+        document: this
       })
       outline.children.forEach(function (outline, index) {
         outlineItem.children.push(generateOutline(outline, index, outlineItem))
@@ -824,13 +825,6 @@ class ComPDFKitViewer {
         }
         this.pdfOutlineViewer?.render({ outline, pdfDocument });
       });
-
-      pdfViewer.optionalContentConfigPromise.then(optionalContentConfig => {
-        if (pdfDocument !== this.pdfDocument) {
-          return; // The document was closed while the layers resolved.
-        }
-        this.pdfLayerViewer?.render({ optionalContentConfig, pdfDocument });
-      });
     });
 
     this.eventBus.dispatch("documentinit", { source: this });
@@ -851,13 +845,8 @@ class ComPDFKitViewer {
   bindEvents() {
     const { eventBus, _boundEvents } = this;
 
-    _boundEvents.beforePrint = this.beforePrint.bind(this);
-    _boundEvents.afterPrint = this.afterPrint.bind(this);
-
     eventBus._on("resize", this.webViewerResize.bind(this));
     eventBus._on("pagerendered", this.webViewerPageRendered.bind(this));
-    eventBus._on("beforeprint", _boundEvents.beforePrint);
-    eventBus._on("afterprint", _boundEvents.afterPrint);
     eventBus._on("updateviewarea", this.webViewerUpdateViewarea.bind(this));
     eventBus._on("pagechanging", this.webViewerPageChanging.bind(this));
     eventBus._on("rotationchanging", this.webViewerRotationChanging.bind(this));
@@ -874,12 +863,10 @@ class ComPDFKitViewer {
     eventBus._on("scalechanged", this.webViewerScaleChanged.bind(this));
     eventBus._on("rotatecw", this.webViewerRotateCw.bind(this));
     eventBus._on("rotateccw", this.webViewerRotateCcw.bind(this));
-    eventBus._on("optionalcontentconfig", this.webViewerOptionalContentConfig.bind(this));
     eventBus._on("switchscrollmode", this.webViewerSwitchScrollMode.bind(this));
     eventBus._on("scrollmodechanged", this.webViewerScrollModeChanged.bind(this));
     eventBus._on("switchspreadmode", this.webViewerSwitchSpreadMode.bind(this));
     eventBus._on("spreadmodechanged", this.webViewerSpreadModeChanged.bind(this));
-    eventBus._on("documentproperties", this.webViewerDocumentProperties.bind(this));
     eventBus._on("findfromurlhash", this.webViewerFindFromUrlHash.bind(this));
     eventBus._on("updatefindmatchescount", this.webViewerUpdateFindMatchesCount.bind(this));
     eventBus._on("updatefindcontrolstate", this.webViewerUpdateFindControlState.bind(this));
@@ -909,12 +896,6 @@ class ComPDFKitViewer {
         hash: document.location.hash.substring(1),
       });
     };
-    _boundEvents.windowBeforePrint = () => {
-      eventBus.dispatch("beforeprint", { source: window });
-    };
-    _boundEvents.windowAfterPrint = () => {
-      eventBus.dispatch("afterprint", { source: window });
-    };
     _boundEvents.windowUpdateFromSandbox = event => {
       eventBus.dispatch("updatefromsandbox", {
         source: window,
@@ -924,8 +905,6 @@ class ComPDFKitViewer {
 
     window.addEventListener("resize", _boundEvents.windowResize);
     window.addEventListener("hashchange", _boundEvents.windowHashChange);
-    window.addEventListener("beforeprint", _boundEvents.windowBeforePrint);
-    window.addEventListener("afterprint", _boundEvents.windowAfterPrint);
     window.addEventListener(
       "updatefromsandbox",
       _boundEvents.windowUpdateFromSandbox
@@ -958,14 +937,13 @@ class ComPDFKitViewer {
     this._contentDispositionFilename = null;
     this._contentLength = null;
     this._saveInProgress = false;
-    this._docStats = null;
     this._hasAnnotationEditors = false;
 
     this.pdfSidebar?.reset();
     this.pdfOutlineViewer?.reset();
     this.pdfAttachmentViewer?.reset();
-    this.pdfLayerViewer?.reset();
 
+    this.outlines = []
     this.#pwd = ''
     this._pdfId = null
     this.annotations = null
@@ -1264,10 +1242,8 @@ class ComPDFKitViewer {
     thumbnailView,
     annotationView,
     outlineView,
-    layerView,
     findbarView,
     toggleButton,
-    annotationMode
   }) {
     this.viewerContainer = viewer
     const pdfRenderingQueue = new PDFRenderingQueue();
@@ -1297,7 +1273,6 @@ class ComPDFKitViewer {
         color: this.color
       },
       annotationView,
-      annotationMode,
       renderingQueue: pdfRenderingQueue,
       linkService: pdfLinkService,
       findController,
@@ -1375,14 +1350,6 @@ class ComPDFKitViewer {
       });
     }
 
-    if (layerView) {
-      this.pdfLayerViewer = new PDFLayerViewer({
-        container: layerView,
-        eventBus: this.eventBus,
-        $t: this.$t
-      });
-    }
-
     if (toggleButton) {
       this.pdfSidebar = new PDFSidebar({
         elements: {
@@ -1530,7 +1497,6 @@ class ComPDFKitViewer {
       // Work-around issue 15324 by ignoring "resize" events during printing.
       return;
     }
-    pdfViewer._updateContainerHeightCss();
 
     if (!pdfDocument) {
       return;
@@ -1566,28 +1532,14 @@ class ComPDFKitViewer {
         thumbnailView.setImage(pageView);
       }
     }
-
-    // if (error) {
-    //   this.l10n.get("rendering_error").then(msg => {
-    //     this._otherError(msg, error);
-    //   });
-    // }
-
-    // It is a good time to report stream and font types.
-    this._reportDocumentStatsTelemetry();
   }
 
   get annotationMode() {
+    console.log(this._annotationMode)
     return this._annotationMode
   }
 
   set annotationMode(mode) {
-    if (this.annotationMode === mode) {
-      return
-    }
-    if (!this.pdfDocument) {
-      return;
-    }
     this._annotationMode = mode;
   }
 
@@ -1599,18 +1551,6 @@ class ComPDFKitViewer {
     this.pdfCursorTools.switchTool(mode);
   }
 
-  _reportDocumentStatsTelemetry() {
-    const { stats } = this.pdfDocument;
-    if (stats !== this._docStats) {
-      this._docStats = stats;
-
-      // this.externalServices.reportTelemetry({
-      //   type: "documentStats",
-      //   stats,
-      // });
-    }
-  }
-
   webViewerUpdateViewarea({ location }) {
     if (this.isInitialViewSet) {
       // Only update the storage when the document has been loaded *and* rendered.
@@ -1788,10 +1728,6 @@ class ComPDFKitViewer {
     this.zoomOut();
   }
 
-  webViewerPrint() {
-    this.triggerPrinting();
-  }
-
   webViewerPageNumberChanged(evt) {
     const pdfViewer = this.pdfViewer;
     // Note that for `<input type="number">` HTML elements, an empty string will
@@ -1821,9 +1757,6 @@ class ComPDFKitViewer {
   webViewerRotateCcw() {
     this.rotatePages(-90);
   }
-  webViewerOptionalContentConfig(evt) {
-    this.pdfViewer.optionalContentConfigPromise = evt.promise;
-  }
   webViewerSwitchScrollMode(mode) {
     this.pdfViewer.scrollMode = mode;
   }
@@ -1831,55 +1764,6 @@ class ComPDFKitViewer {
     this.pdfViewer.spreadMode = mode;
   }
 
-
-  beforePrint() {
-
-    if (this.printService) {
-      // There is no way to suppress beforePrint/afterPrint events,
-      // but PDFPrintService may generate double events -- this will ignore
-      // the second event that will be coming from native window.print().
-      return;
-    }
-
-    // The beforePrint is a sync method and we need to know layout before
-    // returning from this method. Ensure that we can get sizes of the pages.
-    if (!this.pdfViewer.pageViewsReady) {
-      // eslint-disable-next-line no-alert
-      window.alert('Warning: The PDF is not fully loaded for printing.');
-      return;
-    }
-
-    const pagesOverview = this.pdfViewer.getPagesOverview();
-    const printContainer = document.getElementById("printContainer");
-    const printResolution = 150;
-    const optionalContentConfigPromise =
-      this.pdfViewer.optionalContentConfigPromise;
-    const printService = PDFPrintServiceFactory.instance.createPrintService(
-      this.pdfDocument,
-      pagesOverview,
-      printContainer,
-      printResolution,
-      optionalContentConfigPromise
-    );
-    this.printService = printService;
-    this.forceRendering();
-    this.setTitle(this._docName);
-
-    printService.layout();
-
-  }
-
-  afterPrint() {
-    if (this.printService) {
-      this.printService.destroy();
-      this.printService = null;
-
-      this.pdfDocument?.annotationStorage.resetModified();
-    }
-    this.forceRendering();
-    this.setTitle(this._title);
-  }
-
   rotatePages(delta) {
     this.pdfViewer.pagesRotation += delta;
     // Note that the thumbnail viewer is updated, and rendering is triggered,
@@ -1897,9 +1781,6 @@ class ComPDFKitViewer {
       });
     }
   }
-  webViewerDocumentProperties() {
-    this.pdfDocumentProperties.open();
-  }
 
   webViewerFindFromUrlHash(evt) {
     this.eventBus.dispatch("find", {
@@ -2227,32 +2108,6 @@ class ComPDFKitViewer {
   }
 }
 
-function webViewerTouchStart(evt) {
-  if (
-    PDFViewerApplication.pdfViewer.isInPresentationMode ||
-    evt.touches.length < 2
-  ) {
-    return;
-  }
-  evt.preventDefault();
-
-  if (evt.touches.length !== 2) {
-    PDFViewerApplication._touchInfo = null;
-    return;
-  }
-
-  let [touch0, touch1] = evt.touches;
-  if (touch0.identifier > touch1.identifier) {
-    [touch0, touch1] = [touch1, touch0];
-  }
-  PDFViewerApplication._touchInfo = {
-    touch0X: touch0.pageX,
-    touch0Y: touch0.pageY,
-    touch1X: touch1.pageX,
-    touch1Y: touch1.pageY,
-  };
-}
-
 class PDFWorker {
   destroyed = false
   constructor() {

+ 1 - 0
packages/core/src/pdf_layer_viewer.js

@@ -148,6 +148,7 @@ class PDFLayerViewer extends BaseTreeViewer {
    * @param {PDFLayerViewerRenderParameters} params
    */
   render({ optionalContentConfig, pdfDocument }) {
+    console.log(90000)
     if (this._optionalContentConfig) {
       this.reset();
     }

+ 73 - 115
packages/core/src/pdf_page_view.js

@@ -1,21 +1,15 @@
 import {
-  AnnotationMode,
   createPromiseCapability,
   RenderingCancelledException,
   setLayerDimensions,
   SVGGraphics,
   shadow,
-  OPS,
   AbortException
 } from "pdfjs-dist/legacy/build/pdf";
 import {
-  approximateFraction,
   DEFAULT_SCALE,
-  docStyle,
-  OutputScale,
   RendererType,
   RenderingStates,
-  roundToDivide,
   TextLayerMode,
   maxCanvasPixels,
 } from "./ui_utils.js";
@@ -75,8 +69,6 @@ const MAX_CANVAS_PIXELS = maxCanvasPixels;
  * @implements {IRenderableView}
  */
 class PDFPageView {
-  #annotationMode = AnnotationMode.ENABLE_FORMS;
-
   #previousRotation = null;
 
   #useThumbnailCanvas = {
@@ -114,12 +106,8 @@ class PDFPageView {
     this.scale = options.scale || DEFAULT_SCALE;
     this.viewport = defaultViewport;
     this.pdfPageRotate = defaultViewport.rotation;
-    this._optionalContentConfigPromise =
-      options.optionalContentConfigPromise || null;
     this.hasRestrictedScaling = false;
     this.textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE;
-    this.#annotationMode =
-      options.annotationMode ?? AnnotationMode.ENABLE_FORMS;
     this.imageResourcesPath = options.imageResourcesPath || "";
     this.useOnlyCssZoom = options.useOnlyCssZoom || false;
     this.isOffscreenCanvasSupported = true;
@@ -195,21 +183,6 @@ class PDFPageView {
         "--scale-factor",
         this.scale * PixelsPerInch.PDF_TO_CSS_UNITS
       );
-
-      const { optionalContentConfigPromise } = options;
-      if (optionalContentConfigPromise) {
-        // Ensure that the thumbnails always display the *initial* document
-        // state, for documents with optional content.
-        optionalContentConfigPromise.then(optionalContentConfig => {
-          if (
-            optionalContentConfigPromise !== this._optionalContentConfigPromise
-          ) {
-            return;
-          }
-          this.#useThumbnailCanvas.initialOptionalContent =
-            optionalContentConfig.hasInitialVisibility;
-        });
-      }
     }
   }
 
@@ -665,28 +638,12 @@ class PDFPageView {
   update({
     scale = 0,
     rotation = null,
-    optionalContentConfigPromise = null,
     drawingDelay = -1,
   }) {
     this.scale = scale || this.scale;
     if (typeof rotation === "number") {
       this.rotation = rotation; // The rotation may be zero.
     }
-    if (optionalContentConfigPromise instanceof Promise) {
-      this._optionalContentConfigPromise = optionalContentConfigPromise;
-
-      // Ensure that the thumbnails always display the *initial* document state,
-      // for documents with optional content.
-      optionalContentConfigPromise.then(optionalContentConfig => {
-        if (
-          optionalContentConfigPromise !== this._optionalContentConfigPromise
-        ) {
-          return;
-        }
-        this.#useThumbnailCanvas.initialOptionalContent =
-          optionalContentConfig.hasInitialVisibility;
-      });
-    }
 
     const totalRotation = (this.rotation + this.pdfPageRotate) % 360;
     this.viewport = this.viewport.clone({
@@ -811,6 +768,7 @@ class PDFPageView {
     cancelExtraDelay = 0,
   } = {}) {
     if (this.paintTask) {
+      this.paintTask.cancel(cancelExtraDelay)
       this.paintTask = null;
     }
     this.resume = null;
@@ -1029,77 +987,76 @@ class PDFPageView {
     const paintTask = this.paintOnCanvas(canvasWrapper);
     paintTask.onRenderContinue = renderContinueCallback;
     this.paintTask = paintTask;
+    const resultPromise = paintTask.then(
+      async () => {
+        await finishPaintTask(null)
+        this.#renderTextLayer();
 
-    const resultPromise = paintTask.promise.then(
-      () => {
-        return finishPaintTask(null).then(async () => {
-          this.#renderTextLayer();
-
-          if (this.annotationLayer) {
-            await this._renderAnnotationLayer();
-          }
+        if (this.annotationLayer) {
+          await this._renderAnnotationLayer();
+        }
 
-          if (!this.annotationEditorLayer) {
-            const { annotationEditorUIManager, annotationStorage } = this.layerProperties();
+        if (!this.annotationEditorLayer) {
+          const { annotationEditorUIManager, annotationStorage } = this.layerProperties();
 
-            if (!annotationEditorUIManager) {
-              return;
-            }
-            this.annotationEditorLayer = new PDFAnnotationLayer({
-              uiManager: annotationEditorUIManager,
-              annotationStorage,
-              pageIndex: this.pageIndex,
-              pageDiv: div,
-              viewport: this.viewport,
-              scale: this.scale,
-              annotations,
-              accessibilityManager: this._accessibilityManager,
-            });
-          }
-          this._renderAnnotationEditorLayer();
-          if (!this.compdfAnnotationLayer) {
-            this.compdfAnnotationLayer = new ComPDFAnnotationLayer({
-              annotationStore: this.annotationStore,
-              messageHandler: this.messageHandler,
-              pageViewer: this,
-              annotations,
-              annotationsAll,
-              viewport: this.viewport,
-              scale: this.scale,
-              pageIndex: this.pageIndex,
-              pageDiv: div,
-              eventBus: this.eventBus,
-              selected: this.selected,
-              $t: this.$t
-            })
-          }
-          this.compdfAnnotationLayer.render(this.viewport)
-
-          // this.AnnotationManager = new AnnotationManager({
-          //   annotations,
-          //   container: div,
-          //   viewport: this.viewport,
-          // })
-
-          if (!this.contentContainer) {
-            this.contentContainer = new ContentContainer({
-              annotationStore: this.annotationStore,
-              pageViewer: this,
-              annotations,
-              annotationsAll,
-              viewport: this.viewport,
-              scale: this.scale,
-              pageIndex: this.id - 1,
-              pageDiv: div,
-              eventBus: this.eventBus,
-              selected: this.selected,
-              $t: this.$t,
-              pagePtr: this.pagesPtr[this.pageIndex].pagePtr,
-              messageHandler: this.messageHandler
-            })
-            this.contentContainer.render()
+          if (!annotationEditorUIManager) {
+            return;
           }
-        });
+          this.annotationEditorLayer = new PDFAnnotationLayer({
+            uiManager: annotationEditorUIManager,
+            annotationStorage,
+            pageIndex: this.pageIndex,
+            pageDiv: div,
+            viewport: this.viewport,
+            scale: this.scale,
+            annotations,
+            accessibilityManager: this._accessibilityManager,
+          });
+        }
+        this._renderAnnotationEditorLayer();
+
+        if (!this.compdfAnnotationLayer) {
+          this.compdfAnnotationLayer = new ComPDFAnnotationLayer({
+            annotationStore: this.annotationStore,
+            messageHandler: this.messageHandler,
+            pageViewer: this,
+            annotations,
+            annotationsAll,
+            viewport: this.viewport,
+            scale: this.scale,
+            pageIndex: this.pageIndex,
+            pageDiv: div,
+            eventBus: this.eventBus,
+            selected: this.selected,
+            $t: this.$t
+          })
+        }
+        this.compdfAnnotationLayer.render(this.viewport)
+
+        // this.AnnotationManager = new AnnotationManager({
+        //   annotations,
+        //   container: div,
+        //   viewport: this.viewport,
+        // })
+
+        if (!this.contentContainer) {
+          this.contentContainer = new ContentContainer({
+            annotationStore: this.annotationStore,
+            pageViewer: this,
+            annotations,
+            annotationsAll,
+            viewport: this.viewport,
+            scale: this.scale,
+            pageIndex: this.pageIndex,
+            pageDiv: div,
+            eventBus: this.eventBus,
+            selected: this.selected,
+            $t: this.$t,
+            pagePtr: this.pagesPtr[this.pageIndex].pagePtr,
+            messageHandler: this.messageHandler
+          })
+        }
+        this.contentContainer.render()
       },
       function (reason) {
         return finishPaintTask(reason);
@@ -1129,10 +1086,10 @@ class PDFPageView {
     return resultPromise;
   }
 
-  paintOnCanvas(canvasWrapper) {
+  async paintOnCanvas(canvasWrapper) {
     const renderCapability = createPromiseCapability();
     const result = {
-      promise: renderCapability.promise,
+      promise: renderCapability,
       onRenderContinue(cont) {
         cont();
       },
@@ -1200,6 +1157,9 @@ class PDFPageView {
       }
     };
 
+    renderTask.cancel = function() {
+    }
+
     renderTask.then(
       function ({ imageArray }) {
         ctx.clearRect(0, 0, canvasWidth, canvasHeight)
@@ -1246,9 +1206,7 @@ class PDFPageView {
       scale: PixelsPerInch.PDF_TO_CSS_UNITS,
     });
     const promise = pdfPage
-      .getOperatorList({
-        annotationMode: this.#annotationMode,
-      })
+      .getOperatorList()
       .then(opList => {
         ensureNotCancelled();
         const svgGfx = new SVGGraphics(pdfPage.commonObjs, pdfPage.objs);

+ 0 - 353
packages/core/src/pdf_print_service.js

@@ -1,353 +0,0 @@
-/* Copyright 2016 Mozilla Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import { AnnotationMode } from "pdfjs-dist/legacy/build/pdf";
-import {
-  PixelsPerInch,
-} from '../constants'
-
-let activeService = null;
-let dialog = null;
-let overlayManager = null;
-
-// Renders the page to the canvas of the given print service, and returns
-// the suggested dimensions of the output page.
-function renderPage(
-  activeServiceOnEntry,
-  pdfDocument,
-  pageNumber,
-  size,
-  printResolution,
-  optionalContentConfigPromise,
-  printAnnotationStoragePromise
-) {
-  const scratchCanvas = activeService.scratchCanvas;
-
-  // The size of the canvas in pixels for printing.
-  const PRINT_UNITS = printResolution / PixelsPerInch.PDF;
-  scratchCanvas.width = Math.floor(size.width * PRINT_UNITS);
-  scratchCanvas.height = Math.floor(size.height * PRINT_UNITS);
-
-  const ctx = scratchCanvas.getContext("2d");
-  ctx.save();
-  ctx.fillStyle = "rgb(255, 255, 255)";
-  ctx.fillRect(0, 0, scratchCanvas.width, scratchCanvas.height);
-  ctx.restore();
-
-  return Promise.all([
-    pdfDocument.getPage(pageNumber),
-    printAnnotationStoragePromise,
-  ]).then(function ([pdfPage, printAnnotationStorage]) {
-    const renderContext = {
-      canvasContext: ctx,
-      transform: [PRINT_UNITS, 0, 0, PRINT_UNITS, 0, 0],
-      viewport: pdfPage.getViewport({ scale: 1, rotation: size.rotation }),
-      intent: "print",
-      annotationMode: AnnotationMode.ENABLE_STORAGE,
-      optionalContentConfigPromise,
-      printAnnotationStorage,
-    };
-    return pdfPage.render(renderContext).promise;
-  });
-}
-
-function PDFPrintService(
-  pdfDocument,
-  pagesOverview,
-  printContainer,
-  printResolution,
-  optionalContentConfigPromise = null,
-  printAnnotationStoragePromise = null,
-  l10n
-) {
-  this.pdfDocument = pdfDocument;
-  this.pagesOverview = pagesOverview;
-  this.printContainer = printContainer;
-  this._printResolution = printResolution || 150;
-  this._optionalContentConfigPromise =
-    optionalContentConfigPromise || pdfDocument.getOptionalContentConfig();
-  this._printAnnotationStoragePromise =
-    printAnnotationStoragePromise || Promise.resolve();
-  this.l10n = l10n;
-  this.currentPage = -1;
-  // The temporary canvas where renderPage paints one page at a time.
-  this.scratchCanvas = document.createElement("canvas");
-}
-
-PDFPrintService.prototype = {
-  layout() {
-    this.throwIfInactive();
-
-    const body = document.querySelector("body");
-    body.setAttribute("data-pdfjsprinting", true);
-    const hasEqualPageSizes = this.pagesOverview.every(function (size) {
-      return (
-        size.width === this.pagesOverview[0].width &&
-        size.height === this.pagesOverview[0].height
-      );
-    }, this);
-    if (!hasEqualPageSizes) {
-      console.warn(
-        "Not all pages have the same size. The printed " +
-          "result may be incorrect!"
-      );
-    }
-
-    // Insert a @page + size rule to make sure that the page size is correctly
-    // set. Note that we assume that all pages have the same size, because
-    // variable-size pages are not supported yet (e.g. in Chrome & Firefox).
-    // TODO(robwu): Use named pages when size calculation bugs get resolved
-    // (e.g. https://crbug.com/355116) AND when support for named pages is
-    // added (http://www.w3.org/TR/css3-page/#using-named-pages).
-    // In browsers where @page + size is not supported (such as Firefox,
-    // https://bugzil.la/851441), the next stylesheet will be ignored and the
-    // user has to select the correct paper size in the UI if wanted.
-    this.pageStyleSheet = document.createElement("style");
-    const pageSize = this.pagesOverview[0];
-    this.pageStyleSheet.textContent =
-      "@page { size: " + pageSize.width + "pt " + pageSize.height + "pt;}";
-    body.append(this.pageStyleSheet);
-  },
-
-  destroy() {
-    if (activeService !== this) {
-      // |activeService| cannot be replaced without calling destroy() first,
-      // so if it differs then an external consumer has a stale reference to us.
-      return;
-    }
-    // this.printContainer.textContent = "";
-
-    const body = document.querySelector("body");
-    body.removeAttribute("data-pdfjsprinting");
-
-    if (this.pageStyleSheet) {
-      this.pageStyleSheet.remove();
-      this.pageStyleSheet = null;
-    }
-    this.scratchCanvas.width = this.scratchCanvas.height = 0;
-    this.scratchCanvas = null;
-    activeService = null;
-    dialog.classList.remove('show')
-  },
-
-  renderPages() {
-    const pageCount = this.pagesOverview.length;
-    const renderNextPage = (resolve, reject) => {
-      this.throwIfInactive();
-      if (++this.currentPage >= pageCount) {
-        renderProgress(pageCount, pageCount);
-        resolve();
-        return;
-      }
-      const index = this.currentPage;
-      renderProgress(index, pageCount);
-      renderPage(
-        this,
-        this.pdfDocument,
-        /* pageNumber = */ index + 1,
-        this.pagesOverview[index],
-        this._printResolution,
-        this._optionalContentConfigPromise,
-        this._printAnnotationStoragePromise
-      )
-        .then(this.useRenderedPage.bind(this))
-        .then(function () {
-          renderNextPage(resolve, reject);
-        }, reject);
-    };
-    return new Promise(renderNextPage);
-  },
-
-  useRenderedPage() {
-    this.throwIfInactive();
-    const img = document.createElement("img");
-    const scratchCanvas = this.scratchCanvas;
-    if ("toBlob" in scratchCanvas) {
-      scratchCanvas.toBlob(function (blob) {
-        img.src = URL.createObjectURL(blob);
-      });
-    } else {
-      img.src = scratchCanvas.toDataURL();
-    }
-
-    const wrapper = document.createElement("div");
-    wrapper.className = "printedPage";
-    wrapper.append(img);
-    this.printContainer.append(wrapper);
-
-    return new Promise(function (resolve, reject) {
-      img.onload = () => {
-        resolve(img);
-      };
-      img.onerror = reject;
-    });
-  },
-
-  performPrint() {
-    this.throwIfInactive();
-    return new Promise(resolve => {
-      // Push window.print in the macrotask queue to avoid being affected by
-      // the deprecation of running print() code in a microtask, see
-      // https://github.com/mozilla/pdf.js/issues/7547.
-      setTimeout(() => {
-        if (!this.active) {
-          resolve();
-          return;
-        }
-        print.call(window);
-        // Delay promise resolution in case print() was not synchronous.
-        setTimeout(resolve, 20); // Tidy-up.
-      }, 0);
-    });
-  },
-
-  get active() {
-    return this === activeService;
-  },
-
-  throwIfInactive() {
-    if (!this.active) {
-      throw new Error("This print request was cancelled or completed.");
-    }
-  },
-};
-
-const print = window.print;
-const PDFPrint = function () {
-  if (activeService) {
-    console.warn("Ignored window.print() because of a pending print job.");
-    return;
-  }
-  if (!dialog) {
-    dialog = document.getElementById("printServiceDialog")
-  }
-  try {
-    dispatchEvent("beforeprint");
-  } finally {
-    if (!activeService) {
-      console.error("Expected print service to be initialized.");
-      dialog.classList.remove('show')
-      return; // eslint-disable-line no-unsafe-finally
-    }
-    dialog.classList.add('show')
-    const activeServiceOnEntry = activeService;
-    
-    activeService.printContainer.textContent = "";
-    activeService
-      .renderPages()
-      .then(function () {
-        return activeServiceOnEntry.performPrint();
-      })
-      .catch(function (err) {
-        // Ignore any error messages.
-        console.log(err)
-      })
-      .then(function () {
-        // aborts acts on the "active" print request, so we need to check
-        // whether the print request (activeServiceOnEntry) is still active.
-        // Without the check, an unrelated print request (created after aborting
-        // this print request while the pages were being generated) would be
-        // aborted.
-        if (activeServiceOnEntry.active) {
-          abort();
-        }
-      });
-  }
-};
-
-function dispatchEvent(eventType) {
-  const event = document.createEvent("CustomEvent");
-  event.initCustomEvent(eventType, false, false, "custom");
-  window.dispatchEvent(event);
-}
-
-function abort() {
-  if (activeService) {
-    activeService.destroy();
-    dispatchEvent("afterprint");
-  }
-}
-
-function renderProgress(index, total) {
-  dialog ||= document.getElementById("printServiceDialog");
-  const progress = Math.round((100 * index) / total);
-  const progressBar = dialog.querySelector("progress");
-  const progressPerc = dialog.querySelector(".relative-progress");
-  progressBar.value = progress;
-  progressPerc.textContent = progress + '%'
-}
-
-window.addEventListener(
-  "keydown",
-  function (event) {
-    // Intercept Cmd/Ctrl + P in all browsers.
-    // Also intercept Cmd/Ctrl + Shift + P in Chrome and Opera
-    if (
-      event.keyCode === /* P= */ 80 &&
-      (event.ctrlKey || event.metaKey) &&
-      !event.altKey &&
-      (!event.shiftKey || window.chrome || window.opera)
-    ) {
-      window.print();
-
-      event.preventDefault();
-      event.stopImmediatePropagation();
-    }
-  },
-  true
-);
-
-if ("onbeforeprint" in window) {
-  // Do not propagate before/afterprint events when they are not triggered
-  // from within this polyfill. (FF / Chrome 63+).
-  const stopPropagationIfNeeded = function (event) {
-    if (event.detail !== "custom") {
-      event.stopImmediatePropagation();
-    }
-  };
-  window.addEventListener("beforeprint", stopPropagationIfNeeded);
-  window.addEventListener("afterprint", stopPropagationIfNeeded);
-}
-
-/* Abstract factory for the print service. */
-const PDFPrintServiceFactory = {
-  instance: {
-    supportsPrinting: true,
-
-    createPrintService(
-      pdfDocument,
-      pagesOverview,
-      printContainer,
-      printResolution,
-      optionalContentConfigPromise,
-      l10n
-    ) {
-      if (activeService) {
-        throw new Error("The print service is created and active.");
-      }
-      activeService = new PDFPrintService(
-        pdfDocument,
-        pagesOverview,
-        printContainer,
-        printResolution,
-        optionalContentConfigPromise,
-        l10n
-      );
-      return activeService;
-    },
-  },
-};
-
-export { PDFPrint, PDFPrintService, PDFPrintServiceFactory };

+ 0 - 3
packages/core/src/pdf_thumbnail_view.js

@@ -47,7 +47,6 @@ class PDFThumbnailView {
     container,
     id,
     defaultViewport,
-    optionalContentConfigPromise,
     linkService,
     renderingQueue,
     pageColors,
@@ -60,7 +59,6 @@ class PDFThumbnailView {
     this.rotation = 0;
     this.viewport = defaultViewport;
     this.pdfPageRotate = defaultViewport.rotation;
-    this._optionalContentConfigPromise = optionalContentConfigPromise || null;
     this.pageColors = pageColors || null;
 
     this.linkService = linkService;
@@ -281,7 +279,6 @@ class PDFThumbnailView {
       canvasContext: ctx,
       transform,
       viewport: drawViewport,
-      optionalContentConfigPromise: this._optionalContentConfigPromise,
       pageColors: this.pageColors,
     };
     const renderTask = (this.renderTask = pdfPage.render(renderContext));

+ 0 - 2
packages/core/src/pdf_thumbnail_viewer.js

@@ -182,7 +182,6 @@ class PDFThumbnailViewer {
       return;
     }
     const firstPagePromise = pdfDocument.getPage(1);
-    const optionalContentConfigPromise = pdfDocument.getOptionalContentConfig();
 
     firstPagePromise
       .then(firstPdfPage => {
@@ -194,7 +193,6 @@ class PDFThumbnailViewer {
             container: this.container,
             id: pageNum,
             defaultViewport: viewport.clone(),
-            optionalContentConfigPromise,
             linkService: this.linkService,
             renderingQueue: this.renderingQueue,
             pageColors: this.pageColors,

+ 4 - 77
packages/core/src/pdf_viewer.js

@@ -129,16 +129,8 @@ class PDFPageViewBuffer {
 class PDFViewer {
   #buffer = null;
 
-  #annotationMode = AnnotationMode.ENABLE_FORMS;
-
-  #containerTopLeft = null;
-
   #enablePermissions = false;
 
-  #previousContainerHeight = 0;
-
-  // #resizeObserver = new ResizeObserver(this.#resizeObserverCallback.bind(this));
-
   #scrollModePageState = null;
 
   #onVisibilityChange = null;
@@ -171,10 +163,7 @@ class PDFViewer {
     this.downloadManager = options.downloadManager || null;
     this.findController = options.findController || null;
     this.removePageBorders = false;
-    this._scriptingManager = options.scriptingManager || null;
     this.textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE;
-    this.#annotationMode =
-      options.annotationMode ?? AnnotationMode.ENABLE_FORMS;
     this._annotationEditorMode =
       options.annotationEditorMode ?? AnnotationEditorType.NONE;
     this.imageResourcesPath = options.imageResourcesPath || "";
@@ -222,8 +211,6 @@ class PDFViewer {
     if (this.removePageBorders) {
       this.viewer.classList.add("removePageBorders");
     }
-
-    this._updateContainerHeightCss();
   }
 
   get pagesCount() {
@@ -248,20 +235,6 @@ class PDFViewer {
     });
   }
 
-  /**
-   * @type {boolean}
-   */
-  get renderForms() {
-    return this.#annotationMode === AnnotationMode.ENABLE_FORMS;
-  }
-
-  /**
-   * @type {boolean}
-   */
-  get enableScripting() {
-    return !!this._scriptingManager;
-  }
-
   /**
    * @type {number}
    */
@@ -455,9 +428,6 @@ class PDFViewer {
       get downloadManager() {
         return self.downloadManager;
       },
-      get enableScripting() {
-        return !!self._scriptingManager;
-      },
       get fieldObjectsPromise() {
         return self.pdfDocument?.getFieldObjects();
       },
@@ -480,7 +450,6 @@ class PDFViewer {
   #initializePermissions(permissions) {
     const params = {
       annotationEditorMode: this._annotationEditorMode,
-      annotationMode: this.#annotationMode,
       textLayerMode: this.textLayerMode,
     };
     if (!permissions) {
@@ -497,8 +466,7 @@ class PDFViewer {
 
     if (
       !permissions.includes(PermissionFlag.MODIFY_ANNOTATIONS) &&
-      !permissions.includes(PermissionFlag.FILL_INTERACTIVE_FORMS) &&
-      this.#annotationMode === AnnotationMode.ENABLE_FORMS
+      !permissions.includes(PermissionFlag.FILL_INTERACTIVE_FORMS)
     ) {
       params.annotationMode = AnnotationMode.ENABLE;
     }
@@ -560,7 +528,6 @@ class PDFViewer {
       this._resetView();
 
       this.findController?.setDocument(null);
-      this._scriptingManager?.setDocument(null);
 
       if (this._annotationEditorUIManager) {
         this._annotationEditorUIManager.destroy();
@@ -646,7 +613,7 @@ class PDFViewer {
         this._firstPageCapability.resolve(firstPdfPage);
         this._optionalContentConfigPromise = optionalContentConfigPromise;
 
-        const { annotationEditorMode, annotationMode, textLayerMode } =
+        const { annotationEditorMode, textLayerMode } =
           this.#initializePermissions(permissions);
 
         if (annotationEditorMode !== AnnotationEditorType.DISABLE) {
@@ -696,7 +663,6 @@ class PDFViewer {
             optionalContentConfigPromise,
             renderingQueue: this.renderingQueue,
             textLayerMode,
-            annotationMode: this.#annotationMode,
             imageResourcesPath: this.imageResourcesPath,
             renderer:
               typeof PDFJSDev === "undefined" ||
@@ -743,7 +709,6 @@ class PDFViewer {
         // rendered so we don't tie up too many resources early on.
         this.#onePageRenderedOrForceFetch().then(async () => {
           this.findController?.setDocument(pdfDocument); // Enable searching.
-          this._scriptingManager?.setDocument(pdfDocument); // Enable scripting.
 
           if (this._annotationEditorUIManager) {
             // Ensure that the Editor buttons, in the toolbar, are updated.
@@ -1633,6 +1598,7 @@ class PDFViewer {
    */
   get optionalContentConfigPromise() {
     if (!this.pdfDocument) {
+      console.log(89898)
       return Promise.resolve(null);
     }
     if (!this._optionalContentConfigPromise) {
@@ -1641,6 +1607,7 @@ class PDFViewer {
       // promise has resolved; won't (normally) happen in the default viewer.
       return this.pdfDocument.getOptionalContentConfig();
     }
+    console.log(8989898989)
     return this._optionalContentConfigPromise;
   }
 
@@ -1663,11 +1630,6 @@ class PDFViewer {
     this._optionalContentConfigPromise = promise;
 
     this.refresh(false, { optionalContentConfigPromise: promise });
-
-    this.eventBus.dispatch("optionalcontentconfigchanged", {
-      source: this,
-      promise,
-    });
   }
 
   /**
@@ -2009,33 +1971,6 @@ class PDFViewer {
     this._setScale(newScale, options);
   }
 
-  _updateContainerHeightCss(height = this.container.clientHeight) {
-    if (height !== this.#previousContainerHeight) {
-      this.#previousContainerHeight = height;
-
-      docStyle.setProperty("--viewer-container-height", `${height}px`);
-    }
-  }
-
-  #resizeObserverCallback(entries) {
-    for (const entry of entries) {
-      if (entry.target === this.container) {
-        this._updateContainerHeightCss(
-          Math.floor(entry.borderBoxSize[0].blockSize)
-        );
-        this.#containerTopLeft = null;
-        break;
-      }
-    }
-  }
-
-  get containerTopLeft() {
-    return (this.#containerTopLeft ||= [
-      this.container.offsetTop,
-      this.container.offsetLeft,
-    ]);
-  }
-
   /**
    * @type {number}
    */
@@ -2071,14 +2006,6 @@ class PDFViewer {
     this._annotationEditorUIManager.updateMode(mode);
   }
 
-  // eslint-disable-next-line accessor-pairs
-  set annotationEditorParams({ type, value }) {
-    if (!this._annotationEditorUIManager) {
-      throw new Error(`The AnnotationEditor is not enabled.`);
-    }
-    this._annotationEditorUIManager.updateParams(type, value);
-  }
-
   refresh(noUpdate = false, updateArgs = Object.create(null)) {
     if (!this.pdfDocument) {
       return;

+ 42 - 0
packages/core/src/utils.ts

@@ -0,0 +1,42 @@
+function scrollIntoView(element: HTMLDivElement, spot: {
+  left?: number,
+  top?: number
+}, scrollMatches = false) {
+  // Assuming offsetParent is available (it's not available when viewer is in
+  // hidden iframe or object). We have to scroll: if the offsetParent is not set
+  // producing the error. See also animationStarted.
+  let parent = element.offsetParent as HTMLDivElement
+  if (!parent) {
+    console.error("offsetParent is not set -- cannot scroll");
+    return;
+  }
+  let offsetY = element.offsetTop + element.clientTop;
+  let offsetX = element.offsetLeft + element.clientLeft;
+  while (
+    (parent.clientHeight === parent.scrollHeight &&
+      parent.clientWidth === parent.scrollWidth) ||
+    (scrollMatches && getComputedStyle(parent).overflow === "hidden")
+  ) {
+    offsetY += parent.offsetTop
+    offsetX += parent.offsetLeft
+
+    parent = parent.offsetParent as HTMLDivElement
+    if (!parent) {
+      return; // no need to scroll
+    }
+  }
+  if (spot) {
+    if (spot.top !== undefined) {
+      offsetY += spot.top;
+    }
+    if (spot.left !== undefined) {
+      offsetX += spot.left;
+      parent.scrollLeft = offsetX;
+    }
+  }
+  parent.scrollTop = offsetY;
+}
+
+export {
+  scrollIntoView
+}

+ 1 - 3
packages/webview/src/components/CompareDocumentContainer/CompareDocumentContainer.vue

@@ -233,12 +233,10 @@ const initDocumentView = () => {
   initializeViewer({
     container: oldFileContainer.value,
     viewer: oldViewerContainer.value,
-    annotationMode: 1
   }, 2)
   initializeViewer({
     container: newFileContainer.value,
     viewer: newViewerContainer.value,
-    annotationMode: 1
   }, 3)
 }
 
@@ -494,4 +492,4 @@ async function handlePdf (pdf, filename = null, docNum) {
     border: 2px dashed #D9D9D9;
   }
 }
-</style>
+</style>

+ 1 - 3
packages/webview/src/components/DocumentContainer/DocumentContainer.vue

@@ -172,20 +172,18 @@ onMounted(async () => {
   const thumbnailView = document.querySelector('.thumbnail-view')
   const annotationView = document.querySelector('.annotation-view')
   const outlineView = document.querySelector('.outline-view')
-  const layerView = document.querySelector('.layer-view')
   const findbarView = document.querySelector('.findbar-view')
   initializeViewer({
     container: mainContainer.value,
     viewer: viewerContainer.value,
     thumbnailView,
     outlineView,
-    layerView,
     annotationView,
     findbarView,
     toggleButton: document.querySelector('.toggle-button')
   })
   let initialDoc = getHashParameters('d', '');
-  initialDoc = initialDoc ? JSON.parse(initialDoc) : './example/Quick Start Guide for ComPDFKit Web Demo.pdf'
+  initialDoc = initialDoc ? JSON.parse(initialDoc) : './example/ComPDFKit Web developer guides - 1.4.0.pdf'
   initialDoc = Array.isArray(initialDoc) ? initialDoc : [initialDoc]
   const activeTab = useViewer.activeTab || 0
   initialDoc = initialDoc[activeTab]

+ 26 - 23
packages/webview/src/components/Outlines/Outlines.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="outline-container">
     <div class="outline-item" :class="isOutlineActive && 'selected'" @click="goToOutline">
-      <div class="outline-item-toggle" :style="{ marginLeft: 12 * outline.level + 'px' }">
+      <div class="outline-item-toggle" :class="isExpanded && 'active'" :style="{ marginLeft: 12 * outline.level + 'px' }">
         <TreeArrow v-if="outline.children.length" @click="toggleOutline" />
       </div>
       <div class="outline-item-title">{{ outline.title }}</div>
@@ -14,55 +14,55 @@
 
 <script setup>
 import { ref, computed, defineEmits } from 'vue'
+import { useDocumentStore } from '@/stores/modules/document'
+
 const emits = defineEmits()
+const useDocument = useDocumentStore()
 
-const { outline, activeOutline } = defineProps({
+const { outline } = defineProps({
   outline: {
     type: Object,
     required: true
-  },
-  activeOutline: {
-    type: Object,
-    default: null
   }
 })
 
 const splitter = '-'
-
-console.log(outline)
 const getOutlineId = (outline) => {
-  const name = outline.getName();
-  const path = this.getPath(outline);
+  const name = outline.title
+  const path = getPath(outline)
 
-  return `${path}${splitter}${name}`;
+  return `${path}${splitter}${name}`
 }
 
 const getPath = (outline) => {
-  return getPathArray(outline).reverse().join(splitter);
+  return getPathArray(outline).reverse().join(splitter)
 }
 
 const getPathArray = (outline) => {
-  const paths = [];
+  const paths = []
 
-  let curr = outline;
+  let curr = outline
   while (curr) {
-    paths.push(curr.getIndex());
-    curr = curr.getParent();
+    paths.push(curr.index)
+    curr = curr.parent
   }
 
-  return paths;
+  return paths
 }
 
+const outlineId = computed(() => getOutlineId(outline))
+
 const isExpanded = ref(false)
-const isOutlineActive = computed(() => activeOutline === outline)
+const isOutlineActive = computed(() => useDocument.getActiveOutlineId === outlineId.value)
 
-const goToOutline = (e) => {
-  e.stopPropagation()
-  isExpanded.value = !isExpanded.value
+const goToOutline = () => {
+  useDocument.setActiveOutlineId(outlineId.value)
+  outline.goTo()
 }
 
-const toggleOutline = () => {
-  emits('update:activeOutline', outline)
+const toggleOutline = (e) => {
+  e.stopPropagation()
+  isExpanded.value = !isExpanded.value
 }
 </script>
 
@@ -81,6 +81,9 @@ const toggleOutline = () => {
   min-width: 16px;
   margin-right: 8px;
   transition: transform .1s ease;
+  &.active {
+    transform: rotate(90deg);
+  }
 }
 .outline-item-title {
   color: var(--c-side-outline-text);

+ 23 - 1
packages/webview/src/components/Outlines/OutlinesPanel.vue

@@ -1,7 +1,12 @@
 <template>
   <div class="outline">
     <div class="outline-title">{{ $t('leftPanel.outlines') }}</div>
-    <Outlines v-for="outline in outlines" :outline="outline" />
+    <div v-if="outlines.length" class="outlines-container">
+      <Outlines v-for="outline in outlines" :outline="outline" />
+    </div>
+    <div v-else class="no-outlines">
+      {{ $t('leftPanel.noOutlines') }}
+    </div>
   </div>
 </template>
 
@@ -15,8 +20,14 @@ const outlines = computed(() => useDocument.getOutlines)
 
 <style lang="scss">
 .outline {
+  display: flex;
+  flex-direction: column;
   height: 100%;
 }
+.outlines-container {
+  flex-grow: 1;
+  overflow-y: auto;
+}
 .outline-title {
   margin: 0;
   padding: 9px 16px;
@@ -25,4 +36,15 @@ const outlines = computed(() => useDocument.getOutlines)
   font-weight: bold;
   color: var(--c-side-title);
 }
+.no-outlines {
+  position: absolute;
+  top: 50%;
+  left: 50%;
+  transform: translate(-50%, 50%);
+  text-align: center;
+  font-weight: 700;
+  color: var(--c-side-text);
+  font-size: 14px;
+  line-height: 16px;
+}
 </style>

+ 0 - 4
packages/webview/src/core/initializeViewer.js

@@ -4,18 +4,14 @@ export default ({
   container,
   viewer,
   thumbnailView,
-  layerView,
   annotationView,
   outlineView,
   toggleButton,
-  annotationMode
 }, number) => core.getDocumentViewer(number).initializeViewer({
   container,
   viewer,
   thumbnailView,
-  layerView,
   annotationView,
   outlineView,
   toggleButton,
-  annotationMode
 })

+ 8 - 1
packages/webview/src/stores/modules/document.js

@@ -136,7 +136,8 @@ export const useDocumentStore = defineStore({
     currentPdfData: null,
     fileHasPwd: false,
     compareResult: null, // 内容对比结果
-    outlines: []
+    outlines: [],
+    activeOutlineId: null
   }),
   getters: {
     getTotalPages () {
@@ -250,6 +251,9 @@ export const useDocumentStore = defineStore({
     },
     getOutlines () {
       return this.outlines
+    },
+    getActiveOutlineId () {
+      return this.activeOutlineId
     }
   },
   actions: {
@@ -387,6 +391,9 @@ export const useDocumentStore = defineStore({
     },
     setOutline (outlines) {
       this.outlines = outlines
+    },
+    setActiveOutlineId (outlineId) {
+      this.activeOutlineId = outlineId
     }
   }
 })