@builder.io/sdk-react-native 1.0.32 → 1.0.34
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/commonjs/blocks/text/text.js +1 -1
- package/lib/browser/commonjs/constants/sdk-version.js +1 -1
- package/lib/browser/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js +4 -18
- package/lib/browser/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
- package/lib/browser/commonjs/functions/is-from-trusted-host.js +3 -0
- package/lib/browser/commonjs/functions/is-from-trusted-host.js.map +1 -1
- package/lib/browser/commonjs/helpers/cookie.js +12 -2
- package/lib/browser/commonjs/helpers/cookie.js.map +1 -1
- package/lib/browser/module/blocks/text/text.js +1 -1
- package/lib/browser/module/blocks/text/text.js.map +1 -1
- package/lib/browser/module/constants/sdk-version.js +1 -1
- package/lib/browser/module/functions/evaluate/node-runtime/safeDynamicRequire.js +5 -18
- package/lib/browser/module/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
- package/lib/browser/module/functions/is-from-trusted-host.js +3 -0
- package/lib/browser/module/functions/is-from-trusted-host.js.map +1 -1
- package/lib/browser/module/helpers/cookie.js +11 -2
- package/lib/browser/module/helpers/cookie.js.map +1 -1
- package/lib/browser/typescript/constants/sdk-version.d.ts +1 -1
- package/lib/browser/typescript/functions/is-from-trusted-host.d.ts.map +1 -1
- package/lib/browser/typescript/helpers/cookie.d.ts +1 -0
- package/lib/browser/typescript/helpers/cookie.d.ts.map +1 -1
- package/lib/edge/commonjs/blocks/text/text.js +1 -1
- package/lib/edge/commonjs/constants/sdk-version.js +1 -1
- package/lib/edge/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js +4 -18
- package/lib/edge/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
- package/lib/edge/commonjs/functions/is-from-trusted-host.js +3 -0
- package/lib/edge/commonjs/functions/is-from-trusted-host.js.map +1 -1
- package/lib/edge/commonjs/helpers/cookie.js +12 -2
- package/lib/edge/commonjs/helpers/cookie.js.map +1 -1
- package/lib/edge/module/blocks/text/text.js +1 -1
- package/lib/edge/module/blocks/text/text.js.map +1 -1
- package/lib/edge/module/constants/sdk-version.js +1 -1
- package/lib/edge/module/functions/evaluate/node-runtime/safeDynamicRequire.js +5 -18
- package/lib/edge/module/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
- package/lib/edge/module/functions/is-from-trusted-host.js +3 -0
- package/lib/edge/module/functions/is-from-trusted-host.js.map +1 -1
- package/lib/edge/module/helpers/cookie.js +11 -2
- package/lib/edge/module/helpers/cookie.js.map +1 -1
- package/lib/edge/typescript/constants/sdk-version.d.ts +1 -1
- package/lib/edge/typescript/functions/is-from-trusted-host.d.ts.map +1 -1
- package/lib/edge/typescript/helpers/cookie.d.ts +1 -0
- package/lib/edge/typescript/helpers/cookie.d.ts.map +1 -1
- package/lib/node/commonjs/blocks/text/text.js +1 -1
- package/lib/node/commonjs/constants/sdk-version.js +1 -1
- package/lib/node/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js +4 -18
- package/lib/node/commonjs/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
- package/lib/node/commonjs/functions/is-from-trusted-host.js +3 -0
- package/lib/node/commonjs/functions/is-from-trusted-host.js.map +1 -1
- package/lib/node/commonjs/helpers/cookie.js +12 -2
- package/lib/node/commonjs/helpers/cookie.js.map +1 -1
- package/lib/node/module/blocks/text/text.js +1 -1
- package/lib/node/module/blocks/text/text.js.map +1 -1
- package/lib/node/module/constants/sdk-version.js +1 -1
- package/lib/node/module/functions/evaluate/node-runtime/safeDynamicRequire.js +5 -18
- package/lib/node/module/functions/evaluate/node-runtime/safeDynamicRequire.js.map +1 -1
- package/lib/node/module/functions/is-from-trusted-host.js +3 -0
- package/lib/node/module/functions/is-from-trusted-host.js.map +1 -1
- package/lib/node/module/helpers/cookie.js +11 -2
- package/lib/node/module/helpers/cookie.js.map +1 -1
- package/lib/node/typescript/constants/sdk-version.d.ts +1 -1
- package/lib/node/typescript/functions/is-from-trusted-host.d.ts.map +1 -1
- package/lib/node/typescript/helpers/cookie.d.ts +1 -0
- package/lib/node/typescript/helpers/cookie.d.ts.map +1 -1
- package/package.json +10 -7
- package/src/blocks/BaseText.tsx +17 -0
- package/src/blocks/accordion/accordion.tsx +181 -0
- package/src/blocks/accordion/accordion.types.ts +12 -0
- package/src/blocks/accordion/component-info.ts +124 -0
- package/src/blocks/accordion/helpers.ts +3 -0
- package/src/blocks/accordion/index.ts +1 -0
- package/src/blocks/button/button.tsx +56 -0
- package/src/blocks/button/button.types.ts +7 -0
- package/src/blocks/button/component-info.ts +35 -0
- package/src/blocks/button/index.ts +1 -0
- package/src/blocks/columns/columns.tsx +199 -0
- package/src/blocks/columns/columns.types.ts +14 -0
- package/src/blocks/columns/component-info.ts +219 -0
- package/src/blocks/columns/helpers.ts +3 -0
- package/src/blocks/columns/index.ts +1 -0
- package/src/blocks/custom-code/component-info.ts +24 -0
- package/src/blocks/custom-code/custom-code.tsx +71 -0
- package/src/blocks/custom-code/index.ts +1 -0
- package/src/blocks/embed/component-info.ts +38 -0
- package/src/blocks/embed/embed.tsx +62 -0
- package/src/blocks/embed/helpers.ts +2 -0
- package/src/blocks/embed/index.ts +1 -0
- package/src/blocks/form/form/component-info.ts +233 -0
- package/src/blocks/form/form/form.tsx +324 -0
- package/src/blocks/form/form/index.ts +1 -0
- package/src/blocks/form/input/component-info.ts +47 -0
- package/src/blocks/form/input/index.ts +1 -0
- package/src/blocks/form/input/input.tsx +49 -0
- package/src/blocks/form/select/component-info.ts +44 -0
- package/src/blocks/form/select/index.ts +1 -0
- package/src/blocks/form/select/select.tsx +54 -0
- package/src/blocks/form/submit-button/component-info.ts +27 -0
- package/src/blocks/form/submit-button/index.ts +1 -0
- package/src/blocks/form/submit-button/submit-button.tsx +34 -0
- package/src/blocks/fragment/component-info.ts +8 -0
- package/src/blocks/fragment/fragment.tsx +18 -0
- package/src/blocks/fragment/fragment.types.ts +5 -0
- package/src/blocks/fragment/index.ts +1 -0
- package/src/blocks/helpers.ts +43 -0
- package/src/blocks/image/component-info.ts +129 -0
- package/src/blocks/image/image.helpers.ts +47 -0
- package/src/blocks/image/image.tsx +65 -0
- package/src/blocks/image/image.types.ts +20 -0
- package/src/blocks/image/index.ts +1 -0
- package/src/blocks/img/component-info.ts +16 -0
- package/src/blocks/img/img.tsx +55 -0
- package/src/blocks/img/index.ts +1 -0
- package/src/blocks/raw-text/component-info.ts +11 -0
- package/src/blocks/raw-text/index.ts +1 -0
- package/src/blocks/raw-text/raw-text.tsx +1 -0
- package/src/blocks/section/component-info.ts +41 -0
- package/src/blocks/section/index.ts +1 -0
- package/src/blocks/section/section.tsx +39 -0
- package/src/blocks/section/section.types.ts +6 -0
- package/src/blocks/slot/component-info.ts +15 -0
- package/src/blocks/slot/index.ts +1 -0
- package/src/blocks/slot/slot.tsx +42 -0
- package/src/blocks/symbol/component-info.ts +35 -0
- package/src/blocks/symbol/index.ts +1 -0
- package/src/blocks/symbol/symbol.helpers.ts +47 -0
- package/src/blocks/symbol/symbol.tsx +100 -0
- package/src/blocks/symbol/symbol.types.ts +17 -0
- package/src/blocks/tabs/component-info.ts +139 -0
- package/src/blocks/tabs/index.ts +1 -0
- package/src/blocks/tabs/tabs.tsx +79 -0
- package/src/blocks/tabs/tabs.types.ts +13 -0
- package/src/blocks/text/component-info.ts +20 -0
- package/src/blocks/text/index.ts +1 -0
- package/src/blocks/text/text.tsx +105 -0
- package/src/blocks/text/text.types.ts +4 -0
- package/src/blocks/textarea/component-info.ts +38 -0
- package/src/blocks/textarea/index.ts +1 -0
- package/src/blocks/textarea/textarea.tsx +41 -0
- package/src/blocks/video/component-info.ts +83 -0
- package/src/blocks/video/index.ts +1 -0
- package/src/blocks/video/video.tsx +70 -0
- package/src/blocks/video/video.types.ts +21 -0
- package/src/components/block/animator.ts +220 -0
- package/src/components/block/block.helpers.ts +124 -0
- package/src/components/block/block.tsx +232 -0
- package/src/components/block/components/block-styles.tsx +136 -0
- package/src/components/block/components/block-wrapper.tsx +52 -0
- package/src/components/block/components/component-ref/component-ref.helpers.ts +55 -0
- package/src/components/block/components/component-ref/component-ref.tsx +66 -0
- package/src/components/block/components/interactive-element.tsx +53 -0
- package/src/components/block/components/repeated-block.tsx +37 -0
- package/src/components/block/types.ts +6 -0
- package/src/components/blocks/blocks-wrapper.tsx +93 -0
- package/src/components/blocks/blocks.tsx +57 -0
- package/src/components/blocks/blocks.types.ts +7 -0
- package/src/components/blocks/index.ts +1 -0
- package/src/components/content/components/enable-editor.tsx +472 -0
- package/src/components/content/components/styles.helpers.ts +101 -0
- package/src/components/content/components/styles.tsx +42 -0
- package/src/components/content/content.helpers.ts +40 -0
- package/src/components/content/content.tsx +150 -0
- package/src/components/content/content.types.ts +13 -0
- package/src/components/content/contentProps.types.ts +17 -0
- package/src/components/content/index.ts +1 -0
- package/src/components/content/wrap-component-ref.ts +6 -0
- package/src/components/content-variants/content-variants.tsx +146 -0
- package/src/components/content-variants/content-variants.types.ts +84 -0
- package/src/components/content-variants/helpers.ts +72 -0
- package/src/components/content-variants/index.ts +1 -0
- package/src/components/content-variants/inlined-fns.ts +22 -0
- package/src/components/dynamic-div.tsx +30 -0
- package/src/components/dynamic-renderer/dynamic-renderer.helpers.ts +7 -0
- package/src/components/dynamic-renderer/dynamic-renderer.tsx +47 -0
- package/src/components/error-boundary.tsx +38 -0
- package/src/components/inlined-script.tsx +10 -0
- package/src/components/inlined-styles.tsx +10 -0
- package/src/constants/builder-registered-components.ts +59 -0
- package/src/constants/device-sizes.ts +59 -0
- package/src/constants/extra-components.ts +1 -0
- package/src/constants/sdk-version.ts +1 -0
- package/src/constants/target.ts +3 -0
- package/src/context/builder.context.ts +15 -0
- package/src/context/components.context.ts +3 -0
- package/src/context/index.ts +1 -0
- package/src/context/types.ts +38 -0
- package/src/functions/apply-patch-with-mutation.ts +61 -0
- package/src/functions/camel-to-kebab-case.ts +1 -0
- package/src/functions/deopt.ts +6 -0
- package/src/functions/evaluate/browser-runtime/browser.ts +61 -0
- package/src/functions/evaluate/browser-runtime/index.ts +1 -0
- package/src/functions/evaluate/choose-eval.ts +23 -0
- package/src/functions/evaluate/edge-runtime/acorn-interpreter.ts +2891 -0
- package/src/functions/evaluate/edge-runtime/edge-runtime.ts +89 -0
- package/src/functions/evaluate/edge-runtime/index.ts +1 -0
- package/src/functions/evaluate/evaluate.ts +76 -0
- package/src/functions/evaluate/helpers.ts +56 -0
- package/src/functions/evaluate/index.ts +1 -0
- package/src/functions/evaluate/node-runtime/index.ts +1 -0
- package/src/functions/evaluate/node-runtime/init.ts +33 -0
- package/src/functions/evaluate/node-runtime/node-runtime.ts +176 -0
- package/src/functions/evaluate/node-runtime/safeDynamicRequire.ts +14 -0
- package/src/functions/evaluate/placeholder-runtime.ts +4 -0
- package/src/functions/evaluate/should-force-browser-runtime-in-node.ts +16 -0
- package/src/functions/event-handler-name.ts +4 -0
- package/src/functions/extract-text-styles.ts +24 -0
- package/src/functions/fast-clone.ts +4 -0
- package/src/functions/fetch-builder-props.ts +75 -0
- package/src/functions/get-block-actions-handler.ts +17 -0
- package/src/functions/get-block-actions.ts +35 -0
- package/src/functions/get-block-component-options.ts +7 -0
- package/src/functions/get-block-properties.ts +62 -0
- package/src/functions/get-builder-search-params/index.ts +33 -0
- package/src/functions/get-class-prop-name.ts +15 -0
- package/src/functions/get-content/generate-content-url.ts +88 -0
- package/src/functions/get-content/index.ts +99 -0
- package/src/functions/get-content/types.ts +157 -0
- package/src/functions/get-env.ts +5 -0
- package/src/functions/get-fetch.ts +11 -0
- package/src/functions/get-global-this.ts +16 -0
- package/src/functions/get-processed-block.ts +70 -0
- package/src/functions/get-style.ts +38 -0
- package/src/functions/get.ts +4 -0
- package/src/functions/is-browser.ts +3 -0
- package/src/functions/is-edge-runtime.ts +9 -0
- package/src/functions/is-editing.ts +8 -0
- package/src/functions/is-from-trusted-host.ts +11 -0
- package/src/functions/is-iframe.ts +4 -0
- package/src/functions/is-node-runtime.ts +8 -0
- package/src/functions/is-previewing.ts +16 -0
- package/src/functions/on-change.ts +29 -0
- package/src/functions/register-component.ts +30 -0
- package/src/functions/register.ts +44 -0
- package/src/functions/set-editor-settings.ts +15 -0
- package/src/functions/set.ts +14 -0
- package/src/functions/track/helpers.ts +51 -0
- package/src/functions/track/index.ts +131 -0
- package/src/functions/track/interaction.ts +63 -0
- package/src/functions/transform-block-properties.ts +33 -0
- package/src/functions/transform-block.ts +30 -0
- package/src/functions/transform-style-property.ts +296 -0
- package/src/helpers/ab-tests.ts +166 -0
- package/src/helpers/canTrack.ts +2 -0
- package/src/helpers/cookie.ts +109 -0
- package/src/helpers/css.ts +33 -0
- package/src/helpers/flatten.ts +41 -0
- package/src/helpers/localStorage.ts +36 -0
- package/src/helpers/logger.ts +7 -0
- package/src/helpers/nullable.ts +2 -0
- package/src/helpers/omit.ts +7 -0
- package/src/helpers/preview-lru-cache/get.ts +4 -0
- package/src/helpers/preview-lru-cache/helpers.ts +1 -0
- package/src/helpers/preview-lru-cache/init.ts +7 -0
- package/src/helpers/preview-lru-cache/set.ts +12 -0
- package/src/helpers/preview-lru-cache/types.ts +1 -0
- package/src/helpers/search/search.ts +18 -0
- package/src/helpers/sessionId.ts +37 -0
- package/src/helpers/subscribe-to-editor.ts +95 -0
- package/src/helpers/time.ts +2 -0
- package/src/helpers/url.ts +15 -0
- package/src/helpers/uuid.ts +17 -0
- package/src/helpers/visitorId.ts +37 -0
- package/src/index-helpers/blocks-exports.ts +16 -0
- package/src/index-helpers/top-of-file.ts +2 -0
- package/src/index.ts +15 -0
- package/src/scripts/init-editing.ts +119 -0
- package/src/server-index.ts +43 -0
- package/src/types/api-version.ts +2 -0
- package/src/types/builder-block.ts +89 -0
- package/src/types/builder-content.ts +47 -0
- package/src/types/builder-props.ts +12 -0
- package/src/types/can-track.ts +3 -0
- package/src/types/components.ts +119 -0
- package/src/types/deep-partial.ts +1 -0
- package/src/types/element.ts +57 -0
- package/src/types/enforced-partials.ts +19 -0
- package/src/types/input.ts +123 -0
- package/src/types/targets.ts +1 -0
- package/src/types/typescript.ts +9 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const onChangeProxySymbol = Symbol('onChangeProxySymbol');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Deeply observe an object and run a callback when it changes
|
|
5
|
+
*
|
|
6
|
+
* See ./on-change.test.ts for more info
|
|
7
|
+
*/
|
|
8
|
+
export function onChange<T extends object = any>(obj: T, cb: () => void): T {
|
|
9
|
+
return new Proxy(obj, {
|
|
10
|
+
get(target, key) {
|
|
11
|
+
if (key === onChangeProxySymbol) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
const value = Reflect.get(target, key);
|
|
15
|
+
if (value && typeof value === 'object') {
|
|
16
|
+
if ((value as any)[onChangeProxySymbol]) {
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
return onChange(value, cb);
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
},
|
|
23
|
+
set(target, key, value) {
|
|
24
|
+
const returnValue = Reflect.set(target, key, value);
|
|
25
|
+
cb();
|
|
26
|
+
return returnValue;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ComponentInfo } from '../types/components';
|
|
2
|
+
import type { Input } from '../types/input';
|
|
3
|
+
import { fastClone } from './fast-clone';
|
|
4
|
+
export const createRegisterComponentMessage = (info: ComponentInfo) => ({
|
|
5
|
+
type: 'builder.registerComponent',
|
|
6
|
+
data: serializeComponentInfo(info)
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
10
|
+
const serializeFn = (fnValue: Function) => {
|
|
11
|
+
const fnStr = fnValue.toString().trim();
|
|
12
|
+
|
|
13
|
+
// we need to account for a few different fn syntaxes:
|
|
14
|
+
// 1. `function name(args) => {code}`
|
|
15
|
+
// 2. `name(args) => {code}`
|
|
16
|
+
// 3. `(args) => {}`
|
|
17
|
+
const appendFunction = !fnStr.startsWith('function') && !fnStr.startsWith('(');
|
|
18
|
+
return `return (${appendFunction ? 'function ' : ''}${fnStr}).apply(this, arguments)`;
|
|
19
|
+
};
|
|
20
|
+
const serializeValue = (value: object): any => typeof value === 'function' ? serializeFn(value) : fastClone(value);
|
|
21
|
+
export const serializeComponentInfo = ({
|
|
22
|
+
inputs,
|
|
23
|
+
...info
|
|
24
|
+
}: ComponentInfo): ComponentInfo => ({
|
|
25
|
+
...fastClone(info),
|
|
26
|
+
inputs: inputs?.map(input => Object.entries(input).reduce((acc, [key, value]) => ({
|
|
27
|
+
...acc,
|
|
28
|
+
[key]: serializeValue(value)
|
|
29
|
+
}), ({} as Input)))
|
|
30
|
+
})
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { BuilderBlock } from '../types/builder-block';
|
|
2
|
+
import type { DeepPartial } from '../types/deep-partial';
|
|
3
|
+
import { isBrowser } from './is-browser';
|
|
4
|
+
export interface InsertMenuItem {
|
|
5
|
+
name: string;
|
|
6
|
+
icon?: string;
|
|
7
|
+
item: DeepPartial<BuilderBlock>;
|
|
8
|
+
}
|
|
9
|
+
export interface InsertMenuConfig {
|
|
10
|
+
name: string;
|
|
11
|
+
priority?: number;
|
|
12
|
+
persist?: boolean;
|
|
13
|
+
advanced?: boolean;
|
|
14
|
+
items: InsertMenuItem[];
|
|
15
|
+
}
|
|
16
|
+
const registry: {
|
|
17
|
+
[key: string]: any[];
|
|
18
|
+
} = {};
|
|
19
|
+
export function register(type: 'insertMenu', info: InsertMenuConfig): void;
|
|
20
|
+
export function register(type: string, info: any): void;
|
|
21
|
+
export function register(type: string, info: any) {
|
|
22
|
+
let typeList = registry[type];
|
|
23
|
+
if (!typeList) {
|
|
24
|
+
typeList = registry[type] = [];
|
|
25
|
+
}
|
|
26
|
+
typeList.push(info);
|
|
27
|
+
if (isBrowser()) {
|
|
28
|
+
const message = {
|
|
29
|
+
type: 'builder.register',
|
|
30
|
+
data: {
|
|
31
|
+
type,
|
|
32
|
+
info
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
try {
|
|
36
|
+
parent.postMessage(message, '*');
|
|
37
|
+
if (parent !== window) {
|
|
38
|
+
window.postMessage(message, '*');
|
|
39
|
+
}
|
|
40
|
+
} catch (err) {
|
|
41
|
+
console.debug('Could not postmessage', err);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { isBrowser } from './is-browser';
|
|
2
|
+
const settings: Settings = {};
|
|
3
|
+
export type Settings = {
|
|
4
|
+
customInsertMenu?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export function setEditorSettings(newSettings: Settings) {
|
|
7
|
+
if (isBrowser()) {
|
|
8
|
+
Object.assign(settings, newSettings);
|
|
9
|
+
const message = {
|
|
10
|
+
type: 'builder.settingsChange',
|
|
11
|
+
data: settings
|
|
12
|
+
};
|
|
13
|
+
parent.postMessage(message, '*');
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal implementation of lodash's _.set
|
|
3
|
+
* https://lodash.com/docs/4.17.15#set
|
|
4
|
+
*
|
|
5
|
+
* See ./set.test.ts for usage examples
|
|
6
|
+
*/
|
|
7
|
+
export const set = (obj: any, _path: string | string[], value: any) => {
|
|
8
|
+
if (Object(obj) !== obj) {
|
|
9
|
+
return obj;
|
|
10
|
+
}
|
|
11
|
+
const path: string[] = Array.isArray(_path) ? _path : (_path.toString().match(/[^.[\]]+/g) as string[]);
|
|
12
|
+
path.slice(0, -1).reduce((a, c, i) => Object(a[c]) === a[c] ? a[c] : a[c] = Math.abs(Number(path[i + 1])) >> 0 === +path[i + 1] ? [] : {}, obj)[path[path.length - 1]] = value;
|
|
13
|
+
return obj;
|
|
14
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { TARGET } from '../../constants/target';
|
|
2
|
+
import type { Nullable } from '../../helpers/nullable';
|
|
3
|
+
import { isBrowser } from '../is-browser';
|
|
4
|
+
const getLocation = (): Nullable<URL> => {
|
|
5
|
+
if (TARGET === 'reactNative') {
|
|
6
|
+
return null;
|
|
7
|
+
} else if (isBrowser()) {
|
|
8
|
+
const parsedLocation = new URL(location.href);
|
|
9
|
+
|
|
10
|
+
// IE11 bug with parsed path being empty string
|
|
11
|
+
// causes issues with our user targeting
|
|
12
|
+
if (parsedLocation.pathname === '') {
|
|
13
|
+
parsedLocation.pathname = '/';
|
|
14
|
+
}
|
|
15
|
+
return parsedLocation;
|
|
16
|
+
} else {
|
|
17
|
+
console.warn('Cannot get location for tracking in non-browser environment');
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const getUserAgent = () => typeof navigator === 'object' && navigator.userAgent || '';
|
|
22
|
+
export const getUserAttributes = () => {
|
|
23
|
+
const userAgent = getUserAgent();
|
|
24
|
+
const isMobile = {
|
|
25
|
+
Android() {
|
|
26
|
+
return userAgent.match(/Android/i);
|
|
27
|
+
},
|
|
28
|
+
BlackBerry() {
|
|
29
|
+
return userAgent.match(/BlackBerry/i);
|
|
30
|
+
},
|
|
31
|
+
iOS() {
|
|
32
|
+
return userAgent.match(/iPhone|iPod/i);
|
|
33
|
+
},
|
|
34
|
+
Opera() {
|
|
35
|
+
return userAgent.match(/Opera Mini/i);
|
|
36
|
+
},
|
|
37
|
+
Windows() {
|
|
38
|
+
return userAgent.match(/IEMobile/i) || userAgent.match(/WPDesktop/i);
|
|
39
|
+
},
|
|
40
|
+
any() {
|
|
41
|
+
return isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows() || TARGET === 'reactNative';
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const isTablet = userAgent.match(/Tablet|iPad/i);
|
|
45
|
+
const url = getLocation();
|
|
46
|
+
return {
|
|
47
|
+
urlPath: url?.pathname,
|
|
48
|
+
host: url?.host || url?.hostname,
|
|
49
|
+
device: isTablet ? 'tablet' : isMobile.any() ? 'mobile' : 'desktop'
|
|
50
|
+
};
|
|
51
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { TARGET } from '../../constants/target';
|
|
2
|
+
import { logger } from '../../helpers/logger';
|
|
3
|
+
import { getSessionId } from '../../helpers/sessionId';
|
|
4
|
+
import { getVisitorId } from '../../helpers/visitorId';
|
|
5
|
+
import type { CanTrack } from '../../types/can-track';
|
|
6
|
+
import type { Dictionary } from '../../types/typescript';
|
|
7
|
+
import { isBrowser } from '../is-browser';
|
|
8
|
+
import { isEditing } from '../is-editing';
|
|
9
|
+
import { getUserAttributes } from './helpers';
|
|
10
|
+
interface Event {
|
|
11
|
+
/**
|
|
12
|
+
* The type of your event.
|
|
13
|
+
*
|
|
14
|
+
* Examples: `click`, `conversion`, `pageview`, `impression`
|
|
15
|
+
*/
|
|
16
|
+
type: string;
|
|
17
|
+
data: {
|
|
18
|
+
/**
|
|
19
|
+
* (Optional) The content's ID. Useful if this event pertains to a specific piece of content.
|
|
20
|
+
*/
|
|
21
|
+
contentId?: string;
|
|
22
|
+
/**
|
|
23
|
+
* This is the ID of the space that the content belongs to.
|
|
24
|
+
*/
|
|
25
|
+
ownerId: string;
|
|
26
|
+
/**
|
|
27
|
+
* (Optional) metadata that you want to provide with your event.
|
|
28
|
+
*/
|
|
29
|
+
metadata?: Dictionary<any>;
|
|
30
|
+
/**
|
|
31
|
+
* Session ID of the user. This is provided by the SDK by checking session storage.
|
|
32
|
+
*/
|
|
33
|
+
sessionId: string | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Visitor ID of the user. This is provided by the SDK by checking cookies.
|
|
36
|
+
*/
|
|
37
|
+
visitorId: string | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* (Optional) If running an A/B test, the ID of the variation that the user is in.
|
|
40
|
+
*/
|
|
41
|
+
variationId?: string;
|
|
42
|
+
[index: string]: any;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
type TrackingData = {
|
|
46
|
+
visitorId: string | undefined;
|
|
47
|
+
sessionId: string | undefined;
|
|
48
|
+
};
|
|
49
|
+
const getTrackingEventData = async ({
|
|
50
|
+
canTrack
|
|
51
|
+
}: CanTrack): Promise<TrackingData> => {
|
|
52
|
+
if (!canTrack) {
|
|
53
|
+
return {
|
|
54
|
+
visitorId: undefined,
|
|
55
|
+
sessionId: undefined
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const sessionId = await getSessionId({
|
|
59
|
+
canTrack
|
|
60
|
+
});
|
|
61
|
+
const visitorId = getVisitorId({
|
|
62
|
+
canTrack
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
sessionId,
|
|
66
|
+
visitorId
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
type EventProperties = Pick<Event, 'type'> & Pick<Event['data'], 'contentId' | 'variationId' | 'metadata'> & {
|
|
70
|
+
/**
|
|
71
|
+
* Your organization's API key.
|
|
72
|
+
*/
|
|
73
|
+
apiKey: Event['data']['ownerId'];
|
|
74
|
+
/**
|
|
75
|
+
* (Optional) Any additional (non-metadata) properties to add to the event.
|
|
76
|
+
*/
|
|
77
|
+
[index: string]: any;
|
|
78
|
+
};
|
|
79
|
+
export type EventProps = EventProperties & CanTrack;
|
|
80
|
+
const createEvent = async ({
|
|
81
|
+
type: eventType,
|
|
82
|
+
canTrack,
|
|
83
|
+
apiKey,
|
|
84
|
+
metadata,
|
|
85
|
+
...properties
|
|
86
|
+
}: EventProps): Promise<Event> => ({
|
|
87
|
+
type: eventType,
|
|
88
|
+
data: {
|
|
89
|
+
...properties,
|
|
90
|
+
metadata: {
|
|
91
|
+
url: location.href,
|
|
92
|
+
...metadata
|
|
93
|
+
},
|
|
94
|
+
...(await getTrackingEventData({
|
|
95
|
+
canTrack
|
|
96
|
+
})),
|
|
97
|
+
userAttributes: getUserAttributes(),
|
|
98
|
+
ownerId: apiKey
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
export async function _track(eventProps: EventProps) {
|
|
102
|
+
if (!eventProps.apiKey) {
|
|
103
|
+
logger.error('Missing API key for track call. Please provide your API key.');
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (!eventProps.canTrack) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (isEditing()) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (!(isBrowser() || TARGET === 'reactNative')) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
return fetch(`https://cdn.builder.io/api/v1/track`, {
|
|
116
|
+
method: 'POST',
|
|
117
|
+
body: JSON.stringify({
|
|
118
|
+
events: [await createEvent(eventProps)]
|
|
119
|
+
}),
|
|
120
|
+
headers: {
|
|
121
|
+
'content-type': 'application/json'
|
|
122
|
+
},
|
|
123
|
+
mode: 'cors'
|
|
124
|
+
}).catch(err => {
|
|
125
|
+
console.error('Failed to track: ', err);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
export const track = (args: EventProperties) => _track({
|
|
129
|
+
...args,
|
|
130
|
+
canTrack: true
|
|
131
|
+
})
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
function round(num: number) {
|
|
2
|
+
return Math.round(num * 1000) / 1000;
|
|
3
|
+
}
|
|
4
|
+
const findParentElement = (target: HTMLElement, callback: (element: HTMLElement) => boolean, checkElement = true): HTMLElement | null => {
|
|
5
|
+
if (!(target instanceof HTMLElement)) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
let parent: HTMLElement | null = checkElement ? target : target.parentElement;
|
|
9
|
+
do {
|
|
10
|
+
if (!parent) {
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
const matches = callback(parent);
|
|
14
|
+
if (matches) {
|
|
15
|
+
return parent;
|
|
16
|
+
}
|
|
17
|
+
} while (parent = parent.parentElement);
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
20
|
+
const findBuilderParent = (target: HTMLElement) => findParentElement(target, el => {
|
|
21
|
+
const id = el.getAttribute('builder-id') || el.id;
|
|
22
|
+
return Boolean(id?.indexOf('builder-') === 0);
|
|
23
|
+
});
|
|
24
|
+
type Offset = {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
};
|
|
28
|
+
const computeOffset = ({
|
|
29
|
+
event,
|
|
30
|
+
target
|
|
31
|
+
}: {
|
|
32
|
+
event: MouseEvent;
|
|
33
|
+
target: HTMLElement;
|
|
34
|
+
}): Offset => {
|
|
35
|
+
const targetRect = target.getBoundingClientRect();
|
|
36
|
+
const xOffset = event.clientX - targetRect.left;
|
|
37
|
+
const yOffset = event.clientY - targetRect.top;
|
|
38
|
+
const xRatio = round(xOffset / targetRect.width);
|
|
39
|
+
const yRatio = round(yOffset / targetRect.height);
|
|
40
|
+
return {
|
|
41
|
+
x: xRatio,
|
|
42
|
+
y: yRatio
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
export const getInteractionPropertiesForEvent = (event: MouseEvent) => {
|
|
46
|
+
const target = (event.target as HTMLElement | null);
|
|
47
|
+
const targetBuilderElement = target && findBuilderParent(target);
|
|
48
|
+
const builderId = targetBuilderElement?.getAttribute('builder-id') || targetBuilderElement?.id;
|
|
49
|
+
return {
|
|
50
|
+
targetBuilderElement: builderId || undefined,
|
|
51
|
+
metadata: {
|
|
52
|
+
targetOffset: target ? computeOffset({
|
|
53
|
+
event,
|
|
54
|
+
target
|
|
55
|
+
}) : undefined,
|
|
56
|
+
builderTargetOffset: targetBuilderElement ? computeOffset({
|
|
57
|
+
event,
|
|
58
|
+
target: targetBuilderElement
|
|
59
|
+
}) : undefined,
|
|
60
|
+
builderElementIndex: targetBuilderElement && builderId ? ([] as Element[]).slice.call(document.getElementsByClassName(builderId)).indexOf(targetBuilderElement) : undefined
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { findDOMNode } from 'react-dom';
|
|
2
|
+
import type { BuilderContextInterface } from '../context/types';
|
|
3
|
+
import type { BuilderBlock } from '../types/builder-block';
|
|
4
|
+
import { isEditing } from './is-editing';
|
|
5
|
+
|
|
6
|
+
export function transformBlockProperties({
|
|
7
|
+
properties,
|
|
8
|
+
}: {
|
|
9
|
+
block: BuilderBlock;
|
|
10
|
+
context: BuilderContextInterface;
|
|
11
|
+
properties: any;
|
|
12
|
+
}) {
|
|
13
|
+
if (!isEditing()) {
|
|
14
|
+
return properties;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const id = properties['builder-id'];
|
|
18
|
+
|
|
19
|
+
if (!id) {
|
|
20
|
+
console.warn('No builder-id found on properties', properties);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
properties.ref = (ref) => {
|
|
24
|
+
if (isEditing()) {
|
|
25
|
+
const el = findDOMNode(ref);
|
|
26
|
+
if (el && !(el instanceof Text)) {
|
|
27
|
+
el.setAttribute('builder-id', id);
|
|
28
|
+
el.classList.add(id);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
return properties;
|
|
33
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { BuilderBlock } from '../types/builder-block';
|
|
2
|
+
|
|
3
|
+
export function transformBlock(block: BuilderBlock): BuilderBlock {
|
|
4
|
+
// Map the DOM-based pixel format to a native compatible one.
|
|
5
|
+
// react-native doesn't support DOM specific fields like `tagName` and `properties`, but any browser framework (e.g. Vue, etc.) do
|
|
6
|
+
// Additionally, we only want to convert the DOM pixel format (looks like `{ tagName: 'img', properties: { src: '...' } }`)
|
|
7
|
+
// but we may move to a DOM-less pixel format that uses `{ component: { name: 'Image', ... } }` so if a `component` property is provided
|
|
8
|
+
// we assume this accounts for native as well and we should not transform this block
|
|
9
|
+
if (block.id.startsWith('builder-pixel-') && !block.component) {
|
|
10
|
+
return {
|
|
11
|
+
...block,
|
|
12
|
+
// drop the `tagName` field so it never ends up rendered.
|
|
13
|
+
tagName: undefined,
|
|
14
|
+
component: {
|
|
15
|
+
name: 'Image',
|
|
16
|
+
options: {
|
|
17
|
+
image: block.properties.src,
|
|
18
|
+
width: 1,
|
|
19
|
+
height: 1,
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
properties: {
|
|
23
|
+
...block.properties,
|
|
24
|
+
width: 1 as any,
|
|
25
|
+
height: 1 as any,
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
return block;
|
|
30
|
+
}
|