diff options
Diffstat (limited to 'src/client/views/nodes/DocumentContentsView.tsx')
-rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 69 |
1 files changed, 40 insertions, 29 deletions
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index a022f2e02..4d20d3e2c 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -19,7 +19,7 @@ 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"; @@ -58,35 +58,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; 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); + const p = (this.props as any)[prop] as string; + 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 || ""; }; - style[prop] = p?.replace(/@([a-zA-Z0-9-_]+)/g, replacer2); - + 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>; } @@ -105,7 +104,8 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { @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? + 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 @@ -126,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.LayoutDoc?.() || Doc.Layout(this.props.Document, this.props.layoutKey ? Cast(this.props.Document[this.props.layoutKey], Doc, null) : undefined); + const template: Doc = this.props.LayoutDoc?.() || + (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, + RootDoc: Cast(this.layoutDoc?.rootDocument, Doc, null) || this.layoutDoc, Document: this.layoutDoc, DataDoc: this.dataDoc, - onClick: onClick + onClick: onClick, + onInput: onInput }; return { props: list }; } @@ -152,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); @@ -163,15 +169,20 @@ 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) : |