From 4d02c9b581a22da777232124f2b1a96f8e342285 Mon Sep 17 00:00:00 2001 From: bob Date: Mon, 21 Oct 2019 15:45:51 -0400 Subject: initial simplification to fieldExt --- src/client/views/DocComponent.tsx | 20 +++--- .../views/collections/CollectionBaseView.tsx | 4 +- .../views/collections/CollectionSchemaView.tsx | 4 +- .../views/collections/CollectionStackingView.tsx | 2 +- .../CollectionStackingViewFieldColumn.tsx | 4 +- src/client/views/collections/CollectionSubView.tsx | 3 +- .../views/collections/CollectionTreeView.tsx | 2 +- src/client/views/collections/CollectionView.tsx | 2 +- .../views/collections/CollectionViewChromes.tsx | 72 ++-------------------- .../collectionFreeForm/CollectionFreeFormView.tsx | 13 ++-- .../collections/collectionFreeForm/MarqueeView.tsx | 4 +- src/client/views/nodes/AudioBox.tsx | 1 - src/client/views/nodes/ColorBox.tsx | 19 +----- src/client/views/nodes/DocumentView.tsx | 2 + src/client/views/nodes/FormattedTextBox.tsx | 6 -- src/client/views/nodes/ImageBox.tsx | 2 +- src/client/views/nodes/PDFBox.tsx | 2 +- src/client/views/nodes/VideoBox.tsx | 5 +- src/client/views/nodes/WebBox.tsx | 2 +- src/client/views/pdf/PDFViewer.tsx | 3 +- src/new_fields/Doc.ts | 69 +++++++++------------ 21 files changed, 74 insertions(+), 167 deletions(-) (limited to 'src') 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

(schemaCtor: (doc: Doc) => T) { class Component extends React.Component

{ @@ -18,6 +20,8 @@ export function DocComponent

(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

(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

(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

(schemaCtor: (doc: Doc) => T) { class Component extends React.Component

{ + _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

(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 { @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) { doc) { } render() { - Doc.UpdateDocumentExtensionForField(this.props.DataDoc ? this.props.DataDoc : this.props.Document, this.props.fieldKey); return (

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 doc) { return 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 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(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 { 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 { {this.SubView} - {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 => { value = value.toLowerCase(); - let docs: Doc | Doc[] | Promise | Promise | (() => 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([]); } else { - let docs: Doc | Doc[] | Promise | Promise | (() => 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(allRows); - } else { - let allRows = docs.map(doc => doc[Id]); - this.props.CollectionView.props.Document.textwrappedSchemaRows = new List(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(allRows); } } @@ -638,63 +623,14 @@ export class CollectionSchemaViewChrome extends React.Component { - @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 => { - value = value.toLowerCase(); - let docs: Doc | Doc[] | Promise | Promise | (() => 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(); - 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

{suggestion}

; - } - - 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 => { 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 (
- + {this.childViews} 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 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(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( 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
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; ContainingCollectionDoc: Opt; + fieldKey: string; Document: Doc; DataDoc?: Doc; fitToBox?: boolean; @@ -598,6 +599,7 @@ export class DocumentView extends DocComponent(Docu return ( 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 ); } render() { - Doc.UpdateDocumentExtensionForField(this.dataDoc, this.props.fieldKey); return (
; @@ -550,7 +549,7 @@ export class PDFViewer extends DocAnnotatableComponent { // 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._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._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]); -- cgit v1.2.3-70-g09d2