@builder.io/sdk-svelte 5.2.6 → 5.2.8
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/lib/browser/blocks/image/image.svelte +1 -1
- package/lib/browser/blocks/personalization-container/helpers.d.ts +2 -0
- package/lib/browser/blocks/personalization-container/helpers.js +30 -3
- package/lib/browser/components/content-variants/content-variants.svelte +4 -3
- package/lib/browser/components/content-variants/content-variants.svelte.d.ts +1 -1
- package/lib/browser/constants/sdk-version.d.ts +1 -1
- package/lib/browser/constants/sdk-version.js +1 -1
- package/lib/browser/types/components.d.ts +14 -0
- package/lib/edge/blocks/image/image.svelte +1 -1
- package/lib/edge/blocks/personalization-container/helpers.d.ts +2 -0
- package/lib/edge/blocks/personalization-container/helpers.js +30 -3
- package/lib/edge/components/content-variants/content-variants.svelte +4 -3
- package/lib/edge/components/content-variants/content-variants.svelte.d.ts +1 -1
- package/lib/edge/constants/sdk-version.d.ts +1 -1
- package/lib/edge/constants/sdk-version.js +1 -1
- package/lib/edge/types/components.d.ts +14 -0
- package/lib/node/blocks/image/image.svelte +1 -1
- package/lib/node/blocks/personalization-container/helpers.d.ts +2 -0
- package/lib/node/blocks/personalization-container/helpers.js +30 -3
- package/lib/node/components/content-variants/content-variants.svelte +4 -3
- package/lib/node/components/content-variants/content-variants.svelte.d.ts +1 -1
- package/lib/node/constants/sdk-version.d.ts +1 -1
- package/lib/node/constants/sdk-version.js +1 -1
- package/lib/node/types/components.d.ts +14 -0
- package/package.json +1 -1
- package/src/blocks/image/image.svelte +1 -1
- package/src/blocks/personalization-container/helpers.ts +31 -3
- package/src/components/content-variants/content-variants.svelte +6 -3
- package/src/constants/sdk-version.ts +1 -1
- package/src/types/components.ts +15 -0
|
@@ -84,7 +84,7 @@ onMount(() => { });
|
|
|
84
84
|
})}
|
|
85
85
|
loading={highPriority ? "eager" : "lazy"}
|
|
86
86
|
fetchpriority={highPriority ? "high" : "auto"}
|
|
87
|
-
alt={altText}
|
|
87
|
+
alt={altText || ""}
|
|
88
88
|
{title}
|
|
89
89
|
role={altText ? undefined : "presentation"}
|
|
90
90
|
class={"builder-image" + (className ? " " + className : "") + " img"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BuilderBlock } from '../../types/builder-block';
|
|
2
|
+
import type { BuilderContent } from '../../types/builder-content';
|
|
2
3
|
import type { Target } from '../../types/targets';
|
|
3
4
|
import type { PersonalizationContainerProps } from './personalization-container.types';
|
|
4
5
|
export declare const DEFAULT_INDEX = "default";
|
|
@@ -41,6 +42,7 @@ export declare function getBlocksToRender({ variants, previewingIndex, isHydrate
|
|
|
41
42
|
filteredVariants: PersonalizationContainerProps['variants'];
|
|
42
43
|
fallbackBlocks?: BuilderBlock[];
|
|
43
44
|
}): BlocksToRenderReturnType;
|
|
45
|
+
export declare const hasPersonalizationContainer: (content: BuilderContent | null | undefined) => boolean;
|
|
44
46
|
export declare const getInitPersonalizationVariantsFnsScriptString: () => string;
|
|
45
47
|
export declare const getPersonalizationScript: (variants: PersonalizationContainerProps['variants'], blockId: string, locale?: string) => string;
|
|
46
48
|
export declare const getUpdateVisibilityStylesScript: (variants: PersonalizationContainerProps['variants'], blockId: string, locale?: string) => string;
|
|
@@ -6,6 +6,7 @@ export const DEFAULT_INDEX = 'default';
|
|
|
6
6
|
const FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME = 'filterWithCustomTargeting';
|
|
7
7
|
const BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME = 'builderIoPersonalization';
|
|
8
8
|
const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'updateVisibilityStylesScript';
|
|
9
|
+
const PERSONALIZATION_CONTAINER_COMPONENT_NAME = 'PersonalizationContainer';
|
|
9
10
|
/**
|
|
10
11
|
* SDKs that support Variant Containers
|
|
11
12
|
*/
|
|
@@ -72,11 +73,37 @@ export function getBlocksToRender({ variants, previewingIndex, isHydrated, filte
|
|
|
72
73
|
// If no winning variant or we are on the server, return the default variant
|
|
73
74
|
return fallback;
|
|
74
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Walks the whole content rather than a known set of paths. A/B variation blocks live on
|
|
78
|
+
* `variations[*].data.blocks`, a sibling of `data.blocks`, and containers can sit inside columns,
|
|
79
|
+
* tabs, slots or inlined symbols. A missed container leaves the inlined fns undefined at parse
|
|
80
|
+
* time, so every variant renders at once.
|
|
81
|
+
*/
|
|
82
|
+
const containsPersonalizationContainer = (value) => {
|
|
83
|
+
if (Array.isArray(value)) {
|
|
84
|
+
return value.some(containsPersonalizationContainer);
|
|
85
|
+
}
|
|
86
|
+
if (!value || typeof value !== 'object')
|
|
87
|
+
return false;
|
|
88
|
+
if (value.component?.name === PERSONALIZATION_CONTAINER_COMPONENT_NAME) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
return Object.values(value).some(containsPersonalizationContainer);
|
|
92
|
+
};
|
|
93
|
+
export const hasPersonalizationContainer = (content) => containsPersonalizationContainer(content);
|
|
75
94
|
export const getInitPersonalizationVariantsFnsScriptString = () => {
|
|
76
95
|
return `
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
96
|
+
(function() {
|
|
97
|
+
if (!window.${FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME}) {
|
|
98
|
+
window.${FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME} = ${FILTER_WITH_CUSTOM_TARGETING_SCRIPT};
|
|
99
|
+
}
|
|
100
|
+
if (!window.${BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME}) {
|
|
101
|
+
window.${BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME} = ${PERSONALIZATION_SCRIPT};
|
|
102
|
+
}
|
|
103
|
+
if (!window.${UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME}) {
|
|
104
|
+
window.${UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME} = ${UPDATE_VISIBILITY_STYLES_SCRIPT};
|
|
105
|
+
}
|
|
106
|
+
})();
|
|
80
107
|
`;
|
|
81
108
|
};
|
|
82
109
|
const isHydrationTarget = TARGET === 'react';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
3
|
<script>import { onMount } from "svelte";
|
|
4
|
-
import { SDKS_SUPPORTING_PERSONALIZATION, getInitPersonalizationVariantsFnsScriptString, } from "../../blocks/personalization-container/helpers";
|
|
4
|
+
import { SDKS_SUPPORTING_PERSONALIZATION, getInitPersonalizationVariantsFnsScriptString, hasPersonalizationContainer, } from "../../blocks/personalization-container/helpers";
|
|
5
5
|
import { TARGET } from "../../constants/target";
|
|
6
6
|
import { handleABTestingSync } from "../../helpers/ab-tests";
|
|
7
7
|
import { getDefaultCanTrack } from "../../helpers/canTrack";
|
|
@@ -11,9 +11,9 @@ import InlinedStyles from "../inlined-styles.svelte";
|
|
|
11
11
|
import { checkShouldRenderVariants, getInitVariantsFnsScriptString, getUpdateCookieAndStylesScript, getVariants, } from "./helpers";
|
|
12
12
|
export let canTrack = undefined;
|
|
13
13
|
export let content;
|
|
14
|
-
export let isNestedRender = undefined;
|
|
15
14
|
export let nonce = undefined;
|
|
16
15
|
export let apiHost = undefined;
|
|
16
|
+
export let isNestedRender = undefined;
|
|
17
17
|
export let model;
|
|
18
18
|
export let data = undefined;
|
|
19
19
|
export let context = undefined;
|
|
@@ -54,6 +54,7 @@ let shouldRenderVariants = checkShouldRenderVariants({
|
|
|
54
54
|
canTrack: getDefaultCanTrack(canTrack),
|
|
55
55
|
content: content,
|
|
56
56
|
});
|
|
57
|
+
let shouldEmitPersonalizationFns = TARGET !== "reactNative" && hasPersonalizationContainer(content);
|
|
57
58
|
onMount(() => {
|
|
58
59
|
/**
|
|
59
60
|
* For Solid/Svelte: we unmount the non-winning variants post-hydration.
|
|
@@ -62,7 +63,7 @@ onMount(() => {
|
|
|
62
63
|
});
|
|
63
64
|
</script>
|
|
64
65
|
|
|
65
|
-
{#if
|
|
66
|
+
{#if shouldEmitPersonalizationFns}
|
|
66
67
|
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
67
68
|
<InlinedScript
|
|
68
69
|
id="builderio-init-personalization-variants-fns"
|
|
@@ -10,9 +10,9 @@ declare const __propDef: {
|
|
|
10
10
|
props: {
|
|
11
11
|
canTrack?: VariantsProviderProps["canTrack"];
|
|
12
12
|
content: VariantsProviderProps["content"];
|
|
13
|
-
isNestedRender?: VariantsProviderProps["isNestedRender"];
|
|
14
13
|
nonce?: VariantsProviderProps["nonce"];
|
|
15
14
|
apiHost?: VariantsProviderProps["apiHost"];
|
|
15
|
+
isNestedRender?: VariantsProviderProps["isNestedRender"];
|
|
16
16
|
model: VariantsProviderProps["model"];
|
|
17
17
|
data?: VariantsProviderProps["data"];
|
|
18
18
|
context?: VariantsProviderProps["context"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "5.2.
|
|
1
|
+
export declare const SDK_VERSION = "5.2.8";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "5.2.
|
|
1
|
+
export const SDK_VERSION = "5.2.8";
|
|
@@ -98,6 +98,20 @@ export interface ComponentInfo {
|
|
|
98
98
|
query?: any;
|
|
99
99
|
};
|
|
100
100
|
friendlyName?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Group custom components into their own accordion sections in the editor's insert menu.
|
|
103
|
+
* Components with the same `group` value are grouped together; components without a `group`
|
|
104
|
+
* (or with a blank value) fall back to the default "Custom Components" accordion.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```js
|
|
108
|
+
* Builder.registerComponent(MyStepComponent, {
|
|
109
|
+
* name: 'Step',
|
|
110
|
+
* group: 'Steps',
|
|
111
|
+
* })
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
group?: string;
|
|
101
115
|
/**
|
|
102
116
|
* Use to restrict access to your component based on a the current user permissions
|
|
103
117
|
* By default components will show to all users
|
|
@@ -84,7 +84,7 @@ onMount(() => { });
|
|
|
84
84
|
})}
|
|
85
85
|
loading={highPriority ? "eager" : "lazy"}
|
|
86
86
|
fetchpriority={highPriority ? "high" : "auto"}
|
|
87
|
-
alt={altText}
|
|
87
|
+
alt={altText || ""}
|
|
88
88
|
{title}
|
|
89
89
|
role={altText ? undefined : "presentation"}
|
|
90
90
|
class={"builder-image" + (className ? " " + className : "") + " img"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BuilderBlock } from '../../types/builder-block';
|
|
2
|
+
import type { BuilderContent } from '../../types/builder-content';
|
|
2
3
|
import type { Target } from '../../types/targets';
|
|
3
4
|
import type { PersonalizationContainerProps } from './personalization-container.types';
|
|
4
5
|
export declare const DEFAULT_INDEX = "default";
|
|
@@ -41,6 +42,7 @@ export declare function getBlocksToRender({ variants, previewingIndex, isHydrate
|
|
|
41
42
|
filteredVariants: PersonalizationContainerProps['variants'];
|
|
42
43
|
fallbackBlocks?: BuilderBlock[];
|
|
43
44
|
}): BlocksToRenderReturnType;
|
|
45
|
+
export declare const hasPersonalizationContainer: (content: BuilderContent | null | undefined) => boolean;
|
|
44
46
|
export declare const getInitPersonalizationVariantsFnsScriptString: () => string;
|
|
45
47
|
export declare const getPersonalizationScript: (variants: PersonalizationContainerProps['variants'], blockId: string, locale?: string) => string;
|
|
46
48
|
export declare const getUpdateVisibilityStylesScript: (variants: PersonalizationContainerProps['variants'], blockId: string, locale?: string) => string;
|
|
@@ -6,6 +6,7 @@ export const DEFAULT_INDEX = 'default';
|
|
|
6
6
|
const FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME = 'filterWithCustomTargeting';
|
|
7
7
|
const BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME = 'builderIoPersonalization';
|
|
8
8
|
const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'updateVisibilityStylesScript';
|
|
9
|
+
const PERSONALIZATION_CONTAINER_COMPONENT_NAME = 'PersonalizationContainer';
|
|
9
10
|
/**
|
|
10
11
|
* SDKs that support Variant Containers
|
|
11
12
|
*/
|
|
@@ -72,11 +73,37 @@ export function getBlocksToRender({ variants, previewingIndex, isHydrated, filte
|
|
|
72
73
|
// If no winning variant or we are on the server, return the default variant
|
|
73
74
|
return fallback;
|
|
74
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Walks the whole content rather than a known set of paths. A/B variation blocks live on
|
|
78
|
+
* `variations[*].data.blocks`, a sibling of `data.blocks`, and containers can sit inside columns,
|
|
79
|
+
* tabs, slots or inlined symbols. A missed container leaves the inlined fns undefined at parse
|
|
80
|
+
* time, so every variant renders at once.
|
|
81
|
+
*/
|
|
82
|
+
const containsPersonalizationContainer = (value) => {
|
|
83
|
+
if (Array.isArray(value)) {
|
|
84
|
+
return value.some(containsPersonalizationContainer);
|
|
85
|
+
}
|
|
86
|
+
if (!value || typeof value !== 'object')
|
|
87
|
+
return false;
|
|
88
|
+
if (value.component?.name === PERSONALIZATION_CONTAINER_COMPONENT_NAME) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
return Object.values(value).some(containsPersonalizationContainer);
|
|
92
|
+
};
|
|
93
|
+
export const hasPersonalizationContainer = (content) => containsPersonalizationContainer(content);
|
|
75
94
|
export const getInitPersonalizationVariantsFnsScriptString = () => {
|
|
76
95
|
return `
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
96
|
+
(function() {
|
|
97
|
+
if (!window.${FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME}) {
|
|
98
|
+
window.${FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME} = ${FILTER_WITH_CUSTOM_TARGETING_SCRIPT};
|
|
99
|
+
}
|
|
100
|
+
if (!window.${BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME}) {
|
|
101
|
+
window.${BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME} = ${PERSONALIZATION_SCRIPT};
|
|
102
|
+
}
|
|
103
|
+
if (!window.${UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME}) {
|
|
104
|
+
window.${UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME} = ${UPDATE_VISIBILITY_STYLES_SCRIPT};
|
|
105
|
+
}
|
|
106
|
+
})();
|
|
80
107
|
`;
|
|
81
108
|
};
|
|
82
109
|
const isHydrationTarget = TARGET === 'react';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
3
|
<script>import { onMount } from "svelte";
|
|
4
|
-
import { SDKS_SUPPORTING_PERSONALIZATION, getInitPersonalizationVariantsFnsScriptString, } from "../../blocks/personalization-container/helpers";
|
|
4
|
+
import { SDKS_SUPPORTING_PERSONALIZATION, getInitPersonalizationVariantsFnsScriptString, hasPersonalizationContainer, } from "../../blocks/personalization-container/helpers";
|
|
5
5
|
import { TARGET } from "../../constants/target";
|
|
6
6
|
import { handleABTestingSync } from "../../helpers/ab-tests";
|
|
7
7
|
import { getDefaultCanTrack } from "../../helpers/canTrack";
|
|
@@ -11,9 +11,9 @@ import InlinedStyles from "../inlined-styles.svelte";
|
|
|
11
11
|
import { checkShouldRenderVariants, getInitVariantsFnsScriptString, getUpdateCookieAndStylesScript, getVariants, } from "./helpers";
|
|
12
12
|
export let canTrack = undefined;
|
|
13
13
|
export let content;
|
|
14
|
-
export let isNestedRender = undefined;
|
|
15
14
|
export let nonce = undefined;
|
|
16
15
|
export let apiHost = undefined;
|
|
16
|
+
export let isNestedRender = undefined;
|
|
17
17
|
export let model;
|
|
18
18
|
export let data = undefined;
|
|
19
19
|
export let context = undefined;
|
|
@@ -54,6 +54,7 @@ let shouldRenderVariants = checkShouldRenderVariants({
|
|
|
54
54
|
canTrack: getDefaultCanTrack(canTrack),
|
|
55
55
|
content: content,
|
|
56
56
|
});
|
|
57
|
+
let shouldEmitPersonalizationFns = TARGET !== "reactNative" && hasPersonalizationContainer(content);
|
|
57
58
|
onMount(() => {
|
|
58
59
|
/**
|
|
59
60
|
* For Solid/Svelte: we unmount the non-winning variants post-hydration.
|
|
@@ -62,7 +63,7 @@ onMount(() => {
|
|
|
62
63
|
});
|
|
63
64
|
</script>
|
|
64
65
|
|
|
65
|
-
{#if
|
|
66
|
+
{#if shouldEmitPersonalizationFns}
|
|
66
67
|
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
67
68
|
<InlinedScript
|
|
68
69
|
id="builderio-init-personalization-variants-fns"
|
|
@@ -10,9 +10,9 @@ declare const __propDef: {
|
|
|
10
10
|
props: {
|
|
11
11
|
canTrack?: VariantsProviderProps["canTrack"];
|
|
12
12
|
content: VariantsProviderProps["content"];
|
|
13
|
-
isNestedRender?: VariantsProviderProps["isNestedRender"];
|
|
14
13
|
nonce?: VariantsProviderProps["nonce"];
|
|
15
14
|
apiHost?: VariantsProviderProps["apiHost"];
|
|
15
|
+
isNestedRender?: VariantsProviderProps["isNestedRender"];
|
|
16
16
|
model: VariantsProviderProps["model"];
|
|
17
17
|
data?: VariantsProviderProps["data"];
|
|
18
18
|
context?: VariantsProviderProps["context"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "5.2.
|
|
1
|
+
export declare const SDK_VERSION = "5.2.8";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "5.2.
|
|
1
|
+
export const SDK_VERSION = "5.2.8";
|
|
@@ -98,6 +98,20 @@ export interface ComponentInfo {
|
|
|
98
98
|
query?: any;
|
|
99
99
|
};
|
|
100
100
|
friendlyName?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Group custom components into their own accordion sections in the editor's insert menu.
|
|
103
|
+
* Components with the same `group` value are grouped together; components without a `group`
|
|
104
|
+
* (or with a blank value) fall back to the default "Custom Components" accordion.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```js
|
|
108
|
+
* Builder.registerComponent(MyStepComponent, {
|
|
109
|
+
* name: 'Step',
|
|
110
|
+
* group: 'Steps',
|
|
111
|
+
* })
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
group?: string;
|
|
101
115
|
/**
|
|
102
116
|
* Use to restrict access to your component based on a the current user permissions
|
|
103
117
|
* By default components will show to all users
|
|
@@ -84,7 +84,7 @@ onMount(() => { });
|
|
|
84
84
|
})}
|
|
85
85
|
loading={highPriority ? "eager" : "lazy"}
|
|
86
86
|
fetchpriority={highPriority ? "high" : "auto"}
|
|
87
|
-
alt={altText}
|
|
87
|
+
alt={altText || ""}
|
|
88
88
|
{title}
|
|
89
89
|
role={altText ? undefined : "presentation"}
|
|
90
90
|
class={"builder-image" + (className ? " " + className : "") + " img"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BuilderBlock } from '../../types/builder-block';
|
|
2
|
+
import type { BuilderContent } from '../../types/builder-content';
|
|
2
3
|
import type { Target } from '../../types/targets';
|
|
3
4
|
import type { PersonalizationContainerProps } from './personalization-container.types';
|
|
4
5
|
export declare const DEFAULT_INDEX = "default";
|
|
@@ -41,6 +42,7 @@ export declare function getBlocksToRender({ variants, previewingIndex, isHydrate
|
|
|
41
42
|
filteredVariants: PersonalizationContainerProps['variants'];
|
|
42
43
|
fallbackBlocks?: BuilderBlock[];
|
|
43
44
|
}): BlocksToRenderReturnType;
|
|
45
|
+
export declare const hasPersonalizationContainer: (content: BuilderContent | null | undefined) => boolean;
|
|
44
46
|
export declare const getInitPersonalizationVariantsFnsScriptString: () => string;
|
|
45
47
|
export declare const getPersonalizationScript: (variants: PersonalizationContainerProps['variants'], blockId: string, locale?: string) => string;
|
|
46
48
|
export declare const getUpdateVisibilityStylesScript: (variants: PersonalizationContainerProps['variants'], blockId: string, locale?: string) => string;
|
|
@@ -6,6 +6,7 @@ export const DEFAULT_INDEX = 'default';
|
|
|
6
6
|
const FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME = 'filterWithCustomTargeting';
|
|
7
7
|
const BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME = 'builderIoPersonalization';
|
|
8
8
|
const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'updateVisibilityStylesScript';
|
|
9
|
+
const PERSONALIZATION_CONTAINER_COMPONENT_NAME = 'PersonalizationContainer';
|
|
9
10
|
/**
|
|
10
11
|
* SDKs that support Variant Containers
|
|
11
12
|
*/
|
|
@@ -72,11 +73,37 @@ export function getBlocksToRender({ variants, previewingIndex, isHydrated, filte
|
|
|
72
73
|
// If no winning variant or we are on the server, return the default variant
|
|
73
74
|
return fallback;
|
|
74
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Walks the whole content rather than a known set of paths. A/B variation blocks live on
|
|
78
|
+
* `variations[*].data.blocks`, a sibling of `data.blocks`, and containers can sit inside columns,
|
|
79
|
+
* tabs, slots or inlined symbols. A missed container leaves the inlined fns undefined at parse
|
|
80
|
+
* time, so every variant renders at once.
|
|
81
|
+
*/
|
|
82
|
+
const containsPersonalizationContainer = (value) => {
|
|
83
|
+
if (Array.isArray(value)) {
|
|
84
|
+
return value.some(containsPersonalizationContainer);
|
|
85
|
+
}
|
|
86
|
+
if (!value || typeof value !== 'object')
|
|
87
|
+
return false;
|
|
88
|
+
if (value.component?.name === PERSONALIZATION_CONTAINER_COMPONENT_NAME) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
return Object.values(value).some(containsPersonalizationContainer);
|
|
92
|
+
};
|
|
93
|
+
export const hasPersonalizationContainer = (content) => containsPersonalizationContainer(content);
|
|
75
94
|
export const getInitPersonalizationVariantsFnsScriptString = () => {
|
|
76
95
|
return `
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
96
|
+
(function() {
|
|
97
|
+
if (!window.${FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME}) {
|
|
98
|
+
window.${FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME} = ${FILTER_WITH_CUSTOM_TARGETING_SCRIPT};
|
|
99
|
+
}
|
|
100
|
+
if (!window.${BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME}) {
|
|
101
|
+
window.${BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME} = ${PERSONALIZATION_SCRIPT};
|
|
102
|
+
}
|
|
103
|
+
if (!window.${UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME}) {
|
|
104
|
+
window.${UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME} = ${UPDATE_VISIBILITY_STYLES_SCRIPT};
|
|
105
|
+
}
|
|
106
|
+
})();
|
|
80
107
|
`;
|
|
81
108
|
};
|
|
82
109
|
const isHydrationTarget = TARGET === 'react';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
3
|
<script>import { onMount } from "svelte";
|
|
4
|
-
import { SDKS_SUPPORTING_PERSONALIZATION, getInitPersonalizationVariantsFnsScriptString, } from "../../blocks/personalization-container/helpers";
|
|
4
|
+
import { SDKS_SUPPORTING_PERSONALIZATION, getInitPersonalizationVariantsFnsScriptString, hasPersonalizationContainer, } from "../../blocks/personalization-container/helpers";
|
|
5
5
|
import { TARGET } from "../../constants/target";
|
|
6
6
|
import { handleABTestingSync } from "../../helpers/ab-tests";
|
|
7
7
|
import { getDefaultCanTrack } from "../../helpers/canTrack";
|
|
@@ -11,9 +11,9 @@ import InlinedStyles from "../inlined-styles.svelte";
|
|
|
11
11
|
import { checkShouldRenderVariants, getInitVariantsFnsScriptString, getUpdateCookieAndStylesScript, getVariants, } from "./helpers";
|
|
12
12
|
export let canTrack = undefined;
|
|
13
13
|
export let content;
|
|
14
|
-
export let isNestedRender = undefined;
|
|
15
14
|
export let nonce = undefined;
|
|
16
15
|
export let apiHost = undefined;
|
|
16
|
+
export let isNestedRender = undefined;
|
|
17
17
|
export let model;
|
|
18
18
|
export let data = undefined;
|
|
19
19
|
export let context = undefined;
|
|
@@ -54,6 +54,7 @@ let shouldRenderVariants = checkShouldRenderVariants({
|
|
|
54
54
|
canTrack: getDefaultCanTrack(canTrack),
|
|
55
55
|
content: content,
|
|
56
56
|
});
|
|
57
|
+
let shouldEmitPersonalizationFns = TARGET !== "reactNative" && hasPersonalizationContainer(content);
|
|
57
58
|
onMount(() => {
|
|
58
59
|
/**
|
|
59
60
|
* For Solid/Svelte: we unmount the non-winning variants post-hydration.
|
|
@@ -62,7 +63,7 @@ onMount(() => {
|
|
|
62
63
|
});
|
|
63
64
|
</script>
|
|
64
65
|
|
|
65
|
-
{#if
|
|
66
|
+
{#if shouldEmitPersonalizationFns}
|
|
66
67
|
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
67
68
|
<InlinedScript
|
|
68
69
|
id="builderio-init-personalization-variants-fns"
|
|
@@ -10,9 +10,9 @@ declare const __propDef: {
|
|
|
10
10
|
props: {
|
|
11
11
|
canTrack?: VariantsProviderProps["canTrack"];
|
|
12
12
|
content: VariantsProviderProps["content"];
|
|
13
|
-
isNestedRender?: VariantsProviderProps["isNestedRender"];
|
|
14
13
|
nonce?: VariantsProviderProps["nonce"];
|
|
15
14
|
apiHost?: VariantsProviderProps["apiHost"];
|
|
15
|
+
isNestedRender?: VariantsProviderProps["isNestedRender"];
|
|
16
16
|
model: VariantsProviderProps["model"];
|
|
17
17
|
data?: VariantsProviderProps["data"];
|
|
18
18
|
context?: VariantsProviderProps["context"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "5.2.
|
|
1
|
+
export declare const SDK_VERSION = "5.2.8";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "5.2.
|
|
1
|
+
export const SDK_VERSION = "5.2.8";
|
|
@@ -98,6 +98,20 @@ export interface ComponentInfo {
|
|
|
98
98
|
query?: any;
|
|
99
99
|
};
|
|
100
100
|
friendlyName?: string;
|
|
101
|
+
/**
|
|
102
|
+
* Group custom components into their own accordion sections in the editor's insert menu.
|
|
103
|
+
* Components with the same `group` value are grouped together; components without a `group`
|
|
104
|
+
* (or with a blank value) fall back to the default "Custom Components" accordion.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```js
|
|
108
|
+
* Builder.registerComponent(MyStepComponent, {
|
|
109
|
+
* name: 'Step',
|
|
110
|
+
* group: 'Steps',
|
|
111
|
+
* })
|
|
112
|
+
* ```
|
|
113
|
+
*/
|
|
114
|
+
group?: string;
|
|
101
115
|
/**
|
|
102
116
|
* Use to restrict access to your component based on a the current user permissions
|
|
103
117
|
* By default components will show to all users
|
package/package.json
CHANGED
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
})}
|
|
94
94
|
loading={highPriority ? "eager" : "lazy"}
|
|
95
95
|
fetchpriority={highPriority ? "high" : "auto"}
|
|
96
|
-
alt={altText}
|
|
96
|
+
alt={altText || ""}
|
|
97
97
|
{title}
|
|
98
98
|
role={altText ? undefined : "presentation"}
|
|
99
99
|
class={"builder-image" + (className ? " " + className : "") + " img"}
|
|
@@ -2,6 +2,7 @@ import { TARGET } from '../../constants/target';
|
|
|
2
2
|
import { isBrowser } from '../../functions/is-browser';
|
|
3
3
|
import { isEditing } from '../../functions/is-editing';
|
|
4
4
|
import type { BuilderBlock } from '../../types/builder-block';
|
|
5
|
+
import type { BuilderContent } from '../../types/builder-content';
|
|
5
6
|
import type { Target } from '../../types/targets';
|
|
6
7
|
import { FILTER_WITH_CUSTOM_TARGETING_SCRIPT, PERSONALIZATION_SCRIPT, UPDATE_VISIBILITY_STYLES_SCRIPT } from './helpers/inlined-fns';
|
|
7
8
|
import type { PersonalizationContainerProps } from './personalization-container.types';
|
|
@@ -9,6 +10,7 @@ export const DEFAULT_INDEX = 'default';
|
|
|
9
10
|
const FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME = 'filterWithCustomTargeting';
|
|
10
11
|
const BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME = 'builderIoPersonalization';
|
|
11
12
|
const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'updateVisibilityStylesScript';
|
|
13
|
+
const PERSONALIZATION_CONTAINER_COMPONENT_NAME = 'PersonalizationContainer';
|
|
12
14
|
export type UserAttributes = {
|
|
13
15
|
date?: string | Date;
|
|
14
16
|
urlPath?: string;
|
|
@@ -103,11 +105,37 @@ export function getBlocksToRender({
|
|
|
103
105
|
// If no winning variant or we are on the server, return the default variant
|
|
104
106
|
return fallback;
|
|
105
107
|
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Walks the whole content rather than a known set of paths. A/B variation blocks live on
|
|
111
|
+
* `variations[*].data.blocks`, a sibling of `data.blocks`, and containers can sit inside columns,
|
|
112
|
+
* tabs, slots or inlined symbols. A missed container leaves the inlined fns undefined at parse
|
|
113
|
+
* time, so every variant renders at once.
|
|
114
|
+
*/
|
|
115
|
+
const containsPersonalizationContainer = (value: unknown): boolean => {
|
|
116
|
+
if (Array.isArray(value)) {
|
|
117
|
+
return value.some(containsPersonalizationContainer);
|
|
118
|
+
}
|
|
119
|
+
if (!value || typeof value !== 'object') return false;
|
|
120
|
+
if ((value as BuilderBlock).component?.name === PERSONALIZATION_CONTAINER_COMPONENT_NAME) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
return Object.values(value).some(containsPersonalizationContainer);
|
|
124
|
+
};
|
|
125
|
+
export const hasPersonalizationContainer = (content: BuilderContent | null | undefined) => containsPersonalizationContainer(content);
|
|
106
126
|
export const getInitPersonalizationVariantsFnsScriptString = () => {
|
|
107
127
|
return `
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
128
|
+
(function() {
|
|
129
|
+
if (!window.${FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME}) {
|
|
130
|
+
window.${FILTER_WITH_CUSTOM_TARGETING_SCRIPT_FN_NAME} = ${FILTER_WITH_CUSTOM_TARGETING_SCRIPT};
|
|
131
|
+
}
|
|
132
|
+
if (!window.${BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME}) {
|
|
133
|
+
window.${BUILDER_IO_PERSONALIZATION_SCRIPT_FN_NAME} = ${PERSONALIZATION_SCRIPT};
|
|
134
|
+
}
|
|
135
|
+
if (!window.${UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME}) {
|
|
136
|
+
window.${UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME} = ${UPDATE_VISIBILITY_STYLES_SCRIPT};
|
|
137
|
+
}
|
|
138
|
+
})();
|
|
111
139
|
`;
|
|
112
140
|
};
|
|
113
141
|
const isHydrationTarget = TARGET === 'react';
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
import {
|
|
14
14
|
SDKS_SUPPORTING_PERSONALIZATION,
|
|
15
15
|
getInitPersonalizationVariantsFnsScriptString,
|
|
16
|
+
hasPersonalizationContainer,
|
|
16
17
|
} from "../../blocks/personalization-container/helpers";
|
|
17
18
|
import { TARGET } from "../../constants/target";
|
|
18
19
|
import { handleABTestingSync } from "../../helpers/ab-tests";
|
|
@@ -30,10 +31,10 @@
|
|
|
30
31
|
|
|
31
32
|
export let canTrack: VariantsProviderProps["canTrack"] = undefined;
|
|
32
33
|
export let content: VariantsProviderProps["content"];
|
|
33
|
-
export let isNestedRender: VariantsProviderProps["isNestedRender"] =
|
|
34
|
-
undefined;
|
|
35
34
|
export let nonce: VariantsProviderProps["nonce"] = undefined;
|
|
36
35
|
export let apiHost: VariantsProviderProps["apiHost"] = undefined;
|
|
36
|
+
export let isNestedRender: VariantsProviderProps["isNestedRender"] =
|
|
37
|
+
undefined;
|
|
37
38
|
export let model: VariantsProviderProps["model"];
|
|
38
39
|
export let data: VariantsProviderProps["data"] = undefined;
|
|
39
40
|
export let context: VariantsProviderProps["context"] = undefined;
|
|
@@ -83,6 +84,8 @@
|
|
|
83
84
|
canTrack: getDefaultCanTrack(canTrack),
|
|
84
85
|
content: content,
|
|
85
86
|
});
|
|
87
|
+
let shouldEmitPersonalizationFns =
|
|
88
|
+
TARGET !== "reactNative" && hasPersonalizationContainer(content);
|
|
86
89
|
|
|
87
90
|
onMount(() => {
|
|
88
91
|
/**
|
|
@@ -92,7 +95,7 @@
|
|
|
92
95
|
});
|
|
93
96
|
</script>
|
|
94
97
|
|
|
95
|
-
{#if
|
|
98
|
+
{#if shouldEmitPersonalizationFns}
|
|
96
99
|
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
97
100
|
<InlinedScript
|
|
98
101
|
id="builderio-init-personalization-variants-fns"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "5.2.
|
|
1
|
+
export const SDK_VERSION = "5.2.8"
|
package/src/types/components.ts
CHANGED
|
@@ -106,6 +106,21 @@ export interface ComponentInfo {
|
|
|
106
106
|
};
|
|
107
107
|
friendlyName?: string;
|
|
108
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Group custom components into their own accordion sections in the editor's insert menu.
|
|
111
|
+
* Components with the same `group` value are grouped together; components without a `group`
|
|
112
|
+
* (or with a blank value) fall back to the default "Custom Components" accordion.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```js
|
|
116
|
+
* Builder.registerComponent(MyStepComponent, {
|
|
117
|
+
* name: 'Step',
|
|
118
|
+
* group: 'Steps',
|
|
119
|
+
* })
|
|
120
|
+
* ```
|
|
121
|
+
*/
|
|
122
|
+
group?: string;
|
|
123
|
+
|
|
109
124
|
/**
|
|
110
125
|
* Use to restrict access to your component based on a the current user permissions
|
|
111
126
|
* By default components will show to all users
|