Sfoglia il codice sorgente

fix: 清除多余代码

liutian 1 anno fa
parent
commit
18bb70bb86

+ 5 - 5
package.json

@@ -1,13 +1,13 @@
 {
-  "name": "vue-pdf",
+  "name": "compdfkit",
   "version": "1.0.0",
   "description": "",
   "main": "index.js",
   "scripts": {
-    "dev": "pnpm --filter @vue-pdf/webview dev",
-    "dev:core": "pnpm --filter @vue-pdf/core build:watch",
-    "build": "pnpm --filter @vue-pdf/webview build",
-    "build:core": "pnpm --filter @vue-pdf/core build:prod"
+    "dev": "pnpm --filter @compdfkit/webview dev",
+    "dev:core": "pnpm --filter @compdfkit/core build:watch",
+    "build": "pnpm --filter @compdfkit/webview build",
+    "build:core": "pnpm --filter @compdfkit/core build:prod"
   },
   "keywords": [],
   "author": "",

+ 2 - 2
packages/core/package.json

@@ -1,5 +1,5 @@
 {
-  "name": "@vue-pdf/core",
+  "name": "@compdfkit/core",
   "version": "1.0.0",
   "description": "",
   "main": "index.js",
@@ -39,12 +39,12 @@
     "@rollup/plugin-commonjs": "^23.0.2",
     "@rollup/plugin-json": "^6.0.0",
     "@rollup/plugin-node-resolve": "^15.0.1",
+    "@rollup/plugin-terser": "^0.4.4",
     "@typescript-eslint/parser": "^6.7.2",
     "cross-env": "^7.0.3",
     "rollup": "^3.2.3",
     "rollup-plugin-node-builtins": "^2.1.2",
     "rollup-plugin-typescript2": "^0.35.0",
-    "rollup-plugin-uglify": "^6.0.4",
     "typescript": "^5.2.2"
   }
 }

+ 10 - 7
packages/core/rollup.config.js

@@ -1,21 +1,26 @@
 import nodeResolve from '@rollup/plugin-node-resolve'
 import commonjs from "@rollup/plugin-commonjs"
 import babel from '@rollup/plugin-babel'
