aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/pdf/PDFViewer.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/pdf/PDFViewer.tsx')
-rw-r--r--src/client/views/pdf/PDFViewer.tsx109
1 files changed, 43 insertions, 66 deletions
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 28d7b0954..73aea9737 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -8,8 +8,7 @@ import { documentSchema } from "../../../fields/documentSchemas";
import { Id } from "../../../fields/FieldSymbols";
import { InkTool } from "../../../fields/InkField";
import { createSchema, makeInterface } from "../../../fields/Schema";
-import { ScriptField } from "../../../fields/ScriptField";
-import { Cast, NumCast, StrCast } from "../../../fields/Types";
+import { Cast, NumCast, StrCast, ScriptCast } from "../../../fields/Types";
import { PdfField } from "../../../fields/URLField";
import { TraceMobx } from "../../../fields/util";
import { addStyleSheet, addStyleSheetRule, clearStyleSheetRules, emptyFunction, OmitKeys, smoothScroll, Utils } from "../../../Utils";
@@ -66,12 +65,12 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
@observable private _pageSizes: { width: number, height: number }[] = [];
@observable private _savedAnnotations: Dictionary<number, HTMLDivElement[]> = new Dictionary<number, HTMLDivElement[]>();
@observable private _script: CompiledScript = CompileScript("return true") as CompiledScript;
- @observable private Index: number = -1;
@observable private _marqueeing: number[] | undefined;
@observable private _showWaiting = true;
@observable private _showCover = false;
@observable private _zoomed = 1;
@observable private _overlayAnnoInfo: Opt<Doc>;
+ @observable private Index: number = -1;
private _pdfViewer: any;
private _styleRule: any; // stylesheet rule for making hyperlinks clickable
@@ -89,7 +88,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
private _viewerIsSetup = false;
private _ignoreScroll = false;
private _initialScroll: Opt<number>;
- private _smoothScrolling = true;
+ private _forcedScroll = true;
@computed get allAnnotations() {
return DocUtils.FilterDocs(DocListCast(this.dataDoc[this.props.fieldKey + "-annotations"]), this.props.docFilters(), this.props.docRangeFilters(), undefined);
@@ -158,12 +157,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
copy = (e: ClipboardEvent) => {
if (this.active() && e.clipboardData) {
- //const annoDoc = this.makeAnnotationDocument("rgba(3,144,152,0.3)"); // copied text markup color (blueish)
- //if (annoDoc) {
e.clipboardData.setData("text/plain", this._selectionText);
- // e.clipboardData.setData("dash/pdfOrigin", this.props.Document[Id]);
- // e.clipboardData.setData("dash/pdfRegion", annoDoc[Id]);
- //}
e.preventDefault();
}
}
@@ -174,12 +168,13 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
this._pageSizes = Array<{ width: number, height: number }>(this.props.pdf.numPages);
await Promise.all(this._pageSizes.map<Pdfjs.PDFPromise<any>>((val, i) =>
this.props.pdf.getPage(i + 1).then(action((page: Pdfjs.PDFPageProxy) => {
+ const page0or180 = page.rotate === 0 || page.rotate === 180;
this._pageSizes.splice(i, 1, {
- width: (page.view[page.rotate === 0 || page.rotate === 180 ? 2 : 3] - page.view[page.rotate === 0 || page.rotate === 180 ? 0 : 1]),
- height: (page.view[page.rotate === 0 || page.rotate === 180 ? 3 : 2] - page.view[page.rotate === 0 || page.rotate === 180 ? 1 : 0])
+ width: (page.view[page0or180 ? 2 : 3] - page.view[page0or180 ? 0 : 1]),
+ height: (page.view[page0or180 ? 3 : 2] - page.view[page0or180 ? 1 : 0])
});
- i === this.props.pdf.numPages - 1 && this.props.loaded?.((page.view[page.rotate === 0 || page.rotate === 180 ? 2 : 3] - page.view[page.rotate === 0 || page.rotate === 180 ? 0 : 1]),
- (page.view[page.rotate === 0 || page.rotate === 180 ? 3 : 2] - page.view[page.rotate === 0 || page.rotate === 180 ? 1 : 0]), i);
+ i === this.props.pdf.numPages - 1 && this.props.loaded?.((page.view[page0or180 ? 2 : 3] - page.view[page0or180 ? 0 : 1]),
+ (page.view[page0or180 ? 3 : 2] - page.view[page0or180 ? 1 : 0]), i);
}))));
this.Document.scrollHeight = this._pageSizes.reduce((size, page) => size + page.height, 0) * 96 / 72;
}
@@ -207,13 +202,13 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
@action
setupPdfJsViewer = async () => {
if (this._viewerIsSetup) return;
- else this._viewerIsSetup = true;
+ this._viewerIsSetup = true;
this._showWaiting = true;
this.props.setPdfViewer(this);
await this.initialLoad();
this._disposers.filterScript = reaction(
- () => Cast(this.Document.filterScript, ScriptField),
+ () => ScriptCast(this.Document.filterScript),
action(scriptField => {
const oldScript = this._script.originalScript;
this._script = scriptField?.script.compiled ? scriptField.script : CompileScript("return true") as CompiledScript;
@@ -234,25 +229,23 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
document.removeEventListener("pagesinit", this.pagesinit);
var quickScroll: string | undefined = this._initialScroll ? this._initialScroll.toString() : "";
this._disposers.scroll = reaction(
- () => NumCast(this.Document._scrollTop),
+ () => Math.abs(NumCast(this.Document._scrollTop)),
(pos) => {
if (!this._ignoreScroll) {
(this._showCover || this._showWaiting) && this.setupPdfJsViewer();
const viewTrans = quickScroll ?? StrCast(this.Document._viewTransition);
- const delay = this._mainCont.current ? 0 : 250; // wait for mainCont and try again to scroll
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;
+ this._forcedScroll = true;
if (duration) {
- this._smoothScrolling = true;
setTimeout(() => {
- this._mainCont.current && smoothScroll(duration, this._mainCont.current, Math.abs(pos || 0));
- setTimeout(() => this._smoothScrolling = false, duration);
- }, delay);
+ this._mainCont.current && smoothScroll(duration, this._mainCont.current, pos);
+ setTimeout(() => this._forcedScroll = false, duration);
+ }, this._mainCont.current ? 0 : 250); // wait for mainCont and try again to scroll
} else {
- this._smoothScrolling = true;
- this._mainCont.current?.scrollTo({ top: Math.abs(pos || 0) });
- this._smoothScrolling = false;
+ this._mainCont.current?.scrollTo({ top: pos });
+ this._forcedScroll = false;
}
}
},
@@ -267,8 +260,10 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
createPdfViewer() {
if (!this._mainCont.current) { // bcz: I don't think this is ever triggered or needed
+ console.log("PDFViewer- I guess we got here");
if (this._retries < 5) {
this._retries++;
+ console.log("PDFViewer- retry num:" + this._retries);
setTimeout(() => this.createPdfViewer(), 1000);
}
return;
@@ -277,9 +272,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
document.addEventListener("copy", this.copy);
const eventBus = new PDFJSViewer.EventBus(true);
eventBus._on("pagesinit", this.pagesinit);
- eventBus._on("pagerendered", action(() => {
- this._showWaiting = false;
- }));
+ eventBus._on("pagerendered", action(() => this._showWaiting = false));
const pdfLinkService = new PDFJSViewer.PDFLinkService({ eventBus });
const pdfFindController = new PDFJSViewer.PDFFindController({ linkService: pdfLinkService, eventBus });
this._pdfViewer = new PDFJSViewer.PDFViewer({
@@ -324,8 +317,8 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
}
onScroll = (e: React.UIEvent<HTMLElement>) => {
- if (this._mainCont.current && !this._smoothScrolling) {
- this._ignoreScroll = true;
+ if (this._mainCont.current && !this._forcedScroll) {
+ this._ignoreScroll = true; // the pdf scrolled, so we need to tell the Doc to scroll but we don't want the doc to then try to set the PDF scroll pos (which would interfere with the smooth scroll animation)
if (!LinkDocPreview.LinkInfo) {
this.layoutDoc._scrollTop = this._mainCont.current.scrollTop;
}
@@ -343,32 +336,24 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
return index;
}
-
@action
search = (searchString: string, fwd: boolean, clear: boolean = false) => {
+ const findOpts = {
+ caseSensitive: false,
+ findPrevious: !fwd,
+ highlightAll: true,
+ phraseSearch: true,
+ query: searchString
+ };
if (clear) {
this._pdfViewer?.findController.executeCommand('reset', { query: "" });
} else if (!searchString) {
fwd ? this.nextAnnotation() : this.prevAnnotation();
} else if (this._pdfViewer?.pageViewsReady) {
- this._pdfViewer.findController.executeCommand('findagain', {
- caseSensitive: false,
- findPrevious: !fwd,
- highlightAll: true,
- phraseSearch: true,
- query: searchString
- });
+ this._pdfViewer.findController.executeCommand('findagain', findOpts);
}
else if (this._mainCont.current) {
- const executeFind = () => {
- this._pdfViewer.findController.executeCommand('find', {
- caseSensitive: false,
- findPrevious: !fwd,
- highlightAll: true,
- phraseSearch: true,
- query: searchString
- });
- };
+ const executeFind = () => this._pdfViewer.findController.executeCommand('find', findOpts);
this._mainCont.current.addEventListener("pagesloaded", executeFind);
this._mainCont.current.addEventListener("pagerendered", executeFind);
}
@@ -376,7 +361,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
@action
onPointerDown = (e: React.PointerEvent): void => {
- const hit = document.elementFromPoint(e.clientX, e.clientY);
+ // const hit = document.elementFromPoint(e.clientX, e.clientY);
// bcz: Change. drag selecting requires that preventDefault is NOT called. This used to happen in DocumentView,
// but that's changed, so this shouldn't be needed.
// if (hit && hit.localName === "span" && this.annotationsActive(true)) { // drag selecting text stops propagation
@@ -414,11 +399,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
this.props.select(false);
}
- @action
- onSelectMove = (e: PointerEvent): void => {
- // if (e.target && (e.target as any).parentElement === this._mainCont.current)
- e.stopPropagation();
- }
+ onSelectMove = (e: PointerEvent) => e.stopPropagation();
@action
onSelectEnd = (e: PointerEvent): void => {
@@ -429,8 +410,7 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
const sel = window.getSelection();
if (sel?.type === "Range") {
- const selRange = sel.getRangeAt(0);
- this.createTextAnnotation(sel, selRange);
+ this.createTextAnnotation(sel, sel.getRangeAt(0));
AnchorMenu.Instance.jumpTo(e.clientX, e.clientY);
}
}
@@ -442,18 +422,16 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
const clientRects = selRange.getClientRects();
for (let i = 0; i < clientRects.length; i++) {
const rect = clientRects.item(i);
- if (rect) {
+ if (rect && rect.width !== this._mainCont.current.clientWidth) {
const scaleX = this._mainCont.current.offsetWidth / boundingRect.width;
- if (rect.width !== this._mainCont.current.clientWidth) {
- const annoBox = document.createElement("div");
- annoBox.className = "marqueeAnnotator-annotationBox";
- // transforms the positions from screen onto the pdf div
- annoBox.style.top = ((rect.top - boundingRect.top) * scaleX / this._zoomed + this._mainCont.current.scrollTop).toString();
- annoBox.style.left = ((rect.left - boundingRect.left) * scaleX / this._zoomed).toString();
- annoBox.style.width = (rect.width * this._mainCont.current.offsetWidth / boundingRect.width / this._zoomed).toString();
- annoBox.style.height = (rect.height * this._mainCont.current.offsetHeight / boundingRect.height / this._zoomed).toString();
- this._annotationLayer.current && MarqueeAnnotator.previewNewAnnotation(this._savedAnnotations, this._annotationLayer.current, annoBox, this.getPageFromScroll(rect.top));
- }
+ const annoBox = document.createElement("div");
+ annoBox.className = "marqueeAnnotator-annotationBox";
+ // transforms the positions from screen onto the pdf div
+ annoBox.style.top = ((rect.top - boundingRect.top) * scaleX / this._zoomed + this._mainCont.current.scrollTop).toString();
+ annoBox.style.left = ((rect.left - boundingRect.left) * scaleX / this._zoomed).toString();
+ annoBox.style.width = (rect.width * this._mainCont.current.offsetWidth / boundingRect.width / this._zoomed).toString();
+ annoBox.style.height = (rect.height * this._mainCont.current.offsetHeight / boundingRect.height / this._zoomed).toString();
+ this._annotationLayer.current && MarqueeAnnotator.previewNewAnnotation(this._savedAnnotations, this._annotationLayer.current, annoBox, this.getPageFromScroll(rect.top));
}
}
}
@@ -509,7 +487,6 @@ export class PDFViewer extends ViewBoxAnnotatableComponent<IViewerProps, PdfDocu
}
@computed get annotationLayer() {
- TraceMobx();
return <div className="pdfViewerDash-annotationLayer" style={{ height: Doc.NativeHeight(this.Document), transform: `scale(${this._zoomed})` }} ref={this._annotationLayer}>
{this.inlineTextAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map(anno =>
<Annotation {...this.props} fieldKey={this.fieldKey + "-annotations"} showInfo={this.showInfo} dataDoc={this.dataDoc} anno={anno} key={`${anno[Id]}-annotation`} />)