@exodus/react-native-webview 11.26.1-exodus.9 → 13.16.0-exodus.1
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/README.md +36 -63
- package/android/build.gradle +83 -110
- package/android/gradle.properties +3 -4
- package/android/src/main/AndroidManifest.xml +12 -0
- package/android/src/main/AndroidManifestNew.xml +26 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCBasicAuthCredential.java +11 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java +407 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebView.java +468 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java +330 -0
- package/android/src/main/java/com/reactnativecommunity/webview/{WebViewConfig.java → RNCWebViewConfig.java} +3 -4
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewFileProvider.java +1 -1
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt +746 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewMessagingModule.kt +9 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModuleImpl.java +554 -0
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java +57 -12
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewWrapper.kt +39 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/SubResourceErrorEvent.kt +25 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopCustomMenuSelectionEvent.kt +24 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopHttpErrorEvent.kt +25 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopNewWindowEvent.kt +25 -0
- package/android/src/main/java/com/reactnativecommunity/webview/events/TopRenderProcessGoneEvent.kt +25 -0
- package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java +570 -0
- package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewModule.java +57 -0
- package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewManager.java +341 -0
- package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewModule.java +59 -0
- package/apple/RCTConvert+WKDataDetectorTypes.h +11 -0
- package/apple/RCTConvert+WKDataDetectorTypes.m +27 -0
- package/apple/RNCWebView.h +26 -100
- package/apple/RNCWebView.mm +555 -0
- package/apple/RNCWebViewDecisionManager.h +20 -0
- package/apple/RNCWebViewDecisionManager.m +47 -0
- package/apple/RNCWebViewImpl.h +164 -0
- package/apple/{RNCWebView.m → RNCWebViewImpl.m} +802 -225
- package/apple/RNCWebViewManager.h +4 -8
- package/apple/RNCWebViewManager.mm +221 -0
- package/apple/RNCWebViewModule.h +23 -0
- package/apple/RNCWebViewModule.mm +34 -0
- package/index.d.ts +2 -3
- package/lib/NativeRNCWebViewModule.d.ts +8 -0
- package/lib/NativeRNCWebViewModule.js +1 -0
- package/lib/RNCWebViewNativeComponent.d.ts +245 -0
- package/lib/RNCWebViewNativeComponent.js +1 -0
- package/lib/WebView.android.d.ts +0 -1
- package/lib/WebView.android.js +1 -135
- package/lib/WebView.d.ts +2 -3
- package/lib/WebView.ios.d.ts +0 -1
- package/lib/WebView.ios.js +1 -114
- package/lib/WebView.js +1 -11
- package/lib/WebView.macos.d.ts +6 -0
- package/lib/WebView.macos.js +1 -0
- package/lib/WebView.styles.d.ts +37 -11
- package/lib/WebView.styles.js +1 -33
- package/lib/WebView.windows.d.ts +17 -0
- package/lib/WebView.windows.js +1 -0
- package/lib/WebViewNativeComponent.macos.d.ts +3 -0
- package/lib/WebViewNativeComponent.macos.js +1 -0
- package/lib/WebViewNativeComponent.windows.d.ts +3 -0
- package/lib/WebViewNativeComponent.windows.js +1 -0
- package/lib/WebViewShared.d.ts +30 -9
- package/lib/WebViewShared.js +1 -174
- package/lib/WebViewTypes.d.ts +514 -98
- package/lib/WebViewTypes.js +1 -6
- package/lib/index.d.ts +0 -1
- package/lib/index.js +1 -3
- package/lib/validation.d.ts +3 -0
- package/lib/validation.js +1 -0
- package/package.json +57 -33
- package/react-native-webview.podspec +32 -5
- package/react-native.config.js +22 -18
- package/src/NativeRNCWebViewModule.ts +13 -0
- package/src/RNCWebViewNativeComponent.ts +348 -0
- package/src/WebView.android.tsx +345 -0
- package/src/WebView.ios.tsx +341 -0
- package/src/WebView.macos.tsx +252 -0
- package/src/WebView.styles.ts +41 -0
- package/src/WebView.tsx +25 -0
- package/src/WebView.windows.tsx +217 -0
- package/src/WebViewNativeComponent.macos.ts +7 -0
- package/src/WebViewNativeComponent.windows.ts +8 -0
- package/src/WebViewShared.tsx +476 -0
- package/src/WebViewTypes.ts +1402 -0
- package/src/__tests__/WebViewShared-test.js +323 -0
- package/src/__tests__/__snapshots__/WebViewShared-test.js.snap +8 -0
- package/src/__tests__/validation-test.js +38 -0
- package/src/index.ts +4 -0
- package/src/validation.ts +20 -0
- package/android/.editorconfig +0 -6
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java +0 -1408
- package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java +0 -506
- package/apple/RNCWebViewManager.m +0 -278
- package/lib/WebViewNativeComponent.android.d.ts +0 -4
- package/lib/WebViewNativeComponent.android.js +0 -3
- package/lib/WebViewNativeComponent.ios.d.ts +0 -4
- package/lib/WebViewNativeComponent.ios.js +0 -3
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
package com.reactnativecommunity.webview;
|
|
2
|
+
|
|
3
|
+
import android.annotation.SuppressLint;
|
|
4
|
+
import android.graphics.Rect;
|
|
5
|
+
import android.net.Uri;
|
|
6
|
+
import android.text.TextUtils;
|
|
7
|
+
import android.view.ActionMode;
|
|
8
|
+
import android.view.Menu;
|
|
9
|
+
import android.view.MenuItem;
|
|
10
|
+
import android.view.MotionEvent;
|
|
11
|
+
import android.view.View;
|
|
12
|
+
import android.webkit.JavascriptInterface;
|
|
13
|
+
import android.webkit.ValueCallback;
|
|
14
|
+
import android.webkit.WebChromeClient;
|
|
15
|
+
import android.webkit.WebView;
|
|
16
|
+
import android.webkit.WebViewClient;
|
|
17
|
+
|
|
18
|
+
import androidx.annotation.NonNull;
|
|
19
|
+
import androidx.annotation.Nullable;
|
|
20
|
+
import androidx.webkit.JavaScriptReplyProxy;
|
|
21
|
+
import androidx.webkit.WebMessageCompat;
|
|
22
|
+
import androidx.webkit.WebViewCompat;
|
|
23
|
+
import androidx.webkit.WebViewFeature;
|
|
24
|
+
|
|
25
|
+
import com.facebook.common.logging.FLog;
|
|
26
|
+
import com.facebook.react.bridge.Arguments;
|
|
27
|
+
import com.facebook.react.bridge.CatalystInstance;
|
|
28
|
+
import com.facebook.react.bridge.JavaScriptModule;
|
|
29
|
+
import com.facebook.react.bridge.LifecycleEventListener;
|
|
30
|
+
import com.facebook.react.bridge.ReactApplicationContext;
|
|
31
|
+
import com.facebook.react.bridge.WritableMap;
|
|
32
|
+
import com.facebook.react.bridge.WritableNativeArray;
|
|
33
|
+
import com.facebook.react.bridge.WritableNativeMap;
|
|
34
|
+
import com.facebook.react.uimanager.ThemedReactContext;
|
|
35
|
+
import com.facebook.react.uimanager.UIManagerHelper;
|
|
36
|
+
import com.facebook.react.uimanager.events.ContentSizeChangeEvent;
|
|
37
|
+
import com.facebook.react.uimanager.events.Event;
|
|
38
|
+
import com.facebook.react.views.scroll.OnScrollDispatchHelper;
|
|
39
|
+
import com.facebook.react.views.scroll.ScrollEvent;
|
|
40
|
+
import com.facebook.react.views.scroll.ScrollEventType;
|
|
41
|
+
import com.reactnativecommunity.webview.events.TopCustomMenuSelectionEvent;
|
|
42
|
+
import com.reactnativecommunity.webview.events.TopMessageEvent;
|
|
43
|
+
|
|
44
|
+
import org.json.JSONException;
|
|
45
|
+
import org.json.JSONObject;
|
|
46
|
+
|
|
47
|
+
import java.util.List;
|
|
48
|
+
import java.util.Map;
|
|
49
|
+
import java.util.Set;
|
|
50
|
+
|
|
51
|
+
public class RNCWebView extends WebView implements LifecycleEventListener {
|
|
52
|
+
protected @Nullable
|
|
53
|
+
String injectedJS;
|
|
54
|
+
protected @Nullable
|
|
55
|
+
String injectedJSBeforeContentLoaded;
|
|
56
|
+
protected static final String JAVASCRIPT_INTERFACE = "ReactNativeWebView";
|
|
57
|
+
protected @Nullable
|
|
58
|
+
RNCWebViewBridge fallbackBridge;
|
|
59
|
+
protected @Nullable
|
|
60
|
+
WebViewCompat.WebMessageListener bridgeListener = null;
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* android.webkit.WebChromeClient fundamentally does not support JS injection into frames other
|
|
64
|
+
* than the main frame, so these two properties are mostly here just for parity with iOS & macOS.
|
|
65
|
+
*/
|
|
66
|
+
protected boolean injectedJavaScriptForMainFrameOnly = true;
|
|
67
|
+
protected boolean injectedJavaScriptBeforeContentLoadedForMainFrameOnly = true;
|
|
68
|
+
|
|
69
|
+
protected boolean messagingEnabled = false;
|
|
70
|
+
protected @Nullable
|
|
71
|
+
String messagingModuleName;
|
|
72
|
+
protected @Nullable
|
|
73
|
+
RNCWebViewMessagingModule mMessagingJSModule;
|
|
74
|
+
protected @Nullable
|
|
75
|
+
RNCWebViewClient mRNCWebViewClient;
|
|
76
|
+
protected boolean sendContentSizeChangeEvents = false;
|
|
77
|
+
private OnScrollDispatchHelper mOnScrollDispatchHelper;
|
|
78
|
+
protected boolean hasScrollEvent = false;
|
|
79
|
+
protected boolean nestedScrollEnabled = false;
|
|
80
|
+
protected ProgressChangedFilter progressChangedFilter;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* WebView must be created with an context of the current activity
|
|
84
|
+
* <p>
|
|
85
|
+
* Activity Context is required for creation of dialogs internally by WebView
|
|
86
|
+
* Reactive Native needed for access to ReactNative internal system functionality
|
|
87
|
+
*/
|
|
88
|
+
public RNCWebView(ThemedReactContext reactContext) {
|
|
89
|
+
super(reactContext);
|
|
90
|
+
mMessagingJSModule = ((ThemedReactContext) this.getContext()).getReactApplicationContext().getJSModule(RNCWebViewMessagingModule.class);
|
|
91
|
+
progressChangedFilter = new ProgressChangedFilter();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public void setBasicAuthCredential(RNCBasicAuthCredential credential) {
|
|
95
|
+
mRNCWebViewClient.setBasicAuthCredential(credential);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
public void setSendContentSizeChangeEvents(boolean sendContentSizeChangeEvents) {
|
|
99
|
+
this.sendContentSizeChangeEvents = sendContentSizeChangeEvents;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
public void setHasScrollEvent(boolean hasScrollEvent) {
|
|
103
|
+
this.hasScrollEvent = hasScrollEvent;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public void setNestedScrollEnabled(boolean nestedScrollEnabled) {
|
|
107
|
+
this.nestedScrollEnabled = nestedScrollEnabled;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@Override
|
|
111
|
+
public void onHostResume() {
|
|
112
|
+
// do nothing
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
@Override
|
|
116
|
+
public void onHostPause() {
|
|
117
|
+
// do nothing
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
@Override
|
|
121
|
+
public void onHostDestroy() {
|
|
122
|
+
cleanupCallbacksAndDestroy();
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@Override
|
|
126
|
+
public boolean onTouchEvent(MotionEvent event) {
|
|
127
|
+
if (this.nestedScrollEnabled) {
|
|
128
|
+
requestDisallowInterceptTouchEvent(true);
|
|
129
|
+
}
|
|
130
|
+
return super.onTouchEvent(event);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@Override
|
|
134
|
+
protected void onSizeChanged(int w, int h, int ow, int oh) {
|
|
135
|
+
super.onSizeChanged(w, h, ow, oh);
|
|
136
|
+
|
|
137
|
+
if (sendContentSizeChangeEvents) {
|
|
138
|
+
dispatchEvent(
|
|
139
|
+
this,
|
|
140
|
+
new ContentSizeChangeEvent(
|
|
141
|
+
RNCWebViewWrapper.getReactTagFromWebView(this),
|
|
142
|
+
w,
|
|
143
|
+
h
|
|
144
|
+
)
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
protected @Nullable
|
|
150
|
+
List<Map<String, String>> menuCustomItems;
|
|
151
|
+
|
|
152
|
+
public void setMenuCustomItems(List<Map<String, String>> menuCustomItems) {
|
|
153
|
+
this.menuCustomItems = menuCustomItems;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
@Override
|
|
157
|
+
public ActionMode startActionMode(ActionMode.Callback callback, int type) {
|
|
158
|
+
if(menuCustomItems == null ){
|
|
159
|
+
return super.startActionMode(callback, type);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return super.startActionMode(new ActionMode.Callback2() {
|
|
163
|
+
@Override
|
|
164
|
+
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
|
|
165
|
+
for (int i = 0; i < menuCustomItems.size(); i++) {
|
|
166
|
+
menu.add(Menu.NONE, i, i, (menuCustomItems.get(i)).get("label"));
|
|
167
|
+
}
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
@Override
|
|
172
|
+
public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
@Override
|
|
177
|
+
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
|
|
178
|
+
WritableMap wMap = Arguments.createMap();
|
|
179
|
+
RNCWebView.this.evaluateJavascript(
|
|
180
|
+
"(function(){return {selection: window.getSelection().toString()} })()",
|
|
181
|
+
new ValueCallback<String>() {
|
|
182
|
+
@Override
|
|
183
|
+
public void onReceiveValue(String selectionJson) {
|
|
184
|
+
Map<String, String> menuItemMap = menuCustomItems.get(item.getItemId());
|
|
185
|
+
wMap.putString("label", menuItemMap.get("label"));
|
|
186
|
+
wMap.putString("key", menuItemMap.get("key"));
|
|
187
|
+
String selectionText = "";
|
|
188
|
+
try {
|
|
189
|
+
selectionText = new JSONObject(selectionJson).getString("selection");
|
|
190
|
+
} catch (JSONException ignored) {}
|
|
191
|
+
wMap.putString("selectedText", selectionText);
|
|
192
|
+
dispatchEvent(RNCWebView.this, new TopCustomMenuSelectionEvent(RNCWebViewWrapper.getReactTagFromWebView(RNCWebView.this), wMap));
|
|
193
|
+
mode.finish();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
);
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
@Override
|
|
201
|
+
public void onDestroyActionMode(ActionMode mode) {
|
|
202
|
+
mode = null;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
@Override
|
|
206
|
+
public void onGetContentRect (ActionMode mode,
|
|
207
|
+
View view,
|
|
208
|
+
Rect outRect){
|
|
209
|
+
if (callback instanceof ActionMode.Callback2) {
|
|
210
|
+
((ActionMode.Callback2) callback).onGetContentRect(mode, view, outRect);
|
|
211
|
+
} else {
|
|
212
|
+
super.onGetContentRect(mode, view, outRect);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}, type);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
@Override
|
|
219
|
+
public void setWebViewClient(WebViewClient client) {
|
|
220
|
+
super.setWebViewClient(client);
|
|
221
|
+
if (client instanceof RNCWebViewClient) {
|
|
222
|
+
mRNCWebViewClient = (RNCWebViewClient) client;
|
|
223
|
+
mRNCWebViewClient.setProgressChangedFilter(progressChangedFilter);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
WebChromeClient mWebChromeClient;
|
|
228
|
+
@Override
|
|
229
|
+
public void setWebChromeClient(WebChromeClient client) {
|
|
230
|
+
this.mWebChromeClient = client;
|
|
231
|
+
super.setWebChromeClient(client);
|
|
232
|
+
if (client instanceof RNCWebChromeClient) {
|
|
233
|
+
((RNCWebChromeClient) client).setProgressChangedFilter(progressChangedFilter);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
public WebChromeClient getWebChromeClient() {
|
|
238
|
+
return this.mWebChromeClient;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
public @Nullable
|
|
242
|
+
RNCWebViewClient getRNCWebViewClient() {
|
|
243
|
+
return mRNCWebViewClient;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
public boolean getMessagingEnabled() {
|
|
247
|
+
return this.messagingEnabled;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
protected void createRNCWebViewBridge(RNCWebView webView) {
|
|
251
|
+
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_MESSAGE_LISTENER)){
|
|
252
|
+
if (this.bridgeListener == null) {
|
|
253
|
+
this.bridgeListener = new WebViewCompat.WebMessageListener() {
|
|
254
|
+
@Override
|
|
255
|
+
public void onPostMessage(@NonNull WebView view, @NonNull WebMessageCompat message, @NonNull Uri sourceOrigin, boolean isMainFrame, @NonNull JavaScriptReplyProxy replyProxy) {
|
|
256
|
+
RNCWebView.this.onMessage(message.getData(), sourceOrigin.toString());
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
WebViewCompat.addWebMessageListener(
|
|
260
|
+
webView,
|
|
261
|
+
JAVASCRIPT_INTERFACE,
|
|
262
|
+
Set.of("*"),
|
|
263
|
+
this.bridgeListener
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
} else {
|
|
267
|
+
if (fallbackBridge == null) {
|
|
268
|
+
fallbackBridge = new RNCWebViewBridge(webView);
|
|
269
|
+
addJavascriptInterface(fallbackBridge, JAVASCRIPT_INTERFACE);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
injectJavascriptObject();
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
private void injectJavascriptObject() {
|
|
276
|
+
if (getSettings().getJavaScriptEnabled()) {
|
|
277
|
+
String js = "(function(){\n" +
|
|
278
|
+
" window." + JAVASCRIPT_INTERFACE + " = window." + JAVASCRIPT_INTERFACE + " || {};\n" +
|
|
279
|
+
" window." + JAVASCRIPT_INTERFACE + ".injectedObjectJson = function () { return " + (injectedJavaScriptObject == null ? null : ("`" + injectedJavaScriptObject + "`")) + "; };\n" +
|
|
280
|
+
"})();";
|
|
281
|
+
evaluateJavascriptWithFallback(js);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
@SuppressLint("AddJavascriptInterface")
|
|
286
|
+
public void setMessagingEnabled(boolean enabled) {
|
|
287
|
+
if (messagingEnabled == enabled) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
messagingEnabled = enabled;
|
|
292
|
+
|
|
293
|
+
if (enabled) {
|
|
294
|
+
createRNCWebViewBridge(this);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
protected void evaluateJavascriptWithFallback(String script) {
|
|
299
|
+
evaluateJavascript(script, null);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
public void callInjectedJavaScript() {
|
|
303
|
+
if (getSettings().getJavaScriptEnabled() &&
|
|
304
|
+
injectedJS != null &&
|
|
305
|
+
!TextUtils.isEmpty(injectedJS)) {
|
|
306
|
+
evaluateJavascriptWithFallback("(function() {\n" + injectedJS + ";\n})();");
|
|
307
|
+
injectJavascriptObject(); // re-inject the Javascript object in case it has been overwritten.
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
public void callInjectedJavaScriptBeforeContentLoaded() {
|
|
312
|
+
if (getSettings().getJavaScriptEnabled() &&
|
|
313
|
+
injectedJSBeforeContentLoaded != null &&
|
|
314
|
+
!TextUtils.isEmpty(injectedJSBeforeContentLoaded)) {
|
|
315
|
+
evaluateJavascriptWithFallback("(function() {\n" + injectedJSBeforeContentLoaded + ";\n})();");
|
|
316
|
+
injectJavascriptObject(); // re-inject the Javascript object in case it has been overwritten.
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
protected String injectedJavaScriptObject = null;
|
|
321
|
+
|
|
322
|
+
public void setInjectedJavaScriptObject(String obj) {
|
|
323
|
+
this.injectedJavaScriptObject = obj;
|
|
324
|
+
injectJavascriptObject();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
public void onMessage(String message, String sourceUrl) {
|
|
328
|
+
ThemedReactContext reactContext = getThemedReactContext();
|
|
329
|
+
RNCWebView mWebView = this;
|
|
330
|
+
|
|
331
|
+
if (mRNCWebViewClient != null) {
|
|
332
|
+
WebView webView = this;
|
|
333
|
+
webView.post(new Runnable() {
|
|
334
|
+
@Override
|
|
335
|
+
public void run() {
|
|
336
|
+
if (mRNCWebViewClient == null) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
WritableMap data = mRNCWebViewClient.createWebViewEvent(webView, sourceUrl);
|
|
340
|
+
data.putString("data", message);
|
|
341
|
+
|
|
342
|
+
if (mMessagingJSModule != null) {
|
|
343
|
+
dispatchDirectMessage(data);
|
|
344
|
+
} else {
|
|
345
|
+
dispatchEvent(webView, new TopMessageEvent(RNCWebViewWrapper.getReactTagFromWebView(webView), data));
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
} else {
|
|
350
|
+
WritableMap eventData = Arguments.createMap();
|
|
351
|
+
eventData.putString("data", message);
|
|
352
|
+
|
|
353
|
+
if (mMessagingJSModule != null) {
|
|
354
|
+
dispatchDirectMessage(eventData);
|
|
355
|
+
} else {
|
|
356
|
+
dispatchEvent(this, new TopMessageEvent(RNCWebViewWrapper.getReactTagFromWebView(this), eventData));
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
protected void dispatchDirectMessage(WritableMap data) {
|
|
362
|
+
WritableNativeMap event = new WritableNativeMap();
|
|
363
|
+
event.putMap("nativeEvent", data);
|
|
364
|
+
event.putString("messagingModuleName", messagingModuleName);
|
|
365
|
+
|
|
366
|
+
mMessagingJSModule.onMessage(event);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
protected boolean dispatchDirectShouldStartLoadWithRequest(WritableMap data) {
|
|
370
|
+
WritableNativeMap event = new WritableNativeMap();
|
|
371
|
+
event.putMap("nativeEvent", data);
|
|
372
|
+
event.putString("messagingModuleName", messagingModuleName);
|
|
373
|
+
|
|
374
|
+
mMessagingJSModule.onShouldStartLoadWithRequest(event);
|
|
375
|
+
return true;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
protected void onScrollChanged(int x, int y, int oldX, int oldY) {
|
|
379
|
+
super.onScrollChanged(x, y, oldX, oldY);
|
|
380
|
+
|
|
381
|
+
if (!hasScrollEvent) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
if (mOnScrollDispatchHelper == null) {
|
|
386
|
+
mOnScrollDispatchHelper = new OnScrollDispatchHelper();
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
if (mOnScrollDispatchHelper.onScrollChanged(x, y)) {
|
|
390
|
+
ScrollEvent event = ScrollEvent.obtain(
|
|
391
|
+
RNCWebViewWrapper.getReactTagFromWebView(this),
|
|
392
|
+
ScrollEventType.SCROLL,
|
|
393
|
+
x,
|
|
394
|
+
y,
|
|
395
|
+
mOnScrollDispatchHelper.getXFlingVelocity(),
|
|
396
|
+
mOnScrollDispatchHelper.getYFlingVelocity(),
|
|
397
|
+
this.computeHorizontalScrollRange(),
|
|
398
|
+
this.computeVerticalScrollRange(),
|
|
399
|
+
this.getWidth(),
|
|
400
|
+
this.getHeight());
|
|
401
|
+
|
|
402
|
+
dispatchEvent(this, event);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
protected void dispatchEvent(WebView webView, Event event) {
|
|
407
|
+
ThemedReactContext reactContext = getThemedReactContext();
|
|
408
|
+
int reactTag = RNCWebViewWrapper.getReactTagFromWebView(webView);
|
|
409
|
+
UIManagerHelper.getEventDispatcherForReactTag(reactContext, reactTag).dispatchEvent(event);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
protected void cleanupCallbacksAndDestroy() {
|
|
413
|
+
setWebViewClient(null);
|
|
414
|
+
destroy();
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
@Override
|
|
418
|
+
public void destroy() {
|
|
419
|
+
if (mWebChromeClient != null) {
|
|
420
|
+
mWebChromeClient.onHideCustomView();
|
|
421
|
+
}
|
|
422
|
+
super.destroy();
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
public ThemedReactContext getThemedReactContext() {
|
|
426
|
+
return (ThemedReactContext) this.getContext();
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
public ReactApplicationContext getReactApplicationContext() {
|
|
430
|
+
return this.getThemedReactContext().getReactApplicationContext();
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
protected class RNCWebViewBridge {
|
|
434
|
+
private String TAG = "RNCWebViewBridge";
|
|
435
|
+
RNCWebView mWebView;
|
|
436
|
+
|
|
437
|
+
RNCWebViewBridge(RNCWebView c) {
|
|
438
|
+
mWebView = c;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* This method is called whenever JavaScript running within the web view calls:
|
|
443
|
+
* - window[JAVASCRIPT_INTERFACE].postMessage
|
|
444
|
+
*/
|
|
445
|
+
@JavascriptInterface
|
|
446
|
+
public void postMessage(String message) {
|
|
447
|
+
if (mWebView.getMessagingEnabled()) {
|
|
448
|
+
// Post to main thread because `mWebView.getUrl()` requires to be executed on main.
|
|
449
|
+
mWebView.post(() -> mWebView.onMessage(message, mWebView.getUrl()));
|
|
450
|
+
} else {
|
|
451
|
+
FLog.w(TAG, "ReactNativeWebView.postMessage method was called but messaging is disabled. Pass an onMessage handler to the WebView.");
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
|
|
457
|
+
protected static class ProgressChangedFilter {
|
|
458
|
+
private boolean waitingForCommandLoadUrl = false;
|
|
459
|
+
|
|
460
|
+
public void setWaitingForCommandLoadUrl(boolean isWaiting) {
|
|
461
|
+
waitingForCommandLoadUrl = isWaiting;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
public boolean isWaitingForCommandLoadUrl() {
|
|
465
|
+
return waitingForCommandLoadUrl;
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
}
|