Skip to content

Commit 0c576ef

Browse files
mdvaccafacebook-github-bot
authored andcommitted
Expose AllowFileAccess property in WebView
Summary: This diff adds a new property in ReactWebView to be able to configure allowFileAccess Reviewed By: achen1 Differential Revision: D9789466 fbshipit-source-id: 39d042ac6ef69e44f006a4c4b0c2dd900f84dbc9
1 parent 1d2808e commit 0c576ef

File tree

3 files changed

+56
-49
lines changed

3 files changed

+56
-49
lines changed

Libraries/Components/WebView/WebView.android.js

+7
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ class WebView extends React.Component {
150150
*/
151151
scalesPageToFit: PropTypes.bool,
152152

153+
/**
154+
* Sets whether the webview allow access to file system.
155+
* @platform android
156+
*/
157+
allowFileAccess: PropTypes.bool,
158+
153159
/**
154160
* Sets the user-agent for this WebView. The user-agent can also be set in native using
155161
* WebViewConfig. This prop will overwrite that config.
@@ -317,6 +323,7 @@ class WebView extends React.Component {
317323
style={webViewStyles}
318324
source={resolveAssetSource(source)}
319325
scalesPageToFit={this.props.scalesPageToFit}
326+
allowFileAccess={this.props.allowFileAccess}
320327
injectedJavaScript={this.props.injectedJavaScript}
321328
userAgent={this.props.userAgent}
322329
javaScriptEnabled={this.props.javaScriptEnabled}

RNTester/js/WebViewExample.js

+1
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ exports.examples = [
436436
backgroundColor: BGWASH,
437437
height: 100,
438438
}}
439+
allowFileAccess={true}
439440
originWhitelist={FILE_SYSTEM_ORIGIN_WHITE_LIST}
440441
source={require('./helloworld.html')}
441442
scalesPageToFit={true}

ReactAndroid/src/main/java/com/facebook/react/views/webview/ReactWebViewManager.java

+48-49
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,8 @@
88
package com.facebook.react.views.webview;
99

1010
import android.annotation.TargetApi;
11-
import android.content.Context;
12-
import com.facebook.react.uimanager.UIManagerModule;
13-
import java.util.LinkedList;
14-
import java.util.List;
15-
import java.util.regex.Pattern;
16-
import javax.annotation.Nullable;
17-
18-
import java.io.UnsupportedEncodingException;
19-
import java.net.URLEncoder;
20-
import java.util.ArrayList;
21-
import java.util.HashMap;
22-
import java.util.Locale;
23-
import java.util.Map;
24-
2511
import android.content.ActivityNotFoundException;
12+
import android.content.Context;
2613
import android.content.Intent;
2714
import android.graphics.Bitmap;
2815
import android.graphics.Picture;
@@ -53,6 +40,7 @@
5340
import com.facebook.react.module.annotations.ReactModule;
5441
import com.facebook.react.uimanager.SimpleViewManager;
5542
import com.facebook.react.uimanager.ThemedReactContext;
43+
import com.facebook.react.uimanager.UIManagerModule;
5644
import com.facebook.react.uimanager.annotations.ReactProp;
5745
import com.facebook.react.uimanager.events.ContentSizeChangeEvent;
5846
import com.facebook.react.uimanager.events.Event;
@@ -62,10 +50,14 @@
6250
import com.facebook.react.views.webview.events.TopLoadingStartEvent;
6351
import com.facebook.react.views.webview.events.TopMessageEvent;
6452
import java.io.UnsupportedEncodingException;
53+
import java.net.URLEncoder;
6554
import java.util.ArrayList;
6655
import java.util.HashMap;
56+
import java.util.LinkedList;
57+
import java.util.List;
6758
import java.util.Locale;
6859
import java.util.Map;
60+
import java.util.regex.Pattern;
6961
import javax.annotation.Nullable;
7062
import org.json.JSONException;
7163
import org.json.JSONObject;
@@ -140,10 +132,10 @@ public void onPageStarted(WebView webView, String url, Bitmap favicon) {
140132
mLastLoadFailed = false;
141133

142134
dispatchEvent(
143-
webView,
144-
new TopLoadingStartEvent(
145-
webView.getId(),
146-
createWebViewEvent(webView, url)));
135+
webView,
136+
new TopLoadingStartEvent(
137+
webView.getId(),
138+
createWebViewEvent(webView, url)));
147139
}
148140

149141
@Override
@@ -153,7 +145,7 @@ public boolean shouldOverrideUrlLoading(WebView view, String url) {
153145
// url blacklisting
154146
if (mUrlPrefixesForDefaultIntent != null && mUrlPrefixesForDefaultIntent.size() > 0) {
155147
ArrayList<Object> urlPrefixesForDefaultIntent =
156-
mUrlPrefixesForDefaultIntent.toArrayList();
148+
mUrlPrefixesForDefaultIntent.toArrayList();
157149
for (Object urlPrefix : urlPrefixesForDefaultIntent) {
158150
if (url.startsWith((String) urlPrefix)) {
159151
launchIntent(view.getContext(), url);
@@ -196,10 +188,10 @@ private boolean shouldHandleURL(List<Pattern> originWhitelist, String url) {
196188

197189
@Override
198190
public void onReceivedError(
199-
WebView webView,
200-
int errorCode,
201-
String description,
202-
String failingUrl) {
191+
WebView webView,
192+
int errorCode,
193+
String description,
194+
String failingUrl) {
203195
super.onReceivedError(webView, errorCode, description, failingUrl);
204196
mLastLoadFailed = true;
205197

@@ -212,16 +204,16 @@ public void onReceivedError(
212204
eventData.putString("description", description);
213205

214206
dispatchEvent(
215-
webView,
216-
new TopLoadingErrorEvent(webView.getId(), eventData));
207+
webView,
208+
new TopLoadingErrorEvent(webView.getId(), eventData));
217209
}
218210

219211
protected void emitFinishEvent(WebView webView, String url) {
220212
dispatchEvent(
221-
webView,
222-
new TopLoadingFinishEvent(
223-
webView.getId(),
224-
createWebViewEvent(webView, url)));
213+
webView,
214+
new TopLoadingFinishEvent(
215+
webView.getId(),
216+
createWebViewEvent(webView, url)));
225217
}
226218

227219
protected WritableMap createWebViewEvent(WebView webView, String url) {
@@ -342,8 +334,8 @@ protected void evaluateJavascriptWithFallback(String script) {
342334

343335
public void callInjectedJavaScript() {
344336
if (getSettings().getJavaScriptEnabled() &&
345-
injectedJS != null &&
346-
!TextUtils.isEmpty(injectedJS)) {
337+
injectedJS != null &&
338+
!TextUtils.isEmpty(injectedJS)) {
347339
evaluateJavascriptWithFallback("(function() {\n" + injectedJS + ";\n})();");
348340
}
349341
}
@@ -366,9 +358,9 @@ public void onReceiveValue(String value) {
366358
evaluateJavascriptWithFallback("(" +
367359
"window.originalPostMessage = window.postMessage," +
368360
"window.postMessage = function(data) {" +
369-
BRIDGE_NAME + ".postMessage(String(data));" +
361+
BRIDGE_NAME + ".postMessage(String(data));" +
370362
"}" +
371-
")");
363+
")");
372364
}
373365
}
374366

@@ -438,8 +430,8 @@ public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermiss
438430

439431
// Fixes broken full-screen modals/galleries due to body height being 0.
440432
webView.setLayoutParams(
441-
new LayoutParams(LayoutParams.MATCH_PARENT,
442-
LayoutParams.MATCH_PARENT));
433+
new LayoutParams(LayoutParams.MATCH_PARENT,
434+
LayoutParams.MATCH_PARENT));
443435

444436
setGeolocationEnabled(webView, false);
445437
if (ReactBuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
@@ -511,7 +503,7 @@ public void setSource(WebView view, @Nullable ReadableMap source) {
511503
String html = source.getString("html");
512504
if (source.hasKey("baseUrl")) {
513505
view.loadDataWithBaseURL(
514-
source.getString("baseUrl"), html, HTML_MIME_TYPE, HTML_ENCODING, null);
506+
source.getString("baseUrl"), html, HTML_MIME_TYPE, HTML_ENCODING, null);
515507
} else {
516508
view.loadData(html, HTML_MIME_TYPE, HTML_ENCODING);
517509
}
@@ -588,14 +580,21 @@ public void setMixedContentMode(WebView view, @Nullable String mixedContentMode)
588580

589581
@ReactProp(name = "urlPrefixesForDefaultIntent")
590582
public void setUrlPrefixesForDefaultIntent(
591-
WebView view,
592-
@Nullable ReadableArray urlPrefixesForDefaultIntent) {
583+
WebView view,
584+
@Nullable ReadableArray urlPrefixesForDefaultIntent) {
593585
ReactWebViewClient client = ((ReactWebView) view).getReactWebViewClient();
594586
if (client != null && urlPrefixesForDefaultIntent != null) {
595587
client.setUrlPrefixesForDefaultIntent(urlPrefixesForDefaultIntent);
596588
}
597589
}
598590

591+
@ReactProp(name = "allowFileAccess")
592+
public void setAllowFileAccess(
593+
WebView view,
594+
@Nullable Boolean allowFileAccess) {
595+
view.getSettings().setAllowFileAccess(allowFileAccess != null && allowFileAccess);
596+
}
597+
599598
@ReactProp(name = "geolocationEnabled")
600599
public void setGeolocationEnabled(
601600
WebView view,
@@ -626,13 +625,13 @@ protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
626625
@Override
627626
public @Nullable Map<String, Integer> getCommandsMap() {
628627
return MapBuilder.of(
629-
"goBack", COMMAND_GO_BACK,
630-
"goForward", COMMAND_GO_FORWARD,
631-
"reload", COMMAND_RELOAD,
632-
"stopLoading", COMMAND_STOP_LOADING,
633-
"postMessage", COMMAND_POST_MESSAGE,
634-
"injectJavaScript", COMMAND_INJECT_JAVASCRIPT
635-
);
628+
"goBack", COMMAND_GO_BACK,
629+
"goForward", COMMAND_GO_FORWARD,
630+
"reload", COMMAND_RELOAD,
631+
"stopLoading", COMMAND_STOP_LOADING,
632+
"postMessage", COMMAND_POST_MESSAGE,
633+
"injectJavaScript", COMMAND_INJECT_JAVASCRIPT
634+
);
636635
}
637636

638637
@Override
@@ -659,13 +658,13 @@ public void receiveCommand(WebView root, int commandId, @Nullable ReadableArray
659658
"var event;" +
660659
"var data = " + eventInitDict.toString() + ";" +
661660
"try {" +
662-
"event = new MessageEvent('message', data);" +
661+
"event = new MessageEvent('message', data);" +
663662
"} catch (e) {" +
664-
"event = document.createEvent('MessageEvent');" +
665-
"event.initMessageEvent('message', true, true, data.data, data.origin, data.lastEventId, data.source);" +
663+
"event = document.createEvent('MessageEvent');" +
664+
"event.initMessageEvent('message', true, true, data.data, data.origin, data.lastEventId, data.source);" +
666665
"}" +
667666
"document.dispatchEvent(event);" +
668-
"})();");
667+
"})();");
669668
} catch (JSONException e) {
670669
throw new RuntimeException(e);
671670
}

0 commit comments

Comments
 (0)