Skip to content

Commit 01f0c17

Browse files
authored
Merge pull request #150 from hmedney/master
IOS and Android updates and fixes for RN 0.33
2 parents d446ef1 + dd8067b commit 01f0c17

File tree

4 files changed

+97
-108
lines changed

4 files changed

+97
-108
lines changed
Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
package com.github.alinz.reactnativewebviewbridge;
22

33
import android.webkit.JavascriptInterface;
4+
import android.webkit.WebView;
45

56
import com.facebook.react.bridge.Arguments;
67
import com.facebook.react.bridge.ReactContext;
78
import com.facebook.react.bridge.WritableMap;
89
import com.facebook.react.modules.core.DeviceEventManagerModule;
10+
import com.facebook.react.uimanager.events.RCTEventEmitter;
911

1012
class JavascriptBridge {
11-
private ReactContext context;
13+
private WebView webView;
1214

13-
public JavascriptBridge(ReactContext context) {
14-
this.context = context;
15-
}
15+
public JavascriptBridge(WebView webView) {
16+
this.webView = webView;
17+
}
1618

17-
@JavascriptInterface
18-
public void send(String message) {
19-
WritableMap params = Arguments.createMap();
20-
params.putString("message", message);
21-
context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
22-
.emit("webViewBridgeMessage", params);
23-
}
24-
}
19+
@JavascriptInterface
20+
public void send(String message) {
21+
WritableMap event = Arguments.createMap();
22+
event.putString("message", message);
23+
ReactContext reactContext = (ReactContext) this.webView.getContext();
24+
reactContext.getJSModule(RCTEventEmitter.class).receiveEvent(
25+
this.webView.getId(),
26+
"topChange",
27+
event);
28+
}
29+
}

android/src/main/java/com/github/alinz/reactnativewebviewbridge/WebViewBridgeManager.java

Lines changed: 66 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -2,98 +2,81 @@
22

33
import android.webkit.WebView;
44

5-
import com.facebook.react.bridge.ReactContext;
65
import com.facebook.react.bridge.ReadableArray;
6+
import com.facebook.react.uimanager.ThemedReactContext;
77
import com.facebook.react.views.webview.ReactWebViewManager;
8-
import com.facebook.react.views.webview.WebViewConfig;
8+
import com.facebook.react.uimanager.annotations.ReactProp;
99

10+
import java.util.ArrayList;
1011
import java.util.Map;
1112

1213
import javax.annotation.Nullable;
1314

