aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2019-09-21 00:50:32 -0400
committerbobzel <zzzman@gmail.com>2019-09-21 00:50:32 -0400
commitfbc3e35a52aee959ce3621f3bc58ffb2e869904d (patch)
tree48a89826cba23e47f183c36bae88f78f4f77ea9f
parent75cf84dd29e7b397e829a137a7c9845134d05984 (diff)
fixed searching with pdf.
-rw-r--r--src/client/views/nodes/PDFBox.tsx93
-rw-r--r--src/client/views/pdf/PDFViewer.tsx71
-rw-r--r--src/client/views/pdf/Page.scss5
3 files changed, 90 insertions, 79 deletions
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index ffec9f29b..764051d62 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -4,12 +4,13 @@ import { observer } from "mobx-react";
import * as Pdfjs from "pdfjs-dist";
import "pdfjs-dist/web/pdf_viewer.css";
import 'react-image-lightbox/style.css';
-import { Doc, WidthSym, Opt } from "../../../new_fields/Doc";
+import { Doc, Opt, WidthSym } from "../../../new_fields/Doc";
import { makeInterface } from "../../../new_fields/Schema";
-import { ScriptField, ComputedField } from '../../../new_fields/ScriptField';
-import { BoolCast, Cast, NumCast } from "../../../new_fields/Types";
+import { ComputedField, ScriptField } from '../../../new_fields/ScriptField';
+import { Cast, NumCast } from "../../../new_fields/Types";
import { PdfField } from "../../../new_fields/URLField";
import { KeyCodes } from '../../northstar/utils/KeyCodes';
+import { panZoomSchema } from '../collections/collectionFreeForm/CollectionFreeFormView';
import { DocComponent } from "../DocComponent";
import { InkingControl } from "../InkingControl";
import { PDFViewer } from "../pdf/PDFViewer";
@@ -18,24 +19,13 @@ import { FieldView, FieldViewProps } from './FieldView';
import { pageSchema } from "./ImageBox";
import "./PDFBox.scss";
import React = require("react");
-import { Scripting } from '../../util/Scripting';
-type PdfDocument = makeInterface<[typeof documentSchema, typeof pageSchema]>;
-const PdfDocument = makeInterface(documentSchema, pageSchema);
-export const handleBackspace = (e: React.KeyboardEvent) => { if (e.keyCode === KeyCodes.BACKSPACE) e.stopPropagation(); };
+type PdfDocument = makeInterface<[typeof documentSchema, typeof panZoomSchema, typeof pageSchema]>;
+const PdfDocument = makeInterface(documentSchema, panZoomSchema, pageSchema);
@observer
export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocument) {
public static LayoutString() { return FieldView.LayoutString(PDFBox); }
-
- @observable private _flyout: boolean = false;
- @observable private _alt = false;
- @observable private _pdf: Opt<Pdfjs.PDFDocumentProxy>;
-
- @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
-
- @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplate ? this.props.DataDoc : Doc.GetProto(this.props.Document); }
-
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
private _reactionDisposer?: IReactionDisposer;
private _keyValue: string = "";
@@ -45,19 +35,26 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
private _valueRef: React.RefObject<HTMLInputElement> = React.createRef();
private _scriptRef: React.RefObject<HTMLInputElement> = React.createRef();
+ @observable private _flyout: boolean = false;
+ @observable private _alt = false;
+ @observable private _pdf: Opt<Pdfjs.PDFDocumentProxy>;
+
+ @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
+
+ @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplate ? this.props.DataDoc : Doc.GetProto(this.props.Document); }
+
componentDidMount() {
this.props.setPdfBox && this.props.setPdfBox(this);
- this.props.Document.pdfDoc = this.dataDoc;
- this.props.Document.curPage = ComputedField.MakeFunction("Math.floor(Number(this.panY) / Number(this.pdfDoc.nativeHeight) + 1)");
+ this.props.Document.curPage = ComputedField.MakeFunction("Math.floor(Number(this.panY) / Number(this.nativeHeight) + 1)");
const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
if (pdfUrl instanceof PdfField) {
Pdfjs.getDocument(pdfUrl.url.pathname).promise.then(pdf => runInAction(() => this._pdf = pdf));
}
this._reactionDisposer = reaction(
- () => this.props.Document.panY,
- () => this._mainCont.current && this._mainCont.current.scrollTo({ top: NumCast(this.Document.panY), behavior: "auto" })
+ () => this.Document.panY,
+ () => this._mainCont.current && this._mainCont.current.scrollTo({ top: this.Document.panY || 0, behavior: "auto" })
);
}
@@ -66,22 +63,22 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
}
public GetPage() {
- return Math.floor(NumCast(this.props.Document.panY) / NumCast(this.dataDoc.nativeHeight)) + 1;
+ return Math.floor((this.Document.panY || 0) / (this.Document.nativeHeight || 0)) + 1;
}
@action
public BackPage() {
- let cp = Math.ceil(NumCast(this.props.Document.panY) / NumCast(this.dataDoc.nativeHeight)) + 1;
+ let cp = Math.ceil((this.Document.panY || 0) / (this.Document.nativeHeight || 0)) + 1;
cp = cp - 1;
if (cp > 0) {
- this.props.Document.panY = (cp - 1) * NumCast(this.dataDoc.nativeHeight);
+ this.Document.panY = (cp - 1) * (this.Document.nativeHeight || 0);
}
}
@action
- public GotoPage(p: number) {
+ public GotoPage = (p: number) => {
if (p > 0 && p <= NumCast(this.dataDoc.numPages)) {
- this.props.Document.panY = (p - 1) * NumCast(this.dataDoc.nativeHeight);
+ this.Document.panY = (p - 1) * (this.Document.nativeHeight || 0);
}
}
@@ -89,20 +86,19 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
public ForwardPage() {
let cp = this.GetPage() + 1;
if (cp <= NumCast(this.dataDoc.numPages)) {
- this.props.Document.panY = (cp - 1) * NumCast(this.dataDoc.nativeHeight);
+ this.Document.panY = (cp - 1) * (this.Document.nativeHeight || 0);
}
}
@action
setPanY = (y: number) => {
- this.props.ContainingCollectionDoc && (this.props.ContainingCollectionDoc.panY = y);
+ this.Document.panY = y;
}
@action
private applyFilter = () => {
- let scriptText = this._scriptValue.length > 0 ? this._scriptValue :
- this._keyValue.length > 0 && this._valueValue.length > 0 ?
- `this.${this._keyValue} === ${this._valueValue}` : "true";
+ let scriptText = this._scriptValue ? this._scriptValue :
+ this._keyValue && this._valueValue ? `this.${this._keyValue} === ${this._valueValue}` : "true";
this.props.Document.filterScript = ScriptField.MakeFunction(scriptText);
}
@@ -111,8 +107,7 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
}
private resetFilters = () => {
- this._keyValue = this._valueValue = "";
- this._scriptValue = "";
+ this._keyValue = this._valueValue = this._scriptValue = "";
this._keyRef.current && (this._keyRef.current.value = "");
this._valueRef.current && (this._valueRef.current.value = "");
this._scriptRef.current && (this._scriptRef.current.value = "");
@@ -126,7 +121,7 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
return !this.props.active() ? (null) :
(<div className="pdfBox-settingsCont" onPointerDown={(e) => e.stopPropagation()}>
<button className="pdfBox-settingsButton" onClick={action(() => this._flyout = !this._flyout)} title="Open Annotation Settings"
- style={{ marginTop: `${this.props.ContainingCollectionDoc ? NumCast(this.props.ContainingCollectionDoc.panY) : 0}px` }}>
+ style={{ marginTop: `${this.Document.panY || 0}px` }}>
<div className="pdfBox-settingsButton-arrow"
style={{
borderTop: `25px solid ${this._flyout ? "#121721" : "transparent"}`,
@@ -143,13 +138,13 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
Annotation View Settings
</div>
<div className="pdfBox-settingsFlyout-kvpInput">
- <input placeholder="Key" className="pdfBox-settingsFlyout-input" onKeyDown={handleBackspace} onChange={this.newKeyChange}
+ <input placeholder="Key" className="pdfBox-settingsFlyout-input" onChange={this.newKeyChange}
style={{ gridColumn: 1 }} ref={this._keyRef} />
- <input placeholder="Value" className="pdfBox-settingsFlyout-input" onKeyDown={handleBackspace} onChange={this.newValueChange}
+ <input placeholder="Value" className="pdfBox-settingsFlyout-input" onChange={this.newValueChange}
style={{ gridColumn: 3 }} ref={this._valueRef} />
</div>
<div className="pdfBox-settingsFlyout-kvpInput">
- <input placeholder="Custom Script" onChange={this.newScriptChange} onKeyDown={handleBackspace} style={{ gridColumn: "1 / 4" }} ref={this._scriptRef} />
+ <input placeholder="Custom Script" onChange={this.newScriptChange} style={{ gridColumn: "1 / 4" }} ref={this._scriptRef} />
</div>
<div className="pdfBox-settingsFlyout-kvpInput">
<button style={{ gridColumn: 1 }} onClick={this.resetFilters}>
@@ -167,20 +162,20 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
loaded = (nw: number, nh: number, np: number) => {
this.dataDoc.numPages = np;
- if (!this.dataDoc.nativeWidth || !this.dataDoc.nativeHeight || !this.dataDoc.scrollHeight) {
- let oldaspect = NumCast(this.dataDoc.nativeHeight) / NumCast(this.dataDoc.nativeWidth, 1);
- this.dataDoc.nativeWidth = nw;
- this.dataDoc.nativeHeight = this.dataDoc.nativeHeight ? nw * oldaspect : nh;
- this.dataDoc.height = this.dataDoc[WidthSym]() * (nh / nw);
- this.dataDoc.scrollHeight = np * this.dataDoc.nativeHeight;
+ if (!this.Document.nativeWidth || !this.Document.nativeHeight || !this.Document.scrollHeight) {
+ let oldaspect = (this.Document.nativeHeight || 0) / (this.Document.nativeWidth || 1);
+ this.Document.nativeWidth = nw;
+ this.Document.nativeHeight = this.Document.nativeHeight ? nw * oldaspect : nh;
+ this.Document.height = this.Document[WidthSym]() * (nh / nw);
+ this.Document.scrollHeight = np * this.Document.nativeHeight;
}
}
@action
onScroll = (e: React.UIEvent<HTMLDivElement>) => {
if (e.currentTarget && this.props.ContainingCollectionDoc) {
- this.props.ContainingCollectionDoc.panTransformType = "None";
- this.props.ContainingCollectionDoc.panY = e.currentTarget.scrollTop;
+ this.props.Document.panTransformType = "None";
+ this.Document.panY = e.currentTarget.scrollTop;
}
}
@@ -192,12 +187,12 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
<div>{`pdf, ${this.dataDoc[this.props.fieldKey]}, not found`}</div> :
<div className={classname}
onScroll={this.onScroll}
- style={{ marginTop: `${this.props.ContainingCollectionDoc ? NumCast(this.props.ContainingCollectionDoc.panY) : 0}px` }}
+ style={{ marginTop: `${(this.Document.panY || 0)}px` }}
ref={this._mainCont}>
- do<div className="pdfBox-scrollHack" style={{ height: NumCast(this.props.Document.scrollHeight) + (NumCast(this.props.Document.nativeHeight) - NumCast(this.props.Document.nativeHeight) / NumCast(this.props.Document.scale, 1)), width: "100%" }} />
- <PDFViewer pdf={this._pdf} url={pdfUrl.url.pathname} active={this.props.active} scrollTo={this.scrollTo} loaded={this.loaded} panY={NumCast(this.props.Document.panY)}
- Document={this.props.Document} DataDoc={this.props.DataDoc}
- addDocTab={this.props.addDocTab} setPanY={this.setPanY}
+ <div className="pdfBox-scrollHack" style={{ height: NumCast(this.props.Document.scrollHeight) + ((this.Document.nativeHeight || 0) - (this.Document.nativeHeight || 0) / (this.Document.scale || 1)) }} />
+ <PDFViewer pdf={this._pdf} url={pdfUrl.url.pathname} active={this.props.active} scrollTo={this.scrollTo} loaded={this.loaded} panY={this.Document.panY || 0}
+ Document={this.props.Document} DataDoc={this.dataDoc}
+ addDocTab={this.props.addDocTab} setPanY={this.setPanY} GoToPage={this.GotoPage}
pinToPres={this.props.pinToPres} addDocument={this.props.addDocument}
fieldKey={this.props.fieldKey} fieldExtensionDoc={this.extensionDoc} />
{this.settingsPanel()}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 4afed0b95..c94b4e3a4 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -1,5 +1,5 @@
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, computed, IReactionDisposer, observable, reaction, runInAction } from "mobx";
+import { action, computed, IReactionDisposer, observable, reaction, runInAction, trace } from "mobx";
import { observer } from "mobx-react";
import * as Pdfjs from "pdfjs-dist";
import "pdfjs-dist/web/pdf_viewer.css";
@@ -19,6 +19,7 @@ import Annotation from "./Annotation";
import Page from "./Page";
import "./PDFViewer.scss";
import React = require("react");
+import requestPromise = require("request-promise");
const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer");
export const scale = 2;
@@ -35,6 +36,7 @@ interface IViewerProps {
scrollTo: (y: number) => void;
active: () => boolean;
setPanY?: (n: number) => void;
+ GoToPage?: (n: number) => void;
addDocTab: (document: Doc, dataDoc: Doc | undefined, where: string) => boolean;
pinToPres: (document: Doc) => void;
addDocument?: (doc: Doc, allowDuplicates?: boolean) => boolean;
@@ -61,7 +63,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
private _filterReactionDisposer?: IReactionDisposer;
private _viewer: React.RefObject<HTMLDivElement> = React.createRef();
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
- private _pdfViewer: any;
+ public _pdfViewer: any;
private _pdfFindController: any;
private _searchString: string = "";
private _selectionText: string = "";
@@ -363,7 +365,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
@action
search = (searchString: string) => {
if (this._pdfViewer._pageViewsReady) {
- this._pdfFindController.executeCommand('find', {
+ this._pdfFindController.executeCommand('findagain', {
caseSensitive: false,
findPrevious: undefined,
highlightAll: true,
@@ -372,13 +374,15 @@ export class PDFViewer extends React.Component<IViewerProps> {
});
}
else if (this._mainCont.current) {
- let executeFind = () => this._pdfFindController.executeCommand('find', {
- caseSensitive: false,
- findPrevious: undefined,
- highlightAll: true,
- phraseSearch: true,
- query: searchString
- });
+ let executeFind = () => {
+ this._pdfFindController.executeCommand('find', {
+ caseSensitive: false,
+ findPrevious: undefined,
+ highlightAll: true,
+ phraseSearch: true,
+ query: searchString
+ });
+ }
this._mainCont.current.addEventListener("pagesloaded", executeFind);
this._mainCont.current.addEventListener("pagerendered", executeFind);
}
@@ -391,14 +395,14 @@ export class PDFViewer extends React.Component<IViewerProps> {
this._searching = !this._searching;
if (this._searching) {
- if (!this._pdfFindController && this._mainCont.current && this._viewer.current) {
- let simpleLinkService = new SimpleLinkService();
+ if (!this._pdfFindController && this._mainCont.current && this._viewer.current && !this._pdfViewer) {
+ let simpleLinkService = new SimpleLinkService(this);
this._pdfViewer = new PDFJSViewer.PDFViewer({
container: this._mainCont.current,
viewer: this._viewer.current,
linkService: simpleLinkService
- });
- simpleLinkService.setPdf(this.props.pdf);
+ })
+ simpleLinkService.setPDFJSview(this._pdfViewer);
this._mainCont.current.addEventListener("pagesinit", () => this._pdfViewer.currentScaleValue = 1);
this._mainCont.current.addEventListener("pagerendered", () => console.log("rendered"));
this._pdfViewer.setDocument(this.props.pdf);
@@ -406,21 +410,16 @@ export class PDFViewer extends React.Component<IViewerProps> {
this._pdfViewer.findController = this._pdfFindController;
}
}
- else {
- this._pdfFindController = null;
- if (this._viewer.current) {
- let cns = this._viewer.current.childNodes;
- for (let i = cns.length - 1; i >= 0; i--) {
- cns.item(i).remove();
- }
- }
- }
+ }
+ @computed get visibleElementWrapper() {
+ trace();
+ return this._visibleElements;
}
render() {
return (<div className="pdfViewer-viewer" ref={this._mainCont} >
<div className="pdfViewer-visibleElements" style={this._searching ? { position: "absolute", top: 0 } : {}}>
- {this._visibleElements}
+ {this.visibleElementWrapper}
</div>
<div className="pdfViewer-text" ref={this._viewer} />
<div className="pdfViewer-annotationLayer" style={{ height: NumCast(this.props.Document.nativeHeight) }} ref={this._annotationLayer}>
@@ -458,9 +457,13 @@ export class PDFViewer extends React.Component<IViewerProps> {
export enum AnnotationTypes { Region }
class SimpleLinkService {
- externalLinkTarget: any = null;
- externalLinkRel: any = null;
- pdf: any = null;
+ _viewer: PDFViewer;
+ _pdfjsView: any;
+
+ constructor(viewer: PDFViewer) {
+ this._viewer = viewer;
+ }
+ setPDFJSview(v: any) { this._pdfjsView = v; }
navigateTo() { }
@@ -470,15 +473,23 @@ class SimpleLinkService {
setHash() { }
+ isPageVisible(page: number) { return true; }
+
executeNamedAction() { }
cachePageRef() { }
- get pagesCount() { return this.pdf ? this.pdf.numPages : 0; }
+ get pagesCount() { return this._viewer._pdfViewer.pagesCount; }
- get page() { return 0; }
+ get page() { return NumCast(this._viewer.props.Document.curPage); }
+ set page(p: number) {
+ this._pdfjsView._ensurePdfPageLoaded(this._pdfjsView._pages[p - 1]).then(() => {
+ this._pdfjsView.renderingQueue.renderView(this._pdfjsView._pages[p - 1]);
+ if (this._viewer.props.GoToPage)
+ this._viewer.props.GoToPage(p);
+ });
+ }
- setPdf(pdf: any) { this.pdf = pdf; }
get rotation() { return 0; }
set rotation(value: any) { }
diff --git a/src/client/views/pdf/Page.scss b/src/client/views/pdf/Page.scss
index af1628a6f..d8034b4b4 100644
--- a/src/client/views/pdf/Page.scss
+++ b/src/client/views/pdf/Page.scss
@@ -1,4 +1,9 @@
+.pdfViewer-text {
+ .page {
+ position: relative;
+ }
+}
.pdfPage-cont {
position: relative;