aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/util/DocumentManager.ts4
-rw-r--r--src/client/views/nodes/PDFBox.scss148
-rw-r--r--src/client/views/nodes/PDFBox.tsx12
-rw-r--r--src/client/views/pdf/PDFViewer.scss28
-rw-r--r--src/client/views/pdf/PDFViewer.tsx165
-rw-r--r--src/client/views/pdf/Page.scss36
-rw-r--r--src/client/views/pdf/Page.tsx293
-rw-r--r--src/debug/Test.tsx99
8 files changed, 134 insertions, 651 deletions
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index a3c7429b9..eaed82918 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -132,9 +132,7 @@ export class DocumentManager {
let doc = Doc.GetProto(docDelegate);
const contextDoc = await Cast(doc.annotationOn, Doc);
if (contextDoc) {
- const page = NumCast(doc.page, linkPage || 0);
- const curPage = NumCast(contextDoc.curPage, page);
- if (page !== curPage) contextDoc.curPage = page;
+ contextDoc.panY = doc.y;
}
let docView: DocumentView | null;
diff --git a/src/client/views/nodes/PDFBox.scss b/src/client/views/nodes/PDFBox.scss
index c88a94c28..b55ca8ba5 100644
--- a/src/client/views/nodes/PDFBox.scss
+++ b/src/client/views/nodes/PDFBox.scss
@@ -5,23 +5,15 @@
height: 100%;
overflow-y: scroll;
overflow-x: hidden;
- .pdfBox-scrollHack {
- pointer-events: none;
- }
}
.pdfBox-cont {
pointer-events: none;
- .pdfPage-textlayer {
- span {
- pointer-events: none !important;
- user-select: none;
- }
- }
}
.pdfBox-cont-interactive {
pointer-events: all;
+
.pdfPage-textlayer {
span {
pointer-events: all !important;
@@ -30,82 +22,90 @@
}
}
-.react-pdf__Page {
- transform-origin: left top;
- position: absolute;
- top: 0;
- left: 0;
-}
+.pdfViewer-text {
+ .textLayer {
+ span {
+ user-select: text;
+ }
+ }
-.react-pdf__Page__textContent span {
- user-select: text;
-}
+ .react-pdf__Page {
+ transform-origin: left top;
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
-.react-pdf__Document {
- position: absolute;
-}
+ .react-pdf__Page__textContent span {
+ user-select: text;
+ }
+ .react-pdf__Document {
+ position: absolute;
+ }
-.pdfBox-settingsCont {
- position: absolute;
- right: 0;
- top: 0;
-
- .pdfBox-settingsButton {
- border-bottom-left-radius: 50%;
- display: flex;
- justify-content: space-evenly;
- align-items: center;
- height: 70px;
- background: none;
- padding: 0;
-
- .pdfBox-settingsButton-arrow {
- width: 0;
- height: 0;
- border-top: 25px solid transparent;
- border-bottom: 25px solid transparent;
- border-right: 25px solid #121721;
- transition: all 0.5s;
- }
- .pdfBox-settingsButton-iconCont {
- background: #121721;
- height: 50px;
- width: 70px;
+ .pdfBox-settingsCont {
+ position: absolute;
+ right: 0;
+ top: 0;
+
+ .pdfBox-settingsButton {
+ border-bottom-left-radius: 50%;
display: flex;
- justify-content: center;
+ justify-content: space-evenly;
align-items: center;
- margin-left: -2px;
- border-radius: 3px;
- }
- }
+ height: 70px;
+ background: none;
+ padding: 0;
- .pdfBox-settingsButton:hover {
- background: none;
- }
+ .pdfBox-settingsButton-arrow {
+ width: 0;
+ height: 0;
+ border-top: 25px solid transparent;
+ border-bottom: 25px solid transparent;
+ border-right: 25px solid #121721;
+ transition: all 0.5s;
+ }
- .pdfBox-settingsFlyout {
- width: 600px;
- position: absolute;
- background: #323232;
- box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
- left: -400px;
- border-radius: 7px;
- padding: 20px;
- display: flex;
- flex-direction: column;
- font-size: 30px;
- transition: all 0.5s;
-
- .pdfBox-settingsFlyout-title {
- color: white;
+ .pdfBox-settingsButton-iconCont {
+ background: #121721;
+ height: 50px;
+ width: 70px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin-left: -2px;
+ border-radius: 3px;
+ }
+ }
+
+ .pdfBox-settingsButton:hover {
+ background: none;
}
- .pdfBox-settingsFlyout-kvpInput {
- margin-top: 20px;
- display: grid;
- grid-template-columns: 47.5% 5% 47.5%;
+ .pdfBox-settingsFlyout {
+ width: 600px;
+ position: absolute;
+ background: #323232;
+ box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.25);
+ left: -400px;
+ border-radius: 7px;
+ padding: 20px;
+ display: flex;
+ flex-direction: column;
+ font-size: 30px;
+ transition: all 0.5s;
+
+ .pdfBox-settingsFlyout-title {
+ color: white;
+ }
+
+ .pdfBox-settingsFlyout-kvpInput {
+ margin-top: 20px;
+ display: grid;
+ grid-template-columns: 47.5% 5% 47.5%;
+ }
}
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 764051d62..8471aefe0 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -52,10 +52,6 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
if (pdfUrl instanceof PdfField) {
Pdfjs.getDocument(pdfUrl.url.pathname).promise.then(pdf => runInAction(() => this._pdf = pdf));
}
- this._reactionDisposer = reaction(
- () => this.Document.panY,
- () => this._mainCont.current && this._mainCont.current.scrollTo({ top: this.Document.panY || 0, behavior: "auto" })
- );
}
componentWillUnmount() {
@@ -167,16 +163,11 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
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.Document.panTransformType = "None";
- this.Document.panY = e.currentTarget.scrollTop;
- }
+ e.stopPropagation();
}
@@ -189,7 +180,6 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
onScroll={this.onScroll}
style={{ marginTop: `${(this.Document.panY || 0)}px` }}
ref={this._mainCont}>
- <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}
diff --git a/src/client/views/pdf/PDFViewer.scss b/src/client/views/pdf/PDFViewer.scss
index 8290a0ee3..247df4e90 100644
--- a/src/client/views/pdf/PDFViewer.scss
+++ b/src/client/views/pdf/PDFViewer.scss
@@ -1,33 +1,17 @@
.pdfViewer-viewer {
pointer-events: inherit;
width: 100%;
+ height: 100%;
+ position: absolute;
+ overflow-y: scroll;
+ overflow-x: hidden;
- .pdfViewer-visibleElements {
- .pdfPage-cont {
- .pdfPage-textLayer {
- div {
- user-select: text;
- }
-
- span {
- color: transparent;
- position: absolute;
- white-space: pre;
- cursor: text;
- -webkit-transform-origin: 0% 0%;
- transform-origin: 0% 0%;
- }
- }
- }
+ .page {
+ position: relative;
}
.pdfViewer-text {
- transform: scale(1.5);
transform-origin: top left;
-
- .page .textLayer {
- user-select: text;
- }
}
.pdfViewer-annotationLayer {
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 108d649a1..c16cb7eb5 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -16,7 +16,6 @@ import { Docs, DocUtils } from "../../documents/Documents";
import { KeyCodes } from "../../northstar/utils/KeyCodes";
import { CompileScript, CompiledScript } from "../../util/Scripting";
import Annotation from "./Annotation";
-import Page from "./Page";
import "./PDFViewer.scss";
import React = require("react");
import requestPromise = require("request-promise");
@@ -24,8 +23,6 @@ import PDFMenu from "./PDFMenu";
import { DragManager } from "../../util/DragManager";
const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer");
-export const scale = 2;
-
interface IViewerProps {
pdf: Pdfjs.PDFDocumentProxy;
url: string;
@@ -134,6 +131,10 @@ export class PDFViewer extends React.Component<IViewerProps> {
}),
{ fireImmediately: true }
);
+ this._reactionDisposer = reaction(
+ () => this.props.Document.panY,
+ () => this._mainCont.current && this._mainCont.current.scrollTo({ top: NumCast(this.props.Document.panY) || 0, behavior: "auto" })
+ );
document.removeEventListener("copy", this.copy);
document.addEventListener("copy", this.copy);
@@ -175,53 +176,31 @@ export class PDFViewer extends React.Component<IViewerProps> {
initialLoad = async () => {
this._pageSizes = Array<{ width: number, height: number }>(this.props.pdf.numPages);
if (this._mainCont.current) {
+ await Promise.all(this._pageSizes.map<Pdfjs.PDFPromise<any>>((val, i) =>
+ this.props.pdf.getPage(i + 1).then((page: Pdfjs.PDFPageProxy) => {
+ runInAction(() => {
+ 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])
+ });
+ });
+ })
+ ));
+ this.props.loaded(Math.max(...this._pageSizes.map(i => i.width)), this._pageSizes[0].height, this.props.pdf.numPages);
this._simpleLinkService = new SimpleLinkService(this);
+ document.addEventListener("pagesinit", () => this._pdfViewer.currentScaleValue = (this.props.Document[WidthSym]() / this._pageSizes[0].width));
+ document.addEventListener("pagerendered", () => console.log("rendered"));
this._pdfViewer = new PDFJSViewer.PDFViewer({
container: this._mainCont.current,
viewer: this._viewer.current,
- linkService: this._simpleLinkService
+ linkService: this._simpleLinkService,
+ renderer: "svg"
});
this._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);
this._pdfFindController = new PDFJSViewer.PDFFindController(this._pdfViewer);
this._pdfViewer.findController = this._pdfFindController;
- await Promise.all(this._pageSizes.map<Pdfjs.PDFPromise<any>>((val, i) =>
- this.props.pdf.getPage(i + 1).then((page: Pdfjs.PDFPageProxy) => {
- 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]) * scale,
- height: (page.view[page.rotate === 0 || page.rotate === 180 ? 3 : 2] - page.view[page.rotate === 0 || page.rotate === 180 ? 1 : 0]) * scale
- });
- }
- )));
- this.props.loaded(Math.max(...this._pageSizes.map(i => i.width)), this._pageSizes[0].height, this.props.pdf.numPages);
}
- // if (this._pageSizes.length === 0) {
- // this._isPage = Array<string>(this.props.pdf.numPages);
- // this._pageSizes = Array<{ width: number, height: number }>(this.props.pdf.numPages);
- // this._visibleElements = Array<JSX.Element>(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) => {
- // 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]) * scale,
- // height: (page.view[page.rotate === 0 || page.rotate === 180 ? 3 : 2] - page.view[page.rotate === 0 || page.rotate === 180 ? 1 : 0]) * scale
- // });
- // this._visibleElements.splice(i, 1,
- // <div key={`${this.props.url}-placeholder-${i + 1}`} className="pdfviewer-placeholder"
- // style={{ width: this._pageSizes[i].width, height: this._pageSizes[i].height }}>
- // "PAGE IS LOADING... "
- // </div>);
- // this.getPlaceholderPage(i);
- // }))));
- // this.props.loaded(Math.max(...this._pageSizes.map(i => i.width)), this._pageSizes[0].height, this.props.pdf.numPages);
-
- // let startY = NumCast(this.props.Document.startY, NumCast(this.props.Document.panY));
- // this.props.setPanY && this.props.setPanY(startY);
- // this.props.scrollTo(startY);
- // }
}
@action
@@ -246,6 +225,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
anno.remove();
this.props.addDocument && this.props.addDocument(annoDoc, false);
mainAnnoDoc = annoDoc;
+ mainAnnoDocProto.y = annoDoc.y;
mainAnnoDocProto = Doc.GetProto(annoDoc);
} else {
this._savedAnnotations.forEach((key: number, value: HTMLDivElement[]) => value.map(anno => {
@@ -277,61 +257,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
@action
- getPlaceholderPage = (page: number) => {
- if (this._isPage[page] !== "none") {
- this._isPage[page] = "none";
- this._visibleElements[page] = (
- <div key={`${this.props.url}-placeholder-${page + 1}`} className="pdfviewer-placeholder"
- style={{ width: this._pageSizes[page].width, height: this._pageSizes[page].height }}>
- "PAGE IS LOADING... "
- </div>);
- }
- }
-
- @action
- getRenderedPage = (page: number) => {
- if (this._isPage[page] !== "page") {
- this._isPage[page] = "page";
- this._visibleElements[page] = (<Page {...this.props}
- size={this._pageSizes[page]}
- numPages={this.props.pdf.numPages}
- setSelectionText={this.setSelectionText}
- page={page}
- key={`${this.props.url}-rendered-${page + 1}`}
- name={`${this.props.pdf.fingerprint + `-page${page + 1}`}`}
- pageLoaded={this.pageLoaded}
- renderAnnotations={this.renderAnnotations}
- createAnnotation={this.createAnnotation}
- sendAnnotations={this.receiveAnnotations}
- makeAnnotationDocuments={this.makeAnnotationDocument}
- getScrollFromPage={this.getScrollFromPage} />);
- }
- }
-
- // change the address to be the file address of the PNG version of each page
- // file address of the pdf
- @action
- getPageImage = async (page: number) => {
- if (this._isPage[page] !== "image") {
- this._isPage[page] = "image";
- try {
- let res = JSON.parse(await rp.get(Utils.prepend(`/thumbnail${this.props.url.substring("files/".length, this.props.url.length - ".pdf".length)}-${page + 1}.PNG`)));
- runInAction(() => this._visibleElements[page] =
- <img key={res.path} src={res.path} onError={() => this.getRenderedPage(page)}
- style={{ width: `${parseInt(res.width) * scale}px`, height: `${parseInt(res.height) * scale}px` }} />);
- } catch (e) {
- console.log(e);
- }
- }
- }
-
- renderPages = () => {
- numberRange(this.props.pdf.numPages).filter(p => this._isPage[p] !== undefined).map(i =>
- (i < this.startIndex || i > this.endIndex) ? this.getPlaceholderPage(i) : // pages outside of the pdf use empty stand-in divs
- this.props.active() ? this.getRenderedPage(i) : this.getPageImage(i));
- }
-
- @action
renderAnnotations = (annotations: Doc[], removeOldAnnotations: boolean): void => {
if (removeOldAnnotations) {
this._annotations = annotations;
@@ -394,7 +319,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
createAnnotation = (div: HTMLDivElement, page: number) => {
if (this._annotationLayer.current) {
if (div.style.top) {
- div.style.top = (parseInt(div.style.top) + this.getScrollFromPage(page)).toString();
+ div.style.top = (parseInt(div.style.top)/*+ this.getScrollFromPage(page)*/).toString();
}
this._annotationLayer.current.append(div);
let savedPage = this._savedAnnotations.getValue(page);
@@ -428,7 +353,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
phraseSearch: true,
query: searchString
});
- }
+ };
this._mainCont.current.addEventListener("pagesloaded", executeFind);
this._mainCont.current.addEventListener("pagerendered", executeFind);
}
@@ -447,10 +372,10 @@ export class PDFViewer extends React.Component<IViewerProps> {
container: this._mainCont.current,
viewer: this._viewer.current,
linkService: simpleLinkService
- })
+ });
simpleLinkService.setPDFJSview(this._pdfViewer);
- this._mainCont.current.addEventListener("pagesinit", () => this._pdfViewer.currentScaleValue = 1);
- this._mainCont.current.addEventListener("pagerendered", () => console.log("rendered"));
+ document.addEventListener("pagesinit", () => this._pdfViewer.currentScaleValue = this.props.Document[WidthSym]() / this._pageSizes[0].width);
+ document.addEventListener("pagerendered", () => console.log("rendered"));
this._pdfViewer.setDocument(this.props.pdf);
this._pdfFindController = new PDFJSViewer.PDFFindController(this._pdfViewer);
this._pdfViewer.findController = this._pdfFindController;
@@ -483,7 +408,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
if (this._mainCont.current) {
let boundingRect = this._mainCont.current.getBoundingClientRect();
this._startX = this._marqueeX = (e.clientX - boundingRect.left) * (this._mainCont.current.offsetWidth / boundingRect.width);
- this._startY = this._marqueeY = (e.clientY - boundingRect.top) * (this._mainCont.current.offsetHeight / boundingRect.height);
+ this._startY = this._marqueeY = (e.clientY - boundingRect.top) * (this._mainCont.current.offsetHeight / boundingRect.height) + this._mainCont.current.scrollTop;
}
this._marqueeing = true;
this._marquee.current && (this._marquee.current.style.opacity = "0.2");
@@ -502,7 +427,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
// transform positions and find the width and height to set the marquee to
let boundingRect = this._mainCont.current.getBoundingClientRect();
this._marqueeWidth = ((e.clientX - boundingRect.left) * (this._mainCont.current.offsetWidth / boundingRect.width)) - this._startX;
- this._marqueeHeight = ((e.clientY - boundingRect.top) * (this._mainCont.current.offsetHeight / boundingRect.height)) - this._startY;
+ this._marqueeHeight = ((e.clientY - boundingRect.top) * (this._mainCont.current.offsetHeight / boundingRect.height)) - this._startY + this._mainCont.current.scrollTop;
this._marqueeX = Math.min(this._startX, this._startX + this._marqueeWidth);
this._marqueeY = Math.min(this._startY, this._startY + this._marqueeHeight);
this._marqueeWidth = Math.abs(this._marqueeWidth);
@@ -521,15 +446,20 @@ export class PDFViewer extends React.Component<IViewerProps> {
let clientRects = selRange.getClientRects();
for (let i = 0; i < clientRects.length; i++) {
let rect = clientRects.item(i);
- if (rect && rect.width !== this._mainCont.current.getBoundingClientRect().width && rect.height !== this._mainCont.current.getBoundingClientRect().height) {
- let annoBox = document.createElement("div");
- annoBox.className = "pdfPage-annotationBox";
- // transforms the positions from screen onto the pdf div
- annoBox.style.top = ((rect.top - boundingRect.top) * (this._mainCont.current.offsetHeight / boundingRect.height)).toString();
- annoBox.style.left = ((rect.left - boundingRect.left) * (this._mainCont.current.offsetWidth / boundingRect.width)).toString();
- annoBox.style.width = (rect.width * this._mainCont.current.offsetWidth / boundingRect.width).toString();
- annoBox.style.height = (rect.height * this._mainCont.current.offsetHeight / boundingRect.height).toString();
- this.createAnnotation(annoBox, this.getPageFromScroll(rect.height));
+ if (rect/* && rect.width !== this._mainCont.current.getBoundingClientRect().width && rect.height !== this._mainCont.current.getBoundingClientRect().height / this.props.pdf.numPages*/) {
+ let page = this.getPageFromScroll(rect.top);
+ let scaleY = this._mainCont.current.offsetHeight / boundingRect.height;
+ let scaleX = this._mainCont.current.offsetWidth / boundingRect.width;
+ if (rect.width !== this._mainCont.current.clientWidth) {
+ let annoBox = document.createElement("div");
+ annoBox.className = "pdfPage-annotationBox";
+ // transforms the positions from screen onto the pdf div
+ annoBox.style.top = ((rect.top - boundingRect.top) * scaleY + this._mainCont.current.scrollTop).toString();
+ annoBox.style.left = ((rect.left - boundingRect.left) * scaleX).toString();
+ annoBox.style.width = (rect.width * this._mainCont.current.offsetWidth / boundingRect.width).toString();
+ annoBox.style.height = (rect.height * this._mainCont.current.offsetHeight / boundingRect.height).toString();
+ this.createAnnotation(annoBox, this.getPageFromScroll(rect.top));
+ }
}
}
}
@@ -641,8 +571,17 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
render() {
- return (<div className="pdfViewer-viewer" ref={this._mainCont} onPointerDown={this.onPointerDown}>
- <div className="pdfViewer-text" ref={this._viewer} />
+ let scaling = this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width / this.props.Document[WidthSym]() : 1;
+ return (<div className="pdfViewer-viewer" ref={this._mainCont} onPointerDown={this.onPointerDown} onWheel={(e) => {
+ runInAction(() => {
+ if (e.currentTarget) {
+ this.props.Document.panTransformType = "None";
+ this.props.Document.panY = e.currentTarget.scrollTop;
+ }
+ e.stopPropagation();
+ });
+ }}>
+ <div className="pdfViewer-text" ref={this._viewer} style={{ transform: `scale(${scaling})` }} />
<div className="pdfPage-dragAnnotationBox" ref={this._marquee}
style={{
left: `${this._marqueeX}px`, top: `${this._marqueeY}px`,
diff --git a/src/client/views/pdf/Page.scss b/src/client/views/pdf/Page.scss
deleted file mode 100644
index d8034b4b4..000000000
--- a/src/client/views/pdf/Page.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-
-.pdfViewer-text {
- .page {
- position: relative;
- }
-}
-.pdfPage-cont {
- position: relative;
-
- .pdfPage-canvasContainer {
- position: absolute;
- }
-
- .pdfPage-dragAnnotationBox {
- position: absolute;
- background-color: transparent;
- opacity: 0.1;
- }
-
- .pdfPage-textLayer {
- position: absolute;
- width: 100%;
- height: 100%;
- div {
- user-select: text;
- }
- span {
- color: transparent;
- position: absolute;
- white-space: pre;
- cursor: text;
- -webkit-transform-origin: 0% 0%;
- transform-origin: 0% 0%;
- }
- }
-} \ No newline at end of file
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
deleted file mode 100644
index 533247170..000000000
--- a/src/client/views/pdf/Page.tsx
+++ /dev/null
@@ -1,293 +0,0 @@
-import { action, IReactionDisposer, observable } from "mobx";
-import { observer } from "mobx-react";
-import * as Pdfjs from "pdfjs-dist";
-import "pdfjs-dist/web/pdf_viewer.css";
-import { Doc, DocListCastAsync, Opt, WidthSym } from "../../../new_fields/Doc";
-import { BoolCast, Cast, NumCast, StrCast } from "../../../new_fields/Types";
-import { Docs, DocUtils } from "../../documents/Documents";
-import { DragManager } from "../../util/DragManager";
-import PDFMenu from "./PDFMenu";
-import { scale } from "./PDFViewer";
-import "./Page.scss";
-import React = require("react");
-
-
-interface IPageProps {
- size: { width: number, height: number };
- pdf: Pdfjs.PDFDocumentProxy;
- name: string;
- numPages: number;
- page: number;
- pageLoaded: (page: Pdfjs.PDFPageViewport) => void;
- fieldExtensionDoc: Doc;
- Document: Doc;
- renderAnnotations: (annotations: Doc[], removeOld: boolean) => void;
- sendAnnotations: (annotations: HTMLDivElement[], page: number) => void;
- createAnnotation: (div: HTMLDivElement, page: number) => void;
- makeAnnotationDocuments: (doc: Doc | undefined, color: string, linkTo: boolean) => Doc;
- getScrollFromPage: (page: number) => number;
- setSelectionText: (text: string) => void;
-}
-
-@observer
-export default class Page extends React.Component<IPageProps> {
- @observable private _state: "N/A" | "rendering" = "N/A";
- @observable private _width: number = this.props.size.width;
- @observable private _height: number = this.props.size.height;
- @observable private _page: Opt<Pdfjs.PDFPageProxy>;
- @observable private _currPage: number = this.props.page + 1;
- @observable private _marqueeX: number = 0;
- @observable private _marqueeY: number = 0;
- @observable private _marqueeWidth: number = 0;
- @observable private _marqueeHeight: number = 0;
-
- private _canvas: React.RefObject<HTMLCanvasElement> = React.createRef();
- private _textLayer: React.RefObject<HTMLDivElement> = React.createRef();
- private _marquee: React.RefObject<HTMLDivElement> = React.createRef();
- private _marqueeing: boolean = false;
- private _reactionDisposer?: IReactionDisposer;
- private _startY: number = 0;
- private _startX: number = 0;
-
- componentDidMount = (): void => this.loadPage(this.props.pdf);
-
- componentDidUpdate = (): void => this.loadPage(this.props.pdf);
-
- componentWillUnmount = (): void => this._reactionDisposer && this._reactionDisposer();
-
- loadPage = (pdf: Pdfjs.PDFDocumentProxy): void => {
- pdf.getPage(this._currPage).then(page => this.renderPage(page));
- }
-
- @action
- renderPage = (page: Pdfjs.PDFPageProxy): void => {
- // lower scale = easier to read at small sizes, higher scale = easier to read at large sizes
- if (this._state !== "rendering" && !this._page && this._canvas.current && this._textLayer.current) {
- this._state = "rendering";
- let viewport = page.getViewport(scale);
- this._canvas.current.width = this._width = viewport.width;
- this._canvas.current.height = this._height = viewport.height;
- this.props.pageLoaded(viewport);
- let ctx = this._canvas.current.getContext("2d");
- if (ctx) {
- //@ts-ignore
- page.render({ canvasContext: ctx, viewport: viewport, enableWebGL: true }); // renders the page onto the canvas context
- page.getTextContent().then(res => // renders text onto the text container
- //@ts-ignore
- Pdfjs.renderTextLayer({
- textContent: res,
- container: this._textLayer.current,
- viewport: viewport
- }));
-
- this._page = page;
- }
- }
- }
-
- @action
- highlight = (targetDoc: Doc | undefined, color: string) => {
- // creates annotation documents for current highlights
- let annotationDoc = this.props.makeAnnotationDocuments(targetDoc, color, false);
- Doc.AddDocToList(this.props.fieldExtensionDoc, "annotations", annotationDoc);
- return annotationDoc;
- }
-
- /**
- * This is temporary for creating annotations from highlights. It will
- * start a drag event and create or put the necessary info into the drag event.
- */
- @action
- startDrag = (e: PointerEvent, ele: HTMLElement): void => {
- e.preventDefault();
- e.stopPropagation();
- if (this._textLayer.current) {
- let targetDoc = Docs.Create.TextDocument({ width: 200, height: 200, title: "New Annotation" });
- targetDoc.targetPage = this.props.page;
- let annotationDoc = this.highlight(undefined, "red");
- annotationDoc.linkedToDoc = false;
- let dragData = new DragManager.AnnotationDragData(this.props.Document, annotationDoc, targetDoc);
- DragManager.StartAnnotationDrag([ele], dragData, e.pageX, e.pageY, {
- handlers: {
- dragComplete: async () => {
- if (!BoolCast(annotationDoc.linkedToDoc)) {
- let annotations = await DocListCastAsync(annotationDoc.annotations);
- annotations && annotations.forEach(anno => anno.target = targetDoc);
- DocUtils.MakeLink(annotationDoc, targetDoc, dragData.targetContext, `Annotation from ${StrCast(this.props.Document.title)}`);
- }
- }
- },
- hideSource: false
- });
- }
- }
-
- // cleans up events and boolean
- endDrag = (e: PointerEvent): void => {
- e.stopPropagation();
- }
-
- createSnippet = (marquee: { left: number, top: number, width: number, height: number }): void => {
- let view = Doc.MakeAlias(this.props.Document);
- let data = Doc.MakeDelegate(Doc.GetProto(this.props.Document));
- data.title = StrCast(data.title) + "_snippet";
- view.proto = data;
- view.nativeHeight = marquee.height;
- view.height = (this.props.Document[WidthSym]() / NumCast(this.props.Document.nativeWidth)) * marquee.height;
- view.nativeWidth = this.props.Document.nativeWidth;
- view.startY = marquee.top + this.props.getScrollFromPage(this.props.page);
- view.width = this.props.Document[WidthSym]();
- DragManager.StartDocumentDrag([], new DragManager.DocumentDragData([view]), 0, 0);
- }
-
- @action
- onPointerDown = (e: React.PointerEvent): void => {
- // if alt+left click, drag and annotate
- if (NumCast(this.props.Document.scale, 1) !== 1) return;
- if (!e.altKey && e.button === 0) {
- PDFMenu.Instance.StartDrag = this.startDrag;
- PDFMenu.Instance.Highlight = this.highlight;
- PDFMenu.Instance.Snippet = this.createSnippet;
- PDFMenu.Instance.Status = "pdf";
- PDFMenu.Instance.fadeOut(true);
- if (e.target && (e.target as any).parentElement === this._textLayer.current) {
- e.stopPropagation();
- if (!e.ctrlKey) {
- this.props.sendAnnotations([], -1);
- }
- }
- else {
- // set marquee x and y positions to the spatially transformed position
- if (this._textLayer.current) {
- let boundingRect = this._textLayer.current.getBoundingClientRect();
- this._startX = this._marqueeX = (e.clientX - boundingRect.left) * (this._textLayer.current.offsetWidth / boundingRect.width);
- this._startY = this._marqueeY = (e.clientY - boundingRect.top) * (this._textLayer.current.offsetHeight / boundingRect.height);
- }
- this._marqueeing = true;
- this._marquee.current && (this._marquee.current.style.opacity = "0.2");
- this.props.sendAnnotations([], -1);
- }
- document.removeEventListener("pointermove", this.onSelectStart);
- document.addEventListener("pointermove", this.onSelectStart);
- document.removeEventListener("pointerup", this.onSelectEnd);
- document.addEventListener("pointerup", this.onSelectEnd);
- }
- }
-
- @action
- onSelectStart = (e: PointerEvent): void => {
- if (this._marqueeing && this._textLayer.current) {
- // transform positions and find the width and height to set the marquee to
- let boundingRect = this._textLayer.current.getBoundingClientRect();
- this._marqueeWidth = ((e.clientX - boundingRect.left) * (this._textLayer.current.offsetWidth / boundingRect.width)) - this._startX;
- this._marqueeHeight = ((e.clientY - boundingRect.top) * (this._textLayer.current.offsetHeight / boundingRect.height)) - this._startY;
- this._marqueeX = Math.min(this._startX, this._startX + this._marqueeWidth);
- this._marqueeY = Math.min(this._startY, this._startY + this._marqueeHeight);
- this._marqueeWidth = Math.abs(this._marqueeWidth);
- e.stopPropagation();
- e.preventDefault();
- }
- else if (e.target && (e.target as any).parentElement === this._textLayer.current) {
- e.stopPropagation();
- }
- }
-
- @action
- onSelectEnd = (e: PointerEvent): void => {
- if (this._marqueeing) {
- this._marqueeing = false;
- if (this._marqueeWidth > 10 || this._marqueeHeight > 10) {
- if (this._marquee.current) { // make a copy of the marquee
- let copy = document.createElement("div");
- let style = this._marquee.current.style;
- copy.style.left = style.left;
- copy.style.top = style.top;
- copy.style.width = style.width;
- copy.style.height = style.height;
- copy.style.border = style.border;
- copy.style.opacity = style.opacity;
- copy.className = "pdfPage-annotationBox";
- this.props.createAnnotation(copy, this.props.page);
- this._marquee.current.style.opacity = "0";
- }
-
- if (!e.ctrlKey) {
- PDFMenu.Instance.Status = "snippet";
- PDFMenu.Instance.Marquee = { left: this._marqueeX, top: this._marqueeY, width: this._marqueeWidth, height: this._marqueeHeight };
- }
- PDFMenu.Instance.jumpTo(e.clientX, e.clientY);
- }
-
- this._marqueeHeight = this._marqueeWidth = 0;
- }
- else {
- let sel = window.getSelection();
- if (sel && sel.type === "Range") {
- let selRange = sel.getRangeAt(0);
- this.createTextAnnotation(sel, selRange);
- PDFMenu.Instance.jumpTo(e.clientX, e.clientY);
- }
- }
-
- if (PDFMenu.Instance.Highlighting) {
- this.highlight(undefined, "goldenrod");
- }
- else {
- PDFMenu.Instance.StartDrag = this.startDrag;
- PDFMenu.Instance.Highlight = this.highlight;
- }
- document.removeEventListener("pointermove", this.onSelectStart);
- document.removeEventListener("pointerup", this.onSelectEnd);
- }
-
- @action
- createTextAnnotation = (sel: Selection, selRange: Range) => {
- if (this._textLayer.current) {
- let boundingRect = this._textLayer.current.getBoundingClientRect();
- let clientRects = selRange.getClientRects();
- for (let i = 0; i < clientRects.length; i++) {
- let rect = clientRects.item(i);
- if (rect && rect.width !== this._textLayer.current.getBoundingClientRect().width && rect.height !== this._textLayer.current.getBoundingClientRect().height) {
- let annoBox = document.createElement("div");
- annoBox.className = "pdfPage-annotationBox";
- // transforms the positions from screen onto the pdf div
- annoBox.style.top = ((rect.top - boundingRect.top) * (this._textLayer.current.offsetHeight / boundingRect.height)).toString();
- annoBox.style.left = ((rect.left - boundingRect.left) * (this._textLayer.current.offsetWidth / boundingRect.width)).toString();
- annoBox.style.width = (rect.width * this._textLayer.current.offsetWidth / boundingRect.width).toString();
- annoBox.style.height = (rect.height * this._textLayer.current.offsetHeight / boundingRect.height).toString();
- this.props.createAnnotation(annoBox, this.props.page);
- }
- }
- }
- let text = selRange.cloneContents().textContent;
- text && this.props.setSelectionText(text);
-
- // clear selection
- if (sel.empty) { // Chrome
- sel.empty();
- } else if (sel.removeAllRanges) { // Firefox
- sel.removeAllRanges();
- }
- }
-
- doubleClick = (e: React.MouseEvent) => {
- if (e.target && (e.target as any).parentElement === this._textLayer.current) {
- // do something to select the paragraph ideally
- }
- }
-
- render() {
- return (
- <div className={"pdfPage-cont"} onPointerDown={this.onPointerDown} onDoubleClick={this.doubleClick} style={{ "width": this._width, "height": this._height }}>
- <canvas className="PdfPage-canvasContainer" ref={this._canvas} />
- <div className="pdfPage-dragAnnotationBox" ref={this._marquee}
- style={{
- left: `${this._marqueeX}px`, top: `${this._marqueeY}px`,
- width: `${this._marqueeWidth}px`, height: `${this._marqueeHeight}px`,
- border: `${this._marqueeWidth === 0 ? "" : "10px dashed black"}`
- }}>
- </div>
- <div className="pdfPage-textlayer" ref={this._textLayer} />
- </div>);
- }
-} \ No newline at end of file
diff --git a/src/debug/Test.tsx b/src/debug/Test.tsx
index 20d02488e..3baedce4b 100644
--- a/src/debug/Test.tsx
+++ b/src/debug/Test.tsx
@@ -5,108 +5,9 @@ import { Doc } from '../new_fields/Doc';
import * as Pdfjs from "pdfjs-dist";
import "pdfjs-dist/web/pdf_viewer.css";
import { Utils } from '../Utils';
-import { scale } from '../client/views/pdf/PDFViewer';
const PDFJSViewer = require("pdfjs-dist/web/pdf_viewer");
const protoId = "protoDoc";
const delegateId = "delegateDoc";
class Test extends React.Component {
- private _viewer: React.RefObject<HTMLDivElement> = React.createRef();
- private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
- private _pageSizes: Array<{ width: number, height: number }> = [];
- _pdfViewer: PDFJSViewer.PDFViewer;
- _pdfFindController: PDFJSViewer.PDFFindController;
- _page: number = 0;
-
- componentDidMount = () => {
- let pdfUrl = Utils.CorsProxy("https://www.hq.nasa.gov/alsj/a17/A17_FlightPlan.pdf");
- Pdfjs.getDocument(pdfUrl).promise.then(async pdf => {
- if (this._mainCont.current) {
- let simpleLinkService = new SimpleLinkService(this);
- this._pdfViewer = new PDFJSViewer.PDFViewer({
- container: this._mainCont.current,
- viewer: this._viewer.current,
- linkService: simpleLinkService
- });
- simpleLinkService.setPDFJSview(this._pdfViewer);
- this._mainCont.current.addEventListener("pagesinit", () => {
- this._pdfViewer.currentScaleValue = 1;
- console.log(this._pdfViewer);
- });
- this._mainCont.current.addEventListener("pagerendered", () => console.log("rendered"));
- this._pdfViewer.setDocument(pdf);
- this._pageSizes = Array<{ width: number, height: number }>(pdf.numPages);
- this._pdfFindController = new PDFJSViewer.PDFFindController(this._pdfViewer);
- this._pdfViewer.findController = this._pdfFindController;
- await Promise.all(this._pageSizes.map<Pdfjs.PDFPromise<any>>((val, i) =>
- pdf.getPage(i + 1).then((page: Pdfjs.PDFPageProxy) => {
- 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]) * scale,
- height: (page.view[page.rotate === 0 || page.rotate === 180 ? 3 : 2] - page.view[page.rotate === 0 || page.rotate === 180 ? 1 : 0]) * scale
- });
- }
- )));
- }
- });
- }
-
- goToPage = (page: number) => {
- if (this._mainCont.current) {
- // this._mainCont.current.scrollTo()
- }
- }
-
- render() {
- return (
- <div ref={this._mainCont}>
- <div ref={this._viewer} />
- </div>
- )
- }
-}
-
-class SimpleLinkService {
- _viewer: Test;
- _pdfjsView: any;
-
- constructor(viewer: Test) {
- this._viewer = viewer;
- }
- setPDFJSview(v: any) { this._pdfjsView = v; }
-
- navigateTo() { }
-
- getDestinationHash() { return "#"; }
-
- getAnchorUrl() { return "#"; }
-
- setHash() { }
-
- isPageVisible(page: number) { return true; }
-
- executeNamedAction() { }
-
- cachePageRef() { }
-
- get pagesCount() { return this._viewer._pdfViewer.pagesCount; }
-
- get page() { return this._viewer._page; }
- 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.goToPage) {
- this._viewer.goToPage(p);
- }
- });
- }
-
-
- get rotation() { return 0; }
- set rotation(value: any) { }
}
-
-DocServer.init(window.location.protocol, window.location.hostname, 4321, "test");
-ReactDOM.render(
- <Test />,
- document.getElementById('root')
-); \ No newline at end of file