@builder.io/sdk-solid 0.0.3 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +7 -2
- package/src/blocks/button.jsx +8 -0
- package/src/blocks/button.lite.tsx +11 -15
- package/src/blocks/{columns.js → columns.jsx} +39 -81
- package/src/blocks/columns.lite.tsx +28 -23
- package/src/blocks/{custom-code.js → custom-code.jsx} +5 -25
- package/src/blocks/custom-code.lite.tsx +3 -1
- package/src/blocks/{embed.js → embed.jsx} +5 -15
- package/src/blocks/embed.lite.tsx +3 -1
- package/src/blocks/{form.js → form.jsx} +34 -136
- package/src/blocks/form.lite.tsx +7 -2
- package/src/blocks/fragment.jsx +6 -0
- package/src/blocks/fragment.lite.tsx +3 -1
- package/src/blocks/{image.js → image.jsx} +47 -138
- package/src/blocks/image.lite.tsx +3 -1
- package/src/blocks/img.jsx +11 -0
- package/src/blocks/img.lite.tsx +3 -1
- package/src/blocks/input.jsx +8 -0
- package/src/blocks/input.lite.tsx +3 -1
- package/src/blocks/raw-text.jsx +6 -0
- package/src/blocks/raw-text.lite.tsx +3 -1
- package/src/blocks/{section.js → section.jsx} +9 -23
- package/src/blocks/section.lite.tsx +3 -1
- package/src/blocks/select.jsx +17 -0
- package/src/blocks/select.lite.tsx +9 -4
- package/src/blocks/submit-button.jsx +8 -0
- package/src/blocks/submit-button.lite.tsx +3 -1
- package/src/blocks/symbol.jsx +25 -0
- package/src/blocks/symbol.lite.tsx +4 -2
- package/src/blocks/text.jsx +6 -0
- package/src/blocks/text.lite.tsx +3 -1
- package/src/blocks/textarea.jsx +6 -0
- package/src/blocks/textarea.lite.tsx +3 -1
- package/src/blocks/video.jsx +15 -0
- package/src/blocks/video.lite.tsx +3 -1
- package/src/components/block-styles.jsx +5 -0
- package/src/components/block-styles.lite.tsx +3 -1
- package/src/components/error-boundary.jsx +5 -0
- package/src/components/error-boundary.lite.tsx +3 -1
- package/src/components/{render-block.js → render-block.jsx} +30 -70
- package/src/components/render-block.lite.tsx +11 -3
- package/src/components/render-blocks.jsx +57 -0
- package/src/components/render-blocks.lite.tsx +7 -4
- package/src/components/render-content/components/render-styles.jsx +73 -0
- package/src/components/render-content/components/render-styles.lite.tsx +72 -0
- package/src/components/render-content/render-content.jsx +210 -0
- package/src/components/{render-content.lite.tsx → render-content/render-content.lite.tsx} +22 -78
- package/src/constants/target.js +4 -0
- package/src/functions/if-target.js +11 -2
- package/src/functions/track.js +2 -2
- package/src/index-helpers/blocks-exports.js +1 -1
- package/src/scripts/init-editing.js +3 -2
- package/src/types/targets.js +0 -0
- package/src/blocks/button.js +0 -41
- package/src/blocks/fragment.js +0 -15
- package/src/blocks/img.js +0 -39
- package/src/blocks/input.js +0 -45
- package/src/blocks/raw-text.js +0 -25
- package/src/blocks/select.js +0 -57
- package/src/blocks/submit-button.js +0 -18
- package/src/blocks/symbol.js +0 -69
- package/src/blocks/text.js +0 -15
- package/src/blocks/textarea.js +0 -34
- package/src/blocks/video.js +0 -54
- package/src/components/block-styles.js +0 -3
- package/src/components/error-boundary.js +0 -3
- package/src/components/render-blocks.js +0 -104
- package/src/components/render-content.js +0 -314
- package/src/functions/get-target.js +0 -6
- package/src/functions/is-react-native.js +0 -6
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { mergeProps as _$mergeProps } from "solid-js/web";
|
|
2
|
-
import { createComponent as _$createComponent } from "solid-js/web";
|
|
3
1
|
import { useContext, Show, For } from "solid-js";
|
|
4
2
|
import { Dynamic } from "solid-js/web";
|
|
5
3
|
import { createMutable } from "solid-js/store";
|
|
@@ -12,7 +10,8 @@ import BuilderContext from "../context/builder.context";
|
|
|
12
10
|
import { getBlockActions } from "../functions/get-block-actions";
|
|
13
11
|
import { getProcessedBlock } from "../functions/get-processed-block";
|
|
14
12
|
import BlockStyles from "./block-styles";
|
|
15
|
-
|
|
13
|
+
|
|
14
|
+
function RenderBlock(props) {
|
|
16
15
|
const state = createMutable({
|
|
17
16
|
get component() {
|
|
18
17
|
const componentName = state.useBlock.component?.name;
|
|
@@ -85,70 +84,31 @@ export default function RenderBlock(props) {
|
|
|
85
84
|
|
|
86
85
|
});
|
|
87
86
|
const builderContext = useContext(BuilderContext);
|
|
88
|
-
return
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
get builderBlock() {
|
|
117
|
-
return state.useBlock;
|
|
118
|
-
},
|
|
119
|
-
|
|
120
|
-
get component() {
|
|
121
|
-
return state.componentRef;
|
|
122
|
-
},
|
|
123
|
-
|
|
124
|
-
get children() {
|
|
125
|
-
return _$createComponent(For, {
|
|
126
|
-
get each() {
|
|
127
|
-
return state.children;
|
|
128
|
-
},
|
|
129
|
-
|
|
130
|
-
children: (child, index) => _$createComponent(RenderBlock, {
|
|
131
|
-
block: child
|
|
132
|
-
})
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
}));
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
}), _$createComponent(For, {
|
|
140
|
-
get each() {
|
|
141
|
-
return state.noCompRefChildren;
|
|
142
|
-
},
|
|
143
|
-
|
|
144
|
-
children: (child, index) => _$createComponent(RenderBlock, {
|
|
145
|
-
block: child
|
|
146
|
-
})
|
|
147
|
-
})];
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
}));
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
});
|
|
154
|
-
}
|
|
87
|
+
return <>
|
|
88
|
+
<Show when={!state.componentInfo?.noWrap}>
|
|
89
|
+
<Dynamic {...state.propertiesAndActions} style={state.css} component={state.tagName}>
|
|
90
|
+
<BlockStyles block={state.useBlock}></BlockStyles>
|
|
91
|
+
<Show when={state.componentRef}>
|
|
92
|
+
<Dynamic {...state.componentOptions} builderBlock={state.useBlock} component={state.componentRef}>
|
|
93
|
+
<For each={state.children}>
|
|
94
|
+
{(child, _index) => {
|
|
95
|
+
const index = _index();
|
|
96
|
+
|
|
97
|
+
return <RenderBlock block={child}></RenderBlock>;
|
|
98
|
+
}}
|
|
99
|
+
</For>
|
|
100
|
+
</Dynamic>
|
|
101
|
+
</Show>
|
|
102
|
+
<For each={state.noCompRefChildren}>
|
|
103
|
+
{(child, _index) => {
|
|
104
|
+
const index = _index();
|
|
105
|
+
|
|
106
|
+
return <RenderBlock block={child}></RenderBlock>;
|
|
107
|
+
}}
|
|
108
|
+
</For>
|
|
109
|
+
</Dynamic>
|
|
110
|
+
</Show>
|
|
111
|
+
</>;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export default RenderBlock;
|
|
@@ -12,7 +12,7 @@ import { getBlockActions } from "../functions/get-block-actions";
|
|
|
12
12
|
import { getProcessedBlock } from "../functions/get-processed-block";
|
|
13
13
|
import BlockStyles from "./block-styles.lite";
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
function RenderBlock(props) {
|
|
16
16
|
const state = createMutable({
|
|
17
17
|
get component() {
|
|
18
18
|
const componentName = state.useBlock.component?.name;
|
|
@@ -94,15 +94,23 @@ export default function RenderBlock(props) {
|
|
|
94
94
|
component={state.componentRef}
|
|
95
95
|
>
|
|
96
96
|
<For each={state.children}>
|
|
97
|
-
{(child,
|
|
97
|
+
{(child, _index) => {
|
|
98
|
+
const index = _index();
|
|
99
|
+
return <RenderBlock block={child}></RenderBlock>;
|
|
100
|
+
}}
|
|
98
101
|
</For>
|
|
99
102
|
</Dynamic>
|
|
100
103
|
</Show>
|
|
101
104
|
<For each={state.noCompRefChildren}>
|
|
102
|
-
{(child,
|
|
105
|
+
{(child, _index) => {
|
|
106
|
+
const index = _index();
|
|
107
|
+
return <RenderBlock block={child}></RenderBlock>;
|
|
108
|
+
}}
|
|
103
109
|
</For>
|
|
104
110
|
</Dynamic>
|
|
105
111
|
</Show>
|
|
106
112
|
</>
|
|
107
113
|
);
|
|
108
114
|
}
|
|
115
|
+
|
|
116
|
+
export default RenderBlock;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { Show, For } from "solid-js";
|
|
2
|
+
import { createMutable } from "solid-js/store";
|
|
3
|
+
import { css } from "solid-styled-components";
|
|
4
|
+
import { isEditing } from "../functions/is-editing";
|
|
5
|
+
import RenderBlock from "./render-block";
|
|
6
|
+
|
|
7
|
+
function RenderBlocks(props) {
|
|
8
|
+
const state = createMutable({
|
|
9
|
+
get className() {
|
|
10
|
+
return "builder-blocks" + (!props.blocks?.length ? " no-blocks" : "");
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
onClick() {
|
|
14
|
+
if (isEditing() && !props.blocks?.length) {
|
|
15
|
+
window.parent?.postMessage({
|
|
16
|
+
type: "builder.clickEmptyBlocks",
|
|
17
|
+
data: {
|
|
18
|
+
parentElementId: props.parent,
|
|
19
|
+
dataPath: props.path
|
|
20
|
+
}
|
|
21
|
+
}, "*");
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
onMouseEnter() {
|
|
26
|
+
if (isEditing() && !props.blocks?.length) {
|
|
27
|
+
window.parent?.postMessage({
|
|
28
|
+
type: "builder.hoverEmptyBlocks",
|
|
29
|
+
data: {
|
|
30
|
+
parentElementId: props.parent,
|
|
31
|
+
dataPath: props.path
|
|
32
|
+
}
|
|
33
|
+
}, "*");
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
});
|
|
38
|
+
return <div class={state.className + " " + css({
|
|
39
|
+
display: "flex",
|
|
40
|
+
flexDirection: "column",
|
|
41
|
+
alignItems: "stretch"
|
|
42
|
+
})} builder-path={props.path} builder-parent-id={props.parent} dataSet={{
|
|
43
|
+
class: state.className
|
|
44
|
+
}} onClick={event => state.onClick()} onMouseEnter={event => state.onMouseEnter()}>
|
|
45
|
+
<Show when={props.blocks}>
|
|
46
|
+
<For each={props.blocks}>
|
|
47
|
+
{(block, _index) => {
|
|
48
|
+
const index = _index();
|
|
49
|
+
|
|
50
|
+
return <RenderBlock key={block.id} block={block}></RenderBlock>;
|
|
51
|
+
}}
|
|
52
|
+
</For>
|
|
53
|
+
</Show>
|
|
54
|
+
</div>;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default RenderBlocks;
|
|
@@ -6,7 +6,7 @@ import { css } from "solid-styled-components";
|
|
|
6
6
|
import { isEditing } from "../functions/is-editing";
|
|
7
7
|
import RenderBlock from "./render-block.lite";
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
function RenderBlocks(props) {
|
|
10
10
|
const state = createMutable({
|
|
11
11
|
get className() {
|
|
12
12
|
return "builder-blocks" + (!props.blocks?.length ? " no-blocks" : "");
|
|
@@ -62,11 +62,14 @@ export default function RenderBlocks(props) {
|
|
|
62
62
|
>
|
|
63
63
|
<Show when={props.blocks}>
|
|
64
64
|
<For each={props.blocks}>
|
|
65
|
-
{(block,
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
{(block, _index) => {
|
|
66
|
+
const index = _index();
|
|
67
|
+
return <RenderBlock key={block.id} block={block}></RenderBlock>;
|
|
68
|
+
}}
|
|
68
69
|
</For>
|
|
69
70
|
</Show>
|
|
70
71
|
</div>
|
|
71
72
|
);
|
|
72
73
|
}
|
|
74
|
+
|
|
75
|
+
export default RenderBlocks;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { createMutable } from "solid-js/store";
|
|
2
|
+
|
|
3
|
+
function RenderStyles(props) {
|
|
4
|
+
const state = createMutable({
|
|
5
|
+
getCssFromFont(font) {
|
|
6
|
+
// TODO: compute what font sizes are used and only load those.......
|
|
7
|
+
const family = font.family + (font.kind && !font.kind.includes("#") ? ", " + font.kind : "");
|
|
8
|
+
const name = family.split(",")[0];
|
|
9
|
+
const url = font.fileUrl ?? font?.files?.regular;
|
|
10
|
+
let str = "";
|
|
11
|
+
|
|
12
|
+
if (url && family && name) {
|
|
13
|
+
str += `
|
|
14
|
+
@font-face {
|
|
15
|
+
font-family: "${family}";
|
|
16
|
+
src: local("${name}"), url('${url}') format('woff2');
|
|
17
|
+
font-display: fallback;
|
|
18
|
+
font-weight: 400;
|
|
19
|
+
}
|
|
20
|
+
`.trim();
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (font.files) {
|
|
24
|
+
for (const weight in font.files) {
|
|
25
|
+
const isNumber = String(Number(weight)) === weight;
|
|
26
|
+
|
|
27
|
+
if (!isNumber) {
|
|
28
|
+
continue;
|
|
29
|
+
} // TODO: maybe limit number loaded
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
const weightUrl = font.files[weight];
|
|
33
|
+
|
|
34
|
+
if (weightUrl && weightUrl !== url) {
|
|
35
|
+
str += `
|
|
36
|
+
@font-face {
|
|
37
|
+
font-family: "${family}";
|
|
38
|
+
src: url('${weightUrl}') format('woff2');
|
|
39
|
+
font-display: fallback;
|
|
40
|
+
font-weight: ${weight};
|
|
41
|
+
}
|
|
42
|
+
`.trim();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return str;
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
getFontCss({
|
|
51
|
+
customFonts
|
|
52
|
+
}) {
|
|
53
|
+
// TODO: flag for this
|
|
54
|
+
// if (!this.builder.allowCustomFonts) {
|
|
55
|
+
// return '';
|
|
56
|
+
// }
|
|
57
|
+
// TODO: separate internal data from external
|
|
58
|
+
return customFonts?.map(font => this.getCssFromFont(font))?.join(" ") || "";
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
getInjectedStyles() {
|
|
62
|
+
return `
|
|
63
|
+
${props.cssCode}
|
|
64
|
+
${state.getFontCss({
|
|
65
|
+
customFonts: props.customFonts
|
|
66
|
+
})}`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
});
|
|
70
|
+
return <style>{state.getInjectedStyles()}</style>;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export default RenderStyles;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createMutable } from "solid-js/store";
|
|
2
|
+
|
|
3
|
+
function RenderStyles(props) {
|
|
4
|
+
const state = createMutable({
|
|
5
|
+
getCssFromFont(font: CustomFont) {
|
|
6
|
+
// TODO: compute what font sizes are used and only load those.......
|
|
7
|
+
const family =
|
|
8
|
+
font.family +
|
|
9
|
+
(font.kind && !font.kind.includes("#") ? ", " + font.kind : "");
|
|
10
|
+
const name = family.split(",")[0];
|
|
11
|
+
const url = font.fileUrl ?? font?.files?.regular;
|
|
12
|
+
let str = "";
|
|
13
|
+
|
|
14
|
+
if (url && family && name) {
|
|
15
|
+
str += `
|
|
16
|
+
@font-face {
|
|
17
|
+
font-family: "${family}";
|
|
18
|
+
src: local("${name}"), url('${url}') format('woff2');
|
|
19
|
+
font-display: fallback;
|
|
20
|
+
font-weight: 400;
|
|
21
|
+
}
|
|
22
|
+
`.trim();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (font.files) {
|
|
26
|
+
for (const weight in font.files) {
|
|
27
|
+
const isNumber = String(Number(weight)) === weight;
|
|
28
|
+
|
|
29
|
+
if (!isNumber) {
|
|
30
|
+
continue;
|
|
31
|
+
} // TODO: maybe limit number loaded
|
|
32
|
+
|
|
33
|
+
const weightUrl = font.files[weight];
|
|
34
|
+
|
|
35
|
+
if (weightUrl && weightUrl !== url) {
|
|
36
|
+
str += `
|
|
37
|
+
@font-face {
|
|
38
|
+
font-family: "${family}";
|
|
39
|
+
src: url('${weightUrl}') format('woff2');
|
|
40
|
+
font-display: fallback;
|
|
41
|
+
font-weight: ${weight};
|
|
42
|
+
}
|
|
43
|
+
`.trim();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return str;
|
|
49
|
+
},
|
|
50
|
+
getFontCss({ customFonts }: { customFonts?: CustomFont[] }) {
|
|
51
|
+
// TODO: flag for this
|
|
52
|
+
// if (!this.builder.allowCustomFonts) {
|
|
53
|
+
// return '';
|
|
54
|
+
// }
|
|
55
|
+
// TODO: separate internal data from external
|
|
56
|
+
return (
|
|
57
|
+
customFonts?.map((font) => this.getCssFromFont(font))?.join(" ") || ""
|
|
58
|
+
);
|
|
59
|
+
},
|
|
60
|
+
getInjectedStyles() {
|
|
61
|
+
return `
|
|
62
|
+
${props.cssCode}
|
|
63
|
+
${state.getFontCss({
|
|
64
|
+
customFonts: props.customFonts,
|
|
65
|
+
})}`;
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
return <style>{state.getInjectedStyles()}</style>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default RenderStyles;
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { Show, onMount } from "solid-js";
|
|
2
|
+
import { Dynamic } from "solid-js/web";
|
|
3
|
+
import { createMutable } from "solid-js/store";
|
|
4
|
+
import { isBrowser } from "../../functions/is-browser";
|
|
5
|
+
import BuilderContext from "../../context/builder.context";
|
|
6
|
+
import { track } from "../../functions/track";
|
|
7
|
+
import { isEditing } from "../../functions/is-editing";
|
|
8
|
+
import { isPreviewing } from "../../functions/is-previewing";
|
|
9
|
+
import { previewingModelName } from "../../functions/previewing-model-name";
|
|
10
|
+
import { getContent } from "../../functions/get-content";
|
|
11
|
+
import { convertSearchParamsToQueryObject, getBuilderSearchParams } from "../../functions/get-builder-search-params";
|
|
12
|
+
import RenderBlocks from "../render-blocks";
|
|
13
|
+
import { evaluate } from "../../functions/evaluate";
|
|
14
|
+
import { getFetch } from "../../functions/get-fetch";
|
|
15
|
+
import { TARGET } from "../../constants/target";
|
|
16
|
+
import RenderStyles from "./components/render-styles";
|
|
17
|
+
|
|
18
|
+
function RenderContent(props) {
|
|
19
|
+
const state = createMutable({
|
|
20
|
+
get useContent() {
|
|
21
|
+
const mergedContent = { ...props.content,
|
|
22
|
+
...state.overrideContent,
|
|
23
|
+
data: { ...props.content?.data,
|
|
24
|
+
...props.data,
|
|
25
|
+
...state.overrideContent?.data
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return mergedContent;
|
|
29
|
+
},
|
|
30
|
+
|
|
31
|
+
overrideContent: null,
|
|
32
|
+
update: 0,
|
|
33
|
+
overrideState: {},
|
|
34
|
+
|
|
35
|
+
get state() {
|
|
36
|
+
return { ...props.content?.data?.state,
|
|
37
|
+
...props.data,
|
|
38
|
+
...state.overrideState
|
|
39
|
+
};
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
get context() {
|
|
43
|
+
return {};
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
processMessage(event) {
|
|
47
|
+
const {
|
|
48
|
+
data
|
|
49
|
+
} = event;
|
|
50
|
+
|
|
51
|
+
if (data) {
|
|
52
|
+
switch (data.type) {
|
|
53
|
+
case "builder.contentUpdate":
|
|
54
|
+
{
|
|
55
|
+
const messageContent = data.data;
|
|
56
|
+
const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
|
|
57
|
+
const contentData = messageContent.data;
|
|
58
|
+
|
|
59
|
+
if (key === props.model) {
|
|
60
|
+
state.overrideContent = contentData;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
case "builder.patchUpdates":
|
|
67
|
+
{
|
|
68
|
+
// TODO
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
evaluateJsCode() {
|
|
76
|
+
// run any dynamic JS code attached to content
|
|
77
|
+
const jsCode = state.useContent?.data?.jsCode;
|
|
78
|
+
|
|
79
|
+
if (jsCode) {
|
|
80
|
+
evaluate({
|
|
81
|
+
code: jsCode,
|
|
82
|
+
context: state.context,
|
|
83
|
+
state: state.state
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
get httpReqsData() {
|
|
89
|
+
return {};
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
evalExpression(expression) {
|
|
93
|
+
return expression.replace(/{{([^}]+)}}/g, (_match, group) => evaluate({
|
|
94
|
+
code: group,
|
|
95
|
+
context: state.context,
|
|
96
|
+
state: state.state
|
|
97
|
+
}));
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
handleRequest({
|
|
101
|
+
url,
|
|
102
|
+
key
|
|
103
|
+
}) {
|
|
104
|
+
const fetchAndSetState = async () => {
|
|
105
|
+
const response = await getFetch()(url);
|
|
106
|
+
const json = await response.json();
|
|
107
|
+
const newOverrideState = { ...state.overrideState,
|
|
108
|
+
[key]: json
|
|
109
|
+
};
|
|
110
|
+
state.overrideState = newOverrideState;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
fetchAndSetState();
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
runHttpRequests() {
|
|
117
|
+
const requests = state.useContent?.data?.httpRequests ?? {};
|
|
118
|
+
Object.entries(requests).forEach(([key, url]) => {
|
|
119
|
+
if (url && (!state.httpReqsData[key] || isEditing())) {
|
|
120
|
+
const evaluatedUrl = state.evalExpression(url);
|
|
121
|
+
state.handleRequest({
|
|
122
|
+
url: evaluatedUrl,
|
|
123
|
+
key
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
emitStateUpdate() {
|
|
130
|
+
window.dispatchEvent(new CustomEvent("builder:component:stateChange", {
|
|
131
|
+
detail: {
|
|
132
|
+
state: state.state,
|
|
133
|
+
ref: {
|
|
134
|
+
name: props.model
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
});
|
|
141
|
+
onMount(() => {
|
|
142
|
+
if (isBrowser()) {
|
|
143
|
+
if (isEditing()) {
|
|
144
|
+
window.addEventListener("message", state.processMessage);
|
|
145
|
+
window.addEventListener("builder:component:stateChangeListenerActivated", state.emitStateUpdate);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (state.useContent) {
|
|
149
|
+
track("impression", {
|
|
150
|
+
contentId: state.useContent.id
|
|
151
|
+
});
|
|
152
|
+
} // override normal content in preview mode
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
if (isPreviewing()) {
|
|
156
|
+
if (props.model && previewingModelName() === props.model) {
|
|
157
|
+
const currentUrl = new URL(location.href);
|
|
158
|
+
const previewApiKey = currentUrl.searchParams.get("apiKey");
|
|
159
|
+
|
|
160
|
+
if (previewApiKey) {
|
|
161
|
+
getContent({
|
|
162
|
+
model: props.model,
|
|
163
|
+
apiKey: previewApiKey,
|
|
164
|
+
options: getBuilderSearchParams(convertSearchParamsToQueryObject(currentUrl.searchParams))
|
|
165
|
+
}).then(content => {
|
|
166
|
+
if (content) {
|
|
167
|
+
state.overrideContent = content;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
state.evaluateJsCode();
|
|
175
|
+
state.runHttpRequests();
|
|
176
|
+
state.emitStateUpdate();
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
return <Dynamic value={{
|
|
180
|
+
get content() {
|
|
181
|
+
return state.useContent;
|
|
182
|
+
},
|
|
183
|
+
|
|
184
|
+
get state() {
|
|
185
|
+
return state.state;
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
get context() {
|
|
189
|
+
return state.context;
|
|
190
|
+
},
|
|
191
|
+
|
|
192
|
+
get apiKey() {
|
|
193
|
+
return props.apiKey;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
}} component={BuilderContext.Provider}>
|
|
197
|
+
<Show when={state.useContent}>
|
|
198
|
+
<div onClick={event => track("click", {
|
|
199
|
+
contentId: state.useContent.id
|
|
200
|
+
})} data-builder-content-id={state.useContent?.id}>
|
|
201
|
+
<Show when={(state.useContent?.data?.cssCode || state.useContent?.data?.customFonts?.length) && TARGET !== "reactNative"}>
|
|
202
|
+
<RenderStyles cssCode={state.useContent.data.cssCode} customFonts={state.useContent.data.customFonts}></RenderStyles>
|
|
203
|
+
</Show>
|
|
204
|
+
<RenderBlocks blocks={state.useContent?.data?.blocks}></RenderBlocks>
|
|
205
|
+
</div>
|
|
206
|
+
</Show>
|
|
207
|
+
</Dynamic>;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export default RenderContent;
|