@builder.io/sdk-svelte 0.0.7 → 0.0.9-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/package/--package.json +2 -3
- package/package/blocks/button/button.svelte +35 -3
- package/package/blocks/form/form.svelte +29 -1
- package/package/blocks/img/img.svelte +29 -1
- package/package/blocks/input/input.svelte +29 -1
- package/package/blocks/section/section.svelte +30 -2
- package/package/blocks/select/select.svelte +29 -1
- package/package/blocks/submit-button/submit-button.svelte +33 -2
- package/package/blocks/symbol/symbol.svelte +29 -1
- package/package/blocks/textarea/textarea.svelte +36 -2
- package/package/blocks/video/video.svelte +30 -2
- package/package/components/render-block/render-block.svelte +29 -8
- package/package/components/render-content/render-content.svelte +24 -3
- package/package/components/render-content/render-content.svelte.d.ts +4 -0
- package/package/functions/evaluate.d.ts +2 -1
- package/package/functions/evaluate.js +8 -5
- package/package/functions/event-handler-name.js +1 -4
- package/package/functions/get-block-actions-handler.d.ts +5 -2
- package/package/functions/get-block-actions-handler.js +7 -8
- package/package/functions/get-block-actions.js +2 -2
- package/package/functions/get-builder-search-params/index.d.ts +1 -1
- package/package/functions/track.d.ts +6 -1
- package/package/functions/track.js +4 -0
- package/package/scripts/init-editing.d.ts +4 -1
- package/package/scripts/init-editing.js +7 -1
- package/package.json +2 -2
- package/src/blocks/button/button.svelte +41 -2
- package/src/blocks/form/form.svelte +36 -1
- package/src/blocks/img/img.svelte +36 -1
- package/src/blocks/input/input.svelte +36 -1
- package/src/blocks/section/section.svelte +36 -1
- package/src/blocks/select/select.svelte +36 -1
- package/src/blocks/submit-button/submit-button.svelte +39 -1
- package/src/blocks/symbol/symbol.svelte +36 -1
- package/src/blocks/textarea/textarea.svelte +42 -1
- package/src/blocks/video/video.svelte +36 -1
- package/src/components/render-block/render-block.svelte +34 -8
- package/src/components/render-content/render-content.svelte +28 -3
- package/src/functions/evaluate.ts +11 -6
- package/src/functions/event-handler-name.ts +1 -6
- package/src/functions/get-block-actions-handler.ts +10 -9
- package/src/functions/get-block-actions.ts +2 -2
- package/src/functions/get-builder-search-params/index.ts +1 -1
- package/src/functions/track.ts +13 -1
- package/src/scripts/init-editing.ts +16 -1
- package/package/functions/mark-mutable.d.ts +0 -2
- package/package/functions/mark-mutable.js +0 -6
- package/src/functions/mark-mutable.ts +0 -7
|
@@ -27,6 +27,40 @@
|
|
|
27
27
|
</script>
|
|
28
28
|
|
|
29
29
|
<script lang="ts">
|
|
30
|
+
const isEvent = (attr) => attr.startsWith("on:");
|
|
31
|
+
const isNonEvent = (attr) => !attr.startsWith("on:");
|
|
32
|
+
|
|
33
|
+
const filterAttrs = (attrs, filter) => {
|
|
34
|
+
const validAttr = {};
|
|
35
|
+
Object.keys(attrs).forEach((attr) => {
|
|
36
|
+
if (filter(attr)) {
|
|
37
|
+
validAttr[attr] = attrs[attr];
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return validAttr;
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const setAttrs = (node, attrs) => {
|
|
44
|
+
const attrKeys = Object.keys(attrs);
|
|
45
|
+
|
|
46
|
+
const setup = (attr) => node.addEventListener(attr.substr(3), attrs[attr]);
|
|
47
|
+
const teardown = (attr) =>
|
|
48
|
+
node.removeEventListener(attr.substr(3), attrs[attr]);
|
|
49
|
+
|
|
50
|
+
attrKeys.map(setup);
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
update(attrs) {
|
|
54
|
+
const attrKeys = Object.keys(attrs);
|
|
55
|
+
attrKeys.map(teardown);
|
|
56
|
+
attrKeys.map(setup);
|
|
57
|
+
},
|
|
58
|
+
destroy() {
|
|
59
|
+
attrKeys.map(teardown);
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
30
64
|
export let autoPlay: VideoProps["autoPlay"];
|
|
31
65
|
export let muted: VideoProps["muted"];
|
|
32
66
|
export let controls: VideoProps["controls"];
|
|
@@ -96,7 +130,8 @@
|
|
|
96
130
|
// not have the video overflow
|
|
97
131
|
borderRadius: 1,
|
|
98
132
|
}}
|
|
99
|
-
{...spreadProps()}
|
|
133
|
+
{...filterAttrs(spreadProps(), isNonEvent)}
|
|
100
134
|
src={video || "no-src"}
|
|
101
135
|
poster={posterImage}
|
|
136
|
+
use:setAttrs={filterAttrs(spreadProps(), isEvent)}
|
|
102
137
|
/>
|
|
@@ -34,6 +34,27 @@
|
|
|
34
34
|
import RenderComponent from "./render-component.svelte";
|
|
35
35
|
import { getReactNativeBlockStyles } from "../../functions/get-react-native-block-styles.js";
|
|
36
36
|
|
|
37
|
+
const setAttrs = (node, attrs) => {
|
|
38
|
+
const attrKeys = Object.keys(attrs);
|
|
39
|
+
|
|
40
|
+
const setup = (attr) => node.addEventListener(attr.substr(3), attrs[attr]);
|
|
41
|
+
const teardown = (attr) =>
|
|
42
|
+
node.removeEventListener(attr.substr(3), attrs[attr]);
|
|
43
|
+
|
|
44
|
+
attrKeys.map(setup);
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
update(attrs) {
|
|
48
|
+
const attrKeys = Object.keys(attrs);
|
|
49
|
+
attrKeys.map(teardown);
|
|
50
|
+
attrKeys.map(setup);
|
|
51
|
+
},
|
|
52
|
+
destroy() {
|
|
53
|
+
attrKeys.map(teardown);
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
37
58
|
export let block: RenderBlockProps["block"];
|
|
38
59
|
export let context: RenderBlockProps["context"];
|
|
39
60
|
|
|
@@ -71,14 +92,16 @@
|
|
|
71
92
|
shouldEvaluateBindings: true,
|
|
72
93
|
});
|
|
73
94
|
};
|
|
95
|
+
$: actions = () => {
|
|
96
|
+
return getBlockActions({
|
|
97
|
+
block: useBlock(),
|
|
98
|
+
state: context.state,
|
|
99
|
+
context: context.context,
|
|
100
|
+
});
|
|
101
|
+
};
|
|
74
102
|
$: attributes = () => {
|
|
75
103
|
return {
|
|
76
104
|
...getBlockProperties(useBlock()),
|
|
77
|
-
...getBlockActions({
|
|
78
|
-
block: useBlock(),
|
|
79
|
-
state: context.state,
|
|
80
|
-
context: context.context,
|
|
81
|
-
}),
|
|
82
105
|
...(TARGET === "reactNative"
|
|
83
106
|
? {
|
|
84
107
|
style: getReactNativeBlockStyles({
|
|
@@ -105,7 +128,10 @@
|
|
|
105
128
|
...(shouldWrap()
|
|
106
129
|
? {}
|
|
107
130
|
: {
|
|
108
|
-
attributes:
|
|
131
|
+
attributes: {
|
|
132
|
+
...attributes(),
|
|
133
|
+
...actions(),
|
|
134
|
+
},
|
|
109
135
|
}),
|
|
110
136
|
},
|
|
111
137
|
context: childrenContext(),
|
|
@@ -198,7 +224,7 @@
|
|
|
198
224
|
|
|
199
225
|
{#if shouldWrap()}
|
|
200
226
|
{#if isEmptyHtmlElement(tag())}
|
|
201
|
-
<svelte:element this={tag()} {...attributes()} />
|
|
227
|
+
<svelte:element this={tag()} {...attributes()} use:setAttrs={actions()} />
|
|
202
228
|
{/if}
|
|
203
229
|
|
|
204
230
|
{#if !isEmptyHtmlElement(tag()) && repeatItemData()}
|
|
@@ -208,7 +234,7 @@
|
|
|
208
234
|
{/if}
|
|
209
235
|
|
|
210
236
|
{#if !isEmptyHtmlElement(tag()) && !repeatItemData()}
|
|
211
|
-
<svelte:element this={tag()} {...attributes()}>
|
|
237
|
+
<svelte:element this={tag()} {...attributes()} use:setAttrs={actions()}>
|
|
212
238
|
<svelte:component
|
|
213
239
|
this={renderComponentTag()}
|
|
214
240
|
{...renderComponentProps()}
|
|
@@ -20,6 +20,8 @@
|
|
|
20
20
|
apiKey: string;
|
|
21
21
|
customComponents?: RegisteredComponent[];
|
|
22
22
|
canTrack?: boolean;
|
|
23
|
+
locale?: string;
|
|
24
|
+
includeRefs?: boolean;
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
interface BuilderComponentStateChange {
|
|
@@ -46,7 +48,6 @@
|
|
|
46
48
|
|
|
47
49
|
import { getDefaultRegisteredComponents } from "../../constants/builder-registered-components.js";
|
|
48
50
|
import { TARGET } from "../../constants/target.js";
|
|
49
|
-
import BuilderContext from "../../context/builder.context.js";
|
|
50
51
|
import { evaluate } from "../../functions/evaluate.js";
|
|
51
52
|
import { getContent } from "../../functions/get-content/index.js";
|
|
52
53
|
import { getFetch } from "../../functions/get-fetch.js";
|
|
@@ -60,6 +61,7 @@
|
|
|
60
61
|
import { _track } from "../../functions/track.js";
|
|
61
62
|
import RenderBlocks from "../render-blocks.svelte";
|
|
62
63
|
import RenderContentStyles from "./components/render-styles.svelte";
|
|
64
|
+
import BuilderContext from "../../context/builder.context.js";
|
|
63
65
|
import {
|
|
64
66
|
registerInsertMenu,
|
|
65
67
|
setupBrowserForEditing,
|
|
@@ -68,10 +70,12 @@
|
|
|
68
70
|
export let content: RenderContentProps["content"];
|
|
69
71
|
export let data: RenderContentProps["data"];
|
|
70
72
|
export let canTrack: RenderContentProps["canTrack"];
|
|
73
|
+
export let locale: RenderContentProps["locale"];
|
|
71
74
|
export let context: RenderContentProps["context"];
|
|
72
75
|
export let customComponents: RenderContentProps["customComponents"];
|
|
73
76
|
export let model: RenderContentProps["model"];
|
|
74
77
|
export let apiKey: RenderContentProps["apiKey"];
|
|
78
|
+
export let includeRefs: RenderContentProps["includeRefs"];
|
|
75
79
|
|
|
76
80
|
setContext(BuilderContext.key, {
|
|
77
81
|
get content() {
|
|
@@ -213,6 +217,11 @@
|
|
|
213
217
|
return {
|
|
214
218
|
...content?.data?.state,
|
|
215
219
|
...data,
|
|
220
|
+
...(locale
|
|
221
|
+
? {
|
|
222
|
+
locale: locale,
|
|
223
|
+
}
|
|
224
|
+
: {}),
|
|
216
225
|
...overrideState,
|
|
217
226
|
};
|
|
218
227
|
};
|
|
@@ -258,11 +267,27 @@
|
|
|
258
267
|
let overrideState = {};
|
|
259
268
|
|
|
260
269
|
onMount(() => {
|
|
270
|
+
if (!apiKey) {
|
|
271
|
+
console.error(
|
|
272
|
+
"[Builder.io]: No API key provided to `RenderContent` component. This can cause issues. Please provide an API key using the `apiKey` prop."
|
|
273
|
+
);
|
|
274
|
+
}
|
|
261
275
|
if (isBrowser()) {
|
|
262
276
|
if (isEditing()) {
|
|
263
277
|
forceReRenderCount = forceReRenderCount + 1;
|
|
264
278
|
registerInsertMenu();
|
|
265
|
-
setupBrowserForEditing(
|
|
279
|
+
setupBrowserForEditing({
|
|
280
|
+
...(locale
|
|
281
|
+
? {
|
|
282
|
+
locale: locale,
|
|
283
|
+
}
|
|
284
|
+
: {}),
|
|
285
|
+
...(includeRefs
|
|
286
|
+
? {
|
|
287
|
+
includeRefs: includeRefs,
|
|
288
|
+
}
|
|
289
|
+
: {}),
|
|
290
|
+
});
|
|
266
291
|
Object.values(allRegisteredComponents()).forEach(
|
|
267
292
|
(registeredComponent) => {
|
|
268
293
|
const message = createRegisterComponentMessage(registeredComponent);
|
|
@@ -314,7 +339,7 @@
|
|
|
314
339
|
function onUpdateFn_0() {
|
|
315
340
|
evaluateJsCode();
|
|
316
341
|
}
|
|
317
|
-
$: onUpdateFn_0(...[useContent?.()?.data?.jsCode]);
|
|
342
|
+
$: onUpdateFn_0(...[useContent?.()?.data?.jsCode, contentState()]);
|
|
318
343
|
function onUpdateFn_1() {
|
|
319
344
|
runHttpRequests();
|
|
320
345
|
}
|
|
@@ -7,9 +7,11 @@ export function evaluate({
|
|
|
7
7
|
context,
|
|
8
8
|
state,
|
|
9
9
|
event,
|
|
10
|
+
isExpression = true,
|
|
10
11
|
}: {
|
|
11
12
|
code: string;
|
|
12
13
|
event?: Event;
|
|
14
|
+
isExpression?: boolean;
|
|
13
15
|
} & Pick<BuilderContextInterface, 'state' | 'context'>): any {
|
|
14
16
|
if (code === '') {
|
|
15
17
|
console.warn('Skipping evaluation of empty code block.');
|
|
@@ -24,11 +26,14 @@ export function evaluate({
|
|
|
24
26
|
|
|
25
27
|
// Be able to handle simple expressions like "state.foo" or "1 + 1"
|
|
26
28
|
// as well as full blocks like "var foo = "bar"; return foo"
|
|
27
|
-
const useReturn =
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
const useReturn =
|
|
30
|
+
// we disable this for cases where we definitely don't want a return
|
|
31
|
+
isExpression &&
|
|
32
|
+
!(
|
|
33
|
+
code.includes(';') ||
|
|
34
|
+
code.includes(' return ') ||
|
|
35
|
+
code.trim().startsWith('return ')
|
|
36
|
+
);
|
|
32
37
|
|
|
33
38
|
const useCode = useReturn ? `return (${code});` : code;
|
|
34
39
|
|
|
@@ -46,7 +51,7 @@ export function evaluate({
|
|
|
46
51
|
'Builder custom code error: \n While Evaluating: \n ',
|
|
47
52
|
useCode,
|
|
48
53
|
'\n',
|
|
49
|
-
|
|
54
|
+
e
|
|
50
55
|
);
|
|
51
56
|
}
|
|
52
57
|
}
|
|
@@ -1,6 +1 @@
|
|
|
1
|
-
|
|
2
|
-
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export const getEventHandlerName = (key: string) =>
|
|
6
|
-
`on${capitalizeFirstLetter(key)}`;
|
|
1
|
+
export const getEventHandlerName = (key: string) => `on:${key.toLowerCase()}`;
|
|
@@ -2,18 +2,19 @@ import type { BuilderContextInterface } from '../context/types.js';
|
|
|
2
2
|
import type { BuilderBlock } from '../types/builder-block.js';
|
|
3
3
|
import { evaluate } from './evaluate.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
type Options = {
|
|
6
|
+
block: BuilderBlock;
|
|
7
|
+
} & Pick<BuilderContextInterface, 'state' | 'context'>;
|
|
8
|
+
|
|
9
|
+
type EventHandler = (event: Event) => any;
|
|
10
|
+
|
|
11
|
+
export const createEventHandler =
|
|
12
|
+
(value: string, options: Options): EventHandler =>
|
|
13
|
+
(event) =>
|
|
13
14
|
evaluate({
|
|
14
15
|
code: value,
|
|
15
16
|
context: options.context,
|
|
16
17
|
state: options.state,
|
|
17
18
|
event,
|
|
19
|
+
isExpression: false,
|
|
18
20
|
});
|
|
19
|
-
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BuilderContextInterface } from '../context/types.js';
|
|
2
2
|
import type { BuilderBlock } from '../types/builder-block.js';
|
|
3
3
|
import { getEventHandlerName } from './event-handler-name.js';
|
|
4
|
-
import {
|
|
4
|
+
import { createEventHandler } from './get-block-actions-handler.js';
|
|
5
5
|
|
|
6
6
|
type Actions = { [index: string]: (event: Event) => any };
|
|
7
7
|
|
|
@@ -19,7 +19,7 @@ export function getBlockActions(
|
|
|
19
19
|
continue;
|
|
20
20
|
}
|
|
21
21
|
const value = optionActions[key];
|
|
22
|
-
obj[getEventHandlerName(key)] =
|
|
22
|
+
obj[getEventHandlerName(key)] = createEventHandler(value, options);
|
|
23
23
|
}
|
|
24
24
|
return obj;
|
|
25
25
|
}
|
|
@@ -2,7 +2,7 @@ import { isBrowser } from '../is-browser.js';
|
|
|
2
2
|
|
|
3
3
|
const BUILDER_SEARCHPARAMS_PREFIX = 'builder.';
|
|
4
4
|
|
|
5
|
-
type QueryObject = Record<string, string>;
|
|
5
|
+
type QueryObject = Record<string, string | string[]>;
|
|
6
6
|
|
|
7
7
|
export const convertSearchParamsToQueryObject = (
|
|
8
8
|
searchParams: URLSearchParams
|
package/src/functions/track.ts
CHANGED
|
@@ -6,7 +6,12 @@ import { isBrowser } from './is-browser.js';
|
|
|
6
6
|
import { isEditing } from './is-editing.js';
|
|
7
7
|
|
|
8
8
|
interface Event {
|
|
9
|
-
|
|
9
|
+
/**
|
|
10
|
+
* The type of your event.
|
|
11
|
+
*
|
|
12
|
+
* Examples: `click`, `conversion`, `pageview`, `impression`
|
|
13
|
+
*/
|
|
14
|
+
type: string;
|
|
10
15
|
data: {
|
|
11
16
|
/**
|
|
12
17
|
* (Optional) The content's ID. Useful if this event pertains to a specific piece of content.
|
|
@@ -95,6 +100,13 @@ const createEvent = async ({
|
|
|
95
100
|
});
|
|
96
101
|
|
|
97
102
|
export async function _track(eventProps: EventProps) {
|
|
103
|
+
if (!eventProps.apiKey) {
|
|
104
|
+
console.error(
|
|
105
|
+
'[Builder.io]: Missing API key for track call. Please provide your API key.'
|
|
106
|
+
);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
|
|
98
110
|
if (!eventProps.canTrack) {
|
|
99
111
|
return;
|
|
100
112
|
}
|
|
@@ -24,7 +24,12 @@ export const registerInsertMenu = () => {
|
|
|
24
24
|
};
|
|
25
25
|
|
|
26
26
|
let isSetupForEditing = false;
|
|
27
|
-
export const setupBrowserForEditing = (
|
|
27
|
+
export const setupBrowserForEditing = (
|
|
28
|
+
options: {
|
|
29
|
+
includeRefs?: boolean;
|
|
30
|
+
locale?: string;
|
|
31
|
+
} = {}
|
|
32
|
+
) => {
|
|
28
33
|
if (isSetupForEditing) {
|
|
29
34
|
return;
|
|
30
35
|
}
|
|
@@ -48,6 +53,16 @@ export const setupBrowserForEditing = () => {
|
|
|
48
53
|
'*'
|
|
49
54
|
);
|
|
50
55
|
|
|
56
|
+
window.parent?.postMessage(
|
|
57
|
+
{
|
|
58
|
+
type: 'builder.updateContent',
|
|
59
|
+
data: {
|
|
60
|
+
options,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
'*'
|
|
64
|
+
);
|
|
65
|
+
|
|
51
66
|
window.addEventListener('message', ({ data }) => {
|
|
52
67
|
if (!data?.type) {
|
|
53
68
|
return;
|