PluginProbe
GiveWP – Donation Plugin and Fundraising Platform / 4.17.0
GiveWP – Donation Plugin and Fundraising Platform v4.17.0
4.17.0 4.16.9 4.16.8.1 4.16.8 4.16.7.2 4.16.7.1 4.16.7 4.16.6.1 4.16.6 4.16.5.1 4.16.5 4.16.4 4.16.3 4.16.2 4.16.1 4.16.0 4.15.5 4.15.4 4.15.3 4.15.2 4.15.1 4.15.0 2.3.0 2.3.1 2.3.2 All 256 releases
give / src / DonationForms / resources / app / utilities / useDonationFormPubSub.ts

useDonationFormPubSub.ts in GiveWP – Donation Plugin and Fundraising Platform 4.17.0, at src/DonationForms/resources/app/utilities/useDonationFormPubSub.ts

190 lines 5.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import {RefObject, useEffect} from 'react';
2 import {iframeRef} from '@givewp/form-builder/components/canvas/DesignPreview';
3 import {FormSettings} from '@givewp/form-builder/types';
4 import {FormColors, FormGoal, RequireAtLeastOne} from '@givewp/forms/types';
5
6 /**
7 * Events used in design mode
8 */
9 export const PREVIEW_EVENTS = {
10 SETTINGS: 'preview:settings',
11 GOAL: 'preview:goal',
12 GOAL_SOURCE: 'preview:goal_source',
13 COLORS: 'preview:colors',
14 CSS: 'preview:css',
15 DESIGN_SETTINGS: 'preview:design-settings',
16 }
17
18 /**
19 * Simple Publish/Subscribe system used for handling form state in preview mode
20 *
21 * @since 3.1.0
22 */
23 export default function useDonationFormPubSub() {
24
25 const events = {};
26
27 useEffect(() => {
28 addEventListener('message', eventListener, false);
29 return () => removeEventListener('message', eventListener);
30 }, []);
31
32 const getMessage = (message: MessageEvent) => {
33 // handle IframeResizer messages
34 if (typeof message.data === 'string') {
35 if (message.data.includes('[iFrameSizer]message:')) {
36 return JSON.parse(message.data.replace('[iFrameSizer]message:', ''));
37 }
38 }
39
40 return message.data
41 }
42
43 /**
44 * @since 4.17.0 Ignore messages from other origins.
45 */
46 const eventListener = (message: MessageEvent) => {
47 if (message.origin !== window.location.origin) {
48 return;
49 }
50
51 const {event, data} = getMessage(message);
52
53 if (events[event]) {
54
55 const filtered = {};
56 // Allow only primitive values
57 Object.entries(data).forEach(([key, value]) => {
58 if (typeof value !== 'function' && typeof value !== 'object') {
59 filtered[key] = value;
60 }
61 });
62
63 events[event].forEach((callback: (data: any) => void) => {
64 callback(filtered);
65 });
66 }
67 }
68
69 const subscribe = (event: string, callback: Function) => {
70 if (!events[event]) {
71 events[event] = [];
72 }
73
74 events[event].push(callback);
75 }
76
77 const publish = (event: string, data: any, iframeRef: RefObject<any>) => {
78 if (iframeRef.current?.sendMessage) {
79 iframeRef.current.sendMessage({
80 event,
81 data
82 });
83 }
84 }
85
86 const publishSettings = (data: RequireAtLeastOne<FormSettings>) => {
87 publish(PREVIEW_EVENTS.SETTINGS, data, iframeRef)
88 }
89
90
91 const publishDesignSettings = (data: RequireAtLeastOne<FormSettings>) => {
92 publish(PREVIEW_EVENTS.DESIGN_SETTINGS, data, iframeRef)
93 }
94
95 const publishGoal = (data: RequireAtLeastOne<FormGoal>) => {
96 publish(PREVIEW_EVENTS.GOAL, data, iframeRef)
97 }
98
99 /**
100 * @since 4.1.0
101 */
102 const publishGoalSource = (data: RequireAtLeastOne<FormSettings>) => {
103 publish(PREVIEW_EVENTS.GOAL_SOURCE, data, iframeRef)
104 }
105
106 const publishGoalType = (type: string) => {
107 const isMoney = ['amount', 'amountFromSubscriptions'].includes(type);
108
109 publish(PREVIEW_EVENTS.GOAL, {
110 type,
111 label: type,
112 typeIsCount: !isMoney,
113 typeIsMoney: isMoney,
114 }, iframeRef)
115 }
116
117 const publishColors = (data: RequireAtLeastOne<FormColors>) => {
118 publish(PREVIEW_EVENTS.COLORS, data, iframeRef)
119 }
120
121 const publishCss = (data: {customCss: string} ) => {
122 publish(PREVIEW_EVENTS.CSS, data, iframeRef)
123 }
124
125 const subscribeToSettings = (callback: (data: FormSettings) => void) => {
126 subscribe(PREVIEW_EVENTS.SETTINGS, callback)
127 }
128
129 const subscribeToDesignSettings = (callback: (data) => void) => {
130 subscribe(PREVIEW_EVENTS.DESIGN_SETTINGS, callback)
131 }
132
133 const subscribeToGoal = (callback: (data: FormGoal) => void) => {
134 subscribe(PREVIEW_EVENTS.GOAL, callback)
135 }
136
137 /**
138 * @since 4.1.0
139 */
140 const subscribeToGoalSource = (callback: (data: 'campaign' | 'form') => void) => {
141 subscribe(PREVIEW_EVENTS.GOAL, callback)
142 }
143
144 const subscribeToColors = (callback: (data: FormColors) => void) => {
145 subscribe(PREVIEW_EVENTS.COLORS, callback)
146 }
147
148 const subscribeToCss = (callback: (data: {customCss: string}) => void) => {
149 subscribe(PREVIEW_EVENTS.CSS, callback)
150 }
151
152 /**
153 * Unsubscribe from event
154 *
155 * @param event
156 */
157 const unsubscribe = (event: string) => {
158 if (events[event]) {
159 delete events[event];
160 }
161 }
162
163 /**
164 * Unsubscribe from all event
165 */
166 const unsubscribeAll = () => {
167 for (const key in PREVIEW_EVENTS) {
168 delete events[key];
169 }
170 }
171
172 return {
173 unsubscribe,
174 unsubscribeAll,
175 publishGoal,
176 publishGoalSource,
177 publishGoalType,
178 publishColors,
179 publishCss,
180 publishSettings,
181 publishDesignSettings,
182 subscribeToGoal,
183 subscribeToGoalSource,
184 subscribeToColors,
185 subscribeToSettings,
186 subscribeToCss,
187 subscribeToDesignSettings
188 }
189 }
190