Skip to content

Commit 9a6a0b0

Browse files
Merge pull request #9 from phantom/merge-upstream-webkit-1.14.0
Merge upstream/master - upgrade androidx.webkit:webkit to 1.14.0
2 parents 890b602 + a08be33 commit 9a6a0b0

File tree

27 files changed

+365
-96
lines changed

27 files changed

+365
-96
lines changed

.changeset/big-files-greet.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
'@phantom/react-native-webview': minor
3+
---
4+
5+
- Merged 16 commits from upstream/master
6+
- Upgraded androidx.webkit:webkit from 1.4.0 to 1.14.0
7+
- Added SSL error handling for sub-resources
8+
- Added Payment Request API support (disabled downloads for security)
9+
- Preserved Phantom's custom changes:
10+
- Package name and version (1.0.2)
11+
- Download blocking with toast message
12+
- All existing security configurations

.github/workflows/ios-ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
working-directory: example/ios
2626
- name: Build iOS test app
2727
run: |
28-
device_name='iPhone 15'
28+
device_name='iPhone 16'
2929
device=$(xcrun simctl list devices "${device_name}" available | grep "${device_name} (")
3030
re='\(([-0-9A-Fa-f]+)\)'
3131
[[ $device =~ $re ]] || exit 1

android/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
ReactNativeWebView_kotlinVersion=1.6.0
2-
ReactNativeWebView_webkitVersion=1.4.0
2+
ReactNativeWebView_webkitVersion=1.14.0
33
ReactNativeWebView_compileSdkVersion=31
44
ReactNativeWebView_targetSdkVersion=31
55
ReactNativeWebView_minSdkVersion=24

android/src/main/AndroidManifest.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
22
package="com.reactnativecommunity.webview">
33

4+
<queries>
5+
<intent>
6+
<action android:name="org.chromium.intent.action.PAY"/>
7+
</intent>
8+
<intent>
9+
<action android:name="org.chromium.intent.action.IS_READY_TO_PAY"/>
10+
</intent>
11+
<intent>
12+
<action android:name="org.chromium.intent.action.UPDATE_PAYMENT_DETAILS"/>
13+
</intent>
14+
</queries>
15+
416
<application>
517
<provider
618
android:name=".RNCWebViewFileProvider"

android/src/main/AndroidManifestNew.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
2+
3+
<queries>
4+
<intent>
5+
<action android:name="org.chromium.intent.action.PAY"/>
6+
</intent>
7+
<intent>
8+
<action android:name="org.chromium.intent.action.IS_READY_TO_PAY"/>
9+
</intent>
10+
<intent>
11+
<action android:name="org.chromium.intent.action.UPDATE_PAYMENT_DETAILS"/>
12+
</intent>
13+
</queries>
14+
215
<application>
316
<provider
417
android:name=".RNCWebViewFileProvider"

android/src/main/java/com/reactnativecommunity/webview/RNCWebView.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,6 @@ public RNCWebView(ThemedReactContext reactContext) {
9191
progressChangedFilter = new ProgressChangedFilter();
9292
}
9393

94-
public void setIgnoreErrFailedForThisURL(String url) {
95-
mRNCWebViewClient.setIgnoreErrFailedForThisURL(url);
96-
}
97-
9894
public void setBasicAuthCredential(RNCBasicAuthCredential credential) {
9995
mRNCWebViewClient.setBasicAuthCredential(credential);
10096
}

