aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DocumentContentsView.tsx
diff options
context:
space:
mode:
authorbobzel <zzzman@gmail.com>2024-05-14 23:15:24 -0400
committerbobzel <zzzman@gmail.com>2024-05-14 23:15:24 -0400
commit3534aaf88a3c30a474b3b5a5b7f04adfe6f15fac (patch)
tree47fb7a8671b209bd4d76e0f755a5b035c6936607 /src/client/views/nodes/DocumentContentsView.tsx
parent87bca251d87b5a95da06b2212400ce9427152193 (diff)
parent5cb7ad90e120123ca572e8ef5b1aa6ca41581134 (diff)
Merge branch 'restoringEslint' into sarah-ai-visualization
Diffstat (limited to 'src/client/views/nodes/DocumentContentsView.tsx')
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx143
1 files changed, 32 insertions, 111 deletions
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index e729e2fa2..18529a429 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,67 +1,24 @@
+/* eslint-disable react/require-default-props */
import { computed, makeObservable } from 'mobx';
import { observer } from 'mobx-react';
import * as React from 'react';
-import JsxParser from 'react-jsx-parser';
import * as XRegExp from 'xregexp';
-import { OmitKeys, Without, emptyPath } from '../../../Utils';
+import { OmitKeys } from '../../../ClientUtils';
+import { Without, emptyPath } from '../../../Utils';
import { Doc, Opt } from '../../../fields/Doc';
import { AclPrivate, DocData } from '../../../fields/DocSymbols';
import { ScriptField } from '../../../fields/ScriptField';
import { Cast, DocCast, StrCast } from '../../../fields/Types';
import { GetEffectiveAcl, TraceMobx } from '../../../fields/util';
-import { InkingStroke } from '../InkingStroke';
-import { ObservableReactComponent } from '../ObservableReactComponent';
-import { CollectionCalendarView } from '../collections/CollectionCalendarView';
-import { CollectionDockingView } from '../collections/CollectionDockingView';
-import { CollectionView } from '../collections/CollectionView';
-import { CollectionFreeFormView } from '../collections/collectionFreeForm/CollectionFreeFormView';
-import { CollectionSchemaView } from '../collections/collectionSchema/CollectionSchemaView';
-import { SchemaRowBox } from '../collections/collectionSchema/SchemaRowBox';
-import { PresElementBox } from '../nodes/trails/PresElementBox';
-import { SearchBox } from '../search/SearchBox';
-import { DashWebRTCVideo } from '../webcam/DashWebRTCVideo';
-import { YoutubeBox } from './../../apis/youtube/YoutubeBox';
-import { AudioBox } from './AudioBox';
-import { ComparisonBox } from './ComparisonBox';
-import { DataVizBox } from './DataVizBox/DataVizBox';
+import { ObservableReactComponent, ObserverJsxParser } from '../ObservableReactComponent';
import './DocumentView.scss';
-import { EquationBox } from './EquationBox';
-import { FieldView, FieldViewProps } from './FieldView';
-import { FontIconBox } from './FontIconBox/FontIconBox';
-import { FunctionPlotBox } from './FunctionPlotBox';
-import { ImageBox } from './ImageBox';
-import { KeyValueBox } from './KeyValueBox';
-import { LabelBox } from './LabelBox';
-import { LinkAnchorBox } from './LinkAnchorBox';
-import { LinkBox } from './LinkBox';
-import { LoadingBox } from './LoadingBox';
-import { MapBox } from './MapBox/MapBox';
-import { MapPushpinBox } from './MapBox/MapPushpinBox';
-import { PDFBox } from './PDFBox';
-import { PhysicsSimulationBox } from './PhysicsBox/PhysicsSimulationBox';
-import { RecordingBox } from './RecordingBox';
-import { ScreenshotBox } from './ScreenshotBox';
-import { ScriptingBox } from './ScriptingBox';
-import { VideoBox } from './VideoBox';
-import { WebBox } from './WebBox';
-import { FormattedTextBox } from './formattedText/FormattedTextBox';
-import { ImportElementBox } from './importBox/ImportElementBox';
-import { PresBox } from './trails/PresBox';
+import { FieldViewProps } from './FieldView';
type BindingProps = Without<FieldViewProps, 'fieldKey'>;
export interface JsxBindings {
props: BindingProps;
}
-class ObserverJsxParser1 extends JsxParser {
- constructor(props: any) {
- super(props);
- observer(this as any);
- }
-}
-
-export const ObserverJsxParser: typeof JsxParser = ObserverJsxParser1 as any;
-
interface HTMLtagProps {
Document: Doc;
htmltag: string;
@@ -71,8 +28,8 @@ interface HTMLtagProps {
children?: JSX.Element[];
}
-//"<HTMLdiv borderRadius='100px' onClick={this.bannerColor=this.bannerColor==='red'?'green':'red'} overflow='hidden' position='absolute' width='100%' height='100%' transform='rotate({2*this.x+this.y}deg)'> <ImageBox {...props} fieldKey={'data'}/> <HTMLspan width='200px' top='0' height='35px' textAlign='center' paddingTop='10px' transform='translate(-40px, 45px) rotate(-45deg)' position='absolute' color='{this.bannerColor===`green`?`light`:`dark`}blue' backgroundColor='{this.bannerColor===`green`?`dark`:`light`}blue'> {this.title}</HTMLspan></HTMLdiv>"
-//"<HTMLdiv borderRadius='100px' overflow='hidden' position='absolute' width='100%' height='100%'
+// "<HTMLdiv borderRadius='100px' onClick={this.bannerColor=this.bannerColor==='red'?'green':'red'} overflow='hidden' position='absolute' width='100%' height='100%' transform='rotate({2*this.x+this.y}deg)'> <ImageBox {...props} fieldKey={'data'}/> <HTMLspan width='200px' top='0' height='35px' textAlign='center' paddingTop='10px' transform='translate(-40px, 45px) rotate(-45deg)' position='absolute' color='{this.bannerColor===`green`?`light`:`dark`}blue' backgroundColor='{this.bannerColor===`green`?`dark`:`light`}blue'> {this.title}</HTMLspan></HTMLdiv>"
+// "<HTMLdiv borderRadius='100px' overflow='hidden' position='absolute' width='100%' height='100%'
// transform='rotate({2*this.x+this.y}deg)'
// onClick = { this.bannerColor = this.bannerColor === 'red' ? 'green' : 'red' } >
// <ImageBox {...props} fieldKey={'data'}/>
@@ -85,22 +42,21 @@ interface HTMLtagProps {
// </HTMLdiv>"
@observer
export class HTMLtag extends React.Component<HTMLtagProps> {
- click = (e: React.MouseEvent) => {
+ click = () => {
const clickScript = (this.props as any).onClick as Opt<ScriptField>;
- clickScript?.script.run({ this: this.props.Document, self: this.props.Document, scale: this.props.scaling });
+ clickScript?.script.run({ this: this.props.Document, scale: this.props.scaling });
};
onInput = (e: React.FormEvent<HTMLDivElement>) => {
const onInputScript = (this.props as any).onInput as Opt<ScriptField>;
- onInputScript?.script.run({ this: this.props.Document, self: this.props.Document, value: (e.target as any).textContent });
+ onInputScript?.script.run({ this: this.props.Document, value: (e.target as any).textContent });
};
render() {
const style: { [key: string]: any } = {};
const divKeys = OmitKeys(this.props, ['children', 'dragStarting', 'dragEnding', 'htmltag', 'scaling', 'Document', 'key', 'onInput', 'onClick', '__proto__']).omit;
- const replacer = (match: any, expr: string, offset: any, string: any) => {
+ const replacer = (match: any, expr: string) =>
// bcz: this executes a script to convert a property expression string: { script } into a value
- return (ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name, scale: 'number' })?.script.run({ self: this.props.Document, this: this.props.Document, scale: this.props.scaling }).result as string) || '';
- };
- Object.keys(divKeys).map((prop: string) => {
+ (ScriptField.MakeFunction(expr, { this: Doc.name, scale: 'number' })?.script.run({ this: this.props.Document, scale: this.props.scaling }).result as string) || '';
+ Object.keys(divKeys).forEach((prop: string) => {
const p = (this.props as any)[prop] as string;
style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer);
});
@@ -118,20 +74,28 @@ export interface DocumentContentsViewProps extends FieldViewProps {
}
@observer
export class DocumentContentsView extends ObservableReactComponent<DocumentContentsViewProps> {
+ private static DefaultLayoutString: string;
+ /**
+ * Set of all available rendering componets for Docs (e.g., ImageBox, CollectionFreeFormView, etc)
+ */
+ private static Components: { [key: string]: any };
+ public static Init(defaultLayoutString: string, components:{ [key: string]: any}) {
+ DocumentContentsView.DefaultLayoutString = defaultLayoutString;
+ DocumentContentsView.Components = components;
+ }
constructor(props: any) {
super(props);
makeObservable(this);
}
-
@computed get layout(): string {
TraceMobx();
if (this._props.LayoutTemplateString) return this._props.LayoutTemplateString;
if (!this.layoutDoc) return '<p>awaiting layout</p>';
- if (this._props.layoutFieldKey === 'layout_keyValue') return StrCast(this._props.Document.layout_keyValue, KeyValueBox.LayoutString());
+ if (this._props.layoutFieldKey === 'layout_keyValue') return StrCast(this._props.Document.layout_keyValue, DocumentContentsView.DefaultLayoutString);
const tempLayout = DocCast(this.layoutDoc[this.layoutDoc === this._props.Document && this._props.layoutFieldKey ? this._props.layoutFieldKey : StrCast(this.layoutDoc.layout_fieldKey, 'layout')]);
const layoutDoc = tempLayout ?? this.layoutDoc;
const layout = Cast(layoutDoc[layoutDoc === this._props.Document && this._props.layoutFieldKey ? this._props.layoutFieldKey : StrCast(layoutDoc.layout_fieldKey, 'layout')], 'string');
- if (layout === undefined) return this._props.Document.data ? "<FieldView {...props} fieldKey='data' />" : KeyValueBox.LayoutString();
+ if (layout === undefined) return this._props.Document.data ? "<FieldView {...props} fieldKey='data' />" : DocumentContentsView.DefaultLayoutString;
if (typeof layout === 'string') return layout;
return '<p>Loading layout</p>';
}
@@ -158,7 +122,7 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
'dontCenter',
'DataTransition',
'contextMenuItems',
- //'onClick', // don't need to omit this since it will be set
+ // 'onClick', // don't need to omit this since it will be set
'onDoubleClickScript',
'onPointerDownScript',
'onPointerUpScript',
@@ -187,21 +151,16 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
let layoutFrame = this.layout;
// replace code content with a script >{content}< as in <HTMLdiv>{this.title}</HTMLdiv>
- const replacer = (match: any, prefix: string, expr: string, postfix: string, offset: any, string: any) => {
- return prefix + ((ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ this: this._props.Document }).result as string) || '') + postfix;
- };
+ const replacer = (match: any, prefix: string, expr: string, postfix: string) => prefix + ((ScriptField.MakeFunction(expr, { this: Doc.name })?.script.run({ this: this._props.Document }).result as string) || '') + postfix;
layoutFrame = layoutFrame.replace(/(>[^{]*)[^=]\{([^.'][^<}]+)\}([^}]*<)/g, replacer);
// replace HTML<tag> with corresponding HTML tag as in: <HTMLdiv> becomes <HTMLtag Document={props.Document} htmltag='div'>
- const replacer2 = (match: any, p1: string, offset: any, string: any) => {
- return `<HTMLtag Document={props.Document} scaling='${this._props.NativeDimScaling?.() || 1}' htmltag='${p1}'`;
- };
+ const replacer2 = (match: any, p1: string) => `<HTMLtag Document={props.Document} scaling='${this._props.NativeDimScaling?.() || 1}' htmltag='${p1}'`;
layoutFrame = layoutFrame.replace(/<HTML([a-zA-Z0-9_-]+)/g, replacer2);
// replace /HTML<tag> with </HTMLdiv> as in: </HTMLdiv> becomes </HTMLtag>
- const replacer3 = (match: any, p1: string, offset: any, string: any) => {
- return `</HTMLtag`;
- };
+ const replacer3 = (/* match: any, p1: string, offset: any, string: any */) => `</HTMLtag`;
+
layoutFrame = layoutFrame.replace(/<\/HTML([a-zA-Z0-9_-]+)/g, replacer3);
// add onClick function to props
@@ -211,7 +170,7 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
const code = XRegExp.matchRecursive(splits[1], '{', '}', '', { valueNames: ['between', 'left', 'match', 'right', 'between'] });
layoutFrame = splits[0] + ` ${func}={props.${func}} ` + splits[1].substring(code[1].end + 1);
const script = code[1].value.replace(/^‘/, '').replace(/’$/, ''); // ‘’ are not valid quotes in javascript so get rid of them -- they may be present to make it easier to write complex scripts - see headerTemplate in currentUserUtils.ts
- return ScriptField.MakeScript(script, { this: Doc.name, self: Doc.name, scale: 'number', value: 'string' });
+ return ScriptField.MakeScript(script, { this: Doc.name, scale: 'number', value: 'string' });
}
return undefined;
// add input function to props
@@ -231,48 +190,10 @@ export class DocumentContentsView extends ObservableReactComponent<DocumentConte
key={42}
blacklistedAttrs={emptyPath}
renderInWrapper={false}
- components={{
- FormattedTextBox,
- ImageBox,
- FontIconBox,
- LabelBox,
- EquationBox,
- FieldView,
- CollectionFreeFormView,
- CollectionDockingView,
- CollectionSchemaView,
- CollectionCalendarView,
- CollectionView,
- WebBox,
- KeyValueBox,
- PDFBox,
- VideoBox,
- AudioBox,
- RecordingBox,
- PresBox,
- YoutubeBox,
- PresElementBox,
- SearchBox,
- FunctionPlotBox,
- DashWebRTCVideo,
- LinkAnchorBox,
- InkingStroke,
- LinkBox,
- ScriptingBox,
- MapBox,
- ScreenshotBox,
- DataVizBox,
- HTMLtag,
- ComparisonBox,
- LoadingBox,
- PhysicsSimulationBox,
- SchemaRowBox,
- ImportElementBox,
- MapPushpinBox,
- }}
+ components={DocumentContentsView.Components}
bindings={bindings}
jsx={layoutFrame}
- showWarnings={true}
+ showWarnings
onError={(test: any) => {
console.log('DocumentContentsView:' + test, bindings, layoutFrame);
}}