1415
public class WebViewBridgeManager extends ReactWebViewManager {
15-
private static final String REACT_CLASS = "RCTWebViewBridge";
16-
17-
public static final int COMMAND_INJECT_BRIDGE_SCRIPT = 100;
18-
public static final int COMMAND_SEND_TO_BRIDGE = 101;
19-
20-
private boolean initializedBridge;
21-
22-
public WebViewBridgeManager() {
23-
super();
24-
initializedBridge = false;
25-
}
26-
27-
public WebViewBridgeManager(WebViewConfig webViewConfig) {
28-
super(webViewConfig);
29-
initializedBridge = false;
30-
}
31-
32-
@Override
33-
public String getName() {
34-
return REACT_CLASS;
35-
}
36-
37-
@Override
38-
public @Nullable Map<String, Integer> getCommandsMap() {
39-
Map<String, Integer> commandsMap = super.getCommandsMap();
40-
41-
commandsMap.put("injectBridgeScript", COMMAND_INJECT_BRIDGE_SCRIPT);
42-
commandsMap.put("sendToBridge", COMMAND_SEND_TO_BRIDGE);
43-
44-
return commandsMap;
45-
}
46-
47-
@Override
48-
public void receiveCommand(WebView root, int commandId, @Nullable ReadableArray args) {
49-
super.receiveCommand(root, commandId, args);
50-
51-
switch (commandId) {
52-
case COMMAND_INJECT_BRIDGE_SCRIPT:
53-
injectBridgeScript(root);
54-
break;
55-
case COMMAND_SEND_TO_BRIDGE:
56-
sendToBridge(root, args.getString(0));
57-
break;
58-
default:
59-
//do nothing!!!!
16+
private static final String REACT_CLASS = "RCTWebViewBridge";
17+
18+
public static final int COMMAND_SEND_TO_BRIDGE = 101;
19+
20+
@Override
21+
public String getName() {
22+
return REACT_CLASS;
23+
}
24+
25+
private ArrayList<Integer> webViewsWithBridgeScript = new ArrayList<Integer>();
26+
27+
@Override
28+
public
29+
@Nullable
30+
Map<String, Integer> getCommandsMap() {
31+
Map<String, Integer> commandsMap = super.getCommandsMap();
32+
33+
commandsMap.put("sendToBridge", COMMAND_SEND_TO_BRIDGE);
34+
35+
return commandsMap;
36+
}
37+
38+
@Override
39+
protected WebView createViewInstance(ThemedReactContext reactContext) {
40+
WebView root = super.createViewInstance(reactContext);
41+
root.addJavascriptInterface(new JavascriptBridge(root), "WebViewBridge");
42+
return root;
43+
}
44+
45+
@Override
46+
public void receiveCommand(WebView root, int commandId, @Nullable ReadableArray args) {
47+
super.receiveCommand(root, commandId, args);
48+
// if (true) return;
49+
50+
switch (commandId) {
51+
case COMMAND_SEND_TO_BRIDGE:
52+
sendToBridge(root, args.getString(0));
53+
break;
54+
default:
55+
//do nothing!!!!
56+
}
57+
}
58+
59+
private void sendToBridge(WebView root, String message) {
60+
//root.loadUrl("javascript:(function() {\n" + script + ";\n})();");
61+
String script = "WebViewBridge.onMessage('" + message + "');";
62+
WebViewBridgeManager.evaluateJavascript(root, script);
63+
}
64+
65+
static private void evaluateJavascript(WebView root, String javascript) {
66+
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
67+
root.evaluateJavascript(javascript, null);
68+
} else {
69+
root.loadUrl("javascript:" + javascript);
70+
}
6071
}
61-
}
62-
63-
private void sendToBridge(WebView root, String message) {
64-
//root.loadUrl("javascript:(function() {\n" + script + ";\n})();");
65-
String script = "WebViewBridge.onMessage('" + message + "');";
66-
WebViewBridgeManager.evaluateJavascript(root, script);
67-
}
68-
69-
private void injectBridgeScript(WebView root) {
70-
//this code needs to be called once per context
71-
if (!initializedBridge) {
72-
root.addJavascriptInterface(new JavascriptBridge((ReactContext) root.getContext()), "WebViewBridgeAndroid");
73-
initializedBridge = true;
74-
root.reload();
72+
73+
@ReactProp(name = "allowFileAccessFromFileURLs")
74+
public void setAllowFileAccessFromFileURLs(WebView root, boolean allows) {
75+
root.getSettings().setAllowFileAccessFromFileURLs(allows);
7576
}
7677

77-
// this code needs to be executed everytime a url changes.
78-
WebViewBridgeManager.evaluateJavascript(root, ""
79-
+ "(function() {"
80-
+ "if (window.WebViewBridge) return;"
81-
+ "var customEvent = document.createEvent('Event');"
82-
+ "var WebViewBridge = {"
83-
+ "send: function(message) { WebViewBridgeAndroid.send(message); },"
84-
+ "onMessage: function() {}"
85-
+ "};"
86-
+ "window.WebViewBridge = WebViewBridge;"
87-
+ "customEvent.initEvent('WebViewBridge', true, true);"
88-
+ "document.dispatchEvent(customEvent);"
89-
+ "}());");
90-
}
91-
92-
static private void evaluateJavascript(WebView root, String javascript) {
93-
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
94-
root.evaluateJavascript(javascript, null);
95-
} else {
96-
root.loadUrl("javascript:" + javascript);
78+
@ReactProp(name = "allowUniversalAccessFromFileURLs")
79+
public void setAllowUniversalAccessFromFileURLs(WebView root, boolean allows) {
80+
root.getSettings().setAllowUniversalAccessFromFileURLs(allows);
9781
}
98-
}
99-
}
82+
}

