@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.
Files changed (88) hide show
  1. package/dist/blocks/button/button.js +1 -0
  2. package/dist/blocks/columns/columns.js +2 -1
  3. package/dist/blocks/custom-code/custom-code.js +1 -0
  4. package/dist/blocks/embed/embed.js +1 -0
  5. package/dist/blocks/form/form.js +1 -0
  6. package/dist/blocks/fragment/fragment.js +1 -0
  7. package/dist/blocks/img/img.js +1 -0
  8. package/dist/blocks/input/input.js +1 -0
  9. package/dist/blocks/raw-text/raw-text.js +1 -0
  10. package/dist/blocks/section/section.js +1 -0
  11. package/dist/blocks/select/select.js +1 -0
  12. package/dist/blocks/submit-button/submit-button.js +1 -0
  13. package/dist/blocks/symbol/symbol.js +2 -1
  14. package/dist/blocks/textarea/textarea.js +1 -0
  15. package/dist/components/render-block/block-styles.js +4 -1
  16. package/dist/components/render-block/render-block.helpers.js +8 -20
  17. package/dist/components/render-block/render-block.js +28 -21
  18. package/dist/components/render-block/render-component.js +4 -3
  19. package/dist/components/render-block/render-repeated-block.js +4 -2
  20. package/dist/components/render-blocks.js +1 -0
  21. package/dist/components/render-content/builder-editing.js +1 -0
  22. package/dist/components/render-content/components/render-styles.js +2 -1
  23. package/dist/components/render-content/render-content.js +48 -10
  24. package/dist/components/render-content/wrap-component-ref.js +5 -0
  25. package/dist/components/render-content-variants/helpers.js +137 -0
  26. package/dist/components/render-content-variants/render-content-variants.js +73 -0
  27. package/dist/components/render-inlined-styles.js +2 -12
  28. package/dist/constants/sdk-version.js +4 -0
  29. package/dist/context/builder.context.js +3 -2
  30. package/dist/functions/evaluate.js +25 -3
  31. package/dist/functions/evaluate.test.js +19 -0
  32. package/dist/functions/get-block-actions-handler.js +3 -1
  33. package/dist/functions/get-content/generate-content-url.js +2 -2
  34. package/dist/functions/get-content/generate-content-url.test.js +15 -0
  35. package/dist/functions/get-content/index.js +36 -19
  36. package/dist/functions/get-processed-block.js +16 -4
  37. package/dist/functions/get-processed-block.test.js +3 -1
  38. package/dist/helpers/ab-tests.js +123 -6
  39. package/dist/helpers/canTrack.js +6 -0
  40. package/dist/helpers/cookie.js +9 -2
  41. package/dist/helpers/logger.js +2 -1
  42. package/dist/index.js +17 -10
  43. package/dist/scripts/init-editing.js +2 -0
  44. package/package.json +2 -5
  45. package/src/blocks/button/button.jsx +1 -0
  46. package/src/blocks/columns/columns.jsx +2 -1
  47. package/src/blocks/custom-code/custom-code.jsx +1 -0
  48. package/src/blocks/embed/embed.jsx +1 -0
  49. package/src/blocks/form/form.jsx +1 -0
  50. package/src/blocks/fragment/fragment.jsx +1 -0
  51. package/src/blocks/img/img.jsx +1 -0
  52. package/src/blocks/input/input.jsx +1 -0
  53. package/src/blocks/raw-text/raw-text.jsx +1 -0
  54. package/src/blocks/section/section.jsx +1 -0
  55. package/src/blocks/select/select.jsx +1 -0
  56. package/src/blocks/submit-button/submit-button.jsx +1 -0
  57. package/src/blocks/symbol/symbol.jsx +2 -1
  58. package/src/blocks/textarea/textarea.jsx +1 -0
  59. package/src/components/render-block/block-styles.jsx +4 -1
  60. package/src/components/render-block/render-block.helpers.js +7 -19
  61. package/src/components/render-block/render-block.jsx +24 -23
  62. package/src/components/render-block/render-component.jsx +5 -5
  63. package/src/components/render-block/render-repeated-block.jsx +4 -2
  64. package/src/components/render-blocks.jsx +1 -0
  65. package/src/components/render-content/builder-editing.jsx +1 -0
  66. package/src/components/render-content/components/render-styles.jsx +4 -3
  67. package/src/components/render-content/render-content.jsx +54 -9
  68. package/src/components/render-content/wrap-component-ref.js +4 -0
  69. package/src/components/render-content-variants/helpers.js +139 -0
  70. package/src/components/render-content-variants/render-content-variants.jsx +101 -0
  71. package/src/components/render-inlined-styles.jsx +2 -22
  72. package/src/constants/sdk-version.js +1 -0
  73. package/src/context/builder.context.js +3 -2
  74. package/src/functions/evaluate.js +27 -3
  75. package/src/functions/evaluate.test.js +17 -0
  76. package/src/functions/get-block-actions-handler.js +3 -1
  77. package/src/functions/get-content/generate-content-url.js +2 -1
  78. package/src/functions/get-content/generate-content-url.test.js +15 -0
  79. package/src/functions/get-content/index.js +35 -18
  80. package/src/functions/get-processed-block.js +20 -4
  81. package/src/functions/get-processed-block.test.js +3 -1
  82. package/src/helpers/ab-tests.js +132 -10
  83. package/src/helpers/canTrack.js +5 -0
  84. package/src/helpers/cookie.js +9 -2
  85. package/src/helpers/logger.js +2 -1
  86. package/src/index.js +18 -7
  87. package/src/scripts/init-editing.js +2 -0
  88. 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 = `${gutterSize}px`;
