@builder.io/sdk-svelte 4.0.9 → 4.1.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/form/form/form.svelte +34 -12
- package/lib/browser/blocks/img/img.svelte +15 -2
- package/lib/browser/blocks/personalization-container/helpers.js +2 -2
- package/lib/browser/blocks/personalization-container/personalization-container.svelte +2 -0
- package/lib/browser/constants/sdk-version.d.ts +1 -1
- package/lib/browser/constants/sdk-version.js +1 -1
- package/lib/browser/helpers/no-serialize-wrapper.d.ts +1 -0
- package/lib/browser/helpers/no-serialize-wrapper.js +3 -0
- package/lib/browser/helpers/user-attributes.d.ts +6 -2
- package/lib/browser/helpers/user-attributes.js +19 -4
- package/lib/edge/blocks/form/form/form.svelte +34 -12
- package/lib/edge/blocks/img/img.svelte +15 -2
- package/lib/edge/blocks/personalization-container/helpers.js +2 -2
- package/lib/edge/blocks/personalization-container/personalization-container.svelte +2 -0
- package/lib/edge/constants/sdk-version.d.ts +1 -1
- package/lib/edge/constants/sdk-version.js +1 -1
- package/lib/edge/helpers/no-serialize-wrapper.d.ts +1 -0
- package/lib/edge/helpers/no-serialize-wrapper.js +3 -0
- package/lib/edge/helpers/user-attributes.d.ts +6 -2
- package/lib/edge/helpers/user-attributes.js +19 -4
- package/lib/node/blocks/form/form/form.svelte +34 -12
- package/lib/node/blocks/img/img.svelte +15 -2
- package/lib/node/blocks/personalization-container/helpers.js +2 -2
- package/lib/node/blocks/personalization-container/personalization-container.svelte +2 -0
- package/lib/node/constants/sdk-version.d.ts +1 -1
- package/lib/node/constants/sdk-version.js +1 -1
- package/lib/node/helpers/no-serialize-wrapper.d.ts +1 -0
- package/lib/node/helpers/no-serialize-wrapper.js +3 -0
- package/lib/node/helpers/user-attributes.d.ts +6 -2
- package/lib/node/helpers/user-attributes.js +19 -4
- package/package.json +1 -1
- package/src/blocks/form/form/form.svelte +37 -12
- package/src/blocks/img/img.svelte +17 -2
- package/src/blocks/personalization-container/helpers.ts +2 -2
- package/src/blocks/personalization-container/personalization-container.svelte +3 -0
- package/src/constants/sdk-version.ts +1 -1
- package/src/helpers/no-serialize-wrapper.ts +3 -0
- package/src/helpers/user-attributes.ts +22 -4
|
@@ -144,6 +144,16 @@ function onSubmit(event) {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
formState = "sending";
|
|
147
|
+
if (sendSubmissionsTo === "email" &&
|
|
148
|
+
(sendSubmissionsToEmail === "your@email.com" || !sendSubmissionsToEmail)) {
|
|
149
|
+
const message = "SubmissionsToEmail is required when sendSubmissionsTo is set to email";
|
|
150
|
+
console.error(message);
|
|
151
|
+
formState = "error";
|
|
152
|
+
mergeNewRootState({
|
|
153
|
+
formErrorMessage: message,
|
|
154
|
+
});
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
147
157
|
const formUrl = `${getEnv() === "dev" ? "http://localhost:5000" : "https://builder.io"}/api/v1/form-submit?apiKey=${$builderContext.apiKey}&to=${btoa(sendSubmissionsToEmail || "")}&name=${encodeURIComponent(name || "")}`;
|
|
148
158
|
const url = sendSubmissionsTo === "email"
|
|
149
159
|
? formUrl
|
|
@@ -162,20 +172,32 @@ function onSubmit(event) {
|
|
|
162
172
|
else {
|
|
163
173
|
body = await res.text();
|
|
164
174
|
}
|
|
165
|
-
if (!res.ok
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
175
|
+
if (!res.ok) {
|
|
176
|
+
const submitErrorEvent = new CustomEvent("submit:error", {
|
|
177
|
+
detail: {
|
|
178
|
+
error: body,
|
|
179
|
+
status: res.status,
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
if (formRef?.nativeElement) {
|
|
183
|
+
formRef?.nativeElement.dispatchEvent(submitErrorEvent);
|
|
184
|
+
if (submitErrorEvent.defaultPrevented) {
|
|
185
|
+
return;
|
|
173
186
|
}
|
|
174
|
-
formErrorMessage = message;
|
|
175
|
-
mergeNewRootState({
|
|
176
|
-
formErrorMessage: message,
|
|
177
|
-
});
|
|
178
187
|
}
|
|
188
|
+
responseData = body;
|
|
189
|
+
formState = "error";
|
|
190
|
+
let message = errorMessagePath
|
|
191
|
+
? get(body, errorMessagePath)
|
|
192
|
+
: body.message || body.error || body;
|
|
193
|
+
if (typeof message !== "string") {
|
|
194
|
+
message = JSON.stringify(message);
|
|
195
|
+
}
|
|
196
|
+
formErrorMessage = message;
|
|
197
|
+
mergeNewRootState({
|
|
198
|
+
formErrorMessage: message,
|
|
199
|
+
});
|
|
200
|
+
return;
|
|
179
201
|
}
|
|
180
202
|
responseData = body;
|
|
181
203
|
formState = res.ok ? "success" : "error";
|
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
<script>import { isEditing } from "../../functions/is-editing";
|
|
7
7
|
import { filterAttrs } from "../helpers";
|
|
8
|
+
import { getSrcSet } from "../image/image.helpers";
|
|
8
9
|
import { setAttrs } from "../helpers";
|
|
10
|
+
export let imgSrc = undefined;
|
|
11
|
+
export let image = undefined;
|
|
9
12
|
export let backgroundSize = undefined;
|
|
10
13
|
export let backgroundPosition = undefined;
|
|
11
|
-
export let imgSrc = undefined;
|
|
12
14
|
export let altText = undefined;
|
|
13
|
-
export let image = undefined;
|
|
14
15
|
export let attributes = undefined;
|
|
15
16
|
function stringifyStyles(stylesObj) {
|
|
16
17
|
let styles = "";
|
|
@@ -22,6 +23,17 @@ function stringifyStyles(stylesObj) {
|
|
|
22
23
|
}
|
|
23
24
|
return styles;
|
|
24
25
|
}
|
|
26
|
+
$: srcSetToUse = () => {
|
|
27
|
+
const url = imgSrc || image;
|
|
28
|
+
if (!url || typeof url !== "string") {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
// We can auto add srcset for cdn.builder.io images
|
|
32
|
+
if (!url.match(/builder\.io/)) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
return getSrcSet(url);
|
|
36
|
+
};
|
|
25
37
|
</script>
|
|
26
38
|
|
|
27
39
|
{#key (isEditing() && imgSrc) || "default-key"}
|
|
@@ -32,6 +44,7 @@ function stringifyStyles(stylesObj) {
|
|
|
32
44
|
})}
|
|
33
45
|
alt={altText}
|
|
34
46
|
src={imgSrc || image}
|
|
47
|
+
srcSet={srcSetToUse()}
|
|
35
48
|
{...filterAttrs(attributes, "on:", false)}
|
|
36
49
|
use:setAttrs={filterAttrs(attributes, "on:", true)}
|
|
37
50
|
/>
|
|
@@ -9,7 +9,7 @@ const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'updateVisibilityStylesScript';
|
|
|
9
9
|
/**
|
|
10
10
|
* SDKs that support Variant Containers
|
|
11
11
|
*/
|
|
12
|
-
export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
|
|
12
|
+
export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte', 'qwik'];
|
|
13
13
|
/**
|
|
14
14
|
* After hydration, we reset the tree
|
|
15
15
|
* These SDKs handle Personalization Container in a special way:
|
|
@@ -19,7 +19,7 @@ export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
|
|
|
19
19
|
* This helps us to avoid flicker and show the correct / winning variant initially and then once we've hydrated we show the winning variant
|
|
20
20
|
* and keep a track of the cookies to update to the correct variant dynamically when the cookie updates.
|
|
21
21
|
*/
|
|
22
|
-
export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte'];
|
|
22
|
+
export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte', 'qwik'];
|
|
23
23
|
export function checkShouldRenderVariants(variants, canTrack) {
|
|
24
24
|
const hasVariants = variants && variants.length > 0;
|
|
25
25
|
if (TARGET === 'reactNative')
|
|
@@ -61,6 +61,8 @@ onMount(() => {
|
|
|
61
61
|
shouldResetVariants = true;
|
|
62
62
|
const unsub = userAttributesService.subscribeOnUserAttributesChange((attrs) => {
|
|
63
63
|
userAttributes = attrs;
|
|
64
|
+
}, {
|
|
65
|
+
fireImmediately: TARGET === "qwik",
|
|
64
66
|
});
|
|
65
67
|
if (!(isEditing() || isPreviewing())) {
|
|
66
68
|
const variant = filteredVariants()[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "4.0
|
|
1
|
+
export declare const SDK_VERSION = "4.1.0";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "4.0
|
|
1
|
+
export const SDK_VERSION = "4.1.0";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function noSerializeWrapper(fn: () => void): () => void;
|
|
@@ -5,13 +5,17 @@ export declare const USER_ATTRIBUTES_COOKIE_NAME = "builder.userAttributes";
|
|
|
5
5
|
export declare function createUserAttributesService(): {
|
|
6
6
|
setUserAttributes(newAttrs: UserAttributes): void;
|
|
7
7
|
getUserAttributes(): any;
|
|
8
|
-
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void
|
|
8
|
+
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
|
|
9
|
+
fireImmediately?: boolean | undefined;
|
|
10
|
+
}): () => void;
|
|
9
11
|
setCanTrack(value: boolean): void;
|
|
10
12
|
};
|
|
11
13
|
export declare const userAttributesService: {
|
|
12
14
|
setUserAttributes(newAttrs: UserAttributes): void;
|
|
13
15
|
getUserAttributes(): any;
|
|
14
|
-
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void
|
|
16
|
+
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
|
|
17
|
+
fireImmediately?: boolean | undefined;
|
|
18
|
+
}): () => void;
|
|
15
19
|
setCanTrack(value: boolean): void;
|
|
16
20
|
};
|
|
17
21
|
export declare const setClientUserAttributes: (attributes: UserAttributes) => void;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { TARGET } from '../constants/target';
|
|
1
2
|
import { isBrowser } from '../functions/is-browser';
|
|
2
3
|
import { getCookieSync, setCookie } from './cookie';
|
|
4
|
+
import { noSerializeWrapper } from './no-serialize-wrapper';
|
|
3
5
|
export const USER_ATTRIBUTES_COOKIE_NAME = 'builder.userAttributes';
|
|
4
6
|
export function createUserAttributesService() {
|
|
5
7
|
let canTrack = true;
|
|
@@ -29,18 +31,31 @@ export function createUserAttributesService() {
|
|
|
29
31
|
canTrack
|
|
30
32
|
}) || '{}');
|
|
31
33
|
},
|
|
32
|
-
subscribeOnUserAttributesChange(callback) {
|
|
34
|
+
subscribeOnUserAttributesChange(callback, { fireImmediately } = {}) {
|
|
33
35
|
subscribers.add(callback);
|
|
34
|
-
|
|
36
|
+
if (fireImmediately) {
|
|
37
|
+
callback(this.getUserAttributes());
|
|
38
|
+
}
|
|
39
|
+
return noSerializeWrapper(function () {
|
|
35
40
|
subscribers.delete(callback);
|
|
36
|
-
};
|
|
41
|
+
});
|
|
37
42
|
},
|
|
38
43
|
setCanTrack(value) {
|
|
39
44
|
canTrack = value;
|
|
40
45
|
}
|
|
41
46
|
};
|
|
42
47
|
}
|
|
43
|
-
|
|
48
|
+
let _userAttributesService;
|
|
49
|
+
if (isBrowser() && TARGET === 'qwik') {
|
|
50
|
+
if (!window.__BUILDER_USER_ATTRIBUTES_SERVICE__) {
|
|
51
|
+
window.__BUILDER_USER_ATTRIBUTES_SERVICE__ = createUserAttributesService();
|
|
52
|
+
}
|
|
53
|
+
_userAttributesService = window.__BUILDER_USER_ATTRIBUTES_SERVICE__;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
_userAttributesService = createUserAttributesService();
|
|
57
|
+
}
|
|
58
|
+
export const userAttributesService = _userAttributesService;
|
|
44
59
|
export const setClientUserAttributes = (attributes) => {
|
|
45
60
|
userAttributesService.setUserAttributes(attributes);
|
|
46
61
|
};
|
|
@@ -144,6 +144,16 @@ function onSubmit(event) {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
formState = "sending";
|
|
147
|
+
if (sendSubmissionsTo === "email" &&
|
|
148
|
+
(sendSubmissionsToEmail === "your@email.com" || !sendSubmissionsToEmail)) {
|
|
149
|
+
const message = "SubmissionsToEmail is required when sendSubmissionsTo is set to email";
|
|
150
|
+
console.error(message);
|
|
151
|
+
formState = "error";
|
|
152
|
+
mergeNewRootState({
|
|
153
|
+
formErrorMessage: message,
|
|
154
|
+
});
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
147
157
|
const formUrl = `${getEnv() === "dev" ? "http://localhost:5000" : "https://builder.io"}/api/v1/form-submit?apiKey=${$builderContext.apiKey}&to=${btoa(sendSubmissionsToEmail || "")}&name=${encodeURIComponent(name || "")}`;
|
|
148
158
|
const url = sendSubmissionsTo === "email"
|
|
149
159
|
? formUrl
|
|
@@ -162,20 +172,32 @@ function onSubmit(event) {
|
|
|
162
172
|
else {
|
|
163
173
|
body = await res.text();
|
|
164
174
|
}
|
|
165
|
-
if (!res.ok
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
175
|
+
if (!res.ok) {
|
|
176
|
+
const submitErrorEvent = new CustomEvent("submit:error", {
|
|
177
|
+
detail: {
|
|
178
|
+
error: body,
|
|
179
|
+
status: res.status,
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
if (formRef?.nativeElement) {
|
|
183
|
+
formRef?.nativeElement.dispatchEvent(submitErrorEvent);
|
|
184
|
+
if (submitErrorEvent.defaultPrevented) {
|
|
185
|
+
return;
|
|
173
186
|
}
|
|
174
|
-
formErrorMessage = message;
|
|
175
|
-
mergeNewRootState({
|
|
176
|
-
formErrorMessage: message,
|
|
177
|
-
});
|
|
178
187
|
}
|
|
188
|
+
responseData = body;
|
|
189
|
+
formState = "error";
|
|
190
|
+
let message = errorMessagePath
|
|
191
|
+
? get(body, errorMessagePath)
|
|
192
|
+
: body.message || body.error || body;
|
|
193
|
+
if (typeof message !== "string") {
|
|
194
|
+
message = JSON.stringify(message);
|
|
195
|
+
}
|
|
196
|
+
formErrorMessage = message;
|
|
197
|
+
mergeNewRootState({
|
|
198
|
+
formErrorMessage: message,
|
|
199
|
+
});
|
|
200
|
+
return;
|
|
179
201
|
}
|
|
180
202
|
responseData = body;
|
|
181
203
|
formState = res.ok ? "success" : "error";
|
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
<script>import { isEditing } from "../../functions/is-editing";
|
|
7
7
|
import { filterAttrs } from "../helpers";
|
|
8
|
+
import { getSrcSet } from "../image/image.helpers";
|
|
8
9
|
import { setAttrs } from "../helpers";
|
|
10
|
+
export let imgSrc = undefined;
|
|
11
|
+
export let image = undefined;
|
|
9
12
|
export let backgroundSize = undefined;
|
|
10
13
|
export let backgroundPosition = undefined;
|
|
11
|
-
export let imgSrc = undefined;
|
|
12
14
|
export let altText = undefined;
|
|
13
|
-
export let image = undefined;
|
|
14
15
|
export let attributes = undefined;
|
|
15
16
|
function stringifyStyles(stylesObj) {
|
|
16
17
|
let styles = "";
|
|
@@ -22,6 +23,17 @@ function stringifyStyles(stylesObj) {
|
|
|
22
23
|
}
|
|
23
24
|
return styles;
|
|
24
25
|
}
|
|
26
|
+
$: srcSetToUse = () => {
|
|
27
|
+
const url = imgSrc || image;
|
|
28
|
+
if (!url || typeof url !== "string") {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
// We can auto add srcset for cdn.builder.io images
|
|
32
|
+
if (!url.match(/builder\.io/)) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
return getSrcSet(url);
|
|
36
|
+
};
|
|
25
37
|
</script>
|
|
26
38
|
|
|
27
39
|
{#key (isEditing() && imgSrc) || "default-key"}
|
|
@@ -32,6 +44,7 @@ function stringifyStyles(stylesObj) {
|
|
|
32
44
|
})}
|
|
33
45
|
alt={altText}
|
|
34
46
|
src={imgSrc || image}
|
|
47
|
+
srcSet={srcSetToUse()}
|
|
35
48
|
{...filterAttrs(attributes, "on:", false)}
|
|
36
49
|
use:setAttrs={filterAttrs(attributes, "on:", true)}
|
|
37
50
|
/>
|
|
@@ -9,7 +9,7 @@ const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'updateVisibilityStylesScript';
|
|
|
9
9
|
/**
|
|
10
10
|
* SDKs that support Variant Containers
|
|
11
11
|
*/
|
|
12
|
-
export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
|
|
12
|
+
export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte', 'qwik'];
|
|
13
13
|
/**
|
|
14
14
|
* After hydration, we reset the tree
|
|
15
15
|
* These SDKs handle Personalization Container in a special way:
|
|
@@ -19,7 +19,7 @@ export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
|
|
|
19
19
|
* This helps us to avoid flicker and show the correct / winning variant initially and then once we've hydrated we show the winning variant
|
|
20
20
|
* and keep a track of the cookies to update to the correct variant dynamically when the cookie updates.
|
|
21
21
|
*/
|
|
22
|
-
export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte'];
|
|
22
|
+
export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte', 'qwik'];
|
|
23
23
|
export function checkShouldRenderVariants(variants, canTrack) {
|
|
24
24
|
const hasVariants = variants && variants.length > 0;
|
|
25
25
|
if (TARGET === 'reactNative')
|
|
@@ -61,6 +61,8 @@ onMount(() => {
|
|
|
61
61
|
shouldResetVariants = true;
|
|
62
62
|
const unsub = userAttributesService.subscribeOnUserAttributesChange((attrs) => {
|
|
63
63
|
userAttributes = attrs;
|
|
64
|
+
}, {
|
|
65
|
+
fireImmediately: TARGET === "qwik",
|
|
64
66
|
});
|
|
65
67
|
if (!(isEditing() || isPreviewing())) {
|
|
66
68
|
const variant = filteredVariants()[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "4.0
|
|
1
|
+
export declare const SDK_VERSION = "4.1.0";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "4.0
|
|
1
|
+
export const SDK_VERSION = "4.1.0";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function noSerializeWrapper(fn: () => void): () => void;
|
|
@@ -5,13 +5,17 @@ export declare const USER_ATTRIBUTES_COOKIE_NAME = "builder.userAttributes";
|
|
|
5
5
|
export declare function createUserAttributesService(): {
|
|
6
6
|
setUserAttributes(newAttrs: UserAttributes): void;
|
|
7
7
|
getUserAttributes(): any;
|
|
8
|
-
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void
|
|
8
|
+
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
|
|
9
|
+
fireImmediately?: boolean | undefined;
|
|
10
|
+
}): () => void;
|
|
9
11
|
setCanTrack(value: boolean): void;
|
|
10
12
|
};
|
|
11
13
|
export declare const userAttributesService: {
|
|
12
14
|
setUserAttributes(newAttrs: UserAttributes): void;
|
|
13
15
|
getUserAttributes(): any;
|
|
14
|
-
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void
|
|
16
|
+
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
|
|
17
|
+
fireImmediately?: boolean | undefined;
|
|
18
|
+
}): () => void;
|
|
15
19
|
setCanTrack(value: boolean): void;
|
|
16
20
|
};
|
|
17
21
|
export declare const setClientUserAttributes: (attributes: UserAttributes) => void;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { TARGET } from '../constants/target';
|
|
1
2
|
import { isBrowser } from '../functions/is-browser';
|
|
2
3
|
import { getCookieSync, setCookie } from './cookie';
|
|
4
|
+
import { noSerializeWrapper } from './no-serialize-wrapper';
|
|
3
5
|
export const USER_ATTRIBUTES_COOKIE_NAME = 'builder.userAttributes';
|
|
4
6
|
export function createUserAttributesService() {
|
|
5
7
|
let canTrack = true;
|
|
@@ -29,18 +31,31 @@ export function createUserAttributesService() {
|
|
|
29
31
|
canTrack
|
|
30
32
|
}) || '{}');
|
|
31
33
|
},
|
|
32
|
-
subscribeOnUserAttributesChange(callback) {
|
|
34
|
+
subscribeOnUserAttributesChange(callback, { fireImmediately } = {}) {
|
|
33
35
|
subscribers.add(callback);
|
|
34
|
-
|
|
36
|
+
if (fireImmediately) {
|
|
37
|
+
callback(this.getUserAttributes());
|
|
38
|
+
}
|
|
39
|
+
return noSerializeWrapper(function () {
|
|
35
40
|
subscribers.delete(callback);
|
|
36
|
-
};
|
|
41
|
+
});
|
|
37
42
|
},
|
|
38
43
|
setCanTrack(value) {
|
|
39
44
|
canTrack = value;
|
|
40
45
|
}
|
|
41
46
|
};
|
|
42
47
|
}
|
|
43
|
-
|
|
48
|
+
let _userAttributesService;
|
|
49
|
+
if (isBrowser() && TARGET === 'qwik') {
|
|
50
|
+
if (!window.__BUILDER_USER_ATTRIBUTES_SERVICE__) {
|
|
51
|
+
window.__BUILDER_USER_ATTRIBUTES_SERVICE__ = createUserAttributesService();
|
|
52
|
+
}
|
|
53
|
+
_userAttributesService = window.__BUILDER_USER_ATTRIBUTES_SERVICE__;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
_userAttributesService = createUserAttributesService();
|
|
57
|
+
}
|
|
58
|
+
export const userAttributesService = _userAttributesService;
|
|
44
59
|
export const setClientUserAttributes = (attributes) => {
|
|
45
60
|
userAttributesService.setUserAttributes(attributes);
|
|
46
61
|
};
|
|
@@ -144,6 +144,16 @@ function onSubmit(event) {
|
|
|
144
144
|
}
|
|
145
145
|
}
|
|
146
146
|
formState = "sending";
|
|
147
|
+
if (sendSubmissionsTo === "email" &&
|
|
148
|
+
(sendSubmissionsToEmail === "your@email.com" || !sendSubmissionsToEmail)) {
|
|
149
|
+
const message = "SubmissionsToEmail is required when sendSubmissionsTo is set to email";
|
|
150
|
+
console.error(message);
|
|
151
|
+
formState = "error";
|
|
152
|
+
mergeNewRootState({
|
|
153
|
+
formErrorMessage: message,
|
|
154
|
+
});
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
147
157
|
const formUrl = `${getEnv() === "dev" ? "http://localhost:5000" : "https://builder.io"}/api/v1/form-submit?apiKey=${$builderContext.apiKey}&to=${btoa(sendSubmissionsToEmail || "")}&name=${encodeURIComponent(name || "")}`;
|
|
148
158
|
const url = sendSubmissionsTo === "email"
|
|
149
159
|
? formUrl
|
|
@@ -162,20 +172,32 @@ function onSubmit(event) {
|
|
|
162
172
|
else {
|
|
163
173
|
body = await res.text();
|
|
164
174
|
}
|
|
165
|
-
if (!res.ok
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
175
|
+
if (!res.ok) {
|
|
176
|
+
const submitErrorEvent = new CustomEvent("submit:error", {
|
|
177
|
+
detail: {
|
|
178
|
+
error: body,
|
|
179
|
+
status: res.status,
|
|
180
|
+
},
|
|
181
|
+
});
|
|
182
|
+
if (formRef?.nativeElement) {
|
|
183
|
+
formRef?.nativeElement.dispatchEvent(submitErrorEvent);
|
|
184
|
+
if (submitErrorEvent.defaultPrevented) {
|
|
185
|
+
return;
|
|
173
186
|
}
|
|
174
|
-
formErrorMessage = message;
|
|
175
|
-
mergeNewRootState({
|
|
176
|
-
formErrorMessage: message,
|
|
177
|
-
});
|
|
178
187
|
}
|
|
188
|
+
responseData = body;
|
|
189
|
+
formState = "error";
|
|
190
|
+
let message = errorMessagePath
|
|
191
|
+
? get(body, errorMessagePath)
|
|
192
|
+
: body.message || body.error || body;
|
|
193
|
+
if (typeof message !== "string") {
|
|
194
|
+
message = JSON.stringify(message);
|
|
195
|
+
}
|
|
196
|
+
formErrorMessage = message;
|
|
197
|
+
mergeNewRootState({
|
|
198
|
+
formErrorMessage: message,
|
|
199
|
+
});
|
|
200
|
+
return;
|
|
179
201
|
}
|
|
180
202
|
responseData = body;
|
|
181
203
|
formState = res.ok ? "success" : "error";
|
|
@@ -5,12 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
<script>import { isEditing } from "../../functions/is-editing";
|
|
7
7
|
import { filterAttrs } from "../helpers";
|
|
8
|
+
import { getSrcSet } from "../image/image.helpers";
|
|
8
9
|
import { setAttrs } from "../helpers";
|
|
10
|
+
export let imgSrc = undefined;
|
|
11
|
+
export let image = undefined;
|
|
9
12
|
export let backgroundSize = undefined;
|
|
10
13
|
export let backgroundPosition = undefined;
|
|
11
|
-
export let imgSrc = undefined;
|
|
12
14
|
export let altText = undefined;
|
|
13
|
-
export let image = undefined;
|
|
14
15
|
export let attributes = undefined;
|
|
15
16
|
function stringifyStyles(stylesObj) {
|
|
16
17
|
let styles = "";
|
|
@@ -22,6 +23,17 @@ function stringifyStyles(stylesObj) {
|
|
|
22
23
|
}
|
|
23
24
|
return styles;
|
|
24
25
|
}
|
|
26
|
+
$: srcSetToUse = () => {
|
|
27
|
+
const url = imgSrc || image;
|
|
28
|
+
if (!url || typeof url !== "string") {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
// We can auto add srcset for cdn.builder.io images
|
|
32
|
+
if (!url.match(/builder\.io/)) {
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
return getSrcSet(url);
|
|
36
|
+
};
|
|
25
37
|
</script>
|
|
26
38
|
|
|
27
39
|
{#key (isEditing() && imgSrc) || "default-key"}
|
|
@@ -32,6 +44,7 @@ function stringifyStyles(stylesObj) {
|
|
|
32
44
|
})}
|
|
33
45
|
alt={altText}
|
|
34
46
|
src={imgSrc || image}
|
|
47
|
+
srcSet={srcSetToUse()}
|
|
35
48
|
{...filterAttrs(attributes, "on:", false)}
|
|
36
49
|
use:setAttrs={filterAttrs(attributes, "on:", true)}
|
|
37
50
|
/>
|
|
@@ -9,7 +9,7 @@ const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'updateVisibilityStylesScript';
|
|
|
9
9
|
/**
|
|
10
10
|
* SDKs that support Variant Containers
|
|
11
11
|
*/
|
|
12
|
-
export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
|
|
12
|
+
export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte', 'qwik'];
|
|
13
13
|
/**
|
|
14
14
|
* After hydration, we reset the tree
|
|
15
15
|
* These SDKs handle Personalization Container in a special way:
|
|
@@ -19,7 +19,7 @@ export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
|
|
|
19
19
|
* This helps us to avoid flicker and show the correct / winning variant initially and then once we've hydrated we show the winning variant
|
|
20
20
|
* and keep a track of the cookies to update to the correct variant dynamically when the cookie updates.
|
|
21
21
|
*/
|
|
22
|
-
export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte'];
|
|
22
|
+
export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte', 'qwik'];
|
|
23
23
|
export function checkShouldRenderVariants(variants, canTrack) {
|
|
24
24
|
const hasVariants = variants && variants.length > 0;
|
|
25
25
|
if (TARGET === 'reactNative')
|
|
@@ -61,6 +61,8 @@ onMount(() => {
|
|
|
61
61
|
shouldResetVariants = true;
|
|
62
62
|
const unsub = userAttributesService.subscribeOnUserAttributesChange((attrs) => {
|
|
63
63
|
userAttributes = attrs;
|
|
64
|
+
}, {
|
|
65
|
+
fireImmediately: TARGET === "qwik",
|
|
64
66
|
});
|
|
65
67
|
if (!(isEditing() || isPreviewing())) {
|
|
66
68
|
const variant = filteredVariants()[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const SDK_VERSION = "4.0
|
|
1
|
+
export declare const SDK_VERSION = "4.1.0";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "4.0
|
|
1
|
+
export const SDK_VERSION = "4.1.0";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function noSerializeWrapper(fn: () => void): () => void;
|
|
@@ -5,13 +5,17 @@ export declare const USER_ATTRIBUTES_COOKIE_NAME = "builder.userAttributes";
|
|
|
5
5
|
export declare function createUserAttributesService(): {
|
|
6
6
|
setUserAttributes(newAttrs: UserAttributes): void;
|
|
7
7
|
getUserAttributes(): any;
|
|
8
|
-
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void
|
|
8
|
+
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
|
|
9
|
+
fireImmediately?: boolean | undefined;
|
|
10
|
+
}): () => void;
|
|
9
11
|
setCanTrack(value: boolean): void;
|
|
10
12
|
};
|
|
11
13
|
export declare const userAttributesService: {
|
|
12
14
|
setUserAttributes(newAttrs: UserAttributes): void;
|
|
13
15
|
getUserAttributes(): any;
|
|
14
|
-
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void
|
|
16
|
+
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
|
|
17
|
+
fireImmediately?: boolean | undefined;
|
|
18
|
+
}): () => void;
|
|
15
19
|
setCanTrack(value: boolean): void;
|
|
16
20
|
};
|
|
17
21
|
export declare const setClientUserAttributes: (attributes: UserAttributes) => void;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { TARGET } from '../constants/target';
|
|
1
2
|
import { isBrowser } from '../functions/is-browser';
|
|
2
3
|
import { getCookieSync, setCookie } from './cookie';
|
|
4
|
+
import { noSerializeWrapper } from './no-serialize-wrapper';
|
|
3
5
|
export const USER_ATTRIBUTES_COOKIE_NAME = 'builder.userAttributes';
|
|
4
6
|
export function createUserAttributesService() {
|
|
5
7
|
let canTrack = true;
|
|
@@ -29,18 +31,31 @@ export function createUserAttributesService() {
|
|
|
29
31
|
canTrack
|
|
30
32
|
}) || '{}');
|
|
31
33
|
},
|
|
32
|
-
subscribeOnUserAttributesChange(callback) {
|
|
34
|
+
subscribeOnUserAttributesChange(callback, { fireImmediately } = {}) {
|
|
33
35
|
subscribers.add(callback);
|
|
34
|
-
|
|
36
|
+
if (fireImmediately) {
|
|
37
|
+
callback(this.getUserAttributes());
|
|
38
|
+
}
|
|
39
|
+
return noSerializeWrapper(function () {
|
|
35
40
|
subscribers.delete(callback);
|
|
36
|
-
};
|
|
41
|
+
});
|
|
37
42
|
},
|
|
38
43
|
setCanTrack(value) {
|
|
39
44
|
canTrack = value;
|
|
40
45
|
}
|
|
41
46
|
};
|
|
42
47
|
}
|
|
43
|
-
|
|
48
|
+
let _userAttributesService;
|
|
49
|
+
if (isBrowser() && TARGET === 'qwik') {
|
|
50
|
+
if (!window.__BUILDER_USER_ATTRIBUTES_SERVICE__) {
|
|
51
|
+
window.__BUILDER_USER_ATTRIBUTES_SERVICE__ = createUserAttributesService();
|
|
52
|
+
}
|
|
53
|
+
_userAttributesService = window.__BUILDER_USER_ATTRIBUTES_SERVICE__;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
_userAttributesService = createUserAttributesService();
|
|
57
|
+
}
|
|
58
|
+
export const userAttributesService = _userAttributesService;
|
|
44
59
|
export const setClientUserAttributes = (attributes) => {
|
|
45
60
|
userAttributesService.setUserAttributes(attributes);
|
|
46
61
|
};
|
package/package.json
CHANGED
|
@@ -188,6 +188,19 @@
|
|
|
188
188
|
}
|
|
189
189
|
}
|
|
190
190
|
formState = "sending";
|
|
191
|
+
if (
|
|
192
|
+
sendSubmissionsTo === "email" &&
|
|
193
|
+
(sendSubmissionsToEmail === "your@email.com" || !sendSubmissionsToEmail)
|
|
194
|
+
) {
|
|
195
|
+
const message =
|
|
196
|
+
"SubmissionsToEmail is required when sendSubmissionsTo is set to email";
|
|
197
|
+
console.error(message);
|
|
198
|
+
formState = "error";
|
|
199
|
+
mergeNewRootState({
|
|
200
|
+
formErrorMessage: message,
|
|
201
|
+
});
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
191
204
|
const formUrl = `${
|
|
192
205
|
getEnv() === "dev" ? "http://localhost:5000" : "https://builder.io"
|
|
193
206
|
}/api/v1/form-submit?apiKey=${$builderContext.apiKey}&to=${btoa(
|
|
@@ -212,20 +225,32 @@
|
|
|
212
225
|
} else {
|
|
213
226
|
body = await res.text();
|
|
214
227
|
}
|
|
215
|
-
if (!res.ok
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
228
|
+
if (!res.ok) {
|
|
229
|
+
const submitErrorEvent = new CustomEvent("submit:error", {
|
|
230
|
+
detail: {
|
|
231
|
+
error: body,
|
|
232
|
+
status: res.status,
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
if (formRef?.nativeElement) {
|
|
236
|
+
formRef?.nativeElement.dispatchEvent(submitErrorEvent);
|
|
237
|
+
if (submitErrorEvent.defaultPrevented) {
|
|
238
|
+
return;
|
|
223
239
|
}
|
|
224
|
-
formErrorMessage = message;
|
|
225
|
-
mergeNewRootState({
|
|
226
|
-
formErrorMessage: message,
|
|
227
|
-
});
|
|
228
240
|
}
|
|
241
|
+
responseData = body;
|
|
242
|
+
formState = "error";
|
|
243
|
+
let message = errorMessagePath
|
|
244
|
+
? get(body, errorMessagePath)
|
|
245
|
+
: body.message || body.error || body;
|
|
246
|
+
if (typeof message !== "string") {
|
|
247
|
+
message = JSON.stringify(message);
|
|
248
|
+
}
|
|
249
|
+
formErrorMessage = message;
|
|
250
|
+
mergeNewRootState({
|
|
251
|
+
formErrorMessage: message,
|
|
252
|
+
});
|
|
253
|
+
return;
|
|
229
254
|
}
|
|
230
255
|
responseData = body;
|
|
231
256
|
formState = res.ok ? "success" : "error";
|
|
@@ -25,13 +25,14 @@
|
|
|
25
25
|
<script lang="ts">
|
|
26
26
|
import { isEditing } from "../../functions/is-editing";
|
|
27
27
|
import { filterAttrs } from "../helpers";
|
|
28
|
+
import { getSrcSet } from "../image/image.helpers";
|
|
28
29
|
import { setAttrs } from "../helpers";
|
|
29
30
|
|
|
31
|
+
export let imgSrc: ImgProps["imgSrc"] = undefined;
|
|
32
|
+
export let image: ImgProps["image"] = undefined;
|
|
30
33
|
export let backgroundSize: ImgProps["backgroundSize"] = undefined;
|
|
31
34
|
export let backgroundPosition: ImgProps["backgroundPosition"] = undefined;
|
|
32
|
-
export let imgSrc: ImgProps["imgSrc"] = undefined;
|
|
33
35
|
export let altText: ImgProps["altText"] = undefined;
|
|
34
|
-
export let image: ImgProps["image"] = undefined;
|
|
35
36
|
export let attributes: ImgProps["attributes"] = undefined;
|
|
36
37
|
function stringifyStyles(stylesObj) {
|
|
37
38
|
let styles = "";
|
|
@@ -43,6 +44,19 @@
|
|
|
43
44
|
}
|
|
44
45
|
return styles;
|
|
45
46
|
}
|
|
47
|
+
|
|
48
|
+
$: srcSetToUse = () => {
|
|
49
|
+
const url = imgSrc || image;
|
|
50
|
+
if (!url || typeof url !== "string") {
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// We can auto add srcset for cdn.builder.io images
|
|
55
|
+
if (!url.match(/builder\.io/)) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
return getSrcSet(url);
|
|
59
|
+
};
|
|
46
60
|
</script>
|
|
47
61
|
|
|
48
62
|
{#key (isEditing() && imgSrc) || "default-key"}
|
|
@@ -53,6 +67,7 @@
|
|
|
53
67
|
})}
|
|
54
68
|
alt={altText}
|
|
55
69
|
src={imgSrc || image}
|
|
70
|
+
srcSet={srcSetToUse()}
|
|
56
71
|
{...filterAttrs(attributes, "on:", false)}
|
|
57
72
|
use:setAttrs={filterAttrs(attributes, "on:", true)}
|
|
58
73
|
/>
|
|
@@ -30,7 +30,7 @@ type BlocksToRenderReturnType = {
|
|
|
30
30
|
/**
|
|
31
31
|
* SDKs that support Variant Containers
|
|
32
32
|
*/
|
|
33
|
-
export const SDKS_SUPPORTING_PERSONALIZATION = (['react', 'vue', 'svelte'] as Target[]);
|
|
33
|
+
export const SDKS_SUPPORTING_PERSONALIZATION = (['react', 'vue', 'svelte', 'qwik'] as Target[]);
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
36
|
* After hydration, we reset the tree
|
|
@@ -41,7 +41,7 @@ export const SDKS_SUPPORTING_PERSONALIZATION = (['react', 'vue', 'svelte'] as Ta
|
|
|
41
41
|
* This helps us to avoid flicker and show the correct / winning variant initially and then once we've hydrated we show the winning variant
|
|
42
42
|
* and keep a track of the cookies to update to the correct variant dynamically when the cookie updates.
|
|
43
43
|
*/
|
|
44
|
-
export const SDKS_REQUIRING_RESET_APPROACH = (['vue', 'svelte'] as Target[]);
|
|
44
|
+
export const SDKS_REQUIRING_RESET_APPROACH = (['vue', 'svelte', 'qwik'] as Target[]);
|
|
45
45
|
export function checkShouldRenderVariants(variants: PersonalizationContainerProps['variants'], canTrack: boolean) {
|
|
46
46
|
const hasVariants = variants && variants.length > 0;
|
|
47
47
|
if (TARGET === 'reactNative') return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const SDK_VERSION = "4.0
|
|
1
|
+
export const SDK_VERSION = "4.1.0"
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { TARGET } from '../constants/target';
|
|
1
2
|
import { isBrowser } from '../functions/is-browser';
|
|
2
3
|
import { getCookieSync, setCookie } from './cookie';
|
|
4
|
+
import { noSerializeWrapper } from './no-serialize-wrapper';
|
|
3
5
|
export interface UserAttributes {
|
|
4
6
|
[key: string]: any;
|
|
5
7
|
}
|
|
@@ -32,18 +34,34 @@ export function createUserAttributesService() {
|
|
|
32
34
|
canTrack
|
|
33
35
|
}) || '{}');
|
|
34
36
|
},
|
|
35
|
-
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void
|
|
37
|
+
subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, {
|
|
38
|
+
fireImmediately
|
|
39
|
+
}: {
|
|
40
|
+
fireImmediately?: boolean;
|
|
41
|
+
} = {}) {
|
|
36
42
|
subscribers.add(callback);
|
|
37
|
-
|
|
43
|
+
if (fireImmediately) {
|
|
44
|
+
callback(this.getUserAttributes());
|
|
45
|
+
}
|
|
46
|
+
return noSerializeWrapper(function () {
|
|
38
47
|
subscribers.delete(callback);
|
|
39
|
-
};
|
|
48
|
+
});
|
|
40
49
|
},
|
|
41
50
|
setCanTrack(value: boolean) {
|
|
42
51
|
canTrack = value;
|
|
43
52
|
}
|
|
44
53
|
};
|
|
45
54
|
}
|
|
46
|
-
|
|
55
|
+
let _userAttributesService: ReturnType<typeof createUserAttributesService>;
|
|
56
|
+
if (isBrowser() && TARGET === 'qwik') {
|
|
57
|
+
if (!(window as any).__BUILDER_USER_ATTRIBUTES_SERVICE__) {
|
|
58
|
+
(window as any).__BUILDER_USER_ATTRIBUTES_SERVICE__ = createUserAttributesService();
|
|
59
|
+
}
|
|
60
|
+
_userAttributesService = (window as any).__BUILDER_USER_ATTRIBUTES_SERVICE__;
|
|
61
|
+
} else {
|
|
62
|
+
_userAttributesService = createUserAttributesService();
|
|
63
|
+
}
|
|
64
|
+
export const userAttributesService = _userAttributesService;
|
|
47
65
|
export const setClientUserAttributes = (attributes: UserAttributes) => {
|
|
48
66
|
userAttributesService.setUserAttributes(attributes);
|
|
49
67
|
}
|