ios/RCTWebViewBridge.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#import "RCTUtils.h"
2222
#import "RCTView.h"
2323
#import "UIView+React.h"
24+
#import <objc/runtime.h>
2425

2526
//This is a very elegent way of defining multiline string in objective-c.
2627
//source: http://stackoverflow.com/a/23387659/828487

webview-bridge/index.android.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,15 @@ var WebViewBridgeState = keyMirror({
4343
ERROR: null,
4444
});
4545

46+
var RCTWebViewBridge = requireNativeComponent('RCTWebViewBridge', WebViewBridge);
47+
4648
/**
4749
* Renders a native WebView.
4850
*/
4951
var WebViewBridge = React.createClass({
5052

5153
propTypes: {
52-
...WebView.propTypes,
54+
...RCTWebViewBridge.propTypes,
5355

5456
/**
5557
* Will be called once the message is being sent from webview
@@ -65,6 +67,7 @@ var WebViewBridge = React.createClass({
6567
};
6668
},
6769

70+
6871
componentWillMount: function() {
6972
DeviceEventEmitter.addListener("webViewBridgeMessage", (body) => {
7073
const { onBridgeMessage } = this.props;
@@ -117,12 +120,14 @@ var WebViewBridge = React.createClass({
117120
<RCTWebViewBridge
118121
ref={RCT_WEBVIEWBRIDGE_REF}
119122
key="webViewKey"
123+
javaScriptEnabled={true}
120124
{...props}
121125
source={resolveAssetSource(source)}
122126
style={webViewStyles}
123127
onLoadingStart={this.onLoadingStart}
124128
onLoadingFinish={this.onLoadingFinish}
125129
onLoadingError={this.onLoadingError}
130+
onChange={this.onMessage}
126131
/>;
127132

128133
return (
@@ -133,6 +138,12 @@ var WebViewBridge = React.createClass({
133138
);
134139
},
135140

141+
onMessage(event) {
142+
if (this.props.onBridgeMessage != null && event.nativeEvent != null) {
143+
this.props.onBridgeMessage(event.nativeEvent.message)
144+
}
145+
},
146+
136147
goForward: function() {
137148
UIManager.dispatchViewManagerCommand(
138149
this.getWebViewBridgeHandle(),
@@ -165,14 +176,6 @@ var WebViewBridge = React.createClass({
165176
);
166177
},
167178

168-
injectBridgeScript: function () {
169-
UIManager.dispatchViewManagerCommand(
170-
this.getWebViewBridgeHandle(),
171-
UIManager.RCTWebViewBridge.Commands.injectBridgeScript,
172-
null
173-
);
174-
},
175-
176179
/**
177180
* We return an event with a bunch of fields including:
178181
* url, title, loading, canGoBack, canGoForward
@@ -188,7 +191,6 @@ var WebViewBridge = React.createClass({
188191
},
189192

190193
onLoadingStart: function(event) {
191-
this.injectBridgeScript();
192194
var onLoadStart = this.props.onLoadStart;
193195
onLoadStart && onLoadStart(event);
194196
this.updateNavigationState(event);
@@ -199,7 +201,6 @@ var WebViewBridge = React.createClass({
199201
var {onError, onLoadEnd} = this.props;
200202
onError && onError(event);
201203
onLoadEnd && onLoadEnd(event);
202-
console.error('Encountered an error loading page', event.nativeEvent);
203204

204205
this.setState({
205206
lastErrorEvent: event.nativeEvent,
@@ -218,7 +219,6 @@ var WebViewBridge = React.createClass({
218219
},
219220
});
220221

221-
var RCTWebViewBridge = requireNativeComponent('RCTWebViewBridge', WebViewBridge);
222222

223223
var styles = StyleSheet.create({
224224
container: {
@@ -230,4 +230,4 @@ var styles = StyleSheet.create({
230230
},
231231
});
232232

233-
module.exports = WebViewBridge;
233+
module.exports = WebViewBridge;

0 commit comments

Comments
 (0)