@builder.io/sdk-svelte 5.3.0 → 5.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/blocks/symbol/symbol.helpers.d.ts +1 -0
- package/lib/browser/blocks/symbol/symbol.helpers.js +6 -0
- package/lib/browser/blocks/symbol/symbol.svelte +5 -1
- package/lib/browser/components/builder-scripts.svelte +39 -0
- package/lib/browser/components/builder-scripts.svelte.d.ts +22 -0
- package/lib/browser/components/content-variants/content-variants.svelte +15 -8
- package/lib/browser/components/content-variants/content-variants.svelte.d.ts +5 -0
- package/lib/browser/components/content-variants/helpers.d.ts +6 -0
- package/lib/browser/components/content-variants/helpers.js +5 -0
- package/lib/browser/constants/sdk-version.d.ts +1 -1
- package/lib/browser/constants/sdk-version.js +1 -1
- package/lib/browser/context/builder-scripts.context.d.ts +7 -0
- package/lib/browser/context/builder-scripts.context.js +5 -0
- package/lib/browser/index-helpers/blocks-exports.d.ts +1 -0
- package/lib/browser/index-helpers/blocks-exports.js +1 -0
- package/lib/edge/blocks/symbol/symbol.helpers.d.ts +1 -0
- package/lib/edge/blocks/symbol/symbol.helpers.js +6 -0
- package/lib/edge/blocks/symbol/symbol.svelte +5 -1
- package/lib/edge/components/builder-scripts.svelte +39 -0
- package/lib/edge/components/builder-scripts.svelte.d.ts +22 -0
- package/lib/edge/components/content-variants/content-variants.svelte +15 -8
- package/lib/edge/components/content-variants/content-variants.svelte.d.ts +5 -0
- package/lib/edge/components/content-variants/helpers.d.ts +6 -0
- package/lib/edge/components/content-variants/helpers.js +5 -0
- package/lib/edge/constants/sdk-version.d.ts +1 -1
- package/lib/edge/constants/sdk-version.js +1 -1
- package/lib/edge/context/builder-scripts.context.d.ts +7 -0
- package/lib/edge/context/builder-scripts.context.js +5 -0
- package/lib/edge/index-helpers/blocks-exports.d.ts +1 -0
- package/lib/edge/index-helpers/blocks-exports.js +1 -0
- package/lib/node/blocks/symbol/symbol.helpers.d.ts +1 -0
- package/lib/node/blocks/symbol/symbol.helpers.js +6 -0
- package/lib/node/blocks/symbol/symbol.svelte +5 -1
- package/lib/node/components/builder-scripts.svelte +39 -0
- package/lib/node/components/builder-scripts.svelte.d.ts +22 -0
- package/lib/node/components/content-variants/content-variants.svelte +15 -8
- package/lib/node/components/content-variants/content-variants.svelte.d.ts +5 -0
- package/lib/node/components/content-variants/helpers.d.ts +6 -0
- package/lib/node/components/content-variants/helpers.js +5 -0
- package/lib/node/constants/sdk-version.d.ts +1 -1
- package/lib/node/constants/sdk-version.js +1 -1
- package/lib/node/context/builder-scripts.context.d.ts +7 -0
- package/lib/node/context/builder-scripts.context.js +5 -0
- package/lib/node/index-helpers/blocks-exports.d.ts +1 -0
- package/lib/node/index-helpers/blocks-exports.js +1 -0
- package/package.json +1 -1
- package/src/blocks/symbol/symbol.helpers.ts +7 -0
- package/src/blocks/symbol/symbol.svelte +8 -1
- package/src/components/builder-scripts.svelte +57 -0
- package/src/components/content-variants/content-variants.svelte +21 -8
- package/src/components/content-variants/helpers.ts +6 -0
- package/src/constants/sdk-version.ts +1 -1
- package/src/context/builder-scripts.context.ts +6 -0
- package/src/index-helpers/blocks-exports.ts +1 -0
|
@@ -10,6 +10,7 @@ export interface SymbolInfo {
|
|
|
10
10
|
ownerId?: string;
|
|
11
11
|
global?: boolean;
|
|
12
12
|
}
|
|
13
|
+
export declare const isSymbolContentInlinedInParent: (symbol: SymbolInfo | undefined, bindings: Record<string, string> | undefined) => boolean;
|
|
13
14
|
export declare const fetchSymbolContent: ({ builderContextValue, symbol }: {
|
|
14
15
|
symbol: SymbolInfo | undefined;
|
|
15
16
|
builderContextValue: BuilderContextInterface;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { fetchOneEntry } from '../../functions/get-content/index';
|
|
2
2
|
import { logger } from '../../helpers/logger';
|
|
3
|
+
const isSymbolContentBinding = (key) => {
|
|
4
|
+
const path = key.startsWith('component.') ? key.slice(10) : key;
|
|
5
|
+
return path === 'options.symbol' || path === 'options.symbol.content' || path.startsWith('options.symbol.content.');
|
|
6
|
+
};
|
|
7
|
+
// Bound symbol content is evaluated at render time, so it is not in the parent content JSON.
|
|
8
|
+
export const isSymbolContentInlinedInParent = (symbol, bindings) => !!symbol?.content && !Object.keys(bindings || {}).some(isSymbolContentBinding);
|
|
3
9
|
export const fetchSymbolContent = async ({ builderContextValue, symbol }) => {
|
|
4
10
|
/**
|
|
5
11
|
* If:
|
|
@@ -4,7 +4,7 @@ import { filterAttrs } from "../helpers";
|
|
|
4
4
|
import "../../components/dynamic-div.svelte";
|
|
5
5
|
import { getClassPropName } from "../../functions/get-class-prop-name";
|
|
6
6
|
import { setAttrs } from "../helpers";
|
|
7
|
-
import { fetchSymbolContent } from "./symbol.helpers";
|
|
7
|
+
import { fetchSymbolContent, isSymbolContentInlinedInParent, } from "./symbol.helpers";
|
|
8
8
|
export let symbol = undefined;
|
|
9
9
|
export let builderComponents;
|
|
10
10
|
export let attributes = undefined;
|
|
@@ -64,6 +64,10 @@ $: onUpdateFn_0(...[symbol]);
|
|
|
64
64
|
<ContentVariants
|
|
65
65
|
nonce={$builderContext.nonce}
|
|
66
66
|
isNestedRender={true}
|
|
67
|
+
isContentInlinedInParent={isSymbolContentInlinedInParent(
|
|
68
|
+
symbol,
|
|
69
|
+
builderBlock?.bindings
|
|
70
|
+
)}
|
|
67
71
|
apiVersion={$builderContext.apiVersion}
|
|
68
72
|
apiKey={symbol?.global && symbol?.ownerId
|
|
69
73
|
? symbol.ownerId
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script context="module">/**
|
|
2
|
+
* Emits the Variant Container and A/B test helper scripts once for all `Content` components inside it.
|
|
3
|
+
*/
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<script>import { getContext, setContext } from "svelte";
|
|
7
|
+
import { getInitPersonalizationVariantsFnsScriptString, SDKS_SUPPORTING_PERSONALIZATION, } from "../blocks/personalization-container/helpers";
|
|
8
|
+
import { TARGET } from "../constants/target";
|
|
9
|
+
import BuilderScriptsContext from "../context/builder-scripts.context";
|
|
10
|
+
import { isBrowser } from "../functions/is-browser";
|
|
11
|
+
import { getInitVariantsFnsScriptString, SDKS_SUPPORTING_BUILDER_SCRIPTS, } from "./content-variants/helpers";
|
|
12
|
+
import InlinedScript from "./inlined-script.svelte";
|
|
13
|
+
export let nonce = undefined;
|
|
14
|
+
let parentScriptsContext = getContext(BuilderScriptsContext.key);
|
|
15
|
+
let isSupported = SDKS_SUPPORTING_BUILDER_SCRIPTS.includes(TARGET);
|
|
16
|
+
let shouldRenderAbTestFns = TARGET !== "react" || !isBrowser();
|
|
17
|
+
setContext(BuilderScriptsContext.key, {
|
|
18
|
+
scriptsEmitted: isSupported,
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
{#if isSupported && !parentScriptsContext?.scriptsEmitted}
|
|
23
|
+
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
24
|
+
<InlinedScript
|
|
25
|
+
id="builderio-init-personalization-variants-fns"
|
|
26
|
+
nonce={nonce || ""}
|
|
27
|
+
scriptStr={getInitPersonalizationVariantsFnsScriptString()}
|
|
28
|
+
/>
|
|
29
|
+
{/if}
|
|
30
|
+
|
|
31
|
+
{#if shouldRenderAbTestFns}
|
|
32
|
+
<InlinedScript
|
|
33
|
+
id="builderio-init-variants-fns"
|
|
34
|
+
nonce={nonce || ""}
|
|
35
|
+
scriptStr={getInitVariantsFnsScriptString()}
|
|
36
|
+
/>
|
|
37
|
+
{/if}
|
|
38
|
+
{/if}
|
|
39
|
+
<slot />
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
type BuilderScriptsProps = {
|
|
3
|
+
nonce?: string;
|
|
4
|
+
children?: any;
|
|
5
|
+
};
|
|
6
|
+
declare const __propDef: {
|
|
7
|
+
props: {
|
|
8
|
+
nonce?: BuilderScriptsProps["nonce"];
|
|
9
|
+
};
|
|
10
|
+
events: {
|
|
11
|
+
[evt: string]: CustomEvent<any>;
|
|
12
|
+
};
|
|
13
|
+
slots: {
|
|
14
|
+
default: {};
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
type BuilderScriptsProps_ = typeof __propDef.props;
|
|
18
|
+
export { BuilderScriptsProps_ as BuilderScriptsProps };
|
|
19
|
+
export type BuilderScriptsEvents = typeof __propDef.events;
|
|
20
|
+
export type BuilderScriptsSlots = typeof __propDef.slots;
|
|
21
|
+
export default class BuilderScripts extends SvelteComponent<BuilderScriptsProps, BuilderScriptsEvents, BuilderScriptsSlots> {
|
|
22
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
|
-
<script>import { onMount } from "svelte";
|
|
3
|
+
<script>import { getContext, onMount } from "svelte";
|
|
4
4
|
import { SDKS_SUPPORTING_PERSONALIZATION, getInitPersonalizationVariantsFnsScriptString, hasPersonalizationContainer, } from "../../blocks/personalization-container/helpers";
|
|
5
5
|
import { TARGET } from "../../constants/target";
|
|
6
|
+
import BuilderScriptsContext from "../../context/builder-scripts.context";
|
|
6
7
|
import { handleABTestingSync } from "../../helpers/ab-tests";
|
|
7
8
|
import { getDefaultCanTrack } from "../../helpers/canTrack";
|
|
8
9
|
import ContentComponent from "../content/content.svelte";
|
|
@@ -11,6 +12,7 @@ import InlinedStyles from "../inlined-styles.svelte";
|
|
|
11
12
|
import { checkShouldRenderVariants, getInitVariantsFnsScriptString, getUpdateCookieAndStylesScript, getVariants, } from "./helpers";
|
|
12
13
|
export let canTrack = undefined;
|
|
13
14
|
export let content;
|
|
15
|
+
export let isContentInlinedInParent = undefined;
|
|
14
16
|
export let nonce = undefined;
|
|
15
17
|
export let apiHost = undefined;
|
|
16
18
|
export let isNestedRender = undefined;
|
|
@@ -29,6 +31,7 @@ export let blocksWrapperProps = undefined;
|
|
|
29
31
|
export let contentWrapper = undefined;
|
|
30
32
|
export let contentWrapperProps = undefined;
|
|
31
33
|
export let trustedHosts = undefined;
|
|
34
|
+
let scriptsContext = getContext(BuilderScriptsContext.key);
|
|
32
35
|
$: updateCookieAndStylesScriptStr = () => {
|
|
33
36
|
return getUpdateCookieAndStylesScript(getVariants(content).map((value) => ({
|
|
34
37
|
id: value.testVariationId,
|
|
@@ -55,7 +58,9 @@ let shouldRenderVariants = checkShouldRenderVariants({
|
|
|
55
58
|
canTrack: getDefaultCanTrack(canTrack),
|
|
56
59
|
content: content,
|
|
57
60
|
});
|
|
58
|
-
let shouldEmitPersonalizationFns = TARGET !== "reactNative" &&
|
|
61
|
+
let shouldEmitPersonalizationFns = TARGET !== "reactNative" &&
|
|
62
|
+
!isContentInlinedInParent &&
|
|
63
|
+
hasPersonalizationContainer(content);
|
|
59
64
|
onMount(() => {
|
|
60
65
|
/**
|
|
61
66
|
* For Solid/Svelte: we unmount the non-winning variants post-hydration.
|
|
@@ -64,7 +69,7 @@ onMount(() => {
|
|
|
64
69
|
});
|
|
65
70
|
</script>
|
|
66
71
|
|
|
67
|
-
{#if shouldEmitPersonalizationFns}
|
|
72
|
+
{#if shouldEmitPersonalizationFns && !!!scriptsContext?.scriptsEmitted}
|
|
68
73
|
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
69
74
|
<InlinedScript
|
|
70
75
|
id="builderio-init-personalization-variants-fns"
|
|
@@ -75,11 +80,13 @@ onMount(() => {
|
|
|
75
80
|
{/if}
|
|
76
81
|
|
|
77
82
|
{#if shouldRenderVariants}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
{#if !!!scriptsContext?.scriptsEmitted}
|
|
84
|
+
<InlinedScript
|
|
85
|
+
id="builderio-init-variants-fns"
|
|
86
|
+
scriptStr={getInitVariantsFnsScriptString()}
|
|
87
|
+
nonce={nonce || ""}
|
|
88
|
+
/>
|
|
89
|
+
{/if}
|
|
83
90
|
<InlinedStyles
|
|
84
91
|
id="builderio-variants"
|
|
85
92
|
styles={hideVariantsStyleString()}
|
|
@@ -4,12 +4,17 @@ type VariantsProviderProps = ContentVariantsPrps & {
|
|
|
4
4
|
* For internal use only. Do not provide this prop.
|
|
5
5
|
*/
|
|
6
6
|
isNestedRender?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* For internal use only. Do not provide this prop.
|
|
9
|
+
*/
|
|
10
|
+
isContentInlinedInParent?: boolean;
|
|
7
11
|
};
|
|
8
12
|
import type { ContentVariantsPrps } from "./content-variants.types";
|
|
9
13
|
declare const __propDef: {
|
|
10
14
|
props: {
|
|
11
15
|
canTrack?: VariantsProviderProps["canTrack"];
|
|
12
16
|
content: VariantsProviderProps["content"];
|
|
17
|
+
isContentInlinedInParent?: VariantsProviderProps["isContentInlinedInParent"];
|
|
13
18
|
nonce?: VariantsProviderProps["nonce"];
|
|
14
19
|
apiHost?: VariantsProviderProps["apiHost"];
|
|
15
20
|
isNestedRender?: VariantsProviderProps["isNestedRender"];
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { Nullable } from '../../helpers/nullable';
|
|
2
2
|
import type { BuilderContent } from '../../types/builder-content';
|
|
3
|
+
import type { Target } from '../../types/targets';
|
|
4
|
+
/**
|
|
5
|
+
* SDKs where `BuilderScripts` can dedupe helper scripts. Elsewhere `Content` cannot read its context
|
|
6
|
+
* (RSC server components, Angular DI) or has no inline scripts (React Native).
|
|
7
|
+
*/
|
|
8
|
+
export declare const SDKS_SUPPORTING_BUILDER_SCRIPTS: Target[];
|
|
3
9
|
export declare const getVariants: (content: Nullable<BuilderContent>) => {
|
|
4
10
|
testVariationId: string | undefined;
|
|
5
11
|
id: string | undefined;
|
|
@@ -9,6 +9,11 @@ import { UPDATE_COOKIES_AND_STYLES_SCRIPT, UPDATE_VARIANT_VISIBILITY_SCRIPT } fr
|
|
|
9
9
|
*/
|
|
10
10
|
const UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME = 'builderIoAbTest';
|
|
11
11
|
const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'builderIoRenderContent';
|
|
12
|
+
/**
|
|
13
|
+
* SDKs where `BuilderScripts` can dedupe helper scripts. Elsewhere `Content` cannot read its context
|
|
14
|
+
* (RSC server components, Angular DI) or has no inline scripts (React Native).
|
|
15
|
+
*/
|
|
16
|
+
export const SDKS_SUPPORTING_BUILDER_SCRIPTS = ['react', 'vue', 'svelte', 'solid', 'qwik'];
|
|
12
17
|
export const getVariants = (content) => Object.values(content?.variations || {}).map(variant => ({
|
|
13
18
|
...variant,
|
|
14
19
|
testVariationId: variant.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "5.
|
|
1
|
+
export declare const SDK_VERSION = "5.4.0";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "5.
|
|
1
|
+
export const SDK_VERSION = "5.4.0";
|
|
@@ -7,6 +7,7 @@ export { default as Symbol } from '../blocks/symbol/index';
|
|
|
7
7
|
export { default as Text } from '../blocks/text/index';
|
|
8
8
|
export { default as Video } from '../blocks/video/index';
|
|
9
9
|
export { default as Blocks } from '../components/blocks/index';
|
|
10
|
+
export { default as BuilderScripts } from '../components/builder-scripts.svelte';
|
|
10
11
|
export { default as Content } from '../components/content-variants/index';
|
|
11
12
|
/**
|
|
12
13
|
* Builder Context
|
|
@@ -7,6 +7,7 @@ export { default as Symbol } from '../blocks/symbol/index';
|
|
|
7
7
|
export { default as Text } from '../blocks/text/index';
|
|
8
8
|
export { default as Video } from '../blocks/video/index';
|
|
9
9
|
export { default as Blocks } from '../components/blocks/index';
|
|
10
|
+
export { default as BuilderScripts } from '../components/builder-scripts.svelte';
|
|
10
11
|
export { default as Content } from '../components/content-variants/index';
|
|
11
12
|
/**
|
|
12
13
|
* Builder Context
|
|
@@ -10,6 +10,7 @@ export interface SymbolInfo {
|
|
|
10
10
|
ownerId?: string;
|
|
11
11
|
global?: boolean;
|
|
12
12
|
}
|
|
13
|
+
export declare const isSymbolContentInlinedInParent: (symbol: SymbolInfo | undefined, bindings: Record<string, string> | undefined) => boolean;
|
|
13
14
|
export declare const fetchSymbolContent: ({ builderContextValue, symbol }: {
|
|
14
15
|
symbol: SymbolInfo | undefined;
|
|
15
16
|
builderContextValue: BuilderContextInterface;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { fetchOneEntry } from '../../functions/get-content/index';
|
|
2
2
|
import { logger } from '../../helpers/logger';
|
|
3
|
+
const isSymbolContentBinding = (key) => {
|
|
4
|
+
const path = key.startsWith('component.') ? key.slice(10) : key;
|
|
5
|
+
return path === 'options.symbol' || path === 'options.symbol.content' || path.startsWith('options.symbol.content.');
|
|
6
|
+
};
|
|
7
|
+
// Bound symbol content is evaluated at render time, so it is not in the parent content JSON.
|
|
8
|
+
export const isSymbolContentInlinedInParent = (symbol, bindings) => !!symbol?.content && !Object.keys(bindings || {}).some(isSymbolContentBinding);
|
|
3
9
|
export const fetchSymbolContent = async ({ builderContextValue, symbol }) => {
|
|
4
10
|
/**
|
|
5
11
|
* If:
|
|
@@ -4,7 +4,7 @@ import { filterAttrs } from "../helpers";
|
|
|
4
4
|
import "../../components/dynamic-div.svelte";
|
|
5
5
|
import { getClassPropName } from "../../functions/get-class-prop-name";
|
|
6
6
|
import { setAttrs } from "../helpers";
|
|
7
|
-
import { fetchSymbolContent } from "./symbol.helpers";
|
|
7
|
+
import { fetchSymbolContent, isSymbolContentInlinedInParent, } from "./symbol.helpers";
|
|
8
8
|
export let symbol = undefined;
|
|
9
9
|
export let builderComponents;
|
|
10
10
|
export let attributes = undefined;
|
|
@@ -64,6 +64,10 @@ $: onUpdateFn_0(...[symbol]);
|
|
|
64
64
|
<ContentVariants
|
|
65
65
|
nonce={$builderContext.nonce}
|
|
66
66
|
isNestedRender={true}
|
|
67
|
+
isContentInlinedInParent={isSymbolContentInlinedInParent(
|
|
68
|
+
symbol,
|
|
69
|
+
builderBlock?.bindings
|
|
70
|
+
)}
|
|
67
71
|
apiVersion={$builderContext.apiVersion}
|
|
68
72
|
apiKey={symbol?.global && symbol?.ownerId
|
|
69
73
|
? symbol.ownerId
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script context="module">/**
|
|
2
|
+
* Emits the Variant Container and A/B test helper scripts once for all `Content` components inside it.
|
|
3
|
+
*/
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<script>import { getContext, setContext } from "svelte";
|
|
7
|
+
import { getInitPersonalizationVariantsFnsScriptString, SDKS_SUPPORTING_PERSONALIZATION, } from "../blocks/personalization-container/helpers";
|
|
8
|
+
import { TARGET } from "../constants/target";
|
|
9
|
+
import BuilderScriptsContext from "../context/builder-scripts.context";
|
|
10
|
+
import { isBrowser } from "../functions/is-browser";
|
|
11
|
+
import { getInitVariantsFnsScriptString, SDKS_SUPPORTING_BUILDER_SCRIPTS, } from "./content-variants/helpers";
|
|
12
|
+
import InlinedScript from "./inlined-script.svelte";
|
|
13
|
+
export let nonce = undefined;
|
|
14
|
+
let parentScriptsContext = getContext(BuilderScriptsContext.key);
|
|
15
|
+
let isSupported = SDKS_SUPPORTING_BUILDER_SCRIPTS.includes(TARGET);
|
|
16
|
+
let shouldRenderAbTestFns = TARGET !== "react" || !isBrowser();
|
|
17
|
+
setContext(BuilderScriptsContext.key, {
|
|
18
|
+
scriptsEmitted: isSupported,
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
{#if isSupported && !parentScriptsContext?.scriptsEmitted}
|
|
23
|
+
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
24
|
+
<InlinedScript
|
|
25
|
+
id="builderio-init-personalization-variants-fns"
|
|
26
|
+
nonce={nonce || ""}
|
|
27
|
+
scriptStr={getInitPersonalizationVariantsFnsScriptString()}
|
|
28
|
+
/>
|
|
29
|
+
{/if}
|
|
30
|
+
|
|
31
|
+
{#if shouldRenderAbTestFns}
|
|
32
|
+
<InlinedScript
|
|
33
|
+
id="builderio-init-variants-fns"
|
|
34
|
+
nonce={nonce || ""}
|
|
35
|
+
scriptStr={getInitVariantsFnsScriptString()}
|
|
36
|
+
/>
|
|
37
|
+
{/if}
|
|
38
|
+
{/if}
|
|
39
|
+
<slot />
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
type BuilderScriptsProps = {
|
|
3
|
+
nonce?: string;
|
|
4
|
+
children?: any;
|
|
5
|
+
};
|
|
6
|
+
declare const __propDef: {
|
|
7
|
+
props: {
|
|
8
|
+
nonce?: BuilderScriptsProps["nonce"];
|
|
9
|
+
};
|
|
10
|
+
events: {
|
|
11
|
+
[evt: string]: CustomEvent<any>;
|
|
12
|
+
};
|
|
13
|
+
slots: {
|
|
14
|
+
default: {};
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
type BuilderScriptsProps_ = typeof __propDef.props;
|
|
18
|
+
export { BuilderScriptsProps_ as BuilderScriptsProps };
|
|
19
|
+
export type BuilderScriptsEvents = typeof __propDef.events;
|
|
20
|
+
export type BuilderScriptsSlots = typeof __propDef.slots;
|
|
21
|
+
export default class BuilderScripts extends SvelteComponent<BuilderScriptsProps, BuilderScriptsEvents, BuilderScriptsSlots> {
|
|
22
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
|
-
<script>import { onMount } from "svelte";
|
|
3
|
+
<script>import { getContext, onMount } from "svelte";
|
|
4
4
|
import { SDKS_SUPPORTING_PERSONALIZATION, getInitPersonalizationVariantsFnsScriptString, hasPersonalizationContainer, } from "../../blocks/personalization-container/helpers";
|
|
5
5
|
import { TARGET } from "../../constants/target";
|
|
6
|
+
import BuilderScriptsContext from "../../context/builder-scripts.context";
|
|
6
7
|
import { handleABTestingSync } from "../../helpers/ab-tests";
|
|
7
8
|
import { getDefaultCanTrack } from "../../helpers/canTrack";
|
|
8
9
|
import ContentComponent from "../content/content.svelte";
|
|
@@ -11,6 +12,7 @@ import InlinedStyles from "../inlined-styles.svelte";
|
|
|
11
12
|
import { checkShouldRenderVariants, getInitVariantsFnsScriptString, getUpdateCookieAndStylesScript, getVariants, } from "./helpers";
|
|
12
13
|
export let canTrack = undefined;
|
|
13
14
|
export let content;
|
|
15
|
+
export let isContentInlinedInParent = undefined;
|
|
14
16
|
export let nonce = undefined;
|
|
15
17
|
export let apiHost = undefined;
|
|
16
18
|
export let isNestedRender = undefined;
|
|
@@ -29,6 +31,7 @@ export let blocksWrapperProps = undefined;
|
|
|
29
31
|
export let contentWrapper = undefined;
|
|
30
32
|
export let contentWrapperProps = undefined;
|
|
31
33
|
export let trustedHosts = undefined;
|
|
34
|
+
let scriptsContext = getContext(BuilderScriptsContext.key);
|
|
32
35
|
$: updateCookieAndStylesScriptStr = () => {
|
|
33
36
|
return getUpdateCookieAndStylesScript(getVariants(content).map((value) => ({
|
|
34
37
|
id: value.testVariationId,
|
|
@@ -55,7 +58,9 @@ let shouldRenderVariants = checkShouldRenderVariants({
|
|
|
55
58
|
canTrack: getDefaultCanTrack(canTrack),
|
|
56
59
|
content: content,
|
|
57
60
|
});
|
|
58
|
-
let shouldEmitPersonalizationFns = TARGET !== "reactNative" &&
|
|
61
|
+
let shouldEmitPersonalizationFns = TARGET !== "reactNative" &&
|
|
62
|
+
!isContentInlinedInParent &&
|
|
63
|
+
hasPersonalizationContainer(content);
|
|
59
64
|
onMount(() => {
|
|
60
65
|
/**
|
|
61
66
|
* For Solid/Svelte: we unmount the non-winning variants post-hydration.
|
|
@@ -64,7 +69,7 @@ onMount(() => {
|
|
|
64
69
|
});
|
|
65
70
|
</script>
|
|
66
71
|
|
|
67
|
-
{#if shouldEmitPersonalizationFns}
|
|
72
|
+
{#if shouldEmitPersonalizationFns && !!!scriptsContext?.scriptsEmitted}
|
|
68
73
|
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
69
74
|
<InlinedScript
|
|
70
75
|
id="builderio-init-personalization-variants-fns"
|
|
@@ -75,11 +80,13 @@ onMount(() => {
|
|
|
75
80
|
{/if}
|
|
76
81
|
|
|
77
82
|
{#if shouldRenderVariants}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
{#if !!!scriptsContext?.scriptsEmitted}
|
|
84
|
+
<InlinedScript
|
|
85
|
+
id="builderio-init-variants-fns"
|
|
86
|
+
scriptStr={getInitVariantsFnsScriptString()}
|
|
87
|
+
nonce={nonce || ""}
|
|
88
|
+
/>
|
|
89
|
+
{/if}
|
|
83
90
|
<InlinedStyles
|
|
84
91
|
id="builderio-variants"
|
|
85
92
|
styles={hideVariantsStyleString()}
|
|
@@ -4,12 +4,17 @@ type VariantsProviderProps = ContentVariantsPrps & {
|
|
|
4
4
|
* For internal use only. Do not provide this prop.
|
|
5
5
|
*/
|
|
6
6
|
isNestedRender?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* For internal use only. Do not provide this prop.
|
|
9
|
+
*/
|
|
10
|
+
isContentInlinedInParent?: boolean;
|
|
7
11
|
};
|
|
8
12
|
import type { ContentVariantsPrps } from "./content-variants.types";
|
|
9
13
|
declare const __propDef: {
|
|
10
14
|
props: {
|
|
11
15
|
canTrack?: VariantsProviderProps["canTrack"];
|
|
12
16
|
content: VariantsProviderProps["content"];
|
|
17
|
+
isContentInlinedInParent?: VariantsProviderProps["isContentInlinedInParent"];
|
|
13
18
|
nonce?: VariantsProviderProps["nonce"];
|
|
14
19
|
apiHost?: VariantsProviderProps["apiHost"];
|
|
15
20
|
isNestedRender?: VariantsProviderProps["isNestedRender"];
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { Nullable } from '../../helpers/nullable';
|
|
2
2
|
import type { BuilderContent } from '../../types/builder-content';
|
|
3
|
+
import type { Target } from '../../types/targets';
|
|
4
|
+
/**
|
|
5
|
+
* SDKs where `BuilderScripts` can dedupe helper scripts. Elsewhere `Content` cannot read its context
|
|
6
|
+
* (RSC server components, Angular DI) or has no inline scripts (React Native).
|
|
7
|
+
*/
|
|
8
|
+
export declare const SDKS_SUPPORTING_BUILDER_SCRIPTS: Target[];
|
|
3
9
|
export declare const getVariants: (content: Nullable<BuilderContent>) => {
|
|
4
10
|
testVariationId: string | undefined;
|
|
5
11
|
id: string | undefined;
|
|
@@ -9,6 +9,11 @@ import { UPDATE_COOKIES_AND_STYLES_SCRIPT, UPDATE_VARIANT_VISIBILITY_SCRIPT } fr
|
|
|
9
9
|
*/
|
|
10
10
|
const UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME = 'builderIoAbTest';
|
|
11
11
|
const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'builderIoRenderContent';
|
|
12
|
+
/**
|
|
13
|
+
* SDKs where `BuilderScripts` can dedupe helper scripts. Elsewhere `Content` cannot read its context
|
|
14
|
+
* (RSC server components, Angular DI) or has no inline scripts (React Native).
|
|
15
|
+
*/
|
|
16
|
+
export const SDKS_SUPPORTING_BUILDER_SCRIPTS = ['react', 'vue', 'svelte', 'solid', 'qwik'];
|
|
12
17
|
export const getVariants = (content) => Object.values(content?.variations || {}).map(variant => ({
|
|
13
18
|
...variant,
|
|
14
19
|
testVariationId: variant.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "5.
|
|
1
|
+
export declare const SDK_VERSION = "5.4.0";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "5.
|
|
1
|
+
export const SDK_VERSION = "5.4.0";
|
|
@@ -7,6 +7,7 @@ export { default as Symbol } from '../blocks/symbol/index';
|
|
|
7
7
|
export { default as Text } from '../blocks/text/index';
|
|
8
8
|
export { default as Video } from '../blocks/video/index';
|
|
9
9
|
export { default as Blocks } from '../components/blocks/index';
|
|
10
|
+
export { default as BuilderScripts } from '../components/builder-scripts.svelte';
|
|
10
11
|
export { default as Content } from '../components/content-variants/index';
|
|
11
12
|
/**
|
|
12
13
|
* Builder Context
|
|
@@ -7,6 +7,7 @@ export { default as Symbol } from '../blocks/symbol/index';
|
|
|
7
7
|
export { default as Text } from '../blocks/text/index';
|
|
8
8
|
export { default as Video } from '../blocks/video/index';
|
|
9
9
|
export { default as Blocks } from '../components/blocks/index';
|
|
10
|
+
export { default as BuilderScripts } from '../components/builder-scripts.svelte';
|
|
10
11
|
export { default as Content } from '../components/content-variants/index';
|
|
11
12
|
/**
|
|
12
13
|
* Builder Context
|
|
@@ -10,6 +10,7 @@ export interface SymbolInfo {
|
|
|
10
10
|
ownerId?: string;
|
|
11
11
|
global?: boolean;
|
|
12
12
|
}
|
|
13
|
+
export declare const isSymbolContentInlinedInParent: (symbol: SymbolInfo | undefined, bindings: Record<string, string> | undefined) => boolean;
|
|
13
14
|
export declare const fetchSymbolContent: ({ builderContextValue, symbol }: {
|
|
14
15
|
symbol: SymbolInfo | undefined;
|
|
15
16
|
builderContextValue: BuilderContextInterface;
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { fetchOneEntry } from '../../functions/get-content/index';
|
|
2
2
|
import { logger } from '../../helpers/logger';
|
|
3
|
+
const isSymbolContentBinding = (key) => {
|
|
4
|
+
const path = key.startsWith('component.') ? key.slice(10) : key;
|
|
5
|
+
return path === 'options.symbol' || path === 'options.symbol.content' || path.startsWith('options.symbol.content.');
|
|
6
|
+
};
|
|
7
|
+
// Bound symbol content is evaluated at render time, so it is not in the parent content JSON.
|
|
8
|
+
export const isSymbolContentInlinedInParent = (symbol, bindings) => !!symbol?.content && !Object.keys(bindings || {}).some(isSymbolContentBinding);
|
|
3
9
|
export const fetchSymbolContent = async ({ builderContextValue, symbol }) => {
|
|
4
10
|
/**
|
|
5
11
|
* If:
|
|
@@ -4,7 +4,7 @@ import { filterAttrs } from "../helpers";
|
|
|
4
4
|
import "../../components/dynamic-div.svelte";
|
|
5
5
|
import { getClassPropName } from "../../functions/get-class-prop-name";
|
|
6
6
|
import { setAttrs } from "../helpers";
|
|
7
|
-
import { fetchSymbolContent } from "./symbol.helpers";
|
|
7
|
+
import { fetchSymbolContent, isSymbolContentInlinedInParent, } from "./symbol.helpers";
|
|
8
8
|
export let symbol = undefined;
|
|
9
9
|
export let builderComponents;
|
|
10
10
|
export let attributes = undefined;
|
|
@@ -64,6 +64,10 @@ $: onUpdateFn_0(...[symbol]);
|
|
|
64
64
|
<ContentVariants
|
|
65
65
|
nonce={$builderContext.nonce}
|
|
66
66
|
isNestedRender={true}
|
|
67
|
+
isContentInlinedInParent={isSymbolContentInlinedInParent(
|
|
68
|
+
symbol,
|
|
69
|
+
builderBlock?.bindings
|
|
70
|
+
)}
|
|
67
71
|
apiVersion={$builderContext.apiVersion}
|
|
68
72
|
apiKey={symbol?.global && symbol?.ownerId
|
|
69
73
|
? symbol.ownerId
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
<script context="module">/**
|
|
2
|
+
* Emits the Variant Container and A/B test helper scripts once for all `Content` components inside it.
|
|
3
|
+
*/
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
<script>import { getContext, setContext } from "svelte";
|
|
7
|
+
import { getInitPersonalizationVariantsFnsScriptString, SDKS_SUPPORTING_PERSONALIZATION, } from "../blocks/personalization-container/helpers";
|
|
8
|
+
import { TARGET } from "../constants/target";
|
|
9
|
+
import BuilderScriptsContext from "../context/builder-scripts.context";
|
|
10
|
+
import { isBrowser } from "../functions/is-browser";
|
|
11
|
+
import { getInitVariantsFnsScriptString, SDKS_SUPPORTING_BUILDER_SCRIPTS, } from "./content-variants/helpers";
|
|
12
|
+
import InlinedScript from "./inlined-script.svelte";
|
|
13
|
+
export let nonce = undefined;
|
|
14
|
+
let parentScriptsContext = getContext(BuilderScriptsContext.key);
|
|
15
|
+
let isSupported = SDKS_SUPPORTING_BUILDER_SCRIPTS.includes(TARGET);
|
|
16
|
+
let shouldRenderAbTestFns = TARGET !== "react" || !isBrowser();
|
|
17
|
+
setContext(BuilderScriptsContext.key, {
|
|
18
|
+
scriptsEmitted: isSupported,
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
{#if isSupported && !parentScriptsContext?.scriptsEmitted}
|
|
23
|
+
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
24
|
+
<InlinedScript
|
|
25
|
+
id="builderio-init-personalization-variants-fns"
|
|
26
|
+
nonce={nonce || ""}
|
|
27
|
+
scriptStr={getInitPersonalizationVariantsFnsScriptString()}
|
|
28
|
+
/>
|
|
29
|
+
{/if}
|
|
30
|
+
|
|
31
|
+
{#if shouldRenderAbTestFns}
|
|
32
|
+
<InlinedScript
|
|
33
|
+
id="builderio-init-variants-fns"
|
|
34
|
+
nonce={nonce || ""}
|
|
35
|
+
scriptStr={getInitVariantsFnsScriptString()}
|
|
36
|
+
/>
|
|
37
|
+
{/if}
|
|
38
|
+
{/if}
|
|
39
|
+
<slot />
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SvelteComponent } from "svelte";
|
|
2
|
+
type BuilderScriptsProps = {
|
|
3
|
+
nonce?: string;
|
|
4
|
+
children?: any;
|
|
5
|
+
};
|
|
6
|
+
declare const __propDef: {
|
|
7
|
+
props: {
|
|
8
|
+
nonce?: BuilderScriptsProps["nonce"];
|
|
9
|
+
};
|
|
10
|
+
events: {
|
|
11
|
+
[evt: string]: CustomEvent<any>;
|
|
12
|
+
};
|
|
13
|
+
slots: {
|
|
14
|
+
default: {};
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
type BuilderScriptsProps_ = typeof __propDef.props;
|
|
18
|
+
export { BuilderScriptsProps_ as BuilderScriptsProps };
|
|
19
|
+
export type BuilderScriptsEvents = typeof __propDef.events;
|
|
20
|
+
export type BuilderScriptsSlots = typeof __propDef.slots;
|
|
21
|
+
export default class BuilderScripts extends SvelteComponent<BuilderScriptsProps, BuilderScriptsEvents, BuilderScriptsSlots> {
|
|
22
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
|
-
<script>import { onMount } from "svelte";
|
|
3
|
+
<script>import { getContext, onMount } from "svelte";
|
|
4
4
|
import { SDKS_SUPPORTING_PERSONALIZATION, getInitPersonalizationVariantsFnsScriptString, hasPersonalizationContainer, } from "../../blocks/personalization-container/helpers";
|
|
5
5
|
import { TARGET } from "../../constants/target";
|
|
6
|
+
import BuilderScriptsContext from "../../context/builder-scripts.context";
|
|
6
7
|
import { handleABTestingSync } from "../../helpers/ab-tests";
|
|
7
8
|
import { getDefaultCanTrack } from "../../helpers/canTrack";
|
|
8
9
|
import ContentComponent from "../content/content.svelte";
|
|
@@ -11,6 +12,7 @@ import InlinedStyles from "../inlined-styles.svelte";
|
|
|
11
12
|
import { checkShouldRenderVariants, getInitVariantsFnsScriptString, getUpdateCookieAndStylesScript, getVariants, } from "./helpers";
|
|
12
13
|
export let canTrack = undefined;
|
|
13
14
|
export let content;
|
|
15
|
+
export let isContentInlinedInParent = undefined;
|
|
14
16
|
export let nonce = undefined;
|
|
15
17
|
export let apiHost = undefined;
|
|
16
18
|
export let isNestedRender = undefined;
|
|
@@ -29,6 +31,7 @@ export let blocksWrapperProps = undefined;
|
|
|
29
31
|
export let contentWrapper = undefined;
|
|
30
32
|
export let contentWrapperProps = undefined;
|
|
31
33
|
export let trustedHosts = undefined;
|
|
34
|
+
let scriptsContext = getContext(BuilderScriptsContext.key);
|
|
32
35
|
$: updateCookieAndStylesScriptStr = () => {
|
|
33
36
|
return getUpdateCookieAndStylesScript(getVariants(content).map((value) => ({
|
|
34
37
|
id: value.testVariationId,
|
|
@@ -55,7 +58,9 @@ let shouldRenderVariants = checkShouldRenderVariants({
|
|
|
55
58
|
canTrack: getDefaultCanTrack(canTrack),
|
|
56
59
|
content: content,
|
|
57
60
|
});
|
|
58
|
-
let shouldEmitPersonalizationFns = TARGET !== "reactNative" &&
|
|
61
|
+
let shouldEmitPersonalizationFns = TARGET !== "reactNative" &&
|
|
62
|
+
!isContentInlinedInParent &&
|
|
63
|
+
hasPersonalizationContainer(content);
|
|
59
64
|
onMount(() => {
|
|
60
65
|
/**
|
|
61
66
|
* For Solid/Svelte: we unmount the non-winning variants post-hydration.
|
|
@@ -64,7 +69,7 @@ onMount(() => {
|
|
|
64
69
|
});
|
|
65
70
|
</script>
|
|
66
71
|
|
|
67
|
-
{#if shouldEmitPersonalizationFns}
|
|
72
|
+
{#if shouldEmitPersonalizationFns && !!!scriptsContext?.scriptsEmitted}
|
|
68
73
|
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
69
74
|
<InlinedScript
|
|
70
75
|
id="builderio-init-personalization-variants-fns"
|
|
@@ -75,11 +80,13 @@ onMount(() => {
|
|
|
75
80
|
{/if}
|
|
76
81
|
|
|
77
82
|
{#if shouldRenderVariants}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
{#if !!!scriptsContext?.scriptsEmitted}
|
|
84
|
+
<InlinedScript
|
|
85
|
+
id="builderio-init-variants-fns"
|
|
86
|
+
scriptStr={getInitVariantsFnsScriptString()}
|
|
87
|
+
nonce={nonce || ""}
|
|
88
|
+
/>
|
|
89
|
+
{/if}
|
|
83
90
|
<InlinedStyles
|
|
84
91
|
id="builderio-variants"
|
|
85
92
|
styles={hideVariantsStyleString()}
|
|
@@ -4,12 +4,17 @@ type VariantsProviderProps = ContentVariantsPrps & {
|
|
|
4
4
|
* For internal use only. Do not provide this prop.
|
|
5
5
|
*/
|
|
6
6
|
isNestedRender?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* For internal use only. Do not provide this prop.
|
|
9
|
+
*/
|
|
10
|
+
isContentInlinedInParent?: boolean;
|
|
7
11
|
};
|
|
8
12
|
import type { ContentVariantsPrps } from "./content-variants.types";
|
|
9
13
|
declare const __propDef: {
|
|
10
14
|
props: {
|
|
11
15
|
canTrack?: VariantsProviderProps["canTrack"];
|
|
12
16
|
content: VariantsProviderProps["content"];
|
|
17
|
+
isContentInlinedInParent?: VariantsProviderProps["isContentInlinedInParent"];
|
|
13
18
|
nonce?: VariantsProviderProps["nonce"];
|
|
14
19
|
apiHost?: VariantsProviderProps["apiHost"];
|
|
15
20
|
isNestedRender?: VariantsProviderProps["isNestedRender"];
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import type { Nullable } from '../../helpers/nullable';
|
|
2
2
|
import type { BuilderContent } from '../../types/builder-content';
|
|
3
|
+
import type { Target } from '../../types/targets';
|
|
4
|
+
/**
|
|
5
|
+
* SDKs where `BuilderScripts` can dedupe helper scripts. Elsewhere `Content` cannot read its context
|
|
6
|
+
* (RSC server components, Angular DI) or has no inline scripts (React Native).
|
|
7
|
+
*/
|
|
8
|
+
export declare const SDKS_SUPPORTING_BUILDER_SCRIPTS: Target[];
|
|
3
9
|
export declare const getVariants: (content: Nullable<BuilderContent>) => {
|
|
4
10
|
testVariationId: string | undefined;
|
|
5
11
|
id: string | undefined;
|
|
@@ -9,6 +9,11 @@ import { UPDATE_COOKIES_AND_STYLES_SCRIPT, UPDATE_VARIANT_VISIBILITY_SCRIPT } fr
|
|
|
9
9
|
*/
|
|
10
10
|
const UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME = 'builderIoAbTest';
|
|
11
11
|
const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'builderIoRenderContent';
|
|
12
|
+
/**
|
|
13
|
+
* SDKs where `BuilderScripts` can dedupe helper scripts. Elsewhere `Content` cannot read its context
|
|
14
|
+
* (RSC server components, Angular DI) or has no inline scripts (React Native).
|
|
15
|
+
*/
|
|
16
|
+
export const SDKS_SUPPORTING_BUILDER_SCRIPTS = ['react', 'vue', 'svelte', 'solid', 'qwik'];
|
|
12
17
|
export const getVariants = (content) => Object.values(content?.variations || {}).map(variant => ({
|
|
13
18
|
...variant,
|
|
14
19
|
testVariationId: variant.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "5.
|
|
1
|
+
export declare const SDK_VERSION = "5.4.0";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "5.
|
|
1
|
+
export const SDK_VERSION = "5.4.0";
|
|
@@ -7,6 +7,7 @@ export { default as Symbol } from '../blocks/symbol/index';
|
|
|
7
7
|
export { default as Text } from '../blocks/text/index';
|
|
8
8
|
export { default as Video } from '../blocks/video/index';
|
|
9
9
|
export { default as Blocks } from '../components/blocks/index';
|
|
10
|
+
export { default as BuilderScripts } from '../components/builder-scripts.svelte';
|
|
10
11
|
export { default as Content } from '../components/content-variants/index';
|
|
11
12
|
/**
|
|
12
13
|
* Builder Context
|
|
@@ -7,6 +7,7 @@ export { default as Symbol } from '../blocks/symbol/index';
|
|
|
7
7
|
export { default as Text } from '../blocks/text/index';
|
|
8
8
|
export { default as Video } from '../blocks/video/index';
|
|
9
9
|
export { default as Blocks } from '../components/blocks/index';
|
|
10
|
+
export { default as BuilderScripts } from '../components/builder-scripts.svelte';
|
|
10
11
|
export { default as Content } from '../components/content-variants/index';
|
|
11
12
|
/**
|
|
12
13
|
* Builder Context
|
package/package.json
CHANGED
|
@@ -12,6 +12,13 @@ export interface SymbolInfo {
|
|
|
12
12
|
ownerId?: string;
|
|
13
13
|
global?: boolean;
|
|
14
14
|
}
|
|
15
|
+
const isSymbolContentBinding = (key: string) => {
|
|
16
|
+
const path = key.startsWith('component.') ? key.slice(10) : key;
|
|
17
|
+
return path === 'options.symbol' || path === 'options.symbol.content' || path.startsWith('options.symbol.content.');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// Bound symbol content is evaluated at render time, so it is not in the parent content JSON.
|
|
21
|
+
export const isSymbolContentInlinedInParent = (symbol: SymbolInfo | undefined, bindings: Record<string, string> | undefined) => !!symbol?.content && !Object.keys(bindings || {}).some(isSymbolContentBinding);
|
|
15
22
|
export const fetchSymbolContent = async ({
|
|
16
23
|
builderContextValue,
|
|
17
24
|
symbol
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
import { getClassPropName } from "../../functions/get-class-prop-name";
|
|
9
9
|
import type { Nullable } from "../../types/typescript";
|
|
10
10
|
import { setAttrs } from "../helpers";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
fetchSymbolContent,
|
|
13
|
+
isSymbolContentInlinedInParent,
|
|
14
|
+
} from "./symbol.helpers";
|
|
12
15
|
import type { SymbolProps } from "./symbol.types";
|
|
13
16
|
|
|
14
17
|
export let symbol: SymbolProps["symbol"] = undefined;
|
|
@@ -75,6 +78,10 @@
|
|
|
75
78
|
<ContentVariants
|
|
76
79
|
nonce={$builderContext.nonce}
|
|
77
80
|
isNestedRender={true}
|
|
81
|
+
isContentInlinedInParent={isSymbolContentInlinedInParent(
|
|
82
|
+
symbol,
|
|
83
|
+
builderBlock?.bindings
|
|
84
|
+
)}
|
|
78
85
|
apiVersion={$builderContext.apiVersion}
|
|
79
86
|
apiKey={symbol?.global && symbol?.ownerId
|
|
80
87
|
? symbol.ownerId
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script context="module" lang="ts">
|
|
2
|
+
type BuilderScriptsProps = {
|
|
3
|
+
nonce?: string;
|
|
4
|
+
children?: any;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Emits the Variant Container and A/B test helper scripts once for all `Content` components inside it.
|
|
9
|
+
*/
|
|
10
|
+
</script>
|
|
11
|
+
|
|
12
|
+
<script lang="ts">
|
|
13
|
+
import { getContext, setContext } from "svelte";
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
getInitPersonalizationVariantsFnsScriptString,
|
|
17
|
+
SDKS_SUPPORTING_PERSONALIZATION,
|
|
18
|
+
} from "../blocks/personalization-container/helpers";
|
|
19
|
+
import { TARGET } from "../constants/target";
|
|
20
|
+
import BuilderScriptsContext from "../context/builder-scripts.context";
|
|
21
|
+
import { isBrowser } from "../functions/is-browser";
|
|
22
|
+
import {
|
|
23
|
+
getInitVariantsFnsScriptString,
|
|
24
|
+
SDKS_SUPPORTING_BUILDER_SCRIPTS,
|
|
25
|
+
} from "./content-variants/helpers";
|
|
26
|
+
import InlinedScript from "./inlined-script.svelte";
|
|
27
|
+
|
|
28
|
+
export let nonce: BuilderScriptsProps["nonce"] = undefined;
|
|
29
|
+
|
|
30
|
+
let parentScriptsContext = getContext(BuilderScriptsContext.key);
|
|
31
|
+
|
|
32
|
+
let isSupported = SDKS_SUPPORTING_BUILDER_SCRIPTS.includes(TARGET);
|
|
33
|
+
let shouldRenderAbTestFns = TARGET !== "react" || !isBrowser();
|
|
34
|
+
|
|
35
|
+
setContext(BuilderScriptsContext.key, {
|
|
36
|
+
scriptsEmitted: isSupported,
|
|
37
|
+
});
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
{#if isSupported && !parentScriptsContext?.scriptsEmitted}
|
|
41
|
+
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
42
|
+
<InlinedScript
|
|
43
|
+
id="builderio-init-personalization-variants-fns"
|
|
44
|
+
nonce={nonce || ""}
|
|
45
|
+
scriptStr={getInitPersonalizationVariantsFnsScriptString()}
|
|
46
|
+
/>
|
|
47
|
+
{/if}
|
|
48
|
+
|
|
49
|
+
{#if shouldRenderAbTestFns}
|
|
50
|
+
<InlinedScript
|
|
51
|
+
id="builderio-init-variants-fns"
|
|
52
|
+
nonce={nonce || ""}
|
|
53
|
+
scriptStr={getInitVariantsFnsScriptString()}
|
|
54
|
+
/>
|
|
55
|
+
{/if}
|
|
56
|
+
{/if}
|
|
57
|
+
<slot />
|
|
@@ -4,11 +4,15 @@
|
|
|
4
4
|
* For internal use only. Do not provide this prop.
|
|
5
5
|
*/
|
|
6
6
|
isNestedRender?: boolean;
|
|
7
|
+
/**
|
|
8
|
+
* For internal use only. Do not provide this prop.
|
|
9
|
+
*/
|
|
10
|
+
isContentInlinedInParent?: boolean;
|
|
7
11
|
};
|
|
8
12
|
</script>
|
|
9
13
|
|
|
10
14
|
<script lang="ts">
|
|
11
|
-
import { onMount } from "svelte";
|
|
15
|
+
import { getContext, onMount } from "svelte";
|
|
12
16
|
|
|
13
17
|
import {
|
|
14
18
|
SDKS_SUPPORTING_PERSONALIZATION,
|
|
@@ -16,6 +20,7 @@
|
|
|
16
20
|
hasPersonalizationContainer,
|
|
17
21
|
} from "../../blocks/personalization-container/helpers";
|
|
18
22
|
import { TARGET } from "../../constants/target";
|
|
23
|
+
import BuilderScriptsContext from "../../context/builder-scripts.context";
|
|
19
24
|
import { handleABTestingSync } from "../../helpers/ab-tests";
|
|
20
25
|
import { getDefaultCanTrack } from "../../helpers/canTrack";
|
|
21
26
|
import ContentComponent from "../content/content.svelte";
|
|
@@ -31,6 +36,8 @@
|
|
|
31
36
|
|
|
32
37
|
export let canTrack: VariantsProviderProps["canTrack"] = undefined;
|
|
33
38
|
export let content: VariantsProviderProps["content"];
|
|
39
|
+
export let isContentInlinedInParent: VariantsProviderProps["isContentInlinedInParent"] =
|
|
40
|
+
undefined;
|
|
34
41
|
export let nonce: VariantsProviderProps["nonce"] = undefined;
|
|
35
42
|
export let apiHost: VariantsProviderProps["apiHost"] = undefined;
|
|
36
43
|
export let isNestedRender: VariantsProviderProps["isNestedRender"] =
|
|
@@ -55,6 +62,8 @@
|
|
|
55
62
|
undefined;
|
|
56
63
|
export let trustedHosts: VariantsProviderProps["trustedHosts"] = undefined;
|
|
57
64
|
|
|
65
|
+
let scriptsContext = getContext(BuilderScriptsContext.key);
|
|
66
|
+
|
|
58
67
|
$: updateCookieAndStylesScriptStr = () => {
|
|
59
68
|
return getUpdateCookieAndStylesScript(
|
|
60
69
|
getVariants(content).map((value) => ({
|
|
@@ -86,7 +95,9 @@
|
|
|
86
95
|
content: content,
|
|
87
96
|
});
|
|
88
97
|
let shouldEmitPersonalizationFns =
|
|
89
|
-
TARGET !== "reactNative" &&
|
|
98
|
+
TARGET !== "reactNative" &&
|
|
99
|
+
!isContentInlinedInParent &&
|
|
100
|
+
hasPersonalizationContainer(content);
|
|
90
101
|
|
|
91
102
|
onMount(() => {
|
|
92
103
|
/**
|
|
@@ -96,7 +107,7 @@
|
|
|
96
107
|
});
|
|
97
108
|
</script>
|
|
98
109
|
|
|
99
|
-
{#if shouldEmitPersonalizationFns}
|
|
110
|
+
{#if shouldEmitPersonalizationFns && !!!scriptsContext?.scriptsEmitted}
|
|
100
111
|
{#if SDKS_SUPPORTING_PERSONALIZATION.includes(TARGET)}
|
|
101
112
|
<InlinedScript
|
|
102
113
|
id="builderio-init-personalization-variants-fns"
|
|
@@ -107,11 +118,13 @@
|
|
|
107
118
|
{/if}
|
|
108
119
|
|
|
109
120
|
{#if shouldRenderVariants}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
121
|
+
{#if !!!scriptsContext?.scriptsEmitted}
|
|
122
|
+
<InlinedScript
|
|
123
|
+
id="builderio-init-variants-fns"
|
|
124
|
+
scriptStr={getInitVariantsFnsScriptString()}
|
|
125
|
+
nonce={nonce || ""}
|
|
126
|
+
/>
|
|
127
|
+
{/if}
|
|
115
128
|
<InlinedStyles
|
|
116
129
|
id="builderio-variants"
|
|
117
130
|
styles={hideVariantsStyleString()}
|
|
@@ -13,6 +13,12 @@ import { UPDATE_COOKIES_AND_STYLES_SCRIPT, UPDATE_VARIANT_VISIBILITY_SCRIPT } fr
|
|
|
13
13
|
*/
|
|
14
14
|
const UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME = 'builderIoAbTest';
|
|
15
15
|
const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'builderIoRenderContent';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* SDKs where `BuilderScripts` can dedupe helper scripts. Elsewhere `Content` cannot read its context
|
|
19
|
+
* (RSC server components, Angular DI) or has no inline scripts (React Native).
|
|
20
|
+
*/
|
|
21
|
+
export const SDKS_SUPPORTING_BUILDER_SCRIPTS = (['react', 'vue', 'svelte', 'solid', 'qwik'] as Target[]);
|
|
16
22
|
export const getVariants = (content: Nullable<BuilderContent>) => Object.values(content?.variations || {}).map(variant => ({
|
|
17
23
|
...variant,
|
|
18
24
|
testVariationId: variant.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "5.
|
|
1
|
+
export const SDK_VERSION = "5.4.0"
|
|
@@ -7,6 +7,7 @@ export { default as Symbol } from '../blocks/symbol/index';
|
|
|
7
7
|
export { default as Text } from '../blocks/text/index';
|
|
8
8
|
export { default as Video } from '../blocks/video/index';
|
|
9
9
|
export { default as Blocks } from '../components/blocks/index';
|
|
10
|
+
export { default as BuilderScripts } from '../components/builder-scripts.svelte';
|
|
10
11
|
export { default as Content } from '../components/content-variants/index';
|
|
11
12
|
|
|
12
13
|
/**
|