aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbob <bcz@cs.brown.edu>2019-10-02 18:26:55 -0400
committerbob <bcz@cs.brown.edu>2019-10-02 18:26:55 -0400
commit9427474b473d70974784a1517a1be902fb8d18ee (patch)
treef2f2762eb8dbcf771711161fc021fe5c0c2ff654
parenta19210e7db3e625c0bfe38b4f13b5312cc0c6e53 (diff)
many fixes to pdfs, linking, annotations, presentations.
-rw-r--r--src/client/documents/Documents.ts24
-rw-r--r--src/client/util/DocumentManager.ts125
-rw-r--r--src/client/util/RichTextSchema.tsx9
-rw-r--r--src/client/util/SharingManager.tsx2
-rw-r--r--src/client/views/collections/CollectionBaseView.tsx9
-rw-r--r--src/client/views/collections/CollectionDockingView.tsx10
-rw-r--r--src/client/views/collections/CollectionSubView.tsx1
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx2
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx10
-rw-r--r--src/client/views/linking/LinkFollowBox.tsx11
-rw-r--r--src/client/views/nodes/DocumentView.tsx44
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx79
-rw-r--r--src/client/views/nodes/ImageBox.tsx2
-rw-r--r--src/client/views/nodes/PDFBox.tsx17
-rw-r--r--src/client/views/nodes/PresBox.tsx24
-rw-r--r--src/client/views/nodes/VideoBox.tsx2
-rw-r--r--src/client/views/pdf/Annotation.tsx17
-rw-r--r--src/client/views/pdf/PDFMenu.tsx6
-rw-r--r--src/client/views/pdf/PDFViewer.tsx72
-rw-r--r--src/client/views/presentationview/PresElementBox.tsx32
-rw-r--r--src/new_fields/Doc.ts2
21 files changed, 224 insertions, 276 deletions
diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts
index 4d9698532..2d323ea4b 100644
--- a/src/client/documents/Documents.ts
+++ b/src/client/documents/Documents.ts
@@ -653,32 +653,30 @@ export namespace DocUtils {
}
});
}
- export function MakeLink(source: Doc, target: Doc, targetContext?: Doc, title: string = "", description: string = "", sourceContext?: Doc, id?: string, anchored1?: boolean) {
- let sv = DocumentManager.Instance.getDocumentView(source);
- if (sv && sv.props.ContainingCollectionDoc === target) return;
- if (target === CurrentUserUtils.UserDocument) return undefined;
+ export function MakeLink(source: {doc:Doc,ctx?:Doc}, target: {doc:Doc,ctx?:Doc}, title: string = "", description: string = "", id?: string, anchored1?: boolean) {
+ let sv = DocumentManager.Instance.getDocumentView(source.doc);
+ if (sv && sv.props.ContainingCollectionDoc === target.doc) return;
+ if (target.doc === CurrentUserUtils.UserDocument) return undefined;
let linkDocProto = new Doc(id, true);
UndoManager.RunInBatch(() => {
linkDocProto.type = DocumentType.LINK;
- linkDocProto.targetContext = targetContext;
- linkDocProto.sourceContext = sourceContext;
- linkDocProto.title = title === "" ? source.title + " to " + target.title : title;
+ linkDocProto.targetContext = target.ctx;
+ linkDocProto.sourceContext = source.ctx;
+ linkDocProto.title = title === "" ? source.doc.title + " to " + target.doc.title : title;
linkDocProto.linkDescription = description;
- linkDocProto.anchor1 = source;
- linkDocProto.anchor1Page = source.curPage;
+ linkDocProto.anchor1 = source.doc;
linkDocProto.anchor1Groups = new List<Doc>([]);
linkDocProto.anchor1anchored = anchored1;
- linkDocProto.anchor2 = target;
- linkDocProto.anchor2Page = target.curPage;
+ linkDocProto.anchor2 = target.doc;
linkDocProto.anchor2Groups = new List<Doc>([]);
LinkManager.Instance.addLink(linkDocProto);
- Doc.GetProto(source).links = ComputedField.MakeFunction("links(this)");
- Doc.GetProto(target).links = ComputedField.MakeFunction("links(this)");
+ Doc.GetProto(source.doc).links = ComputedField.MakeFunction("links(this)");
+ Doc.GetProto(target.doc).links = ComputedField.MakeFunction("links(this)");
}, "make link");
return linkDocProto;
}
diff --git a/src/client/util/DocumentManager.ts b/src/client/util/DocumentManager.ts
index 4e6968f08..4ebcdf83c 100644
--- a/src/client/util/DocumentManager.ts
+++ b/src/client/util/DocumentManager.ts
@@ -1,7 +1,7 @@
import { action, computed, observable } from 'mobx';
import { Doc, DocListCastAsync } from '../../new_fields/Doc';
import { Id } from '../../new_fields/FieldSymbols';
-import { Cast, NumCast } from '../../new_fields/Types';
+import { Cast, NumCast, StrCast } from '../../new_fields/Types';
import { CollectionDockingView } from '../views/collections/CollectionDockingView';
import { CollectionPDFView } from '../views/collections/CollectionPDFView';
import { CollectionVideoView } from '../views/collections/CollectionVideoView';
@@ -56,9 +56,9 @@ export class DocumentManager {
return this.getDocumentViewsById(doc[Id]);
}
- public getDocumentViewById(id: string, preferredCollection?: CollectionView | CollectionPDFView | CollectionVideoView): DocumentView | null {
+ public getDocumentViewById(id: string, preferredCollection?: CollectionView | CollectionPDFView | CollectionVideoView): DocumentView | undefined {
- let toReturn: DocumentView | null = null;
+ let toReturn: DocumentView | undefined;
let passes = preferredCollection ? [preferredCollection, undefined] : [undefined];
for (let pass of passes) {
@@ -81,10 +81,14 @@ export class DocumentManager {
return toReturn;
}
- public getDocumentView(toFind: Doc, preferredCollection?: CollectionView | CollectionPDFView | CollectionVideoView): DocumentView | null {
+ public getDocumentView(toFind: Doc, preferredCollection?: CollectionView | CollectionPDFView | CollectionVideoView): DocumentView | undefined {
return this.getDocumentViewById(toFind[Id], preferredCollection);
}
+ public getFirstDocumentView(toFind: Doc): DocumentView | undefined {
+ const views = this.getDocumentViews(toFind);
+ return views.length ? views[0] : undefined;
+ }
public getDocumentViews(toFind: Doc): DocumentView[] {
let toReturn: DocumentView[] = [];
@@ -127,72 +131,70 @@ export class DocumentManager {
return pairs;
}
-
- @undoBatch
- public jumpToDocument = async (docDelegate: Doc, willZoom: boolean, forceDockFunc: boolean = false, dockFunc?: (doc: Doc) => void, linkPage?: number, docContext?: Doc): Promise<void> => {
- let doc = Doc.GetProto(docDelegate);
- const contextDoc = await Cast(doc.annotationOn, Doc);
- if (contextDoc) {
- contextDoc.scrollY = NumCast(doc.y) - NumCast(contextDoc.height) / 2 * 72 / 96;
- }
-
- let docView: DocumentView | null;
- // using forceDockFunc as a flag for splitting linked to doc to the right...can change later if needed
- if (!forceDockFunc && (docView = DocumentManager.Instance.getDocumentView(doc))) {
- Doc.BrushDoc(docView.props.Document);
- if (linkPage !== undefined) docView.props.Document.curPage = linkPage;
- UndoManager.RunInBatch(() => docView!.props.focus(docView!.props.Document, willZoom), "focus");
+ public jumpToDocument = async (targetDoc: Doc, willZoom: boolean, dockFunc?: (doc: Doc) => void, docContext?: Doc, closeContextIfNotFound: boolean = false): Promise<void> => {
+ const docView = DocumentManager.Instance.getFirstDocumentView(targetDoc);
+ const annotatedDoc = await Cast(targetDoc.annotationOn, Doc);
+ if (docView) { // we have a docView already and aren't forced to create a new one ... just focus on the document. TODO move into view if necessary otherwise just highlight?
+ annotatedDoc && docView.props.focus(annotatedDoc, false);
+ docView.props.focus(targetDoc, willZoom);
} else {
- if (!contextDoc) {
- let docs = docContext ? await DocListCastAsync(docContext.data) : undefined;
- let found = false;
- // bcz: this just searches within the context for the target -- perhaps it should recursively search through all children?
- docs && docs.map(d => found = found || Doc.AreProtosEqual(d, docDelegate));
- if (docContext && found) {
- let targetContextView: DocumentView | null;
-
- if (!forceDockFunc && docContext && (targetContextView = DocumentManager.Instance.getDocumentView(docContext))) {
- docContext.panTransformType = "Ease";
- targetContextView.props.focus(docDelegate, willZoom);
- } else {
- (dockFunc || CollectionDockingView.AddRightSplit)(docContext, undefined);
- setTimeout(() => {
- let dv = DocumentManager.Instance.getDocumentView(docContext);
- dv && this.jumpToDocument(docDelegate, willZoom, forceDockFunc,
- doc => dv!.props.focus(dv!.props.Document, true, 1, () => dv!.props.addDocTab(doc, undefined, "inPlace")),
- linkPage);
- }, 1050);
- }
- } else {
- const actualDoc = Doc.MakeAlias(docDelegate);
- Doc.BrushDoc(actualDoc);
- if (linkPage !== undefined) actualDoc.curPage = linkPage;
- (dockFunc || CollectionDockingView.AddRightSplit)(actualDoc, undefined);
- }
+ const contextDocs = docContext ? await DocListCastAsync(docContext.data) : undefined;
+ const contextDoc = contextDocs && contextDocs.find(doc => Doc.AreProtosEqual(doc, targetDoc)) ? docContext : undefined;
+ const targetDocContext = (annotatedDoc ? annotatedDoc : contextDoc);
+
+ if (!targetDocContext) { // we don't have a view and there's no context specified ... create a new view of the target using the dockFunc or default
+ (dockFunc || CollectionDockingView.AddRightSplit)(Doc.BrushDoc(Doc.MakeAlias(targetDoc)), undefined);
} else {
- let contextView: DocumentView | null;
- Doc.BrushDoc(docDelegate);
- let contextViews = DocumentManager.Instance.getDocumentViews(contextDoc);
- if (!forceDockFunc && contextViews.length) {
- contextView = contextViews[0];
- SelectionManager.SelectDoc(contextView, false); // force unrendered annotations to be created
- contextDoc.panTransformType = "Ease";
+ const targetDocContextView = DocumentManager.Instance.getFirstDocumentView(targetDocContext);
+ if (targetDocContextView) { // we have a context view and aren't forced to create a new one ... focus on the context
+ targetDocContext.panTransformType = "Ease";
+ targetDocContext.scrollY = 0;
+ targetDocContextView.props.focus(targetDocContextView.props.Document, willZoom);
+
+ // now find the target document within the context
setTimeout(() => {
- SelectionManager.DeselectDoc(contextView!);
- docView = DocumentManager.Instance.getDocumentView(docDelegate);
- docView && contextView!.props.focus(contextView!.props.Document, willZoom);
- docView && UndoManager.RunInBatch(() => docView!.props.focus(docView!.props.Document, willZoom), "focus");
+ const retryDocView = DocumentManager.Instance.getDocumentView(targetDoc);
+ if (retryDocView) {
+ retryDocView.props.focus(targetDoc, willZoom); // focus on the target if it now exists in the context
+ } else {
+ if (closeContextIfNotFound && targetDocContextView.props.removeDocument) targetDocContextView.props.removeDocument(targetDocContextView.props.Document);
+ (dockFunc || CollectionDockingView.AddRightSplit)(Doc.BrushDoc(Doc.MakeAlias(targetDoc)), undefined); // otherwise create a new view of the target
+ }
}, 0);
- } else {
- (dockFunc || CollectionDockingView.AddRightSplit)(contextDoc, undefined);
+ } else { // there's no context view so we need to create one first and try again
+ targetDocContext.scrollY = 0;
+ (dockFunc || CollectionDockingView.AddRightSplit)(targetDocContext, undefined);
setTimeout(() => {
- this.jumpToDocument(docDelegate, willZoom, forceDockFunc, dockFunc, linkPage);
- }, 1000);
+ const foundTargetDocContextView = DocumentManager.Instance.getDocumentView(targetDocContext);
+ if (foundTargetDocContextView) { // we should always find a target context here....
+ this.jumpToDocument(targetDoc, willZoom, dockFunc, undefined, true); // so call jump to doc again and if the doc isn't found, it will be created.
+ }
+ }, 2000); // the long timeout gives the context view a chance to create its children. think pdf's which need to be activated to render their annotations.
}
}
}
}
+ public async FollowLink(doc: Doc, focus: (doc: Doc, maxLocation: string) => void, zoom: boolean = false, reverse: boolean = false, currentContext?: Doc) {
+ let linkDocs = LinkManager.Instance.getAllRelatedLinks(doc);
+ SelectionManager.DeselectAll();
+ let firstDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor1 as Doc, doc) && !linkDoc.anchor1anchored);
+ let secondDocs = linkDocs.filter(linkDoc => Doc.AreProtosEqual(linkDoc.anchor2 as Doc, doc) && !linkDoc.anchor2anchored);
+ const firstDocWithoutView = firstDocs.find(d => DocumentManager.Instance.getDocumentViews(d.anchor2 as Doc).length === 0);
+ const secondDocWithoutView = secondDocs.find(d => DocumentManager.Instance.getDocumentViews(d.anchor1 as Doc).length === 0);
+ let first = firstDocWithoutView ? [firstDocWithoutView] : firstDocs;
+ let second = secondDocWithoutView ? [secondDocWithoutView] : secondDocs;
+ let linkFollowDocs = first.length ? [first[0].anchor2 as Doc, first[0].anchor1 as Doc] : second.length ? [second[0].anchor1 as Doc, second[0].anchor2 as Doc] : undefined;
+ let linkFollowDocContexts = first.length ? [await (first[0].targetContext) as Doc, await (first[0].sourceContext) as Doc] : second.length ? [await (second[0].sourceContext) as Doc, await (second[0].targetContext) as Doc] : [undefined, undefined];
+ if (linkFollowDocs && !linkFollowDocs.some(l => l instanceof Promise)) {
+ let maxLocation = StrCast(linkFollowDocs[0].maximizeLocation, "inTab");
+ let targetContext = !Doc.AreProtosEqual(linkFollowDocContexts[reverse ? 1 : 0], currentContext) ? linkFollowDocContexts[reverse ? 1 : 0] : undefined;
+ DocumentManager.Instance.jumpToDocument(linkFollowDocs[reverse ? 1 : 0], zoom,
+ // open up target if it's not already in view ... by zooming into the button document first and setting flag to reset zoom afterwards
+ (doc: Doc) => focus(doc, maxLocation), targetContext);
+ }
+ }
+
@action
zoomIntoScale = (docDelegate: Doc, scale: number) => {
let docView = DocumentManager.Instance.getDocumentView(Doc.GetProto(docDelegate));
@@ -202,8 +204,7 @@ export class DocumentManager {
getScaleOfDocView = (docDelegate: Doc) => {
let doc = Doc.GetProto(docDelegate);
- let docView: DocumentView | null;
- docView = DocumentManager.Instance.getDocumentView(doc);
+ const docView = DocumentManager.Instance.getDocumentView(doc);
if (docView) {
return docView.props.getScale();
} else {
diff --git a/src/client/util/RichTextSchema.tsx b/src/client/util/RichTextSchema.tsx
index 64821d8db..49bd93942 100644
--- a/src/client/util/RichTextSchema.tsx
+++ b/src/client/util/RichTextSchema.tsx
@@ -627,17 +627,16 @@ export class ImageResizeView {
let jumpToDoc = await Cast(linkDoc.anchor2, Doc);
if (jumpToDoc) {
if (DocumentManager.Instance.getDocumentView(jumpToDoc)) {
-
- DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, undefined, NumCast((jumpToDoc === linkDoc.anchor2 ? linkDoc.anchor2Page : linkDoc.anchor1Page)));
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey);
return;
}
}
if (targetContext) {
- DocumentManager.Instance.jumpToDocument(targetContext, e.ctrlKey, false, document => addDocTab(document, undefined, location ? location : "inTab"));
+ DocumentManager.Instance.jumpToDocument(targetContext, e.ctrlKey, document => addDocTab(document, undefined, location ? location : "inTab"));
} else if (jumpToDoc) {
- DocumentManager.Instance.jumpToDocument(jumpToDoc, e.ctrlKey, false, document => addDocTab(document, undefined, location ? location : "inTab"));
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, e.ctrlKey, document => addDocTab(document, undefined, location ? location : "inTab"));
} else {
- DocumentManager.Instance.jumpToDocument(linkDoc, e.ctrlKey, false, document => addDocTab(document, undefined, location ? location : "inTab"));
+ DocumentManager.Instance.jumpToDocument(linkDoc, e.ctrlKey, document => addDocTab(document, undefined, location ? location : "inTab"));
}
}
});
diff --git a/src/client/util/SharingManager.tsx b/src/client/util/SharingManager.tsx
index f427e40b1..1cde2aa8e 100644
--- a/src/client/util/SharingManager.tsx
+++ b/src/client/util/SharingManager.tsx
@@ -192,7 +192,7 @@ export default class SharingManager extends React.Component<{}> {
onClick={() => {
let context: Opt<CollectionVideoView | CollectionPDFView | CollectionView>;
if (this.targetDoc && this.targetDocView && (context = this.targetDocView.props.ContainingCollectionView)) {
- DocumentManager.Instance.jumpToDocument(this.targetDoc, true, undefined, undefined, undefined, context.props.Document);
+ DocumentManager.Instance.jumpToDocument(this.targetDoc, true, undefined, context.props.Document);
}
}}
onPointerEnter={action(() => {
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index e928887e2..38d050e5c 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -5,7 +5,7 @@ import { Doc, DocListCast } from '../../../new_fields/Doc';
import { Id } from '../../../new_fields/FieldSymbols';
import { List } from '../../../new_fields/List';
import { listSpec } from '../../../new_fields/Schema';
-import { BoolCast, Cast, NumCast, PromiseValue, StrCast } from '../../../new_fields/Types';
+import { BoolCast, Cast, NumCast, PromiseValue, StrCast, FieldValue } from '../../../new_fields/Types';
import { DocumentManager } from '../../util/DocumentManager';
import { SelectionManager } from '../../util/SelectionManager';
import { ContextMenu } from '../ContextMenu';
@@ -130,8 +130,11 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
let value = Cast(targetDataDoc[targetField], listSpec(Doc), []);
let index = value.reduce((p, v, i) => (v instanceof Doc && v === doc) ? i : p, -1);
index = index !== -1 ? index : value.reduce((p, v, i) => (v instanceof Doc && Doc.AreProtosEqual(v, doc)) ? i : p, -1);
- PromiseValue(Cast(doc.annotationOn, Doc)).then(annotationOn =>
- annotationOn === this.dataDoc.Document && (doc.annotationOn = undefined));
+ PromiseValue(Cast(doc.annotationOn, Doc)).then(annotationOn => {
+ if (Doc.AreProtosEqual(annotationOn, FieldValue(Cast(this.dataDoc.extendsDoc, Doc)))) {
+ Doc.GetProto(doc).annotationOn = undefined;
+ }
+ });
if (index !== -1) {
value.splice(index, 1);
diff --git a/src/client/views/collections/CollectionDockingView.tsx b/src/client/views/collections/CollectionDockingView.tsx
index 98aff41d3..14e513157 100644
--- a/src/client/views/collections/CollectionDockingView.tsx
+++ b/src/client/views/collections/CollectionDockingView.tsx
@@ -574,8 +574,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
let curPres = Cast(CurrentUserUtils.UserDocument.curPresentation, Doc) as Doc;
if (curPres) {
let pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
- Doc.GetProto(pinDoc).target = doc;
- Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.target instanceof Doc) && this.target.title.toString()');
+ Doc.GetProto(pinDoc).presentationTargetDoc = doc;
+ Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.presentationTargetDoc instanceof Doc) && this.presentationTargetDoc.title.toString()');
const data = Cast(curPres.data, listSpec(Doc));
if (data) {
data.push(pinDoc);
@@ -614,8 +614,8 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
}
}
- panelWidth = () => this._document!.ignoreAspect || this._document!.fitWidth ? this._panelWidth : Math.min(this._panelWidth, Math.max(NumCast(this._document!.width), this.nativeWidth()));
- panelHeight = () => this._document!.ignoreAspect || this._document!.fitWidth ? this._panelHeight : Math.min(this._panelHeight, Math.max(NumCast(this._document!.height), this.nativeHeight()));
+ panelWidth = () => this._document && this._document.maxWidth ? Math.min(Math.max(NumCast(this._document.width), NumCast(this._document.nativeWidth)), this._panelWidth) : this._panelWidth;
+ panelHeight = () => this._panelHeight;
nativeWidth = () => !this._document!.ignoreAspect && !this._document!.fitWidth ? NumCast(this._document!.nativeWidth) || this._panelWidth : 0;
nativeHeight = () => !this._document!.ignoreAspect && !this._document!.fitWidth ? NumCast(this._document!.nativeHeight) || this._panelHeight : 0;
@@ -644,7 +644,7 @@ export class DockedFrameRenderer extends React.Component<DockedFrameProps> {
}
return Transform.Identity();
}
- get previewPanelCenteringOffset() { return this.nativeWidth() && !BoolCast(this._document!.ignoreAspect) ? (this._panelWidth - this.nativeWidth() / this.ScreenToLocalTransform().Scale) / 2 : 0; }
+ get previewPanelCenteringOffset() { return this.nativeWidth() && !this._document!.ignoreAspect ? (this._panelWidth - this.nativeWidth() * this.contentScaling()) / 2 : 0; }
addDocTab = (doc: Doc, dataDoc: Opt<Doc>, location: string) => {
SelectionManager.DeselectAll();
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 155f2718b..28d1eb384 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -31,6 +31,7 @@ export interface CollectionViewProps extends FieldViewProps {
moveDocument: (document: Doc, targetCollection: Doc, addDocument: (document: Doc) => boolean) => boolean;
PanelWidth: () => number;
PanelHeight: () => number;
+ VisibleHeight?: () => number;
chromeCollapsed: boolean;
setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void;
}
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index ffd1f9170..882a0f144 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -217,7 +217,7 @@ class TreeView extends React.Component<TreeViewProps> {
if (de.data instanceof DragManager.LinkDragData) {
let sourceDoc = de.data.linkSourceDocument;
let destDoc = this.props.document;
- DocUtils.MakeLink(sourceDoc, destDoc);
+ DocUtils.MakeLink({doc:sourceDoc}, {doc:destDoc});
e.stopPropagation();
}
if (de.data instanceof DragManager.DocumentDragData) {
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index eb40e0bcb..4bdede48a 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -403,8 +403,13 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
SelectionManager.DeselectAll();
if (this.props.Document.scrollHeight) {
let annotOn = Cast(doc.annotationOn, Doc) as Doc;
- let offset = annotOn && (NumCast(annotOn.height) / 2 * 72 / 96);
- this.props.Document.scrollY = NumCast(doc.y) - offset;
+ if (!annotOn) {
+ this.props.focus(doc);
+ } else {
+ let contextHgt = Doc.AreProtosEqual(annotOn, this.props.Document) && this.props.VisibleHeight ? this.props.VisibleHeight() : NumCast(annotOn.height);
+ let offset = annotOn && (contextHgt / 2 * 96 / 72);
+ this.props.Document.scrollY = NumCast(doc.y) - offset;
+ }
} else {
const newPanX = NumCast(doc.x) + NumCast(doc.width) / 2;
const newPanY = NumCast(doc.y) + NumCast(doc.height) / 2;
@@ -416,6 +421,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
this.setPan(newPanX, newPanY);
this.Document.panTransformType = "Ease";
+ Doc.BrushDoc(this.props.Document);
this.props.focus(this.props.Document);
willZoom && this.setScaleToZoom(doc, scale);
diff --git a/src/client/views/linking/LinkFollowBox.tsx b/src/client/views/linking/LinkFollowBox.tsx
index 72fff8e53..53b720a9e 100644
--- a/src/client/views/linking/LinkFollowBox.tsx
+++ b/src/client/views/linking/LinkFollowBox.tsx
@@ -171,7 +171,7 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
@undoBatch
openFullScreen = () => {
if (LinkFollowBox.destinationDoc) {
- let view: DocumentView | null = DocumentManager.Instance.getDocumentView(LinkFollowBox.destinationDoc);
+ let view = DocumentManager.Instance.getDocumentView(LinkFollowBox.destinationDoc);
view && CollectionDockingView.Instance && CollectionDockingView.Instance.OpenFullScreen(view);
}
}
@@ -250,10 +250,10 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
let dockingFunc = (document: Doc) => { (LinkFollowBox._addDocTab || this.props.addDocTab)(document, undefined, "inTab"); SelectionManager.DeselectAll(); };
if (LinkFollowBox.destinationDoc === LinkFollowBox.linkDoc.anchor2 && targetContext) {
- DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, false, async document => dockingFunc(document), undefined, targetContext);
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, async document => dockingFunc(document), targetContext);
}
else if (LinkFollowBox.destinationDoc === LinkFollowBox.linkDoc.anchor1 && sourceContext) {
- DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, false, document => dockingFunc(sourceContext!));
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, document => dockingFunc(sourceContext!));
if (LinkFollowBox.sourceDoc && LinkFollowBox.destinationDoc) {
if (guid) {
let views = DocumentManager.Instance.getDocumentViews(jumpToDoc);
@@ -264,12 +264,11 @@ export class LinkFollowBox extends React.Component<FieldViewProps> {
}
}
else if (DocumentManager.Instance.getDocumentView(jumpToDoc)) {
- DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, undefined, undefined,
- NumCast((LinkFollowBox.destinationDoc === LinkFollowBox.linkDoc.anchor2 ? LinkFollowBox.linkDoc.anchor2Page : LinkFollowBox.linkDoc.anchor1Page)));
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom);
}
else {
- DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, false, dockingFunc);
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, shouldZoom, dockingFunc);
}
this.highlightDoc();
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a903f8fe2..3273abc1d 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -206,7 +206,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
buttonClick = async (altKey: boolean, ctrlKey: boolean) => {
let maximizedDocs = await DocListCastAsync(this.props.Document.maximizedDocs);
let summarizedDocs = await DocListCastAsync(this.props.Document.summarizedDocs);
- let linkedDocs = LinkManager.Instance.getAllRelatedLinks(this.props.Document);
+ let linkDocs = LinkManager.Instance.getAllRelatedLinks(this.props.Document);
let expandedDocs: Doc[] = [];
expandedDocs = maximizedDocs ? [...maximizedDocs, ...expandedDocs] : expandedDocs;
expandedDocs = summarizedDocs ? [...summarizedDocs, ...expandedDocs] : expandedDocs;
@@ -223,28 +223,10 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
expandedDocs.forEach(maxDoc => (!this.props.addDocTab(maxDoc, undefined, "close") && this.props.addDocTab(maxDoc, undefined, maxLocation)));
}
}
- else if (linkedDocs.length) {
- SelectionManager.DeselectAll();
- let first = linkedDocs.filter(d => Doc.AreProtosEqual(d.anchor1 as Doc, this.props.Document) && !d.anchor1anchored);
- let second = linkedDocs.filter(d => Doc.AreProtosEqual(d.anchor2 as Doc, this.props.Document) && !d.anchor2anchored);
- let firstUnshown = first.filter(d => DocumentManager.Instance.getDocumentViews(d.anchor2 as Doc).length === 0);
- let secondUnshown = second.filter(d => DocumentManager.Instance.getDocumentViews(d.anchor1 as Doc).length === 0);
- if (firstUnshown.length) first = [firstUnshown[0]];
- if (secondUnshown.length) second = [secondUnshown[0]];
- let linkedFwdDocs = first.length ? [first[0].anchor2 as Doc, first[0].anchor1 as Doc] : second.length ? [second[0].anchor1 as Doc, second[0].anchor1 as Doc] : undefined;
-
- // @TODO: shouldn't always follow target context
- let linkedFwdContextDocs = [first.length ? await (first[0].targetContext) as Doc : undefined, undefined];
- let linkedFwdPage = [first.length ? NumCast(first[0].anchor2Page, undefined) : undefined, undefined];
-
- if (linkedFwdDocs && !linkedFwdDocs.some(l => l instanceof Promise)) {
- let maxLocation = StrCast(linkedFwdDocs[0].maximizeLocation, "inTab");
- let targetContext = !Doc.AreProtosEqual(linkedFwdContextDocs[altKey ? 1 : 0], this.props.ContainingCollectionDoc) ? linkedFwdContextDocs[altKey ? 1 : 0] : undefined;
- DocumentManager.Instance.jumpToDocument(linkedFwdDocs[altKey ? 1 : 0], ctrlKey, false,
- // open up target if it's not already in view ... by zooming into the button document first and setting flag to reset zoom afterwards
- doc => this.props.focus(this.props.Document, true, 1, () => this.props.addDocTab(doc, undefined, maxLocation)),
- linkedFwdPage[altKey ? 1 : 0], targetContext);
- }
+ else if (linkDocs.length) {
+ DocumentManager.Instance.FollowLink(this.props.Document,
+ (doc: Doc, maxLocation: string) => this.props.focus(this.props.Document, true, 1, () => this.props.addDocTab(doc, undefined, maxLocation)),
+ ctrlKey, altKey, this.props.ContainingCollectionDoc);
}
}
@@ -352,15 +334,9 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
if (de.data instanceof DragManager.AnnotationDragData) {
/// this whole section for handling PDF annotations looks weird. Need to rethink this to make it cleaner
e.stopPropagation();
- let sourceDoc = de.data.annotationDocument;
- let targetDoc = this.props.Document;
- let annotations = await DocListCastAsync(sourceDoc.annotations);
- sourceDoc.linkedToDoc = true;
- de.data.targetContext = this.props.ContainingCollectionDoc;
- targetDoc.targetContext = de.data.targetContext;
- annotations && annotations.forEach(anno => anno.target = targetDoc);
-
- DocUtils.MakeLink(sourceDoc, targetDoc, this.props.ContainingCollectionDoc, `Link from ${StrCast(sourceDoc.title)}`);
+ (de.data as any).linkedToDoc = true;
+
+ DocUtils.MakeLink({ doc: de.data.annotationDocument }, { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, `Link from ${StrCast(de.data.annotationDocument.title)}`);
}
if (de.data instanceof DragManager.DocumentDragData && de.data.applyAsTemplate) {
Doc.ApplyTemplateTo(de.data.draggedDocuments[0], this.props.Document);
@@ -371,7 +347,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
// const docs = await SearchUtil.Search(`data_l:"${destDoc[Id]}"`, true);
// const views = docs.map(d => DocumentManager.Instance.getDocumentView(d)).filter(d => d).map(d => d as DocumentView);
de.data.linkSourceDocument !== this.props.Document &&
- (de.data.linkDocument = DocUtils.MakeLink(de.data.linkSourceDocument, this.props.Document, this.props.ContainingCollectionDoc, undefined, "in-text link being created")); // TODODO this is where in text links get passed
+ (de.data.linkDocument = DocUtils.MakeLink({ doc: de.data.linkSourceDocument }, { doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, "in-text link being created")); // TODODO this is where in text links get passed
}
}
@@ -407,7 +383,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
let portalID = (this.Document.title + ".portal").replace(/^-/, "").replace(/\([0-9]*\)$/, "");
DocServer.GetRefField(portalID).then(existingPortal => {
let portal = existingPortal instanceof Doc ? existingPortal : Docs.Create.FreeformDocument([], { width: (this.Document.width || 0) + 10, height: this.Document.height || 0, title: portalID });
- DocUtils.MakeLink(this.props.Document, portal, undefined, portalID);
+ DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: portal }, portalID, "portal link");
this.Document.isButton = true;
});
}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index 449f56b16..749886d9a 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -9,7 +9,7 @@ import { Fragment, Node, Node as ProsNode, NodeType, Slice, Mark, ResolvedPos }
import { EditorState, Plugin, Transaction, TextSelection, NodeSelection } from "prosemirror-state";
import { EditorView } from "prosemirror-view";
import { DateField } from '../../../new_fields/DateField';
-import { Doc, DocListCast, Opt, WidthSym } from "../../../new_fields/Doc";
+import { Doc, DocListCast, Opt, WidthSym, DocListCastAsync } from "../../../new_fields/Doc";
import { Copy, Id } from '../../../new_fields/FieldSymbols';
import { List } from '../../../new_fields/List';
import { RichTextField } from "../../../new_fields/RichTextField";
@@ -230,7 +230,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
this.dataDoc[key] = doc || Docs.Create.FreeformDocument([], { title: value, width: 500, height: 500 }, value);
DocUtils.Publish(this.dataDoc[key] as Doc, value, this.props.addDocument, this.props.removeDocument);
if (linkDoc) { (linkDoc as Doc).anchor2 = this.dataDoc[key] as Doc; }
- else DocUtils.MakeLink(this.dataDoc, this.dataDoc[key] as Doc, undefined, "Ref:" + value, undefined, undefined, id, true);
+ else DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: this.dataDoc[key] as Doc }, "Ref:" + value, "link to named target", id, true);
});
});
});
@@ -342,7 +342,7 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
let model: NodeType = [".mov", ".mp4"].includes(url) ? schema.nodes.video : schema.nodes.image;
let pos = this._editorView!.posAtCoords({ left: de.x, top: de.y });
this._editorView!.dispatch(this._editorView!.state.tr.insert(pos!.pos, model.create({ src: url, docid: target[Id] })));
- DocUtils.MakeLink(this.dataDoc, target, undefined, "ImgRef:" + target.title, undefined, undefined, target[Id]);
+ DocUtils.MakeLink({ doc: this.dataDoc, ctx: this.props.ContainingCollectionDoc }, { doc: target }, "ImgRef:" + target.title);
this.tryUpdateHeight();
e.stopPropagation();
} else if (de.data instanceof DragManager.DocumentDragData) {
@@ -667,55 +667,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");
- regionId = cbe.clipboardData.getData("dash/pdfRegion");
- if (!docId || !regionId) {
- return false;
- }
-
- DocServer.GetRefField(docId).then(doc => {
- 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.fieldExtensionDoc(doc, "data");
- let targetAnnotations = DocListCast(fieldExtDoc.annotations);
- if (targetAnnotations) {
- targetAnnotations.push(region);
- fieldExtDoc.annotations = new List<Doc>(targetAnnotations);
- }
+ const pdfDocId = cbe.clipboardData && cbe.clipboardData.getData("dash/pdfOrigin");
+ const pdfRegionId = cbe.clipboardData && cbe.clipboardData.getData("dash/pdfRegion");
+ if (pdfDocId && pdfRegionId) {
+ DocServer.GetRefField(pdfDocId).then(pdfDoc => {
+ DocServer.GetRefField(pdfRegionId).then(pdfRegion => {
+ if ((pdfDoc instanceof Doc) && (pdfRegion instanceof Doc)) {
+ setTimeout(async () => {
+ let targetAnnotations = await DocListCastAsync(Doc.fieldExtensionDoc(pdfDoc, "data").annotations);// bcz: NO... this assumes the pdf is using its 'data' field. need to have the PDF's view handle updating its own annotations
+ targetAnnotations && targetAnnotations.push(pdfRegion);
+ });
- let link = DocUtils.MakeLink(this.props.Document, region, doc);
- if (link) {
- cbe.clipboardData!.setData("dash/linkDoc", link[Id]);
- linkId = link[Id];
- let frag = addMarkToFrag(slice.content, (node: Node) => addLinkMark(node, StrCast(doc.title)));
- 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"));
- }
+ let link = DocUtils.MakeLink({ doc: this.props.Document, ctx: this.props.ContainingCollectionDoc }, { doc: pdfRegion, ctx: pdfDoc }, "note on " + pdfDoc.title, "pasted PDF link");
+ if (link) {
+ cbe.clipboardData!.setData("dash/linkDoc", link[Id]);
+ let linkId = link[Id];
+ let frag = addMarkToFrag(slice.content, (node: Node) => addLinkMark(node, StrCast(pdfDoc.title), linkId));
+ 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;
+ }
+ return false;
- return true;
function addMarkToFrag(frag: Fragment, marker: (node: Node) => Node) {
const nodes: Node[] = [];
frag.forEach(node => nodes.push(marker(node)));
return Fragment.fromArray(nodes);
}
- function addLinkMark(node: Node, title: string) {
+ function addLinkMark(node: Node, title: string, linkId: string) {
if (!node.isText) {
- const content = addMarkToFrag(node.content, (node: Node) => addLinkMark(node, title));
+ const content = addMarkToFrag(node.content, (node: Node) => addLinkMark(node, title, linkId));
return node.copy(content);
}
const marks = [...node.marks];
@@ -879,16 +866,16 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
if (jumpToDoc) {
if (DocumentManager.Instance.getDocumentView(jumpToDoc)) {
- DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey, undefined, undefined, NumCast((jumpToDoc === linkDoc.anchor2 ? linkDoc.anchor2Page : linkDoc.anchor1Page)));
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, e.altKey);
return;
}
}
if (targetContext && (!jumpToDoc || targetContext !== await jumpToDoc.annotationOn)) {
- DocumentManager.Instance.jumpToDocument(jumpToDoc || targetContext, ctrlKey, false, document => this.props.addDocTab(document, undefined, location ? location : "inTab"), undefined, targetContext);
+ DocumentManager.Instance.jumpToDocument(jumpToDoc || targetContext, ctrlKey, document => this.props.addDocTab(document, undefined, location ? location : "inTab"), targetContext);
} else if (jumpToDoc) {
- DocumentManager.Instance.jumpToDocument(jumpToDoc, ctrlKey, false, document => this.props.addDocTab(document, undefined, location ? location : "inTab"));
+ DocumentManager.Instance.jumpToDocument(jumpToDoc, ctrlKey, document => this.props.addDocTab(document, undefined, location ? location : "inTab"));
} else {
- DocumentManager.Instance.jumpToDocument(linkDoc, ctrlKey, false, document => this.props.addDocTab(document, undefined, location ? location : "inTab"));
+ DocumentManager.Instance.jumpToDocument(linkDoc, ctrlKey, document => this.props.addDocTab(document, undefined, location ? location : "inTab"));
}
}
});
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 9e9fe1324..fe4f75cad 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -299,7 +299,7 @@ export class ImageBox extends DocComponent<FieldViewProps, ImageDocument>(ImageD
let rotation = NumCast(this.dataDoc.rotation) % 180;
let realsize = rotation === 90 || rotation === 270 ? { height: size.width, width: size.height } : size;
let aspect = realsize.height / realsize.width;
- if (layoutdoc.nativeHeight !== 0 && layoutdoc.nativeWidth !== 0 && (Math.abs(NumCast(layoutdoc.height) - realsize.height) > 1 || Math.abs(NumCast(layoutdoc.width) - realsize.width) > 1)) {
+ if (layoutdoc.nativeHeight !== 0 && layoutdoc.nativeWidth !== 0 && (Math.abs(1 - NumCast(layoutdoc.nativeHeight) / NumCast(layoutdoc.nativeWidth) / (realsize.height / realsize.width)) > 0.1)) {
setTimeout(action(() => {
layoutdoc.height = layoutdoc[WidthSym]() * aspect;
layoutdoc.nativeHeight = realsize.height;
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 617b580dd..88cd2cdc4 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -57,11 +57,8 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
}
loaded = (nw: number, nh: number, np: number) => {
this.dataDoc.numPages = np;
- if (!this.Document.nativeWidth || !this.Document.nativeHeight || !this.Document.scrollHeight) {
- let oldaspect = (this.Document.nativeHeight || 0) / (this.Document.nativeWidth || 1);
- this.Document.nativeWidth = nw * 96 / 72;
- this.Document.nativeHeight = this.Document.nativeHeight ? nw * 96 / 72 * oldaspect : nh * 96 / 72;
- }
+ this.Document.nativeWidth = nw * 96 / 72;
+ this.Document.nativeHeight = nh * 96 / 72;
!this.Document.fitWidth && !this.Document.ignoreAspect && (this.Document.height = this.Document[WidthSym]() * (nh / nw));
}
@@ -177,12 +174,14 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
ContextMenu.Instance.addItem({ description: "Pdf Funcs...", subitems: funcs, icon: "asterisk" });
}
+ _initialScale: number | undefined;
render() {
const pdfUrl = Cast(this.dataDoc[this.props.fieldKey], PdfField);
let classname = "pdfBox-cont" + (InkingControl.Instance.selectedTool || !this.active ? "" : "-interactive");
let noPdf = !(pdfUrl instanceof PdfField) || !this._pdf;
- if (!noPdf && (this.props.isSelected() || this.props.ScreenToLocalTransform().Scale < 2.5)) this._everActive = true;
- return (!this._everActive ?
+ if (this._initialScale === undefined) this._initialScale = this.props.ScreenToLocalTransform().Scale;
+ if (this.props.isSelected() || this.props.Document.scrollY !== undefined) this._everActive = true;
+ return (noPdf || (!this._everActive && this.props.ScreenToLocalTransform().Scale > 2.5) ?
<div className="pdfBox-title-outer" >
<div className={classname} >
<strong className="pdfBox-title" >{` ${this.props.Document.title}`}</strong>
@@ -203,11 +202,11 @@ export class PDFBox extends DocComponent<FieldViewProps, PdfDocument>(PdfDocumen
setPdfViewer={this.setPdfViewer} ContainingCollectionView={this.props.ContainingCollectionView}
renderDepth={this.props.renderDepth} PanelHeight={this.props.PanelHeight} PanelWidth={this.props.PanelWidth}
Document={this.props.Document} DataDoc={this.dataDoc} ContentScaling={this.props.ContentScaling}
- addDocTab={this.props.addDocTab} GoToPage={this.gotoPage}
+ addDocTab={this.props.addDocTab} GoToPage={this.gotoPage} focus={this.props.focus}
pinToPres={this.props.pinToPres} addDocument={this.props.addDocument}
ScreenToLocalTransform={this.props.ScreenToLocalTransform} select={this.props.select}
isSelected={this.props.isSelected} whenActiveChanged={this.whenActiveChanged}
- fieldKey={this.props.fieldKey} fieldExtensionDoc={this.extensionDoc} startupLive={this.props.ScreenToLocalTransform().Scale < 2.5 ? true : false} />
+ fieldKey={this.props.fieldKey} fieldExtensionDoc={this.extensionDoc} startupLive={this._initialScale < 2.5 ? true : false} />
{this.settingsPanel()}
</div>);
}
diff --git a/src/client/views/nodes/PresBox.tsx b/src/client/views/nodes/PresBox.tsx
index f44ca99b9..180ed9032 100644
--- a/src/client/views/nodes/PresBox.tsx
+++ b/src/client/views/nodes/PresBox.tsx
@@ -43,8 +43,8 @@ export class PresBox extends React.Component<FieldViewProps> {
value.forEach((item, i) => {
if (item instanceof Doc && item.type !== DocumentType.PRESELEMENT) {
let pinDoc = Docs.Create.PresElementBoxDocument({ backgroundColor: "transparent" });
- Doc.GetProto(pinDoc).target = item;
- Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.target instanceof Doc) && this.target.title.toString()');
+ Doc.GetProto(pinDoc).presentationTargetDoc = item;
+ Doc.GetProto(pinDoc).title = ComputedField.MakeFunction('(this.presentationTargetDoc instanceof Doc) && this.presentationTargetDoc.title.toString()');
value.splice(i, 1, pinDoc);
}
});
@@ -124,13 +124,13 @@ export class PresBox extends React.Component<FieldViewProps> {
this.childDocs.forEach((doc, ind) => {
//the order of cases is aligned based on priority
if (doc.hideTillShownButton && ind <= index) {
- (doc.target as Doc).opacity = 1;
+ (doc.presentationTargetDoc as Doc).opacity = 1;
}
if (doc.hideAfterButton && ind < index) {
- (doc.target as Doc).opacity = 0;
+ (doc.presentationTargetDoc as Doc).opacity = 0;
}
if (doc.fadeButton && ind < index) {
- (doc.target as Doc).opacity = 0.5;
+ (doc.presentationTargetDoc as Doc).opacity = 0.5;
}
});
}
@@ -145,13 +145,13 @@ export class PresBox extends React.Component<FieldViewProps> {
//the order of cases is aligned based on priority
if (key.hideAfterButton && ind >= index) {
- (key.target as Doc).opacity = 1;
+ (key.presentationTargetDoc as Doc).opacity = 1;
}
if (key.fadeButton && ind >= index) {
- (key.target as Doc).opacity = 1;
+ (key.presentationTargetDoc as Doc).opacity = 1;
}
if (key.hideTillShownButton && ind > index) {
- (key.target as Doc).opacity = 0;
+ (key.presentationTargetDoc as Doc).opacity = 0;
}
});
}
@@ -162,7 +162,7 @@ export class PresBox extends React.Component<FieldViewProps> {
* te option open, navigates to that element.
*/
navigateToElement = async (curDoc: Doc, fromDocIndex: number) => {
- let fromDoc = this.childDocs[fromDocIndex].target as Doc;
+ let fromDoc = this.childDocs[fromDocIndex].presentationTargetDoc as Doc;
let docToJump = curDoc;
let willZoom = false;
@@ -190,7 +190,7 @@ export class PresBox extends React.Component<FieldViewProps> {
//docToJump stayed same meaning, it was not in the group or was the last element in the group
if (docToJump === curDoc) {
//checking if curDoc has navigation open
- let target = await curDoc.target as Doc;
+ let target = await curDoc.presentationTargetDoc as Doc;
if (curDoc.navButton) {
DocumentManager.Instance.jumpToDocument(target, false);
} else if (curDoc.showButton) {
@@ -210,8 +210,8 @@ export class PresBox extends React.Component<FieldViewProps> {
let curScale = DocumentManager.Instance.getScaleOfDocView(fromDoc);
//awaiting jump so that new scale can be found, since jumping is async
- await DocumentManager.Instance.jumpToDocument(await docToJump.target as Doc, willZoom);
- let newScale = DocumentManager.Instance.getScaleOfDocView(await curDoc.target as Doc);
+ await DocumentManager.Instance.jumpToDocument(await docToJump.presentationTargetDoc as Doc, willZoom);
+ let newScale = DocumentManager.Instance.getScaleOfDocView(await curDoc.presentationTargetDoc as Doc);
curDoc.viewScale = newScale;
//saving the scale that user was on
if (curScale !== 1) {
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index b7d9a1eab..573197117 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -129,7 +129,7 @@ export class VideoBox extends DocComponent<FieldViewProps, VideoDocument>(VideoD
width: 150, height: height / width * 150, title: "--snapshot" + NumCast(this.props.Document.curPage) + " image-"
});
this.props.ContainingCollectionView && this.props.ContainingCollectionView.props.addDocument && this.props.ContainingCollectionView.props.addDocument(imageSummary, false);
- DocUtils.MakeLink(imageSummary, this.props.Document);
+ DocUtils.MakeLink({doc:imageSummary}, {doc: this.props.Document}, "snapshot from " + this.props.Document.title, "video frame snapshot");
}
});
}
diff --git a/src/client/views/pdf/Annotation.tsx b/src/client/views/pdf/Annotation.tsx
index 3ed85f6a5..f7f52b3ef 100644
--- a/src/client/views/pdf/Annotation.tsx
+++ b/src/client/views/pdf/Annotation.tsx
@@ -1,7 +1,7 @@
import React = require("react");
import { action, IReactionDisposer, observable, reaction, runInAction } from "mobx";
import { observer } from "mobx-react";
-import { Doc, DocListCast, HeightSym, WidthSym, Opt } from "../../../new_fields/Doc";
+import { Doc, DocListCast, HeightSym, WidthSym, Opt, DocListCastAsync } from "../../../new_fields/Doc";
import { Id } from "../../../new_fields/FieldSymbols";
import { List } from "../../../new_fields/List";
import { Cast, FieldValue, NumCast, StrCast } from "../../../new_fields/Types";
@@ -14,6 +14,7 @@ interface IAnnotationProps {
fieldExtensionDoc: Doc;
addDocTab: (document: Doc, dataDoc: Opt<Doc>, where: string) => boolean;
pinToPres: (document: Doc) => void;
+ focus: (doc: Doc) => void;
}
export default class Annotation extends React.Component<IAnnotationProps> {
@@ -60,6 +61,7 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
}
componentWillUnmount() {
+ this._brushDisposer && this._brushDisposer();
this._reactionDisposer && this._reactionDisposer();
}
@@ -94,14 +96,11 @@ class RegionAnnotation extends React.Component<IRegionAnnotationProps> {
PDFMenu.Instance.jumpTo(e.clientX, e.clientY, true);
}
else if (e.button === 0) {
- let targetDoc = await Cast(this.props.document.target, Doc);
- if (targetDoc) {
- let context = await Cast(targetDoc.targetContext, Doc);
- if (context) {
- DocumentManager.Instance.jumpToDocument(targetDoc, false, false,
- ((doc) => this.props.addDocTab(targetDoc!, undefined, e.ctrlKey ? "onRight" : "inTab")),
- undefined, undefined);
- }
+ let annoGroup = await Cast(this.props.document.group, Doc);
+ if (annoGroup) {
+ DocumentManager.Instance.FollowLink(annoGroup,
+ (doc: Doc, maxLocation: string) => this.props.addDocTab(doc, undefined, e.ctrlKey ? "onRight" : "inTab"),
+ false, false, undefined);
}
}
}
diff --git a/src/client/views/pdf/PDFMenu.tsx b/src/client/views/pdf/PDFMenu.tsx
index 2202351ee..e62542014 100644
--- a/src/client/views/pdf/PDFMenu.tsx
+++ b/src/client/views/pdf/PDFMenu.tsx
@@ -31,7 +31,7 @@ export default class PDFMenu extends React.Component {
@observable public Pinned: boolean = false;
public StartDrag: (e: PointerEvent, ele: HTMLElement) => void = emptyFunction;
- public Highlight: (d: Doc | undefined, color: string) => void = emptyFunction;
+ public Highlight: (color: string) => void = emptyFunction;
public Delete: () => void = emptyFunction;
public Snippet: (marquee: { left: number, top: number, width: number, height: number }) => void = emptyFunction;
public AddTag: (key: string, value: string) => boolean = returnFalse;
@@ -156,11 +156,11 @@ export default class PDFMenu extends React.Component {
@action
highlightClicked = (e: React.MouseEvent) => {
if (!this.Pinned) {
- this.Highlight(undefined, "#f4f442");
+ this.Highlight("#f4f442");
}
else {
this.Highlighting = !this.Highlighting;
- this.Highlight(undefined, "#f4f442");
+ this.Highlight("#f4f442");
}
}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index 33226eac4..20dfc4d8c 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -10,7 +10,6 @@ import { listSpec } from "../../../new_fields/Schema";
import { ScriptField } from "../../../new_fields/ScriptField";
import { Cast, NumCast, StrCast } from "../../../new_fields/Types";
import smoothScroll, { Utils, emptyFunction, returnOne } from "../../../Utils";
-import { DocServer } from "../../DocServer";
import { Docs, DocUtils } from "../../documents/Documents";
import { DragManager } from "../../util/DragManager";
import { CompiledScript, CompileScript } from "../../util/Scripting";
@@ -44,6 +43,7 @@ interface IViewerProps {
select: (isCtrlPressed: boolean) => void;
startupLive: boolean;
renderDepth: number;
+ focus: (doc: Doc) => void;
isSelected: () => boolean;
loaded: (nw: number, nh: number, np: number) => void;
active: () => boolean;
@@ -108,7 +108,8 @@ export class PDFViewer extends React.Component<IViewerProps> {
// file address of the pdf
this._coverPath = JSON.parse(await rp.get(Utils.prepend(`/thumbnail${this.props.url.substring("files/".length, this.props.url.length - ".pdf".length)}-${NumCast(this.props.Document.curPage, 1)}.PNG`)));
runInAction(() => this._showWaiting = this._showCover = true);
- this._selectionReactionDisposer = reaction(() => this.props.isSelected(), () => this.props.isSelected() && SelectionManager.SelectedDocuments().length === 1 && this.setupPdfJsViewer(), { fireImmediately: this.props.startupLive });
+ this.props.startupLive && this.setupPdfJsViewer();
+ this._selectionReactionDisposer = reaction(() => this.props.isSelected(), () => (this.props.isSelected() && SelectionManager.SelectedDocuments().length === 1) && this.setupPdfJsViewer(), { fireImmediately: true });
this._reactionDisposer = reaction(
() => this.props.Document.scrollY,
(scrollY) => {
@@ -136,19 +137,11 @@ export class PDFViewer extends React.Component<IViewerProps> {
if (this.props.active() && e.clipboardData) {
e.clipboardData.setData("text/plain", this._selectionText);
e.clipboardData.setData("dash/pdfOrigin", this.props.Document[Id]);
- e.clipboardData.setData("dash/pdfRegion", this.makeAnnotationDocument(undefined, "#0390fc")[Id]);
+ e.clipboardData.setData("dash/pdfRegion", this.makeAnnotationDocument("#0390fc")[Id]);
e.preventDefault();
}
}
- paste = (e: ClipboardEvent) => {
- if (e.clipboardData && e.clipboardData.getData("dash/pdfOrigin") === this.props.Document[Id]) {
- let linkDocId = e.clipboardData.getData("dash/linkDoc");
- linkDocId && DocServer.GetRefField(linkDocId).then(async (link) =>
- (link instanceof Doc) && (Doc.GetProto(link).anchor2 = this.makeAnnotationDocument(await Cast(Doc.GetProto(link), Doc), "#0390fc", false)));
- }
- }
-
setSelectionText = (text: string) => this._selectionText = text;
@action
@@ -194,13 +187,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
{ fireImmediately: true }
);
- document.removeEventListener("copy", this.copy);
- document.addEventListener("copy", this.copy);
- document.addEventListener("pagesinit", action(() => {
- this.pdfViewer.currentScaleValue = this._zoomed = 1;
- this.gotoPage(NumCast(this.props.Document.curPage, 1));
- }));
- document.addEventListener("pagerendered", action(() => this._showCover = this._showWaiting = false));
this.createPdfViewer();
}
@@ -212,6 +198,13 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
return;
}
+ document.removeEventListener("copy", this.copy);
+ document.addEventListener("copy", this.copy);
+ document.addEventListener("pagesinit", action(() => {
+ this.pdfViewer.currentScaleValue = this._zoomed = 1;
+ this.gotoPage(NumCast(this.props.Document.curPage, 1));
+ }));
+ document.addEventListener("pagerendered", action(() => this._showCover = this._showWaiting = false));
var pdfLinkService = new PDFJSViewer.PDFLinkService();
let pdfFindController = new PDFJSViewer.PDFFindController({
linkService: pdfLinkService,
@@ -229,19 +222,18 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
@action
- makeAnnotationDocument = (sourceDoc: Doc | undefined, color: string, createLink: boolean = true): Doc => {
+ makeAnnotationDocument = (color: string): Doc => {
let mainAnnoDoc = Docs.Create.InstanceFromProto(new Doc(), "", {});
let mainAnnoDocProto = Doc.GetProto(mainAnnoDoc);
let annoDocs: Doc[] = [];
let minY = Number.MAX_VALUE;
- if (this._savedAnnotations.size() === 1 && this._savedAnnotations.values()[0].length === 1 && !createLink) {
+ if (this._savedAnnotations.size() === 1 && this._savedAnnotations.values()[0].length === 1) {
let anno = this._savedAnnotations.values()[0][0];
let annoDoc = Docs.Create.FreeformDocument([], { backgroundColor: "rgba(255, 0, 0, 0.1)", title: "Annotation on " + StrCast(this.props.Document.title) });
if (anno.style.left) annoDoc.x = parseInt(anno.style.left);
if (anno.style.top) annoDoc.y = parseInt(anno.style.top);
if (anno.style.height) annoDoc.height = parseInt(anno.style.height);
if (anno.style.width) annoDoc.width = parseInt(anno.style.width);
- annoDoc.target = sourceDoc;
annoDoc.group = mainAnnoDoc;
annoDoc.color = color;
annoDoc.type = AnnotationTypes.Region;
@@ -258,7 +250,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
if (anno.style.top) annoDoc.y = parseInt(anno.style.top);
if (anno.style.height) annoDoc.height = parseInt(anno.style.height);
if (anno.style.width) annoDoc.width = parseInt(anno.style.width);
- annoDoc.target = sourceDoc;
annoDoc.group = mainAnnoDoc;
annoDoc.color = color;
annoDoc.type = AnnotationTypes.Region;
@@ -272,9 +263,6 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
mainAnnoDocProto.title = "Annotation on " + StrCast(this.props.Document.title);
mainAnnoDocProto.annotationOn = this.props.Document;
- if (sourceDoc && createLink) {
- DocUtils.MakeLink(sourceDoc, mainAnnoDocProto, undefined, `Annotation from ${StrCast(this.props.Document.title)}`);
- }
this._savedAnnotations.clear();
this.Index = -1;
return mainAnnoDoc;
@@ -529,7 +517,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
if (PDFMenu.Instance.Highlighting) {
- this.highlight(undefined, "goldenrod");
+ this.highlight("goldenrod");
}
else {
PDFMenu.Instance.StartDrag = this.startDrag;
@@ -540,9 +528,9 @@ export class PDFViewer extends React.Component<IViewerProps> {
}
@action
- highlight = (targetDoc: Doc | undefined, color: string) => {
+ highlight = (color: string) => {
// creates annotation documents for current highlights
- let annotationDoc = this.makeAnnotationDocument(targetDoc, color, false);
+ let annotationDoc = this.makeAnnotationDocument(color);
Doc.AddDocToList(this.props.fieldExtensionDoc, this.props.fieldExt, annotationDoc);
return annotationDoc;
}
@@ -555,20 +543,14 @@ export class PDFViewer extends React.Component<IViewerProps> {
startDrag = (e: PointerEvent, ele: HTMLElement): void => {
e.preventDefault();
e.stopPropagation();
- let targetDoc = Docs.Create.TextDocument({ width: 200, height: 200, title: "New Annotation" });
- targetDoc.targetPage = this.getPageFromScroll(this._marqueeY);
- let annotationDoc = this.highlight(undefined, "red");
- annotationDoc.linkedToDoc = false;
+ let targetDoc = Docs.Create.TextDocument({ width: 200, height: 200, title: "Note linked to " + this.props.Document.title });
+ let annotationDoc = this.highlight("red");
let dragData = new DragManager.AnnotationDragData(this.props.Document, annotationDoc, targetDoc);
DragManager.StartAnnotationDrag([ele], dragData, e.pageX, e.pageY, {
handlers: {
- dragComplete: () => {
- if (!annotationDoc.linkedToDoc) {
- let annotations = DocListCast(annotationDoc.annotations);
- annotations && annotations.forEach(anno => anno.target = targetDoc);
- DocUtils.MakeLink(annotationDoc, targetDoc, dragData.targetContext, `Annotation from ${StrCast(this.props.Document.title)}`);
- }
- }
+ dragComplete: () => !(dragData as any).linkedToDoc &&
+ DocUtils.MakeLink({ doc: annotationDoc }, { doc: dragData.dropDocument, ctx: dragData.targetContext }, `Annotation from ${StrCast(this.props.Document.title)}`, "link from PDF")
+
},
hideSource: false
});
@@ -602,6 +584,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
@action.bound
removeDocument(doc: Doc): boolean {
+ Doc.GetProto(doc).annotationOn = undefined;
//TODO This won't create the field if it doesn't already exist
let targetDataDoc = this.props.fieldExtensionDoc;
let targetField = this.props.fieldExt;
@@ -634,10 +617,10 @@ export class PDFViewer extends React.Component<IViewerProps> {
getCoverImage = () => {
if (!this.props.Document[HeightSym]() || !this.props.Document.nativeHeight) {
- setTimeout(() => {
+ setTimeout((() => {
this.props.Document.height = this.props.Document[WidthSym]() * this._coverPath.height / this._coverPath.width;
this.props.Document.nativeHeight = nativeWidth * this._coverPath.height / this._coverPath.width;
- }, 0);
+ }).bind(this), 0);
}
let nativeWidth = NumCast(this.props.Document.nativeWidth);
let nativeHeight = NumCast(this.props.Document.nativeHeight);
@@ -659,7 +642,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
@computed get annotationLayer() {
return <div className="pdfViewer-annotationLayer" style={{ height: NumCast(this.props.Document.nativeHeight) }} ref={this._annotationLayer}>
{this.nonDocAnnotations.sort((a, b) => NumCast(a.y) - NumCast(b.y)).map((anno, index) =>
- <Annotation {...this.props} anno={anno} key={`${anno[Id]}-annotation`} />)}
+ <Annotation {...this.props} focus={this.props.focus} anno={anno} key={`${anno[Id]}-annotation`} />)}
</div>;
}
@computed get pdfViewerDiv() {
@@ -686,7 +669,8 @@ export class PDFViewer extends React.Component<IViewerProps> {
setPreviewCursor={this.setPreviewCursor}
PanelHeight={() => NumCast(this.props.Document.scrollHeight, NumCast(this.props.Document.nativeHeight))}
PanelWidth={() => this._pageSizes.length && this._pageSizes[0] ? this._pageSizes[0].width : NumCast(this.props.Document.nativeWidth)}
- focus={emptyFunction}
+ VisibleHeight={() => this.props.PanelHeight() / this.props.ContentScaling() * 72 / 96}
+ focus={this.props.focus}
isSelected={this.props.isSelected}
select={emptyFunction}
active={this.active}
@@ -694,7 +678,7 @@ export class PDFViewer extends React.Component<IViewerProps> {
whenActiveChanged={this.whenActiveChanged}
removeDocument={this.removeDocument}
moveDocument={this.moveDocument}
- addDocument={(doc: Doc, allow: boolean | undefined) => { Doc.AddDocToList(this.props.fieldExtensionDoc, this.props.fieldExt, doc); return true; }}
+ addDocument={(doc: Doc, allow: boolean | undefined) => { Doc.GetProto(doc).annotationOn = this.props.Document; Doc.AddDocToList(this.props.fieldExtensionDoc, this.props.fieldExt, doc); return true; }}
CollectionView={this.props.ContainingCollectionView}
ScreenToLocalTransform={this.scrollXf}
ruleProvider={undefined}
diff --git a/src/client/views/presentationview/PresElementBox.tsx b/src/client/views/presentationview/PresElementBox.tsx
index de3242d32..daf000dc7 100644
--- a/src/client/views/presentationview/PresElementBox.tsx
+++ b/src/client/views/presentationview/PresElementBox.tsx
@@ -63,13 +63,11 @@ export class PresElementBox extends React.Component<FieldViewProps> {
this.hideTillShownButton = !this.hideTillShownButton;
if (!this.hideTillShownButton) {
if (this.myIndex >= this.currentIndex) {
- (this.props.Document.target as Doc).opacity = 1;
+ (this.props.Document.presentationTargetDoc as Doc).opacity = 1;
}
} else {
- if (this.presentationDoc.presStatus) {
- if (this.myIndex > this.currentIndex) {
- (this.props.Document.target as Doc).opacity = 0;
- }
+ if (this.presentationDoc.presStatus && this.myIndex > this.currentIndex) {
+ (this.props.Document.presentationTargetDoc as Doc).opacity = 0;
}
}
}
@@ -85,14 +83,12 @@ export class PresElementBox extends React.Component<FieldViewProps> {
this.hideAfterButton = !this.hideAfterButton;
if (!this.hideAfterButton) {
if (this.myIndex <= this.currentIndex) {
- (this.props.Document.target as Doc).opacity = 1;
+ (this.props.Document.presentationTargetDoc as Doc).opacity = 1;
}
} else {
if (this.fadeButton) this.fadeButton = false;
- if (this.presentationDoc.presStatus) {
- if (this.myIndex < this.currentIndex) {
- (this.props.Document.target as Doc).opacity = 0;
- }
+ if (this.presentationDoc.presStatus && this.myIndex < this.currentIndex) {
+ (this.props.Document.presentationTargetDoc as Doc).opacity = 0;
}
}
}
@@ -108,14 +104,12 @@ export class PresElementBox extends React.Component<FieldViewProps> {
this.fadeButton = !this.fadeButton;
if (!this.fadeButton) {
if (this.myIndex <= this.currentIndex) {
- (this.props.Document.target as Doc).opacity = 1;
+ (this.props.Document.presentationTargetDoc as Doc).opacity = 1;
}
} else {
this.hideAfterButton = false;
- if (this.presentationDoc.presStatus) {
- if (this.myIndex < this.currentIndex) {
- (this.props.Document.target as Doc).opacity = 0.5;
- }
+ if (this.presentationDoc.presStatus && (this.myIndex < this.currentIndex)) {
+ (this.props.Document.presentationTargetDoc as Doc).opacity = 0.5;
}
}
}
@@ -162,7 +156,7 @@ export class PresElementBox extends React.Component<FieldViewProps> {
* presentation element.
*/
renderEmbeddedInline = () => {
- if (!this.embedOpen || !(this.props.Document.target instanceof Doc)) {
+ if (!this.embedOpen || !(this.props.Document.presentationTargetDoc instanceof Doc)) {
return (null);
}
@@ -175,8 +169,8 @@ export class PresElementBox extends React.Component<FieldViewProps> {
width: propDocWidth === 0 ? "auto" : propDocWidth * scale(),
}}>
<CollectionSchemaPreview
- fitToBox={StrCast(this.props.Document.target.type).indexOf(DocumentType.COL) !== -1}
- Document={this.props.Document.target}
+ fitToBox={StrCast(this.props.Document.presentationTargetDoc.type).indexOf(DocumentType.COL) !== -1}
+ Document={this.props.Document.presentationTargetDoc}
addDocument={returnFalse}
removeDocument={returnFalse}
ruleProvider={undefined}
@@ -205,7 +199,7 @@ export class PresElementBox extends React.Component<FieldViewProps> {
let pbi = "presElementBox-interaction";
return (
<div className={className} key={p.Document[Id] + this.myIndex}
- style={{ outlineWidth: Doc.IsBrushed(p.Document.target as Doc) ? `1px` : "0px", }}
+ style={{ outlineWidth: Doc.IsBrushed(p.Document.presentationTargetDoc as Doc) ? `1px` : "0px", }}
onClick={e => { p.focus(p.Document); e.stopPropagation(); }}>
{treecontainer ? (null) : <>
<strong className="presElementBox-name">
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index aeffc81c4..58304cebb 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -665,10 +665,12 @@ export namespace Doc {
export function BrushDoc(doc: Doc) {
brushManager.BrushedDoc.set(doc, true);
brushManager.BrushedDoc.set(Doc.GetDataDoc(doc), true);
+ return doc;
}
export function UnBrushDoc(doc: Doc) {
brushManager.BrushedDoc.delete(doc);
brushManager.BrushedDoc.delete(Doc.GetDataDoc(doc));
+ return doc;
}
export class HighlightBrush {