diff options
author | Bob Zeleznik <zzzman@gmail.com> | 2020-04-21 22:09:18 -0400 |
---|---|---|
committer | Bob Zeleznik <zzzman@gmail.com> | 2020-04-21 22:09:18 -0400 |
commit | 1808f23e8e72cfca8517d3788f9f89ec989f1062 (patch) | |
tree | 5e97e143d5a4938ae5b808fe7deae1cf055f160f | |
parent | 3d629495644631e6b614b1b48f1d32d6c7aeefc6 (diff) |
functional version of html tags in layout strings including scripts.
-rw-r--r-- | src/client/views/nodes/DocumentContentsView.tsx | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index 765416658..d577068b7 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -37,6 +37,8 @@ import React = require("react"); import { RecommendationsBox } from "../RecommendationsBox"; import { TraceMobx } from "../../../new_fields/util"; +import { ScriptField } from "../../../new_fields/ScriptField"; +import ReactTable from "react-table"; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? type BindingProps = Without<FieldViewProps, 'fieldKey'>; @@ -54,27 +56,38 @@ class ObserverJsxParser1 extends JsxParser { const ObserverJsxParser: typeof JsxParser = ObserverJsxParser1 as any; -interface DivProps { +interface HTMLtagProps { Document: Doc; + htmltag: string; } - +//"<HTMLdiv borderRadius='100px' onClick={() => this.bannerColor=this.bannerColor==='red'?'green':'red'} width='100%' height='100%' transform='rotate({2*this.x+this.y}deg)' backgroundColor='{this.bannerColor}'><ImageBox {...props} fieldKey={'data'}/><HTMLspan width='100%' marginTop='50%' height='10%' position='absolute' backgroundColor='green'>{this.title}</HTMLspan></HTMLdiv>" @observer -export class Div extends React.Component<DivProps> { +export class HTMLtag extends React.Component<HTMLtagProps> { + click = (e: React.MouseEvent) => { + const clickScript = (this.props as any).onClick; + ScriptField.MakeScript(clickScript, { self: Doc.name, this: Doc.name })?.script.run({ this: this.props.Document }); + } render() { const style: { [key: string]: any } = {}; - const divKeys = OmitKeys(this.props, ["children", "Document", "key", "__proto__"]).omit; + const divKeys = OmitKeys(this.props, ["children", "htmltag", "Document", "key", "onClick", "__proto__"]).omit; Object.keys(divKeys).map((prop: string) => { let p = (this.props as any)[prop] as string; - if (p?.startsWith("@")) { // bcz: extend this to support expression -- is this really a script? - const key = p.substring(1); + 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); - p = n ? n.toString() : StrCast(this.props.Document[key], p); - } - style[prop] = p; + return n ? n.toString() : StrCast(this.props.Document[key], p); + }; + style[prop] = p?.replace(/@([a-zA-Z0-9-_]+)/g, replacer2); + }); - return <div style={style}> + const Tag = this.props.htmltag as keyof JSX.IntrinsicElements; + return <Tag style={style} onClick={this.click}> {this.props.children} - </div>; + </Tag>; } } @@ -128,11 +141,24 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { render() { TraceMobx(); let layoutFrame = this.layout; - const replacer = (match: any, p1: string, offset: any, string: any) => { - const n = Cast(this.props.Document[p1], "number", null); - return n !== undefined ? n.toString() : StrCast(this.props.Document[p1], p1); + // replace code content with a script >{content}< as in <HTMLdiv>{this.title}</HTMLdiv> + const replacer = (match: any, expr: string, offset: any, string: any) => { + return ">" + (ScriptField.MakeFunction(expr, { self: Doc.name, this: Doc.name })?.script.run({ this: this.props.Document }).result as string || "") + "<"; }; - layoutFrame = layoutFrame.replace(/\{([a-zA-Z0-9_-]+)\}/g, replacer); + 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} 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`; + }; + layoutFrame = layoutFrame.replace(/<\/HTML([a-zA-Z0-9_-]+)/g, replacer3); + return (this.props.renderDepth > 12 || !layoutFrame || !this.layoutDoc) ? (null) : this.props.forceLayout === "FormattedTextBox" && this.props.forceFieldKey ? <FormattedTextBox {...this.CreateBindings().props} fieldKey={this.props.forceFieldKey} /> @@ -146,7 +172,7 @@ export class DocumentContentsView extends React.Component<DocumentViewProps & { CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, PresBox, YoutubeBox, PresElementBox, QueryBox, ColorBox, DashWebRTCVideo, LinkAnchorBox, InkingStroke, DocHolderBox, LinkBox, ScriptingBox, - RecommendationsBox, ScreenshotBox, Div + RecommendationsBox, ScreenshotBox, HTMLtag }} bindings={this.CreateBindings()} jsx={layoutFrame} |