Skip to content

Instantly share code, notes, and snippets.

@shirakaba
Last active September 29, 2023 23:11
Show Gist options
  • Save shirakaba/688df5300a6f6bca1edbc6d2a5d2131f to your computer and use it in GitHub Desktop.
Save shirakaba/688df5300a6f6bca1edbc6d2a5d2131f to your computer and use it in GitHub Desktop.
react-native-webview jsi patch
diff --git a/node_modules/react-native-jsi-bridge-2/ios/JsiBridgeEmitter.h b/node_modules/react-native-jsi-bridge-2/ios/JsiBridgeEmitter.h
index 62da923..cae7aee 100644
--- a/node_modules/react-native-jsi-bridge-2/ios/JsiBridgeEmitter.h
+++ b/node_modules/react-native-jsi-bridge-2/ios/JsiBridgeEmitter.h
@@ -9,16 +9,16 @@
#import <Foundation/Foundation.h>
#import "_JsiBridge.h"
-typedef void (^JsiBridgeCallback)(id data);
+typedef void (^CustomJsiBridgeCallback)(id data);
-@interface JsiBridgeEmitter : NSObject
+@interface CustomJsiBridgeEmitter : NSObject
-+ (JsiBridgeEmitter*)shared;
++ (CustomJsiBridgeEmitter*)shared;
-- (void)registerJsiBridge:(JsiBridge *)bridge;
+- (void)registerJsiBridge:(CustomJsiBridge *)bridge;
- (void)on:(NSString *)name
- with:(JsiBridgeCallback)callback;
+ with:(CustomJsiBridgeCallback)callback;
- (void)off:(NSString *)name;
diff --git a/node_modules/react-native-jsi-bridge-2/ios/JsiBridgeEmitter.mm b/node_modules/react-native-jsi-bridge-2/ios/JsiBridgeEmitter.mm
index 03dab94..10460a7 100644
--- a/node_modules/react-native-jsi-bridge-2/ios/JsiBridgeEmitter.mm
+++ b/node_modules/react-native-jsi-bridge-2/ios/JsiBridgeEmitter.mm
@@ -8,13 +8,13 @@
#import "JsiBridgeEmitter.h"
-@implementation JsiBridgeEmitter
+@implementation CustomJsiBridgeEmitter
-NSMutableDictionary<NSString*, JsiBridgeCallback> *_nativeListeners;
-__weak JsiBridge *jsiBridge;
+NSMutableDictionary<NSString*, CustomJsiBridgeCallback> *_nativeListeners;
+__weak CustomJsiBridge *jsiBridge;
-+ (JsiBridgeEmitter*)shared {
- static JsiBridgeEmitter *_shared = nil;
++ (CustomJsiBridgeEmitter*)shared {
+ static CustomJsiBridgeEmitter *_shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_shared = [[self alloc] init];
@@ -29,7 +29,7 @@ - (id)init {
return self;
}
-- (void)on:(NSString *)name with:(JsiBridgeCallback)callback {
+- (void)on:(NSString *)name with:(CustomJsiBridgeCallback)callback {
[_nativeListeners setObject:callback forKey:name];
}
@@ -45,7 +45,7 @@ - (void)emit:(NSString *)name with:(id)data {
- (void)emitNative:(NSString *)name with:(id)data {
dispatch_async(dispatch_get_main_queue(), ^{
- JsiBridgeCallback listener = [_nativeListeners objectForKey:name];
+ CustomJsiBridgeCallback listener = [_nativeListeners objectForKey:name];
if (listener) {
@try {
listener(data);
@@ -61,7 +61,7 @@ - (void)emitNative:(NSString *)name with:(id)data {
});
}
-- (void)registerJsiBridge:(JsiBridge *)bridge {
+- (void)registerJsiBridge:(CustomJsiBridge *)bridge {
jsiBridge = bridge;
}
diff --git a/node_modules/react-native-jsi-bridge-2/ios/JsiUtils.h b/node_modules/react-native-jsi-bridge-2/ios/JsiUtils.h
index 551e8b7..1de7bc3 100644
--- a/node_modules/react-native-jsi-bridge-2/ios/JsiUtils.h
+++ b/node_modules/react-native-jsi-bridge-2/ios/JsiUtils.h
@@ -49,6 +49,8 @@ typedef void(^PureBlockType)(void);
#pragma mark - Objc to JSI
+namespace CustomJsiBridgeTurboModuleConvertUtils {
+
static jsi::Value convertNSNumberToJSIBoolean(jsi::Runtime &runtime, NSNumber *value)
{
return jsi::Value((bool)[value boolValue]);
@@ -118,8 +120,7 @@ static std::vector<jsi::Value> convertNSArrayToStdVector(jsi::Runtime &runtime,
static id convertJSIValueToObjCObject(
jsi::Runtime &runtime,
const jsi::Value &value,
- std::shared_ptr<CallInvoker> jsInvoker,
- RCTRetainJSCallback retainJSCallback);
+ std::shared_ptr<CallInvoker> jsInvoker);
static NSString *convertJSIStringToNSString(jsi::Runtime &runtime, const jsi::String &value)
{
return [NSString stringWithUTF8String:value.utf8(runtime).c_str()];
@@ -128,15 +129,14 @@ static NSString *convertJSIStringToNSString(jsi::Runtime &runtime, const jsi::St
static NSArray *convertJSIArrayToNSArray(
jsi::Runtime &runtime,
const jsi::Array &value,
- std::shared_ptr<CallInvoker> jsInvoker,
- RCTRetainJSCallback retainJSCallback)
+ std::shared_ptr<CallInvoker> jsInvoker)
{
size_t size = value.size(runtime);
NSMutableArray *result = [NSMutableArray new];
for (size_t i = 0; i < size; i++) {
- // Insert kCFNull when it's `undefined` value to preserve the indices.
+ // Insert kCFNull when it's `undefined` value to preserve the indices.
[result
- addObject:convertJSIValueToObjCObject(runtime, value.getValueAtIndex(runtime, i), jsInvoker, retainJSCallback)
+ addObject:convertJSIValueToObjCObject(runtime, value.getValueAtIndex(runtime, i), jsInvoker)
?: (id)kCFNull];
}
return [result copy];
@@ -145,8 +145,7 @@ static NSArray *convertJSIArrayToNSArray(
static NSDictionary *convertJSIObjectToNSDictionary(
jsi::Runtime &runtime,
const jsi::Object &value,
- std::shared_ptr<CallInvoker> jsInvoker,
- RCTRetainJSCallback retainJSCallback)
+ std::shared_ptr<CallInvoker> jsInvoker)
{
jsi::Array propertyNames = value.getPropertyNames(runtime);
size_t size = propertyNames.size(runtime);
@@ -154,7 +153,7 @@ static NSDictionary *convertJSIObjectToNSDictionary(
for (size_t i = 0; i < size; i++) {
jsi::String name = propertyNames.getValueAtIndex(runtime, i).getString(runtime);
NSString *k = convertJSIStringToNSString(runtime, name);
- id v = convertJSIValueToObjCObject(runtime, value.getProperty(runtime, name), jsInvoker, retainJSCallback);
+ id v = convertJSIValueToObjCObject(runtime, value.getProperty(runtime, name), jsInvoker);
if (v) {
result[k] = v;
}
@@ -165,13 +164,11 @@ static NSDictionary *convertJSIObjectToNSDictionary(
static RCTResponseSenderBlock convertJSIFunctionToCallback(
jsi::Runtime &runtime,
const jsi::Function &value,
- std::shared_ptr<CallInvoker> jsInvoker,
- RCTRetainJSCallback retainJSCallback);
+ std::shared_ptr<CallInvoker> jsInvoker);
static id convertJSIValueToObjCObject(
jsi::Runtime &runtime,
const jsi::Value &value,
- std::shared_ptr<CallInvoker> jsInvoker,
- RCTRetainJSCallback retainJSCallback)
+ std::shared_ptr<CallInvoker> jsInvoker)
{
if (value.isUndefined() || value.isNull()) {
return nil;
@@ -188,12 +185,12 @@ static id convertJSIValueToObjCObject(
if (value.isObject()) {
jsi::Object o = value.getObject(runtime);
if (o.isArray(runtime)) {
- return convertJSIArrayToNSArray(runtime, o.getArray(runtime), jsInvoker, retainJSCallback);
+ return convertJSIArrayToNSArray(runtime, o.getArray(runtime), jsInvoker);
}
if (o.isFunction(runtime)) {
- return convertJSIFunctionToCallback(runtime, std::move(o.getFunction(runtime)), jsInvoker, retainJSCallback);
+ return convertJSIFunctionToCallback(runtime, std::move(o.getFunction(runtime)), jsInvoker);
}
- return convertJSIObjectToNSDictionary(runtime, o, jsInvoker, retainJSCallback);
+ return convertJSIObjectToNSDictionary(runtime, o, jsInvoker);
}
throw std::runtime_error("Unsupported jsi::jsi::Value kind");
@@ -202,12 +199,9 @@ static id convertJSIValueToObjCObject(
static RCTResponseSenderBlock convertJSIFunctionToCallback(
jsi::Runtime &runtime,
const jsi::Function &value,
- std::shared_ptr<CallInvoker> jsInvoker,
- RCTRetainJSCallback retainJSCallback)
+ std::shared_ptr<CallInvoker> jsInvoker)
{
- auto weakWrapper = retainJSCallback != nil
- ? retainJSCallback(value.getFunction(runtime), runtime, jsInvoker)
- : CallbackWrapper::createWeak(value.getFunction(runtime), runtime, jsInvoker);
+ auto weakWrapper = CallbackWrapper::createWeak(value.getFunction(runtime), runtime, jsInvoker);
JsiBridgeBlockGuard *blockGuard = [[JsiBridgeBlockGuard alloc] initWithCleanup:^() {
auto strongWrapper = weakWrapper.lock();
if (strongWrapper) {
@@ -236,7 +230,7 @@ static RCTResponseSenderBlock convertJSIFunctionToCallback(
strongWrapper2->callback().call(strongWrapper2->runtime(), (const jsi::Value *)args.data(), args.size());
strongWrapper2->destroy();
- // Delete the CallbackWrapper when the block gets dealloced without being invoked.
+ // Delete the CallbackWrapper when the block gets dealloced without being invoked.
(void)blockGuard;
});
@@ -245,3 +239,5 @@ static RCTResponseSenderBlock convertJSIFunctionToCallback(
return [callback copy];
}
+
+} // namespace RNJSIBridgeTurboModuleConvertUtils
diff --git a/node_modules/react-native-jsi-bridge-2/ios/_JsiBridge.h b/node_modules/react-native-jsi-bridge-2/ios/_JsiBridge.h
index 2242145..225b413 100644
--- a/node_modules/react-native-jsi-bridge-2/ios/_JsiBridge.h
+++ b/node_modules/react-native-jsi-bridge-2/ios/_JsiBridge.h
@@ -1,7 +1,7 @@
#import <React/RCTBridgeModule.h>
#import <React/RCTBridge.h>
-@interface JsiBridge : NSObject <RCTBridgeModule>
+@interface CustomJsiBridge : NSObject <RCTBridgeModule>
- (void)emitJs:(NSString *)name with:(id)data;
diff --git a/node_modules/react-native-jsi-bridge-2/ios/_JsiBridge.mm b/node_modules/react-native-jsi-bridge-2/ios/_JsiBridge.mm
index 215984e..3815fb0 100644
--- a/node_modules/react-native-jsi-bridge-2/ios/_JsiBridge.mm
+++ b/node_modules/react-native-jsi-bridge-2/ios/_JsiBridge.mm
@@ -2,7 +2,7 @@
#import <React/RCTBridge+Private.h>
#import <ReactCommon/RCTTurboModule.h>
#import <jsi/jsi.h>
-#import "JsiBridgeEmitter.mm"
+#import "JsiBridgeEmitter.h"
#import "JsiUtils.h"
#include "iostream"
@@ -10,7 +10,7 @@
using namespace facebook;
-@implementation JsiBridge
+@implementation CustomJsiBridge
RCT_EXPORT_MODULE()
@@ -21,7 +21,7 @@ @implementation JsiBridge
jsi::Runtime *jsBridge_runtime;
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(install) {
- NSLog(@"Installing JsiBridge polyfill Bindings...");
+ NSLog(@"Installing CustomJsiBridge polyfill Bindings...");
jsBridge_bridge = [RCTBridge currentBridge];
jsBridge_cxxBridge = (RCTCxxBridge*)jsBridge_bridge;
if (jsBridge_cxxBridge == nil) return @false;
@@ -29,7 +29,7 @@ @implementation JsiBridge
if (jsBridge_runtime == nil) return @false;
auto& runtime = *jsBridge_runtime;
- [JsiBridgeEmitter.shared registerJsiBridge:self];
+ [CustomJsiBridgeEmitter.shared registerJsiBridge:self];
auto registerCallback = jsi::Function::createFromHostFunction(runtime,
jsi::PropNameID::forUtf8(runtime, "registerCallback"),
@@ -73,11 +73,11 @@ @implementation JsiBridge
size_t count) -> jsi::Value {
auto name = args[0].asString(runtime).utf8(runtime);
- id data = convertJSIValueToObjCObject(runtime, args[1], jsBridge_bridge.jsCallInvoker, nil);
+ id data = CustomJsiBridgeTurboModuleConvertUtils::convertJSIValueToObjCObject(runtime, args[1], jsBridge_bridge.jsCallInvoker);
auto nameString = [NSString stringWithUTF8String:name.c_str()];
- [JsiBridgeEmitter.shared emitNative:nameString with:data];
+ [CustomJsiBridgeEmitter.shared emitNative:nameString with:data];
return jsi::Value::undefined();
});
@@ -86,7 +86,7 @@ @implementation JsiBridge
_jsiBridge.setProperty(runtime, "registerCallback", std::move(registerCallback));
_jsiBridge.setProperty(runtime, "removeCallback", std::move(removeCallback));
_jsiBridge.setProperty(runtime, "emit", std::move(emit));
- runtime.global().setProperty(runtime, "_JsiBridge", std::move(_jsiBridge));
+ runtime.global().setProperty(runtime, "_CustomJsiBridge", std::move(_jsiBridge));
return @true;
}
@@ -96,7 +96,7 @@ - (void)emitJs:(NSString *)name with:(id)data {
if (jsListeners_.find(stdName) != jsListeners_.end()) {
auto& runtime = *jsBridge_runtime;
jsBridge_bridge.jsCallInvoker->invokeAsync([&runtime, n = stdName, d = data] () {
- auto dd = convertObjCObjectToJSIValue(runtime, d);
+ auto dd = CustomJsiBridgeTurboModuleConvertUtils::convertObjCObjectToJSIValue(runtime, d);
jsListeners_[n]->call(runtime, std::move(dd));
});
}
diff --git a/node_modules/react-native-jsi-bridge-2/react-native-jsi-bridge-2.podspec b/node_modules/react-native-jsi-bridge-2/react-native-jsi-bridge-2.podspec
index 7e86dd1..ef0bb1b 100644
--- a/node_modules/react-native-jsi-bridge-2/react-native-jsi-bridge-2.podspec
+++ b/node_modules/react-native-jsi-bridge-2/react-native-jsi-bridge-2.podspec
@@ -18,4 +18,5 @@ Pod::Spec.new do |s|
s.dependency "React-Core"
s.dependency "React-callinvoker"
s.dependency 'ReactCommon/turbomodule/core'
+ s.dependency 'React-NativeModulesApple'
end
diff --git a/node_modules/react-native-jsi-bridge-2/src/index.tsx b/node_modules/react-native-jsi-bridge-2/src/index.tsx
index eebec83..bdfd95a 100644
--- a/node_modules/react-native-jsi-bridge-2/src/index.tsx
+++ b/node_modules/react-native-jsi-bridge-2/src/index.tsx
@@ -6,8 +6,8 @@ const LINKING_ERROR =
'- You rebuilt the app after installing the package\n' +
'- You are not using Expo managed workflow\n';
-const _JsiBridge = NativeModules.JsiBridge
- ? NativeModules.JsiBridge
+const _CustomJsiBridge = NativeModules.CustomJsiBridge
+ ? NativeModules.CustomJsiBridge
: new Proxy(
{},
{
@@ -17,21 +17,21 @@ const _JsiBridge = NativeModules.JsiBridge
}
);
-_JsiBridge.install();
+_CustomJsiBridge.install();
-export class JsiBridge {
+export class CustomJsiBridge {
static on(name: string, callback: (data: any) => void) {
//@ts-ignore
- global._JsiBridge.registerCallback(name, callback);
+ global._CustomJsiBridge.registerCallback(name, callback);
}
static off(name: string) {
//@ts-ignore
- global._JsiBridge.removeCallback(name);
+ global._CustomJsiBridge.removeCallback(name);
}
static emit(name: string, data?: any) {
//@ts-ignore
- global._JsiBridge.emit(name, data);
+ global._CustomJsiBridge.emit(name, data);
}
}
diff --git a/node_modules/react-native-webview/.DS_Store b/node_modules/react-native-webview/.DS_Store
new file mode 100644
index 0000000..ab2148c
Binary files /dev/null and b/node_modules/react-native-webview/.DS_Store differ
diff --git a/node_modules/react-native-webview/apple/RNCWebViewImpl.m b/node_modules/react-native-webview/apple/RNCWebViewImpl.m
index ffcf4b2..bfaa317 100644
--- a/node_modules/react-native-webview/apple/RNCWebViewImpl.m
+++ b/node_modules/react-native-webview/apple/RNCWebViewImpl.m
@@ -14,6 +14,7 @@
#else
#import <React/RCTUIKit.h>
#endif // !TARGET_OS_OSX
+#import <react-native-jsi-bridge-2/JsiBridgeEmitter.h>
#import "objc/runtime.h"
@@ -697,11 +698,14 @@ - (void)userContentController:(WKUserContentController *)userContentController
_onLoadingFinish(event);
}
} else if ([message.name isEqualToString:MessageHandlerName]) {
- if (_onMessage) {
- NSMutableDictionary<NSString *, id> *event = [self baseEvent];
- [event addEntriesFromDictionary: @{@"data": message.body}];
- _onMessage(event);
- }
+ [[CustomJsiBridgeEmitter shared] emit:@"webViewMessage" with:message.body];
+ // XXX Turn off classic messaging (it seems _onMessage is always populated,
+ // probably with a no-op callback, even if we don't pass a handler).
+ // if (_onMessage) {
+ // NSMutableDictionary<NSString *, id> *event = [self baseEvent];
+ // [event addEntriesFromDictionary: @{@"data": message.body}];
+ // _onMessage(event);
+ // }
}
}
@@ -1726,9 +1730,9 @@ - (void)resetupScripts:(WKWebViewConfiguration *)wkWebViewConfig {
}
if(_messagingEnabled){
- if (self.postMessageScript){
- [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self]
+ [wkWebViewConfig.userContentController addScriptMessageHandler:[[RNCWeakScriptMessageDelegate alloc] initWithDelegate:self]
name:MessageHandlerName];
+ if (self.postMessageScript){
[wkWebViewConfig.userContentController addUserScript:self.postMessageScript];
}
if (self.atEndScript) {
diff --git a/node_modules/react-native-webview/lib/WebView.ios.js b/node_modules/react-native-webview/lib/WebView.ios.js
index d4204f4..332a1ff 100644
--- a/node_modules/react-native-webview/lib/WebView.ios.js
+++ b/node_modules/react-native-webview/lib/WebView.ios.js
@@ -83,7 +83,8 @@ var useWarnIfChanges = function (value, name) {
};
var WebViewComponent = forwardRef(function (_a, ref) {
var _b, _c;
- var _d = _a.fraudulentWebsiteWarningEnabled, fraudulentWebsiteWarningEnabled = _d === void 0 ? true : _d, _e = _a.javaScriptEnabled, javaScriptEnabled = _e === void 0 ? true : _e, _f = _a.cacheEnabled, cacheEnabled = _f === void 0 ? true : _f, _g = _a.originWhitelist, originWhitelist = _g === void 0 ? defaultOriginWhitelist : _g, _h = _a.useSharedProcessPool, useSharedProcessPool = _h === void 0 ? true : _h, _j = _a.textInteractionEnabled, textInteractionEnabled = _j === void 0 ? true : _j, injectedJavaScript = _a.injectedJavaScript, injectedJavaScriptBeforeContentLoaded = _a.injectedJavaScriptBeforeContentLoaded, _k = _a.injectedJavaScriptForMainFrameOnly, injectedJavaScriptForMainFrameOnly = _k === void 0 ? true : _k, _l = _a.injectedJavaScriptBeforeContentLoadedForMainFrameOnly, injectedJavaScriptBeforeContentLoadedForMainFrameOnly = _l === void 0 ? true : _l, startInLoadingState = _a.startInLoadingState, onNavigationStateChange = _a.onNavigationStateChange, onLoadStart = _a.onLoadStart, onError = _a.onError, onLoad = _a.onLoad, onLoadEnd = _a.onLoadEnd, onLoadProgress = _a.onLoadProgress, onContentProcessDidTerminateProp = _a.onContentProcessDidTerminate, onFileDownload = _a.onFileDownload, onHttpErrorProp = _a.onHttpError, onMessageProp = _a.onMessage, renderLoading = _a.renderLoading, renderError = _a.renderError, style = _a.style, containerStyle = _a.containerStyle, source = _a.source, nativeConfig = _a.nativeConfig, allowsInlineMediaPlayback = _a.allowsInlineMediaPlayback, allowsAirPlayForMediaPlayback = _a.allowsAirPlayForMediaPlayback, mediaPlaybackRequiresUserAction = _a.mediaPlaybackRequiresUserAction, dataDetectorTypes = _a.dataDetectorTypes, incognito = _a.incognito, decelerationRateProp = _a.decelerationRate, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequest, otherProps = __rest(_a, ["fraudulentWebsiteWarningEnabled", "javaScriptEnabled", "cacheEnabled", "originWhitelist", "useSharedProcessPool", "textInteractionEnabled", "injectedJavaScript", "injectedJavaScriptBeforeContentLoaded", "injectedJavaScriptForMainFrameOnly", "injectedJavaScriptBeforeContentLoadedForMainFrameOnly", "startInLoadingState", "onNavigationStateChange", "onLoadStart", "onError", "onLoad", "onLoadEnd", "onLoadProgress", "onContentProcessDidTerminate", "onFileDownload", "onHttpError", "onMessage", "renderLoading", "renderError", "style", "containerStyle", "source", "nativeConfig", "allowsInlineMediaPlayback", "allowsAirPlayForMediaPlayback", "mediaPlaybackRequiresUserAction", "dataDetectorTypes", "incognito", "decelerationRate", "onShouldStartLoadWithRequest"]);
+ var messagingEnabled = !!_a.messagingEnabled;
+ var _d = _a.fraudulentWebsiteWarningEnabled, fraudulentWebsiteWarningEnabled = _d === void 0 ? true : _d, _e = _a.javaScriptEnabled, javaScriptEnabled = _e === void 0 ? true : _e, _f = _a.cacheEnabled, cacheEnabled = _f === void 0 ? true : _f, _g = _a.originWhitelist, originWhitelist = _g === void 0 ? defaultOriginWhitelist : _g, _h = _a.useSharedProcessPool, useSharedProcessPool = _h === void 0 ? true : _h, _j = _a.textInteractionEnabled, textInteractionEnabled = _j === void 0 ? true : _j, injectedJavaScript = _a.injectedJavaScript, injectedJavaScriptBeforeContentLoaded = _a.injectedJavaScriptBeforeContentLoaded, _k = _a.injectedJavaScriptForMainFrameOnly, injectedJavaScriptForMainFrameOnly = _k === void 0 ? true : _k, _l = _a.injectedJavaScriptBeforeContentLoadedForMainFrameOnly, injectedJavaScriptBeforeContentLoadedForMainFrameOnly = _l === void 0 ? true : _l, startInLoadingState = _a.startInLoadingState, onNavigationStateChange = _a.onNavigationStateChange, onLoadStart = _a.onLoadStart, onError = _a.onError, onLoad = _a.onLoad, onLoadEnd = _a.onLoadEnd, onLoadProgress = _a.onLoadProgress, onContentProcessDidTerminateProp = _a.onContentProcessDidTerminate, onFileDownload = _a.onFileDownload, onHttpErrorProp = _a.onHttpError, onMessageProp = _a.onMessage, renderLoading = _a.renderLoading, renderError = _a.renderError, style = _a.style, containerStyle = _a.containerStyle, source = _a.source, nativeConfig = _a.nativeConfig, allowsInlineMediaPlayback = _a.allowsInlineMediaPlayback, allowsAirPlayForMediaPlayback = _a.allowsAirPlayForMediaPlayback, mediaPlaybackRequiresUserAction = _a.mediaPlaybackRequiresUserAction, dataDetectorTypes = _a.dataDetectorTypes, incognito = _a.incognito, decelerationRateProp = _a.decelerationRate, onShouldStartLoadWithRequestProp = _a.onShouldStartLoadWithRequest, otherProps = __rest(_a, ["messagingEnabled", "fraudulentWebsiteWarningEnabled", "javaScriptEnabled", "cacheEnabled", "originWhitelist", "useSharedProcessPool", "textInteractionEnabled", "injectedJavaScript", "injectedJavaScriptBeforeContentLoaded", "injectedJavaScriptForMainFrameOnly", "injectedJavaScriptBeforeContentLoadedForMainFrameOnly", "startInLoadingState", "onNavigationStateChange", "onLoadStart", "onError", "onLoad", "onLoadEnd", "onLoadProgress", "onContentProcessDidTerminate", "onFileDownload", "onHttpError", "onMessage", "renderLoading", "renderError", "style", "containerStyle", "source", "nativeConfig", "allowsInlineMediaPlayback", "allowsAirPlayForMediaPlayback", "mediaPlaybackRequiresUserAction", "dataDetectorTypes", "incognito", "decelerationRate", "onShouldStartLoadWithRequest"]);
var webViewRef = useRef(null);
var onShouldStartLoadWithRequestCallback = useCallback(function (shouldStart, _url, lockIdentifier) {
if (lockIdentifier === void 0) { lockIdentifier = 0; }
@@ -151,7 +152,7 @@ var WebViewComponent = forwardRef(function (_a, ref) {
};
}) : currValue, _b));
}, {}) : sourceResolved;
- var webView = (<NativeWebView key="webViewKey" {...otherProps} fraudulentWebsiteWarningEnabled={fraudulentWebsiteWarningEnabled} javaScriptEnabled={javaScriptEnabled} cacheEnabled={cacheEnabled} useSharedProcessPool={useSharedProcessPool} textInteractionEnabled={textInteractionEnabled} decelerationRate={decelerationRate} messagingEnabled={typeof onMessageProp === 'function'} messagingModuleName="" // android ONLY
+ var webView = (<NativeWebView key="webViewKey" {...otherProps} fraudulentWebsiteWarningEnabled={fraudulentWebsiteWarningEnabled} javaScriptEnabled={javaScriptEnabled} cacheEnabled={cacheEnabled} useSharedProcessPool={useSharedProcessPool} textInteractionEnabled={textInteractionEnabled} decelerationRate={decelerationRate} messagingEnabled={messagingEnabled} messagingModuleName="" // android ONLY
onLoadingError={onLoadingError} onLoadingFinish={onLoadingFinish} onLoadingProgress={onLoadingProgress} onFileDownload={onFileDownload} onLoadingStart={onLoadingStart} onHttpError={onHttpError} onMessage={onMessage} onShouldStartLoadWithRequest={onShouldStartLoadWithRequest} onContentProcessDidTerminate={onContentProcessDidTerminate} injectedJavaScript={injectedJavaScript} injectedJavaScriptBeforeContentLoaded={injectedJavaScriptBeforeContentLoaded} injectedJavaScriptForMainFrameOnly={injectedJavaScriptForMainFrameOnly} injectedJavaScriptBeforeContentLoadedForMainFrameOnly={injectedJavaScriptBeforeContentLoadedForMainFrameOnly} dataDetectorTypes={!dataDetectorTypes || Array.isArray(dataDetectorTypes) ? dataDetectorTypes : [dataDetectorTypes]} allowsAirPlayForMediaPlayback={allowsAirPlayForMediaPlayback} allowsInlineMediaPlayback={allowsInlineMediaPlayback} incognito={incognito} mediaPlaybackRequiresUserAction={mediaPlaybackRequiresUserAction} newSource={newSource} style={webViewStyles} hasOnFileDownload={!!onFileDownload} ref={webViewRef}
// @ts-expect-error old arch only
source={sourceResolved} {...nativeConfig === null || nativeConfig === void 0 ? void 0 : nativeConfig.props}/>);
diff --git a/node_modules/react-native-webview/react-native-webview.podspec b/node_modules/react-native-webview/react-native-webview.podspec
index b6f164a..ee6ec93 100644
--- a/node_modules/react-native-webview/react-native-webview.podspec
+++ b/node_modules/react-native-webview/react-native-webview.podspec
@@ -34,5 +34,6 @@ Pod::Spec.new do |s|
s.dependency "RCTRequired"
s.dependency "RCTTypeSafety"
s.dependency "ReactCommon/turbomodule/core"
+ s.dependency "react-native-jsi-bridge-2"
end
end
diff --git a/node_modules/react-native-webview/src/WebView.ios.tsx b/node_modules/react-native-webview/src/WebView.ios.tsx
index 1970a61..5bc1624 100644
--- a/node_modules/react-native-webview/src/WebView.ios.tsx
+++ b/node_modules/react-native-webview/src/WebView.ios.tsx
@@ -48,6 +48,7 @@ const useWarnIfChanges = <T extends unknown>(value: T, name: string) => {
}
const WebViewComponent = forwardRef<{}, IOSWebViewProps>(({
+ messagingEnabled = false,
fraudulentWebsiteWarningEnabled = true,
javaScriptEnabled = true,
cacheEnabled = true,
@@ -181,7 +182,7 @@ const WebViewComponent = forwardRef<{}, IOSWebViewProps>(({
useSharedProcessPool={useSharedProcessPool}
textInteractionEnabled={textInteractionEnabled}
decelerationRate={decelerationRate}
- messagingEnabled={typeof onMessageProp === 'function'}
+ messagingEnabled={messagingEnabled}
messagingModuleName="" // android ONLY
onLoadingError={onLoadingError}
onLoadingFinish={onLoadingFinish}
diff --git a/node_modules/react-native-webview/src/WebViewTypes.ts b/node_modules/react-native-webview/src/WebViewTypes.ts
index c83e3de..2643999 100644
--- a/node_modules/react-native-webview/src/WebViewTypes.ts
+++ b/node_modules/react-native-webview/src/WebViewTypes.ts
@@ -348,6 +348,11 @@ export interface WindowsWebViewProps extends WebViewSharedProps {
}
export interface IOSWebViewProps extends WebViewSharedProps {
+ /**
+ * @default false
+ */
+ messagingEnabled?: boolean;
+
/**
* Does not store any data within the lifetime of the WebView.
*/

Use as follows:

import { CustomJsiBridge } from 'react-native-jsi-bridge-2';

// ...

// Inside any React component
React.useEffect(() => {
  CustomJsiBridge.on('webViewMessage', (data: unknown) => {
    interface LogPayload {
      type: 'log';
      message: string;
    }
    // You can define other types of payload and discriminate
    // on them by checking the value of 'type'.
    type Payload = LogPayload;
    const isPayload = (data: unknown): data is Payload => {
      return typeof data === 'object' && data !== null;
    };

    if (!isPayload(data)) {
      return;
    }

    if (data.type === 'log') {
      console.log(`[WebView] ${data.message}`);
      return;
    }
    
    // TODO: implement other types of payload
    
  });
    
  return () => {
    CustomJsiBridge.off('webViewMessage');
  };
}, [onLookupTerm, onTopParagraphUpdate]);

// Here's my WebView settings:

<WebView
  ref={novelViewRef}
  originWhitelist={['*']}
  source={source}
  injectedJavaScriptBeforeContentLoaded={jsBeforeContentLoaded}
  injectedJavaScript={jsAfterContentLoaded(startingLine)}
  javaScriptEnabled={true}
  //@ts-ignore missing from props
  messagingEnabled={true}
  // I removed onMessage support because it was firing events
  // even if I didn't provide an onMessage handler. Do all
  // messaging through our global JSI messenger instead.
  // onMessage={onNovelViewMessage}
  webviewDebuggingEnabled={true}
/>

Caveats:

Your app may now crash on each HMR. I think the issue is due to react-native-jsi-bridge-2 throwing an error during deconstruction. Don't ask me - I think I'll be giving up on this patch rather than looking into it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment