| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 | 
							- 'use strict'
 - 
 - import React, {
 -     Component,
 -     PropTypes
 - } from 'react';
 - 
 - import {
 -     findNodeHandle,
 -     requireNativeComponent,
 -     DeviceEventEmitter,
 -     Dimensions,
 -     Platform,
 -     UIManager,
 -     View,
 -     WebView
 - } from 'react-native';
 - 
 - import ImmutableComponent from 'react-immutable-component';
 - 
 - const RCTAutoHeightWebView = requireNativeComponent('RCTAutoHeightWebView', AutoHeightWebView, { nativeOnly: { messagingEnabled: PropTypes.bool } });
 - 
 - export default class AutoHeightWebView extends ImmutableComponent {
 -     constructor(props) {
 -         super(props);
 -         this.onMessage = this.onMessage.bind(this);
 -         if (IsBelowKitKat) {
 -             this.listenWebViewBridgeMessage = this.listenWebViewBridgeMessage.bind(this);
 -         }
 -         const initialScript = props.files ? this.appendFilesToHead(props.files, BaseScript) : BaseScript;
 -         this.state = {
 -             isChangingSource: false,
 -             height: 0,
 -             heightOffset: 0,
 -             script: initialScript
 -         };
 -     }
 - 
 -     componentWillMount() {
 -         if (IsBelowKitKat) {
 -             DeviceEventEmitter.addListener("webViewBridgeMessage", this.listenWebViewBridgeMessage);
 -         }
 -     }
 - 
 -     componentDidMount() {
 -         this.startInterval();
 -     }
 - 
 -     componentWillReceiveProps(nextProps) {
 -         // injectedJavaScript only works when webview reload (html changed)
 -         if (nextProps.html === this.props.html) {
 -             this.htmlHasChanged = false;
 -             return;
 -         }
 -         else {
 -             this.setState({
 -                 isChangingSource: true,
 -                 height: 0,
 -                 heightOffset: 0
 -             });
 -         }
 -         let currentScript = BaseScript;
 -         if (nextProps.files) {
 -             currentScript = this.appendFilesToHead(nextProps.files, BaseScript);
 -         }
 -         this.setState({ script: currentScript });
 -     }
 - 
 -     componentDidUpdate(prevProps, prevState) {
 -         // redisplay webview when changing source
 -         if (this.state.isChangingSource) {
 -             this.startInterval();
 -             this.setState({ isChangingSource: false });
 -         }
 -     }
 - 
 -     componentWillUnmount() {
 -         this.stopInterval();
 -         if (IsBelowKitKat) {
 -             DeviceEventEmitter.removeListener("webViewBridgeMessage", this.listenWebViewBridgeMessage);
 -         }
 -     }
 - 
 -     // below kitkat
 -     listenWebViewBridgeMessage(body) {
 -         this.onMessage(body.message);
 -     }
 - 
 -     postMessage(data) {
 -         UIManager.dispatchViewManagerCommand(
 -             findNodeHandle(this.webview),
 -             UIManager.RCTAutoHeightWebView.Commands.postMessage,
 -             [String(data)]
 -         );
 -     };
 - 
 -     // below kitkat
 -     sendToWebView(message) {
 -         UIManager.dispatchViewManagerCommand(
 -             findNodeHandle(this.webview),
 -             UIManager.RCTAutoHeightWebView.Commands.sendToWebView,
 -             [String(message)]
 -         );
 -     }
 - 
 -     startInterval() {
 -         this.finishInterval = false;
 -         this.interval = setInterval(() => {
 -             if (!this.finishInterval) {
 -                 IsBelowKitKat ? this.sendToWebView('getBodyHeight') : this.postMessage('getBodyHeight');
 -             }
 -         }, 205);
 -     }
 - 
 -     stopInterval() {
 -         this.finishInterval = true;
 -         clearInterval(this.interval);
 -     }
 - 
 -     onMessage(e) {
 -         const height = parseInt(IsBelowKitKat ? e.nativeEvent.message : e.nativeEvent.data);
 -         if (height) {
 -             this.stopInterval();
 -             this.setState({
 -                 heightOffset: this.props.heightOffset,
 -                 height
 -             });
 -             if (this.props.onHeightUpdated) {
 -                 this.props.onHeightUpdated(height);
 -             }
 -         }
 -     }
 - 
 -     appendFilesToHead(files, script) {
 -         if (!files) {
 -             return script;
 -         }
 -         for (let file of files) {
 -             script =
 -                 `
 -                 var link  = document.createElement('link');
 -                 link.rel  = '` + file.rel + `';
 -                 link.type = '` + file.type + `';
 -                 link.href = '` + file.href + `';
 -                 document.head.appendChild(link);
 -                 `+ script;
 -         }
 -         return script;
 -     }
 - 
 -     render() {
 -         const source = this.props.enableBaseUrl ? {
 -             html: this.props.html,
 -             baseUrl: 'file:///android_asset/web/'
 -         } : { html: this.props.html };
 -         return (
 -             <View style={[{
 -                 width: ScreenWidth,
 -                 height: this.state.height + this.state.heightOffset
 -             }, this.props.style]}>
 -                 {
 -                     this.state.isChangingSource ? null :
 -                         <RCTAutoHeightWebView
 -                             ref={webview => this.webview = webview}
 -                             style={{ flex: 1 }}
 -                             javaScriptEnabled={true}
 -                             injectedJavaScript={this.state.script + this.props.customScript}
 -                             scrollEnabled={false}
 -                             source={source}
 -                             // below kitkat
 -                             onChange={this.onMessage}
 -                             onMessage={this.onMessage}
 -                             messagingEnabled={true} />
 -                 }
 -             </View>
 -         );
 -     }
 - }
 - 
 - AutoHeightWebView.propTypes = {
 -     ...WebView.propTypes,
 -     html: PropTypes.string,
 -     onHeightUpdated: PropTypes.func,
 -     customScript: PropTypes.string,
 -     // offset rn webview margin
 -     heightOffset: PropTypes.number,
 -     // baseUrl not work in android 4.3 or below version
 -     enableBaseUrl: PropTypes.bool,
 -     // works if set enableBaseUrl to true; add web/files... to android/app/src/assets/
 -     files: PropTypes.arrayOf(PropTypes.shape({
 -         href: PropTypes.string,
 -         type: PropTypes.string,
 -         rel: PropTypes.string
 -     }))
 - }
 - 
 - AutoHeightWebView.defaultProps = {
 -     enableBaseUrl: false,
 -     heightOffset: 20
 - }
 - 
 - const ScreenWidth = Dimensions.get('window').width;
 - 
 - const IsBelowKitKat = Platform.Version < 19;
 - 
 - const BaseScript =
 -     IsBelowKitKat ?
 -         `
 -     (function () {
 -         AutoHeightWebView.onMessage = function (message) {
 -             AutoHeightWebView.send(String(document.body.offsetHeight));
 -         };
 -     } ()); 
 -     ` :
 -         `
 -     ; (function () {
 -         document.addEventListener('message', function (e) {
 -             window.postMessage(String(document.body.offsetHeight));
 -         });
 -     } ()); 
 -     `;
 
 
  |