@finsweet/webflow-apps-utils 1.0.6 → 1.0.8
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/dist/index.d.ts +0 -3
- package/dist/index.js +0 -3
- package/dist/types/dom.d.ts +1 -0
- package/dist/types/dom.js +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/webflow.d.ts +1 -1
- package/dist/ui/components/layout/Layout.svelte +4 -3
- package/dist/ui/components/layout/Layout.svelte.d.ts +2 -0
- package/dist/ui/components/layout/common/EditModeMessage.svelte +1 -1
- package/dist/ui/components/layout/examples/ExampleLayout.svelte +1 -1
- package/dist/ui/components/layout/examples/Wrapper.svelte +1 -1
- package/dist/ui/components/text/Text.svelte +4 -2
- package/dist/ui/components/text/types.d.ts +22 -0
- package/dist/ui/icons/ChevronIcon.svelte +1 -1
- package/dist/ui/index.d.ts +4 -0
- package/dist/ui/index.js +4 -0
- package/dist/{providers → ui/providers}/GlobalProvider.stories.js +7 -7
- package/dist/{providers → ui/providers}/GlobalProvider.svelte +1 -1
- package/dist/{router → ui/router}/providers/RouterProvider.svelte +1 -1
- package/dist/{router → ui/router}/router.svelte.d.ts +0 -1
- package/dist/{router → ui/router}/router.svelte.js +3 -2
- package/dist/{stores → ui/stores}/forms/Form.stories.js +5 -5
- package/dist/{stores → ui/stores}/forms/FormDemo.svelte +1 -1
- package/dist/{stores → ui/stores}/index.d.ts +1 -2
- package/dist/{stores → ui/stores}/index.js +1 -2
- package/dist/ui/utils/api/checkIfAppModeIsDesign.d.ts +4 -0
- package/dist/ui/utils/api/checkIfAppModeIsDesign.js +19 -0
- package/dist/ui/utils/api/clipboard/handlePaste.d.ts +15 -0
- package/dist/ui/utils/api/clipboard/handlePaste.js +49 -0
- package/dist/ui/utils/api/clipboard/index.d.ts +1 -0
- package/dist/ui/utils/api/clipboard/index.js +1 -0
- package/dist/ui/utils/api/getAllAssets.d.ts +11 -0
- package/dist/ui/utils/api/getAllAssets.js +20 -0
- package/dist/ui/utils/api/getFinsweetComponentsEnvironment.d.ts +8 -0
- package/dist/ui/utils/api/getFinsweetComponentsEnvironment.js +66 -0
- package/dist/ui/utils/api/index.d.ts +5 -0
- package/dist/ui/utils/api/index.js +5 -0
- package/dist/ui/utils/api/insertWithXSCP.d.ts +4 -0
- package/dist/ui/utils/api/insertWithXSCP.js +12 -0
- package/dist/{utils → ui/utils}/auth/crossWindowLogin.d.ts +1 -1
- package/dist/{utils → ui/utils}/auth/crossWindowLogin.js +1 -1
- package/dist/{utils → ui/utils}/auth/index.d.ts +1 -1
- package/dist/{utils → ui/utils}/auth/index.js +4 -6
- package/dist/{utils → ui/utils}/diff-mapper/DiffMapper.stories.js +2 -2
- package/dist/{utils → ui/utils}/diff-mapper/DiffMapperDemo.svelte +1 -1
- package/dist/{utils → ui/utils}/helpers/goto.js +2 -4
- package/dist/ui/utils/helpers/index.d.ts +1 -0
- package/dist/ui/utils/helpers/index.js +1 -0
- package/dist/ui/utils/index.d.ts +3 -0
- package/dist/ui/utils/index.js +3 -0
- package/dist/utils/constants.d.ts +5 -0
- package/dist/utils/constants.js +11 -0
- package/dist/utils/custom-code/api.d.ts +1 -1
- package/dist/utils/custom-code/api.js +4 -6
- package/dist/utils/custom-code/configs.d.ts +3 -2
- package/dist/utils/custom-code/configs.js +5 -8
- package/dist/utils/custom-code/index.d.ts +1 -1
- package/dist/utils/custom-code/index.js +1 -1
- package/dist/utils/helpers/dom.d.ts +37 -0
- package/dist/utils/helpers/dom.js +104 -0
- package/dist/utils/helpers/encodeDecodeConfigs.d.ts +13 -0
- package/dist/utils/helpers/encodeDecodeConfigs.js +20 -0
- package/dist/utils/helpers/events.d.ts +19 -0
- package/dist/utils/helpers/events.js +28 -0
- package/dist/utils/helpers/forms.d.ts +22 -0
- package/dist/utils/helpers/forms.js +82 -0
- package/dist/utils/helpers/guards.d.ts +124 -0
- package/dist/utils/helpers/guards.js +107 -0
- package/dist/utils/helpers/index.d.ts +8 -1
- package/dist/utils/helpers/index.js +8 -1
- package/dist/utils/helpers/parseCSV.d.ts +6 -0
- package/dist/utils/helpers/parseCSV.js +29 -0
- package/dist/utils/helpers/string.d.ts +23 -0
- package/dist/utils/helpers/string.js +33 -0
- package/dist/utils/helpers/wait.d.ts +13 -0
- package/dist/utils/helpers/wait.js +27 -0
- package/dist/utils/index.d.ts +3 -3
- package/dist/utils/index.js +2 -3
- package/dist/utils/logger/index.d.ts +1 -2
- package/dist/utils/stores/index.d.ts +2 -0
- package/dist/utils/stores/index.js +2 -0
- package/dist/utils/stores/isPreviewMode.d.ts +1 -0
- package/dist/utils/stores/isPreviewMode.js +2 -0
- package/dist/utils/webflow/CopyJSONButton.d.ts +54 -0
- package/dist/utils/webflow/CopyJSONButton.js +117 -0
- package/dist/utils/webflow/DisplayController.d.ts +55 -0
- package/dist/utils/webflow/DisplayController.js +91 -0
- package/dist/utils/webflow/Interaction.d.ts +47 -0
- package/dist/utils/webflow/Interaction.js +52 -0
- package/dist/utils/webflow/index.d.ts +4 -0
- package/dist/utils/webflow/index.js +4 -0
- package/dist/utils/webflow/webflow.d.ts +32 -0
- package/dist/utils/webflow/webflow.js +90 -0
- package/package.json +15 -7
- /package/dist/{providers → ui/providers}/GlobalProvider.stories.d.ts +0 -0
- /package/dist/{providers → ui/providers}/GlobalProvider.svelte.d.ts +0 -0
- /package/dist/{providers → ui/providers}/GlobalProviderDemo.svelte +0 -0
- /package/dist/{providers → ui/providers}/GlobalProviderDemo.svelte.d.ts +0 -0
- /package/dist/{providers → ui/providers}/configuratorUtils.d.ts +0 -0
- /package/dist/{providers → ui/providers}/configuratorUtils.js +0 -0
- /package/dist/{providers → ui/providers}/globalContext.svelte.d.ts +0 -0
- /package/dist/{providers → ui/providers}/globalContext.svelte.js +0 -0
- /package/dist/{providers → ui/providers}/index.d.ts +0 -0
- /package/dist/{providers → ui/providers}/index.js +0 -0
- /package/dist/{providers → ui/providers}/types.d.ts +0 -0
- /package/dist/{providers → ui/providers}/types.js +0 -0
- /package/dist/{router → ui/router}/Router.stories.d.ts +0 -0
- /package/dist/{router → ui/router}/Router.stories.js +0 -0
- /package/dist/{router → ui/router}/examples/RouterExample.svelte +0 -0
- /package/dist/{router → ui/router}/examples/RouterExample.svelte.d.ts +0 -0
- /package/dist/{router → ui/router}/examples/index.d.ts +0 -0
- /package/dist/{router → ui/router}/examples/index.js +0 -0
- /package/dist/{router → ui/router}/examples/pages/AboutPage.svelte +0 -0
- /package/dist/{router → ui/router}/examples/pages/AboutPage.svelte.d.ts +0 -0
- /package/dist/{router → ui/router}/examples/pages/HomePage.svelte +0 -0
- /package/dist/{router → ui/router}/examples/pages/HomePage.svelte.d.ts +0 -0
- /package/dist/{router → ui/router}/examples/pages/NotFoundPage.svelte +0 -0
- /package/dist/{router → ui/router}/examples/pages/NotFoundPage.svelte.d.ts +0 -0
- /package/dist/{router → ui/router}/hooks.svelte.d.ts +0 -0
- /package/dist/{router → ui/router}/hooks.svelte.js +0 -0
- /package/dist/{router → ui/router}/index.d.ts +0 -0
- /package/dist/{router → ui/router}/index.js +0 -0
- /package/dist/{router → ui/router}/providers/Link.svelte +0 -0
- /package/dist/{router → ui/router}/providers/Link.svelte.d.ts +0 -0
- /package/dist/{router → ui/router}/providers/Route.svelte +0 -0
- /package/dist/{router → ui/router}/providers/Route.svelte.d.ts +0 -0
- /package/dist/{router → ui/router}/providers/RouterProvider.svelte.d.ts +0 -0
- /package/dist/{router → ui/router}/providers/index.d.ts +0 -0
- /package/dist/{router → ui/router}/providers/index.js +0 -0
- /package/dist/{stores → ui/stores}/breakpoints.d.ts +0 -0
- /package/dist/{stores → ui/stores}/breakpoints.js +0 -0
- /package/dist/{stores → ui/stores}/componentInjectErrors.d.ts +0 -0
- /package/dist/{stores → ui/stores}/componentInjectErrors.js +0 -0
- /package/dist/{stores/forms.d.ts → ui/stores/form.d.ts} +0 -0
- /package/dist/{stores/forms.js → ui/stores/form.js} +0 -0
- /package/dist/{stores → ui/stores}/forms/Form.stories.d.ts +0 -0
- /package/dist/{stores → ui/stores}/forms/FormDemo.svelte.d.ts +0 -0
- /package/dist/{stores → ui/stores}/showConfirmActionModal.d.ts +0 -0
- /package/dist/{stores → ui/stores}/showConfirmActionModal.js +0 -0
- /package/dist/{stores → ui/stores}/siteInfo.d.ts +0 -0
- /package/dist/{stores → ui/stores}/siteInfo.js +0 -0
- /package/dist/{utils → ui/utils}/diff-mapper/DiffMapper.stories.d.ts +0 -0
- /package/dist/{utils → ui/utils}/diff-mapper/DiffMapperDemo.svelte.d.ts +0 -0
- /package/dist/{utils → ui/utils}/diff-mapper/deepDiffMapper.d.ts +0 -0
- /package/dist/{utils → ui/utils}/diff-mapper/deepDiffMapper.js +0 -0
- /package/dist/{utils → ui/utils}/diff-mapper/index.d.ts +0 -0
- /package/dist/{utils → ui/utils}/diff-mapper/index.js +0 -0
- /package/dist/{utils → ui/utils}/helpers/goto.d.ts +0 -0
- /package/dist/{stores → utils/stores}/router.d.ts +0 -0
- /package/dist/{stores → utils/stores}/router.js +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AUTH0_AUDIENCE, AUTH0_CLIENT_ID, AUTH0_LOGIN_URL, AUTH0_REDIRECT_URL, AUTH0_SCOPE, PROD_FINSWEEET_ACCOUNTS_ORIGIN } from '
|
|
1
|
+
import { AUTH0_AUDIENCE, AUTH0_CLIENT_ID, AUTH0_LOGIN_URL, AUTH0_REDIRECT_URL, AUTH0_SCOPE, PROD_FINSWEEET_ACCOUNTS_ORIGIN } from '../../../utils/constants';
|
|
2
2
|
/**
|
|
3
3
|
* Opens a popup window for cross-window authentication with Auth0.
|
|
4
4
|
*/
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
2
|
import Cookies from 'js-cookie';
|
|
3
3
|
import { get, writable } from 'svelte/store';
|
|
4
|
+
import { getLocalStorage, removeLocalStorage, setLocalStorage } from '../../../utils';
|
|
5
|
+
import { FINSWEET_SUBSCRIPTIONS_ENDPOINT, FINSWEET_SUBSCRIPTIONS_ENDPOINT_STAGING } from '../../../utils/constants';
|
|
4
6
|
import { getFinsweetComponentsEnvironment } from '../api';
|
|
5
|
-
import { getLocalStorage, removeLocalStorage, setLocalStorage } from '../browser-storage';
|
|
6
|
-
import { FINSWEET_SUBSCRIPTIONS_ENDPOINT, FINSWEET_SUBSCRIPTIONS_ENDPOINT_STAGING } from '../constants';
|
|
7
|
-
import { getLogger } from '../logger';
|
|
8
7
|
import { crossWindowLogin } from './crossWindowLogin';
|
|
9
|
-
const logger = getLogger('webflow-apps-ui-utils');
|
|
10
8
|
/**
|
|
11
9
|
* Store for the Finsweet user data.
|
|
12
10
|
*/
|
|
@@ -51,7 +49,7 @@ export const getSubscriptions = async (token) => {
|
|
|
51
49
|
return data;
|
|
52
50
|
}
|
|
53
51
|
catch (error) {
|
|
54
|
-
|
|
52
|
+
console.error('Failed to fetch subscriptions', error);
|
|
55
53
|
return [];
|
|
56
54
|
}
|
|
57
55
|
};
|
|
@@ -95,7 +93,7 @@ export const handleLogin = async () => {
|
|
|
95
93
|
}
|
|
96
94
|
catch (error) {
|
|
97
95
|
const err = error;
|
|
98
|
-
|
|
96
|
+
console.error('Login failed:', err.message);
|
|
99
97
|
finsweetUser.set(null);
|
|
100
98
|
webflow.notify({
|
|
101
99
|
type: 'Error',
|
|
@@ -131,7 +131,7 @@ Automatic cache cleanup when size exceeds 100 entries or TTL expires.
|
|
|
131
131
|
The diff mapper is seamlessly integrated with the GlobalProvider system:
|
|
132
132
|
|
|
133
133
|
\`\`\`typescript
|
|
134
|
-
import { useConfiguratorContext } from '
|
|
134
|
+
import { useConfiguratorContext } from '../../../providers';
|
|
135
135
|
|
|
136
136
|
const configurator = useConfiguratorContext<MyConfigType>();
|
|
137
137
|
|
|
@@ -155,7 +155,7 @@ import {
|
|
|
155
155
|
validateWatchOptions,
|
|
156
156
|
extractKeys,
|
|
157
157
|
createDebouncedUpdate
|
|
158
|
-
} from '
|
|
158
|
+
} from '../../../providers';
|
|
159
159
|
|
|
160
160
|
// Create default configurator state
|
|
161
161
|
const defaultState = createDefaultConfiguratorState<MyConfigType>();
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { get } from 'svelte/store';
|
|
2
2
|
import { navigate } from 'svelte-routing';
|
|
3
|
-
import { routerStore } from '
|
|
4
|
-
import { getLogger } from '../logger';
|
|
5
|
-
const logger = getLogger('webflow-apps-ui-utils');
|
|
3
|
+
import { routerStore } from '../../../utils/stores';
|
|
6
4
|
/**
|
|
7
5
|
* Normalizes a URL path to ensure proper formatting.
|
|
8
6
|
*/
|
|
@@ -21,7 +19,7 @@ const normalizeUrlPath = (path, hash) => {
|
|
|
21
19
|
export const goto = (path = '/', state = {}) => {
|
|
22
20
|
const { hash = '' } = get(routerStore);
|
|
23
21
|
if (!hash) {
|
|
24
|
-
|
|
22
|
+
console.error('goto method found no router hash in the router store. Contact Finsweet support.');
|
|
25
23
|
return;
|
|
26
24
|
}
|
|
27
25
|
const url = normalizeUrlPath(`/${hash}/${path}`, hash);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './goto';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './goto';
|
|
@@ -59,3 +59,8 @@ export declare const BRAND: {
|
|
|
59
59
|
*/
|
|
60
60
|
export declare const FINSWEET_COMPONENTS_WEBFLOW_APP_ORIGINS: string[];
|
|
61
61
|
export declare const ACCEPTED_WEBFLOW_ELEMENTS_FOR_INSERTION: string[];
|
|
62
|
+
/**
|
|
63
|
+
* List of domains that are considered staging.
|
|
64
|
+
*/
|
|
65
|
+
export declare const STAGING_DOMAINS: string[];
|
|
66
|
+
export declare const FINSWEET_LOGO_URL = "https://cdn.prod.website-files.com/61819aaca0e7ac73f85a2d54/6865d68f194e84da9c6452e5_Components%20White%20Logo.svg";
|
package/dist/utils/constants.js
CHANGED
|
@@ -71,3 +71,14 @@ export const ACCEPTED_WEBFLOW_ELEMENTS_FOR_INSERTION = [
|
|
|
71
71
|
'Container',
|
|
72
72
|
'BlockContainer'
|
|
73
73
|
];
|
|
74
|
+
/**
|
|
75
|
+
* List of domains that are considered staging.
|
|
76
|
+
*/
|
|
77
|
+
export const STAGING_DOMAINS = [
|
|
78
|
+
'webflow.io',
|
|
79
|
+
'webflow-ext.com',
|
|
80
|
+
'localhost',
|
|
81
|
+
'canvas.webflow.com',
|
|
82
|
+
'server.wized.com'
|
|
83
|
+
];
|
|
84
|
+
export const FINSWEET_LOGO_URL = 'https://cdn.prod.website-files.com/61819aaca0e7ac73f85a2d54/6865d68f194e84da9c6452e5_Components%20White%20Logo.svg';
|
|
@@ -2,7 +2,7 @@ import type { CustomCodeBlock } from '../../types';
|
|
|
2
2
|
/**
|
|
3
3
|
* Gets stored Custom Code blocks by ID or returns all if no ID provided.
|
|
4
4
|
*/
|
|
5
|
-
export declare const getCustomCode: (
|
|
5
|
+
export declare const getCustomCode: (displayName?: string) => Promise<Array<CustomCodeBlock>>;
|
|
6
6
|
/**
|
|
7
7
|
* Sets custom code blocks in the site.
|
|
8
8
|
*/
|
|
@@ -1,17 +1,15 @@
|
|
|
1
|
-
import { getLogger } from '../logger';
|
|
2
|
-
const logger = getLogger('webflow-apps-ui-utils');
|
|
3
1
|
/**
|
|
4
2
|
* Gets stored Custom Code blocks by ID or returns all if no ID provided.
|
|
5
3
|
*/
|
|
6
|
-
export const getCustomCode = async (
|
|
4
|
+
export const getCustomCode = async (displayName) => {
|
|
7
5
|
//TODO: update this when typings are available plus any other place we have disabled this warning.
|
|
8
6
|
//@ts-expect-error - not available in typings for now
|
|
9
7
|
const customCodeBlock = (await webflow.getSiteCustomCode());
|
|
10
8
|
if (!customCodeBlock || customCodeBlock.length === 0)
|
|
11
9
|
return [];
|
|
12
|
-
if (!
|
|
10
|
+
if (!displayName)
|
|
13
11
|
return customCodeBlock;
|
|
14
|
-
const storedConfigs = customCodeBlock.filter((block) => block.id ===
|
|
12
|
+
const storedConfigs = customCodeBlock.filter((block) => block.id === displayName);
|
|
15
13
|
if (storedConfigs)
|
|
16
14
|
return storedConfigs;
|
|
17
15
|
return [];
|
|
@@ -25,7 +23,7 @@ export const setCustomCode = async (customCodeBlock) => {
|
|
|
25
23
|
await webflow.setSiteCustomCode(customCodeBlock);
|
|
26
24
|
}
|
|
27
25
|
catch (error) {
|
|
28
|
-
|
|
26
|
+
console.error('Failed to save custom code block', error, customCodeBlock);
|
|
29
27
|
}
|
|
30
28
|
};
|
|
31
29
|
/**
|
|
@@ -12,11 +12,12 @@ export type CustomCodeConfigsStore = {
|
|
|
12
12
|
export declare const customCodeConfigsStore: import("svelte/store").Writable<CustomCodeConfigsStore>;
|
|
13
13
|
/**
|
|
14
14
|
* Get configs from custom code.
|
|
15
|
+
* @param displayName - The name of the custom code block to get configs from.
|
|
15
16
|
*/
|
|
16
|
-
export declare const getProjectConfigs: () => Promise<any>;
|
|
17
|
+
export declare const getProjectConfigs: (displayName: string) => Promise<any>;
|
|
17
18
|
/**
|
|
18
19
|
* Fetches configs stored in custom code for a given component.
|
|
19
20
|
* @param component
|
|
20
21
|
* @returns
|
|
21
22
|
*/
|
|
22
|
-
export declare const getComponentConfigs: (component: string) => Promise<any>;
|
|
23
|
+
export declare const getComponentConfigs: (component: string, displayName: string) => Promise<any>;
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { writable } from 'svelte/store';
|
|
2
|
-
import { getLogger } from '../logger';
|
|
3
2
|
import { getCustomCode } from './api';
|
|
4
|
-
const logger = getLogger('utils');
|
|
5
|
-
const DISPLAY_NAME = 'finsweetcomponentsconfig';
|
|
6
3
|
/**
|
|
7
4
|
* Store for Custom Code stored Component configs
|
|
8
5
|
*/
|
|
@@ -13,9 +10,10 @@ export const componentConfigsStore = writable(null);
|
|
|
13
10
|
export const customCodeConfigsStore = writable([]);
|
|
14
11
|
/**
|
|
15
12
|
* Get configs from custom code.
|
|
13
|
+
* @param displayName - The name of the custom code block to get configs from.
|
|
16
14
|
*/
|
|
17
|
-
export const getProjectConfigs = async () => {
|
|
18
|
-
const [customCodeBlock] = await getCustomCode(
|
|
15
|
+
export const getProjectConfigs = async (displayName) => {
|
|
16
|
+
const [customCodeBlock] = await getCustomCode(displayName);
|
|
19
17
|
if (!customCodeBlock || !customCodeBlock.hostedLocation) {
|
|
20
18
|
return null;
|
|
21
19
|
}
|
|
@@ -24,7 +22,6 @@ export const getProjectConfigs = async () => {
|
|
|
24
22
|
const configs = await import(/* @vite-ignore */ customCodeBlock.hostedLocation);
|
|
25
23
|
window.isLoadingCustomCodeConfigs = false;
|
|
26
24
|
customCodeConfigsStore.set(configs);
|
|
27
|
-
logger.log({}, 'Project custom code configs', configs);
|
|
28
25
|
return configs;
|
|
29
26
|
};
|
|
30
27
|
/**
|
|
@@ -32,8 +29,8 @@ export const getProjectConfigs = async () => {
|
|
|
32
29
|
* @param component
|
|
33
30
|
* @returns
|
|
34
31
|
*/
|
|
35
|
-
export const getComponentConfigs = async (component) => {
|
|
36
|
-
const customCodeBlock = await getProjectConfigs();
|
|
32
|
+
export const getComponentConfigs = async (component, displayName) => {
|
|
33
|
+
const customCodeBlock = await getProjectConfigs(displayName);
|
|
37
34
|
if (!customCodeBlock || Object.keys(customCodeBlock[component]).length === 0)
|
|
38
35
|
return null;
|
|
39
36
|
return customCodeBlock[component];
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if an element is scrollable
|
|
3
|
+
* @param element
|
|
4
|
+
* @returns True or false
|
|
5
|
+
*/
|
|
6
|
+
export declare const isScrollable: (element: Element) => boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Finds the first child text node of an element
|
|
9
|
+
* @param element The element to search into.
|
|
10
|
+
*/
|
|
11
|
+
export declare const findTextNode: (element: HTMLElement) => ChildNode | undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Function to fetch the Document of a specified URL.
|
|
14
|
+
*
|
|
15
|
+
* @param url - The URL of the page.
|
|
16
|
+
* @param slug - [optional] The slug of the page.
|
|
17
|
+
* @returns
|
|
18
|
+
*/
|
|
19
|
+
export declare const fetchDocument: (url: string, slug?: string) => Promise<Document>;
|
|
20
|
+
/**
|
|
21
|
+
* Function to fetch the Elements of a specified URL.
|
|
22
|
+
*
|
|
23
|
+
* @param url - The URL of the page.
|
|
24
|
+
* @param tagName - The tag name of the elements to fetch. If not provided, returns the whole page as a string.
|
|
25
|
+
* @param asElement - [optional] If true, returns the element as an object.
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
28
|
+
export declare const fetchElements: (url: URL, tagName?: string, asElement?: boolean) => Promise<string[] | HTMLElement[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Fetch elements by attribute
|
|
31
|
+
*/
|
|
32
|
+
export declare const fetchElementsByAttribute: (url: URL, attribute: string) => Promise<string[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Checks if an element is visible
|
|
35
|
+
* @param element
|
|
36
|
+
*/
|
|
37
|
+
export declare const isVisible: (element: HTMLElement) => boolean;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { load } from 'cheerio';
|
|
2
|
+
import { FINSWEET_REVERSE_PROXY_URL } from '../constants';
|
|
3
|
+
import { isHTMLElement } from './guards';
|
|
4
|
+
/**
|
|
5
|
+
* Check if an element is scrollable
|
|
6
|
+
* @param element
|
|
7
|
+
* @returns True or false
|
|
8
|
+
*/
|
|
9
|
+
export const isScrollable = (element) => {
|
|
10
|
+
const { overflow } = getComputedStyle(element);
|
|
11
|
+
return overflow === 'auto' || overflow === 'scroll';
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Finds the first child text node of an element
|
|
15
|
+
* @param element The element to search into.
|
|
16
|
+
*/
|
|
17
|
+
export const findTextNode = (element) => {
|
|
18
|
+
let textNode;
|
|
19
|
+
for (const node of Array.from(element.childNodes)) {
|
|
20
|
+
if (isHTMLElement(node) && node.childNodes.length)
|
|
21
|
+
textNode = findTextNode(node);
|
|
22
|
+
else if (node.nodeType === Node.TEXT_NODE && node.textContent?.trim())
|
|
23
|
+
textNode = node;
|
|
24
|
+
if (textNode)
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
return textNode;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Function to fetch the Document of a specified URL.
|
|
31
|
+
*
|
|
32
|
+
* @param url - The URL of the page.
|
|
33
|
+
* @param slug - [optional] The slug of the page.
|
|
34
|
+
* @returns
|
|
35
|
+
*/
|
|
36
|
+
export const fetchDocument = async (url, slug) => {
|
|
37
|
+
const pageUrl = new URL(url);
|
|
38
|
+
if (slug)
|
|
39
|
+
pageUrl.pathname = slug;
|
|
40
|
+
const target = `${FINSWEET_REVERSE_PROXY_URL}${pageUrl}`;
|
|
41
|
+
const response = await fetch(target);
|
|
42
|
+
const pageContent = await response.text();
|
|
43
|
+
const parser = new DOMParser();
|
|
44
|
+
return parser.parseFromString(pageContent, 'text/html');
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Function to fetch the Elements of a specified URL.
|
|
48
|
+
*
|
|
49
|
+
* @param url - The URL of the page.
|
|
50
|
+
* @param tagName - The tag name of the elements to fetch. If not provided, returns the whole page as a string.
|
|
51
|
+
* @param asElement - [optional] If true, returns the element as an object.
|
|
52
|
+
* @returns
|
|
53
|
+
*/
|
|
54
|
+
export const fetchElements = async (url, tagName, asElement) => {
|
|
55
|
+
const target = `${FINSWEET_REVERSE_PROXY_URL}${url.href}`;
|
|
56
|
+
const response = await fetch(target);
|
|
57
|
+
const html = await response.text();
|
|
58
|
+
const $ = load(html);
|
|
59
|
+
// return the whole page if no tag name is provided
|
|
60
|
+
if (!tagName)
|
|
61
|
+
return [$.html()];
|
|
62
|
+
// crawl page and get elements
|
|
63
|
+
if (asElement && tagName) {
|
|
64
|
+
const elements = $(tagName)
|
|
65
|
+
.map((_, el) => {
|
|
66
|
+
const outerHTML = $.html(el); // Get the outer HTML of each element
|
|
67
|
+
const parser = new DOMParser();
|
|
68
|
+
const parsedDoc = parser.parseFromString(outerHTML, 'text/html');
|
|
69
|
+
const element = parsedDoc.querySelector(tagName);
|
|
70
|
+
return element;
|
|
71
|
+
})
|
|
72
|
+
.get();
|
|
73
|
+
return elements;
|
|
74
|
+
}
|
|
75
|
+
// crawl page and get elements as strings
|
|
76
|
+
const elements = $(tagName)
|
|
77
|
+
.map((_, el) => {
|
|
78
|
+
const outerHTML = $.html(el);
|
|
79
|
+
return outerHTML;
|
|
80
|
+
})
|
|
81
|
+
.get();
|
|
82
|
+
return elements;
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Fetch elements by attribute
|
|
86
|
+
*/
|
|
87
|
+
export const fetchElementsByAttribute = async (url, attribute) => {
|
|
88
|
+
const target = `${FINSWEET_REVERSE_PROXY_URL}${url.href}`;
|
|
89
|
+
const response = await fetch(target);
|
|
90
|
+
const html = await response.text();
|
|
91
|
+
const $ = load(html);
|
|
92
|
+
const elements = $(attribute)
|
|
93
|
+
.map((_, el) => {
|
|
94
|
+
const outerHTML = $.html(el);
|
|
95
|
+
return outerHTML;
|
|
96
|
+
})
|
|
97
|
+
.get();
|
|
98
|
+
return elements;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* Checks if an element is visible
|
|
102
|
+
* @param element
|
|
103
|
+
*/
|
|
104
|
+
export const isVisible = (element) => !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a configuration object to a base64-encoded string.
|
|
3
|
+
* @param {object} configs
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
export declare const encodeComponentConfigs: (configs: object) => string;
|
|
7
|
+
/**
|
|
8
|
+
* Decodes a base64-encoded configuration string to a configuration object.
|
|
9
|
+
* @param configsString
|
|
10
|
+
* @param component
|
|
11
|
+
* @returns
|
|
12
|
+
*/
|
|
13
|
+
export declare const decodeComponentConfigs: <T>(configsString: string) => T;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Converts a configuration object to a base64-encoded string.
|
|
3
|
+
* @param {object} configs
|
|
4
|
+
* @returns
|
|
5
|
+
*/
|
|
6
|
+
export const encodeComponentConfigs = (configs) => {
|
|
7
|
+
const previewModeConfigs = btoa(JSON.stringify(configs));
|
|
8
|
+
return previewModeConfigs;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Decodes a base64-encoded configuration string to a configuration object.
|
|
12
|
+
* @param configsString
|
|
13
|
+
* @param component
|
|
14
|
+
* @returns
|
|
15
|
+
*/
|
|
16
|
+
export const decodeComponentConfigs = (configsString) => {
|
|
17
|
+
const jsonString = atob(configsString);
|
|
18
|
+
const configParsed = JSON.parse(jsonString);
|
|
19
|
+
return configParsed;
|
|
20
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Adds an event listener to an element.
|
|
3
|
+
* @returns A callback to remove the event listener from the element.
|
|
4
|
+
*
|
|
5
|
+
* @param target
|
|
6
|
+
* @param type
|
|
7
|
+
* @param listener
|
|
8
|
+
* @param options
|
|
9
|
+
*/
|
|
10
|
+
export declare function addListener<TargetInterface extends EventTarget, Type extends TargetInterface extends Window ? keyof WindowEventMap | string : TargetInterface extends Document ? keyof DocumentEventMap | string : TargetInterface extends HTMLElement ? keyof HTMLElementEventMap | string : keyof ElementEventMap | string, Listener extends Type extends keyof WindowEventMap ? (this: Document, ev: WindowEventMap[Type]) => unknown : Type extends keyof DocumentEventMap ? (this: Document, ev: DocumentEventMap[Type]) => unknown : Type extends keyof HTMLElementEventMap ? (this: HTMLElement, ev: HTMLElementEventMap[Type]) => unknown : Type extends keyof ElementEventMap ? (this: Element, ev: ElementEventMap[Type]) => unknown : EventListenerOrEventListenerObject>(target: TargetInterface | null | undefined, type: Type, listener: Listener, options?: boolean | AddEventListenerOptions): () => void;
|
|
11
|
+
type AllowedEvent = keyof DocumentEventMap | 'w-close';
|
|
12
|
+
/**
|
|
13
|
+
* Dispatches a custom event that bubbles from the target.
|
|
14
|
+
* @param target The element where the event will originate.
|
|
15
|
+
* @param events The event name or an array of event names.
|
|
16
|
+
* @returns True if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
|
|
17
|
+
*/
|
|
18
|
+
export declare const simulateEvent: (target: EventTarget, events: AllowedEvent | Array<AllowedEvent>) => boolean;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { noop } from './noop';
|
|
2
|
+
/**
|
|
3
|
+
* Adds an event listener to an element.
|
|
4
|
+
* @returns A callback to remove the event listener from the element.
|
|
5
|
+
*
|
|
6
|
+
* @param target
|
|
7
|
+
* @param type
|
|
8
|
+
* @param listener
|
|
9
|
+
* @param options
|
|
10
|
+
*/
|
|
11
|
+
export function addListener(target, type, listener, options) {
|
|
12
|
+
if (!target)
|
|
13
|
+
return noop;
|
|
14
|
+
target.addEventListener(type, listener, options);
|
|
15
|
+
return () => target.removeEventListener(type, listener, options);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Dispatches a custom event that bubbles from the target.
|
|
19
|
+
* @param target The element where the event will originate.
|
|
20
|
+
* @param events The event name or an array of event names.
|
|
21
|
+
* @returns True if either event's cancelable attribute value is false or its preventDefault() method was not invoked, and false otherwise.
|
|
22
|
+
*/
|
|
23
|
+
export const simulateEvent = (target, events) => {
|
|
24
|
+
if (!Array.isArray(events))
|
|
25
|
+
events = [events];
|
|
26
|
+
const eventsSuccess = events.map((event) => target.dispatchEvent(new Event(event, { bubbles: true })));
|
|
27
|
+
return eventsSuccess.every((success) => success);
|
|
28
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { FormField } from '../../types';
|
|
2
|
+
import { simulateEvent } from './events';
|
|
3
|
+
/**
|
|
4
|
+
* Clears the form field's value and emits an input and changed event.
|
|
5
|
+
* If the field is a checkbox or a radio, it will unselect it.
|
|
6
|
+
* @param field The `FormField` to clear.
|
|
7
|
+
* @param omitEvents By default, events are dispatched from the `FormField`. In some cases, these events might collide with other logic of the system.
|
|
8
|
+
* You can omit certain events from being dispatched by passing them in an array.
|
|
9
|
+
*/
|
|
10
|
+
export declare const clearFormField: (field: FormField, omitEvents?: Parameters<typeof simulateEvent>["1"]) => void;
|
|
11
|
+
/**
|
|
12
|
+
* Gets the value of a given input element.
|
|
13
|
+
* @param {FormField} input
|
|
14
|
+
*/
|
|
15
|
+
export declare const getFormFieldValue: (input: FormField) => string;
|
|
16
|
+
/**
|
|
17
|
+
* Sets a value to a FormField element and emits `click`, `input` and `change` Events.
|
|
18
|
+
*
|
|
19
|
+
* @param element The FormField to update.
|
|
20
|
+
* @param value `boolean` for Checkboxes and Radios, `string` for the rest.
|
|
21
|
+
*/
|
|
22
|
+
export declare const setFormFieldValue: (element: FormField, value: string | boolean) => void;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { FORM_CSS_CLASSES } from '../webflow';
|
|
2
|
+
import { simulateEvent } from './events';
|
|
3
|
+
import { isHTMLInputElement } from './guards';
|
|
4
|
+
/**
|
|
5
|
+
* Clears the form field's value and emits an input and changed event.
|
|
6
|
+
* If the field is a checkbox or a radio, it will unselect it.
|
|
7
|
+
* @param field The `FormField` to clear.
|
|
8
|
+
* @param omitEvents By default, events are dispatched from the `FormField`. In some cases, these events might collide with other logic of the system.
|
|
9
|
+
* You can omit certain events from being dispatched by passing them in an array.
|
|
10
|
+
*/
|
|
11
|
+
export const clearFormField = (field, omitEvents = []) => {
|
|
12
|
+
const { type } = field;
|
|
13
|
+
if (isHTMLInputElement(field) && ['checkbox', 'radio'].includes(type)) {
|
|
14
|
+
if (!field.checked)
|
|
15
|
+
return;
|
|
16
|
+
// Reset the field's value
|
|
17
|
+
field.checked = false;
|
|
18
|
+
// Emit DOM events
|
|
19
|
+
simulateEvent(field, ['click', 'input', 'change'].filter((event) => !omitEvents.includes(event)));
|
|
20
|
+
if (type === 'checkbox')
|
|
21
|
+
return;
|
|
22
|
+
// Clear custom radio button classes
|
|
23
|
+
const { parentElement } = field;
|
|
24
|
+
if (!parentElement)
|
|
25
|
+
return;
|
|
26
|
+
const radioInput = parentElement.querySelector(`.${FORM_CSS_CLASSES.radioInput}`);
|
|
27
|
+
if (!radioInput)
|
|
28
|
+
return;
|
|
29
|
+
radioInput.classList.remove(FORM_CSS_CLASSES.checkboxOrRadioFocus, FORM_CSS_CLASSES.checkboxOrRadioChecked);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// Reset the field's value
|
|
33
|
+
field.value = '';
|
|
34
|
+
// Emit DOM events
|
|
35
|
+
simulateEvent(field, ['input', 'change'].filter((eventKey) => !omitEvents.includes(eventKey)));
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Gets the value of a given input element.
|
|
39
|
+
* @param {FormField} input
|
|
40
|
+
*/
|
|
41
|
+
export const getFormFieldValue = (input) => {
|
|
42
|
+
let { value } = input;
|
|
43
|
+
// Perform actions depending on input type
|
|
44
|
+
if (input.type === 'checkbox')
|
|
45
|
+
value = input.checked.toString();
|
|
46
|
+
if (input.type === 'radio') {
|
|
47
|
+
// Get the checked radio
|
|
48
|
+
const checkedOption = input
|
|
49
|
+
.closest('form')
|
|
50
|
+
?.querySelector(`input[name="${input.name}"]:checked`);
|
|
51
|
+
// If exists, set its value
|
|
52
|
+
value = isHTMLInputElement(checkedOption) ? checkedOption.value : '';
|
|
53
|
+
}
|
|
54
|
+
return value.toString();
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Sets a value to a FormField element and emits `click`, `input` and `change` Events.
|
|
58
|
+
*
|
|
59
|
+
* @param element The FormField to update.
|
|
60
|
+
* @param value `boolean` for Checkboxes and Radios, `string` for the rest.
|
|
61
|
+
*/
|
|
62
|
+
export const setFormFieldValue = (element, value) => {
|
|
63
|
+
const { type } = element;
|
|
64
|
+
const isRadio = type === 'radio';
|
|
65
|
+
const isCheckbox = type === 'checkbox';
|
|
66
|
+
if (isRadio || isCheckbox) {
|
|
67
|
+
if (!isHTMLInputElement(element) ||
|
|
68
|
+
typeof value !== 'boolean' ||
|
|
69
|
+
value === element.checked ||
|
|
70
|
+
(isRadio && value === false)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
element.checked = value;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
if (element.value === value)
|
|
77
|
+
return;
|
|
78
|
+
element.value = value.toString();
|
|
79
|
+
}
|
|
80
|
+
// Emit DOM events
|
|
81
|
+
simulateEvent(element, ['click', 'input', 'change']);
|
|
82
|
+
};
|