@builder.io/sdk-svelte 4.0.1 → 4.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/blocks/custom-code/custom-code.svelte +22 -8
- package/lib/browser/blocks/embed/embed.svelte +3 -2
- package/lib/browser/components/content/components/enable-editor.svelte +9 -3
- package/lib/browser/components/content-variants/helpers.js +2 -1
- package/lib/browser/components/content-variants/inlined-fns.d.ts +1 -1
- package/lib/browser/components/content-variants/inlined-fns.js +1 -1
- package/lib/browser/constants/sdk-version.d.ts +1 -1
- package/lib/browser/constants/sdk-version.js +1 -1
- package/lib/edge/blocks/custom-code/custom-code.svelte +22 -8
- package/lib/edge/blocks/embed/embed.svelte +3 -2
- package/lib/edge/components/content/components/enable-editor.svelte +9 -3
- package/lib/edge/components/content-variants/helpers.js +2 -1
- package/lib/edge/components/content-variants/inlined-fns.d.ts +1 -1
- package/lib/edge/components/content-variants/inlined-fns.js +1 -1
- package/lib/edge/constants/sdk-version.d.ts +1 -1
- package/lib/edge/constants/sdk-version.js +1 -1
- package/lib/node/blocks/custom-code/custom-code.svelte +22 -8
- package/lib/node/blocks/embed/embed.svelte +3 -2
- package/lib/node/components/content/components/enable-editor.svelte +9 -3
- package/lib/node/components/content-variants/helpers.js +2 -1
- package/lib/node/components/content-variants/inlined-fns.d.ts +1 -1
- package/lib/node/components/content-variants/inlined-fns.js +1 -1
- package/lib/node/constants/sdk-version.d.ts +1 -1
- package/lib/node/constants/sdk-version.js +1 -1
- package/package.json +1 -1
- package/src/blocks/custom-code/custom-code.svelte +33 -10
- package/src/blocks/embed/embed.svelte +2 -1
- package/src/components/content/components/enable-editor.svelte +10 -3
- package/src/components/content-variants/helpers.ts +2 -1
- package/src/components/content-variants/inlined-fns.ts +1 -1
- package/src/constants/sdk-version.ts +1 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
3
|
<script>import { onMount } from "svelte";
|
|
4
|
-
|
|
4
|
+
import { isEditing } from "../../functions/is-editing";
|
|
5
|
+
import { logger } from "../../helpers/logger";
|
|
5
6
|
export let code;
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (!elementRef?.getElementsByTagName || typeof window === "undefined") {
|
|
7
|
+
export let replaceNodes = undefined;
|
|
8
|
+
function runScripts() {
|
|
9
|
+
if (!elementRef ||
|
|
10
|
+
!elementRef?.getElementsByTagName ||
|
|
11
|
+
typeof window === "undefined") {
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
14
|
const scripts = elementRef.getElementsByTagName("script");
|
|
@@ -38,11 +38,25 @@ onMount(() => {
|
|
|
38
38
|
new Function(script.innerText)();
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
|
-
|
|
41
|
+
logger.warn("[BUILDER.IO] `CustomCode`: Error running script:", error);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
+
}
|
|
46
|
+
let elementRef;
|
|
47
|
+
let scriptsInserted = [];
|
|
48
|
+
let scriptsRun = [];
|
|
49
|
+
onMount(() => {
|
|
50
|
+
runScripts();
|
|
45
51
|
});
|
|
52
|
+
function onUpdateFn_0(..._args) {
|
|
53
|
+
if (isEditing()) {
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
runScripts();
|
|
56
|
+
}, 0);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
$: onUpdateFn_0(...[code]);
|
|
46
60
|
</script>
|
|
47
61
|
|
|
48
62
|
<div
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
|
-
<script>import {
|
|
3
|
+
<script>import { logger } from "../../helpers/logger";
|
|
4
|
+
import { isJsScript } from "./helpers";
|
|
4
5
|
export let content;
|
|
5
6
|
function findAndRunScripts() {
|
|
6
7
|
if (!elem || !elem.getElementsByTagName)
|
|
@@ -21,7 +22,7 @@ function findAndRunScripts() {
|
|
|
21
22
|
new Function(script.innerText)();
|
|
22
23
|
}
|
|
23
24
|
catch (error) {
|
|
24
|
-
|
|
25
|
+
logger.warn("[BUILDER.IO] `Embed`: Error running script:", error);
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
}
|
|
@@ -13,6 +13,7 @@ import { createRegisterComponentMessage } from "../../../functions/register-comp
|
|
|
13
13
|
import { _track } from "../../../functions/track/index";
|
|
14
14
|
import { getInteractionPropertiesForEvent } from "../../../functions/track/interaction";
|
|
15
15
|
import { getDefaultCanTrack } from "../../../helpers/canTrack";
|
|
16
|
+
import { getCookieSync } from "../../../helpers/cookie";
|
|
16
17
|
import "../../../helpers/preview-lru-cache/set";
|
|
17
18
|
import { createEditorListener } from "../../../helpers/subscribe-to-editor";
|
|
18
19
|
import { registerInsertMenu, setupBrowserForEditing, } from "../../../scripts/init-editing";
|
|
@@ -247,6 +248,7 @@ $: showContentProps = () => {
|
|
|
247
248
|
};
|
|
248
249
|
};
|
|
249
250
|
let elementRef;
|
|
251
|
+
let hasExecuted = false;
|
|
250
252
|
let ContentWrapper = contentWrapper || "div";
|
|
251
253
|
let httpReqsData = {};
|
|
252
254
|
let httpReqsPending = {};
|
|
@@ -261,8 +263,12 @@ onMount(() => {
|
|
|
261
263
|
}
|
|
262
264
|
}
|
|
263
265
|
const shouldTrackImpression = $builderContextSignal.content && getDefaultCanTrack(canTrack);
|
|
264
|
-
|
|
265
|
-
|
|
266
|
+
const winningVariantId = getCookieSync({
|
|
267
|
+
name: `builder.tests.${$builderContextSignal.content?.id}`,
|
|
268
|
+
canTrack: true,
|
|
269
|
+
});
|
|
270
|
+
const variationId = $builderContextSignal.content?.testVariationId;
|
|
271
|
+
if (shouldTrackImpression && variationId === winningVariantId) {
|
|
266
272
|
const contentId = $builderContextSignal.content?.id;
|
|
267
273
|
const apiKeyProp = apiKey;
|
|
268
274
|
_track({
|
|
@@ -271,7 +277,7 @@ onMount(() => {
|
|
|
271
277
|
canTrack: true,
|
|
272
278
|
contentId,
|
|
273
279
|
apiKey: apiKeyProp,
|
|
274
|
-
variationId:
|
|
280
|
+
variationId: winningVariantId !== contentId ? winningVariantId : undefined,
|
|
275
281
|
});
|
|
276
282
|
}
|
|
277
283
|
/**
|
|
@@ -41,6 +41,7 @@ export const checkShouldRenderVariants = ({ canTrack, content }) => {
|
|
|
41
41
|
return true;
|
|
42
42
|
};
|
|
43
43
|
const getIsHydrationTarget = (target) => target === 'react' || target === 'reactNative';
|
|
44
|
+
const isAngularSDK = TARGET === 'angular';
|
|
44
45
|
const isHydrationTarget = getIsHydrationTarget(TARGET);
|
|
45
46
|
export const getInitVariantsFnsScriptString = () => `
|
|
46
47
|
window.${UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME} = ${UPDATE_COOKIES_AND_STYLES_SCRIPT}
|
|
@@ -48,7 +49,7 @@ export const getInitVariantsFnsScriptString = () => `
|
|
|
48
49
|
`;
|
|
49
50
|
export const getUpdateCookieAndStylesScript = (variants, contentId) => `
|
|
50
51
|
window.${UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME}(
|
|
51
|
-
"${contentId}",${JSON.stringify(variants)}, ${isHydrationTarget}
|
|
52
|
+
"${contentId}",${JSON.stringify(variants)}, ${isHydrationTarget}, ${isAngularSDK}
|
|
52
53
|
)`;
|
|
53
54
|
export const getUpdateVariantVisibilityScript = ({ contentId, variationId }) => `window.${UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME}(
|
|
54
55
|
"${variationId}", "${contentId}", ${isHydrationTarget}
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
* For more information on how this works,
|
|
11
11
|
* see our [SSR A/B Test Docs](https://github.com/BuilderIO/builder/tree/main/packages/sdks/docs/SSR_AB_TEST.md)
|
|
12
12
|
*/
|
|
13
|
-
export declare const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n
|
|
13
|
+
export declare const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget, isAngularSDK) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n let styleEl = document.currentScript?.previousElementSibling;\n if (isAngularSDK) {\n styleEl = document.currentScript?.parentElement?.previousElementSibling?.querySelector('style');\n }\n if (isHydrationTarget) {\n styleEl.remove();\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n } else {\n const newStyleStr = variants.concat({\n id: contentId\n }).filter(variant => variant.id !== winningVariantId).map(value => {\n return `.variant-${value.id} { display: none; }\n `;\n }).join('');\n styleEl.innerHTML = newStyleStr;\n }\n}";
|
|
14
14
|
export declare const UPDATE_VARIANT_VISIBILITY_SCRIPT = "function updateVariantVisibility(variantContentId, defaultContentId, isHydrationTarget) {\n if (!navigator.cookieEnabled) {\n return;\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${defaultContentId}`;\n const winningVariant = getCookie(cookieName);\n const parentDiv = document.currentScript?.parentElement;\n const isDefaultContent = variantContentId === defaultContentId;\n const isWinningVariant = winningVariant === variantContentId;\n if (isWinningVariant && !isDefaultContent) {\n parentDiv?.removeAttribute('hidden');\n parentDiv?.removeAttribute('aria-hidden');\n } else if (!isWinningVariant && isDefaultContent) {\n parentDiv?.setAttribute('hidden', 'true');\n parentDiv?.setAttribute('aria-hidden', 'true');\n }\n if (isHydrationTarget) {\n if (!isWinningVariant) {\n parentDiv?.remove();\n }\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n }\n return;\n}";
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
* For more information on how this works,
|
|
11
11
|
* see our [SSR A/B Test Docs](https://github.com/BuilderIO/builder/tree/main/packages/sdks/docs/SSR_AB_TEST.md)
|
|
12
12
|
*/
|
|
13
|
-
export const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n
|
|
13
|
+
export const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget, isAngularSDK) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n let styleEl = document.currentScript?.previousElementSibling;\n if (isAngularSDK) {\n styleEl = document.currentScript?.parentElement?.previousElementSibling?.querySelector('style');\n }\n if (isHydrationTarget) {\n styleEl.remove();\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n } else {\n const newStyleStr = variants.concat({\n id: contentId\n }).filter(variant => variant.id !== winningVariantId).map(value => {\n return `.variant-${value.id} { display: none; }\n `;\n }).join('');\n styleEl.innerHTML = newStyleStr;\n }\n}";
|
|
14
14
|
export const UPDATE_VARIANT_VISIBILITY_SCRIPT = "function updateVariantVisibility(variantContentId, defaultContentId, isHydrationTarget) {\n if (!navigator.cookieEnabled) {\n return;\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${defaultContentId}`;\n const winningVariant = getCookie(cookieName);\n const parentDiv = document.currentScript?.parentElement;\n const isDefaultContent = variantContentId === defaultContentId;\n const isWinningVariant = winningVariant === variantContentId;\n if (isWinningVariant && !isDefaultContent) {\n parentDiv?.removeAttribute('hidden');\n parentDiv?.removeAttribute('aria-hidden');\n } else if (!isWinningVariant && isDefaultContent) {\n parentDiv?.setAttribute('hidden', 'true');\n parentDiv?.setAttribute('aria-hidden', 'true');\n }\n if (isHydrationTarget) {\n if (!isWinningVariant) {\n parentDiv?.remove();\n }\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n }\n return;\n}";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "4.0.
|
|
1
|
+
export declare const SDK_VERSION = "4.0.3";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "4.0.
|
|
1
|
+
export const SDK_VERSION = "4.0.3";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
3
|
<script>import { onMount } from "svelte";
|
|
4
|
-
|
|
4
|
+
import { isEditing } from "../../functions/is-editing";
|
|
5
|
+
import { logger } from "../../helpers/logger";
|
|
5
6
|
export let code;
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (!elementRef?.getElementsByTagName || typeof window === "undefined") {
|
|
7
|
+
export let replaceNodes = undefined;
|
|
8
|
+
function runScripts() {
|
|
9
|
+
if (!elementRef ||
|
|
10
|
+
!elementRef?.getElementsByTagName ||
|
|
11
|
+
typeof window === "undefined") {
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
14
|
const scripts = elementRef.getElementsByTagName("script");
|
|
@@ -38,11 +38,25 @@ onMount(() => {
|
|
|
38
38
|
new Function(script.innerText)();
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
|
-
|
|
41
|
+
logger.warn("[BUILDER.IO] `CustomCode`: Error running script:", error);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
+
}
|
|
46
|
+
let elementRef;
|
|
47
|
+
let scriptsInserted = [];
|
|
48
|
+
let scriptsRun = [];
|
|
49
|
+
onMount(() => {
|
|
50
|
+
runScripts();
|
|
45
51
|
});
|
|
52
|
+
function onUpdateFn_0(..._args) {
|
|
53
|
+
if (isEditing()) {
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
runScripts();
|
|
56
|
+
}, 0);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
$: onUpdateFn_0(...[code]);
|
|
46
60
|
</script>
|
|
47
61
|
|
|
48
62
|
<div
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
|
-
<script>import {
|
|
3
|
+
<script>import { logger } from "../../helpers/logger";
|
|
4
|
+
import { isJsScript } from "./helpers";
|
|
4
5
|
export let content;
|
|
5
6
|
function findAndRunScripts() {
|
|
6
7
|
if (!elem || !elem.getElementsByTagName)
|
|
@@ -21,7 +22,7 @@ function findAndRunScripts() {
|
|
|
21
22
|
new Function(script.innerText)();
|
|
22
23
|
}
|
|
23
24
|
catch (error) {
|
|
24
|
-
|
|
25
|
+
logger.warn("[BUILDER.IO] `Embed`: Error running script:", error);
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
}
|
|
@@ -13,6 +13,7 @@ import { createRegisterComponentMessage } from "../../../functions/register-comp
|
|
|
13
13
|
import { _track } from "../../../functions/track/index";
|
|
14
14
|
import { getInteractionPropertiesForEvent } from "../../../functions/track/interaction";
|
|
15
15
|
import { getDefaultCanTrack } from "../../../helpers/canTrack";
|
|
16
|
+
import { getCookieSync } from "../../../helpers/cookie";
|
|
16
17
|
import "../../../helpers/preview-lru-cache/set";
|
|
17
18
|
import { createEditorListener } from "../../../helpers/subscribe-to-editor";
|
|
18
19
|
import { registerInsertMenu, setupBrowserForEditing, } from "../../../scripts/init-editing";
|
|
@@ -247,6 +248,7 @@ $: showContentProps = () => {
|
|
|
247
248
|
};
|
|
248
249
|
};
|
|
249
250
|
let elementRef;
|
|
251
|
+
let hasExecuted = false;
|
|
250
252
|
let ContentWrapper = contentWrapper || "div";
|
|
251
253
|
let httpReqsData = {};
|
|
252
254
|
let httpReqsPending = {};
|
|
@@ -261,8 +263,12 @@ onMount(() => {
|
|
|
261
263
|
}
|
|
262
264
|
}
|
|
263
265
|
const shouldTrackImpression = $builderContextSignal.content && getDefaultCanTrack(canTrack);
|
|
264
|
-
|
|
265
|
-
|
|
266
|
+
const winningVariantId = getCookieSync({
|
|
267
|
+
name: `builder.tests.${$builderContextSignal.content?.id}`,
|
|
268
|
+
canTrack: true,
|
|
269
|
+
});
|
|
270
|
+
const variationId = $builderContextSignal.content?.testVariationId;
|
|
271
|
+
if (shouldTrackImpression && variationId === winningVariantId) {
|
|
266
272
|
const contentId = $builderContextSignal.content?.id;
|
|
267
273
|
const apiKeyProp = apiKey;
|
|
268
274
|
_track({
|
|
@@ -271,7 +277,7 @@ onMount(() => {
|
|
|
271
277
|
canTrack: true,
|
|
272
278
|
contentId,
|
|
273
279
|
apiKey: apiKeyProp,
|
|
274
|
-
variationId:
|
|
280
|
+
variationId: winningVariantId !== contentId ? winningVariantId : undefined,
|
|
275
281
|
});
|
|
276
282
|
}
|
|
277
283
|
/**
|
|
@@ -41,6 +41,7 @@ export const checkShouldRenderVariants = ({ canTrack, content }) => {
|
|
|
41
41
|
return true;
|
|
42
42
|
};
|
|
43
43
|
const getIsHydrationTarget = (target) => target === 'react' || target === 'reactNative';
|
|
44
|
+
const isAngularSDK = TARGET === 'angular';
|
|
44
45
|
const isHydrationTarget = getIsHydrationTarget(TARGET);
|
|
45
46
|
export const getInitVariantsFnsScriptString = () => `
|
|
46
47
|
window.${UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME} = ${UPDATE_COOKIES_AND_STYLES_SCRIPT}
|
|
@@ -48,7 +49,7 @@ export const getInitVariantsFnsScriptString = () => `
|
|
|
48
49
|
`;
|
|
49
50
|
export const getUpdateCookieAndStylesScript = (variants, contentId) => `
|
|
50
51
|
window.${UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME}(
|
|
51
|
-
"${contentId}",${JSON.stringify(variants)}, ${isHydrationTarget}
|
|
52
|
+
"${contentId}",${JSON.stringify(variants)}, ${isHydrationTarget}, ${isAngularSDK}
|
|
52
53
|
)`;
|
|
53
54
|
export const getUpdateVariantVisibilityScript = ({ contentId, variationId }) => `window.${UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME}(
|
|
54
55
|
"${variationId}", "${contentId}", ${isHydrationTarget}
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
* For more information on how this works,
|
|
11
11
|
* see our [SSR A/B Test Docs](https://github.com/BuilderIO/builder/tree/main/packages/sdks/docs/SSR_AB_TEST.md)
|
|
12
12
|
*/
|
|
13
|
-
export declare const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n
|
|
13
|
+
export declare const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget, isAngularSDK) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n let styleEl = document.currentScript?.previousElementSibling;\n if (isAngularSDK) {\n styleEl = document.currentScript?.parentElement?.previousElementSibling?.querySelector('style');\n }\n if (isHydrationTarget) {\n styleEl.remove();\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n } else {\n const newStyleStr = variants.concat({\n id: contentId\n }).filter(variant => variant.id !== winningVariantId).map(value => {\n return `.variant-${value.id} { display: none; }\n `;\n }).join('');\n styleEl.innerHTML = newStyleStr;\n }\n}";
|
|
14
14
|
export declare const UPDATE_VARIANT_VISIBILITY_SCRIPT = "function updateVariantVisibility(variantContentId, defaultContentId, isHydrationTarget) {\n if (!navigator.cookieEnabled) {\n return;\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${defaultContentId}`;\n const winningVariant = getCookie(cookieName);\n const parentDiv = document.currentScript?.parentElement;\n const isDefaultContent = variantContentId === defaultContentId;\n const isWinningVariant = winningVariant === variantContentId;\n if (isWinningVariant && !isDefaultContent) {\n parentDiv?.removeAttribute('hidden');\n parentDiv?.removeAttribute('aria-hidden');\n } else if (!isWinningVariant && isDefaultContent) {\n parentDiv?.setAttribute('hidden', 'true');\n parentDiv?.setAttribute('aria-hidden', 'true');\n }\n if (isHydrationTarget) {\n if (!isWinningVariant) {\n parentDiv?.remove();\n }\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n }\n return;\n}";
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
* For more information on how this works,
|
|
11
11
|
* see our [SSR A/B Test Docs](https://github.com/BuilderIO/builder/tree/main/packages/sdks/docs/SSR_AB_TEST.md)
|
|
12
12
|
*/
|
|
13
|
-
export const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n
|
|
13
|
+
export const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget, isAngularSDK) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n let styleEl = document.currentScript?.previousElementSibling;\n if (isAngularSDK) {\n styleEl = document.currentScript?.parentElement?.previousElementSibling?.querySelector('style');\n }\n if (isHydrationTarget) {\n styleEl.remove();\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n } else {\n const newStyleStr = variants.concat({\n id: contentId\n }).filter(variant => variant.id !== winningVariantId).map(value => {\n return `.variant-${value.id} { display: none; }\n `;\n }).join('');\n styleEl.innerHTML = newStyleStr;\n }\n}";
|
|
14
14
|
export const UPDATE_VARIANT_VISIBILITY_SCRIPT = "function updateVariantVisibility(variantContentId, defaultContentId, isHydrationTarget) {\n if (!navigator.cookieEnabled) {\n return;\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${defaultContentId}`;\n const winningVariant = getCookie(cookieName);\n const parentDiv = document.currentScript?.parentElement;\n const isDefaultContent = variantContentId === defaultContentId;\n const isWinningVariant = winningVariant === variantContentId;\n if (isWinningVariant && !isDefaultContent) {\n parentDiv?.removeAttribute('hidden');\n parentDiv?.removeAttribute('aria-hidden');\n } else if (!isWinningVariant && isDefaultContent) {\n parentDiv?.setAttribute('hidden', 'true');\n parentDiv?.setAttribute('aria-hidden', 'true');\n }\n if (isHydrationTarget) {\n if (!isWinningVariant) {\n parentDiv?.remove();\n }\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n }\n return;\n}";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "4.0.
|
|
1
|
+
export declare const SDK_VERSION = "4.0.3";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "4.0.
|
|
1
|
+
export const SDK_VERSION = "4.0.3";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
3
|
<script>import { onMount } from "svelte";
|
|
4
|
-
|
|
4
|
+
import { isEditing } from "../../functions/is-editing";
|
|
5
|
+
import { logger } from "../../helpers/logger";
|
|
5
6
|
export let code;
|
|
6
|
-
let
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (!elementRef?.getElementsByTagName || typeof window === "undefined") {
|
|
7
|
+
export let replaceNodes = undefined;
|
|
8
|
+
function runScripts() {
|
|
9
|
+
if (!elementRef ||
|
|
10
|
+
!elementRef?.getElementsByTagName ||
|
|
11
|
+
typeof window === "undefined") {
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
14
|
const scripts = elementRef.getElementsByTagName("script");
|
|
@@ -38,11 +38,25 @@ onMount(() => {
|
|
|
38
38
|
new Function(script.innerText)();
|
|
39
39
|
}
|
|
40
40
|
catch (error) {
|
|
41
|
-
|
|
41
|
+
logger.warn("[BUILDER.IO] `CustomCode`: Error running script:", error);
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
+
}
|
|
46
|
+
let elementRef;
|
|
47
|
+
let scriptsInserted = [];
|
|
48
|
+
let scriptsRun = [];
|
|
49
|
+
onMount(() => {
|
|
50
|
+
runScripts();
|
|
45
51
|
});
|
|
52
|
+
function onUpdateFn_0(..._args) {
|
|
53
|
+
if (isEditing()) {
|
|
54
|
+
setTimeout(() => {
|
|
55
|
+
runScripts();
|
|
56
|
+
}, 0);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
$: onUpdateFn_0(...[code]);
|
|
46
60
|
</script>
|
|
47
61
|
|
|
48
62
|
<div
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script context="module"></script>
|
|
2
2
|
|
|
3
|
-
<script>import {
|
|
3
|
+
<script>import { logger } from "../../helpers/logger";
|
|
4
|
+
import { isJsScript } from "./helpers";
|
|
4
5
|
export let content;
|
|
5
6
|
function findAndRunScripts() {
|
|
6
7
|
if (!elem || !elem.getElementsByTagName)
|
|
@@ -21,7 +22,7 @@ function findAndRunScripts() {
|
|
|
21
22
|
new Function(script.innerText)();
|
|
22
23
|
}
|
|
23
24
|
catch (error) {
|
|
24
|
-
|
|
25
|
+
logger.warn("[BUILDER.IO] `Embed`: Error running script:", error);
|
|
25
26
|
}
|
|
26
27
|
}
|
|
27
28
|
}
|
|
@@ -13,6 +13,7 @@ import { createRegisterComponentMessage } from "../../../functions/register-comp
|
|
|
13
13
|
import { _track } from "../../../functions/track/index";
|
|
14
14
|
import { getInteractionPropertiesForEvent } from "../../../functions/track/interaction";
|
|
15
15
|
import { getDefaultCanTrack } from "../../../helpers/canTrack";
|
|
16
|
+
import { getCookieSync } from "../../../helpers/cookie";
|
|
16
17
|
import "../../../helpers/preview-lru-cache/set";
|
|
17
18
|
import { createEditorListener } from "../../../helpers/subscribe-to-editor";
|
|
18
19
|
import { registerInsertMenu, setupBrowserForEditing, } from "../../../scripts/init-editing";
|
|
@@ -247,6 +248,7 @@ $: showContentProps = () => {
|
|
|
247
248
|
};
|
|
248
249
|
};
|
|
249
250
|
let elementRef;
|
|
251
|
+
let hasExecuted = false;
|
|
250
252
|
let ContentWrapper = contentWrapper || "div";
|
|
251
253
|
let httpReqsData = {};
|
|
252
254
|
let httpReqsPending = {};
|
|
@@ -261,8 +263,12 @@ onMount(() => {
|
|
|
261
263
|
}
|
|
262
264
|
}
|
|
263
265
|
const shouldTrackImpression = $builderContextSignal.content && getDefaultCanTrack(canTrack);
|
|
264
|
-
|
|
265
|
-
|
|
266
|
+
const winningVariantId = getCookieSync({
|
|
267
|
+
name: `builder.tests.${$builderContextSignal.content?.id}`,
|
|
268
|
+
canTrack: true,
|
|
269
|
+
});
|
|
270
|
+
const variationId = $builderContextSignal.content?.testVariationId;
|
|
271
|
+
if (shouldTrackImpression && variationId === winningVariantId) {
|
|
266
272
|
const contentId = $builderContextSignal.content?.id;
|
|
267
273
|
const apiKeyProp = apiKey;
|
|
268
274
|
_track({
|
|
@@ -271,7 +277,7 @@ onMount(() => {
|
|
|
271
277
|
canTrack: true,
|
|
272
278
|
contentId,
|
|
273
279
|
apiKey: apiKeyProp,
|
|
274
|
-
variationId:
|
|
280
|
+
variationId: winningVariantId !== contentId ? winningVariantId : undefined,
|
|
275
281
|
});
|
|
276
282
|
}
|
|
277
283
|
/**
|
|
@@ -41,6 +41,7 @@ export const checkShouldRenderVariants = ({ canTrack, content }) => {
|
|
|
41
41
|
return true;
|
|
42
42
|
};
|
|
43
43
|
const getIsHydrationTarget = (target) => target === 'react' || target === 'reactNative';
|
|
44
|
+
const isAngularSDK = TARGET === 'angular';
|
|
44
45
|
const isHydrationTarget = getIsHydrationTarget(TARGET);
|
|
45
46
|
export const getInitVariantsFnsScriptString = () => `
|
|
46
47
|
window.${UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME} = ${UPDATE_COOKIES_AND_STYLES_SCRIPT}
|
|
@@ -48,7 +49,7 @@ export const getInitVariantsFnsScriptString = () => `
|
|
|
48
49
|
`;
|
|
49
50
|
export const getUpdateCookieAndStylesScript = (variants, contentId) => `
|
|
50
51
|
window.${UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME}(
|
|
51
|
-
"${contentId}",${JSON.stringify(variants)}, ${isHydrationTarget}
|
|
52
|
+
"${contentId}",${JSON.stringify(variants)}, ${isHydrationTarget}, ${isAngularSDK}
|
|
52
53
|
)`;
|
|
53
54
|
export const getUpdateVariantVisibilityScript = ({ contentId, variationId }) => `window.${UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME}(
|
|
54
55
|
"${variationId}", "${contentId}", ${isHydrationTarget}
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
* For more information on how this works,
|
|
11
11
|
* see our [SSR A/B Test Docs](https://github.com/BuilderIO/builder/tree/main/packages/sdks/docs/SSR_AB_TEST.md)
|
|
12
12
|
*/
|
|
13
|
-
export declare const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n
|
|
13
|
+
export declare const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget, isAngularSDK) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n let styleEl = document.currentScript?.previousElementSibling;\n if (isAngularSDK) {\n styleEl = document.currentScript?.parentElement?.previousElementSibling?.querySelector('style');\n }\n if (isHydrationTarget) {\n styleEl.remove();\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n } else {\n const newStyleStr = variants.concat({\n id: contentId\n }).filter(variant => variant.id !== winningVariantId).map(value => {\n return `.variant-${value.id} { display: none; }\n `;\n }).join('');\n styleEl.innerHTML = newStyleStr;\n }\n}";
|
|
14
14
|
export declare const UPDATE_VARIANT_VISIBILITY_SCRIPT = "function updateVariantVisibility(variantContentId, defaultContentId, isHydrationTarget) {\n if (!navigator.cookieEnabled) {\n return;\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${defaultContentId}`;\n const winningVariant = getCookie(cookieName);\n const parentDiv = document.currentScript?.parentElement;\n const isDefaultContent = variantContentId === defaultContentId;\n const isWinningVariant = winningVariant === variantContentId;\n if (isWinningVariant && !isDefaultContent) {\n parentDiv?.removeAttribute('hidden');\n parentDiv?.removeAttribute('aria-hidden');\n } else if (!isWinningVariant && isDefaultContent) {\n parentDiv?.setAttribute('hidden', 'true');\n parentDiv?.setAttribute('aria-hidden', 'true');\n }\n if (isHydrationTarget) {\n if (!isWinningVariant) {\n parentDiv?.remove();\n }\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n }\n return;\n}";
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
* For more information on how this works,
|
|
11
11
|
* see our [SSR A/B Test Docs](https://github.com/BuilderIO/builder/tree/main/packages/sdks/docs/SSR_AB_TEST.md)
|
|
12
12
|
*/
|
|
13
|
-
export const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n
|
|
13
|
+
export const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget, isAngularSDK) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n let styleEl = document.currentScript?.previousElementSibling;\n if (isAngularSDK) {\n styleEl = document.currentScript?.parentElement?.previousElementSibling?.querySelector('style');\n }\n if (isHydrationTarget) {\n styleEl.remove();\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n } else {\n const newStyleStr = variants.concat({\n id: contentId\n }).filter(variant => variant.id !== winningVariantId).map(value => {\n return `.variant-${value.id} { display: none; }\n `;\n }).join('');\n styleEl.innerHTML = newStyleStr;\n }\n}";
|
|
14
14
|
export const UPDATE_VARIANT_VISIBILITY_SCRIPT = "function updateVariantVisibility(variantContentId, defaultContentId, isHydrationTarget) {\n if (!navigator.cookieEnabled) {\n return;\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${defaultContentId}`;\n const winningVariant = getCookie(cookieName);\n const parentDiv = document.currentScript?.parentElement;\n const isDefaultContent = variantContentId === defaultContentId;\n const isWinningVariant = winningVariant === variantContentId;\n if (isWinningVariant && !isDefaultContent) {\n parentDiv?.removeAttribute('hidden');\n parentDiv?.removeAttribute('aria-hidden');\n } else if (!isWinningVariant && isDefaultContent) {\n parentDiv?.setAttribute('hidden', 'true');\n parentDiv?.setAttribute('aria-hidden', 'true');\n }\n if (isHydrationTarget) {\n if (!isWinningVariant) {\n parentDiv?.remove();\n }\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n }\n return;\n}";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "4.0.
|
|
1
|
+
export declare const SDK_VERSION = "4.0.3";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "4.0.
|
|
1
|
+
export const SDK_VERSION = "4.0.3";
|
package/package.json
CHANGED
|
@@ -8,17 +8,18 @@
|
|
|
8
8
|
<script lang="ts">
|
|
9
9
|
import { onMount } from "svelte";
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
let elementRef;
|
|
11
|
+
import { isEditing } from "../../functions/is-editing";
|
|
12
|
+
import { logger } from "../../helpers/logger";
|
|
15
13
|
|
|
16
|
-
let
|
|
17
|
-
let
|
|
14
|
+
export let code: CustomCodeProps["code"];
|
|
15
|
+
export let replaceNodes: CustomCodeProps["replaceNodes"] = undefined;
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
function runScripts() {
|
|
18
|
+
if (
|
|
19
|
+
!elementRef ||
|
|
20
|
+
!elementRef?.getElementsByTagName ||
|
|
21
|
+
typeof window === "undefined"
|
|
22
|
+
) {
|
|
22
23
|
return;
|
|
23
24
|
}
|
|
24
25
|
const scripts = elementRef.getElementsByTagName("script");
|
|
@@ -48,11 +49,33 @@
|
|
|
48
49
|
scriptsRun.push(script.innerText);
|
|
49
50
|
new Function(script.innerText)();
|
|
50
51
|
} catch (error) {
|
|
51
|
-
|
|
52
|
+
logger.warn(
|
|
53
|
+
"[BUILDER.IO] `CustomCode`: Error running script:",
|
|
54
|
+
error
|
|
55
|
+
);
|
|
52
56
|
}
|
|
53
57
|
}
|
|
54
58
|
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let elementRef;
|
|
62
|
+
|
|
63
|
+
let scriptsInserted = [];
|
|
64
|
+
let scriptsRun = [];
|
|
65
|
+
|
|
66
|
+
onMount(() => {
|
|
67
|
+
runScripts();
|
|
55
68
|
});
|
|
69
|
+
|
|
70
|
+
function onUpdateFn_0(..._args: any[]) {
|
|
71
|
+
if (isEditing()) {
|
|
72
|
+
setTimeout(() => {
|
|
73
|
+
runScripts();
|
|
74
|
+
}, 0);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
$: onUpdateFn_0(...[code]);
|
|
56
79
|
</script>
|
|
57
80
|
|
|
58
81
|
<div
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<script lang="ts">
|
|
8
|
+
import { logger } from "../../helpers/logger";
|
|
8
9
|
import { isJsScript } from "./helpers";
|
|
9
10
|
|
|
10
11
|
export let content: EmbedProps["content"];
|
|
@@ -25,7 +26,7 @@
|
|
|
25
26
|
scriptsRun.push(script.innerText);
|
|
26
27
|
new Function(script.innerText)();
|
|
27
28
|
} catch (error) {
|
|
28
|
-
|
|
29
|
+
logger.warn("[BUILDER.IO] `Embed`: Error running script:", error);
|
|
29
30
|
}
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
import { _track } from "../../../functions/track/index";
|
|
31
31
|
import { getInteractionPropertiesForEvent } from "../../../functions/track/interaction";
|
|
32
32
|
import { getDefaultCanTrack } from "../../../helpers/canTrack";
|
|
33
|
+
import { getCookieSync } from "../../../helpers/cookie";
|
|
33
34
|
import { postPreviewContent } from "../../../helpers/preview-lru-cache/set";
|
|
34
35
|
import { createEditorListener } from "../../../helpers/subscribe-to-editor";
|
|
35
36
|
import {
|
|
@@ -304,6 +305,7 @@
|
|
|
304
305
|
|
|
305
306
|
let elementRef;
|
|
306
307
|
|
|
308
|
+
let hasExecuted = false;
|
|
307
309
|
let ContentWrapper = contentWrapper || "div";
|
|
308
310
|
let httpReqsData = {};
|
|
309
311
|
let httpReqsPending = {};
|
|
@@ -320,8 +322,12 @@
|
|
|
320
322
|
}
|
|
321
323
|
const shouldTrackImpression =
|
|
322
324
|
$builderContextSignal.content && getDefaultCanTrack(canTrack);
|
|
323
|
-
|
|
324
|
-
|
|
325
|
+
const winningVariantId = getCookieSync({
|
|
326
|
+
name: `builder.tests.${$builderContextSignal.content?.id}`,
|
|
327
|
+
canTrack: true,
|
|
328
|
+
});
|
|
329
|
+
const variationId = $builderContextSignal.content?.testVariationId;
|
|
330
|
+
if (shouldTrackImpression && variationId === winningVariantId) {
|
|
325
331
|
const contentId = $builderContextSignal.content?.id;
|
|
326
332
|
const apiKeyProp = apiKey;
|
|
327
333
|
_track({
|
|
@@ -330,7 +336,8 @@
|
|
|
330
336
|
canTrack: true,
|
|
331
337
|
contentId,
|
|
332
338
|
apiKey: apiKeyProp!,
|
|
333
|
-
variationId:
|
|
339
|
+
variationId:
|
|
340
|
+
winningVariantId !== contentId ? winningVariantId : undefined,
|
|
334
341
|
});
|
|
335
342
|
}
|
|
336
343
|
|
|
@@ -52,6 +52,7 @@ type VariantData = {
|
|
|
52
52
|
testRatio?: number;
|
|
53
53
|
};
|
|
54
54
|
const getIsHydrationTarget = (target: Target) => target === 'react' || target === 'reactNative';
|
|
55
|
+
const isAngularSDK = TARGET === 'angular';
|
|
55
56
|
const isHydrationTarget = getIsHydrationTarget(TARGET);
|
|
56
57
|
export const getInitVariantsFnsScriptString = () => `
|
|
57
58
|
window.${UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME} = ${UPDATE_COOKIES_AND_STYLES_SCRIPT}
|
|
@@ -59,7 +60,7 @@ export const getInitVariantsFnsScriptString = () => `
|
|
|
59
60
|
`;
|
|
60
61
|
export const getUpdateCookieAndStylesScript = (variants: VariantData[], contentId: string) => `
|
|
61
62
|
window.${UPDATE_COOKIES_AND_STYLES_SCRIPT_NAME}(
|
|
62
|
-
"${contentId}",${JSON.stringify(variants)}, ${isHydrationTarget}
|
|
63
|
+
"${contentId}",${JSON.stringify(variants)}, ${isHydrationTarget}, ${isAngularSDK}
|
|
63
64
|
)`;
|
|
64
65
|
export const getUpdateVariantVisibilityScript = ({
|
|
65
66
|
contentId,
|
|
@@ -18,5 +18,5 @@ type VariantData = {
|
|
|
18
18
|
* see our [SSR A/B Test Docs](https://github.com/BuilderIO/builder/tree/main/packages/sdks/docs/SSR_AB_TEST.md)
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
-
export const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n
|
|
21
|
+
export const UPDATE_COOKIES_AND_STYLES_SCRIPT = "function updateCookiesAndStyles(contentId, variants, isHydrationTarget, isAngularSDK) {\n function getAndSetVariantId() {\n function setCookie(name, value, days) {\n let expires = '';\n if (days) {\n const date = new Date();\n date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);\n expires = '; expires=' + date.toUTCString();\n }\n document.cookie = name + '=' + (value || '') + expires + '; path=/' + '; Secure; SameSite=None';\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${contentId}`;\n const variantInCookie = getCookie(cookieName);\n const availableIDs = variants.map(vr => vr.id).concat(contentId);\n if (variantInCookie && availableIDs.includes(variantInCookie)) {\n return variantInCookie;\n }\n let n = 0;\n const random = Math.random();\n for (let i = 0; i < variants.length; i++) {\n const variant = variants[i];\n const testRatio = variant.testRatio;\n n += testRatio;\n if (random < n) {\n setCookie(cookieName, variant.id);\n return variant.id;\n }\n }\n setCookie(cookieName, contentId);\n return contentId;\n }\n const winningVariantId = getAndSetVariantId();\n let styleEl = document.currentScript?.previousElementSibling;\n if (isAngularSDK) {\n styleEl = document.currentScript?.parentElement?.previousElementSibling?.querySelector('style');\n }\n if (isHydrationTarget) {\n styleEl.remove();\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n } else {\n const newStyleStr = variants.concat({\n id: contentId\n }).filter(variant => variant.id !== winningVariantId).map(value => {\n return `.variant-${value.id} { display: none; }\n `;\n }).join('');\n styleEl.innerHTML = newStyleStr;\n }\n}";
|
|
22
22
|
export const UPDATE_VARIANT_VISIBILITY_SCRIPT = "function updateVariantVisibility(variantContentId, defaultContentId, isHydrationTarget) {\n if (!navigator.cookieEnabled) {\n return;\n }\n function getCookie(name) {\n const nameEQ = name + '=';\n const ca = document.cookie.split(';');\n for (let i = 0; i < ca.length; i++) {\n let c = ca[i];\n while (c.charAt(0) === ' ') c = c.substring(1, c.length);\n if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);\n }\n return null;\n }\n const cookieName = `builder.tests.${defaultContentId}`;\n const winningVariant = getCookie(cookieName);\n const parentDiv = document.currentScript?.parentElement;\n const isDefaultContent = variantContentId === defaultContentId;\n const isWinningVariant = winningVariant === variantContentId;\n if (isWinningVariant && !isDefaultContent) {\n parentDiv?.removeAttribute('hidden');\n parentDiv?.removeAttribute('aria-hidden');\n } else if (!isWinningVariant && isDefaultContent) {\n parentDiv?.setAttribute('hidden', 'true');\n parentDiv?.setAttribute('aria-hidden', 'true');\n }\n if (isHydrationTarget) {\n if (!isWinningVariant) {\n parentDiv?.remove();\n }\n const thisScriptEl = document.currentScript;\n thisScriptEl?.remove();\n }\n return;\n}";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "4.0.
|
|
1
|
+
export const SDK_VERSION = "4.0.3"
|