@builder.io/sdk-svelte 0.4.4 → 0.4.5
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 +5 -2
- package/package/CHANGELOG.md +9 -0
- package/package/blocks/columns/columns.svelte +2 -2
- package/package/blocks/symbol/symbol.svelte +8 -5
- package/package/blocks/text/text.svelte +1 -1
- package/package/blocks/text/text.svelte.d.ts +1 -1
- package/package/components/inlined-script.svelte +7 -0
- package/package/components/inlined-script.svelte.d.ts +21 -0
- package/package/components/inlined-styles.svelte.d.ts +21 -0
- package/package/components/render-block/block-styles.svelte +2 -2
- package/package/components/render-content/components/render-styles.svelte +2 -2
- package/package/components/render-content/render-content.svelte +9 -8
- package/package/components/render-content/render-content.svelte.d.ts +1 -2
- package/package/components/render-content/render-content.types.d.ts +9 -23
- package/package/components/render-content-variants/helpers.d.ts +27 -3
- package/package/components/render-content-variants/helpers.js +38 -24
- package/package/components/render-content-variants/render-content-variants.svelte +57 -30
- package/package/components/render-content-variants/render-content-variants.svelte.d.ts +15 -4
- package/package/components/render-content-variants/render-content-variants.types.d.ts +20 -0
- package/package/components/render-content-variants/render-content-variants.types.js +1 -0
- package/package/constants/sdk-version.d.ts +1 -1
- package/package/constants/sdk-version.js +1 -1
- package/package/helpers/ab-tests.js +6 -0
- package/package/types/enforced-partials.d.ts +21 -0
- package/package/types/enforced-partials.js +1 -0
- package/package/types/typescript.d.ts +3 -0
- package/package.json +1 -1
- package/src/blocks/columns/columns.svelte +2 -2
- package/src/blocks/symbol/symbol.svelte +8 -5
- package/src/blocks/text/text.svelte +2 -2
- package/src/components/inlined-script.svelte +13 -0
- package/src/components/render-block/block-styles.svelte +2 -2
- package/src/components/render-content/components/render-styles.svelte +2 -2
- package/src/components/render-content/render-content.svelte +9 -8
- package/src/components/render-content/render-content.types.ts +10 -25
- package/src/components/render-content-variants/helpers.ts +43 -38
- package/src/components/render-content-variants/render-content-variants.svelte +67 -32
- package/src/components/render-content-variants/render-content-variants.types.ts +22 -0
- package/src/constants/sdk-version.ts +1 -1
- package/src/helpers/ab-tests.ts +6 -0
- package/src/types/enforced-partials.ts +27 -0
- package/src/types/typescript.ts +5 -0
- package/package/components/render-inlined-styles.svelte.d.ts +0 -21
- /package/package/components/{render-inlined-styles.svelte → inlined-styles.svelte} +0 -0
- /package/src/components/{render-inlined-styles.svelte → inlined-styles.svelte} +0 -0
package/package/--package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@builder.io/sdk-svelte",
|
|
3
3
|
"description": "Builder.io SDK for Svelte",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"package",
|
|
@@ -64,6 +64,8 @@
|
|
|
64
64
|
"./blocks/util": "./blocks/util.js",
|
|
65
65
|
"./blocks/video/component-info": "./blocks/video/component-info.js",
|
|
66
66
|
"./blocks/video/video.svelte": "./blocks/video/video.svelte",
|
|
67
|
+
"./components/inlined-script.svelte": "./components/inlined-script.svelte",
|
|
68
|
+
"./components/inlined-styles.svelte": "./components/inlined-styles.svelte",
|
|
67
69
|
"./components/render-block/block-styles.svelte": "./components/render-block/block-styles.svelte",
|
|
68
70
|
"./components/render-block/render-block.helpers": "./components/render-block/render-block.helpers.js",
|
|
69
71
|
"./components/render-block/render-block.svelte": "./components/render-block/render-block.svelte",
|
|
@@ -81,7 +83,7 @@
|
|
|
81
83
|
"./components/render-content/wrap-component-ref": "./components/render-content/wrap-component-ref.js",
|
|
82
84
|
"./components/render-content-variants/helpers": "./components/render-content-variants/helpers.js",
|
|
83
85
|
"./components/render-content-variants/render-content-variants.svelte": "./components/render-content-variants/render-content-variants.svelte",
|
|
84
|
-
"./components/render-
|
|
86
|
+
"./components/render-content-variants/render-content-variants.types": "./components/render-content-variants/render-content-variants.types.js",
|
|
85
87
|
"./constants/builder-registered-components": "./constants/builder-registered-components.js",
|
|
86
88
|
"./constants/device-sizes": "./constants/device-sizes.js",
|
|
87
89
|
"./constants/sdk-version": "./constants/sdk-version.js",
|
|
@@ -151,6 +153,7 @@
|
|
|
151
153
|
"./types/components": "./types/components.js",
|
|
152
154
|
"./types/deep-partial": "./types/deep-partial.js",
|
|
153
155
|
"./types/element": "./types/element.js",
|
|
156
|
+
"./types/enforced-partials": "./types/enforced-partials.js",
|
|
154
157
|
"./types/input": "./types/input.js",
|
|
155
158
|
"./types/targets": "./types/targets.js",
|
|
156
159
|
"./types/typescript": "./types/typescript.js"
|
package/package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
### 0.4.5
|
|
2
|
+
|
|
3
|
+
- Fix: show dynamic symbols correctly in Preview mode.
|
|
4
|
+
- Feature: SSR A/B test Symbols nested inside page content.
|
|
5
|
+
|
|
6
|
+
### 0.4.4
|
|
7
|
+
|
|
8
|
+
- Fix: tracking URL from `builder.io/api/v1/track` to `cdn.builder.io/api/v1/track` for improved reliability.
|
|
9
|
+
|
|
1
10
|
### 0.4.3
|
|
2
11
|
|
|
3
12
|
- Fix: SSR A/B test environment check (`isHydrationTarget`) now accurately checks current environment.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<script>import { getContext } from "svelte";
|
|
4
4
|
import RenderBlocks from "../../components/render-blocks.svelte";
|
|
5
5
|
import { getSizesForBreakpoints } from "../../constants/device-sizes";
|
|
6
|
-
import
|
|
6
|
+
import InlinedStyles from "../../components/inlined-styles.svelte";
|
|
7
7
|
import { TARGET } from "../../constants/target.js";
|
|
8
8
|
import BuilderContext from "../../context/builder.context.js";
|
|
9
9
|
export let space;
|
|
@@ -130,7 +130,7 @@ let flexDir = stackColumnsAt === "never"
|
|
|
130
130
|
}}
|
|
131
131
|
>
|
|
132
132
|
{#if TARGET !== "reactNative"}
|
|
133
|
-
<
|
|
133
|
+
<InlinedStyles styles={columnsStyles()} />
|
|
134
134
|
{/if}
|
|
135
135
|
|
|
136
136
|
{#each columns as column, index (index)}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
3
|
<script>import { getContext, onMount } from "svelte";
|
|
4
|
-
import
|
|
4
|
+
import RenderContentVariants from "../../components/render-content-variants/render-content-variants.svelte";
|
|
5
5
|
import BuilderContext from "../../context/builder.context.js";
|
|
6
6
|
import { getContent } from "../../functions/get-content/index.js";
|
|
7
7
|
import { TARGET } from "../../constants/target";
|
|
@@ -55,9 +55,11 @@ function fetchContent() {
|
|
|
55
55
|
model: symbol.model,
|
|
56
56
|
apiKey: $builderContext.apiKey,
|
|
57
57
|
apiVersion: $builderContext.apiVersion,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
...(symbol?.entry && {
|
|
59
|
+
query: {
|
|
60
|
+
id: symbol.entry,
|
|
61
|
+
},
|
|
62
|
+
}),
|
|
61
63
|
})
|
|
62
64
|
.then((response) => {
|
|
63
65
|
if (response) {
|
|
@@ -97,7 +99,8 @@ $: onUpdateFn_0(...[symbol]);
|
|
|
97
99
|
class={className}
|
|
98
100
|
use:setAttrs={filterAttrs(attributes, isEvent)}
|
|
99
101
|
>
|
|
100
|
-
<
|
|
102
|
+
<RenderContentVariants
|
|
103
|
+
__isNestedRender={true}
|
|
101
104
|
apiVersion={$builderContext.apiVersion}
|
|
102
105
|
apiKey={$builderContext.apiKey}
|
|
103
106
|
context={$builderContext.context}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
interface Props {
|
|
3
|
+
scriptStr: string;
|
|
4
|
+
id?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const __propDef: {
|
|
7
|
+
props: {
|
|
8
|
+
scriptStr: Props["scriptStr"];
|
|
9
|
+
id: Props["id"];
|
|
10
|
+
};
|
|
11
|
+
events: {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
};
|
|
14
|
+
slots: {};
|
|
15
|
+
};
|
|
16
|
+
export type InlinedScriptProps = typeof __propDef.props;
|
|
17
|
+
export type InlinedScriptEvents = typeof __propDef.events;
|
|
18
|
+
export type InlinedScriptSlots = typeof __propDef.slots;
|
|
19
|
+
export default class InlinedScript extends SvelteComponentTyped<InlinedScriptProps, InlinedScriptEvents, InlinedScriptSlots> {
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { SvelteComponentTyped } from "svelte";
|
|
2
|
+
interface Props {
|
|
3
|
+
styles: string;
|
|
4
|
+
id?: string;
|
|
5
|
+
}
|
|
6
|
+
declare const __propDef: {
|
|
7
|
+
props: {
|
|
8
|
+
styles: Props["styles"];
|
|
9
|
+
id: Props["id"];
|
|
10
|
+
};
|
|
11
|
+
events: {
|
|
12
|
+
[evt: string]: CustomEvent<any>;
|
|
13
|
+
};
|
|
14
|
+
slots: {};
|
|
15
|
+
};
|
|
16
|
+
export type InlinedStylesProps = typeof __propDef.props;
|
|
17
|
+
export type InlinedStylesEvents = typeof __propDef.events;
|
|
18
|
+
export type InlinedStylesSlots = typeof __propDef.slots;
|
|
19
|
+
export default class InlinedStyles extends SvelteComponentTyped<InlinedStylesProps, InlinedStylesEvents, InlinedStylesSlots> {
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
@@ -5,7 +5,7 @@ import { TARGET } from "../../constants/target.js";
|
|
|
5
5
|
import { getProcessedBlock } from "../../functions/get-processed-block.js";
|
|
6
6
|
import { createCssClass } from "../../helpers/css.js";
|
|
7
7
|
import { checkIsDefined } from "../../helpers/nullable.js";
|
|
8
|
-
import
|
|
8
|
+
import InlinedStyles from "../inlined-styles.svelte";
|
|
9
9
|
export let block;
|
|
10
10
|
export let context;
|
|
11
11
|
$: useBlock = () => {
|
|
@@ -64,5 +64,5 @@ $: css = () => {
|
|
|
64
64
|
</script>
|
|
65
65
|
|
|
66
66
|
{#if TARGET !== "reactNative" && css() && canShowBlock()}
|
|
67
|
-
<
|
|
67
|
+
<InlinedStyles styles={css()} />
|
|
68
68
|
{/if}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
|
-
<script>import
|
|
3
|
+
<script>import InlinedStyles from "../../inlined-styles.svelte";
|
|
4
4
|
import { getCss } from "./render-styles.helpers";
|
|
5
5
|
import { getFontCss } from "./render-styles.helpers";
|
|
6
6
|
export let cssCode;
|
|
@@ -30,4 +30,4 @@ ${getFontCss({
|
|
|
30
30
|
`.trim();
|
|
31
31
|
</script>
|
|
32
32
|
|
|
33
|
-
<
|
|
33
|
+
<InlinedStyles styles={injectedStyles} />
|
|
@@ -20,6 +20,7 @@ import { TARGET } from "../../constants/target.js";
|
|
|
20
20
|
import { logger } from "../../helpers/logger.js";
|
|
21
21
|
import { getRenderContentScriptString } from "../render-content-variants/helpers.js";
|
|
22
22
|
import { wrapComponentRef } from "./wrap-component-ref.js";
|
|
23
|
+
import InlinedScript from "../inlined-script.svelte";
|
|
23
24
|
const isEvent = (attr) => attr.startsWith("on:");
|
|
24
25
|
const isNonEvent = (attr) => !attr.startsWith("on:");
|
|
25
26
|
const filterAttrs = (attrs = {}, filter) => {
|
|
@@ -52,12 +53,11 @@ export let model;
|
|
|
52
53
|
export let context;
|
|
53
54
|
export let apiKey;
|
|
54
55
|
export let content;
|
|
55
|
-
export let parentContentId;
|
|
56
56
|
export let data;
|
|
57
57
|
export let locale;
|
|
58
58
|
export let apiVersion;
|
|
59
59
|
export let customComponents;
|
|
60
|
-
export let
|
|
60
|
+
export let showContent;
|
|
61
61
|
export let classNameProp;
|
|
62
62
|
export let isSsrAbTest;
|
|
63
63
|
export let includeRefs;
|
|
@@ -212,9 +212,10 @@ let canTrackToUse = checkIsDefined(canTrack) ? canTrack : true;
|
|
|
212
212
|
let httpReqsData = {};
|
|
213
213
|
let clicked = false;
|
|
214
214
|
let scriptStr = getRenderContentScriptString({
|
|
215
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
|
|
216
|
+
variationId: content?.testVariationId,
|
|
215
217
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-non-null-asserted-optional-chain
|
|
216
218
|
contentId: content?.id,
|
|
217
|
-
parentContentId: parentContentId,
|
|
218
219
|
});
|
|
219
220
|
let builderContextSignal = writable({
|
|
220
221
|
content: getContentInitialValue({
|
|
@@ -376,12 +377,12 @@ onDestroy(() => {
|
|
|
376
377
|
: {},
|
|
377
378
|
isNonEvent
|
|
378
379
|
)}
|
|
379
|
-
{...
|
|
380
|
-
? {
|
|
380
|
+
{...showContent
|
|
381
|
+
? {}
|
|
382
|
+
: {
|
|
381
383
|
hidden: true,
|
|
382
384
|
"aria-hidden": true,
|
|
383
|
-
}
|
|
384
|
-
: {}}
|
|
385
|
+
}}
|
|
385
386
|
class={classNameProp}
|
|
386
387
|
use:setAttrs={filterAttrs(
|
|
387
388
|
TARGET === "reactNative"
|
|
@@ -397,7 +398,7 @@ onDestroy(() => {
|
|
|
397
398
|
)}
|
|
398
399
|
>
|
|
399
400
|
{#if isSsrAbTest}
|
|
400
|
-
<
|
|
401
|
+
<InlinedScript {scriptStr} />
|
|
401
402
|
{/if}
|
|
402
403
|
|
|
403
404
|
{#if TARGET !== "reactNative"}
|
|
@@ -7,12 +7,11 @@ declare const __propDef: {
|
|
|
7
7
|
context: RenderContentProps["context"];
|
|
8
8
|
apiKey: RenderContentProps["apiKey"];
|
|
9
9
|
content: RenderContentProps["content"];
|
|
10
|
-
parentContentId: RenderContentProps["parentContentId"];
|
|
11
10
|
data: RenderContentProps["data"];
|
|
12
11
|
locale: RenderContentProps["locale"];
|
|
13
12
|
apiVersion: RenderContentProps["apiVersion"];
|
|
14
13
|
customComponents: RenderContentProps["customComponents"];
|
|
15
|
-
|
|
14
|
+
showContent: RenderContentProps["showContent"];
|
|
16
15
|
classNameProp: RenderContentProps["classNameProp"];
|
|
17
16
|
isSsrAbTest: RenderContentProps["isSsrAbTest"];
|
|
18
17
|
includeRefs: RenderContentProps["includeRefs"];
|
|
@@ -1,30 +1,15 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
export interface RenderContentProps {
|
|
6
|
-
content?: Nullable<BuilderContent>;
|
|
7
|
-
model?: string;
|
|
8
|
-
data?: {
|
|
9
|
-
[key: string]: any;
|
|
10
|
-
};
|
|
11
|
-
context?: BuilderRenderContext;
|
|
12
|
-
apiKey: string;
|
|
13
|
-
apiVersion?: ApiVersion;
|
|
14
|
-
customComponents?: RegisteredComponent[];
|
|
15
|
-
canTrack?: boolean;
|
|
16
|
-
locale?: string;
|
|
17
|
-
/** @deprecated use `enrich` instead **/
|
|
18
|
-
includeRefs?: boolean;
|
|
19
|
-
enrich?: boolean;
|
|
1
|
+
import type { BuilderRenderState } from '../../context/types';
|
|
2
|
+
import type { EnforcePartials } from '../../types/enforced-partials';
|
|
3
|
+
import type { RenderContentVariantsProps } from '../render-content-variants/render-content-variants.types';
|
|
4
|
+
interface InternalRenderProps {
|
|
20
5
|
/**
|
|
21
6
|
* TO-DO: improve qwik generator to not remap this name for non-HTML tags, then name it `className`
|
|
22
7
|
*/
|
|
23
|
-
classNameProp
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
isSsrAbTest?: boolean;
|
|
8
|
+
classNameProp: string | undefined;
|
|
9
|
+
showContent: boolean;
|
|
10
|
+
isSsrAbTest: boolean;
|
|
27
11
|
}
|
|
12
|
+
export type RenderContentProps = InternalRenderProps & EnforcePartials<RenderContentVariantsProps>;
|
|
28
13
|
export interface BuilderComponentStateChange {
|
|
29
14
|
state: BuilderRenderState;
|
|
30
15
|
ref: {
|
|
@@ -36,3 +21,4 @@ export interface BuilderComponentStateChange {
|
|
|
36
21
|
};
|
|
37
22
|
};
|
|
38
23
|
}
|
|
24
|
+
export {};
|
|
@@ -1,6 +1,29 @@
|
|
|
1
1
|
import type { Nullable } from '../../helpers/nullable';
|
|
2
2
|
import type { BuilderContent } from '../../types/builder-content';
|
|
3
|
-
export declare const getVariants: (content: Nullable<BuilderContent>) =>
|
|
3
|
+
export declare const getVariants: (content: Nullable<BuilderContent>) => {
|
|
4
|
+
testVariationId: string | undefined;
|
|
5
|
+
id: string | undefined;
|
|
6
|
+
data?: {
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
title?: string | undefined;
|
|
9
|
+
blocks?: import("../../types/builder-block").BuilderBlock[] | undefined;
|
|
10
|
+
inputs?: import("../../types/input").Input[] | undefined;
|
|
11
|
+
state?: {
|
|
12
|
+
[key: string]: any;
|
|
13
|
+
} | undefined;
|
|
14
|
+
jsCode?: string | undefined;
|
|
15
|
+
tsCode?: string | undefined;
|
|
16
|
+
httpRequests?: {
|
|
17
|
+
[key: string]: string;
|
|
18
|
+
} | undefined;
|
|
19
|
+
} | undefined;
|
|
20
|
+
name?: string | undefined;
|
|
21
|
+
testRatio?: number | undefined;
|
|
22
|
+
meta?: {
|
|
23
|
+
[key: string]: any;
|
|
24
|
+
breakpoints?: import("../../types/typescript").Nullable<import("../../types/builder-content").Breakpoints>;
|
|
25
|
+
} | undefined;
|
|
26
|
+
}[];
|
|
4
27
|
export declare const checkShouldRunVariants: ({ canTrack, content, }: {
|
|
5
28
|
canTrack: Nullable<boolean>;
|
|
6
29
|
content: Nullable<BuilderContent>;
|
|
@@ -9,9 +32,10 @@ type VariantData = {
|
|
|
9
32
|
id: string;
|
|
10
33
|
testRatio?: number;
|
|
11
34
|
};
|
|
35
|
+
export declare const getScriptString: () => string;
|
|
12
36
|
export declare const getVariantsScriptString: (variants: VariantData[], contentId: string) => string;
|
|
13
|
-
export declare const getRenderContentScriptString: ({
|
|
37
|
+
export declare const getRenderContentScriptString: ({ contentId, variationId, }: {
|
|
38
|
+
variationId: string;
|
|
14
39
|
contentId: string;
|
|
15
|
-
parentContentId: string;
|
|
16
40
|
}) => string;
|
|
17
41
|
export {};
|
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
import { TARGET } from '../../constants/target';
|
|
2
2
|
import { isBrowser } from '../../functions/is-browser';
|
|
3
|
-
export const getVariants = (content) => Object.values(content?.variations || {})
|
|
3
|
+
export const getVariants = (content) => Object.values(content?.variations || {}).map((variant) => ({
|
|
4
|
+
...variant,
|
|
5
|
+
testVariationId: variant.id,
|
|
6
|
+
id: content?.id,
|
|
7
|
+
}));
|
|
4
8
|
export const checkShouldRunVariants = ({ canTrack, content, }) => {
|
|
5
9
|
const hasVariants = getVariants(content).length > 0;
|
|
6
|
-
|
|
10
|
+
/**
|
|
11
|
+
* We cannot SSR in React-Native.
|
|
12
|
+
*/
|
|
13
|
+
if (TARGET === 'reactNative')
|
|
7
14
|
return false;
|
|
8
|
-
|
|
9
|
-
if (!canTrack) {
|
|
15
|
+
if (!hasVariants)
|
|
10
16
|
return false;
|
|
11
|
-
|
|
12
|
-
|
|
17
|
+
if (!canTrack)
|
|
18
|
+
return false;
|
|
19
|
+
/**
|
|
20
|
+
* For Vue 2 and Vue 3, we need to (initially) render the variants. This is to avoid hydration mismatch errors.
|
|
21
|
+
* Unlike React, Vue's hydration checks are shallow and do not check the attributes/contents of each element, so we
|
|
22
|
+
* are able to modify the `hidden` HTML attributes and `display` CSS properties without causing a hydration mismatch error.
|
|
23
|
+
*
|
|
24
|
+
* NOTE: after the app is hydrated, we strip the variants from the DOM (on mount) to reduce the amount of HTML in the DOM.
|
|
25
|
+
*/
|
|
26
|
+
if (TARGET === 'vue2' || TARGET === 'vue3')
|
|
27
|
+
return true;
|
|
28
|
+
if (isBrowser())
|
|
13
29
|
return false;
|
|
14
|
-
}
|
|
15
30
|
return true;
|
|
16
31
|
};
|
|
17
32
|
/**
|
|
@@ -77,13 +92,14 @@ function bldrAbTest(contentId, variants, isHydrationTarget) {
|
|
|
77
92
|
return contentId;
|
|
78
93
|
}
|
|
79
94
|
const winningVariantId = getAndSetVariantId();
|
|
80
|
-
const styleEl = document.
|
|
95
|
+
const styleEl = document.currentScript
|
|
96
|
+
?.previousElementSibling;
|
|
81
97
|
/**
|
|
82
98
|
* For React to work, we need hydration to match SSR, so we completely remove this node and the styles tag.
|
|
83
99
|
*/
|
|
84
100
|
if (isHydrationTarget) {
|
|
85
101
|
styleEl.remove();
|
|
86
|
-
const thisScriptEl = document.
|
|
102
|
+
const thisScriptEl = document.currentScript;
|
|
87
103
|
thisScriptEl?.remove();
|
|
88
104
|
}
|
|
89
105
|
else {
|
|
@@ -96,7 +112,6 @@ function bldrAbTest(contentId, variants, isHydrationTarget) {
|
|
|
96
112
|
`;
|
|
97
113
|
})
|
|
98
114
|
.join('');
|
|
99
|
-
/* TO-DO: check if this actually updates the style */
|
|
100
115
|
styleEl.innerHTML = newStyleStr;
|
|
101
116
|
}
|
|
102
117
|
}
|
|
@@ -122,8 +137,7 @@ function bldrCntntScrpt(variantContentId, defaultContentId, isHydrationTarget) {
|
|
|
122
137
|
}
|
|
123
138
|
const cookieName = `builder.tests.${defaultContentId}`;
|
|
124
139
|
const variantId = getCookie(cookieName);
|
|
125
|
-
|
|
126
|
-
const parentDiv = document.querySelector(`[builder-content-id="${variantContentId}"]`);
|
|
140
|
+
const parentDiv = document.currentScript?.parentElement;
|
|
127
141
|
const variantIsDefaultContent = variantContentId === defaultContentId;
|
|
128
142
|
if (variantId === variantContentId) {
|
|
129
143
|
if (variantIsDefaultContent) {
|
|
@@ -156,10 +170,7 @@ function bldrCntntScrpt(variantContentId, defaultContentId, isHydrationTarget) {
|
|
|
156
170
|
}
|
|
157
171
|
return;
|
|
158
172
|
}
|
|
159
|
-
const getIsHydrationTarget = (target) => target === 'react' ||
|
|
160
|
-
target === 'reactNative' ||
|
|
161
|
-
target === 'vue3' ||
|
|
162
|
-
target === 'vue2';
|
|
173
|
+
const getIsHydrationTarget = (target) => target === 'react' || target === 'reactNative';
|
|
163
174
|
const isHydrationTarget = getIsHydrationTarget(TARGET);
|
|
164
175
|
/**
|
|
165
176
|
* We hardcode explicit function names here, because the `.toString()` of a function can change depending on the bundler.
|
|
@@ -167,18 +178,21 @@ const isHydrationTarget = getIsHydrationTarget(TARGET);
|
|
|
167
178
|
*
|
|
168
179
|
* So we hardcode the function names here, and then use those names in the script string to make sure the function names are consistent.
|
|
169
180
|
*/
|
|
170
|
-
const AB_TEST_FN_NAME = '
|
|
171
|
-
const CONTENT_FN_NAME = '
|
|
172
|
-
export const
|
|
181
|
+
const AB_TEST_FN_NAME = 'builderIoAbTest';
|
|
182
|
+
const CONTENT_FN_NAME = 'builderIoRenderContent';
|
|
183
|
+
export const getScriptString = () => {
|
|
173
184
|
const fnStr = bldrAbTest.toString().replace(/\s+/g, ' ');
|
|
174
185
|
const fnStr2 = bldrCntntScrpt.toString().replace(/\s+/g, ' ');
|
|
175
186
|
return `
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
${AB_TEST_FN_NAME}("${contentId}", ${JSON.stringify(variants)}, ${isHydrationTarget})
|
|
187
|
+
window.${AB_TEST_FN_NAME} = ${fnStr}
|
|
188
|
+
window.${CONTENT_FN_NAME} = ${fnStr2}
|
|
179
189
|
`;
|
|
180
190
|
};
|
|
181
|
-
export const
|
|
191
|
+
export const getVariantsScriptString = (variants, contentId) => {
|
|
192
|
+
return `
|
|
193
|
+
window.${AB_TEST_FN_NAME}("${contentId}",${JSON.stringify(variants)}, ${isHydrationTarget})`;
|
|
194
|
+
};
|
|
195
|
+
export const getRenderContentScriptString = ({ contentId, variationId, }) => {
|
|
182
196
|
return `
|
|
183
|
-
|
|
197
|
+
window.${CONTENT_FN_NAME}("${variationId}", "${contentId}", ${isHydrationTarget})`;
|
|
184
198
|
};
|
|
@@ -1,70 +1,97 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
|
-
<script>import {
|
|
3
|
+
<script>import { onMount } from "svelte";
|
|
4
|
+
import { checkShouldRunVariants, getScriptString, getVariants, getVariantsScriptString, } from "./helpers";
|
|
4
5
|
import RenderContent from "../render-content/render-content.svelte";
|
|
5
6
|
import { getDefaultCanTrack } from "../../helpers/canTrack";
|
|
6
|
-
import
|
|
7
|
+
import InlinedStyles from "../inlined-styles.svelte";
|
|
7
8
|
import { handleABTestingSync } from "../../helpers/ab-tests";
|
|
8
|
-
|
|
9
|
+
import InlinedScript from "../inlined-script.svelte";
|
|
10
|
+
import { TARGET } from "../../constants/target";
|
|
9
11
|
export let canTrack;
|
|
12
|
+
export let content;
|
|
13
|
+
export let __isNestedRender;
|
|
14
|
+
export let model;
|
|
15
|
+
export let data;
|
|
16
|
+
export let context;
|
|
10
17
|
export let apiKey;
|
|
11
18
|
export let apiVersion;
|
|
12
19
|
export let customComponents;
|
|
13
|
-
export let
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
testRatio: value.testRatio,
|
|
17
|
-
})), content?.id || "");
|
|
20
|
+
export let locale;
|
|
21
|
+
export let includeRefs;
|
|
22
|
+
export let enrich;
|
|
18
23
|
let shouldRenderVariants = checkShouldRunVariants({
|
|
19
24
|
canTrack: getDefaultCanTrack(canTrack),
|
|
20
25
|
content: content,
|
|
21
26
|
});
|
|
27
|
+
let variantScriptStr = getVariantsScriptString(getVariants(content).map((value) => ({
|
|
28
|
+
id: value.testVariationId,
|
|
29
|
+
testRatio: value.testRatio,
|
|
30
|
+
})), content?.id || "");
|
|
22
31
|
let hideVariantsStyleString = getVariants(content)
|
|
23
|
-
.map((value) => `.variant-${value.
|
|
32
|
+
.map((value) => `.variant-${value.testVariationId} { display: none; } `)
|
|
24
33
|
.join("");
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
});
|
|
34
|
+
onMount(() => {
|
|
35
|
+
/**
|
|
36
|
+
* We unmount the non-winning variants post-hydration in Vue.
|
|
37
|
+
*/
|
|
38
|
+
if (TARGET === "vue2" || TARGET === "vue3") {
|
|
39
|
+
shouldRenderVariants = false;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
34
42
|
</script>
|
|
35
43
|
|
|
44
|
+
{#if !__isNestedRender && TARGET !== "reactNative"}
|
|
45
|
+
<InlinedScript scriptStr={getScriptString()} />
|
|
46
|
+
{/if}
|
|
47
|
+
|
|
36
48
|
{#if shouldRenderVariants}
|
|
37
|
-
<
|
|
49
|
+
<InlinedStyles
|
|
38
50
|
id={`variants-styles-${content?.id}`}
|
|
39
51
|
styles={hideVariantsStyleString}
|
|
40
52
|
/>
|
|
41
53
|
|
|
42
|
-
<
|
|
43
|
-
>{@html variantScriptStr}</svelte:element
|
|
44
|
-
>
|
|
54
|
+
<InlinedScript scriptStr={variantScriptStr} />
|
|
45
55
|
|
|
46
|
-
{#each getVariants(content) as variant (variant.
|
|
56
|
+
{#each getVariants(content) as variant (variant.testVariationId)}
|
|
47
57
|
<RenderContent
|
|
48
58
|
content={variant}
|
|
59
|
+
showContent={false}
|
|
60
|
+
classNameProp={undefined}
|
|
61
|
+
{model}
|
|
62
|
+
{data}
|
|
63
|
+
{context}
|
|
49
64
|
{apiKey}
|
|
50
65
|
{apiVersion}
|
|
51
|
-
{canTrack}
|
|
52
66
|
{customComponents}
|
|
53
|
-
|
|
54
|
-
|
|
67
|
+
{canTrack}
|
|
68
|
+
{locale}
|
|
69
|
+
{includeRefs}
|
|
70
|
+
{enrich}
|
|
55
71
|
isSsrAbTest={shouldRenderVariants}
|
|
56
72
|
/>
|
|
57
73
|
{/each}
|
|
58
74
|
{/if}
|
|
59
75
|
|
|
60
76
|
<RenderContent
|
|
77
|
+
{...{}}
|
|
78
|
+
content={shouldRenderVariants
|
|
79
|
+
? content
|
|
80
|
+
: handleABTestingSync({
|
|
81
|
+
item: content,
|
|
82
|
+
canTrack: getDefaultCanTrack(canTrack),
|
|
83
|
+
})}
|
|
84
|
+
classNameProp={`variant-${content?.id}`}
|
|
85
|
+
showContent={true}
|
|
61
86
|
{model}
|
|
62
|
-
|
|
87
|
+
{data}
|
|
88
|
+
{context}
|
|
63
89
|
{apiKey}
|
|
64
90
|
{apiVersion}
|
|
65
|
-
{canTrack}
|
|
66
91
|
{customComponents}
|
|
67
|
-
|
|
68
|
-
|
|
92
|
+
{canTrack}
|
|
93
|
+
{locale}
|
|
94
|
+
{includeRefs}
|
|
95
|
+
{enrich}
|
|
69
96
|
isSsrAbTest={shouldRenderVariants}
|
|
70
97
|
/>
|
|
@@ -1,14 +1,25 @@
|
|
|
1
1
|
import { SvelteComponentTyped } from "svelte";
|
|
2
|
-
type VariantsProviderProps =
|
|
3
|
-
|
|
2
|
+
type VariantsProviderProps = RenderContentVariantsProps & {
|
|
3
|
+
/**
|
|
4
|
+
* For internal use only. Do not provide this prop.
|
|
5
|
+
*/
|
|
6
|
+
__isNestedRender?: boolean;
|
|
7
|
+
};
|
|
8
|
+
import type { RenderContentVariantsProps } from "./render-content-variants.types";
|
|
4
9
|
declare const __propDef: {
|
|
5
10
|
props: {
|
|
6
|
-
content: VariantsProviderProps["content"];
|
|
7
11
|
canTrack: VariantsProviderProps["canTrack"];
|
|
12
|
+
content: VariantsProviderProps["content"];
|
|
13
|
+
__isNestedRender: VariantsProviderProps["__isNestedRender"];
|
|
14
|
+
model: VariantsProviderProps["model"];
|
|
15
|
+
data: VariantsProviderProps["data"];
|
|
16
|
+
context: VariantsProviderProps["context"];
|
|
8
17
|
apiKey: VariantsProviderProps["apiKey"];
|
|
9
18
|
apiVersion: VariantsProviderProps["apiVersion"];
|
|
10
19
|
customComponents: VariantsProviderProps["customComponents"];
|
|
11
|
-
|
|
20
|
+
locale: VariantsProviderProps["locale"];
|
|
21
|
+
includeRefs: VariantsProviderProps["includeRefs"];
|
|
22
|
+
enrich: VariantsProviderProps["enrich"];
|
|
12
23
|
};
|
|
13
24
|
events: {
|
|
14
25
|
[evt: string]: CustomEvent<any>;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { BuilderRenderContext, RegisteredComponent } from '../../context/types';
|
|
2
|
+
import type { ApiVersion } from '../../types/api-version';
|
|
3
|
+
import type { BuilderContent } from '../../types/builder-content';
|
|
4
|
+
import type { Nullable } from '../../types/typescript';
|
|
5
|
+
export interface RenderContentVariantsProps {
|
|
6
|
+
content?: Nullable<BuilderContent>;
|
|
7
|
+
model?: string;
|
|
8
|
+
data?: {
|
|
9
|
+
[key: string]: any;
|
|
10
|
+
};
|
|
11
|
+
context?: BuilderRenderContext;
|
|
12
|
+
apiKey: string;
|
|
13
|
+
apiVersion?: ApiVersion;
|
|
14
|
+
customComponents?: RegisteredComponent[];
|
|
15
|
+
canTrack?: boolean;
|
|
16
|
+
locale?: string;
|
|
17
|
+
/** @deprecated use `enrich` instead **/
|
|
18
|
+
includeRefs?: boolean;
|
|
19
|
+
enrich?: boolean;
|
|
20
|
+
}
|