mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-23 20:01:01 +08:00
Implement a postMessage function and an onMessage event for webviews …
Summary: JS API very similar to web workers and node's child process. Work has been done by somebody else for the Android implementation over at #7020, so we'd need to have these in sync before anything gets merged. I've made a prop `messagingEnabled` to be more explicit about creating globals—it might be sufficient to just check for an onMessage handler though.  Closes https://github.com/facebook/react-native/pull/9762 Differential Revision: D4008260 fbshipit-source-id: 84b1afafbc0ab1edc3dfbf1a8fb870218e171a4c
This commit is contained in:
committed by
Facebook Github Bot
parent
6ea26c01de
commit
abb8ea3aea
@@ -58,6 +58,7 @@ class WebView extends React.Component {
|
||||
automaticallyAdjustContentInsets: PropTypes.bool,
|
||||
contentInset: EdgeInsetsPropType,
|
||||
onNavigationStateChange: PropTypes.func,
|
||||
onMessage: PropTypes.func,
|
||||
onContentSizeChange: PropTypes.func,
|
||||
startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load
|
||||
style: View.propTypes.style,
|
||||
@@ -218,6 +219,8 @@ class WebView extends React.Component {
|
||||
userAgent={this.props.userAgent}
|
||||
javaScriptEnabled={this.props.javaScriptEnabled}
|
||||
domStorageEnabled={this.props.domStorageEnabled}
|
||||
messagingEnabled={typeof this.props.onMessage === 'function'}
|
||||
onMessage={this.onMessage}
|
||||
contentInset={this.props.contentInset}
|
||||
automaticallyAdjustContentInsets={this.props.automaticallyAdjustContentInsets}
|
||||
onContentSizeChange={this.props.onContentSizeChange}
|
||||
@@ -268,6 +271,14 @@ class WebView extends React.Component {
|
||||
);
|
||||
};
|
||||
|
||||
postMessage = (data) => {
|
||||
UIManager.dispatchViewManagerCommand(
|
||||
this.getWebViewHandle(),
|
||||
UIManager.RCTWebView.Commands.postMessage,
|
||||
[String(data)]
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* We return an event with a bunch of fields including:
|
||||
* url, title, loading, canGoBack, canGoForward
|
||||
@@ -310,9 +321,18 @@ class WebView extends React.Component {
|
||||
});
|
||||
this.updateNavigationState(event);
|
||||
};
|
||||
|
||||
onMessage = (event: Event) => {
|
||||
var {onMessage} = this.props;
|
||||
onMessage && onMessage(event);
|
||||
}
|
||||
}
|
||||
|
||||
var RCTWebView = requireNativeComponent('RCTWebView', WebView);
|
||||
var RCTWebView = requireNativeComponent('RCTWebView', WebView, {
|
||||
nativeOnly: {
|
||||
messagingEnabled: PropTypes.bool,
|
||||
},
|
||||
});
|
||||
|
||||
var styles = StyleSheet.create({
|
||||
container: {
|
||||
|
||||
@@ -235,6 +235,16 @@ class WebView extends React.Component {
|
||||
* Function that is invoked when the `WebView` loading starts or ends.
|
||||
*/
|
||||
onNavigationStateChange: PropTypes.func,
|
||||
/**
|
||||
* A function that is invoked when the webview calls `window.postMessage`.
|
||||
* Setting this property will inject a `postMessage` global into your
|
||||
* webview, but will still call pre-existing values of `postMessage`.
|
||||
*
|
||||
* `window.postMessage` accepts one argument, `data`, which will be
|
||||
* available on the event object, `event.nativeEvent.data`. `data`
|
||||
* must be a string.
|
||||
*/
|
||||
onMessage: PropTypes.func,
|
||||
/**
|
||||
* Boolean value that forces the `WebView` to show the loading view
|
||||
* on the first load.
|
||||
@@ -382,6 +392,8 @@ class WebView extends React.Component {
|
||||
source.uri = this.props.url;
|
||||
}
|
||||
|
||||
const messagingEnabled = typeof this.props.onMessage === 'function';
|
||||
|
||||
var webView =
|
||||
<RCTWebView
|
||||
ref={RCT_WEBVIEW_REF}
|
||||
@@ -397,6 +409,8 @@ class WebView extends React.Component {
|
||||
onLoadingStart={this._onLoadingStart}
|
||||
onLoadingFinish={this._onLoadingFinish}
|
||||
onLoadingError={this._onLoadingError}
|
||||
messagingEnabled={messagingEnabled}
|
||||
onMessage={this._onMessage}
|
||||
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
||||
scalesPageToFit={this.props.scalesPageToFit}
|
||||
allowsInlineMediaPlayback={this.props.allowsInlineMediaPlayback}
|
||||
@@ -457,6 +471,24 @@ class WebView extends React.Component {
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Posts a message to the web view, which will emit a `message` event.
|
||||
* Accepts one argument, `data`, which must be a string.
|
||||
*
|
||||
* In your webview, you'll need to something like the following.
|
||||
*
|
||||
* ```js
|
||||
* document.addEventListener('message', e => { document.title = e.data; });
|
||||
* ```
|
||||
*/
|
||||
postMessage = (data) => {
|
||||
UIManager.dispatchViewManagerCommand(
|
||||
this.getWebViewHandle(),
|
||||
UIManager.RCTWebView.Commands.postMessage,
|
||||
[String(data)]
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* We return an event with a bunch of fields including:
|
||||
* url, title, loading, canGoBack, canGoForward
|
||||
@@ -502,6 +534,11 @@ class WebView extends React.Component {
|
||||
});
|
||||
this._updateNavigationState(event);
|
||||
};
|
||||
|
||||
_onMessage = (event: Event) => {
|
||||
var {onMessage} = this.props;
|
||||
onMessage && onMessage(event);
|
||||
}
|
||||
}
|
||||
|
||||
var RCTWebView = requireNativeComponent('RCTWebView', WebView, {
|
||||
@@ -509,6 +546,8 @@ var RCTWebView = requireNativeComponent('RCTWebView', WebView, {
|
||||
onLoadingStart: true,
|
||||
onLoadingError: true,
|
||||
onLoadingFinish: true,
|
||||
onMessage: true,
|
||||
messagingEnabled: PropTypes.bool,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user