@builder.io/sdk-solid 0.1.2 → 0.1.3
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/sdk-solid.cjs +34 -0
- package/dist/sdk-solid.js +3937 -0
- package/package.json +5 -6
- package/src/blocks/BaseText.jsx +5 -1
- package/src/blocks/button/button.jsx +25 -7
- package/src/blocks/columns/columns.jsx +84 -38
- package/src/blocks/custom-code/custom-code.jsx +25 -3
- package/src/blocks/embed/embed.jsx +14 -2
- package/src/blocks/form/form.jsx +175 -121
- package/src/blocks/fragment/fragment.jsx +2 -1
- package/src/blocks/image/image.jsx +75 -38
- package/src/blocks/img/img.jsx +15 -5
- package/src/blocks/input/input.jsx +17 -2
- package/src/blocks/raw-text/raw-text.jsx +8 -2
- package/src/blocks/section/section.jsx +24 -14
- package/src/blocks/select/select.jsx +21 -6
- package/src/blocks/submit-button/submit-button.jsx +6 -3
- package/src/blocks/symbol/symbol.jsx +54 -15
- package/src/blocks/text/text.jsx +2 -1
- package/src/blocks/textarea/textarea.jsx +11 -2
- package/src/blocks/video/video.jsx +49 -27
- package/src/components/render-block/block-styles.jsx +45 -21
- package/src/components/render-block/render-block.helpers.js +90 -0
- package/src/components/render-block/render-block.jsx +110 -131
- package/src/components/render-block/render-component.jsx +26 -9
- package/src/components/render-block/render-repeated-block.jsx +20 -24
- package/src/components/render-blocks.jsx +70 -30
- package/src/components/render-content/builder-editing.jsx +2 -1
- package/src/components/render-content/components/render-styles.jsx +17 -8
- package/src/components/render-content/render-content.jsx +234 -148
- package/src/components/render-inlined-styles.jsx +14 -4
- package/src/functions/track/helpers.js +50 -0
- package/src/functions/{track.js → track/index.js} +10 -6
- package/src/functions/track/interaction.js +53 -0
- package/src/index.js +1 -1
- package/vite.config.ts +18 -0
- package/solid-index.jsx +0 -5
- package/src/components/render-block/render-component-with-context.jsx +0 -28
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Show, onMount, on, createEffect, createSignal } from "solid-js";
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import { createStore, reconcile } from "solid-js/store";
|
|
4
|
+
|
|
4
5
|
import { getDefaultRegisteredComponents } from "../../constants/builder-registered-components.js";
|
|
5
6
|
import { TARGET } from "../../constants/target.js";
|
|
6
7
|
import { evaluate } from "../../functions/evaluate.js";
|
|
@@ -9,89 +10,111 @@ import { fetch } from "../../functions/get-fetch.js";
|
|
|
9
10
|
import { isBrowser } from "../../functions/is-browser.js";
|
|
10
11
|
import { isEditing } from "../../functions/is-editing.js";
|
|
11
12
|
import { isPreviewing } from "../../functions/is-previewing.js";
|
|
12
|
-
import {
|
|
13
|
-
|
|
13
|
+
import {
|
|
14
|
+
components,
|
|
15
|
+
createRegisterComponentMessage,
|
|
16
|
+
} from "../../functions/register-component.js";
|
|
17
|
+
import { _track } from "../../functions/track/index.js";
|
|
14
18
|
import RenderBlocks from "../render-blocks.jsx";
|
|
15
19
|
import RenderContentStyles from "./components/render-styles.jsx";
|
|
16
|
-
import
|
|
17
|
-
import {
|
|
20
|
+
import builderContext from "../../context/builder.context.js";
|
|
21
|
+
import {
|
|
22
|
+
registerInsertMenu,
|
|
23
|
+
setupBrowserForEditing,
|
|
24
|
+
} from "../../scripts/init-editing.js";
|
|
18
25
|
import { checkIsDefined } from "../../helpers/nullable.js";
|
|
26
|
+
import { getInteractionPropertiesForEvent } from "../../functions/track/interaction.js";
|
|
27
|
+
|
|
19
28
|
function RenderContent(props) {
|
|
20
29
|
const [forceReRenderCount, setForceReRenderCount] = createSignal(0);
|
|
30
|
+
|
|
21
31
|
const [overrideContent, setOverrideContent] = createSignal(null);
|
|
32
|
+
|
|
22
33
|
const [update, setUpdate] = createSignal(0);
|
|
34
|
+
|
|
23
35
|
const [useBreakpoints, setUseBreakpoints] = createSignal(null);
|
|
36
|
+
|
|
37
|
+
const [canTrackToUse, setCanTrackToUse] = createSignal(
|
|
38
|
+
checkIsDefined(props.canTrack) ? props.canTrack : true
|
|
39
|
+
);
|
|
40
|
+
|
|
24
41
|
const [overrideState, setOverrideState] = createSignal({});
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
42
|
+
|
|
43
|
+
const [contextContext, setContextContext] = createSignal(props.context || {});
|
|
44
|
+
|
|
45
|
+
const [allRegisteredComponents, setAllRegisteredComponents] = createSignal(
|
|
46
|
+
[
|
|
47
|
+
...getDefaultRegisteredComponents(),
|
|
48
|
+
// While this `components` object is deprecated, we must maintain support for it.
|
|
49
|
+
// Since users are able to override our default components, we need to make sure that we do not break such
|
|
50
|
+
// existing usage.
|
|
51
|
+
// This is why we spread `components` after the default Builder.io components, but before the `props.customComponents`,
|
|
52
|
+
// which is the new standard way of providing custom components, and must therefore take precedence.
|
|
53
|
+
...components,
|
|
54
|
+
...(props.customComponents || []),
|
|
55
|
+
].reduce(
|
|
56
|
+
(acc, curr) => ({
|
|
57
|
+
...acc,
|
|
58
|
+
[curr.name]: curr,
|
|
59
|
+
}),
|
|
60
|
+
{}
|
|
61
|
+
)
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
const [httpReqsData, setHttpReqsData] = createSignal({});
|
|
65
|
+
|
|
66
|
+
const [clicked, setClicked] = createSignal(false);
|
|
67
|
+
|
|
28
68
|
function contentState() {
|
|
29
69
|
return {
|
|
30
70
|
...props.content?.data?.state,
|
|
31
71
|
...props.data,
|
|
32
|
-
...(props.locale
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
72
|
+
...(props.locale
|
|
73
|
+
? {
|
|
74
|
+
locale: props.locale,
|
|
75
|
+
}
|
|
76
|
+
: {}),
|
|
77
|
+
...overrideState(),
|
|
36
78
|
};
|
|
37
79
|
}
|
|
38
|
-
|
|
39
|
-
return props.context || {};
|
|
40
|
-
}
|
|
41
|
-
function allRegisteredComponents() {
|
|
42
|
-
const allComponentsArray = [...getDefaultRegisteredComponents(),
|
|
43
|
-
// While this `components` object is deprecated, we must maintain support for it.
|
|
44
|
-
// Since users are able to override our default components, we need to make sure that we do not break such
|
|
45
|
-
// existing usage.
|
|
46
|
-
// This is why we spread `components` after the default Builder.io components, but before the `props.customComponents`,
|
|
47
|
-
// which is the new standard way of providing custom components, and must therefore take precedence.
|
|
48
|
-
...components, ...(props.customComponents || [])];
|
|
49
|
-
const allComponents = allComponentsArray.reduce((acc, curr) => ({
|
|
50
|
-
...acc,
|
|
51
|
-
[curr.name]: curr
|
|
52
|
-
}), {});
|
|
53
|
-
return allComponents;
|
|
54
|
-
}
|
|
80
|
+
|
|
55
81
|
function processMessage(event) {
|
|
56
|
-
const {
|
|
57
|
-
data
|
|
58
|
-
} = event;
|
|
82
|
+
const { data } = event;
|
|
59
83
|
if (data) {
|
|
60
84
|
switch (data.type) {
|
|
61
|
-
case "builder.configureSdk":
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
85
|
+
case "builder.configureSdk": {
|
|
86
|
+
const messageContent = data.data;
|
|
87
|
+
const { breakpoints, contentId } = messageContent;
|
|
88
|
+
if (!contentId || contentId !== useContent?.id) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
setUseBreakpoints(breakpoints);
|
|
92
|
+
setForceReRenderCount(forceReRenderCount() + 1); // This is a hack to force Qwik to re-render.
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
case "builder.contentUpdate": {
|
|
96
|
+
const messageContent = data.data;
|
|
97
|
+
const key =
|
|
98
|
+
messageContent.key ||
|
|
99
|
+
messageContent.alias ||
|
|
100
|
+
messageContent.entry ||
|
|
101
|
+
messageContent.modelName;
|
|
102
|
+
const contentData = messageContent.data;
|
|
103
|
+
if (key === props.model) {
|
|
104
|
+
setOverrideContent(contentData);
|
|
72
105
|
setForceReRenderCount(forceReRenderCount() + 1); // This is a hack to force Qwik to re-render.
|
|
73
|
-
break;
|
|
74
106
|
}
|
|
75
|
-
case "builder.contentUpdate":
|
|
76
|
-
{
|
|
77
|
-
const messageContent = data.data;
|
|
78
|
-
const key = messageContent.key || messageContent.alias || messageContent.entry || messageContent.modelName;
|
|
79
|
-
const contentData = messageContent.data;
|
|
80
|
-
if (key === props.model) {
|
|
81
|
-
setOverrideContent(contentData);
|
|
82
|
-
setForceReRenderCount(forceReRenderCount() + 1); // This is a hack to force Qwik to re-render.
|
|
83
|
-
}
|
|
84
107
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
case "builder.patchUpdates":
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
case "builder.patchUpdates": {
|
|
111
|
+
// TODO
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
92
114
|
}
|
|
93
115
|
}
|
|
94
116
|
}
|
|
117
|
+
|
|
95
118
|
function evaluateJsCode() {
|
|
96
119
|
// run any dynamic JS code attached to content
|
|
97
120
|
const jsCode = useContent?.data?.jsCode;
|
|
@@ -99,14 +122,12 @@ function RenderContent(props) {
|
|
|
99
122
|
evaluate({
|
|
100
123
|
code: jsCode,
|
|
101
124
|
context: contextContext(),
|
|
102
|
-
state: contentState()
|
|
125
|
+
state: contentState(),
|
|
103
126
|
});
|
|
104
127
|
}
|
|
105
128
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
function onClick(_event) {
|
|
129
|
+
|
|
130
|
+
function onClick(event) {
|
|
110
131
|
if (useContent) {
|
|
111
132
|
const variationId = useContent?.testVariationId;
|
|
112
133
|
const contentId = useContent?.id;
|
|
@@ -115,31 +136,41 @@ function RenderContent(props) {
|
|
|
115
136
|
canTrack: canTrackToUse(),
|
|
116
137
|
contentId,
|
|
117
138
|
apiKey: props.apiKey,
|
|
118
|
-
variationId: variationId !== contentId ? variationId : undefined
|
|
139
|
+
variationId: variationId !== contentId ? variationId : undefined,
|
|
140
|
+
...getInteractionPropertiesForEvent(event),
|
|
141
|
+
unique: !clicked(),
|
|
119
142
|
});
|
|
120
143
|
}
|
|
144
|
+
if (!clicked()) {
|
|
145
|
+
setClicked(true);
|
|
146
|
+
}
|
|
121
147
|
}
|
|
148
|
+
|
|
122
149
|
function evalExpression(expression) {
|
|
123
|
-
return expression.replace(/{{([^}]+)}}/g, (_match, group) =>
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
150
|
+
return expression.replace(/{{([^}]+)}}/g, (_match, group) =>
|
|
151
|
+
evaluate({
|
|
152
|
+
code: group,
|
|
153
|
+
context: contextContext(),
|
|
154
|
+
state: contentState(),
|
|
155
|
+
})
|
|
156
|
+
);
|
|
128
157
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
158
|
+
|
|
159
|
+
function handleRequest({ url, key }) {
|
|
160
|
+
fetch(url)
|
|
161
|
+
.then((response) => response.json())
|
|
162
|
+
.then((json) => {
|
|
163
|
+
const newOverrideState = {
|
|
164
|
+
...overrideState(),
|
|
165
|
+
[key]: json,
|
|
166
|
+
};
|
|
167
|
+
setOverrideState(newOverrideState);
|
|
168
|
+
})
|
|
169
|
+
.catch((err) => {
|
|
170
|
+
console.log("error fetching dynamic data", url, err);
|
|
171
|
+
});
|
|
142
172
|
}
|
|
173
|
+
|
|
143
174
|
function runHttpRequests() {
|
|
144
175
|
const requests = useContent?.data?.httpRequests ?? {};
|
|
145
176
|
Object.entries(requests).forEach(([key, url]) => {
|
|
@@ -147,71 +178,99 @@ function RenderContent(props) {
|
|
|
147
178
|
const evaluatedUrl = evalExpression(url);
|
|
148
179
|
handleRequest({
|
|
149
180
|
url: evaluatedUrl,
|
|
150
|
-
key
|
|
181
|
+
key,
|
|
151
182
|
});
|
|
152
183
|
}
|
|
153
184
|
});
|
|
154
185
|
}
|
|
186
|
+
|
|
155
187
|
function emitStateUpdate() {
|
|
156
188
|
if (isEditing()) {
|
|
157
|
-
window.dispatchEvent(
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
189
|
+
window.dispatchEvent(
|
|
190
|
+
new CustomEvent("builder:component:stateChange", {
|
|
191
|
+
detail: {
|
|
192
|
+
state: contentState(),
|
|
193
|
+
ref: {
|
|
194
|
+
name: props.model,
|
|
195
|
+
},
|
|
196
|
+
},
|
|
197
|
+
})
|
|
198
|
+
);
|
|
165
199
|
}
|
|
166
200
|
}
|
|
201
|
+
|
|
167
202
|
function shouldRenderContentStyles() {
|
|
168
|
-
return Boolean(
|
|
203
|
+
return Boolean(
|
|
204
|
+
(useContent?.data?.cssCode || useContent?.data?.customFonts?.length) &&
|
|
205
|
+
TARGET !== "reactNative"
|
|
206
|
+
);
|
|
169
207
|
}
|
|
208
|
+
|
|
170
209
|
const updateUseContent = function useContent() {
|
|
171
210
|
if (!props.content && !overrideContent()) {
|
|
172
211
|
return undefined;
|
|
173
212
|
}
|
|
174
|
-
|
|
213
|
+
return {
|
|
175
214
|
...props.content,
|
|
176
215
|
...overrideContent(),
|
|
177
216
|
data: {
|
|
178
217
|
...props.content?.data,
|
|
179
218
|
...props.data,
|
|
180
|
-
...overrideContent()?.data
|
|
219
|
+
...overrideContent()?.data,
|
|
181
220
|
},
|
|
182
221
|
meta: {
|
|
183
222
|
...props.content?.meta,
|
|
184
223
|
...overrideContent()?.meta,
|
|
185
|
-
breakpoints:
|
|
186
|
-
|
|
224
|
+
breakpoints:
|
|
225
|
+
useBreakpoints() ||
|
|
226
|
+
overrideContent()?.meta?.breakpoints ||
|
|
227
|
+
props.content?.meta?.breakpoints,
|
|
228
|
+
},
|
|
187
229
|
};
|
|
188
|
-
return mergedContent;
|
|
189
230
|
};
|
|
190
231
|
const [useContent, setUseContent] = createStore(updateUseContent());
|
|
191
|
-
createEffect(
|
|
232
|
+
createEffect(
|
|
233
|
+
on(
|
|
234
|
+
() => [overrideContent(), useBreakpoints(), props.content, props.data],
|
|
235
|
+
() => setUseContent(reconcile(updateUseContent()))
|
|
236
|
+
)
|
|
237
|
+
);
|
|
238
|
+
|
|
192
239
|
let elementRef;
|
|
240
|
+
|
|
193
241
|
onMount(() => {
|
|
194
242
|
if (!props.apiKey) {
|
|
195
|
-
console.error(
|
|
243
|
+
console.error(
|
|
244
|
+
"[Builder.io]: No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop."
|
|
245
|
+
);
|
|
196
246
|
}
|
|
197
247
|
if (isBrowser()) {
|
|
198
248
|
if (isEditing()) {
|
|
199
249
|
setForceReRenderCount(forceReRenderCount() + 1);
|
|
200
250
|
registerInsertMenu();
|
|
201
251
|
setupBrowserForEditing({
|
|
202
|
-
...(props.locale
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
252
|
+
...(props.locale
|
|
253
|
+
? {
|
|
254
|
+
locale: props.locale,
|
|
255
|
+
}
|
|
256
|
+
: {}),
|
|
257
|
+
...(props.includeRefs
|
|
258
|
+
? {
|
|
259
|
+
includeRefs: props.includeRefs,
|
|
260
|
+
}
|
|
261
|
+
: {}),
|
|
212
262
|
});
|
|
263
|
+
Object.values(allRegisteredComponents()).forEach(
|
|
264
|
+
(registeredComponent) => {
|
|
265
|
+
const message = createRegisterComponentMessage(registeredComponent);
|
|
266
|
+
window.parent?.postMessage(message, "*");
|
|
267
|
+
}
|
|
268
|
+
);
|
|
213
269
|
window.addEventListener("message", processMessage);
|
|
214
|
-
window.addEventListener(
|
|
270
|
+
window.addEventListener(
|
|
271
|
+
"builder:component:stateChangeListenerActivated",
|
|
272
|
+
emitStateUpdate
|
|
273
|
+
);
|
|
215
274
|
}
|
|
216
275
|
if (useContent) {
|
|
217
276
|
const variationId = useContent?.testVariationId;
|
|
@@ -221,25 +280,40 @@ function RenderContent(props) {
|
|
|
221
280
|
canTrack: canTrackToUse(),
|
|
222
281
|
contentId,
|
|
223
282
|
apiKey: props.apiKey,
|
|
224
|
-
variationId: variationId !== contentId ? variationId : undefined
|
|
283
|
+
variationId: variationId !== contentId ? variationId : undefined,
|
|
225
284
|
});
|
|
226
285
|
}
|
|
227
286
|
|
|
228
287
|
// override normal content in preview mode
|
|
229
288
|
if (isPreviewing()) {
|
|
230
289
|
const searchParams = new URL(location.href).searchParams;
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
290
|
+
const searchParamPreview = searchParams.get("builder.preview");
|
|
291
|
+
const previewApiKey =
|
|
292
|
+
searchParams.get("apiKey") || searchParams.get("builder.space");
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Make sure that:
|
|
296
|
+
* - the preview model name is the same as the one we're rendering, since there can be multiple models rendered
|
|
297
|
+
* at the same time, e.g. header/page/footer.
|
|
298
|
+
* - the API key is the same, since we don't want to preview content from other organizations.
|
|
299
|
+
*
|
|
300
|
+
* TO-DO: should we check that the preview item ID is the same as the initial one being rendered? Or would
|
|
301
|
+
* this break scenarios where the item is not published yet?
|
|
302
|
+
*
|
|
303
|
+
* TO-DO: should we only update the state when there is a change?
|
|
304
|
+
**/
|
|
305
|
+
if (
|
|
306
|
+
searchParamPreview === props.model &&
|
|
307
|
+
previewApiKey === props.apiKey
|
|
308
|
+
) {
|
|
309
|
+
getContent({
|
|
310
|
+
model: props.model,
|
|
311
|
+
apiKey: props.apiKey,
|
|
312
|
+
}).then((content) => {
|
|
313
|
+
if (content) {
|
|
314
|
+
setOverrideContent(content);
|
|
315
|
+
}
|
|
316
|
+
});
|
|
243
317
|
}
|
|
244
318
|
}
|
|
245
319
|
evaluateJsCode();
|
|
@@ -247,43 +321,55 @@ function RenderContent(props) {
|
|
|
247
321
|
emitStateUpdate();
|
|
248
322
|
}
|
|
249
323
|
});
|
|
324
|
+
|
|
250
325
|
function onUpdateFn_0() {
|
|
251
326
|
evaluateJsCode();
|
|
252
327
|
}
|
|
253
|
-
createEffect(
|
|
328
|
+
createEffect(
|
|
329
|
+
on(() => [useContent?.data?.jsCode, contentState()], onUpdateFn_0)
|
|
330
|
+
);
|
|
331
|
+
|
|
254
332
|
function onUpdateFn_1() {
|
|
255
333
|
runHttpRequests();
|
|
256
334
|
}
|
|
257
335
|
createEffect(on(() => [useContent?.data?.httpRequests], onUpdateFn_1));
|
|
336
|
+
|
|
258
337
|
function onUpdateFn_2() {
|
|
259
338
|
emitStateUpdate();
|
|
260
339
|
}
|
|
261
340
|
createEffect(on(() => [contentState()], onUpdateFn_2));
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
return props.apiKey;
|
|
274
|
-
},
|
|
275
|
-
get registeredComponents() {
|
|
276
|
-
return allRegisteredComponents();
|
|
277
|
-
}
|
|
278
|
-
}} component={BuilderContext.Provider}>
|
|
341
|
+
|
|
342
|
+
return (
|
|
343
|
+
<builderContext.Provider
|
|
344
|
+
value={{
|
|
345
|
+
content: useContent,
|
|
346
|
+
state: contentState(),
|
|
347
|
+
context: contextContext(),
|
|
348
|
+
apiKey: props.apiKey,
|
|
349
|
+
registeredComponents: allRegisteredComponents(),
|
|
350
|
+
}}
|
|
351
|
+
>
|
|
279
352
|
<Show when={useContent}>
|
|
280
|
-
<div
|
|
353
|
+
<div
|
|
354
|
+
ref={elementRef}
|
|
355
|
+
onClick={(event) => onClick(event)}
|
|
356
|
+
builder-content-id={useContent?.id}
|
|
357
|
+
builder-model={props.model}
|
|
358
|
+
>
|
|
281
359
|
<Show when={shouldRenderContentStyles()}>
|
|
282
|
-
<RenderContentStyles
|
|
360
|
+
<RenderContentStyles
|
|
361
|
+
cssCode={useContent?.data?.cssCode}
|
|
362
|
+
customFonts={useContent?.data?.customFonts}
|
|
363
|
+
></RenderContentStyles>
|
|
283
364
|
</Show>
|
|
284
|
-
<RenderBlocks
|
|
365
|
+
<RenderBlocks
|
|
366
|
+
blocks={useContent?.data?.blocks}
|
|
367
|
+
key={forceReRenderCount()}
|
|
368
|
+
></RenderBlocks>
|
|
285
369
|
</div>
|
|
286
370
|
</Show>
|
|
287
|
-
</
|
|
371
|
+
</builderContext.Provider>
|
|
372
|
+
);
|
|
288
373
|
}
|
|
289
|
-
|
|
374
|
+
|
|
375
|
+
export default RenderContent;
|
|
@@ -1,17 +1,27 @@
|
|
|
1
|
-
import { Show } from "solid-js";
|
|
1
|
+
import { Show, createSignal } from "solid-js";
|
|
2
2
|
import { Dynamic } from "solid-js/web";
|
|
3
|
+
|
|
3
4
|
import { TARGET } from "../constants/target.js";
|
|
5
|
+
|
|
4
6
|
function RenderInlinedStyles(props) {
|
|
5
7
|
function injectedStyleScript() {
|
|
6
8
|
return `<${tag()}>${props.styles}</${tag()}>`;
|
|
7
9
|
}
|
|
10
|
+
|
|
8
11
|
function tag() {
|
|
9
12
|
// NOTE: we have to obfusctate the name of the tag due to a limitation in the svelte-preprocessor plugin.
|
|
10
13
|
// https://github.com/sveltejs/vite-plugin-svelte/issues/315#issuecomment-1109000027
|
|
11
14
|
return "sty" + "le";
|
|
12
15
|
}
|
|
13
|
-
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Show
|
|
19
|
+
fallback={<Dynamic component={tag()}>{props.styles}</Dynamic>}
|
|
20
|
+
when={TARGET === "svelte"}
|
|
21
|
+
>
|
|
14
22
|
<div innerHTML={injectedStyleScript()}></div>
|
|
15
|
-
</Show
|
|
23
|
+
</Show>
|
|
24
|
+
);
|
|
16
25
|
}
|
|
17
|
-
|
|
26
|
+
|
|
27
|
+
export default RenderInlinedStyles;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { TARGET } from "../../constants/target";
|
|
2
|
+
import { isBrowser } from "../is-browser";
|
|
3
|
+
const getLocation = () => {
|
|
4
|
+
if (TARGET === "reactNative") {
|
|
5
|
+
return null;
|
|
6
|
+
} else if (isBrowser()) {
|
|
7
|
+
const parsedLocation = new URL(location.href);
|
|
8
|
+
if (parsedLocation.pathname === "") {
|
|
9
|
+
parsedLocation.pathname = "/";
|
|
10
|
+
}
|
|
11
|
+
return parsedLocation;
|
|
12
|
+
} else {
|
|
13
|
+
console.warn("Cannot get location for tracking in non-browser environment");
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
const getUserAgent = () => typeof navigator === "object" && navigator.userAgent || "";
|
|
18
|
+
const getUserAttributes = () => {
|
|
19
|
+
const userAgent = getUserAgent();
|
|
20
|
+
const isMobile = {
|
|
21
|
+
Android() {
|
|
22
|
+
return userAgent.match(/Android/i);
|
|
23
|
+
},
|
|
24
|
+
BlackBerry() {
|
|
25
|
+
return userAgent.match(/BlackBerry/i);
|
|
26
|
+
},
|
|
27
|
+
iOS() {
|
|
28
|
+
return userAgent.match(/iPhone|iPod/i);
|
|
29
|
+
},
|
|
30
|
+
Opera() {
|
|
31
|
+
return userAgent.match(/Opera Mini/i);
|
|
32
|
+
},
|
|
33
|
+
Windows() {
|
|
34
|
+
return userAgent.match(/IEMobile/i) || userAgent.match(/WPDesktop/i);
|
|
35
|
+
},
|
|
36
|
+
any() {
|
|
37
|
+
return isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows() || TARGET === "reactNative";
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const isTablet = userAgent.match(/Tablet|iPad/i);
|
|
41
|
+
const url = getLocation();
|
|
42
|
+
return {
|
|
43
|
+
urlPath: url == null ? void 0 : url.pathname,
|
|
44
|
+
host: (url == null ? void 0 : url.host) || (url == null ? void 0 : url.hostname),
|
|
45
|
+
device: isTablet ? "tablet" : isMobile.any() ? "mobile" : "desktop"
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
export {
|
|
49
|
+
getUserAttributes
|
|
50
|
+
};
|
|
@@ -49,11 +49,12 @@ var __async = (__this, __arguments, generator) => {
|
|
|
49
49
|
step((generator = generator.apply(__this, __arguments)).next());
|
|
50
50
|
});
|
|
51
51
|
};
|
|
52
|
-
import { TARGET } from "
|
|
53
|
-
import { getSessionId } from "
|
|
54
|
-
import { getVisitorId } from "
|
|
55
|
-
import { isBrowser } from "
|
|
56
|
-
import { isEditing } from "
|
|
52
|
+
import { TARGET } from "../../constants/target.js";
|
|
53
|
+
import { getSessionId } from "../../helpers/sessionId.js";
|
|
54
|
+
import { getVisitorId } from "../../helpers/visitorId.js";
|
|
55
|
+
import { isBrowser } from "../is-browser.js";
|
|
56
|
+
import { isEditing } from "../is-editing.js";
|
|
57
|
+
import { getUserAttributes } from "./helpers.js";
|
|
57
58
|
const getTrackingEventData = (_0) => __async(void 0, [_0], function* ({
|
|
58
59
|
canTrack
|
|
59
60
|
}) {
|
|
@@ -82,8 +83,11 @@ const createEvent = (_a) => __async(void 0, null, function* () {
|
|
|
82
83
|
return {
|
|
83
84
|
type: eventType,
|
|
84
85
|
data: __spreadProps(__spreadValues(__spreadProps(__spreadValues({}, properties), {
|
|
85
|
-
metadata:
|
|
86
|
+
metadata: __spreadValues({
|
|
87
|
+
url: location.href
|
|
88
|
+
}, metadata)
|
|
86
89
|
}), yield getTrackingEventData({ canTrack })), {
|
|
90
|
+
userAttributes: getUserAttributes(),
|
|
87
91
|
ownerId: apiKey
|
|
88
92
|
})
|
|
89
93
|
};
|