New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add WKWebViewIOS component #10456
Add WKWebViewIOS component #10456
Changes from 1 commit
fec3325
b5ed9cc
871bebe
316964c
81a15b5
fb8de1c
3517b9f
3900fa0
933cd8b
c6f1bb5
dcae282
920ae86
0770488
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,384 @@ | ||
/** | ||
* Copyright (c) 2013-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* The examples provided by Facebook are for non-commercial testing and | ||
* evaluation purposes only. | ||
* | ||
* Facebook reserves all rights not expressly granted. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | ||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
* FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL | ||
* FACEBOOK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | ||
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
* | ||
* @flow | ||
*/ | ||
'use strict'; | ||
|
||
var React = require('react'); | ||
var ReactNative = require('react-native'); | ||
var { | ||
StyleSheet, | ||
Text, | ||
TextInput, | ||
TouchableWithoutFeedback, | ||
TouchableOpacity, | ||
View, | ||
WKWebViewIOS | ||
} = ReactNative; | ||
|
||
var HEADER = '#3b5998'; | ||
var BGWASH = 'rgba(255,255,255,0.8)'; | ||
var DISABLED_WASH = 'rgba(255,255,255,0.25)'; | ||
|
||
var TEXT_INPUT_REF = 'urlInput'; | ||
var WEBVIEW_REF = 'webview'; | ||
var DEFAULT_URL = 'https://m.facebook.com'; | ||
|
||
class WKWebViewIOSExample extends React.Component { | ||
state = { | ||
url: DEFAULT_URL, | ||
status: 'No Page Loaded', | ||
backButtonEnabled: false, | ||
forwardButtonEnabled: false, | ||
loading: true, | ||
}; | ||
|
||
inputText = ''; | ||
|
||
handleTextInputChange = (event) => { | ||
var url = event.nativeEvent.text; | ||
if (!/^[a-zA-Z-_]+:/.test(url)) { | ||
url = 'http://' + url; | ||
} | ||
this.inputText = url; | ||
}; | ||
|
||
render() { | ||
this.inputText = this.state.url; | ||
|
||
return ( | ||
<View style={[styles.container]}> | ||
<View style={[styles.addressBarRow]}> | ||
<TouchableOpacity | ||
onPress={this.goBack} | ||
style={this.state.backButtonEnabled ? styles.navButton : styles.disabledButton}> | ||
<Text> | ||
{'<'} | ||
</Text> | ||
</TouchableOpacity> | ||
<TouchableOpacity | ||
onPress={this.goForward} | ||
style={this.state.forwardButtonEnabled ? styles.navButton : styles.disabledButton}> | ||
<Text> | ||
{'>'} | ||
</Text> | ||
</TouchableOpacity> | ||
<TextInput | ||
ref={TEXT_INPUT_REF} | ||
autoCapitalize="none" | ||
defaultValue={this.state.url} | ||
onSubmitEditing={this.onSubmitEditing} | ||
onChange={this.handleTextInputChange} | ||
clearButtonMode="while-editing" | ||
style={styles.addressBarTextInput} | ||
/> | ||
<TouchableOpacity onPress={this.pressGoButton}> | ||
<View style={styles.goButton}> | ||
<Text> | ||
Go! | ||
</Text> | ||
</View> | ||
</TouchableOpacity> | ||
</View> | ||
<WKWebViewIOS | ||
ref={WEBVIEW_REF} | ||
automaticallyAdjustContentInsets={false} | ||
style={styles.webView} | ||
source={{uri: this.state.url}} | ||
javaScriptEnabled={true} | ||
domStorageEnabled={true} | ||
decelerationRate="normal" | ||
onNavigationStateChange={this.onNavigationStateChange} | ||
onShouldStartLoadWithRequest={this.onShouldStartLoadWithRequest} | ||
startInLoadingState={true} | ||
/> | ||
<View style={styles.statusBar}> | ||
<Text style={styles.statusBarText}>{this.state.status}</Text> | ||
</View> | ||
</View> | ||
); | ||
} | ||
|
||
goBack = () => { | ||
this.refs[WEBVIEW_REF].goBack(); | ||
}; | ||
|
||
goForward = () => { | ||
this.refs[WEBVIEW_REF].goForward(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. react/no-string-refs: Using this.refs is deprecated. |
||
}; | ||
|
||
reload = () => { | ||
this.refs[WEBVIEW_REF].reload(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. react/no-string-refs: Using this.refs is deprecated. |
||
}; | ||
|
||
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, | ||
}); | ||
}; | ||
|
||
onSubmitEditing = (event) => { | ||
this.pressGoButton(); | ||
}; | ||
|
||
pressGoButton = () => { | ||
var url = this.inputText.toLowerCase(); | ||
if (url === this.state.url) { | ||
this.reload(); | ||
} else { | ||
this.setState({ | ||
url: url, | ||
}); | ||
} | ||
// dismiss keyboard | ||
this.refs[TEXT_INPUT_REF].blur(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. react/no-string-refs: Using this.refs is deprecated. |
||
}; | ||
} | ||
|
||
class Button extends React.Component { | ||
_handlePress = () => { | ||
if (this.props.enabled !== false && this.props.onPress) { | ||
this.props.onPress(); | ||
} | ||
}; | ||
|
||
render() { | ||
return ( | ||
<TouchableWithoutFeedback onPress={this._handlePress}> | ||
<View style={styles.button}> | ||
<Text>{this.props.text}</Text> | ||
</View> | ||
</TouchableWithoutFeedback> | ||
); | ||
} | ||
} | ||
|
||
class MessagingTest extends React.Component { | ||
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(): ReactElement<any> { | ||
const {messagesReceivedFromWebView, message} = this.state; | ||
|
||
return ( | ||
<View style={[styles.container, { height: 200 }]}> | ||
<View style={styles.container}> | ||
<Text>Messages received from web view: {messagesReceivedFromWebView}</Text> | ||
<Text>{message || '(No message)'}</Text> | ||
<View style={styles.buttons}> | ||
<Button text="Send Message to Web View" enabled onPress={this.postMessage} /> | ||
</View> | ||
</View> | ||
<View style={styles.container}> | ||
<WKWebViewIOS | ||
ref={webview => { this.webview = webview; }} | ||
style={{ | ||
backgroundColor: BGWASH, | ||
height: 100, | ||
}} | ||
source={require('./wkmessagingtest.html')} | ||
onMessage={this.onMessage} | ||
/> | ||
</View> | ||
</View> | ||
); | ||
} | ||
} | ||
|
||
var 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, | ||
}, | ||
spinner: { | ||
width: 20, | ||
marginRight: 6, | ||
}, | ||
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 = ` | ||
<!DOCTYPE html>\n | ||
<html> | ||
<head> | ||
<title>Hello Static World</title> | ||
<meta http-equiv="content-type" content="text/html; charset=utf-8"> | ||
<meta name="viewport" content="width=320, user-scalable=no"> | ||
<style type="text/css"> | ||
body { | ||
margin: 0; | ||
padding: 0; | ||
font: 62.5% arial, sans-serif; | ||
background: #ccc; | ||
} | ||
h1 { | ||
padding: 45px; | ||
margin: 0; | ||
text-align: center; | ||
color: #33f; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<h1>Hello Static World</h1> | ||
</body> | ||
</html> | ||
`; | ||
|
||
exports.displayName = (undefined: ?string); | ||
exports.title = '<WKWebViewIOS>'; | ||
exports.description = 'Base component to display web content'; | ||
exports.examples = [ | ||
{ | ||
title: 'Simple Browser', | ||
render(): React.Element<any> { return <WKWebViewIOSExample />; } | ||
}, | ||
{ | ||
title: 'Bundled HTML', | ||
render(): React.Element<any> { | ||
return ( | ||
<WKWebViewIOS | ||
style={{ | ||
backgroundColor: BGWASH, | ||
height: 100, | ||
}} | ||
source={require('./helloworld.html')} | ||
/> | ||
); | ||
} | ||
}, | ||
{ | ||
title: 'Static HTML', | ||
render(): React.Element<any> { | ||
return ( | ||
<WKWebViewIOS | ||
style={{ | ||
backgroundColor: BGWASH, | ||
height: 100, | ||
}} | ||
source={{html: HTML}} | ||
/> | ||
); | ||
} | ||
}, | ||
{ | ||
title: 'Mesaging Test', | ||
render(): ReactElement<any> { return <MessagingTest />; } | ||
} | ||
]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
react/no-string-refs: Using this.refs is deprecated.