diff --git a/IntegrationTests/IntegrationTestsApp.js b/IntegrationTests/IntegrationTestsApp.js
index 283669488e3..7c5f2c755b3 100644
--- a/IntegrationTests/IntegrationTestsApp.js
+++ b/IntegrationTests/IntegrationTestsApp.js
@@ -33,7 +33,6 @@ const TESTS = [
require('./ImageCachePolicyTest'),
require('./ImageSnapshotTest'),
require('./PromiseTest'),
- require('./WebViewTest'),
require('./SyncMethodTest'),
require('./WebSocketTest'),
require('./AccessibilityManagerTest'),
diff --git a/IntegrationTests/WebViewTest.js b/IntegrationTests/WebViewTest.js
deleted file mode 100644
index 269b9d24bde..00000000000
--- a/IntegrationTests/WebViewTest.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- */
-
-'use strict';
-
-const React = require('react');
-const ReactNative = require('react-native');
-const {WebView} = ReactNative;
-
-const {TestModule} = ReactNative.NativeModules;
-
-class WebViewTest extends React.Component {
- render() {
- let firstMessageReceived = false;
- let secondMessageReceived = false;
- function processMessage(e) {
- const message = e.nativeEvent.data;
- if (message === 'First') {
- firstMessageReceived = true;
- }
- if (message === 'Second') {
- secondMessageReceived = true;
- }
-
- // got both messages
- if (firstMessageReceived && secondMessageReceived) {
- TestModule.markTestPassed(true);
- }
- // wait for next message
- else if (firstMessageReceived && !secondMessageReceived) {
- return;
- }
- // first message got lost
- else if (!firstMessageReceived && secondMessageReceived) {
- throw new Error('First message got lost');
- }
- }
- const html =
- 'Hello world' +
- '';
-
- // fail if messages didn't get through;
- window.setTimeout(function() {
- throw new Error(
- firstMessageReceived
- ? 'Both messages got lost'
- : 'Second message got lost',
- );
- }, 10000);
-
- const source = {
- html: html,
- };
-
- return (
-
- );
- }
-}
-
-WebViewTest.displayName = 'WebViewTest';
-
-module.exports = WebViewTest;
diff --git a/Libraries/react-native/react-native-implementation.js b/Libraries/react-native/react-native-implementation.js
index deee26c0d53..143eb9df8fc 100644
--- a/Libraries/react-native/react-native-implementation.js
+++ b/Libraries/react-native/react-native-implementation.js
@@ -176,15 +176,6 @@ module.exports = {
get VirtualizedList() {
return require('VirtualizedList');
},
- get WebView() {
- warnOnce(
- 'webview-moved',
- 'WebView has been extracted from react-native core and will be removed in a future release. ' +
- "It can now be installed and imported from 'react-native-webview' instead of 'react-native'. " +
- 'See https://github.com/react-native-community/react-native-webview',
- );
- return require('WebView');
- },
// APIs
get ActionSheetIOS() {
@@ -390,4 +381,17 @@ if (__DEV__) {
);
},
});
+
+ // $FlowFixMe This is intentional: Flow will error when attempting to access WebView.
+ Object.defineProperty(module.exports, 'WebView', {
+ configurable: true,
+ get() {
+ invariant(
+ false,
+ 'WebView has been removed from React Native. ' +
+ "It can now be installed and imported from 'react-native-webview' instead of 'react-native'. " +
+ 'See https://github.com/react-native-community/react-native-webview',
+ );
+ },
+ });
}
diff --git a/RNTester/RNTesterIntegrationTests/RNTesterIntegrationTests.m b/RNTester/RNTesterIntegrationTests/RNTesterIntegrationTests.m
index eb8660b0cda..1fd0c0d52ee 100644
--- a/RNTester/RNTesterIntegrationTests/RNTesterIntegrationTests.m
+++ b/RNTester/RNTesterIntegrationTests/RNTesterIntegrationTests.m
@@ -75,8 +75,4 @@ RCT_TEST(PromiseTest)
RCT_TEST_ONLY_WITH_PACKAGER(WebSocketTest) // Requires a WebSocket test server, see scripts/objc-test.sh
RCT_TEST(AccessibilityManagerTest)
-#if !TARGET_OS_TV // tvOS does not fully support WebView
-RCT_TEST(WebViewTest)
-#endif
-
@end
diff --git a/RNTester/android/app/proguard-rules.pro b/RNTester/android/app/proguard-rules.pro
index 4dc17584e31..f28b70eeded 100644
--- a/RNTester/android/app/proguard-rules.pro
+++ b/RNTester/android/app/proguard-rules.pro
@@ -13,10 +13,3 @@
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
diff --git a/RNTester/js/RNTesterList.android.js b/RNTester/js/RNTesterList.android.js
index 9946ad0df62..95ff31b10cc 100644
--- a/RNTester/js/RNTesterList.android.js
+++ b/RNTester/js/RNTesterList.android.js
@@ -107,10 +107,6 @@ const ComponentExamples: Array = [
* when making Flow check .android.js files. */
module: require('./ViewPagerAndroidExample'),
},
- {
- key: 'WebViewExample',
- module: require('./WebViewExample'),
- },
];
const APIExamples: Array = [
diff --git a/RNTester/js/RNTesterList.ios.js b/RNTester/js/RNTesterList.ios.js
index 0a5557727c5..418936778fe 100644
--- a/RNTester/js/RNTesterList.ios.js
+++ b/RNTester/js/RNTesterList.ios.js
@@ -158,11 +158,6 @@ const ComponentExamples: Array = [
module: require('./ViewExample'),
supportsTVOS: true,
},
- {
- key: 'WebViewExample',
- module: require('./WebViewExample'),
- supportsTVOS: false,
- },
];
const APIExamples: Array = [
diff --git a/RNTester/js/WebViewExample.js b/RNTester/js/WebViewExample.js
deleted file mode 100644
index f973d816210..00000000000
--- a/RNTester/js/WebViewExample.js
+++ /dev/null
@@ -1,489 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- * @flow
- */
-
-'use strict';
-
-const React = require('react');
-const ReactNative = require('react-native');
-const {
- StyleSheet,
- Text,
- TextInput,
- TouchableWithoutFeedback,
- TouchableOpacity,
- View,
- WebView,
-} = ReactNative;
-
-const HEADER = '#3b5998';
-const BGWASH = 'rgba(255,255,255,0.8)';
-const DISABLED_WASH = 'rgba(255,255,255,0.25)';
-
-const TEXT_INPUT_REF = 'urlInput';
-const WEBVIEW_REF = 'webview';
-const DEFAULT_URL = 'https://m.facebook.com';
-const FILE_SYSTEM_ORIGIN_WHITE_LIST = ['file://*', 'http://*', 'https://*'];
-
-class WebViewExample extends React.Component<{}, $FlowFixMeState> {
- state = {
- url: DEFAULT_URL,
- status: 'No Page Loaded',
- backButtonEnabled: false,
- forwardButtonEnabled: false,
- loading: true,
- scalesPageToFit: true,
- };
-
- inputText = '';
-
- handleTextInputChange = event => {
- let url = event.nativeEvent.text;
- if (!/^[a-zA-Z-_]+:/.test(url)) {
- url = 'http://' + url;
- }
- this.inputText = url;
- };
-
- render() {
- this.inputText = this.state.url;
-
- return (
-
-
-
- {'<'}
-
-
- {'>'}
-
-
-
-
- Go!
-
-
-
-
-
- {this.state.status}
-
-
- );
- }
-
- goBack = () => {
- this.refs[WEBVIEW_REF].goBack();
- };
-
- goForward = () => {
- this.refs[WEBVIEW_REF].goForward();
- };
-
- reload = () => {
- this.refs[WEBVIEW_REF].reload();
- };
-
- onShouldStartLoadWithRequest = event => {
- // Implement any custom loading logic here, don't forget to return!
- return true;
- };
-
- onNavigationStateChange = navState => {
- this.setState({
- backButtonEnabled: navState.canGoBack,
- forwardButtonEnabled: navState.canGoForward,
- url: navState.url,
- status: navState.title,
- loading: navState.loading,
- scalesPageToFit: true,
- });
- };
-
- onSubmitEditing = event => {
- this.pressGoButton();
- };
-
- pressGoButton = () => {
- const url = this.inputText.toLowerCase();
- if (url === this.state.url) {
- this.reload();
- } else {
- this.setState({
- url: url,
- });
- }
- // dismiss keyboard
- this.refs[TEXT_INPUT_REF].blur();
- };
-}
-
-class Button extends React.Component<$FlowFixMeProps> {
- _handlePress = () => {
- if (this.props.enabled !== false && this.props.onPress) {
- this.props.onPress();
- }
- };
-
- render() {
- return (
-
-
- {this.props.text}
-
-
- );
- }
-}
-
-class ScaledWebView extends React.Component<{}, $FlowFixMeState> {
- state = {
- scalingEnabled: true,
- };
-
- render() {
- return (
-
-
-
- {this.state.scalingEnabled ? (
-
-
- );
- }
-}
-
-class MessagingTest extends React.Component<{}, $FlowFixMeState> {
- webview = null;
-
- state = {
- messagesReceivedFromWebView: 0,
- message: '',
- };
-
- onMessage = e =>
- this.setState({
- messagesReceivedFromWebView: this.state.messagesReceivedFromWebView + 1,
- message: e.nativeEvent.data,
- });
-
- postMessage = () => {
- if (this.webview) {
- this.webview.postMessage('"Hello" from React Native!');
- }
- };
-
- render(): React.Node {
- const {messagesReceivedFromWebView, message} = this.state;
-
- return (
-
-
-
- Messages received from web view: {messagesReceivedFromWebView}
-
- {message || '(No message)'}
-
-
-
-
-
- {
- this.webview = webview;
- }}
- style={{
- backgroundColor: BGWASH,
- height: 100,
- }}
- originWhitelist={FILE_SYSTEM_ORIGIN_WHITE_LIST}
- source={require('./messagingtest.html')}
- onMessage={this.onMessage}
- />
-
-
- );
- }
-}
-
-class InjectJS extends React.Component<{}> {
- webview = null;
- injectJS = () => {
- const script = 'document.write("Injected JS ")';
- if (this.webview) {
- this.webview.injectJavaScript(script);
- }
- };
- render() {
- return (
-
- {
- this.webview = webview;
- }}
- style={{
- backgroundColor: BGWASH,
- height: 300,
- }}
- source={{uri: 'https://www.facebook.com'}}
- scalesPageToFit={true}
- />
-
-
-
-
- );
- }
-}
-
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- backgroundColor: HEADER,
- },
- addressBarRow: {
- flexDirection: 'row',
- padding: 8,
- },
- webView: {
- backgroundColor: BGWASH,
- height: 350,
- },
- addressBarTextInput: {
- backgroundColor: BGWASH,
- borderColor: 'transparent',
- borderRadius: 3,
- borderWidth: 1,
- height: 24,
- paddingLeft: 10,
- paddingTop: 3,
- paddingBottom: 3,
- flex: 1,
- fontSize: 14,
- },
- navButton: {
- width: 20,
- padding: 3,
- marginRight: 3,
- alignItems: 'center',
- justifyContent: 'center',
- backgroundColor: BGWASH,
- borderColor: 'transparent',
- borderRadius: 3,
- },
- disabledButton: {
- width: 20,
- padding: 3,
- marginRight: 3,
- alignItems: 'center',
- justifyContent: 'center',
- backgroundColor: DISABLED_WASH,
- borderColor: 'transparent',
- borderRadius: 3,
- },
- goButton: {
- height: 24,
- padding: 3,
- marginLeft: 8,
- alignItems: 'center',
- backgroundColor: BGWASH,
- borderColor: 'transparent',
- borderRadius: 3,
- alignSelf: 'stretch',
- },
- statusBar: {
- flexDirection: 'row',
- alignItems: 'center',
- paddingLeft: 5,
- height: 22,
- },
- statusBarText: {
- color: 'white',
- fontSize: 13,
- },
- buttons: {
- flexDirection: 'row',
- height: 30,
- backgroundColor: 'black',
- alignItems: 'center',
- justifyContent: 'space-between',
- },
- button: {
- flex: 0.5,
- width: 0,
- margin: 5,
- borderColor: 'gray',
- borderWidth: 1,
- backgroundColor: 'gray',
- },
-});
-
-const HTML = `
-\n
-
-
- Hello Static World
-
-
-
-
-
- Hello Static World
-
-
-`;
-
-exports.displayName = (undefined: ?string);
-exports.title = '';
-exports.description = 'Base component to display web content';
-exports.examples = [
- {
- title: 'Simple Browser',
- render(): React.Element {
- return ;
- },
- },
- {
- title: 'Scale Page to Fit',
- render(): React.Element {
- return ;
- },
- },
- {
- title: 'Bundled HTML',
- render(): React.Element {
- return (
-
- );
- },
- },
- {
- title: 'Static HTML',
- render(): React.Element {
- return (
-
- );
- },
- },
- {
- title: 'POST Test',
- render(): React.Element {
- return (
-
- );
- },
- },
- {
- title: 'Messaging Test',
- render(): React.Element {
- return ;
- },
- },
- {
- title: 'Inject JavaScript',
- render(): React.Element {
- return ;
- },
- },
-];
diff --git a/RNTester/js/XHRExample.js b/RNTester/js/XHRExample.js
index 789a08a80ac..78f925e7da1 100644
--- a/RNTester/js/XHRExample.js
+++ b/RNTester/js/XHRExample.js
@@ -18,7 +18,6 @@ const XHRExampleFormData = require('./XHRExampleFormData');
const XHRExampleHeaders = require('./XHRExampleHeaders');
const XHRExampleFetch = require('./XHRExampleFetch');
const XHRExampleOnTimeOut = require('./XHRExampleOnTimeOut');
-const XHRExampleCookies = require('./XHRExampleCookies');
exports.framework = 'React';
exports.title = 'XMLHttpRequest';
@@ -62,10 +61,4 @@ exports.examples = [
return ;
},
},
- {
- title: 'Cookies',
- render() {
- return ;
- },
- },
];
diff --git a/RNTester/js/XHRExampleCookies.js b/RNTester/js/XHRExampleCookies.js
deleted file mode 100644
index 0d835f3901c..00000000000
--- a/RNTester/js/XHRExampleCookies.js
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- * @flow
- */
-
-'use strict';
-
-const React = require('react');
-const ReactNative = require('react-native');
-const {StyleSheet, Text, TouchableHighlight, View, WebView} = ReactNative;
-
-const RCTNetworking = require('RCTNetworking');
-
-class XHRExampleCookies extends React.Component {
- cancelled: boolean;
-
- constructor(props: any) {
- super(props);
- this.cancelled = false;
- this.state = {
- status: '',
- a: 1,
- b: 2,
- };
- }
-
- setCookie(domain: string) {
- const {a, b} = this.state;
- const url = `https://${domain}/cookies/set?a=${a}&b=${b}`;
- fetch(url).then(response => {
- this.setStatus(`Cookies a=${a}, b=${b} set`);
- this.refreshWebview();
- });
-
- this.setState({
- status: 'Setting cookies...',
- a: a + 1,
- b: b + 2,
- });
- }
-
- getCookies(domain: string) {
- fetch(`https://${domain}/cookies`)
- .then(response => {
- return response.json();
- })
- .then(data => {
- this.setStatus(
- `Got cookies ${JSON.stringify(data.cookies)} from server`,
- );
- this.refreshWebview();
- });
-
- this.setStatus('Getting cookies...');
- }
-
- clearCookies() {
- RCTNetworking.clearCookies(cleared => {
- this.setStatus('Cookies cleared, had cookies=' + cleared.toString());
- this.refreshWebview();
- });
- }
-
- refreshWebview() {
- this.refs.webview.reload();
- }
-
- setStatus(status: string) {
- this.setState({status});
- }
-
- render() {
- return (
-
-
-
- Set cookie
-
-
-
-
- Set cookie (EU)
-
-
-
-
- Get cookies
-
-
-
-
- Get cookies (EU)
-
-
-
-
- Clear cookies
-
-
- {this.state.status}
-
-
- Refresh Webview
-
-
-
-
- );
- }
-}
-
-const styles = StyleSheet.create({
- wrapper: {
- borderRadius: 5,
- marginBottom: 5,
- },
- button: {
- backgroundColor: '#eeeeee',
- padding: 8,
- },
-});
-
-module.exports = XHRExampleCookies;
diff --git a/ReactAndroid/proguard-rules.pro b/ReactAndroid/proguard-rules.pro
index c4a0ab71587..67e7aa1ccb9 100644
--- a/ReactAndroid/proguard-rules.pro
+++ b/ReactAndroid/proguard-rules.pro
@@ -14,13 +14,6 @@
# Add any project specific keep options here:
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}
-
# Disabling obfuscation is useful if you collect stack traces from production crashes
# (unless you are using a system that supports de-obfuscate the stack traces).
# -dontobfuscate
diff --git a/template/android/app/proguard-rules.pro b/template/android/app/proguard-rules.pro
index a92fa177ee4..11b025724a3 100644
--- a/template/android/app/proguard-rules.pro
+++ b/template/android/app/proguard-rules.pro
@@ -8,10 +8,3 @@
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-# public *;
-#}