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
This commit is contained in:
David Vacca 2018-09-12 11:34:13 -07:00 committed by Facebook Github Bot
parent 1d2808eee8
commit 0c576ef84a
3 changed files with 56 additions and 49 deletions

View File

@ -150,6 +150,12 @@ class WebView extends React.Component {
*/
scalesPageToFit: PropTypes.bool,
/**
* Sets whether the webview allow access to file system.
* @platform android
*/
allowFileAccess: PropTypes.bool,
/**
* Sets the user-agent for this WebView. The user-agent can also be set in native using
* WebViewConfig. This prop will overwrite that config.
@ -317,6 +323,7 @@ class WebView extends React.Component {
style={webViewStyles}
source={resolveAssetSource(source)}
scalesPageToFit={this.props.scalesPageToFit}
allowFileAccess={this.props.allowFileAccess}
injectedJavaScript={this.props.injectedJavaScript}
userAgent={this.props.userAgent}
javaScriptEnabled={this.props.javaScriptEnabled}

View File

@ -436,6 +436,7 @@ exports.examples = [
backgroundColor: BGWASH,
height: 100,
}}
allowFileAccess={true}
originWhitelist={FILE_SYSTEM_ORIGIN_WHITE_LIST}
source={require('./helloworld.html')}
scalesPageToFit={true}

View File

@ -8,21 +8,8 @@
package com.facebook.react.views.webview;
import android.annotation.TargetApi;
import android.content.Context;
import com.facebook.react.uimanager.UIManagerModule;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Picture;
@ -53,6 +40,7 @@ import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.SimpleViewManager;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.ContentSizeChangeEvent;
import com.facebook.react.uimanager.events.Event;
@ -62,10 +50,14 @@ import com.facebook.react.views.webview.events.TopLoadingFinishEvent;
import com.facebook.react.views.webview.events.TopLoadingStartEvent;
import com.facebook.react.views.webview.events.TopMessageEvent;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
@ -140,10 +132,10 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
mLastLoadFailed = false;
dispatchEvent(
webView,
new TopLoadingStartEvent(
webView.getId(),
createWebViewEvent(webView, url)));
webView,
new TopLoadingStartEvent(
webView.getId(),
createWebViewEvent(webView, url)));
}
@Override
@ -153,7 +145,7 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
// url blacklisting
if (mUrlPrefixesForDefaultIntent != null && mUrlPrefixesForDefaultIntent.size() > 0) {
ArrayList<Object> urlPrefixesForDefaultIntent =
mUrlPrefixesForDefaultIntent.toArrayList();
mUrlPrefixesForDefaultIntent.toArrayList();
for (Object urlPrefix : urlPrefixesForDefaultIntent) {
if (url.startsWith((String) urlPrefix)) {
launchIntent(view.getContext(), url);
@ -196,10 +188,10 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
@Override
public void onReceivedError(
WebView webView,
int errorCode,
String description,
String failingUrl) {
WebView webView,
int errorCode,
String description,
String failingUrl) {
super.onReceivedError(webView, errorCode, description, failingUrl);
mLastLoadFailed = true;
@ -212,16 +204,16 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
eventData.putString("description", description);
dispatchEvent(
webView,
new TopLoadingErrorEvent(webView.getId(), eventData));
webView,
new TopLoadingErrorEvent(webView.getId(), eventData));
}
protected void emitFinishEvent(WebView webView, String url) {
dispatchEvent(
webView,
new TopLoadingFinishEvent(
webView.getId(),
createWebViewEvent(webView, url)));
webView,
new TopLoadingFinishEvent(
webView.getId(),
createWebViewEvent(webView, url)));
}
protected WritableMap createWebViewEvent(WebView webView, String url) {
@ -342,8 +334,8 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
public void callInjectedJavaScript() {
if (getSettings().getJavaScriptEnabled() &&
injectedJS != null &&
!TextUtils.isEmpty(injectedJS)) {
injectedJS != null &&
!TextUtils.isEmpty(injectedJS)) {
evaluateJavascriptWithFallback("(function() {\n" + injectedJS + ";\n})();");
}
}
@ -366,9 +358,9 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
evaluateJavascriptWithFallback("(" +
"window.originalPostMessage = window.postMessage," +
"window.postMessage = function(data) {" +
BRIDGE_NAME + ".postMessage(String(data));" +
BRIDGE_NAME + ".postMessage(String(data));" +
"}" +
")");
")");
}
}
@ -438,8 +430,8 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
// Fixes broken full-screen modals/galleries due to body height being 0.
webView.setLayoutParams(
new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
setGeolocationEnabled(webView, false);
if (ReactBuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
@ -511,7 +503,7 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
String html = source.getString("html");
if (source.hasKey("baseUrl")) {
view.loadDataWithBaseURL(
source.getString("baseUrl"), html, HTML_MIME_TYPE, HTML_ENCODING, null);
source.getString("baseUrl"), html, HTML_MIME_TYPE, HTML_ENCODING, null);
} else {
view.loadData(html, HTML_MIME_TYPE, HTML_ENCODING);
}
@ -588,14 +580,21 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
@ReactProp(name = "urlPrefixesForDefaultIntent")
public void setUrlPrefixesForDefaultIntent(
WebView view,
@Nullable ReadableArray urlPrefixesForDefaultIntent) {
WebView view,
@Nullable ReadableArray urlPrefixesForDefaultIntent) {
ReactWebViewClient client = ((ReactWebView) view).getReactWebViewClient();
if (client != null && urlPrefixesForDefaultIntent != null) {
client.setUrlPrefixesForDefaultIntent(urlPrefixesForDefaultIntent);
}
}
@ReactProp(name = "allowFileAccess")
public void setAllowFileAccess(
WebView view,
@Nullable Boolean allowFileAccess) {
view.getSettings().setAllowFileAccess(allowFileAccess != null && allowFileAccess);
}
@ReactProp(name = "geolocationEnabled")
public void setGeolocationEnabled(
WebView view,
@ -626,13 +625,13 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
@Override
public @Nullable Map<String, Integer> getCommandsMap() {
return MapBuilder.of(
"goBack", COMMAND_GO_BACK,
"goForward", COMMAND_GO_FORWARD,
"reload", COMMAND_RELOAD,
"stopLoading", COMMAND_STOP_LOADING,
"postMessage", COMMAND_POST_MESSAGE,
"injectJavaScript", COMMAND_INJECT_JAVASCRIPT
);
"goBack", COMMAND_GO_BACK,
"goForward", COMMAND_GO_FORWARD,
"reload", COMMAND_RELOAD,
"stopLoading", COMMAND_STOP_LOADING,
"postMessage", COMMAND_POST_MESSAGE,
"injectJavaScript", COMMAND_INJECT_JAVASCRIPT
);
}
@Override
@ -659,13 +658,13 @@ public class ReactWebViewManager extends SimpleViewManager<WebView> {
"var event;" +
"var data = " + eventInitDict.toString() + ";" +
"try {" +
"event = new MessageEvent('message', data);" +
"event = new MessageEvent('message', data);" +
"} catch (e) {" +
"event = document.createEvent('MessageEvent');" +
"event.initMessageEvent('message', true, true, data.data, data.origin, data.lastEventId, data.source);" +
"event = document.createEvent('MessageEvent');" +
"event.initMessageEvent('message', true, true, data.data, data.origin, data.lastEventId, data.source);" +
"}" +
"document.dispatchEvent(event);" +
"})();");
"})();");
} catch (JSONException e) {
throw new RuntimeException(e);
}