@builder.io/sdk-react-native 0.2.3 → 0.4.0
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/dist/blocks/button/button.js +1 -0
- package/dist/blocks/columns/columns.js +2 -1
- package/dist/blocks/custom-code/custom-code.js +1 -0
- package/dist/blocks/embed/embed.js +1 -0
- package/dist/blocks/form/form.js +1 -0
- package/dist/blocks/fragment/fragment.js +1 -0
- package/dist/blocks/img/img.js +1 -0
- package/dist/blocks/input/input.js +1 -0
- package/dist/blocks/raw-text/raw-text.js +1 -0
- package/dist/blocks/section/section.js +1 -0
- package/dist/blocks/select/select.js +1 -0
- package/dist/blocks/submit-button/submit-button.js +1 -0
- package/dist/blocks/symbol/symbol.js +2 -1
- package/dist/blocks/textarea/textarea.js +1 -0
- package/dist/components/render-block/block-styles.js +4 -1
- package/dist/components/render-block/render-block.helpers.js +8 -20
- package/dist/components/render-block/render-block.js +28 -21
- package/dist/components/render-block/render-component.js +4 -3
- package/dist/components/render-block/render-repeated-block.js +4 -2
- package/dist/components/render-blocks.js +1 -0
- package/dist/components/render-content/builder-editing.js +1 -0
- package/dist/components/render-content/components/render-styles.js +2 -1
- package/dist/components/render-content/render-content.js +48 -10
- package/dist/components/render-content/wrap-component-ref.js +5 -0
- package/dist/components/render-content-variants/helpers.js +137 -0
- package/dist/components/render-content-variants/render-content-variants.js +73 -0
- package/dist/components/render-inlined-styles.js +2 -12
- package/dist/constants/sdk-version.js +4 -0
- package/dist/context/builder.context.js +3 -2
- package/dist/functions/evaluate.js +25 -3
- package/dist/functions/evaluate.test.js +19 -0
- package/dist/functions/get-block-actions-handler.js +3 -1
- package/dist/functions/get-content/generate-content-url.js +2 -2
- package/dist/functions/get-content/generate-content-url.test.js +15 -0
- package/dist/functions/get-content/index.js +36 -19
- package/dist/functions/get-processed-block.js +16 -4
- package/dist/functions/get-processed-block.test.js +3 -1
- package/dist/helpers/ab-tests.js +123 -6
- package/dist/helpers/canTrack.js +6 -0
- package/dist/helpers/cookie.js +9 -2
- package/dist/helpers/logger.js +2 -1
- package/dist/index.js +17 -10
- package/dist/scripts/init-editing.js +2 -0
- package/package.json +2 -5
- package/src/blocks/button/button.jsx +1 -0
- package/src/blocks/columns/columns.jsx +2 -1
- package/src/blocks/custom-code/custom-code.jsx +1 -0
- package/src/blocks/embed/embed.jsx +1 -0
- package/src/blocks/form/form.jsx +1 -0
- package/src/blocks/fragment/fragment.jsx +1 -0
- package/src/blocks/img/img.jsx +1 -0
- package/src/blocks/input/input.jsx +1 -0
- package/src/blocks/raw-text/raw-text.jsx +1 -0
- package/src/blocks/section/section.jsx +1 -0
- package/src/blocks/select/select.jsx +1 -0
- package/src/blocks/submit-button/submit-button.jsx +1 -0
- package/src/blocks/symbol/symbol.jsx +2 -1
- package/src/blocks/textarea/textarea.jsx +1 -0
- package/src/components/render-block/block-styles.jsx +4 -1
- package/src/components/render-block/render-block.helpers.js +7 -19
- package/src/components/render-block/render-block.jsx +24 -23
- package/src/components/render-block/render-component.jsx +5 -5
- package/src/components/render-block/render-repeated-block.jsx +4 -2
- package/src/components/render-blocks.jsx +1 -0
- package/src/components/render-content/builder-editing.jsx +1 -0
- package/src/components/render-content/components/render-styles.jsx +4 -3
- package/src/components/render-content/render-content.jsx +54 -9
- package/src/components/render-content/wrap-component-ref.js +4 -0
- package/src/components/render-content-variants/helpers.js +139 -0
- package/src/components/render-content-variants/render-content-variants.jsx +101 -0
- package/src/components/render-inlined-styles.jsx +2 -22
- package/src/constants/sdk-version.js +1 -0
- package/src/context/builder.context.js +3 -2
- package/src/functions/evaluate.js +27 -3
- package/src/functions/evaluate.test.js +17 -0
- package/src/functions/get-block-actions-handler.js +3 -1
- package/src/functions/get-content/generate-content-url.js +2 -1
- package/src/functions/get-content/generate-content-url.test.js +15 -0
- package/src/functions/get-content/index.js +35 -18
- package/src/functions/get-processed-block.js +20 -4
- package/src/functions/get-processed-block.test.js +3 -1
- package/src/helpers/ab-tests.js +132 -10
- package/src/helpers/canTrack.js +5 -0
- package/src/helpers/cookie.js +9 -2
- package/src/helpers/logger.js +2 -1
- package/src/index.js +18 -7
- package/src/scripts/init-editing.js +2 -0
- package/src/functions/get-content/ab-testing.js +0 -99
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
import {
|
|
3
4
|
FlatList,
|
|
@@ -73,7 +74,7 @@ function Columns(props) {
|
|
|
73
74
|
};
|
|
74
75
|
}
|
|
75
76
|
const width = getColumnCssWidth(index);
|
|
76
|
-
const gutterPixels = `${
|
|
77
|
+
const gutterPixels = `${gutter}px`;
|
|
77
78
|
const mobileWidth = "100%";
|
|
78
79
|
const mobileMarginLeft = 0;
|
|
79
80
|
return {
|
package/src/blocks/form/form.jsx
CHANGED
package/src/blocks/img/img.jsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
import {
|
|
3
4
|
FlatList,
|
|
@@ -91,7 +92,7 @@ function Symbol(props) {
|
|
|
91
92
|
customComponents={Object.values(builderContext.registeredComponents)}
|
|
92
93
|
data={{
|
|
93
94
|
...props.symbol?.data,
|
|
94
|
-
...builderContext.
|
|
95
|
+
...builderContext.localState,
|
|
95
96
|
...contentToUse?.data?.state,
|
|
96
97
|
}}
|
|
97
98
|
model={props.symbol?.model}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
import {
|
|
3
4
|
FlatList,
|
|
@@ -21,7 +22,9 @@ function BlockStyles(props) {
|
|
|
21
22
|
function useBlock() {
|
|
22
23
|
return getProcessedBlock({
|
|
23
24
|
block: props.block,
|
|
24
|
-
|
|
25
|
+
localState: props.context.localState,
|
|
26
|
+
rootState: props.context.rootState,
|
|
27
|
+
rootSetState: props.context.rootSetState,
|
|
25
28
|
context: props.context.context,
|
|
26
29
|
shouldEvaluateBindings: true,
|
|
27
30
|
});
|
|
@@ -58,7 +58,9 @@ const getComponent = ({
|
|
|
58
58
|
var _a;
|
|
59
59
|
const componentName = (_a = getProcessedBlock({
|
|
60
60
|
block,
|
|
61
|
-
|
|
61
|
+
localState: context.localState,
|
|
62
|
+
rootState: context.rootState,
|
|
63
|
+
rootSetState: context.rootSetState,
|
|
62
64
|
context: context.context,
|
|
63
65
|
shouldEvaluateBindings: false
|
|
64
66
|
}).component) == null ? void 0 : _a.name;
|
|
@@ -85,7 +87,9 @@ const getRepeatItemData = ({
|
|
|
85
87
|
}
|
|
86
88
|
const itemsArray = evaluate({
|
|
87
89
|
code: repeat.collection,
|
|
88
|
-
|
|
90
|
+
localState: context.localState,
|
|
91
|
+
rootState: context.rootState,
|
|
92
|
+
rootSetState: context.rootSetState,
|
|
89
93
|
context: context.context
|
|
90
94
|
});
|
|
91
95
|
if (!Array.isArray(itemsArray)) {
|
|
@@ -95,7 +99,7 @@ const getRepeatItemData = ({
|
|
|
95
99
|
const itemNameToUse = repeat.itemName || (collectionName ? collectionName + "Item" : "item");
|
|
96
100
|
const repeatArray = itemsArray.map((item, index) => ({
|
|
97
101
|
context: __spreadProps(__spreadValues({}, context), {
|
|
98
|
-
|
|
102
|
+
localState: __spreadProps(__spreadValues({}, context.localState), {
|
|
99
103
|
$index: index,
|
|
100
104
|
$item: item,
|
|
101
105
|
[itemNameToUse]: item,
|
|
@@ -106,24 +110,8 @@ const getRepeatItemData = ({
|
|
|
106
110
|
}));
|
|
107
111
|
return repeatArray;
|
|
108
112
|
};
|
|
109
|
-
const getProxyState = (context) => {
|
|
110
|
-
if (typeof Proxy === "undefined") {
|
|
111
|
-
console.error("no Proxy available in this environment, cannot proxy state.");
|
|
112
|
-
return context.state;
|
|
113
|
-
}
|
|
114
|
-
const useState = new Proxy(context.state, {
|
|
115
|
-
set: (obj, prop, value) => {
|
|
116
|
-
var _a;
|
|
117
|
-
obj[prop] = value;
|
|
118
|
-
(_a = context.setState) == null ? void 0 : _a.call(context, obj);
|
|
119
|
-
return true;
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
return useState;
|
|
123
|
-
};
|
|
124
113
|
export {
|
|
125
114
|
getComponent,
|
|
126
|
-
getProxyState,
|
|
127
115
|
getRepeatItemData,
|
|
128
116
|
isEmptyHtmlElement
|
|
129
117
|
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
import {
|
|
3
4
|
FlatList,
|
|
@@ -15,7 +16,6 @@ import { getProcessedBlock } from "../../functions/get-processed-block.js";
|
|
|
15
16
|
import BlockStyles from "./block-styles";
|
|
16
17
|
import {
|
|
17
18
|
getComponent,
|
|
18
|
-
getProxyState,
|
|
19
19
|
getRepeatItemData,
|
|
20
20
|
isEmptyHtmlElement,
|
|
21
21
|
} from "./render-block.helpers.js";
|
|
@@ -33,25 +33,27 @@ function RenderBlock(props) {
|
|
|
33
33
|
})
|
|
34
34
|
);
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
getRepeatItemData({
|
|
36
|
+
function repeatItem() {
|
|
37
|
+
return getRepeatItemData({
|
|
38
38
|
block: props.block,
|
|
39
39
|
context: props.context,
|
|
40
|
-
})
|
|
41
|
-
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
42
|
|
|
43
43
|
function useBlock() {
|
|
44
|
-
return
|
|
44
|
+
return repeatItem()
|
|
45
45
|
? props.block
|
|
46
46
|
: getProcessedBlock({
|
|
47
47
|
block: props.block,
|
|
48
|
-
|
|
48
|
+
localState: props.context.localState,
|
|
49
|
+
rootState: props.context.rootState,
|
|
50
|
+
rootSetState: props.context.rootSetState,
|
|
49
51
|
context: props.context.context,
|
|
50
52
|
shouldEvaluateBindings: true,
|
|
51
53
|
});
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
const [
|
|
56
|
+
const [Tag, setTag] = useState(() => props.block.tagName || "div");
|
|
55
57
|
|
|
56
58
|
function canShowBlock() {
|
|
57
59
|
if ("hide" in useBlock()) {
|
|
@@ -63,14 +65,12 @@ function RenderBlock(props) {
|
|
|
63
65
|
return true;
|
|
64
66
|
}
|
|
65
67
|
|
|
66
|
-
const [proxyState, setProxyState] = useState(() =>
|
|
67
|
-
getProxyState(props.context)
|
|
68
|
-
);
|
|
69
|
-
|
|
70
68
|
function actions() {
|
|
71
69
|
return getBlockActions({
|
|
72
70
|
block: useBlock(),
|
|
73
|
-
|
|
71
|
+
rootState: props.context.rootState,
|
|
72
|
+
rootSetState: props.context.rootSetState,
|
|
73
|
+
localState: props.context.localState,
|
|
74
74
|
context: props.context.context,
|
|
75
75
|
});
|
|
76
76
|
}
|
|
@@ -99,7 +99,7 @@ function RenderBlock(props) {
|
|
|
99
99
|
* blocks, and the children will be repeated within those blocks.
|
|
100
100
|
*/
|
|
101
101
|
const shouldRenderChildrenOutsideRef =
|
|
102
|
-
!component?.component && !
|
|
102
|
+
!component?.component && !repeatItem();
|
|
103
103
|
return shouldRenderChildrenOutsideRef ? useBlock().children ?? [] : [];
|
|
104
104
|
}
|
|
105
105
|
|
|
@@ -119,10 +119,11 @@ function RenderBlock(props) {
|
|
|
119
119
|
return {
|
|
120
120
|
apiKey: props.context.apiKey,
|
|
121
121
|
apiVersion: props.context.apiVersion,
|
|
122
|
-
|
|
122
|
+
localState: props.context.localState,
|
|
123
|
+
rootState: props.context.rootState,
|
|
124
|
+
rootSetState: props.context.rootSetState,
|
|
123
125
|
content: props.context.content,
|
|
124
126
|
context: props.context.context,
|
|
125
|
-
setState: props.context.setState,
|
|
126
127
|
registeredComponents: props.context.registeredComponents,
|
|
127
128
|
inheritedStyles: getInheritedTextStyles(),
|
|
128
129
|
};
|
|
@@ -157,14 +158,14 @@ function RenderBlock(props) {
|
|
|
157
158
|
<>
|
|
158
159
|
{!component?.noWrap ? (
|
|
159
160
|
<>
|
|
160
|
-
{isEmptyHtmlElement(
|
|
161
|
+
{isEmptyHtmlElement(Tag) ? (
|
|
161
162
|
<>
|
|
162
|
-
<
|
|
163
|
+
<Tag {...attributes()} {...actions()} />
|
|
163
164
|
</>
|
|
164
165
|
) : null}
|
|
165
|
-
{!isEmptyHtmlElement(
|
|
166
|
+
{!isEmptyHtmlElement(Tag) && repeatItem() ? (
|
|
166
167
|
<>
|
|
167
|
-
{
|
|
168
|
+
{repeatItem()?.map((data, index) => (
|
|
168
169
|
<RenderRepeatedBlock
|
|
169
170
|
key={index}
|
|
170
171
|
repeatContext={data.context}
|
|
@@ -173,9 +174,9 @@ function RenderBlock(props) {
|
|
|
173
174
|
))}
|
|
174
175
|
</>
|
|
175
176
|
) : null}
|
|
176
|
-
{!isEmptyHtmlElement(
|
|
177
|
+
{!isEmptyHtmlElement(Tag) && !repeatItem() ? (
|
|
177
178
|
<>
|
|
178
|
-
<
|
|
179
|
+
<Tag {...attributes()} {...actions()}>
|
|
179
180
|
<RenderComponent {...renderComponentProps()} />
|
|
180
181
|
|
|
181
182
|
{childrenWithoutParentComponent()?.map((child) => (
|
|
@@ -193,7 +194,7 @@ function RenderBlock(props) {
|
|
|
193
194
|
context={childrenContext()}
|
|
194
195
|
/>
|
|
195
196
|
))}
|
|
196
|
-
</
|
|
197
|
+
</Tag>
|
|
197
198
|
</>
|
|
198
199
|
) : null}
|
|
199
200
|
</>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
import {
|
|
3
4
|
FlatList,
|
|
@@ -13,13 +14,12 @@ import RenderBlock from "./render-block";
|
|
|
13
14
|
import BuilderContext from "../../context/builder.context.js";
|
|
14
15
|
|
|
15
16
|
function RenderComponent(props) {
|
|
16
|
-
const ComponentRefRef = props.componentRef;
|
|
17
|
-
|
|
18
17
|
return (
|
|
19
18
|
<BuilderContext.Provider
|
|
20
19
|
value={{
|
|
21
20
|
content: props.context.content,
|
|
22
|
-
|
|
21
|
+
rootState: props.context.rootState,
|
|
22
|
+
localState: props.context.localState,
|
|
23
23
|
context: props.context.context,
|
|
24
24
|
apiKey: props.context.apiKey,
|
|
25
25
|
registeredComponents: props.context.registeredComponents,
|
|
@@ -29,7 +29,7 @@ function RenderComponent(props) {
|
|
|
29
29
|
>
|
|
30
30
|
{props.componentRef ? (
|
|
31
31
|
<>
|
|
32
|
-
<
|
|
32
|
+
<props.componentRef {...props.componentOptions}>
|
|
33
33
|
{props.blockChildren?.map((child) => (
|
|
34
34
|
<RenderBlock
|
|
35
35
|
key={"render-block-" + child.id}
|
|
@@ -45,7 +45,7 @@ function RenderComponent(props) {
|
|
|
45
45
|
context={props.context}
|
|
46
46
|
/>
|
|
47
47
|
))}
|
|
48
|
-
</
|
|
48
|
+
</props.componentRef>
|
|
49
49
|
</>
|
|
50
50
|
) : null}
|
|
51
51
|
</BuilderContext.Provider>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
import {
|
|
3
4
|
FlatList,
|
|
@@ -16,8 +17,9 @@ function RenderRepeatedBlock(props) {
|
|
|
16
17
|
<BuilderContext.Provider
|
|
17
18
|
value={{
|
|
18
19
|
content: props.repeatContext.content,
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
localState: props.repeatContext.localState,
|
|
21
|
+
rootState: props.repeatContext.rootState,
|
|
22
|
+
rootSetState: props.repeatContext.rootSetState,
|
|
21
23
|
context: props.repeatContext.context,
|
|
22
24
|
apiKey: props.repeatContext.apiKey,
|
|
23
25
|
registeredComponents: props.repeatContext.registeredComponents,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
import {
|
|
3
4
|
FlatList,
|
|
@@ -13,8 +14,8 @@ import { getCss } from "./render-styles.helpers";
|
|
|
13
14
|
import { getFontCss } from "./render-styles.helpers";
|
|
14
15
|
|
|
15
16
|
function RenderContentStyles(props) {
|
|
16
|
-
const [injectedStyles, setInjectedStyles] = useState(
|
|
17
|
-
|
|
17
|
+
const [injectedStyles, setInjectedStyles] = useState(() =>
|
|
18
|
+
`
|
|
18
19
|
${getCss({
|
|
19
20
|
cssCode: props.cssCode,
|
|
20
21
|
contentId: props.contentId,
|
|
@@ -35,7 +36,7 @@ ${getFontCss({
|
|
|
35
36
|
text-align: inherit;
|
|
36
37
|
font-family: inherit;
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
+
`.trim()
|
|
39
40
|
);
|
|
40
41
|
|
|
41
42
|
return <RenderInlinedStyles styles={injectedStyles} />;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
import * as React from "react";
|
|
2
3
|
import {
|
|
3
4
|
FlatList,
|
|
@@ -35,6 +36,8 @@ import {
|
|
|
35
36
|
} from "./render-content.helpers.js";
|
|
36
37
|
import { TARGET } from "../../constants/target.js";
|
|
37
38
|
import { logger } from "../../helpers/logger.js";
|
|
39
|
+
import { getRenderContentScriptString } from "../render-content-variants/helpers.js";
|
|
40
|
+
import { wrapComponentRef } from "./wrap-component-ref.js";
|
|
38
41
|
|
|
39
42
|
function RenderContent(props) {
|
|
40
43
|
const elementRef = useRef(null);
|
|
@@ -90,8 +93,8 @@ function RenderContent(props) {
|
|
|
90
93
|
})
|
|
91
94
|
);
|
|
92
95
|
|
|
93
|
-
function
|
|
94
|
-
setContentState(
|
|
96
|
+
function contentSetState(newRootState) {
|
|
97
|
+
setContentState(newRootState);
|
|
95
98
|
}
|
|
96
99
|
|
|
97
100
|
const [allRegisteredComponents, setAllRegisteredComponents] = useState(() =>
|
|
@@ -105,9 +108,13 @@ function RenderContent(props) {
|
|
|
105
108
|
...components,
|
|
106
109
|
...(props.customComponents || []),
|
|
107
110
|
].reduce(
|
|
108
|
-
(acc, curr) => ({
|
|
111
|
+
(acc, { component, ...curr }) => ({
|
|
109
112
|
...acc,
|
|
110
|
-
[curr.name]:
|
|
113
|
+
[curr.name]: {
|
|
114
|
+
component:
|
|
115
|
+
TARGET === "vue3" ? wrapComponentRef(component) : component,
|
|
116
|
+
...curr,
|
|
117
|
+
},
|
|
111
118
|
}),
|
|
112
119
|
{}
|
|
113
120
|
)
|
|
@@ -159,7 +166,9 @@ function RenderContent(props) {
|
|
|
159
166
|
evaluate({
|
|
160
167
|
code: jsCode,
|
|
161
168
|
context: props.context || {},
|
|
162
|
-
|
|
169
|
+
localState: undefined,
|
|
170
|
+
rootState: contentState,
|
|
171
|
+
rootSetState: contentSetState,
|
|
163
172
|
});
|
|
164
173
|
}
|
|
165
174
|
}
|
|
@@ -192,7 +201,9 @@ function RenderContent(props) {
|
|
|
192
201
|
evaluate({
|
|
193
202
|
code: group,
|
|
194
203
|
context: props.context || {},
|
|
195
|
-
|
|
204
|
+
localState: undefined,
|
|
205
|
+
rootState: contentState,
|
|
206
|
+
rootSetState: contentSetState,
|
|
196
207
|
})
|
|
197
208
|
);
|
|
198
209
|
}
|
|
@@ -205,7 +216,7 @@ function RenderContent(props) {
|
|
|
205
216
|
...contentState,
|
|
206
217
|
[key]: json,
|
|
207
218
|
};
|
|
208
|
-
|
|
219
|
+
contentSetState(newState);
|
|
209
220
|
})
|
|
210
221
|
.catch((err) => {
|
|
211
222
|
console.error("error fetching dynamic data", url, err);
|
|
@@ -240,6 +251,14 @@ function RenderContent(props) {
|
|
|
240
251
|
}
|
|
241
252
|
}
|
|
242
253
|
|
|
254
|
+
const [scriptStr, setScriptStr] = useState(() =>
|
|
255
|
+
getRenderContentScriptString({
|
|
256
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
|
|
257
|
+
contentId: props.content?.id,
|
|
258
|
+
parentContentId: props.parentContentId,
|
|
259
|
+
})
|
|
260
|
+
);
|
|
261
|
+
|
|
243
262
|
useEffect(() => {
|
|
244
263
|
if (!props.apiKey) {
|
|
245
264
|
logger.error(
|
|
@@ -261,6 +280,11 @@ function RenderContent(props) {
|
|
|
261
280
|
includeRefs: props.includeRefs,
|
|
262
281
|
}
|
|
263
282
|
: {}),
|
|
283
|
+
...(props.enrich
|
|
284
|
+
? {
|
|
285
|
+
enrich: props.enrich,
|
|
286
|
+
}
|
|
287
|
+
: {}),
|
|
264
288
|
});
|
|
265
289
|
Object.values(allRegisteredComponents).forEach(
|
|
266
290
|
(registeredComponent) => {
|
|
@@ -356,8 +380,9 @@ function RenderContent(props) {
|
|
|
356
380
|
<builderContext.Provider
|
|
357
381
|
value={{
|
|
358
382
|
content: useContent,
|
|
359
|
-
|
|
360
|
-
|
|
383
|
+
localState: undefined,
|
|
384
|
+
rootState: contentState,
|
|
385
|
+
rootSetState: TARGET === "qwik" ? undefined : contentSetState,
|
|
361
386
|
context: props.context || {},
|
|
362
387
|
apiKey: props.apiKey,
|
|
363
388
|
apiVersion: props.apiVersion,
|
|
@@ -372,7 +397,27 @@ function RenderContent(props) {
|
|
|
372
397
|
onClick={(event) => onClick(event)}
|
|
373
398
|
builder-content-id={useContent?.id}
|
|
374
399
|
builder-model={props.model}
|
|
400
|
+
{...(TARGET === "reactNative"
|
|
401
|
+
? {
|
|
402
|
+
dataSet: {
|
|
403
|
+
// currently, we can't set the actual ID here. // we don't need it right now, we just need to identify content divs for testing.
|
|
404
|
+
"builder-content-id": "",
|
|
405
|
+
},
|
|
406
|
+
}
|
|
407
|
+
: {})}
|
|
408
|
+
{...(props.hideContent
|
|
409
|
+
? {
|
|
410
|
+
hidden: true,
|
|
411
|
+
"aria-hidden": true,
|
|
412
|
+
}
|
|
413
|
+
: {})}
|
|
375
414
|
>
|
|
415
|
+
{props.isSsrAbTest ? (
|
|
416
|
+
<>
|
|
417
|
+
<ScrollView dangerouslySetInnerHTML={{ __html: scriptStr }} />
|
|
418
|
+
</>
|
|
419
|
+
) : null}
|
|
420
|
+
|
|
376
421
|
{TARGET !== "reactNative" ? (
|
|
377
422
|
<>
|
|
378
423
|
<RenderContentStyles
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { isBrowser } from "../../functions/is-browser";
|
|
2
|
+
const getVariants = (content) => Object.values((content == null ? void 0 : content.variations) || {});
|
|
3
|
+
const checkShouldRunVariants = ({
|
|
4
|
+
canTrack,
|
|
5
|
+
content
|
|
6
|
+
}) => {
|
|
7
|
+
const hasVariants = getVariants(content).length > 0;
|
|
8
|
+
if (!hasVariants) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
if (!canTrack) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (isBrowser()) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return true;
|
|
18
|
+
};
|
|
19
|
+
function bldrAbTest(contentId, variants, isHydrationTarget2) {
|
|
20
|
+
function getAndSetVariantId() {
|
|
21
|
+
function setCookie(name, value, days) {
|
|
22
|
+
let expires = "";
|
|
23
|
+
if (days) {
|
|
24
|
+
const date = new Date();
|
|
25
|
+
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1e3);
|
|
26
|
+
expires = "; expires=" + date.toUTCString();
|
|
27
|
+
}
|
|
28
|
+
document.cookie = name + "=" + (value || "") + expires + "; path=/; Secure; SameSite=None";
|
|
29
|
+
}
|
|
30
|
+
function getCookie(name) {
|
|
31
|
+
const nameEQ = name + "=";
|
|
32
|
+
const ca = document.cookie.split(";");
|
|
33
|
+
for (let i = 0; i < ca.length; i++) {
|
|
34
|
+
let c = ca[i];
|
|
35
|
+
while (c.charAt(0) === " ")
|
|
36
|
+
c = c.substring(1, c.length);
|
|
37
|
+
if (c.indexOf(nameEQ) === 0)
|
|
38
|
+
return c.substring(nameEQ.length, c.length);
|
|
39
|
+
}
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const cookieName = `builder.tests.${contentId}`;
|
|
43
|
+
const variantInCookie = getCookie(cookieName);
|
|
44
|
+
const availableIDs = variants.map((vr) => vr.id).concat(contentId);
|
|
45
|
+
if (variantInCookie && availableIDs.includes(variantInCookie)) {
|
|
46
|
+
return variantInCookie;
|
|
47
|
+
}
|
|
48
|
+
let n = 0;
|
|
49
|
+
const random = Math.random();
|
|
50
|
+
for (let i = 0; i < variants.length; i++) {
|
|
51
|
+
const variant = variants[i];
|
|
52
|
+
const testRatio = variant.testRatio;
|
|
53
|
+
n += testRatio;
|
|
54
|
+
if (random < n) {
|
|
55
|
+
setCookie(cookieName, variant.id);
|
|
56
|
+
return variant.id;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
setCookie(cookieName, contentId);
|
|
60
|
+
return contentId;
|
|
61
|
+
}
|
|
62
|
+
const winningVariantId = getAndSetVariantId();
|
|
63
|
+
const styleEl = document.getElementById(`variants-styles-${contentId}`);
|
|
64
|
+
if (isHydrationTarget2) {
|
|
65
|
+
styleEl.remove();
|
|
66
|
+
const thisScriptEl = document.getElementById(`variants-script-${contentId}`);
|
|
67
|
+
thisScriptEl == null ? void 0 : thisScriptEl.remove();
|
|
68
|
+
} else {
|
|
69
|
+
const newStyleStr = variants.concat({ id: contentId }).filter((variant) => variant.id !== winningVariantId).map((value) => {
|
|
70
|
+
return `.variant-${value.id} { display: none; }
|
|
71
|
+
`;
|
|
72
|
+
}).join("");
|
|
73
|
+
styleEl.innerHTML = newStyleStr;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function bldrCntntScrpt(variantContentId, defaultContentId, isHydrationTarget2) {
|
|
77
|
+
if (!navigator.cookieEnabled) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
function getCookie(name) {
|
|
81
|
+
const nameEQ = name + "=";
|
|
82
|
+
const ca = document.cookie.split(";");
|
|
83
|
+
for (let i = 0; i < ca.length; i++) {
|
|
84
|
+
let c = ca[i];
|
|
85
|
+
while (c.charAt(0) === " ")
|
|
86
|
+
c = c.substring(1, c.length);
|
|
87
|
+
if (c.indexOf(nameEQ) === 0)
|
|
88
|
+
return c.substring(nameEQ.length, c.length);
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
const cookieName = `builder.tests.${defaultContentId}`;
|
|
93
|
+
const variantId = getCookie(cookieName);
|
|
94
|
+
const parentDiv = document.querySelector(`[builder-content-id="${variantContentId}"]`);
|
|
95
|
+
const variantIsDefaultContent = variantContentId === defaultContentId;
|
|
96
|
+
if (variantId === variantContentId) {
|
|
97
|
+
if (variantIsDefaultContent) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
parentDiv == null ? void 0 : parentDiv.removeAttribute("hidden");
|
|
101
|
+
parentDiv == null ? void 0 : parentDiv.removeAttribute("aria-hidden");
|
|
102
|
+
} else {
|
|
103
|
+
if (variantIsDefaultContent) {
|
|
104
|
+
if (isHydrationTarget2) {
|
|
105
|
+
parentDiv == null ? void 0 : parentDiv.remove();
|
|
106
|
+
} else {
|
|
107
|
+
parentDiv == null ? void 0 : parentDiv.setAttribute("hidden", "true");
|
|
108
|
+
parentDiv == null ? void 0 : parentDiv.setAttribute("aria-hidden", "true");
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const isHydrationTarget = (target) => target === "react" || target === "reactNative" || target === "vue3" || target === "vue2";
|
|
116
|
+
const AB_TEST_FN_NAME = "bldrAbTest";
|
|
117
|
+
const CONTENT_FN_NAME = "bldrCntntScrpt";
|
|
118
|
+
const getVariantsScriptString = (variants, contentId) => {
|
|
119
|
+
const fnStr = bldrAbTest.toString().replace(/\s+/g, " ");
|
|
120
|
+
const fnStr2 = bldrCntntScrpt.toString().replace(/\s+/g, " ");
|
|
121
|
+
return `
|
|
122
|
+
const ${AB_TEST_FN_NAME} = ${fnStr}
|
|
123
|
+
const ${CONTENT_FN_NAME} = ${fnStr2}
|
|
124
|
+
${AB_TEST_FN_NAME}("${contentId}", ${JSON.stringify(variants)}, ${isHydrationTarget})
|
|
125
|
+
`;
|
|
126
|
+
};
|
|
127
|
+
const getRenderContentScriptString = ({
|
|
128
|
+
parentContentId,
|
|
129
|
+
contentId
|
|
130
|
+
}) => {
|
|
131
|
+
return `
|
|
132
|
+
${CONTENT_FN_NAME}("${contentId}", "${parentContentId}", ${isHydrationTarget})`;
|
|
133
|
+
};
|
|
134
|
+
export {
|
|
135
|
+
checkShouldRunVariants,
|
|
136
|
+
getRenderContentScriptString,
|
|
137
|
+
getVariants,
|
|
138
|
+
getVariantsScriptString
|
|
139
|
+
};
|