import React, { VoidFunctionComponent, useEffect, useRef, useState } from 'react'; import { ViewProps } from './ViewRenderer'; export interface UrlViewProps { url: string; /** Inject CSS into the webview */ css?: string; /** Inject JS into the webview */ js?: string; /** Add query parameters to the url */ query?: Record; /** Set or clear the localStorage of the webview */ localStorage?: Record; } interface DetailedHTMLWebViewElement extends HTMLWebViewElement { removeInsertedCSS: (key: string) => void; insertCSS: (css: string) => Promise; // eslint-disable-next-line @typescript-eslint/no-explicit-any executeJavaScript: (code: string, userGesture?: boolean) => Promise; openDevTools: () => void; closeDevTools: () => void; reload: () => void; reloadIgnoringCache: () => void; } const UrlView: VoidFunctionComponent = ({ url, css, js, query, localStorage, mouseInteraction, onReady }) => { const ref = useRef(null); const readyTimeoutRef = useRef(null); const [cssKey, setCssKey] = useState(); /** Load optional CSS and localStorage in the ref */ const manipulateContent = () => { ref.current?.addEventListener('crashed', () => { ref.current?.reloadIgnoringCache(); }); ref.current?.addEventListener('did-finish-load', () => { if (cssKey) { ref.current?.removeInsertedCSS(cssKey); setCssKey(undefined); } if (css) { ref.current?.insertCSS(css).then((key: string) => { setCssKey(key); }); } if (js) { ref.current?.executeJavaScript(js); } if (localStorage) { let script = ''; Object.keys(localStorage).forEach((key) => { const content = localStorage[key]; if (!content) { script += `localStorage.removeItem('${key}');`; } else { script += `localStorage.setItem('${key}', '${content}');`; } }); ref.current?.executeJavaScript(script); } readyTimeoutRef.current && clearTimeout(readyTimeoutRef.current); readyTimeoutRef.current = setTimeout(onReady, 500); }); }; const getURL = (url: string, query?: Record): string => { const updatedURL = new URL(url); if (query) { Object.keys(query).forEach(key => { updatedURL.searchParams.set(key, query[key]); }); } return updatedURL.href; }; useEffect(manipulateContent, []); return ( ); }; export default UrlView;