import Foundation enum RedditLoginBridgeStyle { static let messageHandlerName = "reddoraLogin" /// Intercepts Log In and blocks Reddit's embedded auth modal, which cannot complete /// credential sign-in reliably in WKWebView ("Server error. Try again later."). static let injectionScript = """ (function() { if (window.__reddoraLoginBridgeInstalled) return; window.__reddoraLoginBridgeInstalled = true; const LOGIN_PATTERN = /log\\s*in/i; const HEADER_SELECTORS = 'header, [role="banner"], #header, faceplate-header, nav'; const AUTH_MODAL_SELECTORS = [ 'auth-flow-modal', '[data-testid="login-modal"]', '#credentials-login-popup', 'faceplate-modal[slot="login"]', 'faceplate-modal[open]' ].join(', '); function nodeLabel(node) { if (!(node instanceof Element)) return ''; return ( (node.textContent || '') + ' ' + (node.getAttribute('aria-label') || '') + ' ' + (node.getAttribute('title') || '') ).trim(); } function isHeaderLoginTrigger(node) { if (!(node instanceof Element)) return false; const clickable = node.matches('button, a, [role="button"], faceplate-tracker, faceplate-button') ? node : node.closest('button, a, [role="button"], faceplate-tracker, faceplate-button'); if (!clickable) return false; if (clickable.id === 'login-button') return true; if (clickable.getAttribute('data-testid') === 'login-button') return true; const label = nodeLabel(clickable); if (!LOGIN_PATTERN.test(label)) return false; return !!clickable.closest(HEADER_SELECTORS); } function isLoginPage() { const host = window.location.hostname.toLowerCase(); return (host === 'www.reddit.com' || host === 'reddit.com' || host === 'new.reddit.com') && /^\\/login\\/?$/i.test(window.location.pathname); } function requestInAppLogin() { if (isLoginPage()) return; if (window.__reddoraLoginPanelRequested) return; window.__reddoraLoginPanelRequested = true; setTimeout(function() { window.__reddoraLoginPanelRequested = false; }, 1000); if ( window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.reddoraLogin ) { window.webkit.messageHandlers.reddoraLogin.postMessage('open'); } } function isAuthModal(element) { if (!(element instanceof Element)) return false; if (element.matches('auth-flow-modal, [data-testid="login-modal"], #credentials-login-popup')) { return true; } if (element.matches('faceplate-modal')) { const label = nodeLabel(element); return LOGIN_PATTERN.test(label) || !!element.querySelector('input[type="password"]'); } return false; } window.__reddoraCloseRedditAuthModal = function() { document.querySelectorAll(AUTH_MODAL_SELECTORS).forEach(function(element) { if (!isAuthModal(element)) return; const closeButton = element.querySelector( '[aria-label="Close"], [aria-label="close"], button[close]' ); if (closeButton) { closeButton.click(); } else { element.remove(); } }); }; function installAuthModalBlocker() { if (isLoginPage()) return; const STYLE_ID = 'reddora-auth-block-style'; if (!document.getElementById(STYLE_ID)) { const style = document.createElement('style'); style.id = STYLE_ID; style.textContent = [ 'auth-flow-modal,', '[data-testid="login-modal"],', '#credentials-login-popup {', ' display: none !important;', ' pointer-events: none !important;', '}' ].join('\\n'); (document.head || document.documentElement).appendChild(style); } const observer = new MutationObserver(function() { if (isLoginPage()) return; let foundAuthModal = false; document.querySelectorAll(AUTH_MODAL_SELECTORS).forEach(function(element) { if (!isAuthModal(element)) return; foundAuthModal = true; element.remove(); }); if (foundAuthModal) { requestInAppLogin(); } }); observer.observe(document.documentElement, { childList: true, subtree: true }); } document.addEventListener('click', function(event) { if (isLoginPage()) return; const path = event.composedPath(); for (let i = 0; i < path.length; i++) { if (!isHeaderLoginTrigger(path[i])) continue; event.preventDefault(); event.stopImmediatePropagation(); window.__reddoraCloseRedditAuthModal(); requestInAppLogin(); return; } }, true); installAuthModalBlocker(); })(); """ static let closeAuthModalScript = "window.__reddoraCloseRedditAuthModal && window.__reddoraCloseRedditAuthModal();" }