rampkit-expo-dev 0.0.24 → 0.0.26
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 +1 -0
- package/build/RampkitOverlay.js +74 -4
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
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";
|
|
2
2
|
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";
|
|
3
|
+
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";
|
|
3
4
|
export type ScreenPayload = {
|
|
4
5
|
id: string;
|
|
5
6
|
html: string;
|
package/build/RampkitOverlay.js
CHANGED
|
@@ -36,7 +36,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
36
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.injectedNoSelect = exports.injectedHardening = void 0;
|
|
39
|
+
exports.injectedVarsHandler = exports.injectedNoSelect = exports.injectedHardening = void 0;
|
|
40
40
|
exports.showRampkitOverlay = showRampkitOverlay;
|
|
41
41
|
exports.hideRampkitOverlay = hideRampkitOverlay;
|
|
42
42
|
exports.closeRampkitOverlay = closeRampkitOverlay;
|
|
@@ -125,6 +125,54 @@ exports.injectedNoSelect = `
|
|
|
125
125
|
true;
|
|
126
126
|
})();
|
|
127
127
|
`;
|
|
128
|
+
// Robust variable handler that ensures variables are always received and applied
|
|
129
|
+
// This runs after content loads and sets up listeners for incoming variable updates
|
|
130
|
+
exports.injectedVarsHandler = `
|
|
131
|
+
(function(){
|
|
132
|
+
try {
|
|
133
|
+
if (window.__rkVarsHandlerApplied) return true;
|
|
134
|
+
window.__rkVarsHandlerApplied = true;
|
|
135
|
+
|
|
136
|
+
// Handler function that updates variables and notifies the page
|
|
137
|
+
window.__rkHandleVarsUpdate = function(vars) {
|
|
138
|
+
if (!vars || typeof vars !== 'object') return;
|
|
139
|
+
// Update the global variables object
|
|
140
|
+
window.__rampkitVariables = vars;
|
|
141
|
+
// Dispatch a custom event that the page's JS can listen to for re-rendering
|
|
142
|
+
try {
|
|
143
|
+
document.dispatchEvent(new CustomEvent('rampkit:vars-updated', { detail: vars }));
|
|
144
|
+
} catch(e) {}
|
|
145
|
+
// Also try calling a global handler if the page defined one
|
|
146
|
+
try {
|
|
147
|
+
if (typeof window.onRampkitVarsUpdate === 'function') {
|
|
148
|
+
window.onRampkitVarsUpdate(vars);
|
|
149
|
+
}
|
|
150
|
+
} catch(e) {}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// Listen for message events from React Native
|
|
154
|
+
document.addEventListener('message', function(event) {
|
|
155
|
+
try {
|
|
156
|
+
var data = event.data;
|
|
157
|
+
if (data && data.type === 'rampkit:variables' && data.vars) {
|
|
158
|
+
window.__rkHandleVarsUpdate(data.vars);
|
|
159
|
+
}
|
|
160
|
+
} catch(e) {}
|
|
161
|
+
}, false);
|
|
162
|
+
|
|
163
|
+
// Also listen on window for compatibility
|
|
164
|
+
window.addEventListener('message', function(event) {
|
|
165
|
+
try {
|
|
166
|
+
var data = event.data;
|
|
167
|
+
if (data && data.type === 'rampkit:variables' && data.vars) {
|
|
168
|
+
window.__rkHandleVarsUpdate(data.vars);
|
|
169
|
+
}
|
|
170
|
+
} catch(e) {}
|
|
171
|
+
}, false);
|
|
172
|
+
} catch (_) {}
|
|
173
|
+
true;
|
|
174
|
+
})();
|
|
175
|
+
`;
|
|
128
176
|
function performRampkitHaptic(event) {
|
|
129
177
|
if (!event || event.action !== "haptic") {
|
|
130
178
|
// Backwards compatible default
|
|
@@ -225,7 +273,7 @@ function preloadRampkitOverlay(opts) {
|
|
|
225
273
|
opacity: 0,
|
|
226
274
|
top: -1000,
|
|
227
275
|
left: -1000,
|
|
228
|
-
}, children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { originWhitelist: ["*"], source: { html: docs[0] || "<html></html>" }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, hideKeyboardAccessoryView: true }) }));
|
|
276
|
+
}, children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { originWhitelist: ["*"], source: { html: docs[0] || "<html></html>" }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect + exports.injectedVarsHandler, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, hideKeyboardAccessoryView: true }) }));
|
|
229
277
|
preloadSibling = new react_native_root_siblings_1.default((0, jsx_runtime_1.jsx)(HiddenPreloader, {}));
|
|
230
278
|
}
|
|
231
279
|
catch (e) {
|
|
@@ -366,6 +414,11 @@ function Overlay(props) {
|
|
|
366
414
|
else if (typeof pager.setPageWithoutAnimation === "function") {
|
|
367
415
|
pager.setPageWithoutAnimation(nextIndex);
|
|
368
416
|
}
|
|
417
|
+
// Explicitly send vars to the new page after setting it
|
|
418
|
+
// This ensures the webview receives the latest state
|
|
419
|
+
requestAnimationFrame(() => {
|
|
420
|
+
sendVarsToWebView(nextIndex);
|
|
421
|
+
});
|
|
369
422
|
return;
|
|
370
423
|
}
|
|
371
424
|
setIsTransitioning(true);
|
|
@@ -380,6 +433,10 @@ function Overlay(props) {
|
|
|
380
433
|
// @ts-ignore: method exists on PagerView instance
|
|
381
434
|
(_c = (_b = (_a = pagerRef.current) === null || _a === void 0 ? void 0 : _a.setPageWithoutAnimation) === null || _b === void 0 ? void 0 : _b.call(_a, nextIndex)) !== null && _c !== void 0 ? _c : (_d = pagerRef.current) === null || _d === void 0 ? void 0 : _d.setPage(nextIndex);
|
|
382
435
|
requestAnimationFrame(() => {
|
|
436
|
+
// Explicitly send vars to the new page after the page switch completes
|
|
437
|
+
// This ensures the webview receives the latest state even if onPageSelected
|
|
438
|
+
// timing was off during the transition
|
|
439
|
+
sendVarsToWebView(nextIndex);
|
|
383
440
|
react_native_1.Animated.timing(fadeOpacity, {
|
|
384
441
|
toValue: 0,
|
|
385
442
|
duration: 160,
|
|
@@ -476,7 +533,20 @@ function Overlay(props) {
|
|
|
476
533
|
// ensure current page is synced with latest vars when selected
|
|
477
534
|
if (__DEV__)
|
|
478
535
|
console.log("[Rampkit] onPageSelected", pos);
|
|
479
|
-
|
|
536
|
+
// Send vars multiple times with increasing delays to ensure the webview
|
|
537
|
+
// receives them. The first send might fail if the webview isn't fully ready,
|
|
538
|
+
// so we retry a few times.
|
|
539
|
+
requestAnimationFrame(() => {
|
|
540
|
+
sendVarsToWebView(pos);
|
|
541
|
+
});
|
|
542
|
+
// Retry after a short delay in case the first send didn't work
|
|
543
|
+
setTimeout(() => {
|
|
544
|
+
sendVarsToWebView(pos);
|
|
545
|
+
}, 50);
|
|
546
|
+
// Final retry to catch any edge cases
|
|
547
|
+
setTimeout(() => {
|
|
548
|
+
sendVarsToWebView(pos);
|
|
549
|
+
}, 150);
|
|
480
550
|
// Track screen change event
|
|
481
551
|
if (props.onScreenChange && props.screens[pos]) {
|
|
482
552
|
props.onScreenChange(pos, props.screens[pos].id);
|
|
@@ -557,7 +627,7 @@ function Overlay(props) {
|
|
|
557
627
|
styles.root,
|
|
558
628
|
!visible && styles.invisible,
|
|
559
629
|
visible && { opacity: overlayOpacity },
|
|
560
|
-
], pointerEvents: visible && !isClosing ? "auto" : "none", children: [(0, jsx_runtime_1.jsx)(react_native_pager_view_1.default, { ref: pagerRef, style: react_native_1.StyleSheet.absoluteFill, scrollEnabled: false, initialPage: 0, onPageSelected: onPageSelected, offscreenPageLimit: props.screens.length, overScrollMode: "never", children: docs.map((doc, i) => ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: styles.page, renderToHardwareTextureAndroid: true, children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { ref: (r) => (webviewsRef.current[i] = r), style: styles.webview, originWhitelist: ["*"], source: { html: doc }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, overScrollMode: "never", scalesPageToFit: false, showsHorizontalScrollIndicator: false, dataDetectorTypes: "none", allowsLinkPreview: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, javaScriptEnabled: true, domStorageEnabled: true, hideKeyboardAccessoryView: true, onLoadEnd: () => {
|
|
630
|
+
], pointerEvents: visible && !isClosing ? "auto" : "none", children: [(0, jsx_runtime_1.jsx)(react_native_pager_view_1.default, { ref: pagerRef, style: react_native_1.StyleSheet.absoluteFill, scrollEnabled: false, initialPage: 0, onPageSelected: onPageSelected, offscreenPageLimit: props.screens.length, overScrollMode: "never", children: docs.map((doc, i) => ((0, jsx_runtime_1.jsx)(react_native_1.View, { style: styles.page, renderToHardwareTextureAndroid: true, children: (0, jsx_runtime_1.jsx)(react_native_webview_1.WebView, { ref: (r) => (webviewsRef.current[i] = r), style: styles.webview, originWhitelist: ["*"], source: { html: doc }, injectedJavaScriptBeforeContentLoaded: exports.injectedHardening, injectedJavaScript: exports.injectedNoSelect + exports.injectedVarsHandler, automaticallyAdjustContentInsets: false, contentInsetAdjustmentBehavior: "never", bounces: false, scrollEnabled: false, overScrollMode: "never", scalesPageToFit: false, showsHorizontalScrollIndicator: false, dataDetectorTypes: "none", allowsLinkPreview: false, allowsInlineMediaPlayback: true, mediaPlaybackRequiresUserAction: false, cacheEnabled: true, javaScriptEnabled: true, domStorageEnabled: true, hideKeyboardAccessoryView: true, onLoadEnd: () => {
|
|
561
631
|
setLoadedCount((c) => c + 1);
|
|
562
632
|
if (i === 0) {
|
|
563
633
|
setFirstPageLoaded(true);
|
package/package.json
CHANGED