PluginProbe ʕ •ᴥ•ʔ
GiveWP – Donation Plugin and Fundraising Platform / 4.16.6
GiveWP – Donation Plugin and Fundraising Platform v4.16.6
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 2.30.0 2.31.0 2.31.1 2.32.0 2.33.0 2.33.1 2.33.2 2.33.3 2.33.4 2.33.5 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.4.7 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.2 2.5.3 2.5.4 2.5.5 2.5.6 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.2 2.6.3 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.8.0 2.8.1 2.9.0 2.9.1 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.10.0 3.11.0 3.12.0 3.12.1 3.12.2 3.12.3 3.13.0 3.14.0 3.14.1 3.14.2 3.15.0 3.15.1 3.16.0 3.16.1 3.16.2 3.16.3 3.16.4 3.16.5 3.17.0 3.17.1 3.17.2 3.18.0 3.19.0 3.19.1 3.19.2 3.19.3 3.19.4 3.2.0 3.2.1 3.2.2 3.20.0 3.21.0 3.21.1 3.22.0 3.22.1 3.22.2 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.7.0 3.8.0 3.9.0 4.0.0 4.1.0 4.1.1 4.10.0 4.10.1 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.14.5 4.14.6 4.2.0 4.2.1 4.3.0 4.3.1 4.3.2 4.4.0 4.5.0 4.6.1 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 trunk 1.9.0 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.2 2.11.3 2.12.0 2.12.1 2.12.2 2.12.3 2.13.0 2.13.1 2.13.2 2.13.3 2.13.4 2.14.0 2.15.0 2.16.0 2.16.1 2.17.0 2.17.1 2.17.3 2.18.0 2.18.1 2.19.1 2.19.2 2.19.3 2.19.4 2.19.5 2.19.6 2.19.7 2.19.8 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.20.0 2.20.1 2.20.2 2.21.0 2.21.1 2.21.2 2.21.3 2.21.4 2.22.0 2.22.1 2.22.2 2.22.3 2.23.0 2.23.1 2.23.2 2.24.0 2.24.1 2.24.2 2.25.0 2.25.1 2.25.2 2.25.3 2.26.0 2.27.0 2.27.1 2.27.2 2.27.3 2.28.0 2.29.0 2.29.1 2.29.2
give / src / DonationForms / resources / registrars / templates / fields / Consent / createIframePortal.tsx
give / src / DonationForms / resources / registrars / templates / fields / Consent Last commit date
ConsentModal.tsx 2 years ago ShowTerms.tsx 2 years ago createIframePortal.tsx 1 year ago index.tsx 2 years ago styles.scss 2 years ago
createIframePortal.tsx
121 lines
1 import {createPortal} from 'react-dom';
2 import {createRoot} from 'react-dom/client';
3 import {useEffect, useRef} from 'react';
4
5 import './styles.scss';
6
7 /**
8 * @since 3.14.0
9 * Creates a portal to the Top Level document, rendering children elements within an iframe.
10 */
11 export default function createIframePortal(children, targetElement = window.top.document.body) {
12 const iframeRef = useRef<HTMLIFrameElement | null>(null);
13 const rootRef = useRef<any>(null);
14
15 useEffect(() => {
16 const iframe = iframeRef.current;
17 if (!iframe) return;
18
19 // Wait for iframe to be ready
20 const setupIframe = () => {
21 const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
22
23 // Clear existing content
24 iframeDoc.open();
25 iframeDoc.write('<!DOCTYPE html><html><head></head><body></body></html>');
26 iframeDoc.close();
27
28 async function renderContent() {
29 try {
30 await fetchStylesheets(iframeDoc);
31 // Create a container in the iframe
32 const iframeContainer = iframeDoc.createElement('div');
33 iframeContainer.id = 'givewp-fields-consent-iframe-container';
34 iframeDoc.body.appendChild(iframeContainer);
35
36 // Create root and render
37 rootRef.current = createRoot(iframeContainer);
38 rootRef.current.render(children);
39 } catch (error) {
40 console.error('Error loading stylesheets:', error);
41 }
42 }
43
44 renderContent();
45 };
46
47 iframe.onload = setupIframe;
48
49 if (iframe.contentDocument?.readyState === 'complete') {
50 setupIframe();
51 }
52 }, [children, targetElement]);
53
54 return createPortal(
55 <iframe
56 ref={iframeRef}
57 id={'givewp-fields-consent-iframe-portal'}
58 style={{
59 position: 'fixed',
60 border: 'none',
61 top: '0',
62 left: '0',
63 minHeight: '100%',
64 minWidth: '100%',
65 // Required to be visible in the Visual Form Builder.
66 zIndex: '9999999999',
67 }}
68 />,
69 targetElement
70 );
71 }
72
73 /**
74 * @since 3.14.0
75 * Fetches stylesheets from the originating document and injects them into the new iframe document's head.
76 * This allows user provided styles to be applied to the iframe content.
77 * Returns a promise that resolves when all stylesheets are loaded.
78 */
79 export async function fetchStylesheets(iframeDoc: Document) {
80 const styleSheets = Array.from(document.styleSheets);
81
82 // Promisify the loading of each stylesheet
83 const loadStylesheet = (styleSheet) => {
84 return new Promise<void>((resolve, reject) => {
85 try {
86 if (styleSheet.href) {
87 // For external stylesheets
88 const newLink = document.createElement('link');
89 newLink.rel = 'stylesheet';
90 newLink.href = styleSheet.href;
91 newLink.onload = () => resolve();
92 newLink.onerror = reject;
93 iframeDoc.head.appendChild(newLink);
94 } else if (styleSheet.cssRules) {
95 // For <style/> tags
96 const newStyle = document.createElement('style');
97 Array.from(styleSheet.cssRules).forEach((rule: {cssText: string}) => {
98 newStyle.appendChild(document.createTextNode(rule.cssText));
99 });
100 iframeDoc.head.appendChild(newStyle);
101 resolve();
102 } else {
103 const styleElement = styleSheet.ownerNode;
104 if (styleElement) {
105 const clonedStyle = styleElement.cloneNode(true);
106 iframeDoc.head.appendChild(clonedStyle);
107 resolve();
108 } else {
109 resolve();
110 }
111 }
112 } catch (error) {
113 reject(error);
114 }
115 });
116 };
117
118 const promises = styleSheets.map(loadStylesheet);
119 return await Promise.all(promises);
120 }
121