77
+ const gutterPixels = `${gutter}px`;
77
78
  const mobileWidth = "100%";
78
79
  const mobileMarginLeft = 0;
79
80
  return {
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import * as React from "react";
2
3
  import {
3
4
  FlatList,
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import * as React from "react";
2
3
  import {
3
4
  FlatList,
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import BaseText from "../BaseText";
2
3
  import * as React from "react";
3
4
  import {
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import * as React from "react";
2
3
  import {
3
4
  FlatList,
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import * as React from "react";
2
3
  import {
3
4
  FlatList,
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import * as React from "react";
2
3
  import {
3
4
  FlatList,
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import * as React from "react";
2
3
  import {
3
4
  FlatList,
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import * as React from "react";
2
3
  import {
3
4
  FlatList,
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import BaseText from "../BaseText";
2
3
  import * as React from "react";
3
4
  import {
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import BaseText from "../BaseText";
2
3
  import * as React from "react";
3
4
  import {
@@ -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.state,
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,
@@ -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
- state: props.context.state,
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
- state: context.state,
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
- state: context.state,
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
- state: __spreadProps(__spreadValues({}, context.state), {
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
- const [repeatItemData, setRepeatItemData] = useState(() =>
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 repeatItemData
44
+ return repeatItem()
45
45
  ? props.block
46
46
  : getProcessedBlock({
47
47
  block: props.block,
48
- state: props.context.state,
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 [tag, setTag] = useState(() => props.block.tagName || "div");
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
- state: TARGET === "qwik" ? props.context.state : proxyState,
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 && !repeatItemData;
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
- state: props.context.state,
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(tag) ? (
161
+ {isEmptyHtmlElement(Tag) ? (
161
162
  <>
162
- <View {...attributes()} {...actions()} />
163
+ <Tag {...attributes()} {...actions()} />
163
164
  </>
164
165
  ) : null}
165
- {!isEmptyHtmlElement(tag) && repeatItemData ? (
166
+ {!isEmptyHtmlElement(Tag) && repeatItem() ? (
166
167
  <>
167
- {repeatItemData?.map((data, index) => (
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(tag) && !repeatItemData ? (
177
+ {!isEmptyHtmlElement(Tag) && !repeatItem() ? (
177
178
  <>
178
- <View {...attributes()} {...actions()}>
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
- </View>
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
- state: props.context.state,
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
- <ComponentRefRef {...props.componentOptions}>
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
- </ComponentRefRef>
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
- state: props.repeatContext.state,
20
- setState: props.repeatContext.setState,
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,
@@ -1,3 +1,4 @@
1
+ 'use client';
1
2
  import * as React from "react";
2
3
  import {
3
4
  FlatList,
@@ -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 setContextState(newState) {
94
- setContentState(newState);
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]: curr,
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
- state: contentState,
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
- state: contentState,
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
- setContextState(newState);
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
- state: contentState,
360
- setState: setContextState,
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,4 @@
1
+ const wrapComponentRef = (component) => component;
2
+ export {
3
+ wrapComponentRef
4
+ };
@@ -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
+ };