From c360dc0adb468ae3aaa1c2d943606993d01a5a52 Mon Sep 17 00:00:00 2001
From: Bob Zeleznik <zzzman@gmail.com>
Date: Sat, 27 Jul 2019 11:08:44 -0400
Subject: fixed handling of keyboard events to avoid triggering global key
 events. made BoolCast default to false. fixed templating to deal with
 conflict between field fields and template fields

---
 src/client/views/pdf/Page.tsx | 22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

(limited to 'src/client/views/pdf/Page.tsx')

diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index c9d442fe5..a6864e0f3 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -1,22 +1,18 @@
+import { action, IReactionDisposer, observable } from "mobx";
 import { observer } from "mobx-react";
-import React = require("react");
-import { observable, action, runInAction, IReactionDisposer, reaction } from "mobx";
 import * as Pdfjs from "pdfjs-dist";
-import { Opt, Doc, FieldResult, Field, DocListCast, WidthSym, HeightSym, DocListCastAsync } from "../../../new_fields/Doc";
-import "./PDFViewer.scss";
 import "pdfjs-dist/web/pdf_viewer.css";
-import { PDFBox } from "../nodes/PDFBox";
-import { DragManager } from "../../util/DragManager";
-import { Docs, DocUtils } from "../../documents/Documents";
+import { Doc, DocListCastAsync, Opt, WidthSym } from "../../../new_fields/Doc";
 import { List } from "../../../new_fields/List";
-import { emptyFunction } from "../../../Utils";
-import { Cast, NumCast, StrCast, BoolCast } from "../../../new_fields/Types";
 import { listSpec } from "../../../new_fields/Schema";
-import { menuBar } from "prosemirror-menu";
-import { AnnotationTypes, PDFViewer, scale } from "./PDFViewer";
+import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
+import { Docs, DocUtils } from "../../documents/Documents";
+import { DragManager } from "../../util/DragManager";
+import { PDFBox } from "../nodes/PDFBox";
 import PDFMenu from "./PDFMenu";
-import { UndoManager } from "../../util/UndoManager";
-import { copy } from "typescript-collections/dist/lib/arrays";
+import { scale } from "./PDFViewer";
+import "./PDFViewer.scss";
+import React = require("react");
 
 
 interface IPageProps {
-- 
cgit v1.2.3-70-g09d2


From d53ad748d90ca1c863a7ef52d0835573ce967a54 Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Sat, 27 Jul 2019 16:49:07 -0400
Subject: init

---
 src/client/util/TooltipTextMenu.tsx         |  6 +++++-
 src/client/views/GlobalKeyHandler.ts        |  2 +-
 src/client/views/nodes/FormattedTextBox.tsx | 30 ++++++++++++++++++++++++++++-
 src/client/views/nodes/PDFBox.tsx           | 14 ++++++++++++++
 src/client/views/pdf/Page.tsx               | 11 ++++++++---
 5 files changed, 57 insertions(+), 6 deletions(-)

(limited to 'src/client/views/pdf/Page.tsx')

diff --git a/src/client/util/TooltipTextMenu.tsx b/src/client/util/TooltipTextMenu.tsx
index a4c053de2..6214b568c 100644
--- a/src/client/util/TooltipTextMenu.tsx
+++ b/src/client/util/TooltipTextMenu.tsx
@@ -1,6 +1,6 @@
 import { action } from "mobx";
 import { Dropdown, MenuItem, icons, } from "prosemirror-menu"; //no import css
-import { EditorState, NodeSelection, TextSelection } from "prosemirror-state";
+import { EditorState, NodeSelection, TextSelection, Transaction } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { schema } from "./RichTextSchema";
 import { Schema, NodeType, MarkType, Mark, ResolvedPos } from "prosemirror-model";
@@ -321,6 +321,10 @@ export class TooltipTextMenu {
         }
     }
 
