aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/nodes/DocumentContentsView.tsx
diff options
context:
space:
mode:
authorMelissa Zhang <mzhang19096@gmail.com>2020-05-15 19:10:07 -0700
committerMelissa Zhang <mzhang19096@gmail.com>2020-05-15 19:10:07 -0700
commit253d5efbbafe4a44c350fef7dda6d553a70a94c9 (patch)
treeb43a55e1efddc86e25df4bb7d90a99f3c7b52a17 /src/client/views/nodes/DocumentContentsView.tsx
parent36c01920e3874e1484222a7012745b581405f67d (diff)
parent08b6bf8b51ab631c8cfe9c3e12bfb0ae2dd7b4c7 (diff)
merge with master
Diffstat (limited to 'src/client/views/nodes/DocumentContentsView.tsx')
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx106
1 files changed, 68 insertions, 38 deletions
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx
index 90d2d4936..c9db1ea01 100644
--- a/src/client/views/nodes/DocumentContentsView.tsx
+++ b/src/client/views/nodes/DocumentContentsView.tsx
@@ -1,7 +1,7 @@
import { computed } from "mobx";
import { observer } from "mobx-react";
-import { Doc, Opt, Field } from "../../../new_fields/Doc";
-import { Cast, StrCast, NumCast } from "../../../new_fields/Types";
+import { Doc, Opt, Field } from "../../../fields/Doc";
+import { Cast, StrCast, NumCast } from "../../../fields/Types";
import { OmitKeys, Without, emptyPath } from "../../../Utils";
import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox";
import { CollectionDockingView } from "../collections/CollectionDockingView";
@@ -14,12 +14,12 @@ import { LabelBox } from "./LabelBox";
import { SliderBox } from "./SliderBox";
import { LinkBox } from "./LinkBox";
import { ScriptingBox } from "./ScriptingBox";
-import { DocHolderBox } from "./DocumentBox";
+import { DocHolderBox } from "./DocHolderBox";
import { DocumentViewProps } from "./DocumentView";
import "./DocumentView.scss";
import { FontIconBox } from "./FontIconBox";
import { FieldView, FieldViewProps } from "./FieldView";
-import { FormattedTextBox } from "./FormattedTextBox";
+import { FormattedTextBox } from "./formattedText/FormattedTextBox";
import { ImageBox } from "./ImageBox";
import { KeyValueBox } from "./KeyValueBox";
import { PDFBox } from "./PDFBox";
@@ -36,8 +36,8 @@ import { WebBox } from "./WebBox";
import { InkingStroke } from "../InkingStroke";
import React = require("react");
import { RecommendationsBox } from "../RecommendationsBox";
-import { TraceMobx } from "../../../new_fields/util";
-import { ScriptField } from "../../../new_fields/ScriptField";
+import { TraceMobx } from "../../../fields/util";
+import { ScriptField } from "../../../fields/ScriptField";
import XRegExp = require("xregexp");
const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this?
@@ -59,35 +59,34 @@ const ObserverJsxParser: typeof JsxParser = ObserverJsxParser1 as any;
interface HTMLtagProps {
Document: Doc;
+ RootDoc: Doc;
htmltag: string;
onClick?: ScriptField;
+ onInput?: ScriptField;
}
//"<HTMLdiv borderRadius='100px' onClick={this.bannerColor=this.bannerColor==='red'?'green':'red'} width='100%' height='100%' transform='rotate({2*this.x+this.y}deg)'><ImageBox {...props} fieldKey={'data'}/><HTMLspan width='100%' marginTop='50%' height='10%' position='absolute' backgroundColor='{this.bannerColor===`green`?`dark`:`light`}grey'>{this.title}</HTMLspan></HTMLdiv>"@observer
@observer
export class HTMLtag extends React.Component<HTMLtagProps> {
click = (e: React.MouseEvent) => {
const clickScript = (this.props as any).onClick as Opt<ScriptField>;
- clickScript?.script.run({ this: this.props.Document });
+ clickScript?.script.run({ this: this.props.Document, self: this.props.RootDoc });
+ }
+ 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.RootDoc, value: (e.target as any).textContent });
}
render() {
const style: { [key: string]: any } = {};
- const divKeys = OmitKeys(this.props, ["children", "htmltag", "Document", "key", "onClick", "__proto__"]).omit;
+ const divKeys = OmitKeys(this.props, ["children", "htmltag", "RootDoc", "Document", "key", "onInput", "onClick", "__proto__"]).omit;
+ const replacer = (match: any, expr: string, offset: any, string: any) => { // bcz: this executes a script to convert a propery expression string: { script } into a value
+ return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ self: this.props.RootDoc, this: this.props.Document }).result as string || "";
+ };
Object.keys(divKeys).map((prop: string) => {
- let p = (this.props as any)[prop] as string;
- const replacer = (match: any, expr: string, offset: any, string: any) => { // bcz: extend this to support expression -- is this really a script?
- return ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ this: this.props.Document }).result as string || "";
- };
- p = p?.replace(/{([^.'][^}']+)}/g, replacer);
-
- const replacer2 = (match: any, key: string, offset: any, string: any) => { // bcz: extend this to support expression -- is this really a script?
- const n = Cast(this.props.Document[key], "number", null);
- return n ? n.toString() : StrCast(this.props.Document[key], p);
- };
- style[prop] = p?.replace(/@([a-zA-Z0-9-_]+)/g, replacer2);
-
+ const p = (this.props as any)[prop] as string;
+ style[prop] = p?.replace(/{([^.'][^}']+)}/g, replacer);
});
const Tag = this.props.htmltag as keyof JSX.IntrinsicElements;
- return <Tag style={style} onClick={this.click}>
+ return <Tag style={style} onClick={this.click} onInput={this.onInput as any}>
{this.props.children}
</Tag>;
}
@@ -98,15 +97,15 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
isSelected: (outsideReaction: boolean) => boolean,
select: (ctrl: boolean) => void,
layoutKey: string,
- forceLayout?: string,
- forceFieldKey?: string,
hideOnLeave?: boolean,
makeLink?: () => Opt<Doc>, // function to call when a link is made
}> {
@computed get layout(): string {
TraceMobx();
if (!this.layoutDoc) return "<p>awaiting layout</p>";
- const layout = Cast(this.layoutDoc[StrCast(this.layoutDoc.layoutKey, this.layoutDoc === this.props.Document ? this.props.layoutKey : "layout")], "string");
+ // const layout = Cast(this.layoutDoc[StrCast(this.layoutDoc.layoutKey, this.layoutDoc === this.props.Document ? this.props.layoutKey : "layout")], "string"); // bcz: replaced this with below... is it right?
+ if (this.props.LayoutTemplateString) return this.props.LayoutTemplateString;
+ const layout = Cast(this.layoutDoc[this.layoutDoc === this.props.Document && this.props.layoutKey ? this.props.layoutKey : StrCast(this.layoutDoc.layoutKey, "layout")], "string");
if (this.props.layoutKey === "layout_keyValue") {
return StrCast(this.props.Document.layout_keyValue, KeyValueBox.LayoutString("data"));
} else
@@ -127,16 +126,22 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
}
get layoutDoc() {
const params = StrCast(this.props.Document.PARAMS);
- const template: Doc = this.props.LayoutDoc?.() || Doc.Layout(this.props.Document, this.props.layoutKey ? Cast(this.props.Document[this.props.layoutKey], Doc, null) : undefined);
+ // bcz: replaced this with below : is it correct? change was made to accommodate passing fieldKey's from a layout script
+ // const template: Doc = this.props.LayoutTemplate?.() || Doc.Layout(this.props.Document, this.props.layoutKey ? Cast(this.props.Document[this.props.layoutKey], Doc, null) : undefined);
+ const template: Doc = this.props.LayoutTemplate?.() || (this.props.LayoutTemplateString && this.props.Document) ||
+ (this.props.layoutKey && StrCast(this.props.Document[this.props.layoutKey]) && this.props.Document) ||
+ Doc.Layout(this.props.Document, this.props.layoutKey ? Cast(this.props.Document[this.props.layoutKey], Doc, null) : undefined);
return Doc.expandTemplateLayout(template, this.props.Document, params ? "(" + params + ")" : this.props.layoutKey);
}
- CreateBindings(onClick: Opt<ScriptField>): JsxBindings {
+ CreateBindings(onClick: Opt<ScriptField>, onInput: Opt<ScriptField>): JsxBindings {
const list = {
- ...OmitKeys(this.props, ['parentActive'], (obj: any) => obj.active = this.props.parentActive).omit,
+ ...OmitKeys(this.props, ['parentActive'], "", (obj: any) => obj.active = this.props.parentActive).omit,
+ RootDoc: Cast(this.layoutDoc?.rootDocument, Doc, null) || this.layoutDoc,
Document: this.layoutDoc,
DataDoc: this.dataDoc,
- onClick: onClick
+ onClick: onClick,
+ onInput: onInput
};
return { props: list };
}
@@ -153,7 +158,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
// 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} htmltag='${p1}'`;
+ return `<HTMLtag RootDoc={props.RootDoc} Document={props.Document} htmltag='${p1}'`;
};
layoutFrame = layoutFrame.replace(/<HTML([a-zA-Z0-9_-]+)/g, replacer2);
@@ -164,18 +169,24 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
layoutFrame = layoutFrame.replace(/<\/HTML([a-zA-Z0-9_-]+)/g, replacer3);
// add onClick function to props
- const splits = layoutFrame.split("onClick=");
- let onClick: Opt<ScriptField>;
- if (splits.length > 1) {
- const code = XRegExp.matchRecursive(splits[1], "{", "}", "", { valueNames: ["between", "left", "match", "right", "between"] });
- layoutFrame = splits[0] + " onClick={props.onClick} " + splits[1].substring(code[1].end + 1);
- onClick = ScriptField.MakeScript(code[1].value, { this: Doc.name, self: Doc.name });
- }
-
- const bindings = this.CreateBindings(onClick);
+ const makeFuncProp = (func: string) => {
+ const splits = layoutFrame.split(`func=`);
+ if (splits.length > 1) {
+ const code = XRegExp.matchRecursive(splits[1], "{", "}", "", { valueNames: ["between", "left", "match", "right", "between"] });
+ layoutFrame = splits[0] + ` ${func}={props.onClick} ` + splits[1].substring(code[1].end + 1);
+ return ScriptField.MakeScript(code[1].value, { this: Doc.name, self: Doc.name, value: "string" });
+ }
+ return undefined;
+ // add input function to props
+ };
+ const onClick = makeFuncProp("onClick");
+ const onInput = makeFuncProp("onInput");
+
+ const bindings = this.CreateBindings(onClick, onInput);
// layoutFrame = splits.length > 1 ? splits[0] + splits[1].replace(/{([^{}]|(?R))*}/, replacer4) : ""; // might have been more elegant if javascript supported recursive patterns
return (this.props.renderDepth > 12 || !layoutFrame || !this.layoutDoc) ? (null) :
+<<<<<<< HEAD
this.props.forceLayout === "FormattedTextBox" && this.props.forceFieldKey ?
<FormattedTextBox {...bindings.props} fieldKey={this.props.forceFieldKey} />
:
@@ -196,5 +207,24 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & {
onError={(test: any) => { console.log(test); }}
/>;
+=======
+ <ObserverJsxParser
+ key={42}
+ blacklistedAttrs={[]}
+ renderInWrapper={false}
+ components={{
+ FormattedTextBox, ImageBox, DirectoryImportBox, FontIconBox, LabelBox, SliderBox, FieldView,
+ CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox,
+ PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, QueryBox,
+ ColorBox, DashWebRTCVideo, LinkAnchorBox, InkingStroke, DocHolderBox, LinkBox, ScriptingBox,
+ RecommendationsBox, ScreenshotBox, HTMLtag
+ }}
+ bindings={bindings}
+ jsx={layoutFrame}
+ showWarnings={true}
+
+ onError={(test: any) => { console.log(test); }}
+ />;
+>>>>>>> 08b6bf8b51ab631c8cfe9c3e12bfb0ae2dd7b4c7
}
} \ No newline at end of file