diff options
Diffstat (limited to 'src/client/views/pdf/PDFViewer.tsx')
-rw-r--r-- | src/client/views/pdf/PDFViewer.tsx | 59 |
1 files changed, 29 insertions, 30 deletions
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index 83b3dffe5..fc2567fbc 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -1,9 +1,10 @@ import { action, computed, IReactionDisposer, makeObservable, observable, ObservableMap, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as Pdfjs from 'pdfjs-dist'; +import { GlobalWorkerOptions } from 'pdfjs-dist/build/pdf.mjs'; import * as PDFJSViewer from 'pdfjs-dist/web/pdf_viewer.mjs'; -import 'pdfjs-dist/webpack.mjs'; // sets the PDF workerSrc import * as React from 'react'; +import ReactLoading from 'react-loading'; import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, ClientUtils, returnAll, returnFalse, returnNone, returnZero, smoothScroll } from '../../../ClientUtils'; import { CreateLinkToActiveAudio, Doc, DocListCast, Opt } from '../../../fields/Doc'; import { DocData, Height } from '../../../fields/DocSymbols'; @@ -14,6 +15,7 @@ import { TraceMobx } from '../../../fields/util'; import { emptyFunction, numberRange, unimplementedFunction } from '../../../Utils'; import { DocUtils } from '../../documents/DocUtils'; import { SnappingManager } from '../../util/SnappingManager'; +import { Transform } from '../../util/Transform'; import { MarqueeOptionsMenu } from '../collections/collectionFreeForm'; import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView'; import { MarqueeAnnotator } from '../MarqueeAnnotator'; @@ -28,12 +30,13 @@ import { AnchorMenu } from './AnchorMenu'; import { Annotation } from './Annotation'; import { GPTPopup } from './GPTPopup/GPTPopup'; import './PDFViewer.scss'; -import ReactLoading from 'react-loading'; -import { Transform } from '../../util/Transform'; +import { DocumentViewProps } from '../nodes/DocumentContentsView'; +if (window?.Worker) GlobalWorkerOptions.workerSrc = 'files/node_modules/pdfjs-dist/build/pdf.worker.min.mjs'; // npm start/etc use copyfiles to copy the worker from the pdfjs-dist package to the public folder +export * from 'pdfjs-dist/build/pdf.mjs'; interface IViewerProps extends FieldViewProps { pdfBox: PDFBox; - Document: Doc; + Doc: Doc; dataDoc: Doc; layoutDoc: Doc; fieldKey: string; @@ -52,7 +55,7 @@ interface IViewerProps extends FieldViewProps { */ @observer export class PDFViewer extends ObservableReactComponent<IViewerProps> { - static _annotationStyle = addStyleSheet(); + static _annotationStyle = addStyleSheet().sheet; constructor(props: IViewerProps) { super(props); @@ -111,8 +114,8 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { () => this._props.layoutDoc._layout_autoHeight, layoutAutoHeight => { if (layoutAutoHeight) { - this._props.layoutDoc._nativeHeight = NumCast(this._props.Document[this._props.fieldKey + '_nativeHeight']); - this._props.setHeight?.(NumCast(this._props.Document[this._props.fieldKey + '_nativeHeight']) * (this._props.NativeDimScaling?.() || 1)); + this._props.layoutDoc._nativeHeight = NumCast(this._props.Doc[this._props.fieldKey + '_nativeHeight']); + this._props.setHeight?.(NumCast(this._props.Doc[this._props.fieldKey + '_nativeHeight']) * (this._props.NativeDimScaling?.() || 1)); } } ); @@ -123,7 +126,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { { fireImmediately: true } ); this._disposers.curPage = reaction( - () => Cast(this._props.Document._layout_curPage, 'number', null), + () => Cast(this._props.Doc._layout_curPage, 'number', null), page => page !== undefined && page !== this._pdfViewer?.currentPageNumber && this.gotoPage(page), { fireImmediately: true } ); @@ -131,7 +134,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { componentWillUnmount = () => { Object.values(this._disposers).forEach(disposer => disposer?.()); - document.removeEventListener('copy', this.copy); + document.removeEventListener('copy', this.copy, true); }; copy = (e: ClipboardEvent) => { @@ -143,6 +146,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { e.clipboardData.setData('dash/pdfAnchor', anchor[DocData][Id]); } e.preventDefault(); + e.stopPropagation(); } }; @@ -179,7 +183,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { scrollFocus = (doc: Doc, scrollTop: number, options: FocusViewOptions) => { const mainCont = this._mainCont.current; let focusSpeed: Opt<number>; - if (doc !== this._props.Document && mainCont) { + if (doc !== this._props.Doc && mainCont) { const windowHeight = this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); const scrollTo = ClientUtils.scrollIntoView(scrollTop, doc[Height](), NumCast(this._props.layoutDoc._layout_scrollTop), windowHeight, windowHeight * 0.1, this._scrollHeight); if (scrollTo !== undefined && scrollTo !== this._props.layoutDoc._layout_scrollTop) { @@ -214,11 +218,11 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { { fireImmediately: true } ); this._disposers.scroll = reaction( - () => Math.abs(NumCast(this._props.Document._layout_scrollTop)), + () => Math.abs(NumCast(this._props.Doc._layout_scrollTop)), pos => { if (!this._ignoreScroll) { this._showWaiting && this.setupPdfJsViewer(); - const viewTrans = quickScroll?.loc ?? StrCast(this._props.Document._viewTransition); + const viewTrans = quickScroll?.loc ?? StrCast(this._props.Doc._viewTransition); const durationMiliStr = viewTrans.match(/([0-9]*)ms/); const durationSecStr = viewTrans.match(/([0-9.]*)s/); const duration = durationMiliStr ? Number(durationMiliStr[1]) : durationSecStr ? Number(durationSecStr[1]) * 1000 : 0; @@ -259,16 +263,11 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { } return; } - document.removeEventListener('copy', this.copy); - document.addEventListener('copy', this.copy); + document.removeEventListener('copy', this.copy, true); + document.addEventListener('copy', this.copy, true); const eventBus = new PDFJSViewer.EventBus(); eventBus._on('pagesinit', this.pagesinit); - eventBus._on( - 'pagerendered', - action(() => { - this._showWaiting = false; - }) - ); + eventBus._on('pagerendered',action(() => (this._showWaiting = false))); // prettier-ignore const pdfLinkService = new PDFJSViewer.PDFLinkService({ eventBus }); const pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService, eventBus }); this._pdfViewer = new PDFJSViewer.PDFViewer({ @@ -369,9 +368,9 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { // if alt+left click, drag and annotate this._downX = e.clientX; this._downY = e.clientY; - if ((this._props.Document._freeform_scale || 1) !== 1) return; + if ((this._props.Doc._freeform_scale || 1) !== 1) return; if ((e.button !== 0 || e.altKey) && this._props.isContentActive()) { - this._setPreviewCursor?.(e.clientX, e.clientY, true, false, this._props.Document); + this._setPreviewCursor?.(e.clientX, e.clientY, true, false, this._props.Doc); } if (!e.altKey && e.button === 0 && this._props.isContentActive() && Doc.ActiveTool !== InkTool.Ink) { this._props.select(false); @@ -429,9 +428,9 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { }; addDrawingAnnotation = (drawing: Doc) => { - // drawing[DocData].x = this._props.pdfBox.ScreenToLocalBoxXf().TranslateX + // drawing.x = this._props.pdfBox.ScreenToLocalBoxXf().TranslateX // const scaleX = this._mainCont.current.offsetWidth / boundingRect.width; - drawing.y = NumCast(drawing.y) + NumCast(this._props.Document.layout_scrollTop); + drawing.y = NumCast(drawing.y) + NumCast(this._props.Doc.layout_scrollTop); this._props.addDocument?.(drawing); }; @@ -476,7 +475,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { onClick = (e: React.MouseEvent) => { this._scrollStopper?.(); if (this._setPreviewCursor && e.button === 0 && Math.abs(e.clientX - this._downX) < ClientUtils.DRAG_THRESHOLD && Math.abs(e.clientY - this._downY) < ClientUtils.DRAG_THRESHOLD) { - this._setPreviewCursor(e.clientX, e.clientY, false, false, this._props.Document); + this._setPreviewCursor(e.clientX, e.clientY, false, false, this._props.Doc); } // e.stopPropagation(); // bcz: not sure why this was here. We need to allow the DocumentView to get clicks to process doubleClicks }; @@ -504,7 +503,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { @computed get annotationLayer() { const inlineAnnos = this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).filter(anno => !anno.hidden); return ( - <div className="pdfViewerDash-annotationLayer" style={{ height: Doc.NativeHeight(this._props.Document), transform: `scale(${NumCast(this._props.layoutDoc._freeform_scale, 1)})` }} ref={this._annotationLayer}> + <div className="pdfViewerDash-annotationLayer" style={{ height: Doc.NativeHeight(this._props.Doc), transform: `scale(${NumCast(this._props.layoutDoc._freeform_scale, 1)})` }} ref={this._annotationLayer}> {inlineAnnos.map(anno => ( <Annotation {...this._props} fieldKey={this._props.fieldKey + '_annotations'} pointerEvents={this.pointerEvents} containerDataDoc={this._props.dataDoc} annoDoc={anno} key={`${anno[Id]}-annotation`} /> ))} @@ -519,7 +518,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { panelHeight = () => this._props.PanelHeight() / (this._props.NativeDimScaling?.() || 1); transparentFilter = () => [...this._props.childFilters(), ClientUtils.TransparentBackgroundFilter]; opaqueFilter = () => [...this._props.childFilters(), ClientUtils.noDragDocsFilter, ...(SnappingManager.CanEmbed && this._props.isContentActive() ? [] : [ClientUtils.OpaqueBackgroundFilter])]; - childStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => { + childStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps & DocumentViewProps>, property: string) => { if (doc instanceof Doc && property === StyleProp.PointerEvents) { if (this.inlineTextAnnotations.includes(doc) || this._props.isContentActive() === false) return 'none'; const isInk = doc.layout_isSvg && !props?.LayoutTemplateString; @@ -595,7 +594,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { onClick={this.onClick} style={{ overflowX: NumCast(this._props.layoutDoc._freeform_scale, 1) !== 1 ? 'scroll' : undefined, - height: !this._props.Document._layout_fitWidth && window.screen.width > 600 ? Doc.NativeHeight(this._props.Document) : `100%`, + height: !this._props.Doc._layout_fitWidth && window.screen.width > 600 ? Doc.NativeHeight(this._props.Doc) : `100%`, }}> {this.pdfViewerDiv} {this.annotationLayer} @@ -604,12 +603,12 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { {!this._mainCont.current || !this._annotationLayer.current || !this.props.pdfBox.DocumentView ? null : ( <MarqueeAnnotator ref={this._marqueeref} - Document={this._props.Document} + Document={this._props.Doc} getPageFromScroll={this.getPageFromScroll} anchorMenuClick={this._props.anchorMenuClick} scrollTop={0} annotationLayerScaling={() => Pdfjs.PixelsPerInch.PDF_TO_CSS_UNITS} - annotationLayerScrollTop={NumCast(this._props.Document._layout_scrollTop)} + annotationLayerScrollTop={NumCast(this._props.Doc._layout_scrollTop)} addDocument={this.addDocumentWrapper} docView={this.props.pdfBox.DocumentView} screenTransform={this.screenToMarqueeXf} |