+    makeLinkWithState = (state: EditorState, target: string, location: string) => {
+        let link = state.schema.mark(state.schema.marks.link, { href: target, location: location });
+    }
+
     makeLink = (target: string, location: string) => {
         let node = this.view.state.selection.$from.nodeAfter;
         let link = this.view.state.schema.mark(this.view.state.schema.marks.link, { href: target, location: location });
diff --git a/src/client/views/GlobalKeyHandler.ts b/src/client/views/GlobalKeyHandler.ts
index 7477c5b4f..6c80c7645 100644
--- a/src/client/views/GlobalKeyHandler.ts
+++ b/src/client/views/GlobalKeyHandler.ts
@@ -151,9 +151,9 @@ export default class KeyManager {
                 stopPropagation = false;
                 break;
             case "a":
-            case "c":
             case "v":
             case "x":
+            case "c":
                 stopPropagation = false;
                 preventDefault = false;
                 break;
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 0a79677e2..cf913a4c7 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -6,7 +6,7 @@ import { baseKeymap } from "prosemirror-commands";
 import { history } from "prosemirror-history";
 import { keymap } from "prosemirror-keymap";
 import { NodeType } from 'prosemirror-model';
-import { EditorState, Plugin, Transaction } from "prosemirror-state";
+import { EditorState, Plugin, Transaction, Selection } from "prosemirror-state";
 import { EditorView } from "prosemirror-view";
 import { Doc, Opt } from "../../../new_fields/Doc";
 import { Id, Copy } from '../../../new_fields/FieldSymbols';
@@ -123,12 +123,40 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
         if (this.props.isOverlay) {
             DragManager.StartDragFunctions.push(() => FormattedTextBox.InputBoxOverlay = undefined);
         }
+
+        document.addEventListener("paste", this.paste);
     }
 
     @computed get extensionDoc() { return Doc.resolvedFieldDataDoc(this.dataDoc, this.props.fieldKey, "dummy"); }
 
     @computed get dataDoc() { return BoolCast(this.props.Document.isTemplate) && this.props.DataDoc ? this.props.DataDoc : Doc.GetProto(this.props.Document); }
 
+    paste = (e: ClipboardEvent) => {
+        if (e.clipboardData && this._editorView) {
+            let pdfPasteText = `${Utils.GenerateDeterministicGuid("pdf paste")}`;
+            for (let i = 0; i < e.clipboardData.items.length; i++) {
+                let item = e.clipboardData.items.item(i);
+                if (item.type === "text/plain") {
+                    item.getAsString((text) => {
+                        let pdfPasteIndex = text.indexOf(pdfPasteText);
+                        if (pdfPasteIndex > -1) {
+                            let insertText = text.substr(0, pdfPasteIndex);
+                            const tx = this._editorView!.state.tr.insertText(insertText);
+                            // tx.setSelection(new Selection(tx.))
+                            const state = this._editorView!.state;
+                            this._editorView!.dispatch(tx);
+                            if (this._toolTipTextMenu) {
+                                // this._toolTipTextMenu.makeLinkWithState(state)
+                            }
+                            e.stopPropagation();
+                            e.preventDefault();
+                        }
+                    });
+                }
+            }
+        }
+    }
+
     dispatchTransaction = (tx: Transaction) => {
         if (this._editorView) {
             const state = this._editorView.state.apply(tx);
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 5a5e6e6dd..282312dca 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -24,6 +24,8 @@ import { Flyout, anchorPoints } from '../DocumentDecorations';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { ScriptField } from '../../../new_fields/ScriptField';
 import { KeyCodes } from '../../northstar/utils/KeyCodes';
+import { Utils } from '../../../Utils';
+import { Id } from '../../../new_fields/FieldSymbols';
 
 type PdfDocument = makeInterface<[typeof positionSchema, typeof pageSchema]>;
 const PdfDocument = makeInterface(positionSchema, pageSchema);
@@ -32,6 +34,7 @@ export const handleBackspace = (e: React.KeyboardEvent) => { if (e.keyCode === K
 @observer
 export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocument) {
     public static LayoutString() { return FieldView.LayoutString(PDFBox); }
+    public selectionText: string = "";
 
     @observable private _alt = false;
     @observable private _scrollY: number = 0;
@@ -63,6 +66,8 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
         this._keyRef = React.createRef();
         this._valueRef = React.createRef();
         this._scriptRef = React.createRef();
+
+        document.addEventListener("keydown", this.onKeyDown);
     }
 
     componentDidMount() {
@@ -73,6 +78,14 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
         this._reactionDisposer && this._reactionDisposer();
     }
 
+    onKeyDown = (e: KeyboardEvent) => {
+        if (e.ctrlKey && e.keyCode === KeyCodes.C) {
+            let text = this.selectionText;
+            text += `${Utils.GenerateDeterministicGuid("pdf paste")}/${this.props.Document[Id]}`;
+            navigator.clipboard.writeText(text);
+        }
+    }
+
     public GetPage() {
         return Math.floor(NumCast(this.props.Document.scrollY) / NumCast(this.dataDoc.pdfHeight)) + 1;
     }
@@ -241,6 +254,7 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
         let classname = "pdfBox-cont" + (this.props.active() && !InkingControl.Instance.selectedTool && !this._alt ? "-interactive" : "");
         return (
             <div className={classname}
+                onKeyDown={this.onKeyDown}
                 onScroll={this.onScroll}
                 style={{
                     marginTop: `${NumCast(this.props.ContainingCollectionView!.props.Document.panY)}px`
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index c9d442fe5..c6bdb2af6 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -357,7 +357,8 @@ export default class Page extends React.Component<IPageProps> {
         else {
             let sel = window.getSelection();
             if (sel && sel.type === "Range") {
-                this.createTextAnnotation(sel);
+                let selRange = sel.getRangeAt(0);
+                this.createTextAnnotation(sel, selRange);
                 PDFMenu.Instance.jumpTo(e.clientX, e.clientY);
             }
         }
@@ -375,8 +376,8 @@ export default class Page extends React.Component<IPageProps> {
     }
 
     @action
-    createTextAnnotation = (sel: Selection) => {
-        let clientRects = sel.getRangeAt(0).getClientRects();
+    createTextAnnotation = (sel: Selection, selRange: Range) => {
+        let clientRects = selRange.getClientRects();
         if (this._textLayer.current) {
             let boundingRect = this._textLayer.current.getBoundingClientRect();
             for (let i = 0; i < clientRects.length; i++) {
@@ -393,6 +394,10 @@ export default class Page extends React.Component<IPageProps> {
                 }
             }
         }
+        let text = selRange.extractContents().textContent;
+        if (text) {
+            this.props.parent.selectionText = text;
+        }
         // clear selection
         if (sel.empty) {  // Chrome
             sel.empty();
-- 
cgit v1.2.3-70-g09d2


From 160ca6c2673b96b8cfe9dfd5bd887a3637a1a45f Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Sat, 27 Jul 2019 22:58:01 -0400
Subject: finisheddd

---
 src/client/views/nodes/FormattedTextBox.tsx | 42 +++++++++++++++++++----------
 src/client/views/nodes/PDFBox.tsx           |  2 --
 src/client/views/pdf/PDFViewer.tsx          | 30 ++++++++++++++++++---
 src/client/views/pdf/Page.tsx               |  3 ++-
 4 files changed, 56 insertions(+), 21 deletions(-)

(limited to 'src/client/views/pdf/Page.tsx')

diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 364dc1c83..f019868aa 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -8,7 +8,7 @@ import { keymap } from "prosemirror-keymap";
 import { EditorState, Plugin, Transaction, Selection } from "prosemirror-state";
 import { NodeType, Slice, Node, Fragment } from 'prosemirror-model';
 import { EditorView } from "prosemirror-view";
-import { Doc, Opt } from "../../../new_fields/Doc";
+import { Doc, Opt, DocListCast } from "../../../new_fields/Doc";
 import { Id, Copy } from '../../../new_fields/FieldSymbols';
 import { List } from '../../../new_fields/List';
 import { RichTextField } from "../../../new_fields/RichTextField";
@@ -302,28 +302,42 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
     handlePaste = (view: EditorView, event: Event, slice: Slice): boolean => {
         let cbe = event as ClipboardEvent;
         let docId: string;
+        let regionId: string;
         if (!cbe.clipboardData) {
             return false;
         }
         let linkId: string;
         docId = cbe.clipboardData.getData("dash/pdfOrigin");
-        if (!docId) {
+        regionId = cbe.clipboardData.getData("dash/pdfRegion");
+        if (!docId || !regionId) {
             return false;
         }
 
         DocServer.GetRefField(docId).then(doc => {
-            if (!(doc instanceof Doc)) {
-                return;
-            }
-            let link = DocUtils.MakeLink(this.props.Document, doc);
-            if (link) {
-                cbe.clipboardData!.setData("dash/linkDoc", link[Id]);
-                linkId = link[Id];
-                let frag = addMarkToFrag(slice.content);
-                slice = new Slice(frag, slice.openStart, slice.openEnd);
-                var tr = view.state.tr.replaceSelection(slice);
-                view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste"));
-            }
+            DocServer.GetRefField(regionId).then(region => {
+                if (!(doc instanceof Doc) || !(region instanceof Doc)) {
+                    return;
+                }
+
+                let annotations = DocListCast(region.annotations);
+                annotations.forEach(anno => anno.target = this.props.Document);
+                let fieldExtDoc = Doc.resolvedFieldDataDoc(doc, "data", "true");
+                let targetAnnotations = DocListCast(fieldExtDoc.annotations);
+                if (targetAnnotations) {
+                    targetAnnotations.push(region);
+                    fieldExtDoc.annotations = new List<Doc>(targetAnnotations);
+                }
+
+                let link = DocUtils.MakeLink(this.props.Document, region);
+                if (link) {
+                    cbe.clipboardData!.setData("dash/linkDoc", link[Id]);
+                    linkId = link[Id];
+                    let frag = addMarkToFrag(slice.content);
+                    slice = new Slice(frag, slice.openStart, slice.openEnd);
+                    var tr = view.state.tr.replaceSelection(slice);
+                    view.dispatch(tr.scrollIntoView().setMeta("paste", true).setMeta("uiEvent", "paste"));
+                }
+            });
         });
 
         return true;
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 72d835fce..f527c0595 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -34,7 +34,6 @@ export const handleBackspace = (e: React.KeyboardEvent) => { if (e.keyCode === K
 @observer
 export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocument) {
     public static LayoutString() { return FieldView.LayoutString(PDFBox); }
-    public selectionText: string = "";
 
     @observable private _alt = false;
     @observable private _scrollY: number = 0;
@@ -82,7 +81,6 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
 
     private copy = (e: ClipboardEvent) => {
         if (this.props.active()) {
-            let text = this.selectionText;
             if (e.clipboardData) {
                 e.clipboardData.setData("text/plain", text);
                 e.clipboardData.setData("dash/pdfOrigin", this.props.Document[Id]);
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index db2d49f0f..6fef8a4de 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -92,6 +92,7 @@ export class Viewer extends React.Component<IViewerProps> {
     // private _textContent: Pdfjs.TextContent[] = [];
     private _pdfFindController: any;
     private _searchString: string = "";
+    private _selectionText: string = "";
 
     constructor(props: IViewerProps) {
         super(props);
@@ -102,6 +103,10 @@ export class Viewer extends React.Component<IViewerProps> {
         this._mainCont = React.createRef();
     }
 
+    setSelectionText = (text: string) => {
+        this._selectionText = text;
+    }
+
     componentDidUpdate = (prevProps: IViewerProps) => {
         if (this.scrollY !== prevProps.scrollY) {
             this.renderPages();
@@ -158,8 +163,8 @@ export class Viewer extends React.Component<IViewerProps> {
             this._dropDisposer = this._mainCont.current && DragManager.MakeDropTarget(this._mainCont.current, { handlers: { drop: this.drop.bind(this) } });
         }
 
-        document.removeEventListener("paste", this.paste);
-        document.addEventListener("paste", this.paste);
+        document.removeEventListener("copy", this.copy);
+        document.addEventListener("copy", this.copy);
     }
 
     componentWillUnmount = () => {
@@ -167,7 +172,24 @@ export class Viewer extends React.Component<IViewerProps> {
         this._annotationReactionDisposer && this._annotationReactionDisposer();
         this._filterReactionDisposer && this._filterReactionDisposer();
         this._dropDisposer && this._dropDisposer();
-        document.removeEventListener("paste", this.paste);
+        document.removeEventListener("copy", this.copy);
+    }
+
+    private copy = (e: ClipboardEvent) => {
+        if (this.props.parent.props.active()) {
+            let text = this._selectionText;
+            if (e.clipboardData) {
+                e.clipboardData.setData("text/plain", text);
+                e.clipboardData.setData("dash/pdfOrigin", this.props.parent.props.Document[Id]);
+                let annoDoc = this.makeAnnotationDocument(undefined, 0, "#0390fc");
+                e.clipboardData.setData("dash/pdfRegion", annoDoc[Id]);
+                e.preventDefault();
+            }
+        }
+        // let targetAnnotations = DocListCast(this.props.parent.fieldExtensionDoc.annotations);
+        // if (targetAnnotations) {
+        //     targetAnnotations.push(destDoc);
+        // }
     }
 
     paste = (e: ClipboardEvent) => {
@@ -281,7 +303,6 @@ export class Viewer extends React.Component<IViewerProps> {
             let targetAnnotations = DocListCast(this.props.parent.fieldExtensionDoc.annotations);
             if (targetAnnotations) {
                 targetAnnotations.push(destDoc);
-                this.props.parent.fieldExtensionDoc.annotations = new List<Doc>(targetAnnotations);
             }
             else {
                 this.props.parent.fieldExtensionDoc.annotations = new List<Doc>([destDoc]);
@@ -315,6 +336,7 @@ export class Viewer extends React.Component<IViewerProps> {
             this._isPage[page] = "page";
             this._visibleElements[page] = (
                 <Page
+                    setSelectionText={this.setSelectionText}
                     size={this._pageSizes[page]}
                     pdf={this.props.pdf}
                     page={page}
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index 989a53ec9..c205617b4 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -29,6 +29,7 @@ interface IPageProps {
     createAnnotation: (div: HTMLDivElement, page: number) => void;
     makeAnnotationDocuments: (doc: Doc | undefined, scale: number, color: string, linkTo: boolean) => Doc;
     getScrollFromPage: (page: number) => number;
+    setSelectionText: (text: string) => void;
 }
 
 @observer
@@ -392,7 +393,7 @@ export default class Page extends React.Component<IPageProps> {
         }
         let text = selRange.extractContents().textContent;
         if (text) {
-            this.props.parent.selectionText = text;
+            this.props.setSelectionText(text);
         }
         // clear selection
         if (sel.empty) {  // Chrome
-- 
cgit v1.2.3-70-g09d2


From e042f916375fbe4f23288ece0dcec5b61ef2fbed Mon Sep 17 00:00:00 2001
From: yipstanley <stanley_yip@brown.edu>
Date: Mon, 29 Jul 2019 21:20:51 -0400
Subject: annotations now open the target context

---
 src/client/util/DragManager.ts                               |  1 +
 .../collectionFreeForm/CollectionFreeFormView.tsx            |  2 ++
 src/client/views/nodes/DocumentView.tsx                      |  4 +++-
 src/client/views/pdf/Annotation.tsx                          | 12 +++++++++---
 src/client/views/pdf/Page.tsx                                |  2 +-
 5 files changed, 16 insertions(+), 5 deletions(-)

(limited to 'src/client/views/pdf/Page.tsx')

diff --git a/src/client/util/DragManager.ts b/src/client/util/DragManager.ts
index 9221ef274..abcc3a4e1 100644
--- a/src/client/util/DragManager.ts
+++ b/src/client/util/DragManager.ts
@@ -216,6 +216,7 @@ export namespace DragManager {
             this.annotationDocument = annotationDoc;
             this.xOffset = this.yOffset = 0;
         }
+        targetContext: Doc | undefined;
         dragDocument: Doc;
         annotationDocument: Doc;
         dropDocument: Doc;
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 0780320d6..179a65739 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -151,6 +151,8 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
                     let dropY = NumCast(de.data.dropDocument.y);
                     dragDoc.x = x + NumCast(dragDoc.x) - dropX;
                     dragDoc.y = y + NumCast(dragDoc.y) - dropY;
+                    de.data.targetContext = this.props.Document;
+                    dragDoc.targetContext = this.props.Document;
                     this.bringToFront(dragDoc);
                 }
             }
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index f101222ae..b37485e62 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -439,7 +439,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             e.stopPropagation();
             let annotationDoc = de.data.annotationDocument;
             annotationDoc.linkedToDoc = true;
+            de.data.targetContext = this.props.ContainingCollectionView!.props.Document;
             let targetDoc = this.props.Document;
+            targetDoc.targetContext = de.data.targetContext;
             let annotations = await DocListCastAsync(annotationDoc.annotations);
             if (annotations) {
                 annotations.forEach(anno => {
@@ -448,7 +450,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
             }
             let pdfDoc = await Cast(annotationDoc.pdfDoc, Doc);
             if (pdfDoc) {
-                DocUtils.MakeLink(annotationDoc, targetDoc, undefined, `Annotation from ${StrCast(pdfDoc.title)}`, "", StrCast(pdfDoc.title));
+                DocUtils.MakeLink(annotationDoc, targetDoc, this.props.ContainingCollectionView!.props.Document, `Annotation from ${StrCast(pdfDoc.title)}`, "", StrCast(pdfDoc.title));
             }
         }
         if (de.data instanceof DragManager.LinkDragData) {
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index ed7081b1d..e8d1da94b 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -9,6 +9,8 @@ import { List } from "../../../new_fields/List";
 import PDFMenu from "./PDFMenu";
 import { DocumentManager } from "../../util/DocumentManager";
 import { PresentationView } from "../presentationview/PresentationView";
+import { LinkManager } from "../../util/LinkManager";
+import { CollectionDockingView } from "../collections/CollectionDockingView";
 
 interface IAnnotationProps {
     anno: Doc;
@@ -110,11 +112,15 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
     }
 
     @action
-    onPointerDown = (e: React.PointerEvent) => {
+    onPointerDown = async (e: React.PointerEvent) => {
         if (e.button === 0) {
-            let targetDoc = Cast(this.props.document.target, Doc, null);
+            let targetDoc = await Cast(this.props.document.target, Doc);
             if (targetDoc) {
-                DocumentManager.Instance.jumpToDocument(targetDoc, false);
+                let context = await Cast(targetDoc.targetContext, Doc);
+                if (context) {
+                    DocumentManager.Instance.jumpToDocument(targetDoc, false, undefined,
+                        ((doc) => this.props.parent.props.parent.props.addDocTab(context, context.proto, e.ctrlKey ? "onRight" : "inTab")));
+                }
             }
         }
         if (e.button === 2) {
diff --git a/src/client/views/pdf/Page.tsx b/src/client/views/pdf/Page.tsx
index c205617b4..c5b2a1dda 100644
--- a/src/client/views/pdf/Page.tsx
+++ b/src/client/views/pdf/Page.tsx
@@ -175,7 +175,7 @@ export default class Page extends React.Component<IPageProps> {
                             }
                             let pdfDoc = await Cast(annotationDoc.pdfDoc, Doc);
                             if (pdfDoc) {
-                                DocUtils.MakeLink(annotationDoc, targetDoc, undefined, `Annotation from ${StrCast(pdfDoc.title)}`, "", StrCast(pdfDoc.title));
+                                DocUtils.MakeLink(annotationDoc, targetDoc, dragData.targetContext, `Annotation from ${StrCast(pdfDoc.title)}`, "", StrCast(pdfDoc.title));
                             }
                         }
                     }
-- 
cgit v1.2.3-70-g09d2

