Skip to content

Commit 382f11e

Browse files
committed
支持
1 parent 7bccf74 commit 382f11e

File tree

5 files changed

+115
-35
lines changed

5 files changed

+115
-35
lines changed

.idea/inspectionProfiles/profiles_settings.xml

Lines changed: 0 additions & 5 deletions
This file was deleted.

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

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
import java.util.List;
88
import java.util.regex.Pattern;
99
import javax.annotation.Nullable;
10+
import com.facebook.react.bridge.ReactMethod;
11+
import android.widget.Toast;
12+
import com.facebook.react.uimanager.events.RCTEventEmitter;
13+
import com.reactnativecommunity.webview.events.TopShouldStartLoadWithRequestEvent;
1014

1115
import java.io.UnsupportedEncodingException;
1216
import java.net.URLEncoder;
@@ -72,12 +76,14 @@
7276
* - GO_BACK
7377
* - GO_FORWARD
7478
* - RELOAD
79+
* - LOAD_URL
7580
*
7681
* {@link WebView} instances could emit following direct events:
7782
* - topLoadingFinish
7883
* - topLoadingStart
7984
* - topLoadingStart
8085
* - topLoadingProgress
86+
* - topShouldStartLoadWithRequest
8187
*
8288
* Each event will carry the following properties:
8389
* - target - view's react tag
@@ -104,6 +110,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
104110
public static final int COMMAND_STOP_LOADING = 4;
105111
public static final int COMMAND_POST_MESSAGE = 5;
106112
public static final int COMMAND_INJECT_JAVASCRIPT = 6;
113+
public static final int COMMAND_LOAD_URL = 7;
107114

108115
// Use `webView.loadUrl("about:blank")` to reliably reset the view
109116
// state and release page resources (including any running JavaScript).
@@ -144,25 +151,7 @@ public void onPageStarted(WebView webView, String url, Bitmap favicon) {
144151

145152
@Override
146153
public boolean shouldOverrideUrlLoading(WebView view, String url) {
147-
if (url.equals(BLANK_URL)) return false;
148-
149-
// url blacklisting
150-
if (mUrlPrefixesForDefaultIntent != null && mUrlPrefixesForDefaultIntent.size() > 0) {
151-
ArrayList<Object> urlPrefixesForDefaultIntent =
152-
mUrlPrefixesForDefaultIntent.toArrayList();
153-
for (Object urlPrefix : urlPrefixesForDefaultIntent) {
154-
if (url.startsWith((String) urlPrefix)) {
155-
launchIntent(view.getContext(), url);
156-
return true;
157-
}
158-
}
159-
}
160-
161-
if (mOriginWhitelist != null && shouldHandleURL(mOriginWhitelist, url)) {
162-
return false;
163-
}
164-
165-
launchIntent(view.getContext(), url);
154+
dispatchEvent(view, new TopShouldStartLoadWithRequestEvent(view.getId(), url));
166155
return true;
167156
}
168157

@@ -676,7 +665,8 @@ public Map getExportedCustomDirectEventTypeConstants() {
676665
"reload", COMMAND_RELOAD,
677666
"stopLoading", COMMAND_STOP_LOADING,
678667
"postMessage", COMMAND_POST_MESSAGE,
679-
"injectJavaScript", COMMAND_INJECT_JAVASCRIPT
668+
"injectJavaScript", COMMAND_INJECT_JAVASCRIPT,
669+
"loadUrl", COMMAND_LOAD_URL
680670
);
681671
}
682672

@@ -719,6 +709,12 @@ public void receiveCommand(WebView root, int commandId, @Nullable ReadableArray
719709
RNCWebView reactWebView = (RNCWebView) root;
720710
reactWebView.evaluateJavascriptWithFallback(args.getString(0));
721711
break;
712+
case COMMAND_LOAD_URL:
713+
if (args == null) {
714+
throw new RuntimeException("Arguments for loading an url are null!");
715+
}
716+
root.loadUrl(args.getString(0));
717+
break;
722718
}
723719
}
724720

