@exodus/react-native-webview 11.26.1-exodus.8 → 13.16.0-exodus.0

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.
Files changed (118) hide show
  1. package/README.md +36 -63
  2. package/android/build.gradle +83 -110
  3. package/android/gradle.properties +3 -4
  4. package/android/src/main/AndroidManifest.xml +12 -0
  5. package/android/src/main/AndroidManifestNew.xml +26 -0
  6. package/android/src/main/java/com/reactnativecommunity/webview/RNCBasicAuthCredential.java +11 -0
  7. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebChromeClient.java +407 -0
  8. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebView.java +468 -0
  9. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java +330 -0
  10. package/android/src/main/java/com/reactnativecommunity/webview/{WebViewConfig.java → RNCWebViewConfig.java} +3 -4
  11. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewFileProvider.java +1 -1
  12. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt +746 -0
  13. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewMessagingModule.kt +9 -0
  14. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModuleImpl.java +554 -0
  15. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewPackage.java +57 -12
  16. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewWrapper.kt +39 -0
  17. package/android/src/main/java/com/reactnativecommunity/webview/events/SubResourceErrorEvent.kt +25 -0
  18. package/android/src/main/java/com/reactnativecommunity/webview/events/TopCustomMenuSelectionEvent.kt +24 -0
  19. package/android/src/main/java/com/reactnativecommunity/webview/events/TopHttpErrorEvent.kt +25 -0
  20. package/android/src/main/java/com/reactnativecommunity/webview/events/TopNewWindowEvent.kt +25 -0
  21. package/android/src/main/java/com/reactnativecommunity/webview/events/TopRenderProcessGoneEvent.kt +25 -0
  22. package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java +570 -0
  23. package/android/src/newarch/com/reactnativecommunity/webview/RNCWebViewModule.java +57 -0
  24. package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewManager.java +341 -0
  25. package/android/src/oldarch/com/reactnativecommunity/webview/RNCWebViewModule.java +59 -0
  26. package/apple/RCTConvert+WKDataDetectorTypes.h +11 -0
  27. package/apple/RCTConvert+WKDataDetectorTypes.m +27 -0
  28. package/apple/RNCWebView.h +26 -100
  29. package/apple/RNCWebView.mm +555 -0
  30. package/apple/RNCWebViewDecisionManager.h +20 -0
  31. package/apple/RNCWebViewDecisionManager.m +47 -0
  32. package/apple/RNCWebViewImpl.h +164 -0
  33. package/apple/{RNCWebView.m → RNCWebViewImpl.m} +803 -226
  34. package/apple/RNCWebViewManager.h +4 -8
  35. package/apple/RNCWebViewManager.mm +221 -0
  36. package/apple/RNCWebViewModule.h +23 -0
  37. package/apple/RNCWebViewModule.mm +34 -0
  38. package/index.d.ts +2 -3
  39. package/lib/NativeRNCWebViewModule.d.ts +8 -0
  40. package/lib/NativeRNCWebViewModule.js +1 -0
  41. package/lib/RNCWebViewNativeComponent.d.ts +245 -0
  42. package/lib/RNCWebViewNativeComponent.js +1 -0
  43. package/lib/WebView.android.d.ts +0 -1
  44. package/lib/WebView.android.js +1 -135
  45. package/lib/WebView.d.ts +2 -3
  46. package/lib/WebView.ios.d.ts +0 -1
  47. package/lib/WebView.ios.js +1 -114
  48. package/lib/WebView.js +1 -11
  49. package/lib/WebView.macos.d.ts +6 -0
  50. package/lib/WebView.macos.js +1 -0
  51. package/lib/WebView.styles.d.ts +37 -11
  52. package/lib/WebView.styles.js +1 -33
  53. package/lib/WebView.windows.d.ts +17 -0
  54. package/lib/WebView.windows.js +1 -0
  55. package/lib/WebViewNativeComponent.macos.d.ts +3 -0
  56. package/lib/WebViewNativeComponent.macos.js +1 -0
  57. package/lib/WebViewNativeComponent.windows.d.ts +3 -0
  58. package/lib/WebViewNativeComponent.windows.js +1 -0
  59. package/lib/WebViewShared.d.ts +30 -9
  60. package/lib/WebViewShared.js +1 -174
  61. package/lib/WebViewTypes.d.ts +514 -98
  62. package/lib/WebViewTypes.js +1 -6
  63. package/lib/index.d.ts +0 -1
  64. package/lib/index.js +1 -3
  65. package/lib/validation.d.ts +3 -0
  66. package/lib/validation.js +1 -0
  67. package/package.json +57 -33
  68. package/react-native-webview.podspec +32 -5
  69. package/react-native.config.js +22 -18
  70. package/src/NativeRNCWebViewModule.ts +13 -0
  71. package/src/RNCWebViewNativeComponent.ts +348 -0
  72. package/src/WebView.android.tsx +345 -0
  73. package/src/WebView.ios.tsx +341 -0
  74. package/src/WebView.macos.tsx +252 -0
  75. package/src/WebView.styles.ts +41 -0
  76. package/src/WebView.tsx +25 -0
  77. package/src/WebView.windows.tsx +217 -0
  78. package/src/WebViewNativeComponent.macos.ts +7 -0
  79. package/src/WebViewNativeComponent.windows.ts +8 -0
  80. package/src/WebViewShared.tsx +476 -0
  81. package/src/WebViewTypes.ts +1402 -0
  82. package/src/__tests__/WebViewShared-test.js +323 -0
  83. package/src/__tests__/__snapshots__/WebViewShared-test.js.snap +8 -0
  84. package/src/__tests__/validation-test.js +38 -0
  85. package/src/index.ts +4 -0
  86. package/src/validation.ts +20 -0
  87. package/android/.editorconfig +0 -6
  88. package/android/.gradle/7.4.2/checksums/checksums.lock +0 -0
  89. package/android/.gradle/7.4.2/dependencies-accessors/dependencies-accessors.lock +0 -0
  90. package/android/.gradle/7.4.2/dependencies-accessors/gc.properties +0 -0
  91. package/android/.gradle/7.4.2/executionHistory/executionHistory.lock +0 -0
  92. package/android/.gradle/7.4.2/fileChanges/last-build.bin +0 -0
  93. package/android/.gradle/7.4.2/fileHashes/fileHashes.lock +0 -0
  94. package/android/.gradle/7.4.2/gc.properties +0 -0
  95. package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
  96. package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
  97. package/android/.gradle/vcs-1/gc.properties +0 -0
  98. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java +0 -1408
  99. package/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewModule.java +0 -506
  100. package/apple/RNCWebViewManager.m +0 -278
  101. package/ios/Pods/Manifest.lock +0 -3
  102. package/ios/Pods/Pods.xcodeproj/project.pbxproj +0 -397
  103. package/ios/Pods/Pods.xcodeproj/xcuserdata/gabrielezenwankwo.xcuserdatad/xcschemes/Pods-RNCWebView.xcscheme +0 -58
  104. package/ios/Pods/Pods.xcodeproj/xcuserdata/gabrielezenwankwo.xcuserdatad/xcschemes/xcschememanagement.plist +0 -16
  105. package/ios/Pods/Target Support Files/Pods-RNCWebView/Pods-RNCWebView-Info.plist +0 -26
  106. package/ios/Pods/Target Support Files/Pods-RNCWebView/Pods-RNCWebView-acknowledgements.markdown +0 -3
  107. package/ios/Pods/Target Support Files/Pods-RNCWebView/Pods-RNCWebView-acknowledgements.plist +0 -29
  108. package/ios/Pods/Target Support Files/Pods-RNCWebView/Pods-RNCWebView-dummy.m +0 -5
  109. package/ios/Pods/Target Support Files/Pods-RNCWebView/Pods-RNCWebView-umbrella.h +0 -16
  110. package/ios/Pods/Target Support Files/Pods-RNCWebView/Pods-RNCWebView.debug.xcconfig +0 -8
  111. package/ios/Pods/Target Support Files/Pods-RNCWebView/Pods-RNCWebView.modulemap +0 -6
  112. package/ios/Pods/Target Support Files/Pods-RNCWebView/Pods-RNCWebView.release.xcconfig +0 -8
  113. package/lib/UpdateOS.d.ts +0 -6
  114. package/lib/UpdateOS.js +0 -49
  115. package/lib/WebViewNativeComponent.android.d.ts +0 -4
  116. package/lib/WebViewNativeComponent.android.js +0 -3
  117. package/lib/WebViewNativeComponent.ios.d.ts +0 -4
  118. 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
+ }