@builder.io/sdk-svelte 0.1.1 → 0.1.3-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/package/--package.json +3 -3
- package/package/CHANGELOG.md +9 -0
- package/package/blocks/BaseText.svelte +1 -1
- package/package/blocks/button/button.svelte +1 -1
- package/package/blocks/columns/columns.svelte +3 -3
- package/package/blocks/custom-code/custom-code.svelte +1 -1
- package/package/blocks/embed/embed.svelte +2 -3
- package/package/blocks/form/form.svelte +1 -1
- package/package/blocks/fragment/fragment.svelte +1 -1
- package/package/blocks/image/image.svelte +1 -2
- package/package/blocks/img/img.svelte +1 -1
- package/package/blocks/input/input.svelte +1 -1
- package/package/blocks/raw-text/raw-text.svelte +1 -1
- package/package/blocks/section/section.svelte +1 -1
- package/package/blocks/select/select.svelte +1 -1
- package/package/blocks/submit-button/submit-button.svelte +1 -1
- package/package/blocks/symbol/symbol.svelte +4 -2
- package/package/blocks/text/text.svelte +1 -1
- package/package/blocks/textarea/textarea.svelte +1 -1
- package/package/blocks/video/video.svelte +1 -1
- package/package/components/render-block/block-styles.svelte +1 -1
- package/package/components/render-block/render-block.helpers.d.ts +11 -0
- package/package/components/render-block/render-block.helpers.js +58 -0
- package/package/components/render-block/render-block.svelte +33 -109
- package/package/components/render-block/render-component.svelte +1 -1
- package/package/components/render-block/render-repeated-block.svelte +7 -19
- package/package/components/render-blocks.svelte +1 -1
- package/package/components/render-content/builder-editing.svelte +1 -1
- package/package/components/render-content/components/render-styles.svelte +3 -3
- package/package/components/render-content/render-content.svelte +53 -53
- package/package/components/render-inlined-styles.svelte +1 -1
- package/package/functions/track/helpers.d.ts +5 -0
- package/package/functions/track/helpers.js +56 -0
- package/package/functions/{track.d.ts → track/index.d.ts} +5 -10
- package/package/functions/{track.js → track/index.js} +11 -6
- package/package/helpers/ab-tests.d.ts +1 -1
- package/package/helpers/cookie.d.ts +1 -1
- package/package/helpers/cookie.js +7 -2
- package/package/helpers/localStorage.d.ts +2 -1
- package/package/helpers/localStorage.js +1 -0
- package/package/helpers/sessionId.d.ts +2 -2
- package/package/helpers/sessionId.js +2 -1
- package/package/helpers/url.js +3 -0
- package/package/helpers/url.test.js +6 -0
- package/package/helpers/visitorId.js +1 -0
- package/package/index.d.ts +1 -1
- package/package/index.js +1 -1
- package/package.json +1 -1
- package/src/blocks/BaseText.svelte +2 -2
- package/src/blocks/button/button.svelte +1 -6
- package/src/blocks/columns/columns.svelte +3 -3
- package/src/blocks/custom-code/custom-code.svelte +1 -1
- package/src/blocks/embed/component-info.ts +29 -27
- package/src/blocks/embed/embed.svelte +1 -3
- package/src/blocks/form/form.svelte +2 -7
- package/src/blocks/fragment/fragment.svelte +1 -1
- package/src/blocks/image/component-info.ts +57 -55
- package/src/blocks/image/image.svelte +1 -2
- package/src/blocks/img/img.svelte +1 -6
- package/src/blocks/input/input.svelte +1 -6
- package/src/blocks/raw-text/raw-text.svelte +1 -1
- package/src/blocks/section/section.svelte +1 -6
- package/src/blocks/select/select.svelte +1 -6
- package/src/blocks/submit-button/submit-button.svelte +1 -6
- package/src/blocks/symbol/symbol.svelte +5 -8
- package/src/blocks/text/text.svelte +1 -1
- package/src/blocks/textarea/textarea.svelte +1 -6
- package/src/blocks/video/video.svelte +1 -6
- package/src/components/render-block/block-styles.svelte +1 -1
- package/src/components/render-block/render-block.helpers.ts +85 -0
- package/src/components/render-block/render-block.svelte +41 -118
- package/src/components/render-block/render-component.svelte +1 -1
- package/src/components/render-block/render-repeated-block.svelte +8 -20
- package/src/components/render-blocks.svelte +2 -2
- package/src/components/render-content/builder-editing.svelte +1 -1
- package/src/components/render-content/components/render-styles.svelte +5 -3
- package/src/components/render-content/render-content.svelte +59 -64
- package/src/components/render-inlined-styles.svelte +1 -1
- package/src/functions/track/helpers.ts +67 -0
- package/src/functions/{track.ts → track/index.ts} +16 -17
- package/src/helpers/cookie.ts +9 -4
- package/src/helpers/localStorage.ts +3 -1
- package/src/helpers/sessionId.ts +5 -1
- package/src/helpers/url.test.ts +7 -0
- package/src/helpers/url.ts +4 -0
- package/src/helpers/visitorId.ts +3 -1
- package/src/index.ts +1 -1
- package/package/components/render-block/render-component-with-context.svelte +0 -32
- package/package/components/render-block/render-component-with-context.svelte.d.ts +0 -19
- package/src/components/render-block/render-component-with-context.svelte +0 -38
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
<script context="module" lang="ts">
|
|
2
|
-
import type {
|
|
3
|
-
BuilderContextInterface,
|
|
4
|
-
RegisteredComponent,
|
|
5
|
-
} from "../../context/types.js";
|
|
2
|
+
import type { BuilderContextInterface } from "../../context/types.js";
|
|
6
3
|
|
|
7
4
|
import type { BuilderBlock } from "../../types/builder-block.js";
|
|
8
5
|
|
|
9
|
-
import type { Nullable } from "../../types/typescript.js";
|
|
10
|
-
|
|
11
6
|
import type { RenderComponentProps } from "./render-component";
|
|
12
7
|
|
|
13
|
-
import type { RepeatData } from "./types.js";
|
|
14
|
-
|
|
15
8
|
export type RenderBlockProps = {
|
|
16
9
|
block: BuilderBlock;
|
|
17
10
|
context: BuilderContextInterface;
|
|
@@ -24,25 +17,24 @@
|
|
|
24
17
|
import { getBlockProperties } from "../../functions/get-block-properties.js";
|
|
25
18
|
import { getBlockTag } from "../../functions/get-block-tag.js";
|
|
26
19
|
import { getProcessedBlock } from "../../functions/get-processed-block.js";
|
|
27
|
-
import { evaluate } from "../../functions/evaluate.js";
|
|
28
20
|
import BlockStyles from "./block-styles.svelte";
|
|
29
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
getComponent,
|
|
23
|
+
getRepeatItemData,
|
|
24
|
+
isEmptyHtmlElement,
|
|
25
|
+
} from "./render-block.helpers.js";
|
|
30
26
|
import RenderRepeatedBlock from "./render-repeated-block.svelte";
|
|
31
27
|
import { TARGET } from "../../constants/target.js";
|
|
32
28
|
import { extractTextStyles } from "../../functions/extract-text-styles.js";
|
|
33
|
-
import RenderComponentWithContext from "./render-component-with-context.svelte";
|
|
34
29
|
import RenderComponent from "./render-component.svelte";
|
|
35
30
|
import { getReactNativeBlockStyles } from "../../functions/get-react-native-block-styles.js";
|
|
36
31
|
|
|
37
32
|
const setAttrs = (node, attrs) => {
|
|
38
33
|
const attrKeys = Object.keys(attrs);
|
|
39
|
-
|
|
40
34
|
const setup = (attr) => node.addEventListener(attr.substr(3), attrs[attr]);
|
|
41
35
|
const teardown = (attr) =>
|
|
42
36
|
node.removeEventListener(attr.substr(3), attrs[attr]);
|
|
43
|
-
|
|
44
37
|
attrKeys.map(setup);
|
|
45
|
-
|
|
46
38
|
return {
|
|
47
39
|
update(attrs) {
|
|
48
40
|
const attrKeys = Object.keys(attrs);
|
|
@@ -58,32 +50,11 @@
|
|
|
58
50
|
export let block: RenderBlockProps["block"];
|
|
59
51
|
export let context: RenderBlockProps["context"];
|
|
60
52
|
|
|
61
|
-
$: component = () => {
|
|
62
|
-
const componentName = getProcessedBlock({
|
|
63
|
-
block: block,
|
|
64
|
-
state: context.state,
|
|
65
|
-
context: context.context,
|
|
66
|
-
shouldEvaluateBindings: false,
|
|
67
|
-
}).component?.name;
|
|
68
|
-
if (!componentName) {
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
71
|
-
const ref = context.registeredComponents[componentName];
|
|
72
|
-
if (!ref) {
|
|
73
|
-
// TODO: Public doc page with more info about this message
|
|
74
|
-
console.warn(`
|
|
75
|
-
Could not find a registered component named "${componentName}".
|
|
76
|
-
If you registered it, is the file that registered it imported by the file that needs to render it?`);
|
|
77
|
-
return undefined;
|
|
78
|
-
} else {
|
|
79
|
-
return ref;
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
53
|
$: tag = () => {
|
|
83
54
|
return getBlockTag(useBlock());
|
|
84
55
|
};
|
|
85
56
|
$: useBlock = () => {
|
|
86
|
-
return repeatItemData
|
|
57
|
+
return repeatItemData
|
|
87
58
|
? block
|
|
88
59
|
: getProcessedBlock({
|
|
89
60
|
block: block,
|
|
@@ -114,20 +85,17 @@
|
|
|
114
85
|
: {}),
|
|
115
86
|
};
|
|
116
87
|
};
|
|
117
|
-
$: shouldWrap = () => {
|
|
118
|
-
return !component?.()?.noWrap;
|
|
119
|
-
};
|
|
120
88
|
$: renderComponentProps = () => {
|
|
121
89
|
return {
|
|
122
|
-
blockChildren:
|
|
123
|
-
componentRef: component?.
|
|
90
|
+
blockChildren: useBlock().children ?? [],
|
|
91
|
+
componentRef: component?.component,
|
|
124
92
|
componentOptions: {
|
|
125
93
|
...getBlockComponentOptions(useBlock()),
|
|
126
94
|
/**
|
|
127
95
|
* These attributes are passed to the wrapper element when there is one. If `noWrap` is set to true, then
|
|
128
96
|
* they are provided to the component itself directly.
|
|
129
97
|
*/
|
|
130
|
-
...(
|
|
98
|
+
...(!component?.noWrap
|
|
131
99
|
? {}
|
|
132
100
|
: {
|
|
133
101
|
attributes: {
|
|
@@ -140,13 +108,6 @@
|
|
|
140
108
|
context: childrenContext(),
|
|
141
109
|
};
|
|
142
110
|
};
|
|
143
|
-
$: useChildren = () => {
|
|
144
|
-
// TO-DO: When should `canHaveChildren` dictate rendering?
|
|
145
|
-
// This is currently commented out because some Builder components (e.g. Box) do not have `canHaveChildren: true`,
|
|
146
|
-
// but still receive and need to render children.
|
|
147
|
-
// return componentInfo?.canHaveChildren ? useBlock().children : [];
|
|
148
|
-
return useBlock().children ?? [];
|
|
149
|
-
};
|
|
150
111
|
$: childrenWithoutParentComponent = () => {
|
|
151
112
|
/**
|
|
152
113
|
* When there is no `componentRef`, there might still be children that need to be rendered. In this case,
|
|
@@ -155,94 +116,56 @@
|
|
|
155
116
|
* blocks, and the children will be repeated within those blocks.
|
|
156
117
|
*/
|
|
157
118
|
const shouldRenderChildrenOutsideRef =
|
|
158
|
-
!component?.
|
|
159
|
-
return shouldRenderChildrenOutsideRef ?
|
|
160
|
-
};
|
|
161
|
-
$: repeatItemData = () => {
|
|
162
|
-
/**
|
|
163
|
-
* we don't use `useBlock()` here because the processing done within its logic includes evaluating the block's bindings,
|
|
164
|
-
* which will not work if there is a repeat.
|
|
165
|
-
*/
|
|
166
|
-
const { repeat, ...blockWithoutRepeat } = block;
|
|
167
|
-
if (!repeat?.collection) {
|
|
168
|
-
return undefined;
|
|
169
|
-
}
|
|
170
|
-
const itemsArray = evaluate({
|
|
171
|
-
code: repeat.collection,
|
|
172
|
-
state: context.state,
|
|
173
|
-
context: context.context,
|
|
174
|
-
});
|
|
175
|
-
if (!Array.isArray(itemsArray)) {
|
|
176
|
-
return undefined;
|
|
177
|
-
}
|
|
178
|
-
const collectionName = repeat.collection.split(".").pop();
|
|
179
|
-
const itemNameToUse =
|
|
180
|
-
repeat.itemName || (collectionName ? collectionName + "Item" : "item");
|
|
181
|
-
const repeatArray = itemsArray.map((item, index) => ({
|
|
182
|
-
context: {
|
|
183
|
-
...context,
|
|
184
|
-
state: {
|
|
185
|
-
...context.state,
|
|
186
|
-
$index: index,
|
|
187
|
-
$item: item,
|
|
188
|
-
[itemNameToUse]: item,
|
|
189
|
-
[`$${itemNameToUse}Index`]: index,
|
|
190
|
-
},
|
|
191
|
-
},
|
|
192
|
-
block: blockWithoutRepeat,
|
|
193
|
-
}));
|
|
194
|
-
return repeatArray;
|
|
195
|
-
};
|
|
196
|
-
$: inheritedTextStyles = () => {
|
|
197
|
-
if (TARGET !== "reactNative") {
|
|
198
|
-
return {};
|
|
199
|
-
}
|
|
200
|
-
const styles = getReactNativeBlockStyles({
|
|
201
|
-
block: useBlock(),
|
|
202
|
-
context: context,
|
|
203
|
-
blockStyles: attributes().style,
|
|
204
|
-
});
|
|
205
|
-
return extractTextStyles(styles);
|
|
119
|
+
!component?.component && !repeatItemData;
|
|
120
|
+
return shouldRenderChildrenOutsideRef ? useBlock().children ?? [] : [];
|
|
206
121
|
};
|
|
207
122
|
$: childrenContext = () => {
|
|
123
|
+
const getInheritedTextStyles = () => {
|
|
124
|
+
if (TARGET !== "reactNative") {
|
|
125
|
+
return {};
|
|
126
|
+
}
|
|
127
|
+
return extractTextStyles(
|
|
128
|
+
getReactNativeBlockStyles({
|
|
129
|
+
block: useBlock(),
|
|
130
|
+
context: context,
|
|
131
|
+
blockStyles: attributes().style,
|
|
132
|
+
})
|
|
133
|
+
);
|
|
134
|
+
};
|
|
208
135
|
return {
|
|
209
136
|
apiKey: context.apiKey,
|
|
210
137
|
state: context.state,
|
|
211
138
|
content: context.content,
|
|
212
139
|
context: context.context,
|
|
213
140
|
registeredComponents: context.registeredComponents,
|
|
214
|
-
inheritedStyles:
|
|
141
|
+
inheritedStyles: getInheritedTextStyles(),
|
|
215
142
|
};
|
|
216
143
|
};
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
};
|
|
144
|
+
|
|
145
|
+
let component = getComponent({
|
|
146
|
+
block: block,
|
|
147
|
+
context: context,
|
|
148
|
+
});
|
|
149
|
+
let repeatItemData = getRepeatItemData({
|
|
150
|
+
block: block,
|
|
151
|
+
context: context,
|
|
152
|
+
});
|
|
227
153
|
</script>
|
|
228
154
|
|
|
229
|
-
{#if
|
|
155
|
+
{#if !component?.noWrap}
|
|
230
156
|
{#if isEmptyHtmlElement(tag())}
|
|
231
157
|
<svelte:element this={tag()} {...attributes()} use:setAttrs={actions()} />
|
|
232
158
|
{/if}
|
|
233
159
|
|
|
234
|
-
{#if !isEmptyHtmlElement(tag()) && repeatItemData
|
|
235
|
-
{#each repeatItemData
|
|
160
|
+
{#if !isEmptyHtmlElement(tag()) && repeatItemData}
|
|
161
|
+
{#each repeatItemData as data, index (index)}
|
|
236
162
|
<RenderRepeatedBlock repeatContext={data.context} block={data.block} />
|
|
237
163
|
{/each}
|
|
238
164
|
{/if}
|
|
239
165
|
|
|
240
|
-
{#if !isEmptyHtmlElement(tag()) && !repeatItemData
|
|
166
|
+
{#if !isEmptyHtmlElement(tag()) && !repeatItemData}
|
|
241
167
|
<svelte:element this={tag()} {...attributes()} use:setAttrs={actions()}>
|
|
242
|
-
<
|
|
243
|
-
this={renderComponentTag()}
|
|
244
|
-
{...renderComponentProps()}
|
|
245
|
-
/>
|
|
168
|
+
<RenderComponent {...renderComponentProps()} />
|
|
246
169
|
|
|
247
170
|
{#each childrenWithoutParentComponent() as child ("render-block-" + child.id)}
|
|
248
171
|
<svelte:self block={child} context={childrenContext()} />
|
|
@@ -254,5 +177,5 @@
|
|
|
254
177
|
</svelte:element>
|
|
255
178
|
{/if}
|
|
256
179
|
{:else}
|
|
257
|
-
<
|
|
258
|
-
{/if}
|
|
180
|
+
<RenderComponent {...renderComponentProps()} />
|
|
181
|
+
{/if}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
</script>
|
|
21
21
|
|
|
22
22
|
<script lang="ts">
|
|
23
|
-
import {
|
|
23
|
+
import { setContext } from "svelte";
|
|
24
24
|
|
|
25
25
|
import BuilderContext from "../../context/builder.context.js";
|
|
26
26
|
import RenderBlock from "./render-block.svelte";
|
|
@@ -29,25 +29,13 @@
|
|
|
29
29
|
export let repeatContext: Props["repeatContext"];
|
|
30
30
|
|
|
31
31
|
setContext(BuilderContext.key, {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
get context() {
|
|
39
|
-
return repeatContext.context;
|
|
40
|
-
},
|
|
41
|
-
get apiKey() {
|
|
42
|
-
return repeatContext.apiKey;
|
|
43
|
-
},
|
|
44
|
-
get registeredComponents() {
|
|
45
|
-
return repeatContext.registeredComponents;
|
|
46
|
-
},
|
|
47
|
-
get inheritedStyles() {
|
|
48
|
-
return repeatContext.inheritedStyles;
|
|
49
|
-
},
|
|
32
|
+
content: repeatContext.content,
|
|
33
|
+
state: repeatContext.state,
|
|
34
|
+
context: repeatContext.context,
|
|
35
|
+
apiKey: repeatContext.apiKey,
|
|
36
|
+
registeredComponents: repeatContext.registeredComponents,
|
|
37
|
+
inheritedStyles: repeatContext.inheritedStyles,
|
|
50
38
|
});
|
|
51
39
|
</script>
|
|
52
40
|
|
|
53
|
-
<RenderBlock {block} context={repeatContext} />
|
|
41
|
+
<RenderBlock {block} context={repeatContext} />
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
</script>
|
|
11
11
|
|
|
12
12
|
<script lang="ts">
|
|
13
|
-
import { getContext
|
|
13
|
+
import { getContext } from "svelte";
|
|
14
14
|
|
|
15
15
|
import BuilderContext from "../context/builder.context.js";
|
|
16
16
|
import { isEditing } from "../functions/is-editing.js";
|
|
@@ -101,4 +101,4 @@
|
|
|
101
101
|
flex-direction: column;
|
|
102
102
|
align-items: stretch;
|
|
103
103
|
}
|
|
104
|
-
</style>
|
|
104
|
+
</style>
|
|
@@ -62,11 +62,13 @@
|
|
|
62
62
|
}
|
|
63
63
|
function getFontCss({ customFonts }) {
|
|
64
64
|
// TODO: flag for this
|
|
65
|
-
// if (!builder.allowCustomFonts) {
|
|
65
|
+
// if (!this.builder.allowCustomFonts) {
|
|
66
66
|
// return '';
|
|
67
67
|
// }
|
|
68
68
|
// TODO: separate internal data from external
|
|
69
|
-
return
|
|
69
|
+
return (
|
|
70
|
+
customFonts?.map((font) => this.getCssFromFont(font))?.join(" ") || ""
|
|
71
|
+
);
|
|
70
72
|
}
|
|
71
73
|
$: injectedStyles = () => {
|
|
72
74
|
return `
|
|
@@ -77,4 +79,4 @@ ${getFontCss({
|
|
|
77
79
|
};
|
|
78
80
|
</script>
|
|
79
81
|
|
|
80
|
-
<RenderInlinedStyles styles={injectedStyles()} />
|
|
82
|
+
<RenderInlinedStyles styles={injectedStyles()} />
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
BuilderContent,
|
|
12
12
|
} from "../../types/builder-content.js";
|
|
13
13
|
|
|
14
|
-
import type {
|
|
14
|
+
import type { Nullable } from "../../types/typescript.js";
|
|
15
15
|
|
|
16
16
|
export type RenderContentProps = {
|
|
17
17
|
content?: Nullable<BuilderContent>;
|
|
@@ -41,13 +41,7 @@
|
|
|
41
41
|
</script>
|
|
42
42
|
|
|
43
43
|
<script lang="ts">
|
|
44
|
-
import {
|
|
45
|
-
afterUpdate,
|
|
46
|
-
getContext,
|
|
47
|
-
onDestroy,
|
|
48
|
-
onMount,
|
|
49
|
-
setContext,
|
|
50
|
-
} from "svelte";
|
|
44
|
+
import { onDestroy, onMount, setContext } from "svelte";
|
|
51
45
|
|
|
52
46
|
import { getDefaultRegisteredComponents } from "../../constants/builder-registered-components.js";
|
|
53
47
|
import { TARGET } from "../../constants/target.js";
|
|
@@ -61,14 +55,15 @@
|
|
|
61
55
|
components,
|
|
62
56
|
createRegisterComponentMessage,
|
|
63
57
|
} from "../../functions/register-component.js";
|
|
64
|
-
import { _track } from "../../functions/track.js";
|
|
58
|
+
import { _track } from "../../functions/track/index.js";
|
|
65
59
|
import RenderBlocks from "../render-blocks.svelte";
|
|
66
60
|
import RenderContentStyles from "./components/render-styles.svelte";
|
|
67
|
-
import
|
|
61
|
+
import builderContext from "../../context/builder.context.js";
|
|
68
62
|
import {
|
|
69
63
|
registerInsertMenu,
|
|
70
64
|
setupBrowserForEditing,
|
|
71
65
|
} from "../../scripts/init-editing.js";
|
|
66
|
+
import { checkIsDefined } from "../../helpers/nullable.js";
|
|
72
67
|
|
|
73
68
|
export let content: RenderContentProps["content"];
|
|
74
69
|
export let data: RenderContentProps["data"];
|
|
@@ -80,7 +75,7 @@
|
|
|
80
75
|
export let apiKey: RenderContentProps["apiKey"];
|
|
81
76
|
export let includeRefs: RenderContentProps["includeRefs"];
|
|
82
77
|
|
|
83
|
-
setContext(
|
|
78
|
+
setContext(builderContext.key, {
|
|
84
79
|
get content() {
|
|
85
80
|
return useContent();
|
|
86
81
|
},
|
|
@@ -88,13 +83,13 @@
|
|
|
88
83
|
return contentState();
|
|
89
84
|
},
|
|
90
85
|
get context() {
|
|
91
|
-
return contextContext
|
|
86
|
+
return contextContext;
|
|
92
87
|
},
|
|
93
88
|
get apiKey() {
|
|
94
89
|
return apiKey;
|
|
95
90
|
},
|
|
96
91
|
get registeredComponents() {
|
|
97
|
-
return allRegisteredComponents
|
|
92
|
+
return allRegisteredComponents;
|
|
98
93
|
},
|
|
99
94
|
});
|
|
100
95
|
|
|
@@ -140,7 +135,7 @@
|
|
|
140
135
|
if (jsCode) {
|
|
141
136
|
evaluate({
|
|
142
137
|
code: jsCode,
|
|
143
|
-
context: contextContext
|
|
138
|
+
context: contextContext,
|
|
144
139
|
state: contentState(),
|
|
145
140
|
});
|
|
146
141
|
}
|
|
@@ -151,7 +146,7 @@
|
|
|
151
146
|
const contentId = useContent?.()?.id;
|
|
152
147
|
_track({
|
|
153
148
|
type: "click",
|
|
154
|
-
canTrack: canTrackToUse
|
|
149
|
+
canTrack: canTrackToUse,
|
|
155
150
|
contentId,
|
|
156
151
|
apiKey: apiKey,
|
|
157
152
|
variationId: variationId !== contentId ? variationId : undefined,
|
|
@@ -162,7 +157,7 @@
|
|
|
162
157
|
return expression.replace(/{{([^}]+)}}/g, (_match, group) =>
|
|
163
158
|
evaluate({
|
|
164
159
|
code: group,
|
|
165
|
-
context: contextContext
|
|
160
|
+
context: contextContext,
|
|
166
161
|
state: contentState(),
|
|
167
162
|
})
|
|
168
163
|
);
|
|
@@ -184,7 +179,7 @@
|
|
|
184
179
|
function runHttpRequests() {
|
|
185
180
|
const requests = useContent?.()?.data?.httpRequests ?? {};
|
|
186
181
|
Object.entries(requests).forEach(([key, url]) => {
|
|
187
|
-
if (url && (!httpReqsData
|
|
182
|
+
if (url && (!httpReqsData[key] || isEditing())) {
|
|
188
183
|
const evaluatedUrl = evalExpression(url);
|
|
189
184
|
handleRequest({
|
|
190
185
|
url: evaluatedUrl,
|
|
@@ -211,7 +206,7 @@
|
|
|
211
206
|
if (!content && !overrideContent) {
|
|
212
207
|
return undefined;
|
|
213
208
|
}
|
|
214
|
-
|
|
209
|
+
return {
|
|
215
210
|
...content,
|
|
216
211
|
...overrideContent,
|
|
217
212
|
data: {
|
|
@@ -228,10 +223,6 @@
|
|
|
228
223
|
content?.meta?.breakpoints,
|
|
229
224
|
},
|
|
230
225
|
};
|
|
231
|
-
return mergedContent;
|
|
232
|
-
};
|
|
233
|
-
$: canTrackToUse = () => {
|
|
234
|
-
return canTrack || true;
|
|
235
226
|
};
|
|
236
227
|
$: contentState = () => {
|
|
237
228
|
return {
|
|
@@ -245,32 +236,6 @@
|
|
|
245
236
|
...overrideState,
|
|
246
237
|
};
|
|
247
238
|
};
|
|
248
|
-
$: contextContext = () => {
|
|
249
|
-
return context || {};
|
|
250
|
-
};
|
|
251
|
-
$: allRegisteredComponents = () => {
|
|
252
|
-
const allComponentsArray = [
|
|
253
|
-
...getDefaultRegisteredComponents(),
|
|
254
|
-
// While this `components` object is deprecated, we must maintain support for it.
|
|
255
|
-
// Since users are able to override our default components, we need to make sure that we do not break such
|
|
256
|
-
// existing usage.
|
|
257
|
-
// This is why we spread `components` after the default Builder.io components, but before the `customComponents`,
|
|
258
|
-
// which is the new standard way of providing custom components, and must therefore take precedence.
|
|
259
|
-
...components,
|
|
260
|
-
...(customComponents || []),
|
|
261
|
-
];
|
|
262
|
-
const allComponents = allComponentsArray.reduce(
|
|
263
|
-
(acc, curr) => ({
|
|
264
|
-
...acc,
|
|
265
|
-
[curr.name]: curr,
|
|
266
|
-
}),
|
|
267
|
-
{}
|
|
268
|
-
);
|
|
269
|
-
return allComponents;
|
|
270
|
-
};
|
|
271
|
-
$: httpReqsData = () => {
|
|
272
|
-
return {};
|
|
273
|
-
};
|
|
274
239
|
$: shouldRenderContentStyles = () => {
|
|
275
240
|
return Boolean(
|
|
276
241
|
(useContent?.()?.data?.cssCode ||
|
|
@@ -285,7 +250,26 @@
|
|
|
285
250
|
let overrideContent = null;
|
|
286
251
|
let update = 0;
|
|
287
252
|
let useBreakpoints = null;
|
|
253
|
+
let canTrackToUse = checkIsDefined(canTrack) ? canTrack : true;
|
|
288
254
|
let overrideState = {};
|
|
255
|
+
let contextContext = context || {};
|
|
256
|
+
let allRegisteredComponents = [
|
|
257
|
+
...getDefaultRegisteredComponents(),
|
|
258
|
+
// While this `components` object is deprecated, we must maintain support for it.
|
|
259
|
+
// Since users are able to override our default components, we need to make sure that we do not break such
|
|
260
|
+
// existing usage.
|
|
261
|
+
// This is why we spread `components` after the default Builder.io components, but before the `props.customComponents`,
|
|
262
|
+
// which is the new standard way of providing custom components, and must therefore take precedence.
|
|
263
|
+
...components,
|
|
264
|
+
...(customComponents || []),
|
|
265
|
+
].reduce(
|
|
266
|
+
(acc, curr) => ({
|
|
267
|
+
...acc,
|
|
268
|
+
[curr.name]: curr,
|
|
269
|
+
}),
|
|
270
|
+
{}
|
|
271
|
+
);
|
|
272
|
+
let httpReqsData = {};
|
|
289
273
|
|
|
290
274
|
onMount(() => {
|
|
291
275
|
if (!apiKey) {
|
|
@@ -309,7 +293,7 @@
|
|
|
309
293
|
}
|
|
310
294
|
: {}),
|
|
311
295
|
});
|
|
312
|
-
Object.values(allRegisteredComponents
|
|
296
|
+
Object.values(allRegisteredComponents).forEach(
|
|
313
297
|
(registeredComponent) => {
|
|
314
298
|
const message = createRegisterComponentMessage(registeredComponent);
|
|
315
299
|
window.parent?.postMessage(message, "*");
|
|
@@ -326,7 +310,7 @@
|
|
|
326
310
|
const contentId = useContent?.()?.id;
|
|
327
311
|
_track({
|
|
328
312
|
type: "impression",
|
|
329
|
-
canTrack: canTrackToUse
|
|
313
|
+
canTrack: canTrackToUse,
|
|
330
314
|
contentId,
|
|
331
315
|
apiKey: apiKey,
|
|
332
316
|
variationId: variationId !== contentId ? variationId : undefined,
|
|
@@ -336,19 +320,30 @@
|
|
|
336
320
|
// override normal content in preview mode
|
|
337
321
|
if (isPreviewing()) {
|
|
338
322
|
const searchParams = new URL(location.href).searchParams;
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
323
|
+
const searchParamPreview = searchParams.get("builder.preview");
|
|
324
|
+
const previewApiKey =
|
|
325
|
+
searchParams.get("apiKey") || searchParams.get("builder.space");
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Make sure that:
|
|
329
|
+
* - the preview model name is the same as the one we're rendering, since there can be multiple models rendered
|
|
330
|
+
* at the same time, e.g. header/page/footer.
|
|
331
|
+
* - the API key is the same, since we don't want to preview content from other organizations.
|
|
332
|
+
*
|
|
333
|
+
* TO-DO: should we check that the preview item ID is the same as the initial one being rendered? Or would
|
|
334
|
+
* this break scenarios where the item is not published yet?
|
|
335
|
+
*
|
|
336
|
+
* TO-DO: should we only update the state when there is a change?
|
|
337
|
+
**/
|
|
338
|
+
if (searchParamPreview === model && previewApiKey === apiKey) {
|
|
339
|
+
getContent({
|
|
340
|
+
model: model,
|
|
341
|
+
apiKey: apiKey,
|
|
342
|
+
}).then((content) => {
|
|
343
|
+
if (content) {
|
|
344
|
+
overrideContent = content;
|
|
345
|
+
}
|
|
346
|
+
});
|
|
352
347
|
}
|
|
353
348
|
}
|
|
354
349
|
evaluateJsCode();
|
|
@@ -401,4 +396,4 @@
|
|
|
401
396
|
key={forceReRenderCount}
|
|
402
397
|
/>
|
|
403
398
|
</div>
|
|
404
|
-
{/if}
|
|
399
|
+
{/if}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { TARGET } from '../../constants/target';
|
|
2
|
+
import type { Nullable } from '../../helpers/nullable';
|
|
3
|
+
import { isBrowser } from '../is-browser';
|
|
4
|
+
|
|
5
|
+
const getLocation = (): Nullable<URL> => {
|
|
6
|
+
if (TARGET === 'reactNative') {
|
|
7
|
+
return null;
|
|
8
|
+
} else if (isBrowser()) {
|
|
9
|
+
const parsedLocation = new URL(location.href);
|
|
10
|
+
|
|
11
|
+
// IE11 bug with parsed path being empty string
|
|
12
|
+
// causes issues with our user targeting
|
|
13
|
+
if (parsedLocation.pathname === '') {
|
|
14
|
+
parsedLocation.pathname = '/';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return parsedLocation;
|
|
18
|
+
} else {
|
|
19
|
+
console.warn('Cannot get location for tracking in non-browser environment');
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const getUserAgent = () =>
|
|
25
|
+
(typeof navigator === 'object' && navigator.userAgent) || '';
|
|
26
|
+
|
|
27
|
+
export const getUserAttributes = () => {
|
|
28
|
+
const userAgent = getUserAgent();
|
|
29
|
+
|
|
30
|
+
const isMobile = {
|
|
31
|
+
Android() {
|
|
32
|
+
return userAgent.match(/Android/i);
|
|
33
|
+
},
|
|
34
|
+
BlackBerry() {
|
|
35
|
+
return userAgent.match(/BlackBerry/i);
|
|
36
|
+
},
|
|
37
|
+
iOS() {
|
|
38
|
+
return userAgent.match(/iPhone|iPod/i);
|
|
39
|
+
},
|
|
40
|
+
Opera() {
|
|
41
|
+
return userAgent.match(/Opera Mini/i);
|
|
42
|
+
},
|
|
43
|
+
Windows() {
|
|
44
|
+
return userAgent.match(/IEMobile/i) || userAgent.match(/WPDesktop/i);
|
|
45
|
+
},
|
|
46
|
+
any() {
|
|
47
|
+
return (
|
|
48
|
+
isMobile.Android() ||
|
|
49
|
+
isMobile.BlackBerry() ||
|
|
50
|
+
isMobile.iOS() ||
|
|
51
|
+
isMobile.Opera() ||
|
|
52
|
+
isMobile.Windows() ||
|
|
53
|
+
TARGET === 'reactNative'
|
|
54
|
+
);
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const isTablet = userAgent.match(/Tablet|iPad/i);
|
|
59
|
+
|
|
60
|
+
const url = getLocation();
|
|
61
|
+
|
|
62
|
+
return {
|
|
63
|
+
urlPath: url?.pathname,
|
|
64
|
+
host: url?.host || url?.hostname,
|
|
65
|
+
device: isTablet ? 'tablet' : isMobile.any() ? 'mobile' : 'desktop',
|
|
66
|
+
};
|
|
67
|
+
};
|