rampkit-expo-dev 0.0.82 → 0.0.83
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/RampkitOverlay.d.ts +2 -2
- package/build/RampkitOverlay.js +88 -68
- package/package.json +1 -1
|
@@ -2,8 +2,8 @@ import { RampKitContext, NavigationData } from "./types";
|
|
|
2
2
|
export declare const injectedHardening = "\n(function(){\n try {\n var meta = document.querySelector('meta[name=\"viewport\"]');\n if (!meta) { meta = document.createElement('meta'); meta.name = 'viewport'; document.head.appendChild(meta); }\n meta.setAttribute('content','width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover');\n var style = document.createElement('style');\n style.textContent='html,body{overflow-x:hidden!important;} html,body,*{-webkit-user-select:none!important;user-select:none!important;-webkit-touch-callout:none!important;-ms-user-select:none!important;touch-action: pan-y;} *{-webkit-tap-highlight-color: rgba(0,0,0,0)!important;} ::selection{background: transparent!important;} ::-moz-selection{background: transparent!important;} a,img{-webkit-user-drag:none!important;user-drag:none!important;-webkit-touch-callout:none!important} input,textarea{caret-color:transparent!important;-webkit-user-select:none!important;user-select:none!important}';\n document.head.appendChild(style);\n var prevent=function(e){e.preventDefault&&e.preventDefault();};\n document.addEventListener('gesturestart',prevent,{passive:false});\n document.addEventListener('gesturechange',prevent,{passive:false});\n document.addEventListener('gestureend',prevent,{passive:false});\n document.addEventListener('dblclick',prevent,{passive:false});\n document.addEventListener('wheel',function(e){ if(e.ctrlKey) e.preventDefault(); },{passive:false});\n document.addEventListener('touchmove',function(e){ if(e.scale && e.scale !== 1) e.preventDefault(); },{passive:false});\n document.addEventListener('selectstart',prevent,{passive:false,capture:true});\n document.addEventListener('contextmenu',prevent,{passive:false,capture:true});\n document.addEventListener('copy',prevent,{passive:false,capture:true});\n document.addEventListener('cut',prevent,{passive:false,capture:true});\n document.addEventListener('paste',prevent,{passive:false,capture:true});\n document.addEventListener('dragstart',prevent,{passive:false,capture:true});\n // Belt-and-suspenders: aggressively clear any attempted selection\n var clearSel=function(){\n try{var sel=window.getSelection&&window.getSelection(); if(sel&&sel.removeAllRanges) sel.removeAllRanges();}catch(_){} }\n document.addEventListener('selectionchange',clearSel,{passive:true,capture:true});\n document.onselectstart=function(){ clearSel(); return false; };\n try{ document.documentElement.style.webkitUserSelect='none'; document.documentElement.style.userSelect='none'; }catch(_){ }\n try{ document.body.style.webkitUserSelect='none'; document.body.style.userSelect='none'; }catch(_){ }\n var __selTimer = setInterval(clearSel, 160);\n window.addEventListener('pagehide',function(){ try{ clearInterval(__selTimer); }catch(_){} });\n // Continuously enforce no-select on all elements and new nodes\n var enforceNoSelect = function(el){\n try{\n el.style && (el.style.webkitUserSelect='none', el.style.userSelect='none', el.style.webkitTouchCallout='none');\n el.setAttribute && (el.setAttribute('unselectable','on'), el.setAttribute('contenteditable','false'));\n }catch(_){}\n }\n try{\n var all=document.getElementsByTagName('*');\n for(var i=0;i<all.length;i++){ enforceNoSelect(all[i]); }\n var obs = new MutationObserver(function(muts){\n for(var j=0;j<muts.length;j++){\n var m=muts[j];\n if(m.type==='childList'){\n m.addedNodes && m.addedNodes.forEach && m.addedNodes.forEach(function(n){ if(n && n.nodeType===1){ enforceNoSelect(n); var q=n.getElementsByTagName? n.getElementsByTagName('*'): []; for(var k=0;k<q.length;k++){ enforceNoSelect(q[k]); }}});\n } else if(m.type==='attributes'){\n enforceNoSelect(m.target);\n }\n }\n });\n obs.observe(document.documentElement,{ childList:true, subtree:true, attributes:true, attributeFilter:['contenteditable','style'] });\n }catch(_){ }\n } catch(_) {}\n})(); true;\n";
|
|
3
3
|
export declare const injectedNoSelect = "\n(function(){\n try {\n if (window.__rkNoSelectApplied) return true;\n window.__rkNoSelectApplied = true;\n var style = document.getElementById('rk-no-select-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'rk-no-select-style';\n style.innerHTML = \"\n * {\n user-select: none !important;\n -webkit-user-select: none !important;\n -webkit-touch-callout: none !important;\n }\n ::selection {\n background: transparent !important;\n }\n \";\n document.head.appendChild(style);\n }\n var prevent = function(e){ if(e && e.preventDefault) e.preventDefault(); return false; };\n document.addEventListener('contextmenu', prevent, { passive: false, capture: true });\n document.addEventListener('selectstart', prevent, { passive: false, capture: true });\n } catch (_) {}\n true;\n})();\n";
|
|
4
4
|
export declare const injectedVarsHandler = "\n(function(){\n try {\n if (window.__rkVarsHandlerApplied) return true;\n window.__rkVarsHandlerApplied = true;\n \n // Handler function that updates variables and notifies the page\n window.__rkHandleVarsUpdate = function(vars) {\n if (!vars || typeof vars !== 'object') return;\n // Update the global variables object\n window.__rampkitVariables = vars;\n // Dispatch a custom event that the page's JS can listen to for re-rendering\n try {\n document.dispatchEvent(new CustomEvent('rampkit:vars-updated', { detail: vars }));\n } catch(e) {}\n // Also try calling a global handler if the page defined one\n try {\n if (typeof window.onRampkitVarsUpdate === 'function') {\n window.onRampkitVarsUpdate(vars);\n }\n } catch(e) {}\n };\n \n // Listen for message events from React Native\n document.addEventListener('message', function(event) {\n try {\n var data = event.data;\n if (data && data.type === 'rampkit:variables' && data.vars) {\n window.__rkHandleVarsUpdate(data.vars);\n }\n } catch(e) {}\n }, false);\n \n // Also listen on window for compatibility\n window.addEventListener('message', function(event) {\n try {\n var data = event.data;\n if (data && data.type === 'rampkit:variables' && data.vars) {\n window.__rkHandleVarsUpdate(data.vars);\n }\n } catch(e) {}\n }, false);\n } catch (_) {}\n true;\n})();\n";
|
|
5
|
-
export declare const injectedDynamicTapHandler = "\n(function() {\n if (window.__rampkitClickInterceptorInstalled) return;\n window.__rampkitClickInterceptorInstalled = true;\n\n // ========== DEBUG: Screen 19 specific logging (REMOVE AFTER BUG FIX) ==========\n var isScreen19Dynamic = function() {\n var screenId = window.__rampkitScreenId || '';\n var screenIndex = window.__rampkitScreenIndex;\n return screenId.indexOf('19') !== -1 ||\n screenId.toLowerCase().indexOf('screen 19') !== -1 ||\n screenId.toLowerCase().indexOf('screen19') !== -1 ||\n screenIndex === 19 ||\n screenIndex === 18;\n };\n\n var debugScreen19Dynamic = function(msg, data) {\n if (isScreen19Dynamic()) {\n console.log('[SCREEN19-DEBUG][DynamicTap] ' + msg, JSON.stringify(data || {}));\n }\n };\n // ========== END DEBUG ==========\n\n // Decode HTML entities\n function decodeHtml(str) {\n if (!str) return str;\n return str.replace(/"/g, '\"').replace(/"/g, '\"').replace(/"/g, '\"')\n .replace(/'/g, \"'\").replace(/'/g, \"'\").replace(/'/g, \"'\")\n .replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&');\n }\n\n // Find dynamic tap config on element or ancestors\n function findDynamicTap(el) {\n var current = el;\n var depth = 0;\n var attrNames = ['data-tap-dynamic', 'data-tapdynamic', 'tapDynamic', 'data-dynamic-tap'];\n var searchTrail = []; // DEBUG: Track search path\n\n while (current && current !== document.body && current !== document.documentElement && depth < 20) {\n // DEBUG: Build search trail for Screen 19\n var trailInfo = {\n depth: depth,\n tag: current.tagName,\n id: current.id || '(none)',\n class: (current.className && typeof current.className === 'string') ? current.className.substring(0,50) : '(none)'\n };\n searchTrail.push(trailInfo);\n\n if (current.getAttribute) {\n for (var i = 0; i < attrNames.length; i++) {\n var attr = current.getAttribute(attrNames[i]);\n if (attr && attr.length > 2) {\n var rect = current.getBoundingClientRect ? current.getBoundingClientRect() : {};\n debugScreen19Dynamic('FOUND data-tap-dynamic', {\n attrName: attrNames[i],\n depth: depth,\n element: trailInfo,\n size: rect.width + 'x' + rect.height,\n configPreview: attr.substring(0, 100) + '...',\n trail: searchTrail\n });\n return { element: current, config: attr };\n }\n }\n if (current.dataset && current.dataset.tapDynamic) {\n var rect2 = current.getBoundingClientRect ? current.getBoundingClientRect() : {};\n debugScreen19Dynamic('FOUND dataset.tapDynamic', {\n depth: depth,\n element: trailInfo,\n size: rect2.width + 'x' + rect2.height,\n trail: searchTrail\n });\n return { element: current, config: current.dataset.tapDynamic };\n }\n }\n current = current.parentElement;\n depth++;\n }\n debugScreen19Dynamic('NO data-tap-dynamic found', { trail: searchTrail });\n return null;\n }\n \n // Get variables for condition evaluation - check ALL possible sources\n function getVars() {\n var vars = {};\n if (window.__rampkitVariables) {\n Object.keys(window.__rampkitVariables).forEach(function(k) {\n vars[k] = window.__rampkitVariables[k];\n });\n }\n if (window.__rampkitVars) {\n Object.keys(window.__rampkitVars).forEach(function(k) {\n vars[k] = window.__rampkitVars[k];\n });\n }\n if (window.RK_VARS) {\n Object.keys(window.RK_VARS).forEach(function(k) {\n vars[k] = window.RK_VARS[k];\n });\n }\n return vars;\n }\n \n // Evaluate a single rule\n function evalRule(rule, vars) {\n if (!rule || !rule.key) return false;\n var left = vars[rule.key];\n var right = rule.value;\n var op = rule.op || '=';\n if (left === undefined || left === null) left = '';\n if (right === undefined || right === null) right = '';\n var leftStr = String(left);\n var rightStr = String(right);\n var result = false;\n switch (op) {\n case '=': case '==': result = leftStr === rightStr; break;\n case '!=': case '<>': result = leftStr !== rightStr; break;\n case '>': result = parseFloat(left) > parseFloat(right); break;\n case '<': result = parseFloat(left) < parseFloat(right); break;\n case '>=': result = parseFloat(left) >= parseFloat(right); break;\n case '<=': result = parseFloat(left) <= parseFloat(right); break;\n default: result = false;\n }\n return result;\n }\n \n // Evaluate all rules (AND logic)\n function evalRules(rules, vars) {\n if (!rules || !rules.length) return true;\n for (var i = 0; i < rules.length; i++) {\n if (!evalRule(rules[i], vars)) return false;\n }\n return true;\n }\n \n // Execute an action\n function execAction(action) {\n if (!action || !action.type) return;\n var msg = null;\n var actionType = action.type.toLowerCase();\n \n switch (actionType) {\n case 'navigate':\n msg = { type: 'rampkit:navigate', targetScreenId: action.targetScreenId || '__continue__', animation: action.animation || 'fade' };\n break;\n case 'continue':\n msg = { type: 'rampkit:navigate', targetScreenId: '__continue__', animation: action.animation || 'fade' };\n break;\n case 'goback':\n msg = { type: 'rampkit:goBack', animation: action.animation || 'fade' };\n break;\n case 'close':\n msg = { type: 'rampkit:close' };\n break;\n case 'haptic':\n msg = { type: 'rampkit:haptic', hapticType: action.hapticType || 'impact', impactStyle: action.impactStyle || 'Medium', notificationType: action.notificationType };\n break;\n case 'showpaywall':\n msg = { type: 'rampkit:show-paywall', payload: action.payload || { paywallId: action.paywallId } };\n break;\n case 'requestreview':\n msg = { type: 'rampkit:request-review' };\n break;\n case 'requestnotificationpermission':\n msg = { type: 'rampkit:request-notification-permission' };\n break;\n case 'onboardingfinished':\n msg = { type: 'rampkit:onboarding-finished', payload: action.payload };\n break;\n case 'setvariable':\n case 'setstate':\n case 'updatevariable':\n case 'set':\n case 'assign':\n var varKey = action.key || action.variableName || action.name || action.variable;\n var varValue = action.variableValue !== undefined ? action.variableValue :\n action.value !== undefined ? action.value :\n action.newValue !== undefined ? action.newValue : undefined;\n if (varKey && varValue !== undefined) {\n if (window.__rampkitVariables) window.__rampkitVariables[varKey] = varValue;\n if (window.__rampkitVars) window.__rampkitVars[varKey] = varValue;\n var updateVars = {};\n updateVars[varKey] = varValue;\n msg = { type: 'rampkit:variables', vars: updateVars };\n }\n break;\n }\n if (msg) {\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(JSON.stringify(msg));\n }\n } catch(e) {}\n }\n }\n \n // Evaluate dynamic tap config\n function evalDynamicTap(config) {\n if (!config || !config.values) return false;\n var vars = getVars();\n var conditions = config.values;\n for (var i = 0; i < conditions.length; i++) {\n var cond = conditions[i];\n var condType = cond.conditionType || 'if';\n var rules = cond.rules || [];\n var actions = cond.actions || [];\n if (condType === 'else' || evalRules(rules, vars)) {\n for (var j = 0; j < actions.length; j++) {\n execAction(actions[j]);\n }\n return true;\n }\n }\n return false;\n }\n \n // Click interceptor - capture phase, runs BEFORE onclick handlers\n function interceptClick(event) {\n // ========== DEBUG: Screen 19 click logging ==========\n if (isScreen19Dynamic()) {\n var clickX = event.clientX;\n var clickY = event.clientY;\n var originalTarget = event.target;\n var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};\n console.log('[SCREEN19-DEBUG][Click] Click at (' + clickX + ',' + clickY + ')', JSON.stringify({\n originalTarget: {\n tag: originalTarget.tagName,\n id: originalTarget.id || '(none)',\n class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',\n size: originalRect.width + 'x' + originalRect.height\n }\n }));\n }\n // ========== END DEBUG ==========\n\n var result = findDynamicTap(event.target);\n if (!result) return;\n\n // ========== DEBUG: Screen 19 - log when dynamic tap is found ==========\n if (isScreen19Dynamic()) {\n var rect = result.element.getBoundingClientRect ? result.element.getBoundingClientRect() : {};\n var screenWidth = window.innerWidth;\n var screenHeight = window.innerHeight;\n var isFullScreen = (rect.width >= screenWidth * 0.9 && rect.height >= screenHeight * 0.9);\n console.log('[SCREEN19-DEBUG][Click] DYNAMIC TAP WILL BE HANDLED', JSON.stringify({\n element: {\n tag: result.element.tagName,\n id: result.element.id || '(none)',\n class: (result.element.className && typeof result.element.className === 'string') ? result.element.className.substring(0,100) : '(none)',\n size: rect.width + 'x' + rect.height\n },\n isFullScreen: isFullScreen,\n WARNING: isFullScreen ? 'FULL SCREEN ELEMENT WITH DYNAMIC TAP - THIS IS THE BUG!' : 'normal element'\n }));\n }\n // ========== END DEBUG ==========\n\n try {\n var configStr = decodeHtml(result.config);\n var config = JSON.parse(configStr);\n\n // ========== DEBUG: Screen 19 - log parsed config ==========\n if (isScreen19Dynamic()) {\n console.log('[SCREEN19-DEBUG][Click] Parsed config:', JSON.stringify({\n hasValues: !!(config && config.values),\n valuesCount: config && config.values ? config.values.length : 0,\n firstCondition: config && config.values && config.values[0] ? {\n conditionType: config.values[0].conditionType,\n rulesCount: config.values[0].rules ? config.values[0].rules.length : 0,\n actionsCount: config.values[0].actions ? config.values[0].actions.length : 0\n } : null\n }));\n }\n // ========== END DEBUG ==========\n\n var handled = evalDynamicTap(config);\n if (handled) {\n debugScreen19Dynamic('Click HANDLED by dynamic tap - event stopped', { handled: true });\n event.stopImmediatePropagation();\n event.preventDefault();\n return false;\n }\n } catch (e) {\n console.log('[RampKit] Dynamic tap error:', e);\n if (isScreen19Dynamic()) {\n console.log('[SCREEN19-DEBUG][Click] Dynamic tap parse error:', e.message);\n }\n }\n }\n\n // Install interceptor on window in capture phase\n window.addEventListener('click', interceptClick, true);\n})();\n";
|
|
6
|
-
export declare const injectedButtonAnimations = "\n(function(){\n try {\n if (window.__rkButtonAnimApplied) return true;\n window.__rkButtonAnimApplied = true;\n\n var pressed = null;\n var pressedOriginalTransform = '';\n var pressedOriginalOpacity = '';\n var pressedOriginalTransition = '';\n var releaseTimer = null;\n\n // ========== DEBUG: Screen 19 specific logging (REMOVE AFTER BUG FIX) ==========\n var isScreen19 = function() {\n // Check multiple ways to identify Screen 19\n var screenId = window.__rampkitScreenId || '';\n var screenIndex = window.__rampkitScreenIndex;\n return screenId.indexOf('19') !== -1 ||\n screenId.toLowerCase().indexOf('screen 19') !== -1 ||\n screenId.toLowerCase().indexOf('screen19') !== -1 ||\n screenIndex === 19 ||\n screenIndex === 18; // 0-indexed, so screen 19 would be index 18\n };\n\n var debugScreen19 = function(msg, data) {\n if (isScreen19()) {\n console.log('[SCREEN19-DEBUG][ButtonAnim] ' + msg, JSON.stringify(data || {}));\n }\n };\n // ========== END DEBUG ==========\n\n // Find interactive element - very permissive, looks for any clickable-looking element\n function findInteractive(el) {\n var current = el;\n var debugTrail = []; // DEBUG: Track search path for Screen 19\n\n for (var i = 0; i < 20 && current && current !== document.body && current !== document.documentElement; i++) {\n if (!current || !current.tagName) { current = current.parentElement; continue; }\n var tag = current.tagName.toLowerCase();\n\n // Skip tiny elements (likely icons inside buttons)\n var rect = current.getBoundingClientRect();\n if (rect.width < 20 || rect.height < 20) { current = current.parentElement; continue; }\n\n // DEBUG: Build trail for Screen 19\n var debugInfo = {\n depth: i,\n tag: tag,\n id: current.id || '(none)',\n class: (current.className && typeof current.className === 'string') ? current.className.substring(0, 100) : '(none)',\n size: rect.width + 'x' + rect.height\n };\n debugTrail.push(debugInfo);\n\n // Match standard interactive elements\n if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') {\n debugScreen19('MATCHED: standard tag', { reason: 'tag=' + tag, element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match elements with any data attribute containing action/navigate/tap/click\n var attrs = current.attributes;\n if (attrs) {\n for (var j = 0; j < attrs.length; j++) {\n var attrName = attrs[j].name.toLowerCase();\n if (attrName.indexOf('click') !== -1 || attrName.indexOf('tap') !== -1 ||\n attrName.indexOf('action') !== -1 || attrName.indexOf('navigate') !== -1 ||\n attrName.indexOf('press') !== -1) {\n debugScreen19('MATCHED: data-attr', { reason: 'attr=' + attrName, value: attrs[j].value.substring(0,50), element: debugInfo, trail: debugTrail });\n return current;\n }\n }\n }\n\n // Match elements with onclick\n if (current.onclick || current.hasAttribute('onclick')) {\n debugScreen19('MATCHED: onclick', { element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match elements with role=\"button\" or tabindex\n if (current.getAttribute('role') === 'button') {\n debugScreen19('MATCHED: role=button', { element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match any element with an ID containing button/btn/cta\n var id = current.id || '';\n if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1)) {\n debugScreen19('MATCHED: button-like ID', { reason: 'id=' + id, element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match elements with button-like classes\n var className = current.className;\n if (className && typeof className === 'string') {\n var cls = className.toLowerCase();\n if (cls.indexOf('btn') !== -1 || cls.indexOf('button') !== -1 || cls.indexOf('cta') !== -1 ||\n cls.indexOf('clickable') !== -1 || cls.indexOf('tappable') !== -1 || cls.indexOf('pressable') !== -1) {\n debugScreen19('MATCHED: button-like class', { reason: 'class=' + className, element: debugInfo, trail: debugTrail });\n return current;\n }\n }\n\n // Match elements with cursor pointer\n try {\n var computed = window.getComputedStyle(current);\n if (computed && computed.cursor === 'pointer') {\n debugScreen19('MATCHED: cursor:pointer', { element: debugInfo, trail: debugTrail });\n return current;\n }\n } catch(e) {}\n\n current = current.parentElement;\n }\n debugScreen19('NO MATCH found', { originalTag: el.tagName, trail: debugTrail });\n return null;\n }\n \n function applyPressedStyle(el) {\n if (!el || !el.style) return;\n // Save original styles\n pressedOriginalTransform = el.style.transform || '';\n pressedOriginalOpacity = el.style.opacity || '';\n pressedOriginalTransition = el.style.transition || '';\n // Apply pressed style with inline styles for maximum specificity\n el.style.transition = 'transform 80ms cubic-bezier(0.25, 0.1, 0.25, 1), opacity 80ms cubic-bezier(0.25, 0.1, 0.25, 1)';\n el.style.transform = 'scale(0.97)';\n el.style.opacity = '0.8';\n }\n \n function applyReleasedStyle(el) {\n if (!el || !el.style) return;\n // Apply spring-back animation\n el.style.transition = 'transform 280ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 280ms cubic-bezier(0.34, 1.56, 0.64, 1)';\n el.style.transform = pressedOriginalTransform || 'scale(1)';\n el.style.opacity = pressedOriginalOpacity || '1';\n }\n \n function resetStyle(el) {\n if (!el || !el.style) return;\n el.style.transform = pressedOriginalTransform;\n el.style.opacity = pressedOriginalOpacity;\n el.style.transition = pressedOriginalTransition;\n }\n \n function onTouchStart(e) {\n try {\n // ========== DEBUG: Screen 19 touch logging ==========\n if (isScreen19()) {\n var touchX = e.touches ? e.touches[0].clientX : e.clientX;\n var touchY = e.touches ? e.touches[0].clientY : e.clientY;\n var originalTarget = e.target;\n var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};\n console.log('[SCREEN19-DEBUG][TouchStart] Touch at (' + touchX + ',' + touchY + ')', JSON.stringify({\n originalTarget: {\n tag: originalTarget.tagName,\n id: originalTarget.id || '(none)',\n class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',\n size: originalRect.width + 'x' + originalRect.height\n }\n }));\n }\n // ========== END DEBUG ==========\n\n var target = findInteractive(e.target);\n if (!target) return;\n\n // ========== DEBUG: Screen 19 - log what element was found interactive ==========\n if (isScreen19() && target) {\n var targetRect = target.getBoundingClientRect();\n var screenWidth = window.innerWidth;\n var screenHeight = window.innerHeight;\n var isFullScreen = (targetRect.width >= screenWidth * 0.9 && targetRect.height >= screenHeight * 0.9);\n console.log('[SCREEN19-DEBUG][TouchStart] INTERACTIVE ELEMENT FOUND', JSON.stringify({\n tag: target.tagName,\n id: target.id || '(none)',\n class: (target.className && typeof target.className === 'string') ? target.className.substring(0,100) : '(none)',\n size: targetRect.width + 'x' + targetRect.height,\n isFullScreen: isFullScreen,\n WARNING: isFullScreen ? 'FULL SCREEN ELEMENT DETECTED - THIS IS THE BUG!' : 'normal element'\n }));\n }\n // ========== END DEBUG ==========\n\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n if (pressed && pressed !== target) { resetStyle(pressed); }\n applyPressedStyle(target);\n pressed = target;\n } catch(err) {}\n }\n \n function onTouchEnd(e) {\n try {\n if (!pressed) return;\n var t = pressed;\n applyReleasedStyle(t);\n releaseTimer = setTimeout(function() {\n resetStyle(t);\n releaseTimer = null;\n }, 300);\n pressed = null;\n } catch(err) {}\n }\n \n function onTouchCancel(e) {\n try {\n if (!pressed) return;\n resetStyle(pressed);\n pressed = null;\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n } catch(err) {}\n }\n \n // Use capture phase for immediate response before any other handlers\n document.addEventListener('touchstart', onTouchStart, { passive: true, capture: true });\n document.addEventListener('touchend', onTouchEnd, { passive: true, capture: true });\n document.addEventListener('touchcancel', onTouchCancel, { passive: true, capture: true });\n // Mouse events for testing\n document.addEventListener('mousedown', onTouchStart, { passive: true, capture: true });\n document.addEventListener('mouseup', onTouchEnd, { passive: true, capture: true });\n \n } catch (err) {}\n true;\n})();\n";
|
|
5
|
+
export declare const injectedDynamicTapHandler = "\n(function() {\n if (window.__rampkitClickInterceptorInstalled) return;\n window.__rampkitClickInterceptorInstalled = true;\n\n // ========== DEBUG: phone-21 (buggy screen) specific logging (REMOVE AFTER BUG FIX) ==========\n var isBuggyScreen = function() {\n var screenId = window.__rampkitScreenId || '';\n var screenIndex = window.__rampkitScreenIndex;\n return screenId === 'phone-21' || screenIndex === 18;\n };\n\n var debugBuggyScreen = function(source, msg, data) {\n if (isBuggyScreen()) {\n var logData = { source: source, msg: msg, data: data };\n console.log('[BUGGY-SCREEN][' + source + '] ' + msg, JSON.stringify(data || {}));\n // Send to React Native via postMessage for visibility in RN console\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(JSON.stringify({\n type: 'rampkit:debug-buggy-screen',\n source: source,\n message: msg,\n data: data\n }));\n }\n } catch(e) {}\n }\n };\n // ========== END DEBUG ==========\n\n // Decode HTML entities\n function decodeHtml(str) {\n if (!str) return str;\n return str.replace(/"/g, '\"').replace(/"/g, '\"').replace(/"/g, '\"')\n .replace(/'/g, \"'\").replace(/'/g, \"'\").replace(/'/g, \"'\")\n .replace(/</g, '<').replace(/>/g, '>').replace(/&/g, '&');\n }\n\n // Find dynamic tap config on element or ancestors\n function findDynamicTap(el) {\n var current = el;\n var depth = 0;\n var attrNames = ['data-tap-dynamic', 'data-tapdynamic', 'tapDynamic', 'data-dynamic-tap'];\n var searchTrail = []; // DEBUG: Track search path\n\n while (current && current !== document.body && current !== document.documentElement && depth < 20) {\n // DEBUG: Build search trail for Screen 19\n var trailInfo = {\n depth: depth,\n tag: current.tagName,\n id: current.id || '(none)',\n class: (current.className && typeof current.className === 'string') ? current.className.substring(0,50) : '(none)'\n };\n searchTrail.push(trailInfo);\n\n if (current.getAttribute) {\n for (var i = 0; i < attrNames.length; i++) {\n var attr = current.getAttribute(attrNames[i]);\n if (attr && attr.length > 2) {\n var rect = current.getBoundingClientRect ? current.getBoundingClientRect() : {};\n debugBuggyScreen('DynamicTap', 'FOUND data-tap-dynamic', {\n attrName: attrNames[i],\n depth: depth,\n element: trailInfo,\n size: rect.width + 'x' + rect.height,\n configPreview: attr.substring(0, 100) + '...',\n trail: searchTrail\n });\n return { element: current, config: attr };\n }\n }\n if (current.dataset && current.dataset.tapDynamic) {\n var rect2 = current.getBoundingClientRect ? current.getBoundingClientRect() : {};\n debugBuggyScreen('DynamicTap', 'FOUND dataset.tapDynamic', {\n depth: depth,\n element: trailInfo,\n size: rect2.width + 'x' + rect2.height,\n trail: searchTrail\n });\n return { element: current, config: current.dataset.tapDynamic };\n }\n }\n current = current.parentElement;\n depth++;\n }\n debugBuggyScreen('DynamicTap', 'NO data-tap-dynamic found', { trail: searchTrail });\n return null;\n }\n \n // Get variables for condition evaluation - check ALL possible sources\n function getVars() {\n var vars = {};\n if (window.__rampkitVariables) {\n Object.keys(window.__rampkitVariables).forEach(function(k) {\n vars[k] = window.__rampkitVariables[k];\n });\n }\n if (window.__rampkitVars) {\n Object.keys(window.__rampkitVars).forEach(function(k) {\n vars[k] = window.__rampkitVars[k];\n });\n }\n if (window.RK_VARS) {\n Object.keys(window.RK_VARS).forEach(function(k) {\n vars[k] = window.RK_VARS[k];\n });\n }\n return vars;\n }\n \n // Evaluate a single rule\n function evalRule(rule, vars) {\n if (!rule || !rule.key) return false;\n var left = vars[rule.key];\n var right = rule.value;\n var op = rule.op || '=';\n if (left === undefined || left === null) left = '';\n if (right === undefined || right === null) right = '';\n var leftStr = String(left);\n var rightStr = String(right);\n var result = false;\n switch (op) {\n case '=': case '==': result = leftStr === rightStr; break;\n case '!=': case '<>': result = leftStr !== rightStr; break;\n case '>': result = parseFloat(left) > parseFloat(right); break;\n case '<': result = parseFloat(left) < parseFloat(right); break;\n case '>=': result = parseFloat(left) >= parseFloat(right); break;\n case '<=': result = parseFloat(left) <= parseFloat(right); break;\n default: result = false;\n }\n return result;\n }\n \n // Evaluate all rules (AND logic)\n function evalRules(rules, vars) {\n if (!rules || !rules.length) return true;\n for (var i = 0; i < rules.length; i++) {\n if (!evalRule(rules[i], vars)) return false;\n }\n return true;\n }\n \n // Execute an action\n function execAction(action) {\n if (!action || !action.type) return;\n var msg = null;\n var actionType = action.type.toLowerCase();\n \n switch (actionType) {\n case 'navigate':\n msg = { type: 'rampkit:navigate', targetScreenId: action.targetScreenId || '__continue__', animation: action.animation || 'fade' };\n break;\n case 'continue':\n msg = { type: 'rampkit:navigate', targetScreenId: '__continue__', animation: action.animation || 'fade' };\n break;\n case 'goback':\n msg = { type: 'rampkit:goBack', animation: action.animation || 'fade' };\n break;\n case 'close':\n msg = { type: 'rampkit:close' };\n break;\n case 'haptic':\n msg = { type: 'rampkit:haptic', hapticType: action.hapticType || 'impact', impactStyle: action.impactStyle || 'Medium', notificationType: action.notificationType };\n break;\n case 'showpaywall':\n msg = { type: 'rampkit:show-paywall', payload: action.payload || { paywallId: action.paywallId } };\n break;\n case 'requestreview':\n msg = { type: 'rampkit:request-review' };\n break;\n case 'requestnotificationpermission':\n msg = { type: 'rampkit:request-notification-permission' };\n break;\n case 'onboardingfinished':\n msg = { type: 'rampkit:onboarding-finished', payload: action.payload };\n break;\n case 'setvariable':\n case 'setstate':\n case 'updatevariable':\n case 'set':\n case 'assign':\n var varKey = action.key || action.variableName || action.name || action.variable;\n var varValue = action.variableValue !== undefined ? action.variableValue :\n action.value !== undefined ? action.value :\n action.newValue !== undefined ? action.newValue : undefined;\n if (varKey && varValue !== undefined) {\n if (window.__rampkitVariables) window.__rampkitVariables[varKey] = varValue;\n if (window.__rampkitVars) window.__rampkitVars[varKey] = varValue;\n var updateVars = {};\n updateVars[varKey] = varValue;\n msg = { type: 'rampkit:variables', vars: updateVars };\n }\n break;\n }\n if (msg) {\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(JSON.stringify(msg));\n }\n } catch(e) {}\n }\n }\n \n // Evaluate dynamic tap config\n function evalDynamicTap(config) {\n if (!config || !config.values) return false;\n var vars = getVars();\n var conditions = config.values;\n for (var i = 0; i < conditions.length; i++) {\n var cond = conditions[i];\n var condType = cond.conditionType || 'if';\n var rules = cond.rules || [];\n var actions = cond.actions || [];\n if (condType === 'else' || evalRules(rules, vars)) {\n for (var j = 0; j < actions.length; j++) {\n execAction(actions[j]);\n }\n return true;\n }\n }\n return false;\n }\n \n // Click interceptor - capture phase, runs BEFORE onclick handlers\n function interceptClick(event) {\n // ========== DEBUG: phone-21 click logging ==========\n if (isBuggyScreen()) {\n var clickX = event.clientX;\n var clickY = event.clientY;\n var originalTarget = event.target;\n var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};\n debugBuggyScreen('Click', 'Click at (' + clickX + ',' + clickY + ')', {\n originalTarget: {\n tag: originalTarget.tagName,\n id: originalTarget.id || '(none)',\n class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',\n size: originalRect.width + 'x' + originalRect.height\n }\n });\n }\n // ========== END DEBUG ==========\n\n var result = findDynamicTap(event.target);\n if (!result) return;\n\n // ========== DEBUG: phone-21 - log when dynamic tap is found ==========\n if (isBuggyScreen()) {\n var rect = result.element.getBoundingClientRect ? result.element.getBoundingClientRect() : {};\n var screenWidth = window.innerWidth;\n var screenHeight = window.innerHeight;\n var isFullScreen = (rect.width >= screenWidth * 0.9 && rect.height >= screenHeight * 0.9);\n debugBuggyScreen('Click', 'DYNAMIC TAP WILL BE HANDLED', {\n element: {\n tag: result.element.tagName,\n id: result.element.id || '(none)',\n class: (result.element.className && typeof result.element.className === 'string') ? result.element.className.substring(0,100) : '(none)',\n size: rect.width + 'x' + rect.height\n },\n isFullScreen: isFullScreen,\n WARNING: isFullScreen ? 'FULL SCREEN ELEMENT WITH DYNAMIC TAP - THIS IS THE BUG!' : 'normal element'\n });\n }\n // ========== END DEBUG ==========\n\n try {\n var configStr = decodeHtml(result.config);\n var config = JSON.parse(configStr);\n\n // ========== DEBUG: phone-21 - log parsed config ==========\n if (isBuggyScreen()) {\n debugBuggyScreen('Click', 'Parsed config', {\n hasValues: !!(config && config.values),\n valuesCount: config && config.values ? config.values.length : 0,\n firstCondition: config && config.values && config.values[0] ? {\n conditionType: config.values[0].conditionType,\n rulesCount: config.values[0].rules ? config.values[0].rules.length : 0,\n actionsCount: config.values[0].actions ? config.values[0].actions.length : 0\n } : null\n });\n }\n // ========== END DEBUG ==========\n\n var handled = evalDynamicTap(config);\n if (handled) {\n debugBuggyScreen('Click', 'HANDLED by dynamic tap - event stopped', { handled: true });\n event.stopImmediatePropagation();\n event.preventDefault();\n return false;\n }\n } catch (e) {\n console.log('[RampKit] Dynamic tap error:', e);\n if (isBuggyScreen()) {\n debugBuggyScreen('Click', 'Dynamic tap parse error', { error: e.message });\n }\n }\n }\n\n // Install interceptor on window in capture phase\n window.addEventListener('click', interceptClick, true);\n})();\n";
|
|
6
|
+
export declare const injectedButtonAnimations = "\n(function(){\n try {\n if (window.__rkButtonAnimApplied) return true;\n window.__rkButtonAnimApplied = true;\n\n var pressed = null;\n var pressedOriginalTransform = '';\n var pressedOriginalOpacity = '';\n var pressedOriginalTransition = '';\n var releaseTimer = null;\n\n // ========== DEBUG: phone-21 (buggy screen) specific logging (REMOVE AFTER BUG FIX) ==========\n var isBuggyScreenAnim = function() {\n var screenId = window.__rampkitScreenId || '';\n var screenIndex = window.__rampkitScreenIndex;\n return screenId === 'phone-21' || screenIndex === 18;\n };\n\n var debugBuggyScreenAnim = function(source, msg, data) {\n if (isBuggyScreenAnim()) {\n console.log('[BUGGY-SCREEN][' + source + '] ' + msg, JSON.stringify(data || {}));\n // Send to React Native via postMessage for visibility\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(JSON.stringify({\n type: 'rampkit:debug-buggy-screen',\n source: source,\n message: msg,\n data: data\n }));\n }\n } catch(e) {}\n }\n };\n // ========== END DEBUG ==========\n\n // Find interactive element - very permissive, looks for any clickable-looking element\n function findInteractive(el) {\n var current = el;\n var debugTrail = []; // DEBUG: Track search path for Screen 19\n\n for (var i = 0; i < 20 && current && current !== document.body && current !== document.documentElement; i++) {\n if (!current || !current.tagName) { current = current.parentElement; continue; }\n var tag = current.tagName.toLowerCase();\n\n // Skip tiny elements (likely icons inside buttons)\n var rect = current.getBoundingClientRect();\n if (rect.width < 20 || rect.height < 20) { current = current.parentElement; continue; }\n\n // DEBUG: Build trail for Screen 19\n var debugInfo = {\n depth: i,\n tag: tag,\n id: current.id || '(none)',\n class: (current.className && typeof current.className === 'string') ? current.className.substring(0, 100) : '(none)',\n size: rect.width + 'x' + rect.height\n };\n debugTrail.push(debugInfo);\n\n // Match standard interactive elements\n if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: standard tag', { reason: 'tag=' + tag, element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match elements with any data attribute containing action/navigate/tap/click\n var attrs = current.attributes;\n if (attrs) {\n for (var j = 0; j < attrs.length; j++) {\n var attrName = attrs[j].name.toLowerCase();\n if (attrName.indexOf('click') !== -1 || attrName.indexOf('tap') !== -1 ||\n attrName.indexOf('action') !== -1 || attrName.indexOf('navigate') !== -1 ||\n attrName.indexOf('press') !== -1) {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: data-attr', { reason: 'attr=' + attrName, value: attrs[j].value.substring(0,50), element: debugInfo, trail: debugTrail });\n return current;\n }\n }\n }\n\n // Match elements with onclick\n if (current.onclick || current.hasAttribute('onclick')) {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: onclick', { element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match elements with role=\"button\" or tabindex\n if (current.getAttribute('role') === 'button') {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: role=button', { element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match any element with an ID containing button/btn/cta\n var id = current.id || '';\n if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1)) {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: button-like ID', { reason: 'id=' + id, element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match elements with button-like classes\n var className = current.className;\n if (className && typeof className === 'string') {\n var cls = className.toLowerCase();\n if (cls.indexOf('btn') !== -1 || cls.indexOf('button') !== -1 || cls.indexOf('cta') !== -1 ||\n cls.indexOf('clickable') !== -1 || cls.indexOf('tappable') !== -1 || cls.indexOf('pressable') !== -1) {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: button-like class', { reason: 'class=' + className, element: debugInfo, trail: debugTrail });\n return current;\n }\n }\n\n // Match elements with cursor pointer\n try {\n var computed = window.getComputedStyle(current);\n if (computed && computed.cursor === 'pointer') {\n debugBuggyScreenAnim('ButtonAnim', 'MATCHED: cursor:pointer', { element: debugInfo, trail: debugTrail });\n return current;\n }\n } catch(e) {}\n\n current = current.parentElement;\n }\n debugBuggyScreenAnim('ButtonAnim', 'NO MATCH found', { originalTag: el.tagName, trail: debugTrail });\n return null;\n }\n \n function applyPressedStyle(el) {\n if (!el || !el.style) return;\n // Save original styles\n pressedOriginalTransform = el.style.transform || '';\n pressedOriginalOpacity = el.style.opacity || '';\n pressedOriginalTransition = el.style.transition || '';\n // Apply pressed style with inline styles for maximum specificity\n el.style.transition = 'transform 80ms cubic-bezier(0.25, 0.1, 0.25, 1), opacity 80ms cubic-bezier(0.25, 0.1, 0.25, 1)';\n el.style.transform = 'scale(0.97)';\n el.style.opacity = '0.8';\n }\n \n function applyReleasedStyle(el) {\n if (!el || !el.style) return;\n // Apply spring-back animation\n el.style.transition = 'transform 280ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 280ms cubic-bezier(0.34, 1.56, 0.64, 1)';\n el.style.transform = pressedOriginalTransform || 'scale(1)';\n el.style.opacity = pressedOriginalOpacity || '1';\n }\n \n function resetStyle(el) {\n if (!el || !el.style) return;\n el.style.transform = pressedOriginalTransform;\n el.style.opacity = pressedOriginalOpacity;\n el.style.transition = pressedOriginalTransition;\n }\n \n function onTouchStart(e) {\n try {\n // ========== DEBUG: phone-21 touch logging ==========\n if (isBuggyScreenAnim()) {\n var touchX = e.touches ? e.touches[0].clientX : e.clientX;\n var touchY = e.touches ? e.touches[0].clientY : e.clientY;\n var originalTarget = e.target;\n var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};\n debugBuggyScreenAnim('TouchStart', 'Touch at (' + touchX + ',' + touchY + ')', {\n originalTarget: {\n tag: originalTarget.tagName,\n id: originalTarget.id || '(none)',\n class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',\n size: originalRect.width + 'x' + originalRect.height\n }\n });\n }\n // ========== END DEBUG ==========\n\n var target = findInteractive(e.target);\n if (!target) return;\n\n // ========== DEBUG: phone-21 - log what element was found interactive ==========\n if (isBuggyScreenAnim() && target) {\n var targetRect = target.getBoundingClientRect();\n var screenWidth = window.innerWidth;\n var screenHeight = window.innerHeight;\n var isFullScreen = (targetRect.width >= screenWidth * 0.9 && targetRect.height >= screenHeight * 0.9);\n debugBuggyScreenAnim('TouchStart', 'INTERACTIVE ELEMENT FOUND', {\n tag: target.tagName,\n id: target.id || '(none)',\n class: (target.className && typeof target.className === 'string') ? target.className.substring(0,100) : '(none)',\n size: targetRect.width + 'x' + targetRect.height,\n isFullScreen: isFullScreen,\n WARNING: isFullScreen ? 'FULL SCREEN ELEMENT DETECTED - THIS IS THE BUG!' : 'normal element'\n });\n }\n // ========== END DEBUG ==========\n\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n if (pressed && pressed !== target) { resetStyle(pressed); }\n applyPressedStyle(target);\n pressed = target;\n } catch(err) {}\n }\n \n function onTouchEnd(e) {\n try {\n if (!pressed) return;\n var t = pressed;\n applyReleasedStyle(t);\n releaseTimer = setTimeout(function() {\n resetStyle(t);\n releaseTimer = null;\n }, 300);\n pressed = null;\n } catch(err) {}\n }\n \n function onTouchCancel(e) {\n try {\n if (!pressed) return;\n resetStyle(pressed);\n pressed = null;\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n } catch(err) {}\n }\n \n // Use capture phase for immediate response before any other handlers\n document.addEventListener('touchstart', onTouchStart, { passive: true, capture: true });\n document.addEventListener('touchend', onTouchEnd, { passive: true, capture: true });\n document.addEventListener('touchcancel', onTouchCancel, { passive: true, capture: true });\n // Mouse events for testing\n document.addEventListener('mousedown', onTouchStart, { passive: true, capture: true });\n document.addEventListener('mouseup', onTouchEnd, { passive: true, capture: true });\n \n } catch (err) {}\n true;\n})();\n";
|
|
7
7
|
export type ScreenPayload = {
|
|
8
8
|
id: string;
|
|
9
9
|
html: string;
|
package/build/RampkitOverlay.js
CHANGED
|
@@ -182,20 +182,28 @@ exports.injectedDynamicTapHandler = `
|
|
|
182
182
|
if (window.__rampkitClickInterceptorInstalled) return;
|
|
183
183
|
window.__rampkitClickInterceptorInstalled = true;
|
|
184
184
|
|
|
185
|
-
// ========== DEBUG:
|
|
186
|
-
var
|
|
185
|
+
// ========== DEBUG: phone-21 (buggy screen) specific logging (REMOVE AFTER BUG FIX) ==========
|
|
186
|
+
var isBuggyScreen = function() {
|
|
187
187
|
var screenId = window.__rampkitScreenId || '';
|
|
188
188
|
var screenIndex = window.__rampkitScreenIndex;
|
|
189
|
-
return screenId
|
|
190
|
-
screenId.toLowerCase().indexOf('screen 19') !== -1 ||
|
|
191
|
-
screenId.toLowerCase().indexOf('screen19') !== -1 ||
|
|
192
|
-
screenIndex === 19 ||
|
|
193
|
-
screenIndex === 18;
|
|
189
|
+
return screenId === 'phone-21' || screenIndex === 18;
|
|
194
190
|
};
|
|
195
191
|
|
|
196
|
-
var
|
|
197
|
-
if (
|
|
198
|
-
|
|
192
|
+
var debugBuggyScreen = function(source, msg, data) {
|
|
193
|
+
if (isBuggyScreen()) {
|
|
194
|
+
var logData = { source: source, msg: msg, data: data };
|
|
195
|
+
console.log('[BUGGY-SCREEN][' + source + '] ' + msg, JSON.stringify(data || {}));
|
|
196
|
+
// Send to React Native via postMessage for visibility in RN console
|
|
197
|
+
try {
|
|
198
|
+
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
199
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
200
|
+
type: 'rampkit:debug-buggy-screen',
|
|
201
|
+
source: source,
|
|
202
|
+
message: msg,
|
|
203
|
+
data: data
|
|
204
|
+
}));
|
|
205
|
+
}
|
|
206
|
+
} catch(e) {}
|
|
199
207
|
}
|
|
200
208
|
};
|
|
201
209
|
// ========== END DEBUG ==========
|
|
@@ -230,7 +238,7 @@ exports.injectedDynamicTapHandler = `
|
|
|
230
238
|
var attr = current.getAttribute(attrNames[i]);
|
|
231
239
|
if (attr && attr.length > 2) {
|
|
232
240
|
var rect = current.getBoundingClientRect ? current.getBoundingClientRect() : {};
|
|
233
|
-
|
|
241
|
+
debugBuggyScreen('DynamicTap', 'FOUND data-tap-dynamic', {
|
|
234
242
|
attrName: attrNames[i],
|
|
235
243
|
depth: depth,
|
|
236
244
|
element: trailInfo,
|
|
@@ -243,7 +251,7 @@ exports.injectedDynamicTapHandler = `
|
|
|
243
251
|
}
|
|
244
252
|
if (current.dataset && current.dataset.tapDynamic) {
|
|
245
253
|
var rect2 = current.getBoundingClientRect ? current.getBoundingClientRect() : {};
|
|
246
|
-
|
|
254
|
+
debugBuggyScreen('DynamicTap', 'FOUND dataset.tapDynamic', {
|
|
247
255
|
depth: depth,
|
|
248
256
|
element: trailInfo,
|
|
249
257
|
size: rect2.width + 'x' + rect2.height,
|
|
@@ -255,7 +263,7 @@ exports.injectedDynamicTapHandler = `
|
|
|
255
263
|
current = current.parentElement;
|
|
256
264
|
depth++;
|
|
257
265
|
}
|
|
258
|
-
|
|
266
|
+
debugBuggyScreen('DynamicTap', 'NO data-tap-dynamic found', { trail: searchTrail });
|
|
259
267
|
return null;
|
|
260
268
|
}
|
|
261
269
|
|
|
@@ -395,33 +403,33 @@ exports.injectedDynamicTapHandler = `
|
|
|
395
403
|
|
|
396
404
|
// Click interceptor - capture phase, runs BEFORE onclick handlers
|
|
397
405
|
function interceptClick(event) {
|
|
398
|
-
// ========== DEBUG:
|
|
399
|
-
if (
|
|
406
|
+
// ========== DEBUG: phone-21 click logging ==========
|
|
407
|
+
if (isBuggyScreen()) {
|
|
400
408
|
var clickX = event.clientX;
|
|
401
409
|
var clickY = event.clientY;
|
|
402
410
|
var originalTarget = event.target;
|
|
403
411
|
var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};
|
|
404
|
-
|
|
412
|
+
debugBuggyScreen('Click', 'Click at (' + clickX + ',' + clickY + ')', {
|
|
405
413
|
originalTarget: {
|
|
406
414
|
tag: originalTarget.tagName,
|
|
407
415
|
id: originalTarget.id || '(none)',
|
|
408
416
|
class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',
|
|
409
417
|
size: originalRect.width + 'x' + originalRect.height
|
|
410
418
|
}
|
|
411
|
-
})
|
|
419
|
+
});
|
|
412
420
|
}
|
|
413
421
|
// ========== END DEBUG ==========
|
|
414
422
|
|
|
415
423
|
var result = findDynamicTap(event.target);
|
|
416
424
|
if (!result) return;
|
|
417
425
|
|
|
418
|
-
// ========== DEBUG:
|
|
419
|
-
if (
|
|
426
|
+
// ========== DEBUG: phone-21 - log when dynamic tap is found ==========
|
|
427
|
+
if (isBuggyScreen()) {
|
|
420
428
|
var rect = result.element.getBoundingClientRect ? result.element.getBoundingClientRect() : {};
|
|
421
429
|
var screenWidth = window.innerWidth;
|
|
422
430
|
var screenHeight = window.innerHeight;
|
|
423
431
|
var isFullScreen = (rect.width >= screenWidth * 0.9 && rect.height >= screenHeight * 0.9);
|
|
424
|
-
|
|
432
|
+
debugBuggyScreen('Click', 'DYNAMIC TAP WILL BE HANDLED', {
|
|
425
433
|
element: {
|
|
426
434
|
tag: result.element.tagName,
|
|
427
435
|
id: result.element.id || '(none)',
|
|
@@ -430,7 +438,7 @@ exports.injectedDynamicTapHandler = `
|
|
|
430
438
|
},
|
|
431
439
|
isFullScreen: isFullScreen,
|
|
432
440
|
WARNING: isFullScreen ? 'FULL SCREEN ELEMENT WITH DYNAMIC TAP - THIS IS THE BUG!' : 'normal element'
|
|
433
|
-
})
|
|
441
|
+
});
|
|
434
442
|
}
|
|
435
443
|
// ========== END DEBUG ==========
|
|
436
444
|
|
|
@@ -438,9 +446,9 @@ exports.injectedDynamicTapHandler = `
|
|
|
438
446
|
var configStr = decodeHtml(result.config);
|
|
439
447
|
var config = JSON.parse(configStr);
|
|
440
448
|
|
|
441
|
-
// ========== DEBUG:
|
|
442
|
-
if (
|
|
443
|
-
|
|
449
|
+
// ========== DEBUG: phone-21 - log parsed config ==========
|
|
450
|
+
if (isBuggyScreen()) {
|
|
451
|
+
debugBuggyScreen('Click', 'Parsed config', {
|
|
444
452
|
hasValues: !!(config && config.values),
|
|
445
453
|
valuesCount: config && config.values ? config.values.length : 0,
|
|
446
454
|
firstCondition: config && config.values && config.values[0] ? {
|
|
@@ -448,21 +456,21 @@ exports.injectedDynamicTapHandler = `
|
|
|
448
456
|
rulesCount: config.values[0].rules ? config.values[0].rules.length : 0,
|
|
449
457
|
actionsCount: config.values[0].actions ? config.values[0].actions.length : 0
|
|
450
458
|
} : null
|
|
451
|
-
})
|
|
459
|
+
});
|
|
452
460
|
}
|
|
453
461
|
// ========== END DEBUG ==========
|
|
454
462
|
|
|
455
463
|
var handled = evalDynamicTap(config);
|
|
456
464
|
if (handled) {
|
|
457
|
-
|
|
465
|
+
debugBuggyScreen('Click', 'HANDLED by dynamic tap - event stopped', { handled: true });
|
|
458
466
|
event.stopImmediatePropagation();
|
|
459
467
|
event.preventDefault();
|
|
460
468
|
return false;
|
|
461
469
|
}
|
|
462
470
|
} catch (e) {
|
|
463
471
|
console.log('[RampKit] Dynamic tap error:', e);
|
|
464
|
-
if (
|
|
465
|
-
|
|
472
|
+
if (isBuggyScreen()) {
|
|
473
|
+
debugBuggyScreen('Click', 'Dynamic tap parse error', { error: e.message });
|
|
466
474
|
}
|
|
467
475
|
}
|
|
468
476
|
}
|
|
@@ -486,21 +494,27 @@ exports.injectedButtonAnimations = `
|
|
|
486
494
|
var pressedOriginalTransition = '';
|
|
487
495
|
var releaseTimer = null;
|
|
488
496
|
|
|
489
|
-
// ========== DEBUG:
|
|
490
|
-
var
|
|
491
|
-
// Check multiple ways to identify Screen 19
|
|
497
|
+
// ========== DEBUG: phone-21 (buggy screen) specific logging (REMOVE AFTER BUG FIX) ==========
|
|
498
|
+
var isBuggyScreenAnim = function() {
|
|
492
499
|
var screenId = window.__rampkitScreenId || '';
|
|
493
500
|
var screenIndex = window.__rampkitScreenIndex;
|
|
494
|
-
return screenId
|
|
495
|
-
screenId.toLowerCase().indexOf('screen 19') !== -1 ||
|
|
496
|
-
screenId.toLowerCase().indexOf('screen19') !== -1 ||
|
|
497
|
-
screenIndex === 19 ||
|
|
498
|
-
screenIndex === 18; // 0-indexed, so screen 19 would be index 18
|
|
501
|
+
return screenId === 'phone-21' || screenIndex === 18;
|
|
499
502
|
};
|
|
500
503
|
|
|
501
|
-
var
|
|
502
|
-
if (
|
|
503
|
-
console.log('[
|
|
504
|
+
var debugBuggyScreenAnim = function(source, msg, data) {
|
|
505
|
+
if (isBuggyScreenAnim()) {
|
|
506
|
+
console.log('[BUGGY-SCREEN][' + source + '] ' + msg, JSON.stringify(data || {}));
|
|
507
|
+
// Send to React Native via postMessage for visibility
|
|
508
|
+
try {
|
|
509
|
+
if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {
|
|
510
|
+
window.ReactNativeWebView.postMessage(JSON.stringify({
|
|
511
|
+
type: 'rampkit:debug-buggy-screen',
|
|
512
|
+
source: source,
|
|
513
|
+
message: msg,
|
|
514
|
+
data: data
|
|
515
|
+
}));
|
|
516
|
+
}
|
|
517
|
+
} catch(e) {}
|
|
504
518
|
}
|
|
505
519
|
};
|
|
506
520
|
// ========== END DEBUG ==========
|
|
@@ -530,7 +544,7 @@ exports.injectedButtonAnimations = `
|
|
|
530
544
|
|
|
531
545
|
// Match standard interactive elements
|
|
532
546
|
if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') {
|
|
533
|
-
|
|
547
|
+
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: standard tag', { reason: 'tag=' + tag, element: debugInfo, trail: debugTrail });
|
|
534
548
|
return current;
|
|
535
549
|
}
|
|
536
550
|
|
|
@@ -542,7 +556,7 @@ exports.injectedButtonAnimations = `
|
|
|
542
556
|
if (attrName.indexOf('click') !== -1 || attrName.indexOf('tap') !== -1 ||
|
|
543
557
|
attrName.indexOf('action') !== -1 || attrName.indexOf('navigate') !== -1 ||
|
|
544
558
|
attrName.indexOf('press') !== -1) {
|
|
545
|
-
|
|
559
|
+
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: data-attr', { reason: 'attr=' + attrName, value: attrs[j].value.substring(0,50), element: debugInfo, trail: debugTrail });
|
|
546
560
|
return current;
|
|
547
561
|
}
|
|
548
562
|
}
|
|
@@ -550,20 +564,20 @@ exports.injectedButtonAnimations = `
|
|
|
550
564
|
|
|
551
565
|
// Match elements with onclick
|
|
552
566
|
if (current.onclick || current.hasAttribute('onclick')) {
|
|
553
|
-
|
|
567
|
+
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: onclick', { element: debugInfo, trail: debugTrail });
|
|
554
568
|
return current;
|
|
555
569
|
}
|
|
556
570
|
|
|
557
571
|
// Match elements with role="button" or tabindex
|
|
558
572
|
if (current.getAttribute('role') === 'button') {
|
|
559
|
-
|
|
573
|
+
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: role=button', { element: debugInfo, trail: debugTrail });
|
|
560
574
|
return current;
|
|
561
575
|
}
|
|
562
576
|
|
|
563
577
|
// Match any element with an ID containing button/btn/cta
|
|
564
578
|
var id = current.id || '';
|
|
565
579
|
if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1)) {
|
|
566
|
-
|
|
580
|
+
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: button-like ID', { reason: 'id=' + id, element: debugInfo, trail: debugTrail });
|
|
567
581
|
return current;
|
|
568
582
|
}
|
|
569
583
|
|
|
@@ -573,7 +587,7 @@ exports.injectedButtonAnimations = `
|
|
|
573
587
|
var cls = className.toLowerCase();
|
|
574
588
|
if (cls.indexOf('btn') !== -1 || cls.indexOf('button') !== -1 || cls.indexOf('cta') !== -1 ||
|
|
575
589
|
cls.indexOf('clickable') !== -1 || cls.indexOf('tappable') !== -1 || cls.indexOf('pressable') !== -1) {
|
|
576
|
-
|
|
590
|
+
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: button-like class', { reason: 'class=' + className, element: debugInfo, trail: debugTrail });
|
|
577
591
|
return current;
|
|
578
592
|
}
|
|
579
593
|
}
|
|
@@ -582,14 +596,14 @@ exports.injectedButtonAnimations = `
|
|
|
582
596
|
try {
|
|
583
597
|
var computed = window.getComputedStyle(current);
|
|
584
598
|
if (computed && computed.cursor === 'pointer') {
|
|
585
|
-
|
|
599
|
+
debugBuggyScreenAnim('ButtonAnim', 'MATCHED: cursor:pointer', { element: debugInfo, trail: debugTrail });
|
|
586
600
|
return current;
|
|
587
601
|
}
|
|
588
602
|
} catch(e) {}
|
|
589
603
|
|
|
590
604
|
current = current.parentElement;
|
|
591
605
|
}
|
|
592
|
-
|
|
606
|
+
debugBuggyScreenAnim('ButtonAnim', 'NO MATCH found', { originalTag: el.tagName, trail: debugTrail });
|
|
593
607
|
return null;
|
|
594
608
|
}
|
|
595
609
|
|
|
@@ -622,40 +636,40 @@ exports.injectedButtonAnimations = `
|
|
|
622
636
|
|
|
623
637
|
function onTouchStart(e) {
|
|
624
638
|
try {
|
|
625
|
-
// ========== DEBUG:
|
|
626
|
-
if (
|
|
639
|
+
// ========== DEBUG: phone-21 touch logging ==========
|
|
640
|
+
if (isBuggyScreenAnim()) {
|
|
627
641
|
var touchX = e.touches ? e.touches[0].clientX : e.clientX;
|
|
628
642
|
var touchY = e.touches ? e.touches[0].clientY : e.clientY;
|
|
629
643
|
var originalTarget = e.target;
|
|
630
644
|
var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};
|
|
631
|
-
|
|
645
|
+
debugBuggyScreenAnim('TouchStart', 'Touch at (' + touchX + ',' + touchY + ')', {
|
|
632
646
|
originalTarget: {
|
|
633
647
|
tag: originalTarget.tagName,
|
|
634
648
|
id: originalTarget.id || '(none)',
|
|
635
649
|
class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',
|
|
636
650
|
size: originalRect.width + 'x' + originalRect.height
|
|
637
651
|
}
|
|
638
|
-
})
|
|
652
|
+
});
|
|
639
653
|
}
|
|
640
654
|
// ========== END DEBUG ==========
|
|
641
655
|
|
|
642
656
|
var target = findInteractive(e.target);
|
|
643
657
|
if (!target) return;
|
|
644
658
|
|
|
645
|
-
// ========== DEBUG:
|
|
646
|
-
if (
|
|
659
|
+
// ========== DEBUG: phone-21 - log what element was found interactive ==========
|
|
660
|
+
if (isBuggyScreenAnim() && target) {
|
|
647
661
|
var targetRect = target.getBoundingClientRect();
|
|
648
662
|
var screenWidth = window.innerWidth;
|
|
649
663
|
var screenHeight = window.innerHeight;
|
|
650
664
|
var isFullScreen = (targetRect.width >= screenWidth * 0.9 && targetRect.height >= screenHeight * 0.9);
|
|
651
|
-
|
|
665
|
+
debugBuggyScreenAnim('TouchStart', 'INTERACTIVE ELEMENT FOUND', {
|
|
652
666
|
tag: target.tagName,
|
|
653
667
|
id: target.id || '(none)',
|
|
654
668
|
class: (target.className && typeof target.className === 'string') ? target.className.substring(0,100) : '(none)',
|
|
655
669
|
size: targetRect.width + 'x' + targetRect.height,
|
|
656
670
|
isFullScreen: isFullScreen,
|
|
657
671
|
WARNING: isFullScreen ? 'FULL SCREEN ELEMENT DETECTED - THIS IS THE BUG!' : 'normal element'
|
|
658
|
-
})
|
|
672
|
+
});
|
|
659
673
|
}
|
|
660
674
|
// ========== END DEBUG ==========
|
|
661
675
|
|
|
@@ -2006,19 +2020,25 @@ function Overlay(props) {
|
|
|
2006
2020
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
2007
2021
|
const raw = ev.nativeEvent.data;
|
|
2008
2022
|
console.log("raw", raw);
|
|
2009
|
-
// ========== DEBUG:
|
|
2023
|
+
// ========== DEBUG: phone-21 onMessage logging (REMOVE AFTER BUG FIX) ==========
|
|
2010
2024
|
const screenId = ((_a = props.screens[i]) === null || _a === void 0 ? void 0 : _a.id) || "";
|
|
2011
|
-
const
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
i === 19 || i === 18;
|
|
2015
|
-
if (isScreen19OnMsg) {
|
|
2016
|
-
console.log(`[SCREEN19-DEBUG][onMessage] Received message from screen ${i} (ID: ${screenId})`, JSON.stringify({
|
|
2025
|
+
const isBuggyScreenOnMsg = screenId === 'phone-21' || i === 18;
|
|
2026
|
+
if (isBuggyScreenOnMsg) {
|
|
2027
|
+
console.log(`[BUGGY-SCREEN][onMessage] Received message from screen ${i} (ID: ${screenId})`, JSON.stringify({
|
|
2017
2028
|
rawPreview: raw.substring(0, 200),
|
|
2018
2029
|
isActiveScreen: i === activeScreenIndexRef.current,
|
|
2019
2030
|
activeScreenIndex: activeScreenIndexRef.current
|
|
2020
2031
|
}));
|
|
2021
2032
|
}
|
|
2033
|
+
// Also handle debug messages from WebView
|
|
2034
|
+
try {
|
|
2035
|
+
const debugData = JSON.parse(raw);
|
|
2036
|
+
if ((debugData === null || debugData === void 0 ? void 0 : debugData.type) === 'rampkit:debug-buggy-screen') {
|
|
2037
|
+
console.log(`[BUGGY-SCREEN][${debugData.source}] ${debugData.message}`, JSON.stringify(debugData.data || {}));
|
|
2038
|
+
return; // Don't process further, it's just a debug message
|
|
2039
|
+
}
|
|
2040
|
+
}
|
|
2041
|
+
catch (_) { }
|
|
2022
2042
|
// ========== END DEBUG ==========
|
|
2023
2043
|
// Accept either raw strings or JSON payloads from your editor
|
|
2024
2044
|
try {
|
|
@@ -2182,9 +2202,9 @@ function Overlay(props) {
|
|
|
2182
2202
|
console.log(`[RampKit] Ignoring continue from inactive screen ${i}`);
|
|
2183
2203
|
return;
|
|
2184
2204
|
}
|
|
2185
|
-
// ========== DEBUG:
|
|
2186
|
-
if (
|
|
2187
|
-
console.log(`[
|
|
2205
|
+
// ========== DEBUG: phone-21 continue logging ==========
|
|
2206
|
+
if (isBuggyScreenOnMsg) {
|
|
2207
|
+
console.log(`[BUGGY-SCREEN][onMessage] CONTINUE action triggered from screen ${i}`, JSON.stringify({
|
|
2188
2208
|
animation: (data === null || data === void 0 ? void 0 : data.animation) || "fade",
|
|
2189
2209
|
screenId: screenId
|
|
2190
2210
|
}));
|
|
@@ -2201,9 +2221,9 @@ function Overlay(props) {
|
|
|
2201
2221
|
return;
|
|
2202
2222
|
}
|
|
2203
2223
|
const target = data === null || data === void 0 ? void 0 : data.targetScreenId;
|
|
2204
|
-
// ========== DEBUG:
|
|
2205
|
-
if (
|
|
2206
|
-
console.log(`[
|
|
2224
|
+
// ========== DEBUG: phone-21 navigate logging ==========
|
|
2225
|
+
if (isBuggyScreenOnMsg) {
|
|
2226
|
+
console.log(`[BUGGY-SCREEN][onMessage] NAVIGATE action triggered from screen ${i}`, JSON.stringify({
|
|
2207
2227
|
target: target,
|
|
2208
2228
|
animation: (data === null || data === void 0 ? void 0 : data.animation) || "fade",
|
|
2209
2229
|
screenId: screenId
|
package/package.json
CHANGED