android/src/main/java/com/reactnativecommunity/webview/RNCWebViewClient.java

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import com.facebook.react.bridge.WritableMap;
2626
import com.facebook.react.uimanager.ThemedReactContext;
2727
import com.facebook.react.uimanager.UIManagerHelper;
28+
import com.reactnativecommunity.webview.events.SubResourceErrorEvent;
2829
import com.reactnativecommunity.webview.events.TopHttpErrorEvent;
2930
import com.reactnativecommunity.webview.events.TopLoadingErrorEvent;
3031
import com.reactnativecommunity.webview.events.TopLoadingFinishEvent;
@@ -42,13 +43,8 @@ public class RNCWebViewClient extends WebViewClient {
4243

4344
protected boolean mLastLoadFailed = false;
4445
protected RNCWebView.ProgressChangedFilter progressChangedFilter = null;
45-
protected @Nullable String ignoreErrFailedForThisURL = null;
4646
protected @Nullable RNCBasicAuthCredential basicAuthCredential = null;
4747

48-
public void setIgnoreErrFailedForThisURL(@Nullable String url) {
49-
ignoreErrFailedForThisURL = url;
50-
}
51-
5248
public void setBasicAuthCredential(@Nullable RNCBasicAuthCredential credential) {
5349
basicAuthCredential = credential;
5450
}
@@ -173,12 +169,6 @@ public void onReceivedSslError(final WebView webView, final SslErrorHandler hand
173169
// Undesired behavior: Return value of WebView.getUrl() may be the current URL instead of the failing URL.
174170
handler.cancel();
175171

176-
if (!topWindowUrl.equalsIgnoreCase(failingUrl)) {
177-
// If error is not due to top-level navigation, then do not call onReceivedError()
178-
Log.w(TAG, "Resource blocked from loading due to SSL error. Blocked URL: "+failingUrl);
179-
return;
180-
}
181-
182172
int code = error.getPrimaryError();
183173
String description = "";
184174
String descriptionPrefix = "SSL error: ";
@@ -210,6 +200,18 @@ public void onReceivedSslError(final WebView webView, final SslErrorHandler hand
210200

211201
description = descriptionPrefix + description;
212202

203+
if (!topWindowUrl.equalsIgnoreCase(failingUrl)) {
204+
// If error is not due to top-level navigation, then do not call onReceivedError()
205+
Log.w(TAG, "Resource blocked from loading due to SSL error. Blocked URL: "+failingUrl);
206+
this.onReceivedSubResourceSslError(
207+
webView,
208+
code,
209+
description,
210+
failingUrl
211+
);
212+
return;
213+
}
214+
213215
this.onReceivedError(
214216
webView,
215217
code,
@@ -218,27 +220,27 @@ public void onReceivedSslError(final WebView webView, final SslErrorHandler hand
218220
);
219221
}
220222

223+
public void onReceivedSubResourceSslError(
224+
WebView webView,
225+
int errorCode,
226+
String description,
227+
String failingUrl) {
228+
229+
WritableMap eventData = createWebViewEvent(webView, failingUrl);
230+
eventData.putDouble("code", errorCode);
231+
eventData.putString("description", description);
232+
233+
int reactTag = RNCWebViewWrapper.getReactTagFromWebView(webView);
234+
UIManagerHelper.getEventDispatcherForReactTag((ReactContext) webView.getContext(), reactTag).dispatchEvent(new SubResourceErrorEvent(reactTag, eventData));
235+
}
236+
221237
@Override
222238
public void onReceivedError(
223239
WebView webView,
224240
int errorCode,
225241
String description,
226242
String failingUrl) {
227243

228-
if (ignoreErrFailedForThisURL != null
229-
&& failingUrl.equals(ignoreErrFailedForThisURL)
230-
&& errorCode == -1
231-
&& description.equals("net::ERR_FAILED")) {
232-
233-
// This is a workaround for a bug in the WebView.
234-
// See these chromium issues for more context:
235-
// https://bugs.chromium.org/p/chromium/issues/detail?id=1023678
236-
// https://bugs.chromium.org/p/chromium/issues/detail?id=1050635
237-
// This entire commit should be reverted once this bug is resolved in chromium.
238-
setIgnoreErrFailedForThisURL(null);
239-
return;
240-
}
241-
242244
super.onReceivedError(webView, errorCode, description, failingUrl);
243245
mLastLoadFailed = true;
244246

android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManagerImpl.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ class RNCWebViewManagerImpl(private val newArch: Boolean = false) {
9292
WebView.setWebContentsDebuggingEnabled(true)
9393
}
9494
webView.setDownloadListener(DownloadListener { url, userAgent, contentDisposition, mimetype, contentLength ->
95-
webView.setIgnoreErrFailedForThisURL(url)
9695
android.widget.Toast.makeText(context, "File downloads are not supported", android.widget.Toast.LENGTH_SHORT).show();
9796
return@DownloadListener;
9897
})
@@ -675,4 +674,11 @@ class RNCWebViewManagerImpl(private val newArch: Boolean = false) {
675674
fun setWebviewDebuggingEnabled(viewWrapper: RNCWebViewWrapper, enabled: Boolean) {
676675
RNCWebView.setWebContentsDebuggingEnabled(enabled)
677676
}
677+
678+
fun setPaymentRequestEnabled(viewWrapper: RNCWebViewWrapper, enabled: Boolean) {
679+
val view = viewWrapper.webView
680+
if (WebViewFeature.isFeatureSupported(WebViewFeature.PAYMENT_REQUEST)) {
681+
WebSettingsCompat.setPaymentRequestEnabled(view.settings, enabled)
682+
}
683+
}
678684
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.reactnativecommunity.webview.events
2+
3+
import com.facebook.react.bridge.WritableMap
4+
import com.facebook.react.uimanager.events.Event
5+
import com.facebook.react.uimanager.events.RCTEventEmitter
6+
7+
/**
8+
* Event emitted when there is an error in loading a subresource
9+
*/
10+
class SubResourceErrorEvent(viewId: Int, private val mEventData: WritableMap) :
11+
Event<SubResourceErrorEvent>(viewId) {
12+
companion object {
13+
const val EVENT_NAME = "topLoadingSubResourceError"
14+
}
15+
16+
override fun getEventName(): String = EVENT_NAME
17+
18+
override fun canCoalesce(): Boolean = false
19+
20+
override fun getCoalescingKey(): Short = 0
21+
22+
override fun dispatch(rctEventEmitter: RCTEventEmitter) =
23+
rctEventEmitter.receiveEvent(viewTag, eventName, mEventData)
24+
25+
}

android/src/newarch/com/reactnativecommunity/webview/RNCWebViewManager.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import com.facebook.react.viewmanagers.RNCWebViewManagerInterface;
1616
import com.facebook.react.views.scroll.ScrollEventType;
1717
import com.reactnativecommunity.webview.events.TopCustomMenuSelectionEvent;
18+
import com.reactnativecommunity.webview.events.SubResourceErrorEvent;
1819
import com.reactnativecommunity.webview.events.TopHttpErrorEvent;
1920
import com.reactnativecommunity.webview.events.TopLoadingErrorEvent;
2021
import com.reactnativecommunity.webview.events.TopLoadingFinishEvent;
@@ -226,7 +227,7 @@ public void setMenuItems(RNCWebViewWrapper view, @Nullable ReadableArray items)
226227
}
227228

228229
@Override
229-
@ReactProp(name = "suppressMenuItems ")
230+
@ReactProp(name = "suppressMenuItems")
230231
public void setSuppressMenuItems(RNCWebViewWrapper view, @Nullable ReadableArray items) {}
231232

232233
@Override
@@ -331,6 +332,12 @@ public void setWebviewDebuggingEnabled(RNCWebViewWrapper view, boolean value) {
331332
mRNCWebViewManagerImpl.setWebviewDebuggingEnabled(view, value);
332333
}
333334

335+
@Override
336+
@ReactProp(name = "paymentRequestEnabled")
337+
public void setPaymentRequestEnabled(RNCWebViewWrapper view, boolean value) {
338+
mRNCWebViewManagerImpl.setPaymentRequestEnabled(view, value);
339+
}
340+
334341
/* iOS PROPS - no implemented here */
335342
@Override
336343
public void setAllowingReadAccessToURL(RNCWebViewWrapper view, @Nullable String value) {}
@@ -395,6 +402,9 @@ public void setPullToRefreshEnabled(RNCWebViewWrapper view, boolean value) {}
395402
@Override
396403
public void setRefreshControlLightMode(RNCWebViewWrapper view, boolean value) {}
397404

405+
@Override
406+
public void setIndicatorStyle(RNCWebViewWrapper view, @Nullable String value) {}
407+
398408
@Override
399409
public void setScrollEnabled(RNCWebViewWrapper view, boolean value) {}
400410

@@ -515,6 +525,7 @@ public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
515525
export.put(TopLoadingStartEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingStart"));
516526
export.put(TopLoadingFinishEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingFinish"));
517527
export.put(TopLoadingErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingError"));
528+
export.put(SubResourceErrorEvent.EVENT_NAME, MapBuilder.of("registrationName", "onLoadingSubResourceError"));
518529
export.put(TopMessageEvent.EVENT_NAME, MapBuilder.of("registrationName", "onMessage"));
519530
// !Default events but adding them here explicitly for clarity
520531

0 commit comments

Comments
 (0)