diff options
Diffstat (limited to 'src/client/views/nodes/PDFBox.tsx')
-rw-r--r-- | src/client/views/nodes/PDFBox.tsx | 143 |
1 files changed, 91 insertions, 52 deletions
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx index 1274220b6..b03b90418 100644 --- a/src/client/views/nodes/PDFBox.tsx +++ b/src/client/views/nodes/PDFBox.tsx @@ -1,9 +1,12 @@ +/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/control-has-associated-label */ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, IReactionDisposer, makeObservable, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; import * as Pdfjs from 'pdfjs-dist'; import 'pdfjs-dist/web/pdf_viewer.css'; import * as React from 'react'; +import { ClientUtils, returnFalse, setupMoveUpEvents } from '../../../ClientUtils'; import { Doc, DocListCast, Opt } from '../../../fields/Doc'; import { DocData } from '../../../fields/DocSymbols'; import { Id } from '../../../fields/FieldSymbols'; @@ -12,7 +15,7 @@ import { ComputedField } from '../../../fields/ScriptField'; import { Cast, FieldValue, ImageCast, NumCast, StrCast } from '../../../fields/Types'; import { ImageField, PdfField } from '../../../fields/URLField'; import { TraceMobx } from '../../../fields/util'; -import { emptyFunction, returnFalse, setupMoveUpEvents, Utils } from '../../../Utils'; +import { emptyFunction } from '../../../Utils'; import { Docs, DocUtils } from '../../documents/Documents'; import { CollectionViewType, DocumentType } from '../../documents/DocumentTypes'; import { DocumentManager } from '../../util/DocumentManager'; @@ -23,16 +26,17 @@ import { CollectionFreeFormView } from '../collections/collectionFreeForm'; import { CollectionStackingView } from '../collections/CollectionStackingView'; import { ContextMenu } from '../ContextMenu'; import { ContextMenuProps } from '../ContextMenuItem'; -import { ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent'; +import { PinProps, ViewBoxAnnotatableComponent, ViewBoxInterface } from '../DocComponent'; import { Colors } from '../global/globalEnums'; -import { CreateImage } from '../nodes/WebBoxRenderer'; +// eslint-disable-next-line import/extensions +import { CreateImage } from './WebBoxRenderer'; import { PDFViewer } from '../pdf/PDFViewer'; import { SidebarAnnos } from '../SidebarAnnos'; import { DocumentView, OpenWhere } from './DocumentView'; -import { FocusViewOptions, FieldView, FieldViewProps } from './FieldView'; +import { FieldView, FieldViewProps, FocusViewOptions } from './FieldView'; import { ImageBox } from './ImageBox'; import './PDFBox.scss'; -import { PinProps, PresBox } from './trails'; +import { PresBox } from './trails'; @observer export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implements ViewBoxInterface { @@ -66,8 +70,16 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem const nh = Doc.NativeHeight(this.Document, this.dataDoc) || 1200; !this.Document._layout_fitWidth && (this.Document._height = NumCast(this.Document._width) * (nh / nw)); if (this.pdfUrl) { - if (PDFBox.pdfcache.get(this.pdfUrl.url.href)) runInAction(() => (this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href))); - else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then(action((pdf: any) => (this._pdf = pdf))); + if (PDFBox.pdfcache.get(this.pdfUrl.url.href)) + runInAction(() => { + this._pdf = PDFBox.pdfcache.get(this.pdfUrl!.url.href); + }); + else if (PDFBox.pdfpromise.get(this.pdfUrl.url.href)) + PDFBox.pdfpromise.get(this.pdfUrl.url.href)?.then( + action((pdf: any) => { + this._pdf = pdf; + }) + ); } } @@ -85,7 +97,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem if (oldDiv instanceof HTMLCanvasElement) { const canvas = oldDiv; const img = document.createElement('img'); // create a Image Element - img.src = canvas.toDataURL(); //image sourcez + img.src = canvas.toDataURL(); // image sourcez img.style.width = canvas.style.width; img.style.height = canvas.style.height; const newCan = newDiv as HTMLCanvasElement; @@ -96,7 +108,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem }; crop = (region: Doc | undefined, addCrop?: boolean) => { - if (!region) return; + if (!region) return undefined; const cropping = Doc.MakeCopy(region, true); const regionData = region[DocData]; regionData.lockedPosition = true; @@ -111,11 +123,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem this.replaceCanvases(docViewContent, newDiv); const htmlString = this._pdfViewer?._mainCont.current && new XMLSerializer().serializeToString(newDiv); - const anchx = NumCast(cropping.x); - const anchy = NumCast(cropping.y); + // const anchx = NumCast(cropping.x); + // const anchy = NumCast(cropping.y); const anchw = NumCast(cropping._width) * (this._props.NativeDimScaling?.() || 1); const anchh = NumCast(cropping._height) * (this._props.NativeDimScaling?.() || 1); - const viewScale = 1; + // const viewScale = 1; cropping.title = 'crop: ' + this.Document.title; cropping.x = NumCast(this.Document.x) + NumCast(this.layoutDoc._width); cropping.y = NumCast(this.Document.y); @@ -128,9 +140,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem croppingProto.proto = Cast(this.Document.proto, Doc, null)?.proto; // set proto of cropping's data doc to be IMAGE_PROTO croppingProto.type = DocumentType.IMG; croppingProto.layout = ImageBox.LayoutString('data'); - croppingProto.data = new ImageField(Utils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png')); - croppingProto['data_nativeWidth'] = anchw; - croppingProto['data_nativeHeight'] = anchh; + croppingProto.data = new ImageField(ClientUtils.CorsProxy('http://www.cs.brown.edu/~bcz/noImage.png')); + croppingProto.data_nativeWidth = anchw; + croppingProto.data_nativeHeight = anchh; if (addCrop) { DocUtils.MakeLink(region, cropping, { link_relationship: 'cropped image' }); } @@ -146,8 +158,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem (NumCast(region.x) * this._props.PanelWidth()) / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']), 4 ) - .then((data_url: any) => { - Utils.convertDataUri(data_url, region[Id]).then(returnedfilename => + .then((dataUrl: any) => { + ClientUtils.convertDataUri(dataUrl, region[Id]).then(returnedfilename => setTimeout( action(() => { croppingProto.data = new ImageField(returnedfilename); @@ -156,7 +168,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem ) ); }) - .catch(function (error: any) { + .catch((error: any) => { console.error('oops, something went wrong!', error); }); @@ -182,8 +194,8 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem (iconFile: string, nativeWidth: number, nativeHeight: number) => { setTimeout(() => { this.dataDoc.icon = new ImageField(iconFile); - this.dataDoc['icon_nativeWidth'] = nativeWidth; - this.dataDoc['icon_nativeHeight'] = nativeHeight; + this.dataDoc.icon_nativeWidth = nativeWidth; + this.dataDoc.icon_nativeHeight = nativeHeight; }, 500); } ); @@ -214,12 +226,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem ); } - sidebarAddDocTab = (doc: Doc, where: OpenWhere) => { - if (DocListCast(this.Document[this._props.fieldKey + '_sidebar']).includes(doc) && !this.SidebarShown) { + sidebarAddDocTab = (docIn: Doc | Doc[], where: OpenWhere) => { + const docs = docIn instanceof Doc ? [docIn] : docIn; + if (docs.some(doc => DocListCast(this.Document[this._props.fieldKey + '_sidebar']).includes(doc)) && !this.SidebarShown) { this.toggleSidebar(false); return true; } - return this._props.addDocTab(doc, where); + return this._props.addDocTab(docs, where); }; focus = (anchor: Doc, options: FocusViewOptions) => { this._initialScrollTarget = anchor; @@ -231,18 +244,20 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem options.didMove = true; this.toggleSidebar(false); } - return new Promise<Opt<DocumentView>>(res => DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv))); + return new Promise<Opt<DocumentView>>(res => { + DocumentManager.Instance.AddViewRenderedCb(doc, dv => res(dv)); + }); }; getAnchor = (addAsAnnotation: boolean, pinProps?: PinProps) => { - let ele: Opt<HTMLDivElement> = undefined; + let ele: Opt<HTMLDivElement>; if (this._pdfViewer?.selectionContent()) { ele = document.createElement('div'); ele.append(this._pdfViewer.selectionContent()!); } const docAnchor = () => Docs.Create.ConfigDocument({ - title: StrCast(this.Document.title + '@' + NumCast(this.layoutDoc._layout_scrollTop)?.toFixed(0)), + title: StrCast(this.Document.title + '@' + (NumCast(this.layoutDoc._layout_scrollTop) ?? 0).toFixed(0)), annotationOn: this.Document, }); const visibleAnchor = this._pdfViewer?._getAnchor?.(this._pdfViewer.savedAnnotations(), true); @@ -285,7 +300,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem this.Document._layout_curPage = Math.min(NumCast(this.dataDoc[this._props.fieldKey + '_numPages']), (NumCast(this.Document._layout_curPage) || 1) + 1); return true; }; - public gotoPage = (p: number) => (this.Document._layout_curPage = p); + public gotoPage = (p: number) => { + this.Document._layout_curPage = p; + }; @undoBatch onKeyDown = action((e: KeyboardEvent) => { @@ -297,6 +314,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem case 'PageUp': processed = this.backPage(); break; + default: } if (processed) { e.stopImmediatePropagation(); @@ -312,7 +330,9 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem this._initialScrollTarget = undefined; } }; - searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => (this._searchString = e.currentTarget.value); + searchStringChanged = (e: React.ChangeEvent<HTMLInputElement>) => { + this._searchString = e.currentTarget.value; + }; // adding external documents; to sidebar key // if (doc.Geolocation) this.addDocument(doc, this.fieldkey+"_annotation") @@ -326,7 +346,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem setupMoveUpEvents( this, e, - (e, down, delta) => { + (moveEv, down, delta) => { const localDelta = this._props .ScreenToLocalTransform() .scale(this._props.NativeDimScaling?.() || 1) @@ -341,7 +361,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem } return false; }, - (e, movement, isClick) => !isClick && batch.end(), + (clickEv, movement, isClick) => !isClick && batch.end(), () => { onButton && this.toggleSidebar(); batch.end(); @@ -368,11 +388,11 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem settingsPanel() { const pageBtns = ( <> - <button className="pdfBox-backBtn" key="back" title="Page Back" onPointerDown={e => e.stopPropagation()} onClick={this.backPage}> - <FontAwesomeIcon style={{ color: 'white' }} icon={'arrow-left'} size="sm" /> + <button type="button" className="pdfBox-backBtn" key="back" title="Page Back" onPointerDown={e => e.stopPropagation()} onClick={this.backPage}> + <FontAwesomeIcon style={{ color: 'white' }} icon="arrow-left" size="sm" /> </button> - <button className="pdfBox-fwdBtn" key="fwd" title="Page Forward" onPointerDown={e => e.stopPropagation()} onClick={this.forwardPage}> - <FontAwesomeIcon style={{ color: 'white' }} icon={'arrow-right'} size="sm" /> + <button type="button" className="pdfBox-fwdBtn" key="fwd" title="Page Forward" onPointerDown={e => e.stopPropagation()} onClick={this.forwardPage}> + <FontAwesomeIcon style={{ color: 'white' }} icon="arrow-right" size="sm" /> </button> </> ); @@ -385,7 +405,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem onPointerDown={e => e.stopPropagation()} style={{ display: this._props.isContentActive() ? 'flex' : 'none' }}> <div className="pdfBox-overlayCont" onPointerDown={e => e.stopPropagation()} style={{ left: `${this._searching ? 0 : 100}%` }}> - <button className="pdfBox-overlayButton" title={searchTitle} /> + <button type="button" className="pdfBox-overlayButton" title={searchTitle} /> <input className="pdfBox-searchBar" placeholder="Search" @@ -396,17 +416,18 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem e.keyCode === KeyCodes.ENTER && this.search(this._searchString, e.shiftKey); }} /> - <button className="pdfBox-search" title="Search" onClick={e => this.search(this._searchString, e.shiftKey)}> + <button type="button" className="pdfBox-search" title="Search" onClick={e => this.search(this._searchString, e.shiftKey)}> <FontAwesomeIcon icon="search" size="sm" /> </button> - <button className="pdfBox-prevIcon" title="Previous Annotation" onClick={this.prevAnnotation}> - <FontAwesomeIcon icon={'arrow-up'} size="lg" /> + <button type="button" className="pdfBox-prevIcon" title="Previous Annotation" onClick={this.prevAnnotation}> + <FontAwesomeIcon icon="arrow-up" size="lg" /> </button> - <button className="pdfBox-nextIcon" title="Next Annotation" onClick={this.nextAnnotation}> - <FontAwesomeIcon icon={'arrow-down'} size="lg" /> + <button type="button" className="pdfBox-nextIcon" title="Next Annotation" onClick={this.nextAnnotation}> + <FontAwesomeIcon icon="arrow-down" size="lg" /> </button> </div> <button + type="button" className="pdfBox-overlayButton" title={searchTitle} onClick={action(() => { @@ -423,9 +444,13 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem <input value={curPage} style={{ width: `${curPage > 99 ? 4 : 3}ch`, pointerEvents: 'all' }} - onChange={e => (this.Document._layout_curPage = Number(e.currentTarget.value))} + onChange={e => { + this.Document._layout_curPage = Number(e.currentTarget.value); + }} onKeyDown={e => e.stopPropagation()} - onClick={action(() => (this._pageControls = !this._pageControls))} + onClick={action(() => { + this._pageControls = !this._pageControls; + })} /> {this._pageControls ? pageBtns : null} </div> @@ -440,18 +465,20 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem return PDFBox.sidebarResizerWidth + nativeDiff * (this._props.NativeDimScaling?.() || 1); }; @undoBatch - toggleSidebarType = () => (this.dataDoc[this.SidebarKey + '_type_collection'] = this.dataDoc[this.SidebarKey + '_type_collection'] === CollectionViewType.Freeform ? CollectionViewType.Stacking : CollectionViewType.Freeform); - specificContextMenu = (e: React.MouseEvent): void => { + toggleSidebarType = () => { + this.dataDoc[this.SidebarKey + '_type_collection'] = this.dataDoc[this.SidebarKey + '_type_collection'] === CollectionViewType.Freeform ? CollectionViewType.Stacking : CollectionViewType.Freeform; + }; + specificContextMenu = (): void => { const cm = ContextMenu.Instance; const options = cm.findByDescription('Options...'); const optionItems: ContextMenuProps[] = options && 'subitems' in options ? options.subitems : []; !Doc.noviceMode && optionItems.push({ description: 'Toggle Sidebar Type', event: this.toggleSidebarType, icon: 'expand-arrows-alt' }); !Doc.noviceMode && optionItems.push({ description: 'update icon', event: () => this.pdfUrl && this.updateIcon(), icon: 'expand-arrows-alt' }); - //optionItems.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" }); + // optionItems.push({ description: "Toggle Sidebar ", event: () => this.toggleSidebar(), icon: "expand-arrows-alt" }); !options && ContextMenu.Instance.addItem({ description: 'Options...', subitems: optionItems, icon: 'asterisk' }); const help = cm.findByDescription('Help...'); const helpItems: ContextMenuProps[] = help && 'subitems' in help ? help.subitems : []; - helpItems.push({ description: 'Copy path', event: () => this.pdfUrl && Utils.CopyText(Utils.prepend('') + this.pdfUrl.url.pathname), icon: 'expand-arrows-alt' }); + helpItems.push({ description: 'Copy path', event: () => this.pdfUrl && ClientUtils.CopyText(ClientUtils.prepend('') + this.pdfUrl.url.pathname), icon: 'expand-arrows-alt' }); !help && ContextMenu.Instance.addItem({ description: 'Help...', noexpand: true, subitems: helpItems, icon: 'asterisk' }); }; @@ -469,7 +496,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick; @observable _showSidebar = false; @computed get SidebarShown() { - return this._showSidebar || this.layoutDoc._show_sidebar ? true : false; + return !!(this._showSidebar || this.layoutDoc._show_sidebar); } @computed get sidebarHandle() { return ( @@ -483,7 +510,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem backgroundColor: this.SidebarShown ? Colors.MEDIUM_BLUE : Colors.BLACK, }} onPointerDown={e => this.sidebarBtnDown(e, true)}> - <FontAwesomeIcon style={{ color: Colors.WHITE }} icon={'comment-alt'} size="sm" /> + <FontAwesomeIcon style={{ color: Colors.WHITE }} icon="comment-alt" size="sm" /> </div> ); } @@ -514,6 +541,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem return ComponentTag === CollectionStackingView ? ( <SidebarAnnos ref={this._sidebarRef} + // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} Document={this.Document} layoutDoc={this.layoutDoc} @@ -529,6 +557,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem ) : ( <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this.DocumentView?.()!, false), true)}> <ComponentTag + // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} setContentViewBox={emptyFunction} // override setContentView to do nothing NativeWidth={this.sidebarNativeWidthFunc} @@ -539,7 +568,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem yPadding={0} viewField={this.SidebarKey} isAnnotationOverlay={false} - originTopLeft={true} + originTopLeft isAnyChildContentActive={this.isAnyChildContentActive} select={emptyFunction} whenChildContentsActiveChanged={this.whenChildContentsActiveChanged} @@ -548,7 +577,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem addDocument={this.sidebarAddDocument} ScreenToLocalTransform={this.sidebarScreenToLocal} renderDepth={this._props.renderDepth + 1} - noSidebar={true} + noSidebar fieldKey={this.SidebarKey} /> </div> @@ -582,6 +611,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem top: 0, }}> <PDFViewer + // eslint-disable-next-line react/jsx-props-no-spreading {...this._props} pdfBox={this} sidebarAddDoc={this.sidebarAddDocument} @@ -614,10 +644,19 @@ export class PDFBox extends ViewBoxAnnotatableComponent<FieldViewProps>() implem const pdfView = !this._pdf ? null : this.renderPdfView; const href = this.pdfUrl?.url.href; if (!pdfView && href) { - if (PDFBox.pdfcache.get(href)) setTimeout(action(() => (this._pdf = PDFBox.pdfcache.get(href)))); + if (PDFBox.pdfcache.get(href)) + setTimeout( + action(() => { + this._pdf = PDFBox.pdfcache.get(href); + }) + ); else { if (!PDFBox.pdfpromise.get(href)) PDFBox.pdfpromise.set(href, Pdfjs.getDocument(href).promise); - PDFBox.pdfpromise.get(href)?.then(action((pdf: any) => PDFBox.pdfcache.set(href, (this._pdf = pdf)))); + PDFBox.pdfpromise.get(href)?.then( + action((pdf: any) => { + PDFBox.pdfcache.set(href, (this._pdf = pdf)); + }) + ); } } return pdfView ?? this.renderTitleBox; |