diff --git a/apple/IFrameDetector.h b/apple/IFrameDetector.h new file mode 100644 index 000000000..d6b44e630 --- /dev/null +++ b/apple/IFrameDetector.h @@ -0,0 +1,7 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +NSString* getIFrameDetectorScript(void); + +NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/apple/IFrameDetector.m b/apple/IFrameDetector.m new file mode 100644 index 000000000..f95fe56d7 --- /dev/null +++ b/apple/IFrameDetector.m @@ -0,0 +1,83 @@ +#import "IFrameDetector.h" + +/** + * JavaScript code to detect all iFrames in the page and report their URLs + * This script runs after page load and also monitors for dynamically added iFrames + */ +NSString* getIFrameDetectorScript(void) { + return @"(function() {\n" + " if (window.iframeDetectorInjected) return;\n" + " window.iframeDetectorInjected = true;\n" + " \n" + " function collectIFrameUrls() {\n" + " const iframes = document.getElementsByTagName('iframe');\n" + " const urls = [];\n" + " \n" + " for (let i = 0; i < iframes.length; i++) {\n" + " const iframe = iframes[i];\n" + " const src = iframe.src;\n" + " \n" + " if (src && src.trim() !== '' && (src.startsWith('http://') || src.startsWith('https://') || src.startsWith('//'))) {\n" + " const normalizedUrl = src.startsWith('//') ? 'https:' + src : src;\n" + " urls.push(normalizedUrl);\n" + " }\n" + " }\n" + " \n" + " return urls;\n" + " }\n" + " \n" + " function reportIFrames() {\n" + " try {\n" + " const urls = collectIFrameUrls();\n" + " if (urls.length > 0) {\n" + " const message = {\n" + " type: 'IFRAME_DETECTED',\n" + " iframeUrls: urls\n" + " };\n" + " \n" + " if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n" + " window.ReactNativeWebView.postMessage(JSON.stringify(message));\n" + " }\n" + " }\n" + " } catch (e) {\n" + " console.error('Error reporting iFrames:', e);\n" + " }\n" + " }\n" + " \n" + " // Initial check for iFrames\n" + " if (document.readyState === 'loading') {\n" + " document.addEventListener('DOMContentLoaded', reportIFrames);\n" + " } else {\n" + " // Document already loaded\n" + " setTimeout(reportIFrames, 100);\n" + " }\n" + " \n" + " // Monitor for dynamically added iFrames\n" + " const observer = new MutationObserver(function(mutations) {\n" + " let shouldCheck = false;\n" + " mutations.forEach(function(mutation) {\n" + " if (mutation.type === 'childList') {\n" + " mutation.addedNodes.forEach(function(node) {\n" + " if (node.nodeType === Node.ELEMENT_NODE) {\n" + " if (node.tagName === 'IFRAME' || node.querySelector('iframe')) {\n" + " shouldCheck = true;\n" + " }\n" + " }\n" + " });\n" + " }\n" + " });\n" + " \n" + " if (shouldCheck) {\n" + " setTimeout(reportIFrames, 100);\n" + " }\n" + " });\n" + " \n" + " observer.observe(document.body || document.documentElement, {\n" + " childList: true,\n" + " subtree: true\n" + " });\n" + " \n" + " // Also check periodically as a fallback\n" + " setInterval(reportIFrames, 5000);\n" + "})();"; +} \ No newline at end of file diff --git a/apple/RNCWebViewImpl.m b/apple/RNCWebViewImpl.m index 13913364b..a9f4ec8f7 100644 --- a/apple/RNCWebViewImpl.m +++ b/apple/RNCWebViewImpl.m @@ -9,6 +9,7 @@ #import #import #import "RNCWKProcessPoolManager.h" +#import "IFrameDetector.h" #if !TARGET_OS_OSX #import #else @@ -126,6 +127,7 @@ @interface RNCWebViewImpl ()