@builder.io/sdk-svelte 0.1.2 → 0.1.3-1
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 +4 -3
- package/package/CHANGELOG.md +5 -0
- package/package/blocks/BaseText.svelte +1 -1
- package/package/blocks/button/button.svelte +2 -2
- 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 +2 -2
- package/package/blocks/fragment/fragment.svelte +1 -1
- package/package/blocks/image/image.svelte +1 -2
- package/package/blocks/img/img.svelte +2 -2
- package/package/blocks/input/input.svelte +2 -2
- package/package/blocks/raw-text/raw-text.svelte +1 -1
- package/package/blocks/section/section.svelte +2 -2
- package/package/blocks/select/select.svelte +2 -2
- package/package/blocks/submit-button/submit-button.svelte +2 -2
- package/package/blocks/symbol/symbol.svelte +5 -3
- package/package/blocks/text/text.svelte +1 -1
- package/package/blocks/textarea/textarea.svelte +2 -2
- package/package/blocks/video/video.svelte +2 -2
- 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 +60 -54
- 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/functions/track/interaction.d.ts +13 -0
- package/package/functions/track/interaction.js +54 -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 +2 -7
- package/src/blocks/columns/columns.svelte +3 -3
- package/src/blocks/custom-code/custom-code.svelte +1 -1
- package/src/blocks/embed/embed.svelte +1 -3
- package/src/blocks/form/form.svelte +3 -8
- package/src/blocks/fragment/fragment.svelte +1 -1
- package/src/blocks/image/image.svelte +1 -2
- package/src/blocks/img/img.svelte +2 -7
- package/src/blocks/input/input.svelte +2 -7
- package/src/blocks/raw-text/raw-text.svelte +1 -1
- package/src/blocks/section/section.svelte +2 -7
- package/src/blocks/select/select.svelte +2 -7
- package/src/blocks/submit-button/submit-button.svelte +2 -7
- package/src/blocks/symbol/symbol.svelte +6 -9
- package/src/blocks/text/text.svelte +1 -1
- package/src/blocks/textarea/textarea.svelte +2 -7
- package/src/blocks/video/video.svelte +2 -7
- 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 +66 -65
- 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/functions/track/interaction.ts +80 -0
- 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
|
@@ -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,15 +55,16 @@
|
|
|
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";
|
|
72
66
|
import { checkIsDefined } from "../../helpers/nullable.js";
|
|
67
|
+
import { getInteractionPropertiesForEvent } from "../../functions/track/interaction.js";
|
|
73
68
|
|
|
74
69
|
export let content: RenderContentProps["content"];
|
|
75
70
|
export let data: RenderContentProps["data"];
|
|
@@ -81,7 +76,7 @@
|
|
|
81
76
|
export let apiKey: RenderContentProps["apiKey"];
|
|
82
77
|
export let includeRefs: RenderContentProps["includeRefs"];
|
|
83
78
|
|
|
84
|
-
setContext(
|
|
79
|
+
setContext(builderContext.key, {
|
|
85
80
|
get content() {
|
|
86
81
|
return useContent();
|
|
87
82
|
},
|
|
@@ -89,13 +84,13 @@
|
|
|
89
84
|
return contentState();
|
|
90
85
|
},
|
|
91
86
|
get context() {
|
|
92
|
-
return contextContext
|
|
87
|
+
return contextContext;
|
|
93
88
|
},
|
|
94
89
|
get apiKey() {
|
|
95
90
|
return apiKey;
|
|
96
91
|
},
|
|
97
92
|
get registeredComponents() {
|
|
98
|
-
return allRegisteredComponents
|
|
93
|
+
return allRegisteredComponents;
|
|
99
94
|
},
|
|
100
95
|
});
|
|
101
96
|
|
|
@@ -141,29 +136,34 @@
|
|
|
141
136
|
if (jsCode) {
|
|
142
137
|
evaluate({
|
|
143
138
|
code: jsCode,
|
|
144
|
-
context: contextContext
|
|
139
|
+
context: contextContext,
|
|
145
140
|
state: contentState(),
|
|
146
141
|
});
|
|
147
142
|
}
|
|
148
143
|
}
|
|
149
|
-
function onClick(
|
|
144
|
+
function onClick(event) {
|
|
150
145
|
if (useContent()) {
|
|
151
146
|
const variationId = useContent?.()?.testVariationId;
|
|
152
147
|
const contentId = useContent?.()?.id;
|
|
153
148
|
_track({
|
|
154
149
|
type: "click",
|
|
155
|
-
canTrack: canTrackToUse
|
|
150
|
+
canTrack: canTrackToUse,
|
|
156
151
|
contentId,
|
|
157
152
|
apiKey: apiKey,
|
|
158
153
|
variationId: variationId !== contentId ? variationId : undefined,
|
|
154
|
+
...getInteractionPropertiesForEvent(event),
|
|
155
|
+
unique: !clicked,
|
|
159
156
|
});
|
|
160
157
|
}
|
|
158
|
+
if (!clicked) {
|
|
159
|
+
clicked = true;
|
|
160
|
+
}
|
|
161
161
|
}
|
|
162
162
|
function evalExpression(expression) {
|
|
163
163
|
return expression.replace(/{{([^}]+)}}/g, (_match, group) =>
|
|
164
164
|
evaluate({
|
|
165
165
|
code: group,
|
|
166
|
-
context: contextContext
|
|
166
|
+
context: contextContext,
|
|
167
167
|
state: contentState(),
|
|
168
168
|
})
|
|
169
169
|
);
|
|
@@ -185,7 +185,7 @@
|
|
|
185
185
|
function runHttpRequests() {
|
|
186
186
|
const requests = useContent?.()?.data?.httpRequests ?? {};
|
|
187
187
|
Object.entries(requests).forEach(([key, url]) => {
|
|
188
|
-
if (url && (!httpReqsData
|
|
188
|
+
if (url && (!httpReqsData[key] || isEditing())) {
|
|
189
189
|
const evaluatedUrl = evalExpression(url);
|
|
190
190
|
handleRequest({
|
|
191
191
|
url: evaluatedUrl,
|
|
@@ -212,7 +212,7 @@
|
|
|
212
212
|
if (!content && !overrideContent) {
|
|
213
213
|
return undefined;
|
|
214
214
|
}
|
|
215
|
-
|
|
215
|
+
return {
|
|
216
216
|
...content,
|
|
217
217
|
...overrideContent,
|
|
218
218
|
data: {
|
|
@@ -229,10 +229,6 @@
|
|
|
229
229
|
content?.meta?.breakpoints,
|
|
230
230
|
},
|
|
231
231
|
};
|
|
232
|
-
return mergedContent;
|
|
233
|
-
};
|
|
234
|
-
$: canTrackToUse = () => {
|
|
235
|
-
return checkIsDefined(canTrack) ? canTrack : true;
|
|
236
232
|
};
|
|
237
233
|
$: contentState = () => {
|
|
238
234
|
return {
|
|
@@ -246,32 +242,6 @@
|
|
|
246
242
|
...overrideState,
|
|
247
243
|
};
|
|
248
244
|
};
|
|
249
|
-
$: contextContext = () => {
|
|
250
|
-
return context || {};
|
|
251
|
-
};
|
|
252
|
-
$: allRegisteredComponents = () => {
|
|
253
|
-
const allComponentsArray = [
|
|
254
|
-
...getDefaultRegisteredComponents(),
|
|
255
|
-
// While this `components` object is deprecated, we must maintain support for it.
|
|
256
|
-
// Since users are able to override our default components, we need to make sure that we do not break such
|
|
257
|
-
// existing usage.
|
|
258
|
-
// This is why we spread `components` after the default Builder.io components, but before the `customComponents`,
|
|
259
|
-
// which is the new standard way of providing custom components, and must therefore take precedence.
|
|
260
|
-
...components,
|
|
261
|
-
...(customComponents || []),
|
|
262
|
-
];
|
|
263
|
-
const allComponents = allComponentsArray.reduce(
|
|
264
|
-
(acc, curr) => ({
|
|
265
|
-
...acc,
|
|
266
|
-
[curr.name]: curr,
|
|
267
|
-
}),
|
|
268
|
-
{}
|
|
269
|
-
);
|
|
270
|
-
return allComponents;
|
|
271
|
-
};
|
|
272
|
-
$: httpReqsData = () => {
|
|
273
|
-
return {};
|
|
274
|
-
};
|
|
275
245
|
$: shouldRenderContentStyles = () => {
|
|
276
246
|
return Boolean(
|
|
277
247
|
(useContent?.()?.data?.cssCode ||
|
|
@@ -286,7 +256,27 @@
|
|
|
286
256
|
let overrideContent = null;
|
|
287
257
|
let update = 0;
|
|
288
258
|
let useBreakpoints = null;
|
|
259
|
+
let canTrackToUse = checkIsDefined(canTrack) ? canTrack : true;
|
|
289
260
|
let overrideState = {};
|
|
261
|
+
let contextContext = context || {};
|
|
262
|
+
let allRegisteredComponents = [
|
|
263
|
+
...getDefaultRegisteredComponents(),
|
|
264
|
+
// While this `components` object is deprecated, we must maintain support for it.
|
|
265
|
+
// Since users are able to override our default components, we need to make sure that we do not break such
|
|
266
|
+
// existing usage.
|
|
267
|
+
// This is why we spread `components` after the default Builder.io components, but before the `props.customComponents`,
|
|
268
|
+
// which is the new standard way of providing custom components, and must therefore take precedence.
|
|
269
|
+
...components,
|
|
270
|
+
...(customComponents || []),
|
|
271
|
+
].reduce(
|
|
272
|
+
(acc, curr) => ({
|
|
273
|
+
...acc,
|
|
274
|
+
[curr.name]: curr,
|
|
275
|
+
}),
|
|
276
|
+
{}
|
|
277
|
+
);
|
|
278
|
+
let httpReqsData = {};
|
|
279
|
+
let clicked = false;
|
|
290
280
|
|
|
291
281
|
onMount(() => {
|
|
292
282
|
if (!apiKey) {
|
|
@@ -310,7 +300,7 @@
|
|
|
310
300
|
}
|
|
311
301
|
: {}),
|
|
312
302
|
});
|
|
313
|
-
Object.values(allRegisteredComponents
|
|
303
|
+
Object.values(allRegisteredComponents).forEach(
|
|
314
304
|
(registeredComponent) => {
|
|
315
305
|
const message = createRegisterComponentMessage(registeredComponent);
|
|
316
306
|
window.parent?.postMessage(message, "*");
|
|
@@ -327,7 +317,7 @@
|
|
|
327
317
|
const contentId = useContent?.()?.id;
|
|
328
318
|
_track({
|
|
329
319
|
type: "impression",
|
|
330
|
-
canTrack: canTrackToUse
|
|
320
|
+
canTrack: canTrackToUse,
|
|
331
321
|
contentId,
|
|
332
322
|
apiKey: apiKey,
|
|
333
323
|
variationId: variationId !== contentId ? variationId : undefined,
|
|
@@ -337,19 +327,30 @@
|
|
|
337
327
|
// override normal content in preview mode
|
|
338
328
|
if (isPreviewing()) {
|
|
339
329
|
const searchParams = new URL(location.href).searchParams;
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
330
|
+
const searchParamPreview = searchParams.get("builder.preview");
|
|
331
|
+
const previewApiKey =
|
|
332
|
+
searchParams.get("apiKey") || searchParams.get("builder.space");
|
|
333
|
+
|
|
334
|
+
/**
|
|
335
|
+
* Make sure that:
|
|
336
|
+
* - the preview model name is the same as the one we're rendering, since there can be multiple models rendered
|
|
337
|
+
* at the same time, e.g. header/page/footer.
|
|
338
|
+
* - the API key is the same, since we don't want to preview content from other organizations.
|
|
339
|
+
*
|
|
340
|
+
* TO-DO: should we check that the preview item ID is the same as the initial one being rendered? Or would
|
|
341
|
+
* this break scenarios where the item is not published yet?
|
|
342
|
+
*
|
|
343
|
+
* TO-DO: should we only update the state when there is a change?
|
|
344
|
+
**/
|
|
345
|
+
if (searchParamPreview === model && previewApiKey === apiKey) {
|
|
346
|
+
getContent({
|
|
347
|
+
model: model,
|
|
348
|
+
apiKey: apiKey,
|
|
349
|
+
}).then((content) => {
|
|
350
|
+
if (content) {
|
|
351
|
+
overrideContent = content;
|
|
352
|
+
}
|
|
353
|
+
});
|
|
353
354
|
}
|
|
354
355
|
}
|
|
355
356
|
evaluateJsCode();
|
|
@@ -402,4 +403,4 @@
|
|
|
402
403
|
key={forceReRenderCount}
|
|
403
404
|
/>
|
|
404
405
|
</div>
|
|
405
|
-
{/if}
|
|
406
|
+
{/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
|
+
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { TARGET } from '
|
|
2
|
-
import { getSessionId } from '
|
|
3
|
-
import { getVisitorId } from '
|
|
4
|
-
import type { CanTrack } from '
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { TARGET } from '../../constants/target.js';
|
|
2
|
+
import { getSessionId } from '../../helpers/sessionId.js';
|
|
3
|
+
import { getVisitorId } from '../../helpers/visitorId.js';
|
|
4
|
+
import type { CanTrack } from '../../types/can-track.js';
|
|
5
|
+
import type { Dictionary } from '../../types/typescript.js';
|
|
6
|
+
import { isBrowser } from '../is-browser.js';
|
|
7
|
+
import { isEditing } from '../is-editing.js';
|
|
8
|
+
import { getUserAttributes } from './helpers.js';
|
|
7
9
|
|
|
8
10
|
interface Event {
|
|
9
11
|
/**
|
|
@@ -22,9 +24,9 @@ interface Event {
|
|
|
22
24
|
*/
|
|
23
25
|
ownerId: string;
|
|
24
26
|
/**
|
|
25
|
-
*
|
|
27
|
+
* (Optional) metadata that you want to provide with your event.
|
|
26
28
|
*/
|
|
27
|
-
metadata?:
|
|
29
|
+
metadata?: Dictionary<any>;
|
|
28
30
|
/**
|
|
29
31
|
* Session ID of the user. This is provided by the SDK by checking session storage.
|
|
30
32
|
*/
|
|
@@ -63,18 +65,11 @@ const getTrackingEventData = async ({
|
|
|
63
65
|
};
|
|
64
66
|
|
|
65
67
|
type EventProperties = Pick<Event, 'type'> &
|
|
66
|
-
Pick<Event['data'], 'contentId' | 'variationId'> & {
|
|
68
|
+
Pick<Event['data'], 'contentId' | 'variationId' | 'metadata'> & {
|
|
67
69
|
/**
|
|
68
70
|
* Your organization's API key.
|
|
69
71
|
*/
|
|
70
72
|
apiKey: Event['data']['ownerId'];
|
|
71
|
-
/**
|
|
72
|
-
* (Optional) metadata that you want to provide with your event.
|
|
73
|
-
*/
|
|
74
|
-
metadata?: {
|
|
75
|
-
[index: string]: any;
|
|
76
|
-
};
|
|
77
|
-
|
|
78
73
|
/**
|
|
79
74
|
* (Optional) Any additional (non-metadata) properties to add to the event.
|
|
80
75
|
*/
|
|
@@ -93,8 +88,12 @@ const createEvent = async ({
|
|
|
93
88
|
type: eventType,
|
|
94
89
|
data: {
|
|
95
90
|
...properties,
|
|
96
|
-
metadata:
|
|
91
|
+
metadata: {
|
|
92
|
+
url: location.href,
|
|
93
|
+
...metadata,
|
|
94
|
+
},
|
|
97
95
|
...(await getTrackingEventData({ canTrack })),
|
|
96
|
+
userAttributes: getUserAttributes(),
|
|
98
97
|
ownerId: apiKey,
|
|
99
98
|
},
|
|
100
99
|
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
function round(num: number) {
|
|
2
|
+
return Math.round(num * 1000) / 1000;
|
|
3
|
+
}
|
|
4
|
+
const findParentElement = (
|
|
5
|
+
target: HTMLElement,
|
|
6
|
+
callback: (element: HTMLElement) => boolean,
|
|
7
|
+
checkElement = true
|
|
8
|
+
): HTMLElement | null => {
|
|
9
|
+
if (!(target instanceof HTMLElement)) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
let parent: HTMLElement | null = checkElement ? target : target.parentElement;
|
|
13
|
+
do {
|
|
14
|
+
if (!parent) {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const matches = callback(parent);
|
|
19
|
+
if (matches) {
|
|
20
|
+
return parent;
|
|
21
|
+
}
|
|
22
|
+
} while ((parent = parent.parentElement));
|
|
23
|
+
|
|
24
|
+
return null;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const findBuilderParent = (target: HTMLElement) =>
|
|
28
|
+
findParentElement(target, (el) => {
|
|
29
|
+
const id = el.getAttribute('builder-id') || el.id;
|
|
30
|
+
return Boolean(id?.indexOf('builder-') === 0);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
type Offset = {
|
|
34
|
+
x: number;
|
|
35
|
+
y: number;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const computeOffset = ({
|
|
39
|
+
event,
|
|
40
|
+
target,
|
|
41
|
+
}: {
|
|
42
|
+
event: MouseEvent;
|
|
43
|
+
target: HTMLElement;
|
|
44
|
+
}): Offset => {
|
|
45
|
+
const targetRect = target.getBoundingClientRect();
|
|
46
|
+
const xOffset = event.clientX - targetRect.left;
|
|
47
|
+
const yOffset = event.clientY - targetRect.top;
|
|
48
|
+
|
|
49
|
+
const xRatio = round(xOffset / targetRect.width);
|
|
50
|
+
const yRatio = round(yOffset / targetRect.height);
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
x: xRatio,
|
|
54
|
+
y: yRatio,
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export const getInteractionPropertiesForEvent = (event: MouseEvent) => {
|
|
59
|
+
const target = event.target as HTMLElement | null;
|
|
60
|
+
const targetBuilderElement = target && findBuilderParent(target);
|
|
61
|
+
const builderId =
|
|
62
|
+
targetBuilderElement?.getAttribute('builder-id') ||
|
|
63
|
+
targetBuilderElement?.id;
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
targetBuilderElement: builderId || undefined,
|
|
67
|
+
metadata: {
|
|
68
|
+
targetOffset: target ? computeOffset({ event, target }) : undefined,
|
|
69
|
+
builderTargetOffset: targetBuilderElement
|
|
70
|
+
? computeOffset({ event, target: targetBuilderElement })
|
|
71
|
+
: undefined,
|
|
72
|
+
builderElementIndex:
|
|
73
|
+
targetBuilderElement && builderId
|
|
74
|
+
? ([] as Element[]).slice
|
|
75
|
+
.call(document.getElementsByClassName(builderId))
|
|
76
|
+
.indexOf(targetBuilderElement)
|
|
77
|
+
: undefined,
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -10,6 +10,6 @@ export * from './functions/register.js';
|
|
|
10
10
|
export * from './functions/set-editor-settings.js';
|
|
11
11
|
export * from './functions/get-content/index.js';
|
|
12
12
|
export * from './functions/get-builder-search-params/index.js';
|
|
13
|
-
export { track } from './functions/track';
|
|
13
|
+
export { track } from './functions/track/index.js';
|
|
14
14
|
export type { RegisteredComponent } from './context/types';
|
|
15
15
|
export type { ComponentInfo } from './types/components';
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
<script context="module"></script>
|
|
2
|
-
|
|
3
|
-
<script>import { setContext } from "svelte";
|
|
4
|
-
import BuilderContext from "../../context/builder.context.js";
|
|
5
|
-
import RenderComponent from "./render-component.svelte";
|
|
6
|
-
export let componentRef;
|
|
7
|
-
export let componentOptions;
|
|
8
|
-
export let blockChildren;
|
|
9
|
-
export let context;
|
|
10
|
-
setContext(BuilderContext.key, {
|
|
11
|
-
get content() {
|
|
12
|
-
return context.content;
|
|
13
|
-
},
|
|
14
|
-
get state() {
|
|
15
|
-
return context.state;
|
|
16
|
-
},
|
|
17
|
-
get context() {
|
|
18
|
-
return context.context;
|
|
19
|
-
},
|
|
20
|
-
get apiKey() {
|
|
21
|
-
return context.apiKey;
|
|
22
|
-
},
|
|
23
|
-
get registeredComponents() {
|
|
24
|
-
return context.registeredComponents;
|
|
25
|
-
},
|
|
26
|
-
get inheritedStyles() {
|
|
27
|
-
return context.inheritedStyles;
|
|
28
|
-
},
|
|
29
|
-
});
|
|
30
|
-
</script>
|
|
31
|
-
|
|
32
|
-
<RenderComponent {componentRef} {componentOptions} {blockChildren} {context} />
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { SvelteComponentTyped } from "svelte";
|
|
2
|
-
declare const __propDef: {
|
|
3
|
-
props: {
|
|
4
|
-
componentRef: RenderComponentProps;
|
|
5
|
-
componentOptions: RenderComponentProps;
|
|
6
|
-
blockChildren: RenderComponentProps;
|
|
7
|
-
context: RenderComponentProps;
|
|
8
|
-
};
|
|
9
|
-
events: {
|
|
10
|
-
[evt: string]: CustomEvent<any>;
|
|
11
|
-
};
|
|
12
|
-
slots: {};
|
|
13
|
-
};
|
|
14
|
-
export declare type RenderComponentWithContextProps = typeof __propDef.props;
|
|
15
|
-
export declare type RenderComponentWithContextEvents = typeof __propDef.events;
|
|
16
|
-
export declare type RenderComponentWithContextSlots = typeof __propDef.slots;
|
|
17
|
-
export default class RenderComponentWithContext extends SvelteComponentTyped<RenderComponentWithContextProps, RenderComponentWithContextEvents, RenderComponentWithContextSlots> {
|
|
18
|
-
}
|
|
19
|
-
export {};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
<script context="module" lang="ts">
|
|
2
|
-
import type { RenderComponentProps } from "./render-component";
|
|
3
|
-
</script>
|
|
4
|
-
|
|
5
|
-
<script lang="ts">
|
|
6
|
-
import { getContext, setContext } from "svelte";
|
|
7
|
-
|
|
8
|
-
import BuilderContext from "../../context/builder.context.js";
|
|
9
|
-
import RenderComponent from "./render-component.svelte";
|
|
10
|
-
|
|
11
|
-
export let componentRef: RenderComponentProps["componentRef"];
|
|
12
|
-
export let componentOptions: RenderComponentProps["componentOptions"];
|
|
13
|
-
export let blockChildren: RenderComponentProps["blockChildren"];
|
|
14
|
-
export let context: RenderComponentProps["context"];
|
|
15
|
-
|
|
16
|
-
setContext(BuilderContext.key, {
|
|
17
|
-
get content() {
|
|
18
|
-
return context.content;
|
|
19
|
-
},
|
|
20
|
-
get state() {
|
|
21
|
-
return context.state;
|
|
22
|
-
},
|
|
23
|
-
get context() {
|
|
24
|
-
return context.context;
|
|
25
|
-
},
|
|
26
|
-
get apiKey() {
|
|
27
|
-
return context.apiKey;
|
|
28
|
-
},
|
|
29
|
-
get registeredComponents() {
|
|
30
|
-
return context.registeredComponents;
|
|
31
|
-
},
|
|
32
|
-
get inheritedStyles() {
|
|
33
|
-
return context.inheritedStyles;
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
</script>
|
|
37
|
-
|
|
38
|
-
<RenderComponent {componentRef} {componentOptions} {blockChildren} {context} />
|