aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/views/DocComponent.tsx20
-rw-r--r--src/client/views/collections/CollectionBaseView.tsx4
-rw-r--r--src/client/views/collections/CollectionSchemaView.tsx4
-rw-r--r--src/client/views/collections/CollectionStackingView.tsx2
-rw-r--r--src/client/views/collections/CollectionStackingViewFieldColumn.tsx4
-rw-r--r--src/client/views/collections/CollectionSubView.tsx3
-rw-r--r--src/client/views/collections/CollectionTreeView.tsx2
-rw-r--r--src/client/views/collections/CollectionView.tsx2
-rw-r--r--src/client/views/collections/CollectionViewChromes.tsx72
-rw-r--r--src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx13
-rw-r--r--src/client/views/collections/collectionFreeForm/MarqueeView.tsx4
-rw-r--r--src/client/views/nodes/AudioBox.tsx1
-rw-r--r--src/client/views/nodes/ColorBox.tsx19
-rw-r--r--src/client/views/nodes/DocumentView.tsx2
-rw-r--r--src/client/views/nodes/FormattedTextBox.tsx6
-rw-r--r--src/client/views/nodes/ImageBox.tsx2
-rw-r--r--src/client/views/nodes/PDFBox.tsx2
-rw-r--r--src/client/views/nodes/VideoBox.tsx5
-rw-r--r--src/client/views/nodes/WebBox.tsx2
-rw-r--r--src/client/views/pdf/PDFViewer.tsx3
-rw-r--r--src/new_fields/Doc.ts69
21 files changed, 74 insertions, 167 deletions
diff --git a/src/client/views/DocComponent.tsx b/src/client/views/DocComponent.tsx
index ff149a9ac..1f9bdaac4 100644
--- a/src/client/views/DocComponent.tsx
+++ b/src/client/views/DocComponent.tsx
@@ -10,6 +10,8 @@ import { InkTool } from '../../new_fields/InkField';
/// DocComponents returns a generic base class for React views of document fields that are not interactive
interface DocComponentProps {
Document: Doc;
+ DataDoc?: Doc;
+ fieldKey: string;
}
export function DocComponent<P extends DocComponentProps, T>(schemaCtor: (doc: Doc) => T) {
class Component extends React.Component<P> {
@@ -18,6 +20,8 @@ export function DocComponent<P extends DocComponentProps, T>(schemaCtor: (doc: D
get Document(): T {
return schemaCtor(this.props.Document);
}
+ @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplateField ? Doc.GetProto(this.props.DataDoc!) : Doc.GetProto(this.props.Document); }
+ @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
}
return Component;
}
@@ -26,6 +30,8 @@ export function DocComponent<P extends DocComponentProps, T>(schemaCtor: (doc: D
/// DocStaticProps return a base class for React views of document fields that are interactive only when selected (e.g. ColorBox)
interface DocStaticProps {
Document: Doc;
+ DataDoc?: Doc;
+ fieldKey: string;
isSelected: () => boolean;
renderDepth: number;
}
@@ -36,6 +42,8 @@ export function DocStaticComponent<P extends DocStaticProps, T>(schemaCtor: (doc
get Document(): T {
return schemaCtor(this.props.Document);
}
+ @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplateField ? Doc.GetProto(this.props.DataDoc!) : Doc.GetProto(this.props.Document); }
+ @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
active = () => !this.props.Document.isBackground && (this.props.Document.forceActive || this.props.isSelected() || this.props.renderDepth === 0);// && !InkingControl.Instance.selectedTool; // bcz: inking state shouldn't affect static tools
}
return Component;
@@ -54,12 +62,15 @@ interface DocAnnotatableProps {
}
export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schemaCtor: (doc: Doc) => T) {
class Component extends React.Component<P> {
+ _isChildActive = false;
//TODO This might be pretty inefficient if doc isn't observed, because computed doesn't cache then
@computed
get Document(): T {
return schemaCtor(this.props.Document);
}
- _isChildActive = false;
+ @computed get dataDoc() { return (this.props.DataDoc && this.props.Document.isTemplateField ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; }
+ @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
+
@action.bound
removeDocument(doc: Doc): boolean {
Doc.GetProto(doc).annotationOn = undefined;
@@ -67,23 +78,18 @@ export function DocAnnotatableComponent<P extends DocAnnotatableProps, T>(schema
let index = value ? Doc.IndexOf(doc, value.map(d => d as Doc), true) : -1;
return index !== -1 && value.splice(index, 1) ? true : false;
}
-
- @computed get dataDoc() { return (this.props.DataDoc && this.props.Document.isTemplateField ? this.props.DataDoc : Doc.GetProto(this.props.Document)) as Doc; }
-
- @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
-
// if the moved document is already in this overlay collection nothing needs to be done.
// otherwise, if the document can be removed from where it was, it will then be added to this document's overlay collection.
@action.bound
moveDocument(doc: Doc, targetCollection: Doc, addDocument: (doc: Doc) => boolean): boolean {
return Doc.AreProtosEqual(this.props.Document, targetCollection) ? true : this.removeDocument(doc) ? addDocument(doc) : false;
}
-
@action.bound
addDocument(doc: Doc): boolean {
Doc.GetProto(doc).annotationOn = this.props.Document;
return Doc.AddDocToList(this.extensionDoc, this.props.fieldExt, doc);
}
+
whenActiveChanged = (isActive: boolean) => this.props.whenActiveChanged(this._isChildActive = isActive);
active = () => ((InkingControl.Instance.selectedTool === InkTool.None && !this.props.Document.isBackground) &&
(this.props.Document.forceActive || this.props.isSelected() || this._isChildActive || this.props.renderDepth === 0) ? true : false)
diff --git a/src/client/views/collections/CollectionBaseView.tsx b/src/client/views/collections/CollectionBaseView.tsx
index 1ade44250..fa543cc01 100644
--- a/src/client/views/collections/CollectionBaseView.tsx
+++ b/src/client/views/collections/CollectionBaseView.tsx
@@ -97,9 +97,11 @@ export class CollectionBaseView extends React.Component<CollectionViewProps> {
@action.bound
addDocument(doc: Doc): boolean {
- let targetDataDoc = this.props.Document;
+ let targetDataDoc = Doc.GetProto(this.props.Document);
let targetField = this.props.fieldKey;
Doc.AddDocToList(targetDataDoc, targetField, doc);
+ let extension = Doc.fieldExtensionDoc(targetDataDoc, targetField);
+ extension && (extension.lastModified = new DateField(new Date(Date.now())));
Doc.GetProto(doc).lastOpened = new DateField;
return true;
}
diff --git a/src/client/views/collections/CollectionSchemaView.tsx b/src/client/views/collections/CollectionSchemaView.tsx
index 23e070750..04bc550ea 100644
--- a/src/client/views/collections/CollectionSchemaView.tsx
+++ b/src/client/views/collections/CollectionSchemaView.tsx
@@ -158,6 +158,7 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
<CollectionSchemaPreview
Document={layoutDoc}
DataDocument={this.previewDocument !== this.props.DataDoc ? this.props.DataDoc : undefined}
+ fieldKey={this.props.fieldKey}
childDocs={this.childDocs}
renderDepth={this.props.renderDepth}
ruleProvider={this.props.Document.isRuleProvider && layoutDoc && layoutDoc.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider}
@@ -226,7 +227,6 @@ export class CollectionSchemaView extends CollectionSubView(doc => doc) {
}
render() {
- Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey);
return (
<div className="collectionSchemaView-container" style={{ height: "100%", marginTop: "0", }}>
<div className="collectionSchemaView-tableContainer" onPointerDown={this.onPointerDown} onWheel={this.onWheel} onDrop={(e: React.DragEvent) => this.onDrop(e, {})} ref={this.createTarget}>
@@ -898,6 +898,7 @@ interface CollectionSchemaPreviewProps {
childDocs?: Doc[];
renderDepth: number;
fitToBox?: boolean;
+ fieldKey: string;
PanelWidth: () => number;
PanelHeight: () => number;
ruleProvider: Doc | undefined;
@@ -993,6 +994,7 @@ export class CollectionSchemaPreview extends React.Component<CollectionSchemaPre
<DocumentView {...this.props}
DataDoc={this.props.DataDocument}
Document={this.props.Document}
+ fieldKey={this.props.fieldKey}
fitToBox={this.props.fitToBox}
onClick={this.props.onClick}
ruleProvider={this.props.ruleProvider}
diff --git a/src/client/views/collections/CollectionStackingView.tsx b/src/client/views/collections/CollectionStackingView.tsx
index 1bb2d2f46..5fb0c0f9f 100644
--- a/src/client/views/collections/CollectionStackingView.tsx
+++ b/src/client/views/collections/CollectionStackingView.tsx
@@ -170,6 +170,7 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
return <CollectionSchemaPreview
Document={doc}
DataDocument={dataDoc}
+ fieldKey={this.props.fieldKey}
showOverlays={this.overlays}
renderDepth={this.props.renderDepth}
ruleProvider={this.props.Document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.Document : this.props.ruleProvider}
@@ -389,7 +390,6 @@ export class CollectionStackingView extends CollectionSubView(doc => doc) {
SetValue: this.addGroup,
contents: "+ ADD A GROUP"
};
- Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey);
let sections = [[undefined, this.filteredChildren] as [SchemaHeaderField | undefined, Doc[]]];
if (this.sectionFilter) {
let entries = Array.from(this.Sections.entries());
diff --git a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
index 7e54b0f29..fec3d90b9 100644
--- a/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
+++ b/src/client/views/collections/CollectionStackingViewFieldColumn.tsx
@@ -2,7 +2,7 @@ import React = require("react");
import { library } from '@fortawesome/fontawesome-svg-core';
import { faPalette } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { action, observable, trace } from "mobx";
+import { action, observable, trace, runInAction } from "mobx";
import { observer } from "mobx-react";
import { Doc, WidthSym } from "../../../new_fields/Doc";
import { Id } from "../../../new_fields/FieldSymbols";
@@ -204,7 +204,7 @@ export class CollectionStackingViewFieldColumn extends React.Component<CSVFieldC
document.removeEventListener("pointerup", this.pointerUp);
document.addEventListener("pointerup", this.pointerUp);
}
- this._createAliasSelected = false;
+ runInAction(() => this._createAliasSelected = false);
}
renderColorPicker = () => {
diff --git a/src/client/views/collections/CollectionSubView.tsx b/src/client/views/collections/CollectionSubView.tsx
index 8bd67b880..43147ed20 100644
--- a/src/client/views/collections/CollectionSubView.tsx
+++ b/src/client/views/collections/CollectionSubView.tsx
@@ -33,6 +33,7 @@ export interface CollectionViewProps extends FieldViewProps {
VisibleHeight?: () => number;
chromeCollapsed: boolean;
setPreviewCursor?: (func: (x: number, y: number, drag: boolean) => void) => void;
+ fieldKey: string;
}
export interface SubCollectionViewProps extends CollectionViewProps {
@@ -77,7 +78,7 @@ export function CollectionSubView<T>(schemaCtor: (doc: Doc) => T) {
// to its children which may be templates.
// The name of the data field comes from fieldExt if it's an extension, or fieldKey otherwise.
@computed get dataField() {
- return Doc.fieldExtensionDoc(this.props.Document.isTemplateField && this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey, this.props.fieldExt)[this.props.fieldExt || this.props.fieldKey];
+ return this.props.fieldExt ? this.extensionDoc[this.props.fieldExt] : this.dataDoc[this.props.fieldKey];
}
get childLayoutPairs() {
diff --git a/src/client/views/collections/CollectionTreeView.tsx b/src/client/views/collections/CollectionTreeView.tsx
index c1b7f7e48..2cad41acb 100644
--- a/src/client/views/collections/CollectionTreeView.tsx
+++ b/src/client/views/collections/CollectionTreeView.tsx
@@ -317,6 +317,7 @@ class TreeView extends React.Component<TreeViewProps> {
<CollectionSchemaPreview
Document={layoutDoc}
DataDocument={this.templateDataDoc}
+ fieldKey={this.fieldKey}
renderDepth={this.props.renderDepth}
showOverlays={this.noOverlays}
ruleProvider={this.props.document.isRuleProvider && layoutDoc.type !== DocumentType.TEXT ? this.props.document : this.props.ruleProvider}
@@ -556,7 +557,6 @@ export class CollectionTreeView extends CollectionSubView(Document) {
}
render() {
- Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey);
let dropAction = StrCast(this.props.Document.dropAction) as dropActionType;
let addDoc = (doc: Doc, relativeTo?: Doc, before?: boolean) => Doc.AddDocToList(this.props.Document, this.props.fieldKey, doc, relativeTo, before, false, false, false);
let moveDoc = (d: Doc, target: Doc, addDoc: (doc: Doc) => boolean) => this.props.moveDocument(d, target, addDoc);
diff --git a/src/client/views/collections/CollectionView.tsx b/src/client/views/collections/CollectionView.tsx
index 4ca6df034..74a388425 100644
--- a/src/client/views/collections/CollectionView.tsx
+++ b/src/client/views/collections/CollectionView.tsx
@@ -149,7 +149,7 @@ export class CollectionView extends React.Component<FieldViewProps> {
{this.SubView}
</CollectionBaseView>
- {this.lightbox(DocListCast(this.props.Document[this.props.fieldKey]).filter(d => d.type === DocumentType.IMG).map(d => Cast(d.data, ImageField)!.url!.href))}
+ {this.lightbox(DocListCast(this.props.Document[this.props.fieldKey]).filter(d => d.type === DocumentType.IMG).map(d => Cast(d.data, ImageField)!.url.href))}
</>
);
}
diff --git a/src/client/views/collections/CollectionViewChromes.tsx b/src/client/views/collections/CollectionViewChromes.tsx
index a5b7f0181..dd5e630e4 100644
--- a/src/client/views/collections/CollectionViewChromes.tsx
+++ b/src/client/views/collections/CollectionViewChromes.tsx
@@ -480,12 +480,7 @@ export class CollectionStackingViewChrome extends React.Component<CollectionView
getKeySuggestions = async (value: string): Promise<string[]> => {
value = value.toLowerCase();
- let docs: Doc | Doc[] | Promise<Doc> | Promise<Doc[]> | (() => DocLike)
- = () => DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldExt ? this.props.CollectionView.props.fieldExt : this.props.CollectionView.props.fieldKey]);
- if (typeof docs === "function") {
- docs = docs();
- }
- docs = await docs;
+ let docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]);
if (docs instanceof Doc) {
return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value));
} else {
@@ -591,19 +586,9 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
if (textwrappedRows.length) {
this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>([]);
} else {
- let docs: Doc | Doc[] | Promise<Doc> | Promise<Doc[]> | (() => DocLike)
- = () => DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldExt ? this.props.CollectionView.props.fieldExt : this.props.CollectionView.props.fieldKey]);
- if (typeof docs === "function") {
- docs = docs();
- }
- docs = await docs;
- if (docs instanceof Doc) {
- let allRows = [docs[Id]];
- this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>(allRows);
- } else {
- let allRows = docs.map(doc => doc[Id]);
- this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>(allRows);
- }
+ let docs = DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldKey]);
+ let allRows = docs instanceof Doc ? [docs[Id]] : docs.map(doc => doc[Id]);
+ this.props.CollectionView.props.Document.textwrappedSchemaRows = new List<string>(allRows);
}
}
@@ -638,63 +623,14 @@ export class CollectionSchemaViewChrome extends React.Component<CollectionViewCh
@observer
export class CollectionTreeViewChrome extends React.Component<CollectionViewChromeProps> {
- @observable private _currentKey: string = "";
- @observable private suggestions: string[] = [];
@computed private get descending() { return Cast(this.props.CollectionView.props.Document.sortAscending, "boolean", null); }
- @computed get sectionFilter() { return StrCast(this.props.CollectionView.props.Document.sectionFilter); }
-
- getKeySuggestions = async (value: string): Promise<string[]> => {
- value = value.toLowerCase();
- let docs: Doc | Doc[] | Promise<Doc> | Promise<Doc[]> | (() => DocLike)
- = () => DocListCast(this.props.CollectionView.props.Document[this.props.CollectionView.props.fieldExt ? this.props.CollectionView.props.fieldExt : this.props.CollectionView.props.fieldKey]);
- if (typeof docs === "function") {
- docs = docs();
- }
- docs = await docs;
- if (docs instanceof Doc) {
- return Object.keys(docs).filter(key => key.toLowerCase().startsWith(value));
- } else {
- const keys = new Set<string>();
- docs.forEach(doc => Doc.allKeys(doc).forEach(key => keys.add(key)));
- return Array.from(keys).filter(key => key.toLowerCase().startsWith(value));
- }
- }
-
- @action
- onKeyChange = (e: React.ChangeEvent, { newValue }: { newValue: string }) => {
- this._currentKey = newValue;
- }
-
- getSuggestionValue = (suggestion: string) => suggestion;
-
- renderSuggestion = (suggestion: string) => {
- return <p>{suggestion}</p>;
- }
-
- onSuggestionFetch = async ({ value }: { value: string }) => {
- const sugg = await this.getKeySuggestions(value);
- runInAction(() => {
- this.suggestions = sugg;
- });
- }
-
- @action
- onSuggestionClear = () => {
- this.suggestions = [];
- }
-
- setValue = (value: string) => {
- this.props.CollectionView.props.Document.sectionFilter = value;
- return true;
- }
@action toggleSort = () => {
if (this.props.CollectionView.props.Document.sortAscending) this.props.CollectionView.props.Document.sortAscending = undefined;
else if (this.props.CollectionView.props.Document.sortAscending === undefined) this.props.CollectionView.props.Document.sortAscending = false;
else this.props.CollectionView.props.Document.sortAscending = true;
}
- @action resetValue = () => { this._currentKey = this.sectionFilter; };
render() {
return (
diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
index 430ba582b..33d6b1358 100644
--- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
+++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx
@@ -113,10 +113,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
return this.childLayoutPairs.filter(pair => this.isCurrent(pair.layout)).map(pair => pair.layout);
}
- @computed get fieldExtensionDoc() {
- return Doc.fieldExtensionDoc(this.props.DataDoc || this.props.Document, this.props.fieldKey);
- }
-
@action
onDrop = (e: React.DragEvent): Promise<void> => {
var pt = this.getTransform().transformPoint(e.pageX, e.pageY);
@@ -309,7 +305,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
return [[range[0][0] > x ? x : range[0][0], range[0][1] < xe ? xe : range[0][1]],
[range[1][0] > y ? y : range[1][0], range[1][1] < ye ? ye : range[1][1]]];
}, [[minx, maxx], [miny, maxy]]);
- let ink = Cast(this.fieldExtensionDoc.ink, InkField);
+ let ink = Cast(this.extensionDoc.ink, InkField);
if (ink && ink.inkData) {
ink.inkData.forEach((value: StrokeData, key: string) => {
let bounds = InkingCanvas.StrokeRect(value);
@@ -605,9 +601,9 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
}
analyzeStrokes = async () => {
- let data = Cast(this.fieldExtensionDoc.ink, InkField);
+ let data = Cast(this.extensionDoc.ink, InkField);
if (data) {
- CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.fieldExtensionDoc, ["inkAnalysis", "handwriting"], data.inkData);
+ CognitiveServices.Inking.Appliers.ConcatenateHandwriting(this.extensionDoc, ["inkAnalysis", "handwriting"], data.inkData);
}
}
@@ -680,7 +676,6 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
this.Document.fitH = this.contentBounds && (this.contentBounds.b - this.contentBounds.y);
// if isAnnotationOverlay is set, then children will be stored in the extension document for the fieldKey.
// otherwise, they are stored in fieldKey. All annotations to this document are stored in the extension document
- Doc.UpdateDocumentExtensionForField(this.props.DataDoc || this.props.Document, this.props.fieldKey);
return (
<div className={"collectionfreeformview-container"} ref={this.createDropTarget} onWheel={this.onPointerWheel}
style={{ pointerEvents: SelectionManager.GetIsDragging() ? "all" : undefined, height: this.isAnnotationOverlay ? (this.props.Document.scrollHeight ? this.Document.scrollHeight : "100%") : this.props.PanelHeight() }}
@@ -690,7 +685,7 @@ export class CollectionFreeFormView extends CollectionSubView(PanZoomDocument) {
getContainerTransform={this.getContainerTransform} getTransform={this.getTransform} isAnnotationOverlay={this.isAnnotationOverlay}>
<CollectionFreeFormViewPannableContents centeringShiftX={this.centeringShiftX} centeringShiftY={this.centeringShiftY}
easing={this.easing} zoomScaling={this.zoomScaling} panX={this.panX} panY={this.panY}>
- <InkingCanvas getScreenTransform={this.getTransform} Document={this.props.Document} AnnotationDocument={this.fieldExtensionDoc} inkFieldKey={"ink"} >
+ <InkingCanvas getScreenTransform={this.getTransform} Document={this.props.Document} AnnotationDocument={this.extensionDoc} inkFieldKey={"ink"} >
{this.childViews}
</InkingCanvas>
<CollectionFreeFormRemoteCursors {...this.props} key="remoteCursors" />
diff --git a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
index 743055875..4ff70daba 100644
--- a/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
+++ b/src/client/views/collections/collectionFreeForm/MarqueeView.tsx
@@ -247,12 +247,12 @@ export class MarqueeView extends React.Component<MarqueeViewProps>
get ink() { // ink will be stored on the extension doc for the field (fieldKey) where the container's data is stored.
let cprops = this.props.container.props;
- return Cast(Doc.fieldExtensionDoc(cprops.Document, cprops.fieldKey).ink, InkField);
+ return Cast(this.props.container.extensionDoc.ink, InkField);
}
set ink(value: InkField | undefined) {
let cprops = this.props.container.props;
- Doc.fieldExtensionDoc(cprops.Document, cprops.fieldKey).ink = value;
+ this.props.container.extensionDoc.ink = value;
}
@undoBatch
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 689d44a2f..3e5deb55b 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -7,7 +7,6 @@ import { AudioField } from "../../../new_fields/URLField";
import { DocStaticComponent } from "../DocComponent";
import { makeInterface } from "../../../new_fields/Schema";
import { documentSchema } from "./DocumentView";
-import { InkingControl } from "../InkingControl";
type AudioDocument = makeInterface<[typeof documentSchema]>;
const AudioDocument = makeInterface(documentSchema);
diff --git a/src/client/views/nodes/ColorBox.tsx b/src/client/views/nodes/ColorBox.tsx
index 30554ea36..fdcedb3a5 100644
--- a/src/client/views/nodes/ColorBox.tsx
+++ b/src/client/views/nodes/ColorBox.tsx
@@ -11,7 +11,6 @@ import { trace, reaction, observable, action, IReactionDisposer } from "mobx";
import { SelectionManager } from "../../util/SelectionManager";
import { StrCast } from "../../../new_fields/Types";
import { CurrentUserUtils } from "../../../server/authentication/models/current_user_utils";
-import { Doc } from "../../../new_fields/Doc";
type ColorDocument = makeInterface<[typeof documentSchema]>;
const ColorDocument = makeInterface(documentSchema);
@@ -19,8 +18,11 @@ const ColorDocument = makeInterface(documentSchema);
@observer
export class ColorBox extends DocStaticComponent<FieldViewProps, ColorDocument>(ColorDocument) {
public static LayoutString(fieldKey?: string) { return FieldView.LayoutString(ColorBox, fieldKey); }
+
_selectedDisposer: IReactionDisposer | undefined;
_penDisposer: IReactionDisposer | undefined;
+ @observable _startupColor = "black";
+
componentDidMount() {
this._selectedDisposer = reaction(() => SelectionManager.SelectedDocuments(),
action(() => this._startupColor = SelectionManager.SelectedDocuments().length ? StrCast(SelectionManager.SelectedDocuments()[0].Document.backgroundColor, "black") : "black"),
@@ -28,27 +30,12 @@ export class ColorBox extends DocStaticComponent<FieldViewProps, ColorDocument>(
this._penDisposer = reaction(() => CurrentUserUtils.ActivePen,
action(() => this._startupColor = CurrentUserUtils.ActivePen ? StrCast(CurrentUserUtils.ActivePen.backgroundColor, "black") : "black"),
{ fireImmediately: true });
-
- // compare to this reaction that used to be in Selection Manager
- // reaction(() => manager.SelectedDocuments, sel => {
- // let targetColor = "#FFFFFF";
- // if (sel.length > 0) {
- // let firstView = sel[0];
- // let doc = firstView.props.Document;
- // let targetDoc = doc.isTemplateField ? doc : Doc.GetProto(doc);
- // let stored = StrCast(targetDoc.backgroundColor);
- // stored.length > 0 && (targetColor = stored);
- // }
- // InkingControl.Instance.updateSelectedColor(targetColor);
- // }, { fireImmediately: true });
}
componentWillUnmount() {
this._penDisposer && this._penDisposer();
this._selectedDisposer && this._selectedDisposer();
}
- @observable _startupColor = "black";
-
render() {
return <div className={`colorBox-container${this.active() ? "-interactive" : ""}`}
onPointerDown={e => e.button === 0 && !e.ctrlKey && e.stopPropagation()}>
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index a41a37e66..089ec77ba 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -67,6 +67,7 @@ library.add(fa.faLaptopCode, fa.faMale, fa.faCopy, fa.faHandPointRight, fa.faCom
export interface DocumentViewProps {
ContainingCollectionView: Opt<CollectionView>;
ContainingCollectionDoc: Opt<Doc>;
+ fieldKey: string;
Document: Doc;
DataDoc?: Doc;
fitToBox?: boolean;
@@ -598,6 +599,7 @@ export class DocumentView extends DocComponent<DocumentViewProps, Document>(Docu
return (<DocumentContentsView ContainingCollectionView={this.props.ContainingCollectionView}
ContainingCollectionDoc={this.props.ContainingCollectionDoc}
Document={this.props.Document}
+ fieldKey={this.props.fieldKey}
fitToBox={this.props.fitToBox}
addDocument={this.props.addDocument}
removeDocument={this.props.removeDocument}
diff --git a/src/client/views/nodes/FormattedTextBox.tsx b/src/client/views/nodes/FormattedTextBox.tsx
index f866e6f7e..020442bf3 100644
--- a/src/client/views/nodes/FormattedTextBox.tsx
+++ b/src/client/views/nodes/FormattedTextBox.tsx
@@ -44,7 +44,6 @@ import React = require("react");
import { ContextMenuProps } from '../ContextMenuItem';
import { ContextMenu } from '../ContextMenu';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { siteVerification } from 'googleapis/build/src/apis/siteVerification';
library.add(faEdit);
library.add(faSmile, faTextHeight, faUpload);
@@ -143,10 +142,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
public get CurrentDiv(): HTMLDivElement { return this._ref.current!; }
- @computed get extensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
-
- @computed get dataDoc() { return this.props.DataDoc && this.props.Document.isTemplateField ? Doc.GetProto(this.props.DataDoc) : Doc.GetProto(this.props.Document); }
-
// the document containing the view layout information - will be the Document itself unless the Document has
// a layout field. In that case, all layout information comes from there unless overriden by Document
@computed get layoutDoc(): Doc { return Doc.Layout(this.props.Document); }
@@ -1028,7 +1023,6 @@ export class FormattedTextBox extends DocComponent<(FieldViewProps & FormattedTe
let rounded = StrCast(this.layoutDoc.borderRounding) === "100%" ? "-rounded" : "";
let interactive: "all" | "none" = InkingControl.Instance.selectedTool || this.layoutDoc.isBackground
? "none" : "all";
- Doc.UpdateDocumentExtensionForField(this.dataDoc, this.props.fieldKey);
if (this.props.isSelected()) {
FormattedTextBox._toolTipTextMenu!.updateFromDash(this._editorView!, undefined, this.props);
}
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index 426b9cbb4..d80e222c2 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -326,11 +326,11 @@ export class ImageBox extends DocAnnotatableComponent<FieldViewProps, ImageDocum
}
render() {
- if (!Doc.UpdateDocumentExtensionForField(this.dataDoc, this.props.fieldKey)) return (null);
return (<div className={"imageBox-container"} onContextMenu={this.specificContextMenu}>
<CollectionFreeFormView {...this.props}
PanelHeight={this.props.PanelHeight}
PanelWidth={this.props.PanelWidth}
+ fieldExt={"annotations"}
isAnnotationOverlay={true}
focus={this.props.focus}
isSelected={this.props.isSelected}
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 5795d6f12..78858731f 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -229,7 +229,7 @@ export class PDFBox extends DocAnnotatableComponent<FieldViewProps, PdfDocument>
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} focus={this.props.focus}
- pinToPres={this.props.pinToPres} addDocument={this.props.addDocument}
+ pinToPres={this.props.pinToPres} addDocument={this.addDocument}
ScreenToLocalTransform={this.props.ScreenToLocalTransform} select={this.props.select}
isSelected={this.props.isSelected} whenActiveChanged={this.whenActiveChanged}
fieldKey={this.props.fieldKey} extensionDoc={this.extensionDoc} startupLive={this._initialScale < 2.5 ? true : false} />
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index 20383bab1..5e8154233 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -322,7 +322,6 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
InkingControl.Instance.switchTool(InkTool.None);
this._isResetClick < 10 && (this.Document.currentTimecode = 0);
}
- @computed get fieldExtensionDoc() { return Doc.fieldExtensionDoc(this.dataDoc, this.props.fieldKey); }
@computed get dataDoc() { return this.props.DataDoc && this.Document.isTemplateField ? this.props.DataDoc : Doc.GetProto(this.props.Document); }
@computed get youtubeContent() {
@@ -337,14 +336,12 @@ export class VideoBox extends DocAnnotatableComponent<FieldViewProps, VideoDocum
@action.bound
addDocumentWithTimestamp(doc: Doc): boolean {
- Doc.GetProto(doc).annotationOn = this.props.Document;
var curTime = (this.Document.currentTimecode || -1);
curTime !== -1 && (doc.displayTimecode = curTime);
- return Doc.AddDocToList(this.fieldExtensionDoc, this.props.fieldExt, doc);
+ return this.addDocument(doc);
}
render() {
- if (!Doc.UpdateDocumentExtensionForField(this.dataDoc, this.props.fieldKey)) return (null);
return (<div className={"videoBox-container"} onContextMenu={this.specificContextMenu}>
<CollectionFreeFormView {...this.props}
PanelHeight={this.props.PanelHeight}
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index d5a1f4e73..907e71627 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -195,11 +195,11 @@ export class WebBox extends DocAnnotatableComponent<FieldViewProps, WebDocument>
</>);
}
render() {
- Doc.UpdateDocumentExtensionForField(this.dataDoc, this.props.fieldKey);
return (<div className={"imageBox-container"} >
<CollectionFreeFormView {...this.props}
PanelHeight={this.props.PanelHeight}
PanelWidth={this.props.PanelWidth}
+ fieldExt={"annotations"}
focus={this.props.focus}
isSelected={this.props.isSelected}
isAnnotationOverlay={true}
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx
index f3aaca471..361e58c65 100644
--- a/src/client/views/pdf/PDFViewer.tsx
+++ b/src/client/views/pdf/PDFViewer.tsx
@@ -46,7 +46,6 @@ interface IViewerProps {
pdf: Pdfjs.PDFDocumentProxy;
url: string;
fieldKey: string;
- fieldExt: string;
Document: Doc;
DataDoc?: Doc;
ContainingCollectionView: Opt<CollectionView>;
@@ -550,7 +549,7 @@ export class PDFViewer extends DocAnnotatableComponent<IViewerProps, PdfDocument
highlight = (color: string) => {
// creates annotation documents for current highlights
let annotationDoc = this.makeAnnotationDocument(color);
- annotationDoc && Doc.AddDocToList(this.props.extensionDoc, this.props.fieldExt, annotationDoc);
+ annotationDoc && this.props.addDocument && this.props.addDocument(annotationDoc);
return annotationDoc;
}
diff --git a/src/new_fields/Doc.ts b/src/new_fields/Doc.ts
index 71b64d7c3..f60a2e720 100644
--- a/src/new_fields/Doc.ts
+++ b/src/new_fields/Doc.ts
@@ -398,44 +398,6 @@ export namespace Doc {
return bounds;
}
- //
- // Resolves a reference to a field by returning 'doc' if no field extension is specified,
- // otherwise, it returns the extension document stored in doc.<fieldKey>_ext.
- // This mechanism allows any fields to be extended with an extension document that can
- // be used to capture field-specific metadata. For example, an image field can be extended
- // to store annotations, ink, and other data.
- //
- export function fieldExtensionDoc(doc: Doc, fieldKey: string, fieldExt: string = "yes") {
- return fieldExt && doc[fieldKey + "_ext"] instanceof Doc ? doc[fieldKey + "_ext"] as Doc : doc;
- }
-
- export function CreateDocumentExtensionForField(doc: Doc, fieldKey: string) {
- let docExtensionForField = new Doc(doc[Id] + fieldKey, true);
- docExtensionForField.title = fieldKey + ".ext";
- docExtensionForField.extendsDoc = doc; // this is used by search to map field matches on the extension doc back to the document it extends.
- docExtensionForField.type = DocumentType.EXTENSION;
- let proto: Doc | undefined = doc;
- while (proto && !Doc.IsPrototype(proto) && proto.proto) {
- proto = proto.proto;
- }
- (proto ? proto : doc)[fieldKey + "_ext"] = new PrefetchProxy(docExtensionForField);
- return docExtensionForField;
- }
-
- export function UpdateDocumentExtensionForField(doc: Doc, fieldKey: string, immediate: boolean = false) {
- let docExtensionForField = doc[fieldKey + "_ext"] as Doc;
- if (docExtensionForField === undefined) {
- if (immediate) {
- CreateDocumentExtensionForField(doc, fieldKey);
- return true;
- }
- else {
- setTimeout(() => CreateDocumentExtensionForField(doc, fieldKey), 0);
- return false;
- }
- }
- return true;
- }
export function MakeTitled(title: string) {
let doc = new Doc();
doc.title = title;
@@ -490,13 +452,38 @@ export namespace Doc {
let layoutDoc: Doc | undefined = childDocLayout;
let resolvedDataDoc = !doc.isTemplateField && dataDoc !== doc && dataDoc ? Doc.GetDataDoc(dataDoc) : undefined;
if (resolvedDataDoc && Doc.WillExpandTemplateLayout(childDocLayout, resolvedDataDoc)) {
- Doc.UpdateDocumentExtensionForField(resolvedDataDoc, fieldKey);
- let fieldExtensionDoc = Doc.fieldExtensionDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title)), "dummy");
- layoutDoc = Doc.expandTemplateLayout(childDocLayout, fieldExtensionDoc !== resolvedDataDoc ? fieldExtensionDoc : undefined);
+ let extensionDoc = fieldExtensionDoc(resolvedDataDoc, StrCast(childDocLayout.templateField, StrCast(childDocLayout.title)));
+ layoutDoc = Doc.expandTemplateLayout(childDocLayout, extensionDoc !== resolvedDataDoc ? extensionDoc : undefined);
} else layoutDoc = childDocLayout;
return { layout: layoutDoc, data: resolvedDataDoc };
}
+ //
+ // Resolves a reference to a field by returning 'doc' if no field extension is specified,
+ // otherwise, it returns the extension document stored in doc.<fieldKey>_ext.
+ // This mechanism allows any fields to be extended with an extension document that can
+ // be used to capture field-specific metadata. For example, an image field can be extended
+ // to store annotations, ink, and other data.
+ //
+ export function fieldExtensionDoc(doc: Doc, fieldKey: string) {
+ let extension = doc[fieldKey + "_ext"] as Doc;
+ (extension === undefined) && setTimeout(() => CreateDocumentExtensionForField(doc, fieldKey), 0);
+ return extension ? extension : doc;
+ }
+
+ export function CreateDocumentExtensionForField(doc: Doc, fieldKey: string) {
+ let docExtensionForField = new Doc(doc[Id] + fieldKey, true);
+ docExtensionForField.title = fieldKey + ".ext";
+ docExtensionForField.extendsDoc = doc; // this is used by search to map field matches on the extension doc back to the document it extends.
+ docExtensionForField.type = DocumentType.EXTENSION;
+ let proto: Doc | undefined = doc;
+ while (proto && !Doc.IsPrototype(proto) && proto.proto) {
+ proto = proto.proto;
+ }
+ (proto ? proto : doc)[fieldKey + "_ext"] = new PrefetchProxy(docExtensionForField);
+ return docExtensionForField;
+ }
+
export function Overwrite(doc: Doc, overwrite: Doc, copyProto: boolean = false): Doc {
Object.keys(doc).forEach(key => {
const field = ProxyField.WithoutProxy(() => doc[key]);