-import { uglify } from 'rollup-plugin-uglify'
+import terser from '@rollup/plugin-terser';
 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 plugins = [
   json(),
   ts(),
+  terser({
+    mangle: {
+      reserved
+    }
+  }),
   nodeResolve({
     preferBuiltins: true,
     mainFields: ['browser']
   }),
   commonjs(),
-  // (uglify()),
-  // (process.env === 'production' && uglify()),
   babel({
     extensions,
     exclude: 'node_modules/**', // 防止打包node_modules下的文件
@@ -39,8 +44,7 @@ export default [{
   output: [
     {
       format: "es",
-      file: "../webview/lib/pdfviewer.worker.js",
-      sourceMap: true
+      file: "../webview/lib/PDFWorker.js"
     }
   ],
   plugins
@@ -50,8 +54,7 @@ export default [{
   output: [
     {
       format: "es",
-      file: "../webview/lib/webview.min.js",
-      sourceMap: true
+      file: "../webview/lib/webview.min.js"
     }
   ],
   plugins

+ 18 - 2
packages/core/src/TextSelection.ts

@@ -1,4 +1,5 @@
 // @ts-nocheck
+import copy from 'copy-to-clipboard';
 import { getAbsoluteCoordinate, getInitialPoint, getActualPoint } from './annotation/utils.js';
 
 const markupType = ['highlight', 'underline', 'squiggly', 'strikeout', '']
@@ -65,6 +66,7 @@ export default class TextSelection {
     this.handleMouseDown = this.handleMouseDown.bind(this)
     this.handleMouseMove = this.handleMouseMove.bind(this)
     this.handleMouseUp = this.handleMouseUp.bind(this)
+    this.handleKeyDown = this.handleKeyDown.bind(this)
 
     this.toolMode = options.toolMode
     this.tool = options.tool
@@ -104,6 +106,7 @@ export default class TextSelection {
     if ((toolType === this._tool && toolType !== '')) return
     
     if (!markupType.includes(toolType) || this.toolMode === 'editor') {
+      document.removeEventListener('keydown', this.handleKeyDown)
       document.removeEventListener('mousedown', this.handleMouseDown)
       document.removeEventListener('touchstart', this.handleMouseDown)
       document.removeEventListener('mousemove', this.handleMouseMove)
@@ -112,6 +115,7 @@ export default class TextSelection {
       return
     }
     if (!(markupType.includes(toolType) && markupType.includes(this.tool))) {
+      document.addEventListener('keydown', this.handleKeyDown)
       document.addEventListener('mousedown', this.handleMouseDown)
       document.addEventListener('touchstart', this.handleMouseDown)
       document.addEventListener('mousemove', this.handleMouseMove)
@@ -129,6 +133,15 @@ export default class TextSelection {
     }
   }
 
+  handleKeyDown(event: KeyboardEvent) {
+    if (event.key.toLocaleLowerCase() === 'c' && event.ctrlKey) {
+      const text = this._selection?.textContent
+      if (text) {
+        copy(text)
+      }
+    }
+  }
+
   handleMouseDown(event: MouseEvent) {
     this.cleanSelection()
     const tool = this.tool
@@ -147,7 +160,10 @@ export default class TextSelection {
 
   async handleMouseMove(event: MouseEvent) {
     const inPage = this.testPoint(event)
-    if (!inPage || document.querySelector('.annotationContainer .outline-container')) return
+    if (!inPage || document.querySelector('.annotationContainer .outline-container')) {
+      this.container?.classList.remove('text')
+      return
+    }
     const { x, y } = inPage
     const point = getInitialPoint({ x, y }, this.viewport, this.scale)
 
@@ -205,7 +221,6 @@ export default class TextSelection {
     this.startPoint = null
     this.endPoint = null
     this.selecting = false
-    this._selection = null
     document.removeEventListener('mouseup', this.handleMouseUp)
     document.removeEventListener('touchend', this.handleMouseUp)
   }
@@ -294,6 +309,7 @@ export default class TextSelection {
     this.textContainer?.remove()
     this.textContainer = null
     this._selection = null
+    document.removeEventListener('keydown', this.handleKeyDown)
     document.removeEventListener('mousedown', this.handleMouseDown)
     document.removeEventListener('touchstart', this.handleMouseDown)
     document.removeEventListener('mousemove', this.handleMouseMove)

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

@@ -776,7 +776,6 @@ export default class Link extends Base {
 
   setProperty (props) {
     if (props.name !== this.annotation.name) return
-    console.log(props, this.annotation)
 
     for (const key in props) {
       for (const item in this.annotation) {

+ 0 - 2
packages/core/src/annotation/text.js

@@ -13,7 +13,6 @@ export default class Text extends Base {
     eventBus,
     layer,
     show = false,
-    $t
   }) {
     super({
       container,
@@ -49,7 +48,6 @@ export default class Text extends Base {
     this.show = show
 
     this.popShow = false
-    this.$t = $t
 
     this.onClick = this.handleClick.bind(this)
     this.onBlur = this.handleBlur.bind(this)

+ 0 - 179
packages/core/src/base_tree_viewer.js

@@ -1,179 +0,0 @@
-/* Copyright 2020 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 { removeNullCharacters } from "./ui_utils.js";
-
-const TREEITEM_OFFSET_TOP = -100; // px
-const TREEITEM_SELECTED_CLASS = "selected";
-
-class BaseTreeViewer {
-  constructor(options) {
-    if (this.constructor === BaseTreeViewer) {
-      throw new Error("Cannot initialize BaseTreeViewer.");
-    }
-    this.container = options.container;
-    this.eventBus = options.eventBus;
-    this.$t = options?.$t;
-
-    this.reset();
-  }
-
-  reset() {
-    this._pdfDocument = null;
-    this._lastToggleIsShow = true;
-    this._currentTreeItem = null;
-
-    // Remove the tree from the DOM.
-    this.container.textContent = "";
-    // Ensure that the left (right in RTL locales) margin is always reset,
-    // to prevent incorrect tree alignment if a new document is opened.
-    this.container.classList.remove("treeWithDeepNesting");
-  }
-
-  /**
-   * @private
-   */
-  _dispatchEvent(count) {
-    throw new Error("Not implemented: _dispatchEvent");
-  }
-
-  /**
-   * @private
-   */
-  _bindLink(element, params) {
-    throw new Error("Not implemented: _bindLink");
-  }
-
-  /**
-   * @private
-   */
-  _normalizeTextContent(str) {
-    // Chars in range [0x01-0x1F] will be replaced with a white space
-    // and 0x00 by "".
-    return (
-      removeNullCharacters(str, /* replaceInvisible */ true) ||
-      /* en dash = */ "\u2013"
-    );
-  }
-
-  /**
-   * Prepend a button before a tree item which allows the user to collapse or
-   * expand all tree items at that level; see `_toggleTreeItem`.
-   * @private
-   */
-  _addToggleButton(div, hidden = false, element = null) {
-    const title = document.createElement("div")
-    title.className = "title"
-    const toggler = document.createElement("div");
-    toggler.innerHTML = '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6.01025 4L11 8.0041L6 12L6.01025 4Z" fill="currentColor"/></svg>'
-    toggler.className = "treeItemToggler";
-    title.classList.add("treeItemsHidden");
-    toggler.onclick = evt => {
-      evt.stopPropagation();
-      title.classList.toggle("treeItemsHidden");
-
-      if (evt.shiftKey) {
-        const shouldShowAll = !title.classList.contains("treeItemsHidden");
-        this._toggleTreeItem(div, shouldShowAll);
-      }
-    };
-    title.append(toggler)
-    element && title.append(element)
-    div.prepend(title);
-  }
-
-  /**
-   * Collapse or expand the subtree of a tree item.
-   *
-   * @param {Element} root - the root of the item (sub)tree.
-   * @param {boolean} show - whether to show the item (sub)tree. If false,
-   *   the item subtree rooted at `root` will be collapsed.
-   * @private
-   */
-  _toggleTreeItem(root, show = false) {
-    this._lastToggleIsShow = show;
-    for (const toggler of root.querySelectorAll(".treeItemToggler")) {
-      toggler.classList.toggle("treeItemsHidden", !show);
-    }
-  }
-
-  /**
-   * Collapse or expand all subtrees of the `container`.
-   * @private
-   */
-  _toggleAllTreeItems() {
-    this._toggleTreeItem(this.container, !this._lastToggleIsShow);
-  }
-
-  /**
-   * @private
-   */
-  _finishRendering(fragment, count, hasAnyNesting = false) {
-    if (hasAnyNesting) {
-      this.container.classList.add("treeWithDeepNesting");
-
-      this._lastToggleIsShow = !fragment.querySelector(".treeItemsHidden");
-    }
-    this.container.append(fragment);
-
-    this._dispatchEvent(count);
-  }
-
-  render(params) {
-    throw new Error("Not implemented: render");
-  }
-
-  /**
-   * @private
-   */
-  _updateCurrentTreeItem(treeItem = null) {
-    if (this._currentTreeItem) {
-      // Ensure that the current treeItem-selection is always removed.
-      this._currentTreeItem.classList.remove(TREEITEM_SELECTED_CLASS);
-      this._currentTreeItem = null;
-    }
-    if (treeItem) {
-      treeItem.classList.add(TREEITEM_SELECTED_CLASS);
-      this._currentTreeItem = treeItem;
-    }
-  }
-
-  /**
-   * @private
-   */
-  _scrollToCurrentTreeItem(treeItem) {
-    if (!treeItem) {
-      return;
-    }
-    // Ensure that the treeItem is *fully* expanded, such that it will first of
-    // all be visible and secondly that scrolling it into view works correctly.
-    let currentNode = treeItem.parentNode;
-    while (currentNode && currentNode !== this.container) {
-      if (currentNode.classList.contains("treeItem")) {
-        const toggler = currentNode.firstElementChild;
-        toggler?.classList.remove("treeItemsHidden");
-      }
-      currentNode = currentNode.parentNode;
-    }
-    this._updateCurrentTreeItem(treeItem);
-
-    this.container.scrollTo(
-      treeItem.offsetLeft,
-      treeItem.offsetTop + TREEITEM_OFFSET_TOP
-    );
-  }
-}
-
-export { BaseTreeViewer };

+ 16 - 35
packages/core/src/index.js

@@ -1,10 +1,9 @@
 import { getDocument, GlobalWorkerOptions, InvalidPDFException, MissingPDFException, UnexpectedResponseException, getPdfFilenameFromUrl } from 'pdfjs-dist/legacy/build/pdf'
-import CryptoJS from 'crypto-js';
-import printJS from 'print-js';
-import { saveAs } from 'file-saver';
+import CryptoJS from 'crypto-js'
+import printJS from 'print-js'
+import { saveAs } from 'file-saver'
 import { PDFLinkService } from "./pdf_link_service"
 import { PasswordPrompt } from "./password_prompt.js";
-import { PDFFindController } from "./pdf_find_controller.js";
 import { PDFViewer } from './pdf_viewer'
 import { PDFThumbnailViewer } from './pdf_thumbnail_viewer'
 import { PDFRenderingQueue } from "./pdf_rendering_queue";
@@ -39,7 +38,6 @@ class ComPDFKitViewer {
     this.pdfLayerViewer = null
     this.pdfDocument = null
     this.downloadComplete = false
-    this.init = false
     this.isInitialViewSet = false
     this.pdfLinkService = null
     this.externalServices = GenericExternalServices
@@ -105,19 +103,21 @@ class ComPDFKitViewer {
     return this.pdfViewer.currentScale;
   }
 
-  initConfig(options) {
-    return new Promise((resolve, reject) => {
+  async init() {
+    await new Promise((resolve, reject) => {
       const worker = new PDFWorker()
 
       this.worker = worker
       const messageHandler = worker.messageHandler
       this.messageHandler = messageHandler
       messageHandler.on('initDoc', ({ doc }) => {
-        console.log('initDoc')
         this.doc = doc
         resolve(true)
       })
     })
+  }
+
+  async initConfig(options) {
     if (!options.license) return false
     this._license = options.license
     const data = {
@@ -129,7 +129,7 @@ class ComPDFKitViewer {
         license: this._license
       })
     }
-    return fetch(this.optionUrl.baseUrl + this.optionUrl.verifyUrl, data)
+    const verified = await fetch(this.optionUrl.baseUrl + this.optionUrl.verifyUrl, data)
       .then((res) => {
         return res.json()
       })
@@ -138,10 +138,16 @@ class ComPDFKitViewer {
           const verified = this._decrypt(resp.data)
           return verified
         } else {
+          alert(resp.message)
           return false
         }
       })
       .catch((error) => ({ error: true, message: error.message }));
+
+    if (verified) {
+      await this.init()
+    }
+    return verified
   }
 
   _decrypt(data) {
@@ -195,7 +201,6 @@ class ComPDFKitViewer {
       this.handleAnnotations(annotations[index], true)
       render && this.pdfViewer.renderAnnotation(annotations[index])
     }
-    console.log(this.annotations)
     this.eventBus.dispatch('annotationChanged', { annotations: this.annotations })
   }
 
@@ -830,20 +835,6 @@ class ComPDFKitViewer {
       });
     })
 
-    onePageRendered.then(data => {
-      this.externalServices.reportTelemetry({
-        type: "pageInfo",
-        timestamp: data.timestamp,
-      });
-
-      pdfDocument.getOutline().then(outline => {
-        if (pdfDocument !== this.pdfDocument) {
-          return; // The document was closed while the outline resolved.
-        }
-        this.pdfOutlineViewer?.render({ outline, pdfDocument });
-      });
-    });
-
     this.eventBus.dispatch("documentinit", { source: this });
   }
 
@@ -982,7 +973,6 @@ class ComPDFKitViewer {
     const annotation = data.annotation
     this.annotationHistory.push(annotation)
     const annotateHandles = []
-    console.log(annotation)
 
     if (data.type === 'add') {
       if (Array.isArray(annotation)) {
@@ -1255,13 +1245,6 @@ class ComPDFKitViewer {
     const pdfLinkService = new PDFLinkService();
     this.pdfLinkService = pdfLinkService;
 
-    const findController = new PDFFindController({
-      linkService: pdfLinkService,
-      eventBus: this.eventBus,
-      updateMatchesCountOnProgress:
-        typeof PDFJSDev === "undefined" || !PDFJSDev.test("GECKOVIEW"),
-    });
-
     this.pdfViewer = new PDFViewer({
       container,
       viewer,
@@ -1274,7 +1257,6 @@ class ComPDFKitViewer {
       annotationView,
       renderingQueue: pdfRenderingQueue,
       linkService: pdfLinkService,
-      findController,
       renderer: 'canvas',
       textLayerMode: 1,
       enablePrintAutoRotate: true,
@@ -1506,7 +1488,6 @@ class ComPDFKitViewer {
   }
 
   get annotationMode() {
-    console.log(this._annotationMode)
     return this._annotationMode
   }
 
@@ -2110,7 +2091,7 @@ class PDFWorker {
 
   _initialize() {
     try {
-      const workerSrc = "./lib/pdfviewer.worker.js"
+      const workerSrc = "./lib/PDFWorker.js"
       const worker = new Worker(workerSrc)
       const messageHandler = new MessageHandler('main', 'worker', worker)
       this._messageHandler = messageHandler

+ 0 - 309
packages/core/src/markup/index.js

@@ -1,309 +0,0 @@
-import { hexToRgb } from "../ui_utils"
-
-class MarkupAnnotation {
-  constructor ({
-    eventBus,
-    viewport,
-    pages,
-    scale
-  }) {
-    this.eventBus = eventBus
-    this.viewport = viewport
-    this.tool = ''
-    this.pages = pages
-    this.scale = scale
-    this.onHandleUp = this.handleUp.bind(this)
-    this.onHandleTool = this.handleTool.bind(this)
-
-    this.init()
-  }
-
-  init () {
-    document.addEventListener('selectionchange', this.handleSelectChange)
-    this.eventBus._on('toolChanged', this.onHandleTool)
-  }
-
-  handleSelectChange () {
-    const selection = document.getSelection()
-    const container = document.querySelector('.document')
-    if (!selection?.isCollapsed) {
-      container.classList.add('selection')
-    } else {
-      container.classList.remove('selection')
-    }
-  }
-
-  handleTool ({
-    tool,
-    color
-  }) {
-    this.tool = tool
-    this.color = color
-
-    const markupType = ['highlight', 'underline', 'squiggly', 'strikeout', '']
-    if (markupType.includes(this.tool)) {
-      document.body.style.userSelect = 'auto'
-      document.body.style.webkitUserSelect = 'auto'
-    } else {
-      document.body.style.userSelect = 'none'
-      document.body.style.webkitUserSelect = 'none'
-    }
-  }
-
-  get tool () {
-    return this._tool
-  }
-
-  set tool (toolType) {
-    if (toolType === this._tool) return
-    this._tool = toolType
-    if (!toolType) {
-      document.removeEventListener('mouseup', this.onHandleUp)
-      document.removeEventListener('touchend', this.onHandleUp)
-      return
-    }
-    document.addEventListener('mouseup', this.onHandleUp)
-    document.addEventListener('touchend', this.onHandleUp)
-  }
-
-  destroy () {
-    this.eventBus._off('toolChanged', this.onHandleTool)
-    document.removeEventListener('mouseup', this.onHandleUp)
-    document.removeEventListener('touchend', this.onHandleUp)
-  }
-
-  handleUp (event) {
-    const selection = document.getSelection()
-    let textLayer = ''
-    if (!selection?.isCollapsed) {
-      if (event.target) {
-        textLayer = (event.target).parentNode
-
-        if (!textLayer.classList.contains('textLayer')) {
-          textLayer = textLayer.closest('.page').querySelector('.textLayer')
-        }
-        const markupType = ['highlight', 'underline', 'squiggly', 'strikeout']
-        if (textLayer && (markupType.includes(this.tool))) {
-          const newMarkup = this.getMarkupWithSelection({
-            textLayer,
-            content: selection && selection.toString(),
-          })
-          if (newMarkup) {
-            this.eventBus.dispatch('annotationChange', {
-              type: 'add',
-              annotation: newMarkup
-            })
-            const pageView = this.pages[newMarkup.pageIndex]
-            if (pageView && pageView.compdfAnnotationLayer) {
-              pageView.compdfAnnotationLayer.renderAnnotation(newMarkup)
-            }
-            selection.removeAllRanges()
-          }
-        }
-      }
-    }
-  }
-
-  getMarkupWithSelection ({
-    textLayer,
-    content,
-  }) {
-    const selection = document.getSelection()
-  
-    if (!selection || selection.isCollapsed) return null
-    const {
-      startContainer,
-      startOffset,
-      endContainer,
-      endOffset,
-    } = selection.getRangeAt(0)
-    const startElement = startContainer.parentNode
-    const endElement = endContainer.parentNode
-    const startPage = startElement?.closest('.page')
-    const startPageNum = parseInt(
-      startPage.getAttribute('data-page-number'),
-      10,
-    )
-
-    const pageHeight = startPage.offsetHeight
-  
-    const startCloneEle = startElement.cloneNode(true)
-    const endCloneEle = endElement.cloneNode(true)
-  
-    const startText = startElement.innerText.substring(0, startOffset)
-    const endText = endElement.innerText.substring(endOffset)
-  
-    startCloneEle.innerText = startText
-    endCloneEle.innerText = endText
-    textLayer.appendChild(startCloneEle)
-    textLayer.appendChild(endCloneEle)
-  
-    const startMatrix = getComputedStyle(startCloneEle).transform === 'none' ? null : getComputedStyle(startCloneEle).transform.split('(')[1].split(')')[0].split(', ')
-    const endMatrix = getComputedStyle(endCloneEle).transform === 'none' ? null : getComputedStyle(endCloneEle).transform.split('(')[1].split(')')[0].split(', ')
-    const startExtraWidth = startMatrix ? parseFloat(getComputedStyle(startCloneEle).width) * parseFloat(startMatrix[0]) : parseFloat(getComputedStyle(startCloneEle).width)
-    const endExtraWidth = endMatrix ? parseFloat(getComputedStyle(endCloneEle).width) * parseFloat(endMatrix[0]) : parseFloat(getComputedStyle(endCloneEle).width)
-  
-    textLayer.removeChild(startCloneEle)
-    textLayer.removeChild(endCloneEle)
-
-    const position = []
-    
-    const startRectMatrix = getComputedStyle(startElement).transform === 'none' ? null : getComputedStyle(startElement).transform.split('(')[1].split(')')[0].split(', ')
-    const endRectMatrix = getComputedStyle(endElement).transform === 'none' ? null : getComputedStyle(endElement).transform.split('(')[1].split(')')[0].split(', ')
-    const startRectWidth = parseFloat(getComputedStyle(startElement).width) * (startRectMatrix ? parseFloat(startRectMatrix[0]) : 1)
-    const endRectWidth = parseFloat(getComputedStyle(endElement).width) * (endRectMatrix ? parseFloat(endRectMatrix[0]) : 1)
-    const startRectHeight = parseFloat(getComputedStyle(startElement).height) * (startRectMatrix ? parseFloat(startRectMatrix[3]) : 1)
-    const endRectHeight = parseFloat(getComputedStyle(endElement).height) * (endRectMatrix ? parseFloat(endRectMatrix[3]) : 1)
-  
-    // left to right and up to down select
-    let startX = startElement.offsetLeft + startExtraWidth
-    let startY = startElement.offsetTop
-    let endX = endElement.offsetLeft + endRectWidth - endExtraWidth
-    let endY = endElement.offsetTop + endRectHeight
-  
-    if (startX > endX && startY >= endY) {
-      // right to left and down to up select
-      startX = endElement.offsetLeft + startExtraWidth
-      startY = endElement.offsetTop
-      endX = startElement.offsetLeft + startRectWidth - endExtraWidth
-      endY = startElement.offsetTop + startRectHeight
-    }
-  
-    const textElements = Array.prototype.slice.call(textLayer.childNodes)
-  
-    let inRange = false
-  
-    textElements.forEach((ele) => {
-      if (!ele.innerText.trim()) return
-      const rectMatrix = getComputedStyle(ele).transform === 'none' ? null : getComputedStyle(ele).transform.split('(')[1].split(')')[0].split(', ')
-      const width = rectMatrix ? parseFloat(getComputedStyle(ele).width) * parseFloat(rectMatrix[0]) : parseFloat(getComputedStyle(ele).width)
-      const height = rectMatrix ? parseFloat(getComputedStyle(ele).height) * parseFloat(rectMatrix[3]) : parseFloat(getComputedStyle(ele).height)
-      const { offsetTop, offsetLeft } = ele
-  
-      const top = offsetTop
-      const left = offsetLeft
-      const right = offsetLeft + width
-      const bottom = offsetTop + height
-      const coords = {
-        top,
-        bottom,
-        left,
-        right,
-      }
-  
-      if (startElement === ele && endElement === ele) {
-        // in same element
-        coords.left = startX
-        coords.right = endX
-        position.push(coords)
-      } else if (startElement === ele) {
-        // in start element
-        coords.left = startX
-        position.push(coords)
-        inRange = true
-      } else if (endElement === ele) {
-        // in end element
-        coords.right = endX
-        position.push(coords)
-        inRange = false
-      } else if (inRange) {
-        // middle element
-        position.push(coords)
-      }
-    })
-  
-    for (let i = 1; i < position.length; i += 1) {
-      if (
-        position[i].top >= position[i - 1].top - 4 &&
-        position[i].bottom <= position[i - 1].bottom + 4
-      ) {
-        position[i - 1].right = position[i].left
-      }
-    }
-    const topArray = []
-    const bottomArray = []
-    const leftArray = []
-    const rightArray = []
-    const newPosition = position.reduce((acc, current) => {
-      const actualPosition = this.parsePositionForBackend(current)
-      topArray.push(actualPosition.top)
-      bottomArray.push(actualPosition.bottom)
-      leftArray.push(actualPosition.left)
-      rightArray.push(actualPosition.right)
-      if (!acc.length) {
-        acc.push(actualPosition)
-        return acc
-      }
-      const endAcc = acc[acc.length - 1]
-      if (actualPosition.left === endAcc.right && actualPosition.top === endAcc.top && actualPosition.bottom === endAcc.bottom) {
-        endAcc.right = actualPosition.right
-      } else {
-        acc.push(actualPosition)
-      }
-      return acc
-    }, [])
-
-    let quadPoints = []
-    for (let i = 0; i < newPosition.length; i++) {
-      const curPosition = newPosition[i]
-      const { left, top, right, bottom } = curPosition
-      const leftTop = {
-        PointX: left,
-        PointY: top
-      }
-      const rightTop = {
-        PointX: right,
-        PointY: top
-      }
-      const leftBottom = {
-        PointX: left,
-        PointY: bottom
-      }
-      const rightBottom = {
-        PointX: right,
-        PointY: bottom
-      }
-      quadPoints.push(leftTop, rightTop, leftBottom, rightBottom)
-    }
-
-    const top = Math.min(...topArray)
-    const bottom = Math.max(...bottomArray)
-    const left = Math.min(...leftArray)
-    const right = Math.max(...rightArray)
-    console.log(this.color)
-    let color = this.color
-
-    const annotationData = {
-      operate: "add-annot",
-      type: this.tool,
-      pageIndex: startPageNum - 1,
-      createDate: new Date(),
-      transparency: 0.5,
-      quadPoints,
-      rect: {
-        left,
-        bottom,
-        right,
-        top,
-      },
-      color,
-      content: content || undefined
-    }
-    if (this.tool === 'highlight') {
-      annotationData.transparency = 0.5
-    }
-    return annotationData
-  }
-
-  parsePositionForBackend (position) {
-    const positionArray = {
-      left: Math.round(position.left * 1000 / this.scale) / 1000,
-      top: Math.round((position.top) * 1000 / this.scale) / 1000,
-      right: Math.round(position.right * 1000 / this.scale) / 1000,
-      bottom: Math.round((position.bottom) * 1000 / this.scale) / 1000
-    }
-
-    return positionArray
-  }
-}
-export default MarkupAnnotation

+ 0 - 218
packages/core/src/pdf_find_bar.js

@@ -1,218 +0,0 @@
-/* Copyright 2012 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 { FindState } from "./pdf_find_controller.js";
-
-const MATCHES_COUNT_LIMIT = 1000;
-
-/**
- * Creates a "search bar" given a set of DOM elements that act as controls
- * for searching or for setting search preferences in the UI. This object
- * also sets up the appropriate events for the controls. Actual searching
- * is done by PDFFindController.
- */
-class PDFFindBar {
-  constructor(options, eventBus) {
-    this.opened = false;
-
-    this.bar = options.bar;
-    this.toggleButton = options.toggleButton;
-    this.findField = options.findField;
-    this.emptyInput = options.emptyInput;
-    this.highlightAll = options.highlightAllCheckbox || { checked: true };
-    this.caseSensitive = options.caseSensitiveCheckbox || { checked: false };
-    this.matchDiacritics = options.matchDiacriticsCheckbox || { checked: false };
-    this.entireWord = options.entireWordCheckbox || { checked: false };
-    this.findMsg = options.findMsg;
-    this.findResultsCount = options.findResultsCount;
-    this.findPreviousButton = options.findPreviousButton;
-    this.findNextButton = options.findNextButton;
-    this.eventBus = eventBus;
-    this.l10n = null;
-    this.findbarView = options.findbarView;
-    this.$t = options.$t;
-    
-    // Add event listeners to the DOM elements.
-    this.findField.addEventListener("input", () => {
-      this.dispatchEvent("");
-      this.emptyInput.classList.remove("hidden");
-      if (!this.findField.value) {
-        this.emptyInput.classList.add("hidden");
-      }
-    });
-
-    this.bar.addEventListener("keydown", e => {
-      switch (e.keyCode) {
-        case 13: // Enter
-          if (e.target === this.findField) {
-            this.dispatchEvent("again", e.shiftKey);
-          }
-          break;
-        case 27: // Escape
-          this.close();
-          break;
-      }
-    });
-
-    this.findPreviousButton.addEventListener("click", () => {
-      this.dispatchEvent("again", true);
-    });
-
-    this.findNextButton.addEventListener("click", () => {
-      this.dispatchEvent("again", false);
-    });
-
-    this.eventBus._on("resize", this.#adjustWidth.bind(this));
-
-    this.emptyInput.addEventListener("click", () => {
-      this.empty();
-    });
-  }
-
-  reset() {
-    this.updateUIState();
-  }
-
-  dispatchEvent(type, findPrev = false, value = null) {
-    this.eventBus.dispatch("find", {
-      source: this,
-      type,
-      query: value || this.findField.value,
-      phraseSearch: true,
-      caseSensitive: this.caseSensitive.checked,
-      entireWord: this.entireWord.checked,
-      highlightAll: this.highlightAll.checked,
-      findPrevious: findPrev,
-      matchDiacritics: this.matchDiacritics.checked,
-    });
-  }
-
-  updateUIState(state, previous, matchesCount) {
-    let status = "";
-    let close = false
-
-    switch (state) {
-      case FindState.FOUND:
-        break;
-      case FindState.PENDING:
-        status = "pending";
-        break;
-      case FindState.NOT_FOUND:
-        status = "notFound";
-        break;
-      case FindState.WRAPPED:
-        break;
-      case FindState.CLOSE:
-        close = true
-        break;
-    }
-    this.findField.setAttribute("data-status", status);
-    this.findField.setAttribute("aria-invalid", state === FindState.NOT_FOUND);
-
-    this.#adjustWidth();
-
-    this.updateResultsCount(matchesCount, close);
-  }
-
-  updateResultsCount({ current = 0, total = 0 } = {}, close = false) {
-    let matchCountMsg = '';
-    if  (close) {
-      matchCountMsg = ''
-      this.findPreviousButton.classList.add("disabled")
-      this.findNextButton.classList.add("disabled")
-    }else if (total > 0) {
-      matchCountMsg = current + '/' + total + ' ' + this.$t('leftPanel.results')
-      this.findPreviousButton.classList.remove("disabled")
-      this.findNextButton.classList.remove("disabled")
-    } else {
-      matchCountMsg = '0/0 ' + this.$t('leftPanel.results')
-      this.findPreviousButton.classList.add("disabled")
-      this.findNextButton.classList.add("disabled")
-      this.eventBus.dispatch('updateFindMatches', [])
-    }
-    this.findResultsCount.textContent = matchCountMsg;
-    // Since `updateResultsCount` may be called from `PDFFindController`,
-    // ensure that the width of the findbar is always updated correctly.
-    this.#adjustWidth();
-  }
-
-  open() {
-    if (!this.opened) {
-      this.opened = true;
-      this.toggleButton.classList.add("toggled");
-      this.toggleButton.setAttribute("aria-expanded", "true");
-      // this.bar.classList.remove("hidden");
-    }
-    this.findField.select();
-    this.findField.focus();
-
-    this.#adjustWidth();
-  }
-
-  close() {
-    if (!this.opened) {
-      return;
-    }
-    this.opened = false;
-    this.toggleButton.classList.remove("toggled");
-    this.toggleButton.setAttribute("aria-expanded", "false");
-    // this.bar.classList.add("hidden");
-    this.empty();
-    this.findResultsCount.textContent = ''
-    this.findPreviousButton.classList.add("disabled")
-    this.findNextButton.classList.add("disabled")
-    this.eventBus.dispatch("findbarclose", { source: this });
-  }
-
-  toggle() {
-    if (this.opened) {
-      this.close();
-    } else {
-      this.open();
-    }
-  }
-
-  #adjustWidth() {
-    if (!this.opened) {
-      return;
-    }
-
-    // The find bar has an absolute position and thus the browser extends
-    // its width to the maximum possible width once the find bar does not fit
-    // entirely within the window anymore (and its elements are automatically
-    // wrapped). Here we detect and fix that.
-    this.bar.classList.remove("wrapContainers");
-
-    const findbarHeight = this.bar.clientHeight;
-    const inputContainerHeight = this.bar.firstElementChild.clientHeight;
-
-    if (findbarHeight > inputContainerHeight) {
-      // The findbar is taller than the input container, which means that
-      // the browser wrapped some of the elements. For a consistent look,
-      // wrap all of them to adjust the width of the find bar.
-      this.bar.classList.add("wrapContainers");
-    }
-  }
-
-  empty() {
-    this.findField.value = '';
-    const inputEvent = new Event("input");
-    this.findField.dispatchEvent(inputEvent);
-    this.eventBus.dispatch('updateFindMatches', [])
-    this.emptyInput.classList.add("hidden");
-  }
-}
-
-export { PDFFindBar };

File diff suppressed because it is too large
+ 0 - 1098
packages/core/src/pdf_find_controller.js


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

@@ -1,274 +0,0 @@
-/* Copyright 2020 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 { BaseTreeViewer } from "./base_tree_viewer.js";
-
-/**
- * @typedef {Object} PDFLayerViewerOptions
- * @property {HTMLDivElement} container - The viewer element.
- * @property {EventBus} eventBus - The application event bus.
- * @property {IL10n} l10n - Localization service.
- */
-
-/**
- * @typedef {Object} PDFLayerViewerRenderParameters
- * @property {OptionalContentConfig|null} optionalContentConfig - An
- *   {OptionalContentConfig} instance.
- * @property {PDFDocument} pdfDocument - A {PDFDocument} instance.
- */
-
-class PDFLayerViewer extends BaseTreeViewer {
-  constructor(options) {
-    super(options);
-    this.l10n = options.l10n;
-
-    this.rawLayersCount = 0;
-    this.layersCount = 0;
-
-    this.toggleButton = null;
-
-    this.eventBus._on("optionalcontentconfigchanged", evt => {
-      this.#updateLayers(evt.promise);
-    });
-    this.eventBus._on("resetlayers", () => {
-      this.#updateLayers();
-    });
-    this.eventBus._on("togglelayerstree", this._toggleAllTreeItems.bind(this));
-  }
-
-  reset() {
-    super.reset();
-    const div = document.createElement("div");
-    div.className = "no-layer";
-    div.innerText = this.$t("leftPanel.noLayers")
-    this.container.append(div)
-    this._optionalContentConfig = null;
-    this._optionalContentHash = null;
-    
-    this.rawLayersCount = 0;
-    this.layersCount = 0;
-
-    this.toggleButton = null;
-  }
-
-  /**
-   * @private
-   */
-  _dispatchEvent(layersCount) {
-    this.eventBus.dispatch("layersloaded", {
-      source: this,
-      layersCount,
-    });
-  }
-
-  /**
-   * @private
-   */
-  _bindLink(element, { groupId, input }) {
-    const setVisibility = () => {
-      this._optionalContentConfig.setVisibility(groupId, input.checked);
-      this._optionalContentHash = this._optionalContentConfig.getHash();
-
-      this.eventBus.dispatch("optionalcontentconfig", {
-        source: this,
-        promise: Promise.resolve(this._optionalContentConfig),
-      });
-      element.classList.toggle('checked')
-      input.checked ? this.layersCount++ : this.layersCount--;
-      if (this.toggleButton && this.rawLayersCount > 0) {
-        this.layersCount === this.rawLayersCount ? this.toggleButton.classList.add('selected') : this.toggleButton.classList.remove('selected')
-      }
-    };
-
-    element.onclick = evt => {
-      if (evt.target === input) {
-        setVisibility();
-        return true;
-      } else if (evt.target !== element) {
-        return true; // The target is the "label", which is handled above.
-      }
-      input.checked = !input.checked;
-      setVisibility();
-      return false;
-    };
-  }
-
-  /**
-   * @private
-   */
-  async _setNestedName(element, { name = null }) {
-    if (typeof name === "string") {
-      element.textContent = this._normalizeTextContent(name);
-      return;
-    }
-    element.textContent = 'Others';
-    element.style.fontStyle = "italic";
-  }
-
-  /**
-   * @private
-   */
-  _addToggleButton(div, { name = null }, element) {
-    super._addToggleButton(div, /* hidden = */ name === null, element);
-  }
-
-  /**
-   * @private
-   */
-  _toggleAllTreeItems() {
-    if (!this._optionalContentConfig) {
-      return;
-    }
-    super._toggleAllTreeItems();
-  }
-  
-  _toggleAllLayerItems() {
-    const inputs = this.container.querySelectorAll('input')
-    const toggleAll = this.rawLayersCount === this.layersCount
-    for (var i = 0; i < inputs.length; i++) {
-      if (toggleAll || !this.layersCount || !inputs[i].checked) {
-        inputs[i].click()
-      }
-    }
-  }
-
-  /**
-   * @param {PDFLayerViewerRenderParameters} params
-   */
-  render({ optionalContentConfig, pdfDocument }) {
-    if (this._optionalContentConfig) {
-      this.reset();
-    }
-    this._optionalContentConfig = optionalContentConfig || null;
-    this._pdfDocument = pdfDocument || null;
-
-    const groups = optionalContentConfig?.getOrder();
-    this.container.innerHTML = '';
-    if (!groups) {
-      const div = document.createElement("div");
-      div.className = "no-layer";
-      div.innerText = this.$t("leftPanel.noLayers")
-      this.container.append(div)
-      this._dispatchEvent(/* layersCount = */ 0);
-      return;
-    }
-    
-    const toggleDiv = document.createElement("div");
-    toggleDiv.innerHTML = `<div>
-      <svg class="not-checked" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
-        <rect x="0.5" y="0.5" width="13" height="13" rx="0.5" fill="white" stroke="currentColor"/>
-      </svg>
-      <svg class="checked" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
-        <rect width="14" height="14" rx="1" fill="currentColor"/>
-        <path d="M10.2784 5.27848L5.84653 9.71032L4.20261 8.06642" stroke="white" stroke-width="1.5" stroke-linecap="square"/>
-      </svg>
-    </div>`
-    toggleDiv.append('Display all')
-    toggleDiv.className="toggle selected"
-    toggleDiv.onclick = () => {
-      this._toggleAllLayerItems();
-    }
-    this.toggleButton = toggleDiv;
-    this.container.append(toggleDiv);
-    this._optionalContentHash = optionalContentConfig.getHash();
-
-    const fragment = document.createDocumentFragment(),
-      queue = [{ parent: fragment, groups }];
-    let layersCount = 0,
-      hasAnyNesting = false;
-    while (queue.length > 0) {
-      const levelData = queue.shift();
-      for (const groupId of levelData.groups) {
-        const div = document.createElement("div");
-        div.className = "treeItem";
-
-        const element = document.createElement("a");
-        if (typeof groupId === "object") {
-          hasAnyNesting = true;
-          this._setNestedName(element, groupId);
-          this._addToggleButton(div, groupId, element);
-
-          const itemsDiv = document.createElement("div");
-          itemsDiv.className = "treeItems";
-          div.append(itemsDiv);
-
-          queue.push({ parent: itemsDiv, groups: groupId.order });
-        } else {
-          const group = optionalContentConfig.getGroup(groupId);
-          const input = document.createElement("input");
-          this._bindLink(element, { groupId, input });
-          input.type = "checkbox";
-          input.checked = group.visible;
-          group.visible && element.classList.add('checked')
-          const label = document.createElement("label");
-          label.textContent = this._normalizeTextContent(group.name);
-
-          const box = document.createElement("div");
-          box.innerHTML = `<svg class="not-checked" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
-            <rect x="0.5" y="0.5" width="13" height="13" rx="0.5" fill="white" stroke="currentColor"/>
-          </svg>
-          <svg class="checked" xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
-            <rect width="14" height="14" rx="1" fill="currentColor"/>
-            <path d="M10.2784 5.27848L5.84653 9.71032L4.20261 8.06642" stroke="white" stroke-width="1.5" stroke-linecap="square"/>
-          </svg>`
-          box.onclick = () => {
-            input.click();
-          }
-
-          label.prepend(input);
-          element.append(box);
-          element.append(label);
-          div.append(element);
-          layersCount++;
-        }
-
-        levelData.parent.append(div);
-      }
-    }
-    this.rawLayersCount = this.layersCount = layersCount;
-    this._finishRendering(fragment, layersCount, hasAnyNesting);
-  }
-
-  async #updateLayers(promise = null) {
-    if (!this._optionalContentConfig) {
-      return;
-    }
-    const pdfDocument = this._pdfDocument;
-    const optionalContentConfig = await (promise ||
-      pdfDocument.getOptionalContentConfig());
-
-    if (pdfDocument !== this._pdfDocument) {
-      return; // The document was closed while the optional content resolved.
-    }
-    if (promise) {
-      if (optionalContentConfig.getHash() === this._optionalContentHash) {
-        return; // The optional content didn't change, hence no need to reset the UI.
-      }
-    } else {
-      this.eventBus.dispatch("optionalcontentconfig", {
-        source: this,
-        promise: Promise.resolve(optionalContentConfig),
-      });
-    }
-
-    // Reset the sidebarView to the new state.
-    this.render({
-      optionalContentConfig,
-      pdfDocument: this._pdfDocument,
-    });
-  }
-}
-
-export { PDFLayerViewer };

+ 1 - 104
packages/core/src/pdf_page_view.js

@@ -3,7 +3,6 @@ import {
   RenderingCancelledException,
   setLayerDimensions,
   SVGGraphics,
-  shadow,
   AbortException
 } from "pdfjs-dist/legacy/build/pdf";
 import {
@@ -16,11 +15,7 @@ import {
 import {
   PixelsPerInch,
 } from '../constants'
-import { TextAccessibilityManager } from "./text_accessibility.js";
-import { StructTreeLayerBuilder } from "./struct_tree_layer_builder.js";
-import { TextHighlighter } from "./text_highlighter.js";
 import { PDFAnnotationLayer } from './pdf_annotation_layer.js'
-import { TextLayerBuilder } from "./text_layer_builder.js";
 import ComPDFAnnotationLayer from './annotation/layer.js';
 import { ContentContainer } from "./editor/content_container.js";
 import TextSelection from "./TextSelection";
@@ -147,7 +142,6 @@ class PDFPageView {
     this.annotationLayer = null;
     this.compdfAnnotationLayer = null;
     this.annotationEditorLayer = null;
-    this.textLayer = null;
     this.textSelect = null
     this.zoomLayer = null;
     this.xfaLayer = null;
@@ -401,18 +395,6 @@ class PDFPageView {
     this.pdfPage?.cleanup();
   }
 
-  get _textHighlighter() {
-    return shadow(
-      this,
-      "_textHighlighter",
-      new TextHighlighter({
-        pageIndex: this.pageIndex,
-        eventBus: this.eventBus,
-        findController: this.layerProperties().findController,
-      })
-    );
-  }
-
   clearSearchResults() {
     if (this.textSearch) {
       this.textSearch.destroy()
@@ -457,28 +439,6 @@ class PDFPageView {
     }
   }
 
-  /**
-   * @private
-   */
-  async _renderXfaLayer() {
-    let error = null;
-    try {
-      const result = await this.xfaLayer.render(this.viewport, "display");
-      if (result?.textDivs && this._textHighlighter) {
-        this._buildXfaTextContentItems(result.textDivs);
-      }
-    } catch (ex) {
-      console.error(`_renderXfaLayer: "${ex}".`);
-      error = ex;
-    } finally {
-      this.eventBus.dispatch("xfalayerrendered", {
-        source: this,
-        pageNumber: this.id,
-        error,
-      });
-    }
-  }
-
   async #renderTextLayer() {
     const { pdfPage, textLayer, viewport } = this;
     if (!textLayer) {
@@ -508,41 +468,6 @@ class PDFPageView {
       numTextDivs: textLayer.numTextDivs,
       error,
     });
-
-    this.#renderStructTreeLayer();
-  }
-
-  /**
-   * The structure tree is currently only supported when the text layer is
-   * enabled and a canvas is used for rendering.
-   *
-   * The structure tree must be generated after the text layer for the
-   * aria-owns to work.
-   */
-  async #renderStructTreeLayer() {
-    if (!this.textLayer) {
-      return;
-    }
-    this.structTreeLayer ||= new StructTreeLayerBuilder();
-
-    const tree = await (!this.structTreeLayer.renderingDone
-      ? this.pdfPage.getStructTree()
-      : null);
-    const treeDom = this.structTreeLayer?.render(tree);
-    if (treeDom) {
-      this.canvas?.append(treeDom);
-    }
-    this.structTreeLayer?.show();
-  }
-
-  async _buildXfaTextContentItems(textDivs) {
-    const text = await this.pdfPage.getTextContent();
-    const items = [];
-    for (const item of text.items) {
-      items.push(item.str);
-    }
-    this._textHighlighter.setTextMapping(textDivs, items);
-    this._textHighlighter.enable();
   }
 
   /**
@@ -786,10 +711,6 @@ class PDFPageView {
     }
     this.resume = null;
 
-    if (this.textLayer && (!keepTextLayer || !this.textLayer.div)) {
-      this.textLayer.cancel();
-      this.textLayer = null;
-    }
     if (this.structTreeLayer && !this.textLayer) {
       this.structTreeLayer = null;
     }
@@ -812,11 +733,6 @@ class PDFPageView {
       this.annotationEditorLayer.cancel();
       this.annotationEditorLayer = null;
     }
-    if (this.xfaLayer && (!keepXfaLayer || !this.xfaLayer.div)) {
-      this.xfaLayer.cancel();
-      this.xfaLayer = null;
-      this._textHighlighter?.disable();
-    }
     if (this.contentContainer) {
       this.contentContainer.cancel();
       this.contentContainer = null;
@@ -891,10 +807,6 @@ class PDFPageView {
       this._renderAnnotationEditorLayer();
     }
 
-    if (redrawXfaLayer && this.xfaLayer) {
-      this._renderXfaLayer();
-    }
-
     if (this.textLayer) {
       if (hideTextLayer) {
         this.textLayer.hide();
@@ -1053,7 +965,6 @@ class PDFPageView {
             pageDiv: div,
             eventBus: this.eventBus,
             selected: this.selected,
-            $t: this.$t,
             pagePtr: this.pagesPtr[this.pageIndex].pagePtr,
             messageHandler: this.messageHandler
           })
@@ -1092,21 +1003,7 @@ class PDFPageView {
       function (reason) {
         return finishPaintTask(reason);
       }
-    );
-
-    if (pdfPage.isPureXfa) {
-      if (!this.xfaLayer) {
-        const { annotationStorage, linkService } = this.layerProperties();
-
-        this.xfaLayer = new XfaLayerBuilder({
-          pageDiv: div,
-          pdfPage,
-          annotationStorage,
-          linkService,
-        });
-      }
-      this._renderXfaLayer();
-    }
+    )
 
     div.setAttribute("data-loaded", true);
 

+ 0 - 22
packages/core/src/pdf_viewer.js

@@ -37,7 +37,6 @@ import {
 } from "./ui_utils.js";
 
 import { PDFPageView } from "./pdf_page_view.js";
-import MarkupAnnotation from "./markup";
 import { PDFRenderingQueue } from "./pdf_rendering_queue.js";
 import { SimpleLinkService } from "./pdf_link_service.js";
 
@@ -159,7 +158,6 @@ class PDFViewer {
     // this.#resizeObserver.observe(this.container);
 
     this.linkService = options.linkService || new SimpleLinkService();
-    this.findController = options.findController || null;
     this.removePageBorders = false;
     this.textLayerMode = options.textLayerMode ?? TextLayerMode.ENABLE;
     this._annotationEditorMode =
@@ -427,9 +425,6 @@ class PDFViewer {
       get fieldObjectsPromise() {
         return self.pdfDocument?.getFieldObjects();
       },
-      get findController() {
-        return self.findController;
-      },
       get hasJSActionsPromise() {
         return self.pdfDocument?.hasJSActions();
       },
@@ -523,19 +518,12 @@ class PDFViewer {
       this._cancelRendering();
       this._resetView();
 
-      this.findController?.setDocument(null);
-
       if (this._annotationEditorUIManager) {
         this._annotationEditorUIManager.destroy();
         this._annotationEditorUIManager = null;
       }
 
       this.pagesPtr = pagesPtr
-
-      if (this.MarkupAnnotation) {
-        this.MarkupAnnotation.destroy()
-        this.MarkupAnnotation = null
-      }
     }
 
     this.pdfDocument = pdfDocument;
@@ -685,13 +673,6 @@ class PDFViewer {
           this.linkService.cachePageRef(1, firstPdfPage.ref);
         }
 
-        this.MarkupAnnotation = new MarkupAnnotation({
-          eventBus: this.eventBus,
-          viewport,
-          pages: this._pages,
-          scale: this.currentScale
-        })
-
         if (this._scrollMode === ScrollMode.PAGE) {
           // Ensure that the current page becomes visible on document load.
           this.#ensurePageViewVisible();
@@ -703,8 +684,6 @@ class PDFViewer {
         // starts to create the correct size canvas. Wait until one page is
         // rendered so we don't tie up too many resources early on.
         this.#onePageRenderedOrForceFetch().then(async () => {
-          this.findController?.setDocument(pdfDocument); // Enable searching.
-
           if (this._annotationEditorUIManager) {
             // Ensure that the Editor buttons, in the toolbar, are updated.
             this.eventBus.dispatch("annotationeditormodechanged", {
@@ -1127,7 +1106,6 @@ class PDFViewer {
       options.preset = true;
       this._setScaleUpdatePages(scale, value, options);
     }
-    this.MarkupAnnotation.scale = this.currentScale
   }
 
   /**

+ 0 - 1
packages/core/src/renderText/index.js

@@ -410,7 +410,6 @@ function renderTextLayer(params) {
   return task;
 }
 
-
 /**
  * @param {TextLayerUpdateParameters} params
  * @returns {undefined}

+ 0 - 148
packages/core/src/struct_tree_layer_builder.js

@@ -1,148 +0,0 @@
-/* Copyright 2021 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.
- */
-
-const PDF_ROLE_TO_HTML_ROLE = {
-  // Document level structure types
-  Document: null, // There's a "document" role, but it doesn't make sense here.
-  DocumentFragment: null,
-  // Grouping level structure types
-  Part: "group",
-  Sect: "group", // XXX: There's a "section" role, but it's abstract.
-  Div: "group",
-  Aside: "note",
-  NonStruct: "none",
-  // Block level structure types
-  P: null,
-  // H<n>,
-  H: "heading",
-  Title: null,
-  FENote: "note",
-  // Sub-block level structure type
-  Sub: "group",
-  // General inline level structure types
-  Lbl: null,
-  Span: null,
-  Em: null,
-  Strong: null,
-  Link: "link",
-  Annot: "note",
-  Form: "form",
-  // Ruby and Warichu structure types
-  Ruby: null,
-  RB: null,
-  RT: null,
-  RP: null,
-  Warichu: null,
-  WT: null,
-  WP: null,
-  // List standard structure types
-  L: "list",
-  LI: "listitem",
-  LBody: null,
-  // Table standard structure types
-  Table: "table",
-  TR: "row",
-  TH: "columnheader",
-  TD: "cell",
-  THead: "columnheader",
-  TBody: null,
-  TFoot: null,
-  // Standard structure type Caption
-  Caption: null,
-  // Standard structure type Figure
-  Figure: "figure",
-  // Standard structure type Formula
-  Formula: null,
-  // standard structure type Artifact
-  Artifact: null,
-};
-
-const HEADING_PATTERN = /^H(\d+)$/;
-
-class StructTreeLayerBuilder {
-  #treeDom = undefined;
-
-  get renderingDone() {
-    return this.#treeDom !== undefined;
-  }
-
-  render(structTree) {
-    if (this.#treeDom !== undefined) {
-      return this.#treeDom;
-    }
-    const treeDom = this.#walk(structTree);
-    treeDom?.classList.add("structTree");
-    return (this.#treeDom = treeDom);
-  }
-
-  hide() {
-    if (this.#treeDom && !this.#treeDom.hidden) {
-      this.#treeDom.hidden = true;
-    }
-  }
-
-  show() {
-    if (this.#treeDom?.hidden) {
-      this.#treeDom.hidden = false;
-    }
-  }
-
-  #setAttributes(structElement, htmlElement) {
-    if (structElement.alt !== undefined) {
-      htmlElement.setAttribute("aria-label", structElement.alt);
-    }
-    if (structElement.id !== undefined) {
-      htmlElement.setAttribute("aria-owns", structElement.id);
-    }
-    if (structElement.lang !== undefined) {
-      htmlElement.setAttribute("lang", structElement.lang);
-    }
-  }
-
-  #walk(node) {
-    if (!node) {
-      return null;
-    }
-
-    const element = document.createElement("span");
-    if ("role" in node) {
-      const { role } = node;
-      const match = role.match(HEADING_PATTERN);
-      if (match) {
-        element.setAttribute("role", "heading");
-        element.setAttribute("aria-level", match[1]);
-      } else if (PDF_ROLE_TO_HTML_ROLE[role]) {
-        element.setAttribute("role", PDF_ROLE_TO_HTML_ROLE[role]);
-      }
-    }
-
-    this.#setAttributes(node, element);
-
-    if (node.children) {
-      if (node.children.length === 1 && "id" in node.children[0]) {
-        // Often there is only one content node so just set the values on the
-        // parent node to avoid creating an extra span.
-        this.#setAttributes(node.children[0], element);
-      } else {
-        for (const kid of node.children) {
-          element.append(this.#walk(kid));
-        }
-      }
-    }
-    return element;
-  }
-}
-
-export { StructTreeLayerBuilder };

+ 0 - 238
packages/core/src/text_accessibility.js

@@ -1,238 +0,0 @@
-import { binarySearchFirstItem } from "./ui_utils.js";
-
-/**
- * This class aims to provide some methods:
- *  - to reorder elements in the DOM with respect to the visual order;
- *  - to create a link, using aria-owns, between spans in the textLayer and
- *    annotations in the annotationLayer. The goal is to help to know
- *    where the annotations are in the text flow.
- */
-class TextAccessibilityManager {
-  #enabled = false;
-
-  #textChildren = null;
-
-  #textNodes = new Map();
-
-  #waitingElements = new Map();
-
-  setTextMapping(textDivs) {
-    this.#textChildren = textDivs;
-  }
-
-  /**
-   * Compare the positions of two elements, it must correspond to
-   * the visual ordering.
-   *
-   * @param {HTMLElement} e1
-   * @param {HTMLElement} e2
-   * @returns {number}
-   */
-  static #compareElementPositions(e1, e2) {
-    const rect1 = e1.getBoundingClientRect();
-    const rect2 = e2.getBoundingClientRect();
-
-    if (rect1.width === 0 && rect1.height === 0) {
-      return +1;
-    }
-
-    if (rect2.width === 0 && rect2.height === 0) {
-      return -1;
-    }
-
-    const top1 = rect1.y;
-    const bot1 = rect1.y + rect1.height;
-    const mid1 = rect1.y + rect1.height / 2;
-
-    const top2 = rect2.y;
-    const bot2 = rect2.y + rect2.height;
-    const mid2 = rect2.y + rect2.height / 2;
-
-    if (mid1 <= top2 && mid2 >= bot1) {
-      return -1;
-    }
-
-    if (mid2 <= top1 && mid1 >= bot2) {
-      return +1;
-    }
-
-    const centerX1 = rect1.x + rect1.width / 2;
-    const centerX2 = rect2.x + rect2.width / 2;
-
-    return centerX1 - centerX2;
-  }
-
-  /**
-   * Function called when the text layer has finished rendering.
-   */
-  enable() {
-    if (this.#enabled) {
-      throw new Error("TextAccessibilityManager is already enabled.");
-    }
-    if (!this.#textChildren) {
-      throw new Error("Text divs and strings have not been set.");
-    }
-
-    this.#enabled = true;
-    this.#textChildren = this.#textChildren.slice();
-    this.#textChildren.sort(TextAccessibilityManager.#compareElementPositions);
-
-    if (this.#textNodes.size > 0) {
-      // Some links have been made before this manager has been disabled, hence
-      // we restore them.
-      const textChildren = this.#textChildren;
-      for (const [id, nodeIndex] of this.#textNodes) {
-        const element = document.getElementById(id);
-        if (!element) {
-          // If the page was *fully* reset the element no longer exists, and it
-          // will be re-inserted later (i.e. when the annotationLayer renders).
-          this.#textNodes.delete(id);
-          continue;
-        }
-        this.#addIdToAriaOwns(id, textChildren[nodeIndex]);
-      }
-    }
-
-    for (const [element, isRemovable] of this.#waitingElements) {
-      this.addPointerInTextLayer(element, isRemovable);
-    }
-    this.#waitingElements.clear();
-  }
-
-  disable() {
-    if (!this.#enabled) {
-      return;
-    }
-
-    // Don't clear this.#textNodes which is used to rebuild the aria-owns
-    // in case it's re-enabled at some point.
-
-    this.#waitingElements.clear();
-    this.#textChildren = null;
-    this.#enabled = false;
-  }
-
-  /**
-   * Remove an aria-owns id from a node in the text layer.
-   * @param {HTMLElement} element
-   */
-  removePointerInTextLayer(element) {
-    if (!this.#enabled) {
-      this.#waitingElements.delete(element);
-      return;
-    }
-
-    const children = this.#textChildren;
-    if (!children || children.length === 0) {
-      return;
-    }
-
-    const { id } = element;
-    const nodeIndex = this.#textNodes.get(id);
-    if (nodeIndex === undefined) {
-      return;
-    }
-
-    const node = children[nodeIndex];
-
-    this.#textNodes.delete(id);
-    let owns = node.getAttribute("aria-owns");
-    if (owns?.includes(id)) {
-      owns = owns
-        .split(" ")
-        .filter(x => x !== id)
-        .join(" ");
-      if (owns) {
-        node.setAttribute("aria-owns", owns);
-      } else {
-        node.removeAttribute("aria-owns");
-        node.setAttribute("role", "presentation");
-      }
-    }
-  }
-
-  #addIdToAriaOwns(id, node) {
-    const owns = node.getAttribute("aria-owns");
-    if (!owns?.includes(id)) {
-      node.setAttribute("aria-owns", owns ? `${owns} ${id}` : id);
-    }
-    node.removeAttribute("role");
-  }
-
-  /**
-   * Find the text node which is the nearest and add an aria-owns attribute
-   * in order to correctly position this editor in the text flow.
-   * @param {HTMLElement} element
-   * @param {boolean} isRemovable
-   */
-  addPointerInTextLayer(element, isRemovable) {
-    const { id } = element;
-    if (!id) {
-      return;
-    }
-
-    if (!this.#enabled) {
-      // The text layer needs to be there, so we postpone the association.
-      this.#waitingElements.set(element, isRemovable);
-      return;
-    }
-
-    if (isRemovable) {
-      this.removePointerInTextLayer(element);
-    }
-
-    const children = this.#textChildren;
-    if (!children || children.length === 0) {
-      return;
-    }
-
-    const index = binarySearchFirstItem(
-      children,
-      node =>
-        TextAccessibilityManager.#compareElementPositions(element, node) < 0
-    );
-
-    const nodeIndex = Math.max(0, index - 1);
-    this.#addIdToAriaOwns(id, children[nodeIndex]);
-    this.#textNodes.set(id, nodeIndex);
-  }
-
-  /**
-   * Move a div in the DOM in order to respect the visual order.
-   * @param {HTMLDivElement} element
-   */
-  moveElementInDOM(container, element, contentElement, isRemovable) {
-    this.addPointerInTextLayer(contentElement, isRemovable);
-
-    if (!container.hasChildNodes()) {
-      container.append(element);
-      return;
-    }
-
-    const children = Array.from(container.childNodes).filter(
-      node => node !== element
-    );
-
-    if (children.length === 0) {
-      return;
-    }
-
-    const elementToCompare = contentElement || element;
-    const index = binarySearchFirstItem(
-      children,
-      node =>
-        TextAccessibilityManager.#compareElementPositions(
-          elementToCompare,
-          node
-        ) < 0
-    );
-
-    if (index === 0) {
-      children[0].before(element);
-    } else {
-      children[index - 1].after(element);
-    }
-  }
-}
-
-export { TextAccessibilityManager };

+ 0 - 300
packages/core/src/text_highlighter.js

@@ -1,300 +0,0 @@
-/* Copyright 2021 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.
- */
-
-/** @typedef {import("./event_utils").EventBus} EventBus */
-// eslint-disable-next-line max-len
-/** @typedef {import("./pdf_find_controller").PDFFindController} PDFFindController */
-
-/**
- * @typedef {Object} TextHighlighterOptions
- * @property {PDFFindController} findController
- * @property {EventBus} eventBus - The application event bus.
- * @property {number} pageIndex - The page index.
- */
-
-/**
- * TextHighlighter handles highlighting matches from the FindController in
- * either the text layer or XFA layer depending on the type of document.
- */
-class TextHighlighter {
-  /**
-   * @param {TextHighlighterOptions} options
-   */
-  constructor({ findController, eventBus, pageIndex }) {
-    this.findController = findController;
-    this.matches = [];
-    this.eventBus = eventBus;
-    this.pageIdx = pageIndex;
-    this._onUpdateTextLayerMatches = null;
-    this.textDivs = null;
-    this.textContentItemsStr = null;
-    this.enabled = false;
-  }
-
-  /**
-   * Store two arrays that will map DOM nodes to text they should contain.
-   * The arrays should be of equal length and the array element at each index
-   * should correspond to the other. e.g.
-   * `items[0] = "<span>Item 0</span>" and texts[0] = "Item 0";
-   *
-   * @param {Array<Node>} divs
-   * @param {Array<string>} texts
-   */
-  setTextMapping(divs, texts) {
-    this.textDivs = divs;
-    this.textContentItemsStr = texts;
-  }
-
-  /**
-   * Start listening for events to update the highlighter and check if there are
-   * any current matches that need be highlighted.
-   */
-  enable() {
-    if (!this.textDivs || !this.textContentItemsStr) {
-      throw new Error("Text divs and strings have not been set.");
-    }
-    if (this.enabled) {
-      throw new Error("TextHighlighter is already enabled.");
-    }
-    this.enabled = true;
-    if (!this._onUpdateTextLayerMatches) {
-      this._onUpdateTextLayerMatches = evt => {
-        if (evt.pageIndex === this.pageIdx || evt.pageIndex === -1) {
-          this._updateMatches();
-        }
-      };
-      this.eventBus._on(
-        "updatetextlayermatches",
-        this._onUpdateTextLayerMatches
-      );
-    }
-    this._updateMatches();
-  }
-
-  disable() {
-    if (!this.enabled) {
-      return;
-    }
-    this.enabled = false;
-    if (this._onUpdateTextLayerMatches) {
-      this.eventBus._off(
-        "updatetextlayermatches",
-        this._onUpdateTextLayerMatches
-      );
-      this._onUpdateTextLayerMatches = null;
-    }
-    this._updateMatches(/* reset = */ true);
-  }
-
-  _convertMatches(matches, matchesLength) {
-    // Early exit if there is nothing to convert.
-    if (!matches) {
-      return [];
-    }
-    const { textContentItemsStr } = this;
-
-    let i = 0,
-      iIndex = 0;
-    const end = textContentItemsStr.length - 1;
-    const result = [];
-
-    for (let m = 0, mm = matches.length; m < mm; m++) {
-      // Calculate the start position.
-      let matchIdx = matches[m];
-
-      // Loop over the divIdxs.
-      while (i !== end && matchIdx >= iIndex + textContentItemsStr[i].length) {
-        iIndex += textContentItemsStr[i].length;
-        i++;
-      }
-
-      if (i === textContentItemsStr.length) {
-        console.error("Could not find a matching mapping");
-      }
-
-      const match = {
-        begin: {
-          divIdx: i,
-          offset: matchIdx - iIndex,
-        },
-      };
-
-      // Calculate the end position.
-      matchIdx += matchesLength[m];
-
-      // Somewhat the same array as above, but use > instead of >= to get
-      // the end position right.
-      while (i !== end && matchIdx > iIndex + textContentItemsStr[i].length) {
-        iIndex += textContentItemsStr[i].length;
-        i++;
-      }
-
-      match.end = {
-        divIdx: i,
-        offset: matchIdx - iIndex,
-      };
-      result.push(match);
-    }
-    return result;
-  }
-
-  _renderMatches(matches) {
-    // Early exit if there is nothing to render.
-    if (matches.length === 0) {
-      return;
-    }
-    const { findController, pageIdx } = this;
-    const { textContentItemsStr, textDivs } = this;
-
-    const isSelectedPage = pageIdx === findController.selected.pageIdx;
-    const selectedMatchIdx = findController.selected.matchIdx;
-    const highlightAll = findController.state.highlightAll;
-    let prevEnd = null;
-    const infinity = {
-      divIdx: -1,
-      offset: undefined,
-    };
-
-    function beginText(begin, className) {
-      const divIdx = begin.divIdx;
-      textDivs[divIdx].textContent = "";
-      return appendTextToDiv(divIdx, 0, begin.offset, className);
-    }
-
-    function appendTextToDiv(divIdx, fromOffset, toOffset, className) {
-      let div = textDivs[divIdx];
-      if (div.nodeType === Node.TEXT_NODE) {
-        const span = document.createElement("span");
-        div.before(span);
-        span.append(div);
-        textDivs[divIdx] = span;
-        div = span;
-      }
-      const content = textContentItemsStr[divIdx].substring(
-        fromOffset,
-        toOffset
-      );
-      const node = document.createTextNode(content);
-      if (className) {
-        const span = document.createElement("span");
-        span.className = `${className} appended`;
-        span.append(node);
-        div.append(span);
-        return className.includes("selected") ? span.offsetLeft : 0;
-      }
-      div.append(node);
-      return 0;
-    }
-
-    let i0 = selectedMatchIdx,
-      i1 = i0 + 1;
-    if (highlightAll) {
-      i0 = 0;
-      i1 = matches.length;
-    } else if (!isSelectedPage) {
-      // Not highlighting all and this isn't the selected page, so do nothing.
-      return;
-    }
-
-    for (let i = i0; i < i1; i++) {
-      const match = matches[i];
-      const begin = match.begin;
-      const end = match.end;
-      const isSelected = isSelectedPage && i === selectedMatchIdx;
-      const highlightSuffix = isSelected ? " selected" : "";
-      let selectedLeft = 0;
-
-      // Match inside new div.
-      if (!prevEnd || begin.divIdx !== prevEnd.divIdx) {
-        // If there was a previous div, then add the text at the end.
-        if (prevEnd !== null) {
-          appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset);
-        }
-        // Clear the divs and set the content until the starting point.
-        beginText(begin);
-      } else {
-        appendTextToDiv(prevEnd.divIdx, prevEnd.offset, begin.offset);
-      }
-
-      if (begin.divIdx === end.divIdx) {
-        selectedLeft = appendTextToDiv(
-          begin.divIdx,
-          begin.offset,
-          end.offset,
-          "highlight" + highlightSuffix
-        );
-      } else {
-        selectedLeft = appendTextToDiv(
-          begin.divIdx,
-          begin.offset,
-          infinity.offset,
-          "highlight begin" + highlightSuffix
-        );
-        for (let n0 = begin.divIdx + 1, n1 = end.divIdx; n0 < n1; n0++) {
-          textDivs[n0].className = "highlight middle" + highlightSuffix;
-        }
-        beginText(end, "highlight end" + highlightSuffix);
-      }
-      prevEnd = end;
-
-      if (isSelected) {
-        // Attempt to scroll the selected match into view.
-        findController.scrollMatchIntoView({
-          element: textDivs[begin.divIdx],
-          selectedLeft,
-          pageIndex: pageIdx,
-          matchIndex: selectedMatchIdx,
-        });
-      }
-    }
-
-    if (prevEnd) {
-      appendTextToDiv(prevEnd.divIdx, prevEnd.offset, infinity.offset);
-    }
-  }
-
-  _updateMatches(reset = false) {
-    if (!this.enabled && !reset) {
-      return;
-    }
-    const { findController, matches, pageIdx } = this;
-    const { textContentItemsStr, textDivs } = this;
-    let clearedUntilDivIdx = -1;
-
-    // Clear all current matches.
-    for (const match of matches) {
-      const begin = Math.max(clearedUntilDivIdx, match.begin.divIdx);
-      for (let n = begin, end = match.end.divIdx; n <= end; n++) {
-        const div = textDivs[n];
-        div.textContent = textContentItemsStr[n];
-        div.className = "";
-      }
-      clearedUntilDivIdx = match.end.divIdx + 1;
-    }
-
-    if (!findController?.highlightMatches || reset) {
-      return;
-    }
-    // Convert the matches on the `findController` into the match format
-    // used for the textLayer.
-    const pageMatches = findController.pageMatches[pageIdx] || null;
-    const pageMatchesLength = findController.pageMatchesLength[pageIdx] || null;
-
-    this.matches = this._convertMatches(pageMatches, pageMatchesLength);
-    this._renderMatches(this.matches);
-  }
-}
-
-export { TextHighlighter };

+ 0 - 225
packages/core/src/text_layer_builder.js

@@ -1,225 +0,0 @@
-import { OPS } from "pdfjs-dist/legacy/build/pdf";
-import { renderTextLayer, updateTextLayer } from "./renderText";
-
-/**
- * @typedef {Object} TextLayerBuilderOptions
- * @property {TextHighlighter} highlighter - Optional object that will handle
- *   highlighting text from the find controller.
- * @property {TextAccessibilityManager} [accessibilityManager]
- * @property {boolean} [isOffscreenCanvasSupported] - Allows to use an
- *   OffscreenCanvas if needed.
- */
-
-/**
- * The text layer builder provides text selection functionality for the PDF.
- * It does this by creating overlay divs over the PDF's text. These divs
- * contain text that matches the PDF text they are overlaying.
- */
-class TextLayerBuilder {
-  constructor({
-    pdfPage,
-    highlighter = null,
-    accessibilityManager = null,
-    isOffscreenCanvasSupported = true,
-  }) {
-    this.pdfPage = pdfPage;
-    this.rotation = 0
-    this.scale = 0;
-    this.textContentSource = null;
-    this.textContentItemsStr = [];
-    this.renderingDone = false;
-    this.textDivs = [];
-    this.textDivProperties = new WeakMap();
-    this.textLayerRenderTask = null;
-    this.highlighter = highlighter;
-    this.accessibilityManager = accessibilityManager;
-    this.isOffscreenCanvasSupported = isOffscreenCanvasSupported;
-
-    this.div = document.createElement("div");
-    this.div.className = "textLayer";
-    this.hide();
-    
-  }
-
-  #finishRendering() {
-    this.renderingDone = true;
-
-    const endOfContent = document.createElement("div");
-    endOfContent.className = "endOfContent";
-    this.div.append(endOfContent);
-
-    this.#bindMouse();
-  }
-
-  get numTextDivs() {
-    return this.textDivs.length;
-  }
-
-  /**
-   * Renders the text layer.
-   * @param {PageViewport} viewport
-   */
-  async render(viewport) {
-    if (!this.textContentSource) {
-      throw new Error('No "textContentSource" parameter specified.');
-    }
-
-    const scale = viewport.scale * (globalThis.devicePixelRatio || 1);
-    const { rotation } = viewport;
-    if (this.renderingDone) {
-      const mustRotate = rotation !== this.rotation;
-      const mustRescale = scale !== this.scale;
-      if (mustRotate || mustRescale) {
-        this.hide();
-        updateTextLayer({
-          container: this.div,
-          viewport,
-          textDivs: this.textDivs,
-          textDivProperties: this.textDivProperties,
-          isOffscreenCanvasSupported: this.isOffscreenCanvasSupported,
-          mustRescale,
-          mustRotate,
-        });
-        this.scale = scale;
-        this.rotation = rotation;
-      }
-      this.show();
-      return;
-    }
-
-    this.cancel();
-    this.highlighter?.setTextMapping(this.textDivs, this.textContentItemsStr);
-    this.accessibilityManager?.setTextMapping(this.textDivs);
-
-    this.textLayerRenderTask = renderTextLayer({
-      textContentSource: this.textContentSource,
-      container: this.div,
-      viewport,
-      textDivs: this.textDivs,
-      textDivProperties: this.textDivProperties,
-      textContentItemsStr: this.textContentItemsStr,
-      isOffscreenCanvasSupported: this.isOffscreenCanvasSupported,
-    });
-    
-    this.pdfPage.getOperatorList().then(opList => {
-      // let textContent = opList.getTextContent();
-      var textContent = '';
-      // 遍历操作符列表
-      for (var i = 0; i < opList.fnArray.length; i++) {
-        var fn = opList.fnArray[i];
-        var args = opList.argsArray[i];
-
-        // 如果是文本操作符
-        if (fn === OPS.showText) {
-          // 遍历参数数组,获取每个字符的Unicode编码值和字形信息
-          for (var j = 0; j < args.length; j++) {
-            if (typeof args[j].unicode === 'string') {
-              // 文本参数
-              textContent += args[j];
-            } else if (typeof args[j].unicode === 'number') {
-              // 字形参数
-              var glyph = pdfPage.commonObjs.get(args[j]);
-              var charCode = glyph.unicode.charCodeAt(0);
-
-              // 处理每个字符的信息
-              // console.log('Char code: ' + charCode + ', glyph info: ', glyph);
-            }
-          }
-        }
-      }
-    })
-
-    await this.textLayerRenderTask.promise;
-    this.#finishRendering();
-    this.scale = scale;
-    this.rotation = rotation;
-    this.show();
-    this.accessibilityManager?.enable();
-  }
-
-  hide() {
-    if (!this.div.hidden) {
-      // We turn off the highlighter in order to avoid to scroll into view an
-      // element of the text layer which could be hidden.
-      this.highlighter?.disable();
-      this.div.hidden = true;
-    }
-  }
-
-  show() {
-    if (this.div.hidden && this.renderingDone) {
-      this.div.hidden = false;
-      this.highlighter?.enable();
-    }
-  }
-
-  /**
-   * Cancel rendering of the text layer.
-   */
-  cancel() {
-    if (this.textLayerRenderTask) {
-      this.textLayerRenderTask.cancel();
-      this.textLayerRenderTask = null;
-    }
-    this.highlighter?.disable();
-    this.accessibilityManager?.disable();
-    this.textContentItemsStr.length = 0;
-    this.textDivs.length = 0;
-    this.textDivProperties = new WeakMap();
-  }
-
-  /**
-   * @param {ReadableStream | TextContent} source
-   */
-  setTextContentSource(source) {
-    this.cancel();
-    this.textContentSource = source;
-  }
-
-  /**
-   * Improves text selection by adding an additional div where the mouse was
-   * clicked. This reduces flickering of the content if the mouse is slowly
-   * dragged up or down.
-   */
-  #bindMouse() {
-    const { div } = this;
-
-    div.addEventListener("mousedown", evt => {
-      const end = div.querySelector(".endOfContent");
-      if (!end) {
-        return;
-      }
-      if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
-        // On non-Firefox browsers, the selection will feel better if the height
-        // of the `endOfContent` div is adjusted to start at mouse click
-        // location. This avoids flickering when the selection moves up.
-        // However it does not work when selection is started on empty space.
-        let adjustTop = evt.target !== div;
-        if (typeof PDFJSDev === "undefined" || PDFJSDev.test("GENERIC")) {
-          adjustTop &&=
-            getComputedStyle(end).getPropertyValue("-moz-user-select") !==
-            "none";
-        }
-        if (adjustTop) {
-          const divBounds = div.getBoundingClientRect();
-          const r = Math.max(0, (evt.pageY - divBounds.top) / divBounds.height);
-          end.style.top = (r * 100).toFixed(2) + "%";
-        }
-      }
-      end.classList.add("active");
-    });
-
-    div.addEventListener("mouseup", () => {
-      const end = div.querySelector(".endOfContent");
-      if (!end) {
-        return;
-      }
-      if (typeof PDFJSDev === "undefined" || !PDFJSDev.test("MOZCENTRAL")) {
-        end.style.top = "";
-      }
-      end.classList.remove("active");
-    });
-  }
-}
-
-export { TextLayerBuilder };

+ 6 - 29
packages/core/src/worker/compdfkit_worker.js

@@ -1,8 +1,7 @@
-importScripts("/lib/ComPDFkit.js")
+importScripts("./ComPDFkit.js")
 
-import Color from '../color';
 import { parseAdobePDFTimestamp, convertToPDFTimestamp, roundToDecimalPlaces, convertColorToCppFormat, convertCppRGBToHex } from '../ui_utils';
-import { AnnotationType, WidgetType, LineTypeString, StampType, StampTypeString, TextStampColorString, TextStampShapeString, ActionTypeString, WidgetTypeString, AnnotationFlags, BorderStyleInt, BorderStyleString, CheckStyleString, ALIGN, ALIGNMAP } from '../../constants'
+import { AnnotationType, WidgetType, LineTypeString, StampType, StampTypeString, TextStampShapeString, ActionTypeString, WidgetTypeString, AnnotationFlags, BorderStyleInt, BorderStyleString, ALIGN, ALIGNMAP } from '../../constants'
 
 let ComPDFKitJS = {}
 let DataArray = []
@@ -163,7 +162,7 @@ class CPDFWorker {
         imageArray[i + 2] = Module.HEAPU8[imageptr + i]
         imageArray[i + 3] = Module.HEAPU8[imageptr + i + 3]
       }
-
+      _free(imageptr)
       return imageArray
     })
 
@@ -198,7 +197,6 @@ class CPDFWorker {
 
     messageHandler.on('EditAnnotation', (data) => {
       const { annotation } = data
-      console.log('EditAnnotation: ', annotation)
       if (annotation.rect) {
         setAnnotRect(annotation)
       }
@@ -324,7 +322,6 @@ class CPDFWorker {
     messageHandler.on('RemoveAnnot', (data) => {
       const { annotPtr } = data
       const res = Module._RemoveAnnot(annotPtr)
-      console.log(res)
     })
 
     messageHandler.on('GetCharIndexAtPos', (data) => {
@@ -359,11 +356,10 @@ class CPDFWorker {
       let xfdfBufferPtr = _malloc(xfdfBuffer.length)
       Module.HEAPU8.set(xfdfBuffer, xfdfBufferPtr)
       const res = Module._XFDFImportAnnotaitons(doc, xfdfBufferPtr, xfdfBuffer.length)
-      console.log(res)
+      _free(xfdfBufferPtr)
     })
 
     messageHandler.on('SaveDocumentByStream', (data) => {
-      console.log('SaveDocumentByStream')
       return saveDocumentByStream(data)
     })
 
@@ -390,7 +386,7 @@ class CPDFWorker {
       const newPagesCount = Module._GetPageCount(newDocPtr)
 
       const minPageCount = Math.min(oldPagesCount, newPagesCount)
-      console.log(data)
+
       // type 1: 内容对比 2: 覆盖对比
       if (data.type === 1) {
         const { replaceColor: rawReplaceColor, insertColor: rawInsertColor, deleteColor: rawDeleteColor, textCompare, imgCompare } = data
@@ -1037,9 +1033,6 @@ function RenderPageBitmapWithMatrix(data) {
     imageArray[i + 1] = Module.HEAPU8[imageptr + i + 1]
     imageArray[i + 2] = Module.HEAPU8[imageptr + i]
     imageArray[i + 3] = Module.HEAPU8[imageptr + i + 3]
-    // if (imageArray[i] !== 255 || imageArray[i + 1] !== 255 || imageArray[i + 2] !== 255 || imageArray[i + 3] !== 255) {
-    //   console.log(223)
-    // }
   }
   _free(imageptr)
 
@@ -1345,13 +1338,6 @@ function createOutline(doc, ptrs, outlinePtr, outlines, level) {
   return Module._GetNext(outlinePtr)
 }
 
-function getActionType(ptr) {
-  const actionPtr = Module._GetOutlineAction(ptr)
-  const actionType = Module._GetActionType(actionPtr)
-  console.log(actionType)
-  return actionType
-}
-
 function getOutlineAction(doc, outlinePtr, actionType, outline) {
   if (actionType === 1) {
     PDFDestination = {}
@@ -1444,7 +1430,6 @@ function getAnnotation({
   const content = U8StringData
   Module._GetAnnotTitle(annotPtr)
   const title = U8StringData
-  console.log(title)
 
   const transparency = roundToDecimalPlaces(Module._GetAnnotTransparency(annotPtr))
 
@@ -1938,9 +1923,7 @@ async function flattenPdfDownload(data) {
 
 function exportXFDFByStream(doc) {
   XFDFData = {}
-  console.log(doc)
   Module._XFDFExportAnnotations(doc)
-  console.log(XFDFData)
   return XFDFData
 }
 
@@ -1967,7 +1950,6 @@ function setAnnotContent(data) {
 
   Module._GetAnnotContent(annotPtr)
   const res = U8StringData
-  console.log(res)
 
   return result
 }
@@ -2055,7 +2037,7 @@ function setInkPointes(data) {
   }
 
   const res = Module._SetInkPath(pagePtr, annotPtr, inklistArrayPtr, lineLength, inkPointesArrayPtr)
-  console.log(res)
+  _free(inkPointesArrayPtr)
 }
 
 function setLinkDest(data) {
@@ -2067,7 +2049,6 @@ function setLinkUri(data) {
   const { annotPtr, url: rawUrl } = data
   const url = stringToNewUTF8(rawUrl)
   const res = Module._SetLinkUri(annotPtr, url)
-  console.log(res)
 }
 
 function setAnnotHidden(data) {
@@ -2087,21 +2068,18 @@ function setCheckBoxIsChecked(data) {
   const { annotPtr, isChecked } = data
 
   const result = Module._SetCheckBoxIsChecked(annotPtr, isChecked)
-  console.log(result)
 }
 
 function setRadioButtonIsChecked(data) {
   const { annotPtr, isChecked } = data
 
   const result = Module._SetRadioButtonIsChecked(annotPtr, isChecked)
-  console.log(result)
 }
 
 function setCheckStyle(data) {
   const { annotPtr, checkStyle } = data
 
   const result = Module._SetWidgetCheckStyle(annotPtr, checkStyle)
-  console.log(result)
 }
 
 function setWidgetBackgroundColor(data) {
@@ -2205,7 +2183,6 @@ function setWidgetItems(data) {
 function deleteWidgetItem(data) {
   const { annotPtr, deleteItemIndex } = data
   const res = Module._RemoveOptionItem(annotPtr, deleteItemIndex)
-  console.log(res)
 }
 
 function createMarkup(data) {

+ 2 - 2
packages/webview/package.json

@@ -1,5 +1,5 @@
 {
-  "name": "@vue-pdf/webview",
+  "name": "@compdfkit/webview",
   "version": "0.0.0",
   "scripts": {
     "dev": "vite --host 0.0.0.0 --port 3032",
@@ -9,7 +9,7 @@
     "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
   },
   "dependencies": {
-    "@vue-pdf/core": "1.0.0",
+    "@compdfkit/core": "1.0.0",
     "@vueuse/core": "^9.12.0",
     "@vueuse/integrations": "^9.5.0",
     "axios": "^0.27.2",

+ 10 - 5
packages/webview/src/components/CompareDocumentContainer/CompareDocumentContainer.vue

@@ -98,13 +98,12 @@
 </template>
 
 <script setup>
-import { computed, ref, watch, onMounted, onBeforeUnmount } from 'vue'
+import { computed, ref, watch } from 'vue'
 import { useViewerStore } from '@/stores/modules/viewer'
 import { useDocumentStore } from '@/stores/modules/document'
 import getHashParameters from '@/helpers/getHashParameters'
 import core from '@/core'
-import initConfig from '@/core/initConfig'
-const { loadDocument, initializeViewer } = core
+const { loadDocument, initializeViewer, init } = core
 
 defineProps({
   docNum: Number
@@ -124,6 +123,8 @@ let newFile = computed(() => useDocument.getCompareFile('newFile'))
 let isDragOverOld = ref(false)
 let isDragOverNew = ref(false)
 
+const verified = computed(() => useViewer.getVerified)
+
 watch(() => toolMode.value, (newValue, oldValue) => {
   if (oldValue === 'compare' && newValue !== oldValue) {
     removeFile()
@@ -131,6 +132,10 @@ watch(() => toolMode.value, (newValue, oldValue) => {
   }
   if (newValue === 'compare' && newValue !== oldValue) {
     setTimeout(() => {
+      console.log(verified)
+      if (!verified.value) {
+        alert('Invalid license')
+      }
       initDocumentView()
     }, 1)
   }
@@ -234,13 +239,13 @@ const initDocumentView = () => {
   core.setDocumentViewer(3, null, {
     $t: instance.$t
   })
-  initConfig({}, 2)
+  init(2)
   initializeViewer({
     container: oldFileContainer.value,
     viewer: oldViewerContainer.value,
   }, 2)
   
-  initConfig({}, 3)
+  init(3)
   initializeViewer({
     container: newFileContainer.value,
     viewer: newViewerContainer.value,

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

@@ -169,6 +169,7 @@ onMounted(async () => {
   const webviewerMode = !!(options && options.webviewerServer) ? options.webviewerServer : 'Standalone'
   useViewer.setWebviewerMode(webviewerMode)
   if (!res) return
+  useViewer.setVierified(true)
   const thumbnailView = document.querySelector('.thumbnail-view')
   const annotationView = document.querySelector('.annotation-view')
   const outlineView = document.querySelector('.outline-view')
@@ -183,7 +184,7 @@ onMounted(async () => {
     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/Quick Start Guide for ComPDFKit Web Demo.pdf'
   initialDoc = Array.isArray(initialDoc) ? initialDoc : [initialDoc]
   const activeTab = useViewer.activeTab || 0
   initialDoc = initialDoc[activeTab]
@@ -192,6 +193,8 @@ onMounted(async () => {
     useViewer.setUploadLoading(true)
     await handlePdf(initialDoc)
     useViewer.setUploadLoading(false)
+  } else {
+    useViewer.setUpload(false)
   }
 })
 </script>
@@ -433,7 +436,7 @@ onMounted(async () => {
     color: #333333;
   }
   &.text svg {
-    cursor: text;
+    cursor: text !important;
   }
   .text-container .text-selection {
     position: absolute;

+ 5 - 0
packages/webview/src/components/HeaderItems/HeaderItems.vue

@@ -115,8 +115,13 @@ let showToolMode = computed(()=>{
 })
 
 const webviewerMode = computed(() => useViewer.getWebviewerMode)
+const verified = computed(() => useViewer.getVerified)
 
 const changeToolMode = (mode) => {
+  if (!verified.value) {
+    alert('Invalid license')
+    return
+  }
   if (webviewerMode.value !== 'Standalone' && mode === 'editor') {
     useViewer.openElement('preventDialog')
     return

+ 3 - 1
packages/webview/src/core/index.js

@@ -48,6 +48,7 @@ import getOutlines from './getOutlines'
 import search from './search'
 import setActiveSearchResult from './setActiveSearchResult'
 import clearSearchResults from './clearSearchResults'
+import init from './init'
 
 export default {
   getDocumentViewer,
@@ -102,5 +103,6 @@ export default {
   getOutlines,
   search,
   setActiveSearchResult,
-  clearSearchResults
+  clearSearchResults,
+  init
 }

+ 3 - 0
packages/webview/src/core/init.js

@@ -0,0 +1,3 @@
+import core from '@/core'
+
+export default (num = 1) => core.getDocumentViewer(num).init()

+ 7 - 0
packages/webview/src/stores/modules/viewer.js

@@ -20,6 +20,7 @@ export const useViewerStore = defineStore({
     activeStickNote: false,
     activeActiveMeasure: false,
     activeHand: false,
+    verified: false,
     activeElements: {
       leftPanel: false,
       rightPanel: false,
@@ -325,6 +326,9 @@ export const useViewerStore = defineStore({
     },
     getCompareMode () {
       return this.compareMode
+    },
+    getVerified () {
+      return this.verified
     }
   },
   actions: {
@@ -368,6 +372,9 @@ export const useViewerStore = defineStore({
         stampPanel: false
       }
     },
+    setVierified (verified) {
+      this.verified = verified
+    },
     setFullMode (fullMode) {
       return this.fullMode = fullMode
     },

+ 64 - 43
pnpm-lock.yaml

@@ -15,7 +15,9 @@ importers:
       '@rollup/plugin-commonjs': ^23.0.2
       '@rollup/plugin-json': ^6.0.0
       '@rollup/plugin-node-resolve': ^15.0.1
+      '@rollup/plugin-terser': ^0.4.4
       '@typescript-eslint/parser': ^6.7.2
+      copy-to-clipboard: ^3.3.3
       cross-env: ^7.0.3
       crypto-js: ^4.1.1
       dayjs: ^1.11.6
@@ -31,12 +33,12 @@ importers:
       rollup: ^3.2.3
       rollup-plugin-node-builtins: ^2.1.2
       rollup-plugin-typescript2: ^0.35.0
-      rollup-plugin-uglify: ^6.0.4
       roughjs: ^4.5.2
       typescript: ^5.2.2
       uuid: ^9.0.0
       uuidv4: ^6.2.13
     dependencies:
+      copy-to-clipboard: 3.3.3
       crypto-js: 4.1.1
       dayjs: 1.11.7
       file-saver: 2.0.5
@@ -60,18 +62,18 @@ importers:
       '@rollup/plugin-commonjs': 23.0.7_rollup@3.20.2
       '@rollup/plugin-json': 6.0.0_rollup@3.20.2
       '@rollup/plugin-node-resolve': 15.0.2_rollup@3.20.2
+      '@rollup/plugin-terser': 0.4.4_rollup@3.20.2
       '@typescript-eslint/parser': 6.7.2_typescript@5.2.2
       cross-env: 7.0.3
       rollup: 3.20.2
       rollup-plugin-node-builtins: 2.1.2
       rollup-plugin-typescript2: 0.35.0_n62mu3igqaflart3wrngw5b5iy
-      rollup-plugin-uglify: 6.0.4_rollup@3.20.2
       typescript: 5.2.2
 
   packages/webview:
     specifiers:
+      '@compdfkit/core': 1.0.0
       '@vitejs/plugin-vue': ^3.1.2
-      '@vue-pdf/core': 1.0.0
       '@vue/test-utils': ^2.1.0
       '@vueuse/core': ^9.12.0
       '@vueuse/integrations': ^9.5.0
@@ -92,7 +94,7 @@ importers:
       vue: ^3.2.41
       vue-i18n: '9'
     dependencies:
-      '@vue-pdf/core': link:../core
+      '@compdfkit/core': link:../core
       '@vueuse/core': 9.13.0_vue@3.2.47
       '@vueuse/integrations': 9.13.0_axios@0.27.2+vue@3.2.47
       axios: 0.27.2
@@ -1448,6 +1450,13 @@ packages:
     engines: {node: '>=6.0.0'}
     dev: true
 
+  /@jridgewell/source-map/0.3.5:
+    resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
+    dependencies:
+      '@jridgewell/gen-mapping': 0.3.3
+      '@jridgewell/trace-mapping': 0.3.18
+    dev: true
+
   /@jridgewell/sourcemap-codec/1.4.14:
     resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==}
     dev: true
@@ -1575,6 +1584,21 @@ packages:
       rollup: 3.20.2
     dev: true
 
+  /@rollup/plugin-terser/0.4.4_rollup@3.20.2:
+    resolution: {integrity: sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==}
+    engines: {node: '>=14.0.0'}
+    peerDependencies:
+      rollup: ^2.0.0||^3.0.0||^4.0.0
+    peerDependenciesMeta:
+      rollup:
+        optional: true
+    dependencies:
+      rollup: 3.20.2
+      serialize-javascript: 6.0.1
+      smob: 1.4.1
+      terser: 5.22.0
+    dev: true
+
   /@rollup/pluginutils/4.2.1:
     resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==}
     engines: {node: '>= 8.0.0'}
@@ -2358,6 +2382,12 @@ packages:
     resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
     dev: true
 
+  /copy-to-clipboard/3.3.3:
+    resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==}
+    dependencies:
+      toggle-selection: 1.0.6
+    dev: false
+
   /core-js-compat/3.30.0:
     resolution: {integrity: sha512-P5A2h/9mRYZFIAP+5Ab8ns6083IyVpSclU74UNvbGVQ8VM7n3n3/g2yF3AkKQ9NXz2O+ioxLbEWKnDtgsFamhg==}
     dependencies:
@@ -3466,14 +3496,6 @@ packages:
     resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
     dev: true
 
-  /jest-worker/24.9.0:
-    resolution: {integrity: sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw==}
-    engines: {node: '>= 6'}
-    dependencies:
-      merge-stream: 2.0.0
-      supports-color: 6.1.0
-    dev: true
-
   /js-beautify/1.14.6:
     resolution: {integrity: sha512-GfofQY5zDp+cuHc+gsEXKPpNw2KbPddreEo35O6jT6i0RVK6LhsoYBhq5TvK4/n74wnA0QbK8gGd+jUZwTMKJw==}
     engines: {node: '>=10'}
@@ -3769,10 +3791,6 @@ packages:
       safe-buffer: 5.2.1
     dev: true
 
-  /merge-stream/2.0.0:
-    resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
-    dev: true
-
   /merge2/1.4.1:
     resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
     engines: {node: '>= 8'}
@@ -4433,18 +4451,6 @@ packages:
       typescript: 5.2.2
     dev: true
 
-  /rollup-plugin-uglify/6.0.4_rollup@3.20.2:
-    resolution: {integrity: sha512-ddgqkH02klveu34TF0JqygPwZnsbhHVI6t8+hGTcYHngPkQb5MIHI0XiztXIN/d6V9j+efwHAqEL7LspSxQXGw==}
-    peerDependencies:
-      rollup: '>=0.66.0 <2'
-    dependencies:
-      '@babel/code-frame': 7.21.4
-      jest-worker: 24.9.0
-      rollup: 3.20.2
-      serialize-javascript: 2.1.2
-      uglify-js: 3.17.4
-    dev: true
-
   /rollup/2.79.1:
     resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==}
     engines: {node: '>=10.0.0'}
@@ -4535,8 +4541,10 @@ packages:
       lru-cache: 6.0.0
     dev: true
 
-  /serialize-javascript/2.1.2:
-    resolution: {integrity: sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==}
+  /serialize-javascript/6.0.1:
+    resolution: {integrity: sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==}
+    dependencies:
+      randombytes: 2.1.0
     dev: true
 
   /set-blocking/2.0.0:
@@ -4596,10 +4604,21 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /smob/1.4.1:
+    resolution: {integrity: sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==}
+    dev: true
+
   /source-map-js/1.0.2:
     resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
     engines: {node: '>=0.10.0'}
 
+  /source-map-support/0.5.21:
+    resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==}
+    dependencies:
+      buffer-from: 1.1.2
+      source-map: 0.6.1
+    dev: true
+
   /source-map/0.6.1:
     resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
     engines: {node: '>=0.10.0'}
@@ -4660,13 +4679,6 @@ packages:
       has-flag: 3.0.0
     dev: true
 
-  /supports-color/6.1.0:
-    resolution: {integrity: sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==}
-    engines: {node: '>=6'}
-    dependencies:
-      has-flag: 3.0.0
-    dev: true
-
   /supports-color/7.2.0:
     resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
     engines: {node: '>=8'}
@@ -4696,6 +4708,17 @@ packages:
     dev: false
     optional: true
 
+  /terser/5.22.0:
+    resolution: {integrity: sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw==}
+    engines: {node: '>=10'}
+    hasBin: true
+    dependencies:
+      '@jridgewell/source-map': 0.3.5
+      acorn: 8.8.2
+      commander: 2.20.3
+      source-map-support: 0.5.21
+    dev: true
+
   /text-table/0.2.0:
     resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
     dev: true
@@ -4725,6 +4748,10 @@ packages:
       is-number: 7.0.0
     dev: true
 
+  /toggle-selection/1.0.6:
+    resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==}
+    dev: false
+
   /tough-cookie/4.1.2:
     resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==}
     engines: {node: '>=6'}
@@ -4802,12 +4829,6 @@ packages:
     hasBin: true
     dev: true
 
-  /uglify-js/3.17.4:
-    resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==}
-    engines: {node: '>=0.8.0'}
-    hasBin: true
-    dev: true
-
   /unicode-canonical-property-names-ecmascript/2.0.0:
     resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==}
     engines: {node: '>=4'}