aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/nodes')
-rw-r--r--src/client/views/nodes/AudioBox.tsx4
-rw-r--r--src/client/views/nodes/CollectionFreeFormDocumentView.tsx8
-rw-r--r--src/client/views/nodes/ComparisonBox.tsx5
-rw-r--r--src/client/views/nodes/DataVizBox/DataVizBox.tsx41
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx11
-rw-r--r--src/client/views/nodes/DocumentIcon.tsx2
-rw-r--r--src/client/views/nodes/DocumentLinksButton.tsx4
-rw-r--r--src/client/views/nodes/DocumentView.tsx308
-rw-r--r--src/client/views/nodes/EquationBox.tsx2
-rw-r--r--src/client/views/nodes/FieldView.tsx9
-rw-r--r--src/client/views/nodes/ImageBox.tsx8
-rw-r--r--src/client/views/nodes/KeyValuePair.tsx65
-rw-r--r--src/client/views/nodes/LinkAnchorBox.tsx14
-rw-r--r--src/client/views/nodes/LinkBox.tsx9
-rw-r--r--src/client/views/nodes/LinkDocPreview.tsx12
-rw-r--r--src/client/views/nodes/MapBox/MapBox.tsx4
-rw-r--r--src/client/views/nodes/MapBox/MapPushpinBox.tsx4
-rw-r--r--src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx4
-rw-r--r--src/client/views/nodes/PDFBox.tsx8
-rw-r--r--src/client/views/nodes/VideoBox.tsx18
-rw-r--r--src/client/views/nodes/WebBox.tsx36
-rw-r--r--src/client/views/nodes/formattedText/DashDocView.tsx4
-rw-r--r--src/client/views/nodes/formattedText/DashFieldView.tsx2
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBox.tsx16
-rw-r--r--src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx3
-rw-r--r--src/client/views/nodes/trails/PresBox.tsx12
-rw-r--r--src/client/views/nodes/trails/PresElementBox.tsx10
27 files changed, 331 insertions, 292 deletions
diff --git a/src/client/views/nodes/AudioBox.tsx b/src/client/views/nodes/AudioBox.tsx
index 908cd5dc0..1729af191 100644
--- a/src/client/views/nodes/AudioBox.tsx
+++ b/src/client/views/nodes/AudioBox.tsx
@@ -211,7 +211,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// removes from currently playing display
@action
removeCurrentlyPlaying = () => {
- const docView = this._props.DocumentView?.();
+ const docView = this.DocumentView?.();
if (CollectionStackedTimeline.CurrentlyPlaying && docView) {
const index = CollectionStackedTimeline.CurrentlyPlaying.indexOf(docView);
index !== -1 && CollectionStackedTimeline.CurrentlyPlaying.splice(index, 1);
@@ -221,7 +221,7 @@ export class AudioBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// adds doc to currently playing display
@action
addCurrentlyPlaying = () => {
- const docView = this._props.DocumentView?.();
+ const docView = this.DocumentView?.();
if (!CollectionStackedTimeline.CurrentlyPlaying) {
CollectionStackedTimeline.CurrentlyPlaying = [];
}
diff --git a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
index ad5aabc21..83cabf355 100644
--- a/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
+++ b/src/client/views/nodes/CollectionFreeFormDocumentView.tsx
@@ -15,7 +15,7 @@ import { DocComponent } from '../DocComponent';
import { StyleProp } from '../StyleProvider';
import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
import './CollectionFreeFormDocumentView.scss';
-import { DocumentView, DocumentViewInternalProps, DocumentViewProps, OpenWhere } from './DocumentView';
+import { DocumentView, DocumentViewProps, OpenWhere } from './DocumentView';
import { FieldViewProps } from './FieldView';
export interface CollectionFreeFormDocumentViewWrapperProps extends DocumentViewProps {
@@ -149,7 +149,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
return this._props.CollectionFreeFormView;
}
- styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewInternalProps | FieldViewProps>, property: string) => {
+ styleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string) => {
if (doc === this.layoutDoc) {
switch (property) {
case StyleProp.Opacity: return this._props.w_Opacity(); // only change the opacity for this specific document, not its children
@@ -229,7 +229,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
@action public float = () => {
const topDoc = this.Document;
- const containerDocView = this._props.docViewPath().lastElement();
+ const containerDocView = this._props.containerViewPath?.().lastElement();
const screenXf = containerDocView?.screenToContentsTransform();
if (screenXf) {
SelectionManager.DeselectAll();
@@ -252,7 +252,7 @@ export class CollectionFreeFormDocumentView extends DocComponent<CollectionFreeF
};
nudge = (x: number, y: number) => {
- const [locX, locY] = this.ScreenToLocalBoxXf().transformDirection(x, y);
+ const [locX, locY] = this._props.ScreenToLocalTransform().transformDirection(x, y);
this._props.Document.x = this._props.w_X() + locX;
this._props.Document.y = this._props.w_Y() + locY;
};
diff --git a/src/client/views/nodes/ComparisonBox.tsx b/src/client/views/nodes/ComparisonBox.tsx
index 5e7e568b0..b171db17c 100644
--- a/src/client/views/nodes/ComparisonBox.tsx
+++ b/src/client/views/nodes/ComparisonBox.tsx
@@ -11,7 +11,7 @@ import { undoBatch } from '../../util/UndoManager';
import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
import { StyleProp } from '../StyleProvider';
import './ComparisonBox.scss';
-import { DocumentView, DocumentViewInternalProps, DocumentViewProps } from './DocumentView';
+import { DocumentView } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import { PinProps, PresBox } from './trails';
@@ -148,7 +148,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
e => this.clearDoc(which)
);
};
- docStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewInternalProps | FieldViewProps>, property: string): any => {
+ docStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => {
if (property === StyleProp.PointerEvents) return 'none';
return this._props.styleProvider?.(doc, props, property);
};
@@ -178,6 +178,7 @@ export class ComparisonBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatabl
{...this._props}
Document={targetDoc}
TemplateDataDocument={undefined}
+ containerViewPath={this.docViewPathFunc}
moveDocument={which.endsWith('1') ? this.moveDoc1 : this.moveDoc2}
removeDocument={which.endsWith('1') ? this.remDoc1 : this.remDoc2}
NativeWidth={returnZero}
diff --git a/src/client/views/nodes/DataVizBox/DataVizBox.tsx b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
index 5a55ca764..5ceec98cb 100644
--- a/src/client/views/nodes/DataVizBox/DataVizBox.tsx
+++ b/src/client/views/nodes/DataVizBox/DataVizBox.tsx
@@ -1,6 +1,6 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Colors, Toggle, ToggleType, Type } from 'browndash-components';
-import { ObservableMap, action, computed, observable, runInAction } from 'mobx';
+import { ObservableMap, action, computed, makeObservable, observable, runInAction } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
import { emptyFunction, returnEmptyString, returnFalse, returnOne, setupMoveUpEvents } from '../../../../Utils';
@@ -14,10 +14,9 @@ import { TraceMobx } from '../../../../fields/util';
import { Docs } from '../../../documents/Documents';
import { DocumentManager } from '../../../util/DocumentManager';
import { UndoManager, undoable } from '../../../util/UndoManager';
-import { ViewBoxAnnotatableComponent } from '../../DocComponent';
+import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent';
import { MarqueeAnnotator } from '../../MarqueeAnnotator';
import { SidebarAnnos } from '../../SidebarAnnos';
-import { CollectionFreeFormView } from '../../collections/collectionFreeForm';
import { AnchorMenu } from '../../pdf/AnchorMenu';
import { GPTPopup } from '../../pdf/GPTPopup/GPTPopup';
import { DocFocusOptions, DocumentView } from '../DocumentView';
@@ -37,22 +36,28 @@ export enum DataVizView {
}
@observer
-export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
+export class DataVizBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps>() {
private _mainCont: React.RefObject<HTMLDivElement> = React.createRef();
- private _ffref = React.createRef<CollectionFreeFormView>();
private _marqueeref = React.createRef<MarqueeAnnotator>();
private _annotationLayer: React.RefObject<HTMLDivElement> = React.createRef();
anchorMenuClick?: () => undefined | ((anchor: Doc) => void);
crop: ((region: Doc | undefined, addCrop?: boolean) => Doc | undefined) | undefined;
- @observable schemaDataVizChildren: any = undefined;
+ @observable _schemaDataVizChildren: any = undefined;
@observable _marqueeing: number[] | undefined = undefined;
@observable _savedAnnotations = new ObservableMap<number, HTMLDivElement[]>();
+
+ constructor(props: ViewBoxAnnotatableProps & FieldViewProps) {
+ super(props);
+ makeObservable(this);
+ this._props.setContentView?.(this);
+ }
+
@computed get annotationLayer() {
TraceMobx();
return <div className="dataVizBox-annotationLayer" style={{ height: this._props.PanelHeight(), width: this._props.PanelWidth() }} ref={this._annotationLayer} />;
}
marqueeDown = (e: React.PointerEvent) => {
- if (!e.altKey && e.button === 0 && NumCast(this.Document._freeform_scale, 1) <= NumCast(this.Document.freeform_scaleMin, 1) && this._props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
+ if (!e.altKey && e.button === 0 && NumCast(this.Document._freeform_scale, 1) <= NumCast(this.Document.freeform_scaleMin, 1) && this._props.isContentActive() && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
setupMoveUpEvents(
this,
e,
@@ -211,12 +216,12 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
.ScreenToLocalTransform()
.scale(this._props.NativeDimScaling?.() || 1)
.transformDirection(delta[0], delta[1]);
- const fullWidth = this._props.width;
- const mapWidth = fullWidth! - this.sidebarWidth();
+ const fullWidth = NumCast(this.layoutDoc._width);
+ const mapWidth = fullWidth - this.sidebarWidth();
if (this.sidebarWidth() + localDelta[0] > 0) {
this.layoutDoc._layout_showSidebar = true;
- this.layoutDoc._width = fullWidth! + localDelta[0];
- this.layoutDoc._layout_sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth! + localDelta[0])).toString() + '%';
+ this.layoutDoc._layout_sidebarWidthPercent = ((100 * (this.sidebarWidth() + localDelta[0])) / (fullWidth + localDelta[0])).toString() + '%';
+ this.layoutDoc._width = fullWidth + localDelta[0];
} else {
this.layoutDoc._layout_showSidebar = false;
this.layoutDoc._width = mapWidth;
@@ -269,12 +274,12 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
axes: this.axes,
//width: this.SidebarShown? this._props.PanelWidth()*.9/1.2: this._props.PanelWidth() * 0.9,
height: (this._props.PanelHeight() / scale - 32) /* height of 'change view' button */ * 0.9,
- width: (this._props.PanelWidth() / scale) * 0.9,
+ width: ((this._props.PanelWidth() - this.sidebarWidth()) / scale) * 0.9,
margin: { top: 10, right: 25, bottom: 75, left: 45 },
};
if (!this.records.length) return 'no data/visualization';
switch (this.dataVizView) {
- case DataVizView.TABLE: return <TableBox {...sharedProps} docView={this._props.DocumentView} selectAxes={this.selectAxes} />;
+ case DataVizView.TABLE: return <TableBox {...sharedProps} docView={this.DocumentView} selectAxes={this.selectAxes} />;
case DataVizView.LINECHART: return <LineChart {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => (this._vizRenderer = r ?? undefined)} vizBox={this} />;
case DataVizView.HISTOGRAM: return <Histogram {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => (this._vizRenderer = r ?? undefined)} />;
case DataVizView.PIECHART: return <PieChart {...sharedProps} dataDoc={this.dataDoc} fieldKey={this.fieldKey} ref={r => (this._vizRenderer = r ?? undefined)}
@@ -285,7 +290,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
@action
onPointerDown = (e: React.PointerEvent): void => {
if ((this.Document._freeform_scale || 1) !== 1) return;
- if (!e.altKey && e.button === 0 && this._props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
+ if (!e.altKey && e.button === 0 && this._props.isContentActive() && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
this._props.select(false);
MarqueeAnnotator.clearAnnotations(this._savedAnnotations);
this._marqueeing = [e.clientX, e.clientY];
@@ -345,7 +350,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
render() {
if (this.layoutDoc && this.layoutDoc.dataViz_asSchema) {
- this.schemaDataVizChildren = DocListCast(DocCast(this.layoutDoc.dataViz_asSchema)[Doc.LayoutFieldKey(DocCast(this.layoutDoc.dataViz_asSchema))]).length;
+ this._schemaDataVizChildren = DocListCast(DocCast(this.layoutDoc.dataViz_asSchema)[Doc.LayoutFieldKey(DocCast(this.layoutDoc.dataViz_asSchema))]).length;
this.updateSchemaViz();
}
@@ -366,7 +371,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}}
onWheel={e => e.stopPropagation()}
ref={this._mainCont}>
- <div className={'datatype-button'}>
+ <div className="datatype-button">
<Toggle text={' TABLE '} toggleType={ToggleType.BUTTON} type={Type.SEC} color={'black'} onClick={e => (this.layoutDoc._dataViz = DataVizView.TABLE)} toggleStatus={this.layoutDoc._dataViz === DataVizView.TABLE} />
<Toggle text={'LINECHART'} toggleType={ToggleType.BUTTON} type={Type.SEC} color={'black'} onClick={e => (this.layoutDoc._dataViz = DataVizView.LINECHART)} toggleStatus={this.layoutDoc._dataViz === DataVizView.LINECHART} />
<Toggle text={'HISTOGRAM'} toggleType={ToggleType.BUTTON} type={Type.SEC} color={'black'} onClick={e => (this.layoutDoc._dataViz = DataVizView.HISTOGRAM)} toggleStatus={this.layoutDoc._dataViz === DataVizView.HISTOGRAM} />
@@ -414,7 +419,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
</div>
{this.sidebarHandle}
{this.annotationLayer}
- {!this._mainCont.current || !this._annotationLayer.current ? null : (
+ {!this._mainCont.current || !this.DocumentView || !this._annotationLayer.current ? null : (
<MarqueeAnnotator
ref={this._marqueeref}
Document={this.Document}
@@ -422,7 +427,7 @@ export class DataVizBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
scrollTop={0}
annotationLayerScrollTop={NumCast(this.Document._layout_scrollTop)}
scaling={returnOne}
- docView={this._props.DocumentView!}
+ docView={this.DocumentView}
addDocument={this.sidebarAddDocument}
finishMarquee={this.finishMarquee}
savedAnnotations={this.savedAnnotations}
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 4cc7fe4c8..0d76959af 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -116,11 +116,12 @@ export class HTMLtag extends React.Component<HTMLtagProps> {
@observer
export class DocumentContentsView extends ObservableReactComponent<
- DocumentViewProps &
- FieldViewProps & {
- setHeight?: (height: number) => void;
- layout_fieldKey: string;
- }
+ FieldViewProps & {
+ layout_fieldKey: string;
+ LayoutTemplateString?: string;
+ onClick?: () => ScriptField;
+ LayoutTemplate?: () => Opt<Doc>;
+ }
> {
constructor(props: any) {
super(props);
diff --git a/src/client/views/nodes/DocumentIcon.tsx b/src/client/views/nodes/DocumentIcon.tsx
index dfd610581..25f56e69a 100644
--- a/src/client/views/nodes/DocumentIcon.tsx
+++ b/src/client/views/nodes/DocumentIcon.tsx
@@ -25,7 +25,7 @@ export class DocumentIcon extends ObservableReactComponent<DocumentIconProps> {
}
static get DocViews() {
- return LightboxView.LightboxDoc ? DocumentManager.Instance.DocumentViews.filter(v => LightboxView.IsLightboxDocView(v._props.docViewPath())) : DocumentManager.Instance.DocumentViews;
+ return LightboxView.LightboxDoc ? DocumentManager.Instance.DocumentViews.filter(v => LightboxView.IsLightboxDocView(v.docViewPath)) : DocumentManager.Instance.DocumentViews;
}
render() {
const view = this._props.view;
diff --git a/src/client/views/nodes/DocumentLinksButton.tsx b/src/client/views/nodes/DocumentLinksButton.tsx
index c549a146a..f5949a451 100644
--- a/src/client/views/nodes/DocumentLinksButton.tsx
+++ b/src/client/views/nodes/DocumentLinksButton.tsx
@@ -152,8 +152,8 @@ export class DocumentLinksButton extends ObservableReactComponent<DocumentLinksB
DocumentLinksButton.AnnotationUri = undefined;
//!this._props.StartLink
} else if (startLink !== endLink) {
- endLink = endLinkView?.docView?._componentView?.getAnchor?.(true, pinProps) || endLink;
- startLink = DocumentLinksButton.StartLinkView?.docView?._componentView?.getAnchor?.(true) || startLink;
+ endLink = endLinkView?.ComponentView?.getAnchor?.(true, pinProps) || endLink;
+ startLink = DocumentLinksButton.StartLinkView?.ComponentView?.getAnchor?.(true) || startLink;
const linkDoc = DocUtils.MakeLink(startLink, endLink, { link_relationship: DocumentLinksButton.AnnotationId ? 'hypothes.is annotation' : undefined });
LinkManager.currentLink = linkDoc;
diff --git a/src/client/views/nodes/DocumentView.tsx b/src/client/views/nodes/DocumentView.tsx
index 6cc61ec62..5345ef0d8 100644
--- a/src/client/views/nodes/DocumentView.tsx
+++ b/src/client/views/nodes/DocumentView.tsx
@@ -109,7 +109,7 @@ export interface DocFocusOptions {
easeFunc?: 'linear' | 'ease'; // transition method for scrolling
}
export type DocFocusFunc = (doc: Doc, options: DocFocusOptions) => Opt<number>;
-export type StyleProviderFunc = (doc: Opt<Doc>, props: Opt<DocumentViewInternalProps | FieldViewProps>, property: string) => any;
+export type StyleProviderFunc = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => any;
export interface DocComponentView {
fieldKey?: string;
annotationKey?: string;
@@ -143,20 +143,31 @@ export interface DocComponentView {
snapPt?: (pt: { X: number; Y: number }, excludeSegs?: number[]) => { nearestPt: { X: number; Y: number }; distance: number };
search?: (str: string, bwd?: boolean, clear?: boolean) => boolean;
}
-// These props are passed to both FieldViews and DocumentViews
+/**
+ * props that DocumentViews, DocumentInternalViews and FieldViews all can use
+ * */
export interface DocumentViewSharedProps {
- renderDepth: number;
Document: Doc;
TemplateDataDocument?: Doc;
+ renderDepth: number;
scriptContext?: any; // can be assigned anything and will be passed as 'scriptContext' to any OnClick script that executes on this document
- DocumentView?: () => DocumentView;
+ treeViewDoc?: Doc;
+ xPadding?: number;
+ yPadding?: number;
+ dontRegisterView?: boolean;
+ dropAction?: dropActionType;
+ dragAction?: dropActionType;
+ forceAutoHeight?: boolean;
+ ignoreAutoHeight?: boolean;
+ disableBrushing?: boolean; // should highlighting for this view be disabled when same document in another view is hovered over.
CollectionFreeFormDocumentView?: () => CollectionFreeFormDocumentView;
fitContentsToBox?: () => boolean; // used by freeformview to fit its contents to its panel. corresponds to _freeform_fitContentsToBox property on a Document
isGroupActive?: () => string | undefined; // is this document part of a group that is active
setContentView?: (view: DocComponentView) => any;
PanelWidth: () => number;
PanelHeight: () => number;
- docViewPath: () => DocumentView[];
+ isDocumentActive?: () => boolean | undefined; // whether a document should handle pointer events
+ isContentActive: () => boolean | undefined; // whether document contents should handle pointer events
childFilters: () => string[];
childFiltersByRanges: () => string[];
styleProvider: Opt<StyleProviderFunc>;
@@ -178,29 +189,12 @@ export interface DocumentViewSharedProps {
waitForDoubleClickToClick?: () => 'never' | 'always' | undefined;
defaultDoubleClick?: () => 'default' | 'ignore' | undefined;
pointerEvents?: () => Opt<string>;
- treeViewDoc?: Doc;
- xPadding?: number;
- yPadding?: number;
- dontRegisterView?: boolean;
- childHideDecorationTitle?: boolean;
- childHideResizeHandles?: boolean;
- childDragAction?: dropActionType; // allows child documents to be dragged out of collection without holding the embedKey or dragging the doc decorations title bar.
- dropAction?: dropActionType;
- dragAction?: dropActionType;
- dragWhenActive?: boolean;
- dontHideOnDrag?: boolean;
- hideLinkButton?: boolean;
- hideCaptions?: boolean;
- ignoreAutoHeight?: boolean;
- forceAutoHeight?: boolean;
- suppressSetHeight?: boolean;
- disableBrushing?: boolean; // should highlighting for this view be disabled when same document in another view is hovered over.
- onClickScriptDisable?: 'never' | 'always'; // undefined = only when selected
}
-// these props are specific to DocuentViews
+/**
+ * props that are used by DocumentViews and DocumentInternalViews but not by the contents of those views (FieldViews).
+ */
export interface DocumentViewProps extends DocumentViewSharedProps {
- // properties specific to DocumentViews but not to FieldView
hideDecorations?: boolean; // whether to suppress all DocumentDecorations when doc is selected
hideResizeHandles?: boolean; // whether to suppress resized handles on doc decorations when this document is selected
hideTitle?: boolean; // forces suppression of title. e.g, treeView document labels suppress titles in case they are globally active via settings
@@ -209,15 +203,22 @@ export interface DocumentViewProps extends DocumentViewSharedProps {
hideOpenButton?: boolean;
hideDeleteButton?: boolean;
hideLinkAnchors?: boolean;
+ hideLinkButton?: boolean;
+ hideCaptions?: boolean;
contentPointerEvents?: 'none' | 'all' | undefined; // pointer events allowed for content of a document view. eg. set to "none" in menuSidebar for sharedDocs so that you can select a document, but not interact with its contents
LayoutTemplateString?: string;
dontCenter?: 'x' | 'y' | 'xy';
- isDocumentActive?: () => boolean | undefined; // whether a document should handle pointer events
- isContentActive: () => boolean | undefined; // whether document contents should handle pointer events
+ childHideDecorationTitle?: boolean;
+ childHideResizeHandles?: boolean;
+ childDragAction?: dropActionType; // allows child documents to be dragged out of collection without holding the embedKey or dragging the doc decorations title bar.
+ dragWhenActive?: boolean;
+ dontHideOnDrag?: boolean;
+ suppressSetHeight?: boolean;
+ onClickScriptDisable?: 'never' | 'always'; // undefined = only when selected
NativeWidth?: () => number;
NativeHeight?: () => number;
- NativeDimScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal NOTE: Must also be added to FieldViewProps
LayoutTemplate?: () => Opt<Doc>;
+ containerViewPath?: () => DocumentView[];
contextMenuItems?: () => { script: ScriptField; filter?: ScriptField; label: string; icon: string }[];
onClick?: () => ScriptField;
onDoubleClick?: () => ScriptField;
@@ -229,12 +230,18 @@ export interface DocumentViewProps extends DocumentViewSharedProps {
dragEnding?: () => void;
}
-// these props are only available in DocumentViewIntenral
-export interface DocumentViewInternalProps extends DocumentViewProps {
- isSelected: () => boolean;
+/**
+ * props used by DocInternalViews and FieldViews but not DocumentViews
+ * these props correspond to things that the DocumentView creates and thus doesn't need to receive as a prop
+ */
+export interface DocumentViewInternalSharedProps {
+ DocumentView?: () => DocumentView;
select: (ctrlPressed: boolean, shiftPress?: boolean) => void;
- DocumentView: () => DocumentView;
- viewPath: () => DocumentView[];
+ isSelected: () => boolean;
+ NativeDimScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal
+}
+export interface DocumentViewInternalProps extends DocumentViewProps, DocumentViewInternalSharedProps {
+ docViewPath: () => DocumentView[];
}
@observer
@@ -265,17 +272,24 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
return this._animateScaleTime ?? 100;
}
public get displayName() {
- return 'DocumentViewInternal(' + this._props.Document.title + ')';
+ return 'DocumentViewInternal(' + this.Document.title + ')';
} // this makes mobx trace() statements more descriptive
+ public get DocumentView() {
+ return this._props.DocumentView!;
+ }
+
public get ContentDiv() {
return this._mainCont.current;
}
public get LayoutFieldKey() {
return Doc.LayoutFieldKey(this.layoutDoc);
}
+ @computed get styleProps(): FieldViewProps {
+ return { ...this._props, fieldKey: '' };
+ }
@computed get layout_showTitle() {
- return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.ShowTitle) as Opt<string>;
+ return this._props.styleProvider?.(this.layoutDoc, this.styleProps, StyleProp.ShowTitle) as Opt<string>;
}
@computed get NativeDimScaling() {
return this._props.NativeDimScaling?.() || 1;
@@ -284,32 +298,32 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
return ImageCast(this.layoutDoc['thumb-frozen'], ImageCast(this.layoutDoc.thumb))?.url?.href.replace('.png', '_m.png');
}
@computed get opacity() {
- return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Opacity);
+ return this._props.styleProvider?.(this.layoutDoc, this.styleProps, StyleProp.Opacity);
}
@computed get boxShadow() {
- return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BoxShadow);
+ return this._props.styleProvider?.(this.layoutDoc, this.styleProps, StyleProp.BoxShadow);
}
@computed get borderRounding() {
- return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BorderRounding);
+ return this._props.styleProvider?.(this.layoutDoc, this.styleProps, StyleProp.BorderRounding);
}
@computed get widgetDecorations() {
TraceMobx();
- return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.Decorations);
+ return this._props.styleProvider?.(this.layoutDoc, this.styleProps, StyleProp.Decorations);
}
@computed get backgroundBoxColor() {
- return this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor + ':box');
+ return this._props.styleProvider?.(this.layoutDoc, this.styleProps, StyleProp.BackgroundColor + ':box');
}
@computed get docContents() {
- return this._props.styleProvider?.(this.Document, this._props, StyleProp.DocContents);
+ return this._props.styleProvider?.(this.Document, this.styleProps, StyleProp.DocContents);
}
@computed get headerMargin() {
- return this._props?.styleProvider?.(this.layoutDoc, this._props, StyleProp.HeaderMargin) || 0;
+ return this._props?.styleProvider?.(this.layoutDoc, this.styleProps, StyleProp.HeaderMargin) || 0;
}
@computed get layout_showCaption() {
- return this._props?.styleProvider?.(this.layoutDoc, this._props, StyleProp.ShowCaption) || 0;
+ return this._props?.hideCaptions ? undefined : this._props?.styleProvider?.(this.layoutDoc, this.styleProps, StyleProp.ShowCaption) || 0;
}
@computed get titleHeight() {
- return this._props?.styleProvider?.(this.layoutDoc, this._props, StyleProp.TitleHeight) || 0;
+ return this._props?.styleProvider?.(this.layoutDoc, this.styleProps, StyleProp.TitleHeight) || 0;
}
@observable _pointerEvents: 'none' | 'all' | 'visiblePainted' | undefined = undefined;
@computed get pointerEvents(): 'none' | 'all' | 'visiblePainted' | undefined {
@@ -363,7 +377,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
{ fireImmediately: true }
);
this._disposers.pointerevents = reaction(
- () => this._props.styleProvider?.(this.Document, this._props, StyleProp.PointerEvents),
+ () => this._props.styleProvider?.(this.Document, this.styleProps, StyleProp.PointerEvents),
pointerevents => (this._pointerEvents = pointerevents),
{ fireImmediately: true }
);
@@ -378,32 +392,32 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
setupHandlers() {
this.cleanupHandlers(false);
if (this._mainCont.current) {
- this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this), this._props.Document, this.preDropFunc);
+ this._dropDisposer = DragManager.MakeDropTarget(this._mainCont.current, this.drop.bind(this), this.Document, this.preDropFunc);
}
}
cleanupHandlers(unbrush: boolean) {
this._dropDisposer?.();
- unbrush && Doc.UnBrushDoc(this._props.Document);
+ unbrush && Doc.UnBrushDoc(this.Document);
Object.values(this._disposers).forEach(disposer => disposer?.());
}
startDragging(x: number, y: number, dropAction: dropActionType, hideSource = false) {
if (this._mainCont.current) {
- const views = SelectionManager.Views.filter(dv => dv.docView?._mainCont.current);
- const selected = views.length > 1 && views.some(dv => dv.Document === this.Document) ? views : [this._props.DocumentView()];
+ const views = SelectionManager.Views.filter(dv => dv.ContentDiv);
+ const selected = views.length > 1 && views.some(dv => dv.Document === this.Document) ? views : [this.DocumentView()];
const dragData = new DragManager.DocumentDragData(selected.map(dv => dv.Document));
- const screenXf = this.props.DocumentView().screenToViewTransform();
+ const screenXf = this.DocumentView().screenToViewTransform();
const [left, top] = screenXf.inverse().transformPoint(0, 0);
dragData.offset = screenXf.transformDirection(x - left, y - top);
dragData.dropAction = dropAction;
dragData.treeViewDoc = this._props.treeViewDoc;
dragData.removeDocument = this._props.removeDocument;
dragData.moveDocument = this._props.moveDocument;
- dragData.draggedViews = [this._props.DocumentView()];
+ dragData.draggedViews = [this.DocumentView()];
dragData.canEmbed = this.Document.dragAction ?? this._props.dragAction ? true : false;
DragManager.StartDocumentDrag(
- selected.map(dv => dv.docView!._mainCont.current!),
+ selected.map(dv => dv.ContentDiv!),
dragData,
x,
y,
@@ -443,7 +457,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
const func = () => this.onDoubleClickHandler.script.run( {
this: this.Document,
scriptContext: this._props.scriptContext,
- documentView: this._props.DocumentView(),
+ documentView: this.DocumentView(),
clientX, clientY, altKey, shiftKey, ctrlKey,
value: undefined,
}, console.log );
@@ -451,7 +465,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
} else if (!Doc.IsSystem(this.Document) && (defaultDblclick === undefined || defaultDblclick === 'default')) {
UndoManager.RunInBatch(() => LightboxView.Instance.AddDocTab(this.Document, OpenWhere.lightbox), 'double tap');
SelectionManager.DeselectAll();
- Doc.UnBrushDoc(this._props.Document);
+ Doc.UnBrushDoc(this.Document);
} else {
this._singleClickFunc?.();
}
@@ -474,7 +488,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
this: this.Document,
_readOnly_: false,
scriptContext: this._props.scriptContext,
- documentView: this._props.DocumentView(),
+ documentView: this.DocumentView(),
clientX,
clientY,
shiftKey,
@@ -498,7 +512,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
const sendToBack = e.altKey;
this._singleClickFunc =
// prettier-ignore
- clickFunc ?? (() => (sendToBack ? this._props.DocumentView()._props.bringToFront(this.Document, true) :
+ clickFunc ?? (() => (sendToBack ? this.DocumentView()._props.bringToFront(this.Document, true) :
this._componentView?.select?.(e.ctrlKey || e.metaKey, e.shiftKey) ??
this._props.select(e.ctrlKey||e.shiftKey, e.metaKey)));
const waitFordblclick = this._props.waitForDoubleClickToClick?.() ?? this.Document.waitForDoubleClickToClick;
@@ -522,7 +536,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
this._props.select(false);
}
}, 1000);
- if (!GestureOverlay.DownDocView) GestureOverlay.DownDocView = this._props.DocumentView();
+ if (!GestureOverlay.DownDocView) GestureOverlay.DownDocView = this.DocumentView();
this._downX = e.clientX;
this._downY = e.clientY;
@@ -600,7 +614,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
this.Document.onClick = Doc.GetProto(this.Document).onClick = undefined;
};
- @undoBatch deleteClicked = () => this._props.removeDocument?.(this._props.Document);
+ @undoBatch deleteClicked = () => this._props.removeDocument?.(this.Document);
@undoBatch setToggleDetail = () =>
(this.Document.onClick = ScriptField.MakeScript(
`toggleDetail(documentView, "${StrCast(this.Document.layout_fieldKey)
@@ -612,7 +626,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
@undoBatch
drop = (e: Event, de: DragManager.DropEvent) => {
if (this._props.dontRegisterView || this._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) return false;
- if (this._props.Document === Doc.ActiveDashboard) {
+ if (this.Document === Doc.ActiveDashboard) {
e.stopPropagation();
e.preventDefault();
alert(
@@ -634,7 +648,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
de.complete.linkDocument = DocUtils.MakeLink(linkdrag.linkSourceDoc, dropDoc, {}, undefined, [de.x, de.y - 50]);
if (de.complete.linkDocument) {
de.complete.linkDocument.layout_isSvg = true;
- this._props.DocumentView().CollectionFreeFormView?.addDocument(de.complete.linkDocument);
+ this.DocumentView().CollectionFreeFormView?.addDocument(de.complete.linkDocument);
}
}
e.stopPropagation();
@@ -646,16 +660,16 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
@undoBatch
makeIntoPortal = () => {
- const portalLink = this.allLinks.find(d => d.link_anchor_1 === this._props.Document && d.link_relationship === 'portal to:portal from');
+ const portalLink = this.allLinks.find(d => d.link_anchor_1 === this.Document && d.link_relationship === 'portal to:portal from');
if (!portalLink) {
DocUtils.MakeLink(
- this._props.Document,
+ this.Document,
Docs.Create.FreeformDocument([], {
_width: NumCast(this.layoutDoc._width) + 10,
_height: Math.max(NumCast(this.layoutDoc._height), NumCast(this.layoutDoc._width) + 10),
_isLightbox: true,
_layout_fitWidth: true,
- title: StrCast(this._props.Document.title) + ' [Portal]',
+ title: StrCast(this.Document.title) + ' [Portal]',
}),
{ link_relationship: 'portal to:portal from' }
);
@@ -686,7 +700,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
if (e && this.layoutDoc._layout_hideContextMenu && Doc.noviceMode) {
e.preventDefault();
e.stopPropagation();
- //!this._props.isSelected(true) && SelectionManager.SelectView(this._props.DocumentView(), false);
+ //!this._props.isSelected(true) && SelectionManager.SelectView(this.DocumentView(), false);
}
// the touch onContextMenu is button 0, the pointer onContextMenu is button 2
if (e) {
@@ -708,7 +722,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
if (e && !(e.nativeEvent as any).dash) {
const onDisplay = () => {
- if (this.Document.type !== DocumentType.MAP) DocumentViewInternal.SelectAfterContextMenu && !this._props.isSelected() && SelectionManager.SelectView(this._props.DocumentView(), false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear.
+ if (this.Document.type !== DocumentType.MAP) DocumentViewInternal.SelectAfterContextMenu && !this._props.isSelected() && SelectionManager.SelectView(this.DocumentView(), false); // on a mac, the context menu is triggered on mouse down, but a YouTube video becaomes interactive when selected which means that the context menu won't show up. by delaying the selection until hopefully after the pointer up, the context menu will appear.
setTimeout(() => simulateMouseClick(document.elementFromPoint(e.clientX, e.clientY), e.clientX, e.clientY, e.screenX, e.screenY));
};
if (navigator.userAgent.includes('Macintosh')) {
@@ -719,14 +733,14 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
return;
}
- const customScripts = Cast(this._props.Document.contextMenuScripts, listSpec(ScriptField), []);
+ const customScripts = Cast(this.Document.contextMenuScripts, listSpec(ScriptField), []);
StrListCast(this.Document.contextMenuLabels).forEach((label, i) =>
cm.addItem({ description: label, event: () => customScripts[i]?.script.run({ documentView: this, this: this.Document, scriptContext: this._props.scriptContext }), icon: 'sticky-note' })
);
this._props.contextMenuItems?.().forEach(item => item.label && cm.addItem({ description: item.label, event: () => item.script.script.run({ this: this.Document, scriptContext: this._props.scriptContext }), icon: item.icon as IconProp }));
- if (!this._props.Document.isFolder) {
- const templateDoc = Cast(this._props.Document[StrCast(this._props.Document.layout_fieldKey)], Doc, null);
+ if (!this.Document.isFolder) {
+ const templateDoc = Cast(this.Document[StrCast(this.Document.layout_fieldKey)], Doc, null);
const appearance = cm.findByDescription('Appearance...');
const appearanceItems: ContextMenuProps[] = appearance && 'subitems' in appearance ? appearance.subitems : [];
@@ -764,7 +778,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
!options && cm.addItem({ description: 'Options...', subitems: optionItems, icon: 'compass' });
onClicks.push({ description: this.onClickHandler ? 'Remove Click Behavior' : 'Follow Link', event: () => this.toggleFollowLink(false, false), icon: 'link' });
- !Doc.noviceMode && onClicks.push({ description: 'Edit onClick Script', event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this._props.Document, undefined, 'onClick'), 'edit onClick'), icon: 'terminal' });
+ !Doc.noviceMode && onClicks.push({ description: 'Edit onClick Script', event: () => UndoManager.RunInBatch(() => DocUtils.makeCustomViewClicked(this.Document, undefined, 'onClick'), 'edit onClick'), icon: 'terminal' });
!existingOnClick && cm.addItem({ description: 'OnClick...', noexpand: true, subitems: onClicks, icon: 'mouse-pointer' });
} else if (LinkManager.Links(this.Document).length) {
onClicks.push({ description: 'Restore On Click default', event: () => this.noOnClick(), icon: 'link' });
@@ -786,15 +800,15 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
const moreItems = more && 'subitems' in more ? more.subitems : [];
if (!Doc.IsSystem(this.Document)) {
if (!Doc.noviceMode) {
- moreItems.push({ description: 'Make View of Metadata Field', event: () => Doc.MakeMetadataFieldTemplate(this._props.Document, this._props.TemplateDataDocument), icon: 'concierge-bell' });
+ moreItems.push({ description: 'Make View of Metadata Field', event: () => Doc.MakeMetadataFieldTemplate(this.Document, this._props.TemplateDataDocument), icon: 'concierge-bell' });
moreItems.push({ description: `${this.Document._chromeHidden ? 'Show' : 'Hide'} Chrome`, event: () => (this.Document._chromeHidden = !this.Document._chromeHidden), icon: 'project-diagram' });
- if (Cast(Doc.GetProto(this._props.Document).data, listSpec(Doc))) {
- moreItems.push({ description: 'Export to Google Photos Album', event: () => GooglePhotos.Export.CollectionToAlbum({ collection: this._props.Document }).then(console.log), icon: 'caret-square-right' });
- moreItems.push({ description: 'Tag Child Images via Google Photos', event: () => GooglePhotos.Query.TagChildImages(this._props.Document), icon: 'caret-square-right' });
- moreItems.push({ description: 'Write Back Link to Album', event: () => GooglePhotos.Transactions.AddTextEnrichment(this._props.Document), icon: 'caret-square-right' });
+ if (Cast(Doc.GetProto(this.Document).data, listSpec(Doc))) {
+ moreItems.push({ description: 'Export to Google Photos Album', event: () => GooglePhotos.Export.CollectionToAlbum({ collection: this.Document }).then(console.log), icon: 'caret-square-right' });
+ moreItems.push({ description: 'Tag Child Images via Google Photos', event: () => GooglePhotos.Query.TagChildImages(this.Document), icon: 'caret-square-right' });
+ moreItems.push({ description: 'Write Back Link to Album', event: () => GooglePhotos.Transactions.AddTextEnrichment(this.Document), icon: 'caret-square-right' });
}
- moreItems.push({ description: 'Copy ID', event: () => Utils.CopyText(Doc.globalServerPath(this._props.Document)), icon: 'fingerprint' });
+ moreItems.push({ description: 'Copy ID', event: () => Utils.CopyText(Doc.globalServerPath(this.Document)), icon: 'fingerprint' });
}
}
@@ -802,14 +816,14 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
const constantItems: ContextMenuProps[] = [];
if (!Doc.IsSystem(this.Document) && this.Document._type_collection !== CollectionViewType.Docking) {
- constantItems.push({ description: 'Zip Export', icon: 'download', event: async () => Doc.Zip(this._props.Document) });
- (this.Document._type_collection !== CollectionViewType.Docking || !Doc.noviceMode) && constantItems.push({ description: 'Share', event: () => SharingManager.Instance.open(this._props.DocumentView()), icon: 'users' });
- if (this._props.removeDocument && Doc.ActiveDashboard !== this._props.Document) {
+ constantItems.push({ description: 'Zip Export', icon: 'download', event: async () => Doc.Zip(this.Document) });
+ (this.Document._type_collection !== CollectionViewType.Docking || !Doc.noviceMode) && constantItems.push({ description: 'Share', event: () => SharingManager.Instance.open(this.DocumentView()), icon: 'users' });
+ if (this._props.removeDocument && Doc.ActiveDashboard !== this.Document) {
// need option to gray out menu items ... preferably with a '?' that explains why they're grayed out (eg., no permissions)
constantItems.push({ description: 'Close', event: this.deleteClicked, icon: 'times' });
}
}
- constantItems.push({ description: 'Show Metadata', event: () => this._props.addDocTab(this._props.Document, OpenWhere.addRightKeyvalue), icon: 'table-columns' });
+ constantItems.push({ description: 'Show Metadata', event: () => this._props.addDocTab(this.Document, OpenWhere.addRightKeyvalue), icon: 'table-columns' });
cm.addItem({ description: 'General...', noexpand: false, subitems: constantItems, icon: 'question' });
const help = cm.findByDescription('Help...');
@@ -820,7 +834,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
let documentationDescription: string | undefined = undefined;
let documentationLink: string | undefined = undefined;
- switch (this._props.Document.type) {
+ switch (this.Document.type) {
case DocumentType.COL:
documentationDescription = 'See collection documentation';
documentationLink = 'https://brown-dash.github.io/Dash-Documentation/views/';
@@ -874,7 +888,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
rootSelected = () => this._rootSelected;
panelHeight = () => this._props.PanelHeight() - this.headerMargin;
- screenToLocalContent = () => this.ScreenToLocalBoxXf().translate(0, -this.headerMargin);
+ screenToLocalContent = () => this._props.ScreenToLocalTransform().translate(0, -this.headerMargin);
onClickFunc: any = () => (this.disableClickScriptFunc ? undefined : this.onClickHandler);
setHeight = (height: number) => !this._props.suppressSetHeight && (this.layoutDoc._height = height);
setContentView = action((view: { getAnchor?: (addAsAnnotation: boolean) => Doc; forward?: () => boolean; back?: () => boolean }) => (this._componentView = view));
@@ -912,7 +926,6 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
{...this._props}
fieldKey=""
pointerEvents={this.contentPointerEvents}
- docViewPath={this._props.viewPath}
setContentView={this.setContentView}
childFilters={this.childFilters}
PanelHeight={this.panelHeight}
@@ -931,7 +944,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
anchorPanelWidth = () => this._props.PanelWidth() || 1;
anchorPanelHeight = () => this._props.PanelHeight() || 1;
- anchorStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewInternalProps | FieldViewProps>, property: string): any => {
+ anchorStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string): any => {
// prettier-ignore
switch (property.split(':')[0]) {
case StyleProp.ShowTitle: return '';
@@ -976,7 +989,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
{...this._props}
isContentActive={returnFalse}
Document={link}
- docViewPath={this._props.viewPath}
+ containerViewPath={this._props.docViewPath}
PanelWidth={this.anchorPanelWidth}
PanelHeight={this.anchorPanelHeight}
dontRegisterView={false}
@@ -1066,7 +1079,7 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
};
- captionStyleProvider = (doc: Opt<Doc>, props: Opt<DocumentViewInternalProps | FieldViewProps>, property: string) => this._props?.styleProvider?.(doc, props, property + ':caption');
+ captionStyleProvider = (doc: Opt<Doc>, props: Opt<FieldViewProps>, property: string) => this._props?.styleProvider?.(doc, props, property + ':caption');
@observable _changingTitleField = false;
@observable _dropDownInnerWidth = 0;
fieldsDropdown = (inputOptions: string[], dropdownWidth: number, placeholder: string, onChange: (val: string | number) => void, onClose: () => void) => {
@@ -1266,10 +1279,10 @@ export class DocumentViewInternal extends DocComponent<DocumentViewInternalProps
}
}
@computed get highlighting() {
- return this._props.styleProvider?.(this.Document, this._props, StyleProp.Highlighting);
+ return this._props.styleProvider?.(this.Document, { ...this._props, fieldKey: '' }, StyleProp.Highlighting);
}
@computed get borderPath() {
- return this._props.styleProvider?.(this.Document, this._props, StyleProp.BorderPath);
+ return this._props.styleProvider?.(this.Document, { ...this._props, fieldKey: '' }, StyleProp.BorderPath);
}
render() {
TraceMobx();
@@ -1332,14 +1345,13 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
@computed public static get exploreMode() {
return () => (SnappingManager.ExploreMode ? ScriptField.MakeScript('CollectionBrowseClick(documentView, clientX, clientY)', { documentView: 'any', clientX: 'number', clientY: 'number' })! : undefined);
}
- @observable public docView: DocumentViewInternal | undefined | null = undefined;
- @observable public textHtmlOverlay: Opt<string> = undefined;
- @observable public textHtmlOverlayTime: Opt<number> = undefined;
+ @observable private _docViewInternal: DocumentViewInternal | undefined | null = undefined;
+ @observable private _htmlOverlayText: Opt<string> = undefined;
@observable private _isHovering = false;
+ private _htmlOverlayEffect: Opt<Doc>;
- public htmlOverlayEffect: Opt<Doc>;
public get displayName() {
- return 'DocumentView(' + this._props.Document?.title + ')';
+ return 'DocumentView(' + this.Document?.title + ')';
} // this makes mobx trace() statements more descriptive
public ContentRef = React.createRef<HTMLDivElement>();
public ViewTimer: NodeJS.Timeout | undefined; // timer for res
@@ -1349,10 +1361,26 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
this.ViewTimer && clearTimeout(this.ViewTimer);
this.layoutDoc._viewTransition = undefined;
};
- public startDragging = (x: number, y: number, dropAction: dropActionType, hideSource = false) => this.docView?.startDragging(x, y, dropAction, hideSource);
-
- public showContextMenu = (pageX: number, pageY: number) => this.docView?.onContextMenu(undefined, pageX, pageY);
-
+ playAnnotation = () => this._docViewInternal?.playAnnotation();
+ noOnClick = () => this._docViewInternal?.noOnClick();
+ makeIntoPortal = () => this._docViewInternal?.makeIntoPortal();
+ setToggleDetail = () => this._docViewInternal?.setToggleDetail();
+ onContextMenu = (e?: React.MouseEvent, pageX?: number, pageY?: number) => this._docViewInternal?.onContextMenu?.(e, pageX, pageY);
+ cleanupPointerEvents = () => this._docViewInternal?.cleanupPointerEvents();
+ public startDragging = (x: number, y: number, dropAction: dropActionType, hideSource = false) => this._docViewInternal?.startDragging(x, y, dropAction, hideSource);
+
+ public showContextMenu = (pageX: number, pageY: number) => this._docViewInternal?.onContextMenu(undefined, pageX, pageY);
+
+ public setTextHtmlOverlay = action((text: string | undefined, effect?: Doc) => {
+ this._htmlOverlayText = text;
+ this._htmlOverlayEffect = effect;
+ });
+ public setAnimateScaling = action((scale: number, time?: number) => {
+ if (this._docViewInternal) {
+ this._docViewInternal._animateScalingTo = scale;
+ this._docViewInternal._animateScaleTime = time;
+ }
+ });
public setAnimEffect = (presEffect: Doc, timeInMs: number, afterTrans?: () => void) => {
this.AnimEffectTimer && clearTimeout(this.AnimEffectTimer);
this.Document[Animation] = presEffect;
@@ -1391,10 +1419,11 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
DocServer.GetRefField(docId).then(docx =>
LightboxView.Instance.SetLightboxDoc(
(docx as Doc) ?? // reuse existing pivot view of documents, or else create a new collection
- Docs.Create.StackingDocument([], { title: linkAnchor.title + '-pivot', _width: 500, _height: 500, target: linkAnchor, updateContentsScript: ScriptField.MakeScript('updateLinkCollection(this, this.target)') }, docId)
+ Docs.Create.StackingDocument([], { title: linkAnchor.title + '-pivot', _width: 500, _height: 500, target: linkAnchor, onViewMounted: ScriptField.MakeScript('updateLinkCollection(this, this.target)') }, docId)
)
);
}
+ toggleFollowLink = (zoom?: boolean, setTargetToggle?: boolean): void => this._docViewInternal?.toggleFollowLink(zoom, setTargetToggle);
get Document() {
return this._props.Document;
@@ -1403,19 +1432,19 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
return this._props.renderDepth === 0;
}
get dataDoc() {
- return this.docView?.dataDoc ?? this.Document;
+ return this._docViewInternal?.dataDoc ?? this.Document;
}
get ContentDiv() {
- return this.docView?.ContentDiv;
+ return this._docViewInternal?.ContentDiv;
}
get ComponentView() {
- return this.docView?._componentView;
+ return this._docViewInternal?._componentView;
}
get allLinks() {
- return (this.docView?.allLinks || []).filter(link => !link.link_matchEmbeddings || link.link_anchor_1 === this.Document || link.link_anchor_2 === this.Document);
+ return (this._docViewInternal?.allLinks || []).filter(link => !link.link_matchEmbeddings || link.link_anchor_1 === this.Document || link.link_anchor_2 === this.Document);
}
get LayoutFieldKey() {
- return this.docView?.LayoutFieldKey || 'layout';
+ return this._docViewInternal?.LayoutFieldKey || 'layout';
}
@computed get layout_fitWidth() {
return this._props.layout_fitWidth?.(this.layoutDoc) ?? this.layoutDoc?.layout_fitWidth;
@@ -1439,8 +1468,17 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
@computed get linkCountView() {
return <DocumentLinksButton hideCount={this.hideLinkCount} View={this} scaling={this.screenToLocalScale} OnHover={true} Bottom={this.topMost} ShowCount={true} />;
}
+ /**
+ * path of DocumentViews terminating in the DocumentView that contains this DocumentView
+ */
+ @computed get containerViewPath() {
+ return this._props.containerViewPath;
+ }
+ /**
+ * path of DocumentViews terminating in this DocumentView
+ */
@computed get docViewPath(): DocumentView[] {
- return this._props.docViewPath ? [...this._props.docViewPath(), this] : [this];
+ return this.containerViewPath ? [...this.containerViewPath(), this] : [this];
}
@computed get layoutDoc() {
return Doc.Layout(this.Document, this._props.LayoutTemplate?.());
@@ -1502,19 +1540,19 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
return this._props.CollectionFreeFormDocumentView?.();
}
- public toggleNativeDimensions = () => this.docView && this.Document.type !== DocumentType.INK && Doc.toggleNativeDimensions(this.layoutDoc, this.docView.NativeDimScaling, this._props.PanelWidth(), this._props.PanelHeight());
+ public toggleNativeDimensions = () => this._docViewInternal && this.Document.type !== DocumentType.INK && Doc.toggleNativeDimensions(this.layoutDoc, this._docViewInternal.NativeDimScaling, this._props.PanelWidth(), this._props.PanelHeight());
public getBounds = () => {
- if (!this.docView?.ContentDiv || this._props.treeViewDoc || Doc.AreProtosEqual(this._props.Document, Doc.UserDoc())) {
+ if (!this._docViewInternal?.ContentDiv || this._props.treeViewDoc || Doc.AreProtosEqual(this.Document, Doc.UserDoc())) {
return undefined;
}
- if (this.docView._componentView?.screenBounds?.()) {
- return this.docView._componentView.screenBounds();
+ if (this._docViewInternal._componentView?.screenBounds?.()) {
+ return this._docViewInternal._componentView.screenBounds();
}
- const xf = this.docView.ScreenToLocalBoxXf().scale(this.nativeScaling).inverse();
+ const xf = this._docViewInternal._props.ScreenToLocalTransform().scale(this.nativeScaling).inverse();
const [[left, top], [right, bottom]] = [xf.transformPoint(0, 0), xf.transformPoint(this.panelWidth, this.panelHeight)];
- if (this.docView._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
- const docuBox = this.docView.ContentDiv.getElementsByClassName('linkAnchorBox-cont');
+ if (this._docViewInternal._props.LayoutTemplateString?.includes(LinkAnchorBox.name)) {
+ const docuBox = this._docViewInternal.ContentDiv.getElementsByClassName('linkAnchorBox-cont');
if (docuBox.length) return { ...docuBox[0].getBoundingClientRect(), center: undefined };
}
return { left, top, right, bottom };
@@ -1522,11 +1560,11 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
public iconify(finished?: () => void, animateTime?: number) {
this.ComponentView?.updateIcon?.();
- const animTime = this.docView?._animateScaleTime;
- runInAction(() => this.docView && animateTime !== undefined && (this.docView._animateScaleTime = animateTime));
+ const animTime = this._docViewInternal?._animateScaleTime;
+ runInAction(() => this._docViewInternal && animateTime !== undefined && (this._docViewInternal._animateScaleTime = animateTime));
const finalFinished = action(() => {
finished?.();
- this.docView && (this.docView._animateScaleTime = animTime);
+ this._docViewInternal && (this._docViewInternal._animateScaleTime = animTime);
});
const layout_fieldKey = Cast(this.Document.layout_fieldKey, 'string', null);
if (layout_fieldKey !== 'layout_icon') {
@@ -1541,12 +1579,12 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
}
@undoBatch
setCustomView = (custom: boolean, layout: string): void => {
- Doc.setNativeView(this._props.Document);
- custom && DocUtils.makeCustomViewClicked(this._props.Document, Docs.Create.StackingDocument, layout, undefined);
+ Doc.setNativeView(this.Document);
+ custom && DocUtils.makeCustomViewClicked(this.Document, Docs.Create.StackingDocument, layout, undefined);
};
switchViews = (custom: boolean, view: string, finished?: () => void, useExistingLayout = false) => {
- runInAction(() => this.docView && (this.docView._animateScalingTo = 0.1)); // shrink doc
+ runInAction(() => this._docViewInternal && (this._docViewInternal._animateScalingTo = 0.1)); // shrink doc
setTimeout(
action(() => {
if (useExistingLayout && custom && this.Document['layout_' + view]) {
@@ -1554,16 +1592,16 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
} else {
this.setCustomView(custom, view);
}
- this.docView && (this.docView._animateScalingTo = 1); // expand it
+ this._docViewInternal && (this._docViewInternal._animateScalingTo = 1); // expand it
setTimeout(
action(() => {
- this.docView && (this.docView._animateScalingTo = 0);
+ this._docViewInternal && (this._docViewInternal._animateScalingTo = 0);
finished?.();
}),
- this.docView ? Math.max(0, this.docView.animateScaleTime - 10) : 0
+ this._docViewInternal ? Math.max(0, this._docViewInternal.animateScaleTime - 10) : 0
);
}),
- this.docView ? Math.max(0, this.docView?.animateScaleTime - 10) : 0
+ this._docViewInternal ? Math.max(0, this._docViewInternal?.animateScaleTime - 10) : 0
);
};
@@ -1606,29 +1644,21 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
componentDidMount() {
runInAction(() => this.Document[DocViews].add(this));
- this._disposers.updateContentsScript = reaction(() => ScriptCast(this.Document.updateContentsScript)?.script?.run({ this: this.Document }).result, emptyFunction);
- this._disposers.height = reaction(
- // increase max auto height if document has been resized to be greater than current max
- () => NumCast(this.layoutDoc._height),
- action(height => {
- const docMax = NumCast(this.layoutDoc.layout_maxAutoHeight);
- if (docMax && docMax < height) this.layoutDoc.layout_maxAutoHeight = height;
- })
- );
- !BoolCast(this._props.Document.dontRegisterView, this._props.dontRegisterView) && DocumentManager.Instance.AddView(this);
+ this._disposers.onViewMounted = reaction(() => ScriptCast(this.Document.onViewMounted)?.script?.run({ this: this.Document }).result, emptyFunction);
+ !BoolCast(this.Document.dontRegisterView, this._props.dontRegisterView) && DocumentManager.Instance.AddView(this);
}
componentWillUnmount() {
- this.Document[DocViews].delete(this);
+ runInAction(() => this.Document[DocViews].delete(this));
Object.values(this._disposers).forEach(disposer => disposer?.());
- !BoolCast(this._props.Document.dontRegisterView, this._props.dontRegisterView) && DocumentManager.Instance.RemoveView(this);
+ !BoolCast(this.Document.dontRegisterView, this._props.dontRegisterView) && DocumentManager.Instance.RemoveView(this);
}
// want the htmloverlay to be able to fade in but we also want it to be display 'none' until it is needed.
// unfortunately, CSS can't transition animate any properties for something that is display 'none'.
// so we need to first activate the div, then, after a render timeout, start the opacity transition.
@observable enableHtmlOverlayTransitions: boolean = false;
@computed get htmlOverlay() {
- const effect = StrCast(this.htmlOverlayEffect?.presentation_effect, StrCast(this.htmlOverlayEffect?.followLinkAnimEffect));
+ const effect = StrCast(this._htmlOverlayEffect?.presentation_effect, StrCast(this._htmlOverlayEffect?.followLinkAnimEffect));
return (
<div
className="documentView-htmlOverlay"
@@ -1638,13 +1668,13 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
setTimeout(action(() => (this.enableHtmlOverlayTransitions = val)));
}
}}
- style={{ display: !this.textHtmlOverlay ? 'none' : undefined }}>
+ style={{ display: !this._htmlOverlayText ? 'none' : undefined }}>
<div className="documentView-htmlOverlayInner" style={{ transition: `all 500ms`, opacity: this.enableHtmlOverlayTransitions ? 0.9 : 0 }}>
{DocumentViewInternal.AnimationEffect(
<div className="webBox-textHighlight">
- <ObserverJsxParser autoCloseVoidElements={true} key={42} onError={(e: any) => console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this.textHtmlOverlay)} />
+ <ObserverJsxParser autoCloseVoidElements={true} key={42} onError={(e: any) => console.log('PARSE error', e)} renderInWrapper={false} jsx={StrCast(this._htmlOverlayText)} />
</div>,
- { ...(this.htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Zoom } as any as Doc,
+ { ...(this._htmlOverlayEffect ?? {}), presentation_effect: effect ?? PresEffect.Zoom } as any as Doc,
this.Document
)}
</div>
@@ -1663,7 +1693,7 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
return (
<div className="contentFittingDocumentView" onPointerEnter={action(() => (this._isHovering = true))} onPointerLeave={action(() => (this._isHovering = false))}>
- {!this._props.Document || !this._props.PanelWidth() ? null : (
+ {!this.Document || !this._props.PanelWidth() ? null : (
<div
className="contentFittingDocumentView-previewDoc"
ref={this.ContentRef}
@@ -1676,7 +1706,7 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
<DocumentViewInternal
{...this._props}
DocumentView={this.selfView}
- viewPath={this.docViewPathFunc}
+ docViewPath={this.docViewPathFunc}
PanelWidth={this.PanelWidth}
PanelHeight={this.PanelHeight}
NativeWidth={this.NativeWidth}
@@ -1687,7 +1717,7 @@ export class DocumentView extends ObservableReactComponent<DocumentViewProps> {
layout_fitWidth={this.layout_fitWidthFunc}
ScreenToLocalTransform={this.screenToContentsTransform}
focus={this._props.focus || emptyFunction}
- ref={action((r: DocumentViewInternal | null) => r && (this.docView = r))}
+ ref={action((r: DocumentViewInternal | null) => r && (this._docViewInternal = r))}
/>
{this.htmlOverlay}
{this.infoUI}
diff --git a/src/client/views/nodes/EquationBox.tsx b/src/client/views/nodes/EquationBox.tsx
index ff92c701f..ebad257ac 100644
--- a/src/client/views/nodes/EquationBox.tsx
+++ b/src/client/views/nodes/EquationBox.tsx
@@ -27,7 +27,7 @@ export class EquationBox extends ViewBoxBaseComponent<FieldViewProps>() {
componentDidMount() {
this._props.setContentView?.(this);
- if (EquationBox.SelectOnLoad === this.Document[Id] && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this._props.docViewPath()))) {
+ if (EquationBox.SelectOnLoad === this.Document[Id] && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.docViewPath))) {
this._props.select(false);
this._ref.current!.mathField.focus();
diff --git a/src/client/views/nodes/FieldView.tsx b/src/client/views/nodes/FieldView.tsx
index 008f10f26..b456807d7 100644
--- a/src/client/views/nodes/FieldView.tsx
+++ b/src/client/views/nodes/FieldView.tsx
@@ -6,23 +6,18 @@ import { Doc, Field, FieldResult, Opt } from '../../../fields/Doc';
import { List } from '../../../fields/List';
import { ScriptField } from '../../../fields/ScriptField';
import { WebField } from '../../../fields/URLField';
-import { DocumentViewSharedProps } from './DocumentView';
+import { DocumentView, DocumentViewInternalSharedProps, DocumentViewSharedProps } from './DocumentView';
//
// these properties get assigned through the render() method of the DocumentView when it creates this node.
// However, that only happens because the properties are "defined" in the markup for the field view.
// See the LayoutString method on each field view : ImageBox, FormattedTextBox, etc.
//
-export interface FieldViewProps extends DocumentViewSharedProps {
+export interface FieldViewProps extends DocumentViewSharedProps, DocumentViewInternalSharedProps {
// FieldView specific props that are not part of DocumentView props
fieldKey: string;
- select: (isCtrlPressed: boolean) => void;
- isContentActive: (outsideReaction?: boolean) => boolean | undefined;
- isDocumentActive?: () => boolean | undefined;
- isSelected: () => boolean;
setHeight?: (height: number) => void;
- NativeDimScaling?: () => number; // scaling the DocumentView does to transform its contents into its panel & needed by ScreenToLocal NOTE: Must also be added to DocumentViewInternalsProps
onBrowseClick?: () => ScriptField | undefined;
onKey?: (e: React.KeyboardEvent, fieldProps: FieldViewProps) => boolean | undefined;
pointerEvents?: () => Opt<string>;
diff --git a/src/client/views/nodes/ImageBox.tsx b/src/client/views/nodes/ImageBox.tsx
index a5853499f..4483d12ce 100644
--- a/src/client/views/nodes/ImageBox.tsx
+++ b/src/client/views/nodes/ImageBox.tsx
@@ -158,7 +158,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
@undoBatch
setNativeSize = action(() => {
- const scaling = (this._props.DocumentView?.().screenToViewTransform().Scale || 1) / NumCast(this.layoutDoc._freeform_scale, 1);
+ const scaling = (this.DocumentView?.().screenToViewTransform().Scale || 1) / NumCast(this.layoutDoc._freeform_scale, 1);
const nscale = NumCast(this._props.PanelWidth()) / scaling;
const nw = nscale / NumCast(this.dataDoc[this.fieldKey + '_nativeWidth']);
this.dataDoc[this.fieldKey + '_nativeHeight'] = NumCast(this.dataDoc[this.fieldKey + '_nativeHeight']) * nw;
@@ -368,7 +368,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
}
screenToLocalTransform = () => this.ScreenToLocalBoxXf().translate(0, NumCast(this.layoutDoc._layout_scrollTop) * this.ScreenToLocalBoxXf().Scale);
marqueeDown = (e: React.PointerEvent) => {
- if (!e.altKey && e.button === 0 && NumCast(this.layoutDoc._freeform_scale, 1) <= NumCast(this.dataDoc.freeform_scaleMin, 1) && this._props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
+ if (!e.altKey && e.button === 0 && NumCast(this.layoutDoc._freeform_scale, 1) <= NumCast(this.dataDoc.freeform_scaleMin, 1) && this._props.isContentActive() && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
setupMoveUpEvents(
this,
e,
@@ -444,7 +444,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
{this.content}
</CollectionFreeFormView>
{this.annotationLayer}
- {!this._mainCont.current || !this._annotationLayer.current ? null : (
+ {!this._mainCont.current || !this.DocumentView || !this._annotationLayer.current ? null : (
<MarqueeAnnotator
Document={this.Document}
ref={this._marqueeref}
@@ -452,7 +452,7 @@ export class ImageBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProp
annotationLayerScrollTop={0}
scaling={returnOne}
annotationLayerScaling={this._props.NativeDimScaling}
- docView={this._props.DocumentView!}
+ docView={this.DocumentView}
addDocument={this.addDocument}
finishMarquee={this.finishMarquee}
savedAnnotations={this.savedAnnotations}
diff --git a/src/client/views/nodes/KeyValuePair.tsx b/src/client/views/nodes/KeyValuePair.tsx
index 7bc9d3f85..b2aab2422 100644
--- a/src/client/views/nodes/KeyValuePair.tsx
+++ b/src/client/views/nodes/KeyValuePair.tsx
@@ -61,33 +61,11 @@ export class KeyValuePair extends ObservableReactComponent<KeyValuePairProps> {
};
render() {
- const props: FieldViewProps = {
- Document: this._props.doc,
- childFilters: returnEmptyFilter,
- childFiltersByRanges: returnEmptyFilter,
- searchFilterDocs: returnEmptyDoclist,
- styleProvider: DefaultStyleProvider,
- docViewPath: returnEmptyDoclist,
- fieldKey: this._props.keyName,
- isSelected: returnFalse,
- setHeight: returnFalse,
- select: emptyFunction,
- bringToFront: emptyFunction,
- renderDepth: 1,
- isContentActive: returnFalse,
- whenChildContentsActiveChanged: emptyFunction,
- ScreenToLocalTransform: Transform.Identity,
- focus: emptyFunction,
- PanelWidth: this._props.PanelWidth,
- PanelHeight: this._props.PanelHeight,
- addDocTab: returnFalse,
- pinToPres: returnZero,
- };
// let fieldKey = Object.keys(props.Document).indexOf(props.fieldKey) !== -1 ? props.fieldKey : "(" + props.fieldKey + ")";
let protoCount = 0;
- let doc: Doc | undefined = props.Document;
+ let doc = this._props.doc;
while (doc) {
- if (Object.keys(doc).includes(props.fieldKey)) {
+ if (Object.keys(doc).includes(this._props.keyName)) {
break;
}
protoCount++;
@@ -106,17 +84,17 @@ export class KeyValuePair extends ObservableReactComponent<KeyValuePairProps> {
style={hover}
className="keyValuePair-td-key-delete"
onClick={undoBatch(() => {
- if (Object.keys(props.Document).indexOf(props.fieldKey) !== -1) {
- delete props.Document[props.fieldKey];
- } else delete DocCast(props.Document.proto)?.[props.fieldKey];
+ if (Object.keys(this._props.doc).indexOf(this._props.keyName) !== -1) {
+ delete this._props.doc[this._props.keyName];
+ } else delete DocCast(this._props.doc.proto)?.[this._props.keyName];
})}>
X
</button>
<input className="keyValuePair-td-key-check" type="checkbox" style={hover} onChange={this.handleCheck} ref={this.checkbox} />
- <Tooltip title={Object.entries(new DocumentOptions()).find((pair: [string, FInfo]) => pair[0].replace(/^_/, '') === props.fieldKey)?.[1].description ?? ''}>
- <div className="keyValuePair-keyField" style={{ marginLeft: 20 * (props.fieldKey.match(/_/g)?.length || 0), color: keyStyle }}>
+ <Tooltip title={Object.entries(new DocumentOptions()).find((pair: [string, FInfo]) => pair[0].replace(/^_/, '') === this._props.keyName)?.[1].description ?? ''}>
+ <div className="keyValuePair-keyField" style={{ marginLeft: 20 * (this._props.keyName.match(/_/g)?.length || 0), color: keyStyle }}>
{'('.repeat(parenCount)}
- {props.fieldKey}
+ {this._props.keyName}
{')'.repeat(parenCount)}
</div>
</Tooltip>
@@ -124,7 +102,32 @@ export class KeyValuePair extends ObservableReactComponent<KeyValuePairProps> {
</td>
<td className="keyValuePair-td-value" style={{ width: `${100 - this._props.keyWidth}%` }} onContextMenu={this.onContextMenu}>
<div className="keyValuePair-td-value-container">
- <EditableView contents={undefined} fieldContents={props} GetValue={() => Field.toKeyValueString(props.Document, props.fieldKey)} SetValue={(value: string) => KeyValueBox.SetField(props.Document, props.fieldKey, value)} />
+ <EditableView
+ contents={undefined}
+ fieldContents={{
+ Document: this._props.doc,
+ childFilters: returnEmptyFilter,
+ childFiltersByRanges: returnEmptyFilter,
+ searchFilterDocs: returnEmptyDoclist,
+ styleProvider: DefaultStyleProvider,
+ fieldKey: this._props.keyName,
+ isSelected: returnFalse,
+ setHeight: returnFalse,
+ select: emptyFunction,
+ bringToFront: emptyFunction,
+ renderDepth: 1,
+ isContentActive: returnFalse,
+ whenChildContentsActiveChanged: emptyFunction,
+ ScreenToLocalTransform: Transform.Identity,
+ focus: emptyFunction,
+ PanelWidth: this._props.PanelWidth,
+ PanelHeight: this._props.PanelHeight,
+ addDocTab: returnFalse,
+ pinToPres: returnZero,
+ }}
+ GetValue={() => Field.toKeyValueString(this._props.doc, this._props.keyName)}
+ SetValue={(value: string) => KeyValueBox.SetField(this._props.doc, this._props.keyName, value)}
+ />
</div>
</td>
</tr>
diff --git a/src/client/views/nodes/LinkAnchorBox.tsx b/src/client/views/nodes/LinkAnchorBox.tsx
index b86ba72a0..864c1955b 100644
--- a/src/client/views/nodes/LinkAnchorBox.tsx
+++ b/src/client/views/nodes/LinkAnchorBox.tsx
@@ -7,13 +7,13 @@ import { TraceMobx } from '../../../fields/util';
import { DragManager } from '../../util/DragManager';
import { LinkFollower } from '../../util/LinkFollower';
import { SelectionManager } from '../../util/SelectionManager';
-import { ViewBoxBaseComponent } from '../DocComponent';
+import { ViewBoxBaseComponent, ViewBoxBaseProps } from '../DocComponent';
import { StyleProp } from '../StyleProvider';
import { FieldView, FieldViewProps } from './FieldView';
import './LinkAnchorBox.scss';
import { LinkInfo } from './LinkDocPreview';
const { default: { MEDIUM_GRAY }, } = require('../global/globalCssVariables.module.scss'); // prettier-ignore
-export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
+export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps & ViewBoxBaseProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(LinkAnchorBox, fieldKey);
}
@@ -33,12 +33,13 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
@computed get linkSource() {
- return this._props.docViewPath()[this._props.docViewPath().length - 2].Document; // this._props.styleProvider?.(this.dataDoc, this._props, StyleProp.LinkSource);
+ return this.containerViewPath?.().lastElement().Document; // this._props.styleProvider?.(this.dataDoc, this._props, StyleProp.LinkSource);
}
onPointerDown = (e: React.PointerEvent) => {
- setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, (e, doubleTap) => {
- if (doubleTap) LinkFollower.FollowLink(this.Document, this.linkSource, false);
+ const linkSource = this.linkSource;
+ linkSource && setupMoveUpEvents(this, e, this.onPointerMove, emptyFunction, (e, doubleTap) => {
+ if (doubleTap) LinkFollower.FollowLink(this.Document, linkSource, false);
else this._props.select(false);
});
};
@@ -86,7 +87,8 @@ export class LinkAnchorBox extends ViewBoxBaseComponent<FieldViewProps>() {
className={`linkAnchorBox-cont${small ? '-small' : ''}`}
onPointerEnter={e =>
LinkInfo.SetLinkInfo({
- docProps: this._props,
+ DocumentView: this.DocumentView,
+ styleProvider: this._props.styleProvider,
linkSrc: this.linkSource,
linkDoc: this.Document,
showHeader: true,
diff --git a/src/client/views/nodes/LinkBox.tsx b/src/client/views/nodes/LinkBox.tsx
index 7f1d41547..4221f464d 100644
--- a/src/client/views/nodes/LinkBox.tsx
+++ b/src/client/views/nodes/LinkBox.tsx
@@ -29,12 +29,12 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
@computed get anchor1() {
const anchor1 = DocCast(this.dataDoc.link_anchor_1);
const anchor_1 = anchor1?.layout_unrendered ? DocCast(anchor1.annotationOn) : anchor1;
- return DocumentManager.Instance.getDocumentView(anchor_1, this._props.docViewPath()[this._props.docViewPath().length - 2]); // this._props.docViewPath().lastElement());
+ return DocumentManager.Instance.getDocumentView(anchor_1, this.containerViewPath?.().lastElement());
}
@computed get anchor2() {
const anchor2 = DocCast(this.dataDoc.link_anchor_2);
const anchor_2 = anchor2?.layout_unrendered ? DocCast(anchor2.annotationOn) : anchor2;
- return DocumentManager.Instance.getDocumentView(anchor_2, this._props.docViewPath()[this._props.docViewPath().length - 2]); // this._props.docViewPath().lastElement());
+ return DocumentManager.Instance.getDocumentView(anchor_2, this.containerViewPath?.().lastElement());
}
screenBounds = () => {
if (this.layoutDoc._layout_isSvg && this.anchor1 && this.anchor2 && this.anchor1.CollectionFreeFormView) {
@@ -66,7 +66,7 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
const a = (this.anchor1 ?? this.anchor2)!;
const b = (this.anchor2 ?? this.anchor1)!;
- const parxf = this._props.docViewPath()[this._props.docViewPath().length - 2].ComponentView as CollectionFreeFormView;
+ const parxf = this.containerViewPath?.().lastElement().ComponentView as CollectionFreeFormView;
const this_xf = parxf?.screenToFreeformContentsXf ?? Transform.Identity; //this.ScreenToLocalTransform();
const a_invXf = a.screenToViewTransform().inverse();
const b_invXf = b.screenToViewTransform().inverse();
@@ -161,12 +161,11 @@ export class LinkBox extends ViewBoxBaseComponent<FieldViewProps>() {
return (
<div className={`linkBox-container${this._props.isContentActive() ? '-interactive' : ''}`} style={{ background: this._props.styleProvider?.(this.layoutDoc, this._props, StyleProp.BackgroundColor) }}>
<ComparisonBox
- {...this._props}
+ {...this._props} //
fieldKey="link_anchor"
setHeight={emptyFunction}
dontRegisterView={true}
renderDepth={this._props.renderDepth + 1}
- isContentActive={this._props.isContentActive}
addDocument={returnFalse}
removeDocument={returnFalse}
moveDocument={returnFalse}
diff --git a/src/client/views/nodes/LinkDocPreview.tsx b/src/client/views/nodes/LinkDocPreview.tsx
index ea23ecbea..ed4878d9d 100644
--- a/src/client/views/nodes/LinkDocPreview.tsx
+++ b/src/client/views/nodes/LinkDocPreview.tsx
@@ -18,8 +18,9 @@ import { SearchUtil } from '../../util/SearchUtil';
import { SettingsManager } from '../../util/SettingsManager';
import { Transform } from '../../util/Transform';
import { ObservableReactComponent } from '../ObservableReactComponent';
-import { DocumentView, DocumentViewSharedProps, OpenWhere } from './DocumentView';
+import { DocumentView, DocumentViewSharedProps, OpenWhere, StyleProviderFunc } from './DocumentView';
import './LinkDocPreview.scss';
+import { FieldViewProps } from './FieldView';
export class LinkInfo {
private static _instance: Opt<LinkInfo>;
@@ -43,7 +44,8 @@ export class LinkInfo {
interface LinkDocPreviewProps {
linkDoc?: Doc;
linkSrc?: Doc;
- docProps: DocumentViewSharedProps;
+ DocumentView?: () => DocumentView;
+ styleProvider?: StyleProviderFunc;
location: number[];
hrefs?: string[];
showHeader?: boolean;
@@ -152,7 +154,7 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
action(() => {
LinkManager.currentLink = this._linkDoc;
LinkManager.currentLinkAnchor = this._linkSrc;
- this._props.docProps.DocumentView?.().select(false);
+ this._props.DocumentView?.().select(false);
if ((SettingsManager.Instance.propertiesWidth ?? 0) < 100) {
SettingsManager.Instance.propertiesWidth = 250;
}
@@ -269,8 +271,8 @@ export class LinkDocPreview extends ObservableReactComponent<LinkDocPreviewProps
}}
Document={this._targetDoc!}
moveDocument={returnFalse}
- styleProvider={this._props.docProps?.styleProvider}
- docViewPath={returnEmptyDoclist}
+ styleProvider={this._props.styleProvider}
+ containerViewPath={returnEmptyDoclist}
ScreenToLocalTransform={Transform.Identity}
isDocumentActive={returnFalse}
isContentActive={returnFalse}
diff --git a/src/client/views/nodes/MapBox/MapBox.tsx b/src/client/views/nodes/MapBox/MapBox.tsx
index 3575b21e4..56fb157da 100644
--- a/src/client/views/nodes/MapBox/MapBox.tsx
+++ b/src/client/views/nodes/MapBox/MapBox.tsx
@@ -379,11 +379,11 @@ export class MapBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
});
const targetCreator = (annotationOn: Doc | undefined) => {
- const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, undefined, annotationOn, undefined, 'yellow');
+ const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, undefined, annotationOn, 'yellow');
FormattedTextBox.SetSelectOnLoad(target);
return target;
};
- const docView = this._props.DocumentView?.();
+ const docView = this.DocumentView?.();
docView &&
DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(docView, sourceAnchorCreator, targetCreator), e.pageX, e.pageY, {
dragComplete: e => {
diff --git a/src/client/views/nodes/MapBox/MapPushpinBox.tsx b/src/client/views/nodes/MapBox/MapPushpinBox.tsx
index 34e237007..fc5b4dd18 100644
--- a/src/client/views/nodes/MapBox/MapPushpinBox.tsx
+++ b/src/client/views/nodes/MapBox/MapPushpinBox.tsx
@@ -18,10 +18,10 @@ export class MapPushpinBox extends ViewBoxBaseComponent<FieldViewProps>() {
}
get mapBoxView() {
- return this._props.DocumentView?.()?._props.docViewPath().lastElement()?.ComponentView as MapBox;
+ return this.DocumentView?.()?.containerViewPath?.().lastElement()?.ComponentView as MapBox;
}
get mapBox() {
- return this._props.DocumentView?.()._props.docViewPath().lastElement()?.Document;
+ return this.DocumentView?.().containerViewPath?.().lastElement()?.Document;
}
render() {
diff --git a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
index ea8496c99..e079f7457 100644
--- a/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
+++ b/src/client/views/nodes/MapboxMapBox/MapboxContainer.tsx
@@ -228,11 +228,11 @@ export class MapBoxContainer extends ViewBoxAnnotatableComponent<ViewBoxAnnotata
});
const targetCreator = (annotationOn: Doc | undefined) => {
- const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, undefined, annotationOn, undefined, 'yellow');
+ const target = DocUtils.GetNewTextDoc('Note linked to ' + this.Document.title, 0, 0, 100, 100, undefined, annotationOn, 'yellow');
FormattedTextBox.SetSelectOnLoad(target);
return target;
};
- const docView = this._props.DocumentView?.();
+ const docView = this.DocumentView?.();
docView &&
DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(docView, sourceAnchorCreator, targetCreator), e.pageX, e.pageY, {
dragComplete: e => {
diff --git a/src/client/views/nodes/PDFBox.tsx b/src/client/views/nodes/PDFBox.tsx
index 959d5d88d..71c1b6a4c 100644
--- a/src/client/views/nodes/PDFBox.tsx
+++ b/src/client/views/nodes/PDFBox.tsx
@@ -102,7 +102,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
Doc.GetProto(region).followLinkToggle = true;
this.addDocument(region);
- const docViewContent = this._props.docViewPath().lastElement().ContentDiv!;
+ const docViewContent = this.DocumentView?.().ContentDiv!;
const newDiv = docViewContent.cloneNode(true) as HTMLDivElement;
newDiv.style.width = NumCast(this.layoutDoc._width).toString();
newDiv.style.height = NumCast(this.layoutDoc._height).toString();
@@ -163,7 +163,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
updateIcon = () => {
// currently we render pdf icons as text labels
- const docViewContent = this._props.docViewPath().lastElement().ContentDiv!;
+ const docViewContent = this.DocumentView?.().ContentDiv!;
const filename = this.layoutDoc[Id] + '-icon' + new Date().getTime();
this._pdfViewer?._mainCont.current &&
CollectionFreeFormView.UpdateIcon(
@@ -304,7 +304,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
setPdfViewer = (pdfViewer: PDFViewer) => {
this._pdfViewer = pdfViewer;
- const docView = this._props.DocumentView?.();
+ const docView = this.DocumentView?.();
if (this._initialScrollTarget && docView) {
this.focus(this._initialScrollTarget, { instant: true });
this._initialScrollTarget = undefined;
@@ -525,7 +525,7 @@ export class PDFBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
removeDocument={this.removeDocument}
/>
) : (
- <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this._props.DocumentView?.()!, false), true)}>
+ <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this.DocumentView?.()!, false), true)}>
<ComponentTag
{...this._props}
setContentView={emptyFunction} // override setContentView to do nothing
diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx
index fb42286af..1913ab032 100644
--- a/src/client/views/nodes/VideoBox.tsx
+++ b/src/client/views/nodes/VideoBox.tsx
@@ -21,7 +21,7 @@ import { CollectionFreeFormView } from '../collections/collectionFreeForm/Collec
import { CollectionStackedTimeline, TrimScope } from '../collections/CollectionStackedTimeline';
import { ContextMenu } from '../ContextMenu';
import { ContextMenuProps } from '../ContextMenuItem';
-import { ViewBoxAnnotatableComponent } from '../DocComponent';
+import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../DocComponent';
import { MarqueeAnnotator } from '../MarqueeAnnotator';
import { AnchorMenu } from '../pdf/AnchorMenu';
import { StyleProp } from '../StyleProvider';
@@ -44,7 +44,7 @@ import './VideoBox.scss';
*/
@observer
-export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
+export class VideoBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps>() {
public static LayoutString(fieldKey: string) {
return FieldView.LayoutString(VideoBox, fieldKey);
}
@@ -608,7 +608,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// removes from currently playing display
@action
removeCurrentlyPlaying = () => {
- const docView = this._props.DocumentView?.();
+ const docView = this.DocumentView?.();
if (CollectionStackedTimeline.CurrentlyPlaying && docView) {
const index = CollectionStackedTimeline.CurrentlyPlaying.indexOf(docView);
index !== -1 && CollectionStackedTimeline.CurrentlyPlaying.splice(index, 1);
@@ -617,7 +617,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// adds doc to currently playing display
@action
addCurrentlyPlaying = () => {
- const docView = this._props.DocumentView?.();
+ const docView = this.DocumentView?.();
if (!CollectionStackedTimeline.CurrentlyPlaying) {
CollectionStackedTimeline.CurrentlyPlaying = [];
}
@@ -749,7 +749,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
// starts marquee selection
marqueeDown = (e: React.PointerEvent) => {
- if (!e.altKey && e.button === 0 && NumCast(this.layoutDoc._freeform_scale, 1) === 1 && this._props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen].includes(Doc.ActiveTool)) {
+ if (!e.altKey && e.button === 0 && NumCast(this.layoutDoc._freeform_scale, 1) === 1 && this._props.isContentActive() && ![InkTool.Highlighter, InkTool.Pen].includes(Doc.ActiveTool)) {
setupMoveUpEvents(
this,
e,
@@ -941,7 +941,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
style={{
pointerEvents: this.layoutDoc._lockedPosition ? 'none' : undefined,
borderRadius,
- overflow: this._props.docViewPath?.().slice(-1)[0].layout_fitWidth ? 'auto' : undefined,
+ overflow: this.DocumentView?.().layout_fitWidth ? 'auto' : undefined,
}}>
<div className="videoBox-viewer" onPointerDown={this.marqueeDown}>
<div
@@ -978,7 +978,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
</CollectionFreeFormView>
</div>
{this.annotationLayer}
- {!this._mainCont.current || !this._annotationLayer.current ? null : (
+ {!this._mainCont.current || !this.DocumentView || !this._annotationLayer.current ? null : (
<MarqueeAnnotator
ref={this._marqueeref}
Document={this.Document}
@@ -986,7 +986,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
annotationLayerScrollTop={0}
scaling={returnOne}
annotationLayerScaling={this._props.NativeDimScaling}
- docView={this._props.DocumentView!}
+ docView={this.DocumentView}
containerOffset={this.marqueeOffset}
addDocument={this.addDocWithTimecode}
finishMarquee={this.finishMarquee}
@@ -1004,7 +1004,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps>() {
}
@computed get UIButtons() {
- const bounds = this._props.docViewPath().lastElement().getBounds();
+ const bounds = this.DocumentView?.().getBounds();
const width = (bounds?.right || 0) - (bounds?.left || 0);
const curTime = NumCast(this.layoutDoc._layout_currentTimecode);
return (
diff --git a/src/client/views/nodes/WebBox.tsx b/src/client/views/nodes/WebBox.tsx
index c3be2b390..86709e4d7 100644
--- a/src/client/views/nodes/WebBox.tsx
+++ b/src/client/views/nodes/WebBox.tsx
@@ -33,7 +33,7 @@ import { Annotation } from '../pdf/Annotation';
import { GPTPopup } from '../pdf/GPTPopup/GPTPopup';
import { SidebarAnnos } from '../SidebarAnnos';
import { StyleProp } from '../StyleProvider';
-import { DocComponentView, DocFocusOptions, DocumentView, DocumentViewInternalProps, DocumentViewProps, OpenWhere } from './DocumentView';
+import { DocComponentView, DocFocusOptions, DocumentView, OpenWhere } from './DocumentView';
import { FieldView, FieldViewProps } from './FieldView';
import { LinkInfo } from './LinkDocPreview';
import { PinProps, PresBox } from './trails';
@@ -250,7 +250,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@action
createTextAnnotation = (sel: Selection, selRange: Range | undefined) => {
if (this._mainCont.current && selRange) {
- if (this.dataDoc[this._props.fieldKey] instanceof HtmlField) this._mainCont.current.style.transform = `rotate(${NumCast(this._props.DocumentView!().screenToContentsTransform().RotateDeg)}deg)`;
+ if (this.dataDoc[this._props.fieldKey] instanceof HtmlField) this._mainCont.current.style.transform = `rotate(${NumCast(this.DocumentView!().screenToContentsTransform().RotateDeg)}deg)`;
const clientRects = selRange.getClientRects();
for (let i = 0; i < clientRects.length; i++) {
const rect = clientRects.item(i);
@@ -274,7 +274,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
// clear selection
this._textAnnotationCreator = undefined;
- if (sel.empty) sel.empty(); // Chrome
+ if (sel.empty)
+ sel.empty(); // Chrome
else if (sel.removeAllRanges) sel.removeAllRanges(); // Firefox
return this._savedAnnotations;
};
@@ -297,8 +298,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
@action
getView = (doc: Doc, options: DocFocusOptions) => {
- if (Doc.AreProtosEqual(doc, this.Document)) return new Promise<Opt<DocumentView>>(res => res(this._props.DocumentView?.()));
- if (this.Document.layout_fieldKey === 'layout_icon') this._props.DocumentView?.().iconify();
+ if (Doc.AreProtosEqual(doc, this.Document)) return new Promise<Opt<DocumentView>>(res => res(this.DocumentView?.()));
+ if (this.Document.layout_fieldKey === 'layout_icon') this.DocumentView?.().iconify();
const webUrl = WebCast(doc.config_data)?.url;
if (this._url && webUrl && webUrl.href !== this._url) this.setData(webUrl.href);
if (this._sidebarRef?.current?.makeDocUnfiltered(doc) && !this.SidebarShown) this.toggleSidebar(false);
@@ -343,7 +344,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
iframeUp = (e: PointerEvent) => {
this._getAnchor = AnchorMenu.Instance?.GetAnchor; // need to save AnchorMenu's getAnchor since a subsequent selection on another doc will overwrite this value
this._textAnnotationCreator = undefined;
- this._props.docViewPath().lastElement()?.docView?.cleanupPointerEvents(); // pointerup events aren't generated on containing document view, so we have to invoke it here.
+ this.DocumentView?.()?.cleanupPointerEvents(); // pointerup events aren't generated on containing document view, so we have to invoke it here.
if (this._iframe?.contentWindow && this._iframe.contentDocument && !this._iframe.contentWindow.getSelection()?.isCollapsed) {
const mainContBounds = Utils.GetScreenTransform(this._mainCont.current!);
const scale = (this._props.NativeDimScaling?.() || 1) * mainContBounds.scale;
@@ -364,7 +365,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
e.stopPropagation();
const sel = window.getSelection();
this._textAnnotationCreator = undefined;
- if (sel?.empty) sel.empty(); // Chrome
+ if (sel?.empty)
+ sel.empty(); // Chrome
else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox
// bcz: NEED TO unrotate e.clientX and e.clientY
const word = getWordAtPoint(e.target, e.clientX, e.clientY);
@@ -556,7 +558,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
clearStyleSheetRules(WebBox.webStyleSheet);
this._scrollTimer = undefined;
const newScrollTop = scrollTop > iframeHeight ? iframeHeight : scrollTop;
- if (!LinkInfo.Instance?.LinkInfo && this._outerRef.current && newScrollTop !== this.layoutDoc.thumbScrollTop && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this._props.docViewPath()))) {
+ if (!LinkInfo.Instance?.LinkInfo && this._outerRef.current && newScrollTop !== this.layoutDoc.thumbScrollTop && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.docViewPath))) {
this.layoutDoc.thumb = undefined;
this.layoutDoc.thumbScrollTop = undefined;
this.layoutDoc.thumbNativeWidth = undefined;
@@ -723,10 +725,11 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
onMarqueeDown = (e: React.PointerEvent) => {
const sel = this._url ? this._iframe?.contentDocument?.getSelection() : window.document.getSelection();
this._textAnnotationCreator = undefined;
- if (sel?.empty) sel.empty(); // Chrome
+ if (sel?.empty)
+ sel.empty(); // Chrome
else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox
this.marqueeing = [e.clientX, e.clientY];
- if (!e.altKey && e.button === 0 && this._props.isContentActive(true) && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
+ if (!e.altKey && e.button === 0 && this._props.isContentActive() && ![InkTool.Highlighter, InkTool.Pen, InkTool.Write].includes(Doc.ActiveTool)) {
setupMoveUpEvents(
this,
e,
@@ -750,7 +753,8 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
this.marqueeing = undefined;
this._textAnnotationCreator = undefined;
const sel = this._url ? this._iframe?.contentDocument?.getSelection() : window.document.getSelection();
- if (sel?.empty) sel.empty(); // Chrome
+ if (sel?.empty)
+ sel.empty(); // Chrome
else if (sel?.removeAllRanges) sel.removeAllRanges(); // Firefox
this._setPreviewCursor?.(x ?? 0, y ?? 0, false, !this._marqueeref.current?.isEmpty, this.Document);
if (x !== undefined && y !== undefined) {
@@ -762,7 +766,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
setTimeout(() => {
// if menu comes up right away, the down event can still be active causing a menu item to be selected
this.specificContextMenu(undefined as any);
- this._props.docViewPath().lastElement().docView?.onContextMenu(undefined, x, y);
+ this.DocumentView?.().onContextMenu(undefined, x, y);
});
}
}
@@ -908,7 +912,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
});
@action
onZoomWheel = (e: React.WheelEvent) => {
- if (this._props.isContentActive(true)) {
+ if (this._props.isContentActive()) {
e.stopPropagation();
}
};
@@ -1065,7 +1069,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
anchorMenuClick = () => this._sidebarRef.current?.anchorMenuClick;
transparentFilter = () => [...this._props.childFilters(), Utils.TransparentBackgroundFilter];
opaqueFilter = () => [...this._props.childFilters(), Utils.noDragDocsFilter, ...(SnappingManager.CanEmbed ? [] : [Utils.OpaqueBackgroundFilter])];
- childStyleProvider = (doc: Doc | undefined, props: Opt<DocumentViewInternalProps | FieldViewProps>, property: string): any => {
+ childStyleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
if (doc instanceof Doc && property === StyleProp.PointerEvents) {
if (this.inlineTextAnnotations.includes(doc)) return 'none';
}
@@ -1099,7 +1103,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
onContextMenu={this.specificContextMenu}>
{this.webpage}
</div>
- {!this._mainCont.current || !this._annotationLayer.current ? null : (
+ {!this._mainCont.current || !this.DocumentView || !this._annotationLayer.current ? null : (
<div style={{ position: 'absolute', height: '100%', width: '100%', pointerEvents: this.marqueeing ? 'all' : 'none' }}>
<MarqueeAnnotator
ref={this._marqueeref}
@@ -1109,7 +1113,7 @@ export class WebBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps
annotationLayerScrollTop={0}
scaling={this._props.NativeDimScaling}
addDocument={this.addDocumentWrapper}
- docView={this._props.DocumentView!}
+ docView={this.DocumentView}
finishMarquee={this.finishMarquee}
savedAnnotations={this.savedAnnotationsCreator}
selectionText={this.selectionText}
diff --git a/src/client/views/nodes/formattedText/DashDocView.tsx b/src/client/views/nodes/formattedText/DashDocView.tsx
index 6a2cd359c..cc58c2071 100644
--- a/src/client/views/nodes/formattedText/DashDocView.tsx
+++ b/src/client/views/nodes/formattedText/DashDocView.tsx
@@ -6,7 +6,7 @@ import * as ReactDOM from 'react-dom/client';
import { Doc } from '../../../../fields/Doc';
import { Height, Width } from '../../../../fields/DocSymbols';
import { NumCast } from '../../../../fields/Types';
-import { emptyFunction, returnFalse, Utils } from '../../../../Utils';
+import { emptyFunction, returnEmptyDoclist, returnFalse, Utils } from '../../../../Utils';
import { DocServer } from '../../../DocServer';
import { Docs, DocUtils } from '../../../documents/Documents';
import { Transform } from '../../../util/Transform';
@@ -207,7 +207,7 @@ export class DashDocViewInternal extends ObservableReactComponent<IDashDocViewIn
isDocumentActive={returnFalse}
isContentActive={this.isContentActive}
styleProvider={this._textBox._props.styleProvider}
- docViewPath={this._textBox._props.docViewPath}
+ containerViewPath={this._textBox.docViewPathFunc ?? returnEmptyDoclist}
ScreenToLocalTransform={this.getDocTransform}
addDocTab={this._textBox._props.addDocTab}
pinToPres={returnFalse}
diff --git a/src/client/views/nodes/formattedText/DashFieldView.tsx b/src/client/views/nodes/formattedText/DashFieldView.tsx
index 555b752f0..3f2ab0ec5 100644
--- a/src/client/views/nodes/formattedText/DashFieldView.tsx
+++ b/src/client/views/nodes/formattedText/DashFieldView.tsx
@@ -148,7 +148,7 @@ export class DashFieldViewInternal extends ObservableReactComponent<IDashFieldVi
}
createPivotForField = (e: React.MouseEvent) => {
- let container = this._props.tbox._props.DocumentView?.()._props.docViewPath().lastElement();
+ let container = this._props.tbox.containerViewPath?.().lastElement();
if (container) {
const embedding = Doc.MakeEmbedding(container.Document);
embedding._type_collection = CollectionViewType.Time;
diff --git a/src/client/views/nodes/formattedText/FormattedTextBox.tsx b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
index ae26f170b..6a6cec094 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBox.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBox.tsx
@@ -42,7 +42,7 @@ import { CollectionStackingView } from '../../collections/CollectionStackingView
import { CollectionTreeView } from '../../collections/CollectionTreeView';
import { ContextMenu } from '../../ContextMenu';
import { ContextMenuProps } from '../../ContextMenuItem';
-import { ViewBoxAnnotatableComponent } from '../../DocComponent';
+import { ViewBoxAnnotatableComponent, ViewBoxAnnotatableProps } from '../../DocComponent';
import { Colors } from '../../global/globalEnums';
import { LightboxView } from '../../LightboxView';
import { AnchorMenu } from '../../pdf/AnchorMenu';
@@ -71,7 +71,7 @@ import { SummaryView } from './SummaryView';
export interface FormattedTextBoxProps {}
@observer
-export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps & FormattedTextBoxProps>() {
+export class FormattedTextBox extends ViewBoxAnnotatableComponent<ViewBoxAnnotatableProps & FieldViewProps & FormattedTextBoxProps>() {
public static LayoutString(fieldStr: string) {
return FieldView.LayoutString(FormattedTextBox, fieldStr);
}
@@ -123,7 +123,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
@computed get noSidebar() {
- return this._props.docViewPath().lastElement()?._props.hideDecorationTitle || this._props.noSidebar || this.Document._layout_noSidebar;
+ return this.DocumentView?.()._props.hideDecorationTitle || this._props.noSidebar || this.Document._layout_noSidebar;
}
@computed get layout_sidebarWidthPercent() {
return this._showSidebar ? '20%' : StrCast(this.layoutDoc._layout_sidebarWidthPercent, '0%');
@@ -310,7 +310,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
return target;
};
- DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this._props.docViewPath().lastElement(), () => this.getAnchor(true), targetCreator), e.pageX, e.pageY);
+ DragManager.StartAnchorAnnoDrag([ele], new DragManager.AnchorAnnoDragData(this.DocumentView?.()!, () => this.getAnchor(true), targetCreator), e.pageX, e.pageY);
});
const coordsB = this._editorView!.coordsAtPos(this._editorView!.state.selection.to);
this._props.rootSelected?.() && AnchorMenu.Instance.jumpTo(coordsB.left, coordsB.bottom);
@@ -1410,7 +1410,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
(this._editorView as any).TextView = this;
}
- const selectOnLoad = Doc.AreProtosEqual(this._props.TemplateDataDocument ?? this.Document, FormattedTextBox.SelectOnLoad) && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this._props.docViewPath()));
+ const selectOnLoad = Doc.AreProtosEqual(this._props.TemplateDataDocument ?? this.Document, FormattedTextBox.SelectOnLoad) && (!LightboxView.LightboxDoc || LightboxView.IsLightboxDocView(this.docViewPath));
if (this._editorView && selectOnLoad && !this._props.dontRegisterView && !this._props.dontSelectOnLoad && this.isActiveTab(this.ProseRef)) {
const selLoadChar = FormattedTextBox.SelectOnLoadChar;
FormattedTextBox.SelectOnLoad = undefined;
@@ -1531,7 +1531,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
}
if (!state || !editor || !this.ProseRef?.children[0].className.includes('-focused')) return;
if (!state.selection.empty && !(state.selection instanceof NodeSelection)) this.setupAnchorMenu();
- else if (this._props.isContentActive(true)) {
+ else if (this._props.isContentActive()) {
const pcords = editor.posAtCoords({ left: e.clientX, top: e.clientY });
let xpos = pcords?.pos || 0;
while (xpos > 0 && !state.doc.resolve(xpos).node()?.isTextblock) {
@@ -1764,7 +1764,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
return toNum(height) + Math.max(0, toNum(marginTop)) + Math.max(0, toNum(marginBottom));
};
const proseHeight = !this.ProseRef ? 0 : children.reduce((p, child) => p + toHgt(child), margins);
- const scrollHeight = this.ProseRef && Math.min(NumCast(this.layoutDoc.layout_maxAutoHeight, proseHeight), proseHeight);
+ const scrollHeight = this.ProseRef && proseHeight;
if (this._props.setHeight && scrollHeight && !this._props.dontRegisterView) {
// if top === 0, then the text box is growing upward (as the overlay caption) which doesn't contribute to the height computation
const setScrollHeight = () => (this.dataDoc[this.fieldKey + '_scrollHeight'] = scrollHeight);
@@ -1852,7 +1852,7 @@ export class FormattedTextBox extends ViewBoxAnnotatableComponent<FieldViewProps
setHeight={this.setSidebarHeight}
/>
) : (
- <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this._props.DocumentView?.()!, false), true)}>
+ <div onPointerDown={e => setupMoveUpEvents(this, e, returnFalse, emptyFunction, () => SelectionManager.SelectView(this.DocumentView?.()!, false), true)}>
<ComponentTag
{...this._props}
ref={this._sidebarTagRef as any}
diff --git a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
index be8736525..ce17af6ca 100644
--- a/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
+++ b/src/client/views/nodes/formattedText/FormattedTextBoxComment.tsx
@@ -134,7 +134,8 @@ export class FormattedTextBoxComment {
//nbef &&
naft &&
LinkInfo.SetLinkInfo({
- docProps: textBox.props,
+ DocumentView: textBox.DocumentView,
+ styleProvider: textBox._props.styleProvider,
linkSrc: textBox.Document,
linkDoc: linkDoc ? (DocServer.GetCachedRefField(linkDoc) as Doc) : undefined,
location: (pos => [pos.left, pos.top + 25])(view.coordsAtPos(state.selection.from - Math.max(0, nbef - 1))),
diff --git a/src/client/views/nodes/trails/PresBox.tsx b/src/client/views/nodes/trails/PresBox.tsx
index 6fa64a765..645ac08e1 100644
--- a/src/client/views/nodes/trails/PresBox.tsx
+++ b/src/client/views/nodes/trails/PresBox.tsx
@@ -294,13 +294,9 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
listItemDoc.presentation_effect = this.activeItem.presBulletEffect;
listItemDoc.presentation_transition = 500;
targetView?.setAnimEffect(listItemDoc, 500);
- if (targetView?.docView && this.activeItem.presBulletExpand) {
- targetView.docView._animateScalingTo = 1.2;
- targetView.docView._animateScaleTime = 400;
- Doc.AddUnHighlightWatcher(() => {
- targetView.docView!._animateScaleTime = undefined;
- targetView!.docView!._animateScalingTo = 0;
- });
+ if (targetView && this.activeItem.presBulletExpand) {
+ targetView.setAnimateScaling(1.2, 400);
+ Doc.AddUnHighlightWatcher(() => targetView?.setAnimateScaling(0, undefined));
}
listItemDoc.opacity = undefined;
this.activeItem.presentation_indexed = presIndexed + 1;
@@ -2622,7 +2618,7 @@ export class PresBox extends ViewBoxBaseComponent<FieldViewProps>() {
ScreenToLocalTransform={this.getTransform}
AddToMap={this.AddToMap}
RemFromMap={this.RemFromMap}
- hierarchyIndex={emptyPath}
+ hierarchyIndex={emptyPath as any as number[]}
/>
) : null}
</div>
diff --git a/src/client/views/nodes/trails/PresElementBox.tsx b/src/client/views/nodes/trails/PresElementBox.tsx
index 4945d66c8..8cf01b9de 100644
--- a/src/client/views/nodes/trails/PresElementBox.tsx
+++ b/src/client/views/nodes/trails/PresElementBox.tsx
@@ -19,7 +19,7 @@ import { TreeView } from '../../collections/TreeView';
import { ViewBoxBaseComponent } from '../../DocComponent';
import { EditableView } from '../../EditableView';
import { Colors } from '../../global/globalEnums';
-import { DocumentView, DocumentViewInternalProps, DocumentViewProps } from '../../nodes/DocumentView';
+import { DocumentView } from '../../nodes/DocumentView';
import { FieldView, FieldViewProps } from '../../nodes/FieldView';
import { StyleProp } from '../../StyleProvider';
import { PresBox } from './PresBox';
@@ -50,7 +50,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
// the presentation view that renders this slide
@computed get presBoxView() {
- return this._props.DocumentView?.()?._props.docViewPath().lastElement()?.ComponentView as PresBox;
+ return this.containerViewPath?.().lastElement()?.ComponentView as PresBox;
}
// the presentation view document that renders this slide
@@ -97,7 +97,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
presExpandDocumentClick = () => (this.slideDoc.presentation_expandInlineButton = !this.slideDoc.presentation_expandInlineButton);
embedHeight = () => this.collapsedHeight + this.expandViewHeight;
embedWidth = () => this._props.PanelWidth() / 2;
- styleProvider = (doc: Doc | undefined, props: Opt<DocumentViewInternalProps | FieldViewProps>, property: string): any => {
+ styleProvider = (doc: Doc | undefined, props: Opt<FieldViewProps>, property: string): any => {
return property === StyleProp.Opacity ? 1 : this._props.styleProvider?.(doc, props, property);
};
/**
@@ -116,7 +116,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
hideLinkButton={true}
ScreenToLocalTransform={Transform.Identity}
renderDepth={this._props.renderDepth + 1}
- docViewPath={returnEmptyDoclist}
+ containerViewPath={returnEmptyDoclist}
childFilters={this._props.childFilters}
childFiltersByRanges={this._props.childFiltersByRanges}
searchFilterDocs={this._props.searchFilterDocs}
@@ -196,7 +196,7 @@ export class PresElementBox extends ViewBoxBaseComponent<FieldViewProps>() {
const dragArray = this.presBoxView?._dragArray ?? [];
const dragData = new DragManager.DocumentDragData(this.presBoxView?.sortArray() ?? []);
if (!dragData.draggedDocuments.length) dragData.draggedDocuments.push(this.slideDoc);
- dragData.treeViewDoc = this.presBox?._type_collection === CollectionViewType.Tree ? this.presBox : undefined; // this._props.DocumentView?.()?._props.treeViewDoc;
+ dragData.treeViewDoc = this.presBox?._type_collection === CollectionViewType.Tree ? this.presBox : undefined; // this.DocumentView?.()?._props.treeViewDoc;
dragData.moveDocument = this._props.moveDocument;
const dragItem: HTMLElement[] = [];
const classesToRestore = new Map<HTMLElement, string>();