aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Zeleznik <zzzman@gmail.com>2020-04-21 22:09:18 -0400
committerBob Zeleznik <zzzman@gmail.com>2020-04-21 22:09:18 -0400
commit1808f23e8e72cfca8517d3788f9f89ec989f1062 (patch)
tree5e97e143d5a4938ae5b808fe7deae1cf055f160f
parent3d629495644631e6b614b1b48f1d32d6c7aeefc6 (diff)
functional version of html tags in layout strings including scripts.
-rw-r--r--src/client/views/nodes/DocumentContentsView.tsx58
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}