@@ -752,4 +748,14 @@ protected static void dispatchEvent(WebView webView, Event event) {
752748
reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
753749
eventDispatcher.dispatchEvent(event);
754750
}
751+
752+
public Map<String, Object> getExportedCustomBubblingEventTypeConstants() {
753+
return MapBuilder.<String, Object>builder()
754+
.put(TopShouldStartLoadWithRequestEvent.EVENT_NAME,
755+
MapBuilder.of(
756+
"phasedRegistrationNames",
757+
MapBuilder.of("bubbled", "onShouldStartLoadWithRequest")))
758+
.build();
759+
}
760+
755761
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.reactnativecommunity.webview.events;
2+
3+
import com.facebook.react.bridge.Arguments;
4+
import com.facebook.react.bridge.WritableMap;
5+
import com.facebook.react.uimanager.events.Event;
6+
import com.facebook.react.uimanager.events.RCTEventEmitter;
7+
8+
public class TopShouldStartLoadWithRequestEvent extends Event<TopMessageEvent> {
9+
public static final String EVENT_NAME = "topShouldStartLoadWithRequest";
10+
private final String mUrl;
11+
12+
public TopShouldStartLoadWithRequestEvent(int viewId, String url) {
13+
super(viewId);
14+
mUrl = url;
15+
}
16+
17+
@Override
18+
public String getEventName() {
19+
return EVENT_NAME;
20+
}
21+
22+
@Override
23+
public boolean canCoalesce() {
24+
return false;
25+
}
26+
27+
@Override
28+
public short getCoalescingKey() {
29+
// All events for a given view can be coalesced.
30+
return 0;
31+
}
32+
33+
@Override
34+
public void dispatch(RCTEventEmitter rctEventEmitter) {
35+
WritableMap data = Arguments.createMap();
36+
data.putString("url", mUrl);
37+
data.putString("navigationType", "other");
38+
rctEventEmitter.receiveEvent(getViewTag(), EVENT_NAME, data);
39+
}
40+
}

js/WebView.android.js

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,39 @@ class WebView extends React.Component<WebViewSharedProps, State> {
131131

132132
let NativeWebView = nativeConfig.component || RNCWebView;
133133

134-
const webView = (
134+
const compiledWhitelist = [
135+
'about:blank',
136+
...(this.props.originWhitelist || []),
137+
].map(WebViewShared.originWhitelistToRegex);
138+
139+
const onShouldStartLoadWithRequest = (event) => {
140+
let shouldStart = true;
141+
const { url } = event.nativeEvent;
142+
const origin = WebViewShared.extractOrigin(url);
143+
const passesWhitelist = compiledWhitelist.some(x =>
144+
new RegExp(x).test(origin),
145+
);
146+
shouldStart = shouldStart && passesWhitelist;
147+
if (!passesWhitelist) {
148+
Linking.openURL(url);
149+
}
150+
if (this.props.onShouldStartLoadWithRequest) {
151+
shouldStart =
152+
shouldStart &&
153+
this.props.onShouldStartLoadWithRequest(event.nativeEvent);
154+
}
155+
156+
if (shouldStart) {
157+
UIManager.dispatchViewManagerCommand(
158+
this.getWebViewHandle(),
159+
UIManager.RNCWebView.Commands.loadUrl,
160+
[String(url)],
161+
);
162+
}
163+
};
164+
165+
166+
const webView = (
135167
<NativeWebView
136168
ref={this.webViewRef}
137169
key="webViewKey"
@@ -146,7 +178,8 @@ class WebView extends React.Component<WebViewSharedProps, State> {
146178
domStorageEnabled={this.props.domStorageEnabled}
147179
messagingEnabled={typeof this.props.onMessage === 'function'}
148180
onMessage={this.onMessage}
149-
overScrollMode={this.props.overScrollMode}
181+
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
182+
overScrollMode={this.props.overScrollMode}
150183
contentInset={this.props.contentInset}
151184
automaticallyAdjustContentInsets={
152185
this.props.automaticallyAdjustContentInsets

js/WebViewTypes.js

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ export type WebViewNavigationEvent = SyntheticEvent<WebViewNavigation>;
6262

6363
export type WebViewMessageEvent = SyntheticEvent<WebViewMessage>;
6464

65+
export type WebViewMessageEvent = SyntheticEvent<WebViewMessage>;
66+
6567
export type WebViewErrorEvent = SyntheticEvent<WebViewError>;
6668

6769
export type DataDetectorTypes =
@@ -201,13 +203,6 @@ export type IOSWebViewProps = $ReadOnly<{|
201203
| ?DataDetectorTypes
202204
| $ReadOnlyArray<DataDetectorTypes>,
203205

204-
/**
205-
* Function that allows custom handling of any web view requests. Return
206-
* `true` from the function to continue loading the request and `false`
207-
* to stop loading.
208-
* @platform ios
209-
*/
210-
onShouldStartLoadWithRequest?: (event: WebViewEvent) => mixed,
211206

212207
/**
213208
* Boolean that determines whether HTML5 videos play inline or use the
@@ -435,7 +430,16 @@ export type WebViewSharedProps = $ReadOnly<{|
435430
*/
436431
originWhitelist?: $ReadOnlyArray<string>,
437432

438-
/**
433+
/**
434+
* Function that allows custom handling of any web view requests. Return
435+
* `true` from the function to continue loading the request and `false`
436+
* to stop loading. The `navigationType` is always `other` on android.
437+
*/
438+
onShouldStartLoadWithRequest?: (event: WebViewNavigation) => mixed,
439+
440+
441+
442+
/**
439443
* Override the native component used to render the WebView. Enables a custom native
440444
* WebView which uses the same JavaScript as the original WebView.
441445
*/
@@ -444,3 +448,5 @@ export type WebViewSharedProps = $ReadOnly<{|
444448
style?: ViewStyleProp,
445449
children: Node,
446450
|}>;
451+
452+

0 commit comments

Comments
 (0)