|  | @@ -1,180 +1,143 @@
 | 
	
		
			
			| 1 |  | -'use strict'
 | 
	
		
			
			|  | 1 | +'use strict';
 | 
	
		
			
			| 2 | 2 |  
 | 
	
		
			
			| 3 | 3 |  import React, { PureComponent } from 'react';
 | 
	
		
			
			| 4 | 4 |  
 | 
	
		
			
			| 5 |  | -import {
 | 
	
		
			
			| 6 |  | -    Animated,
 | 
	
		
			
			| 7 |  | -    Dimensions,
 | 
	
		
			
			| 8 |  | -    StyleSheet,
 | 
	
		
			
			| 9 |  | -    View,
 | 
	
		
			
			| 10 |  | -    ViewPropTypes,
 | 
	
		
			
			| 11 |  | -    WebView
 | 
	
		
			
			| 12 |  | -} from 'react-native';
 | 
	
		
			
			|  | 5 | +import { Animated, Dimensions, StyleSheet, View, ViewPropTypes, WebView } from 'react-native';
 | 
	
		
			
			| 13 | 6 |  
 | 
	
		
			
			| 14 | 7 |  import PropTypes from 'prop-types';
 | 
	
		
			
			| 15 | 8 |  
 | 
	
		
			
			| 16 |  | -export default class AutoHeightWebView extends PureComponent {
 | 
	
		
			
			| 17 |  | -    static propTypes = {
 | 
	
		
			
			| 18 |  | -        hasIframe: PropTypes.bool,
 | 
	
		
			
			| 19 |  | -        source: WebView.propTypes.source,
 | 
	
		
			
			| 20 |  | -        onHeightUpdated: PropTypes.func,
 | 
	
		
			
			| 21 |  | -        customScript: PropTypes.string,
 | 
	
		
			
			| 22 |  | -        customStyle: PropTypes.string,
 | 
	
		
			
			| 23 |  | -        enableAnimation: PropTypes.bool,
 | 
	
		
			
			| 24 |  | -        // if set to true may cause some layout issues (smaller font size)
 | 
	
		
			
			| 25 |  | -        scalesPageToFit: PropTypes.bool,
 | 
	
		
			
			| 26 |  | -        // only works on enable animation
 | 
	
		
			
			| 27 |  | -        animationDuration: PropTypes.number,
 | 
	
		
			
			| 28 |  | -        // offset of rn webview margin
 | 
	
		
			
			| 29 |  | -        heightOffset: PropTypes.number,
 | 
	
		
			
			| 30 |  | -        style: ViewPropTypes.style,
 | 
	
		
			
			| 31 |  | -        //  rn WebView callback
 | 
	
		
			
			| 32 |  | -        onError: PropTypes.func,
 | 
	
		
			
			| 33 |  | -        onLoad: PropTypes.func,
 | 
	
		
			
			| 34 |  | -        onLoadStart: PropTypes.func,
 | 
	
		
			
			| 35 |  | -        onLoadEnd: PropTypes.func,
 | 
	
		
			
			| 36 |  | -        onShouldStartLoadWithRequest: PropTypes.func,
 | 
	
		
			
			| 37 |  | -        // add web/files... to project root
 | 
	
		
			
			| 38 |  | -        files: PropTypes.arrayOf(PropTypes.shape({
 | 
	
		
			
			| 39 |  | -            href: PropTypes.string,
 | 
	
		
			
			| 40 |  | -            type: PropTypes.string,
 | 
	
		
			
			| 41 |  | -            rel: PropTypes.string
 | 
	
		
			
			| 42 |  | -        }))
 | 
	
		
			
			| 43 |  | -    }
 | 
	
		
			
			| 44 |  | -
 | 
	
		
			
			| 45 |  | -    static defaultProps = {
 | 
	
		
			
			| 46 |  | -        scalesPageToFit: false,
 | 
	
		
			
			| 47 |  | -        enableAnimation: true,
 | 
	
		
			
			| 48 |  | -        animationDuration: 555,
 | 
	
		
			
			| 49 |  | -        heightOffset: 12
 | 
	
		
			
			| 50 |  | -    }
 | 
	
		
			
			| 51 |  | -
 | 
	
		
			
			| 52 |  | -    constructor(props) {
 | 
	
		
			
			| 53 |  | -        super(props);
 | 
	
		
			
			| 54 |  | -        this.handleNavigationStateChange = this.handleNavigationStateChange.bind(this);
 | 
	
		
			
			| 55 |  | -        if (this.props.enableAnimation) {
 | 
	
		
			
			| 56 |  | -            this.opacityAnimatedValue = new Animated.Value(0);
 | 
	
		
			
			| 57 |  | -        }
 | 
	
		
			
			| 58 |  | -        let initialScript = props.hasIframe ? IframeBaseScript : BaseScript;
 | 
	
		
			
			| 59 |  | -        initialScript = props.files
 | 
	
		
			
			| 60 |  | -          ? this.appendFilesToHead(props.files, BaseScript)
 | 
	
		
			
			| 61 |  | -          : BaseScript;
 | 
	
		
			
			| 62 |  | -        initialScript = props.customStyle
 | 
	
		
			
			| 63 |  | -          ? this.appendStylesToHead(props.customStyle, initialScript)
 | 
	
		
			
			| 64 |  | -          : initialScript;
 | 
	
		
			
			| 65 |  | -        this.state = {
 | 
	
		
			
			| 66 |  | -            height: 0,
 | 
	
		
			
			| 67 |  | -            script: initialScript
 | 
	
		
			
			| 68 |  | -        };
 | 
	
		
			
			| 69 |  | -    }
 | 
	
		
			
			| 70 |  | -
 | 
	
		
			
			| 71 |  | -    componentWillReceiveProps(nextProps) {
 | 
	
		
			
			| 72 |  | -        let currentScript = nextProps.hasIframe ? IframeBaseScript : BaseScript;
 | 
	
		
			
			| 73 |  | -        if (nextProps.files) {
 | 
	
		
			
			| 74 |  | -            currentScript = this.appendFilesToHead(nextProps.files, currentScript);
 | 
	
		
			
			| 75 |  | -        }
 | 
	
		
			
			| 76 |  | -        currentScript = nextProps.customStyle
 | 
	
		
			
			| 77 |  | -          ? this.appendStylesToHead(nextProps.customStyle, currentScript)
 | 
	
		
			
			| 78 |  | -          : currentScript;
 | 
	
		
			
			| 79 |  | -        this.setState({ script: currentScript });
 | 
	
		
			
			| 80 |  | -    }
 | 
	
		
			
			| 81 |  | -
 | 
	
		
			
			| 82 |  | -    appendFilesToHead(files, script) {
 | 
	
		
			
			| 83 |  | -        if (!files) {
 | 
	
		
			
			| 84 |  | -            return script;
 | 
	
		
			
			| 85 |  | -        }
 | 
	
		
			
			| 86 |  | -        return files.reduceRight((file, combinedScript) => `
 | 
	
		
			
			| 87 |  | -          var link  = document.createElement('link');
 | 
	
		
			
			| 88 |  | -          link.rel  = '${file.rel}';
 | 
	
		
			
			| 89 |  | -          link.type = '${file.type}';
 | 
	
		
			
			| 90 |  | -          link.href = '${file.href}';
 | 
	
		
			
			| 91 |  | -          document.head.appendChild(link);
 | 
	
		
			
			| 92 |  | -          ${combinedScript}
 | 
	
		
			
			| 93 |  | -        `, script);
 | 
	
		
			
			| 94 |  | -    }
 | 
	
		
			
			|  | 9 | +import { getScript, onHeightUpdated, DomMutationObserveScript } from './common.js';
 | 
	
		
			
			| 95 | 10 |  
 | 
	
		
			
			| 96 |  | -    appendStylesToHead(styles, script) {
 | 
	
		
			
			| 97 |  | -      if (!styles) {
 | 
	
		
			
			| 98 |  | -        return script;
 | 
	
		
			
			|  | 11 | +export default class AutoHeightWebView extends PureComponent {
 | 
	
		
			
			|  | 12 | +  static propTypes = {
 | 
	
		
			
			|  | 13 | +    hasIframe: PropTypes.bool,
 | 
	
		
			
			|  | 14 | +    source: WebView.propTypes.source,
 | 
	
		
			
			|  | 15 | +    onHeightUpdated: PropTypes.func,
 | 
	
		
			
			|  | 16 | +    customScript: PropTypes.string,
 | 
	
		
			
			|  | 17 | +    customStyle: PropTypes.string,
 | 
	
		
			
			|  | 18 | +    enableAnimation: PropTypes.bool,
 | 
	
		
			
			|  | 19 | +    // if set to true may cause some layout issues (smaller font size)
 | 
	
		
			
			|  | 20 | +    scalesPageToFit: PropTypes.bool,
 | 
	
		
			
			|  | 21 | +    // only works on enable animation
 | 
	
		
			
			|  | 22 | +    animationDuration: PropTypes.number,
 | 
	
		
			
			|  | 23 | +    // offset of rn webview margin
 | 
	
		
			
			|  | 24 | +    heightOffset: PropTypes.number,
 | 
	
		
			
			|  | 25 | +    style: ViewPropTypes.style,
 | 
	
		
			
			|  | 26 | +    //  rn WebView callback
 | 
	
		
			
			|  | 27 | +    onError: PropTypes.func,
 | 
	
		
			
			|  | 28 | +    onLoad: PropTypes.func,
 | 
	
		
			
			|  | 29 | +    onLoadStart: PropTypes.func,
 | 
	
		
			
			|  | 30 | +    onLoadEnd: PropTypes.func,
 | 
	
		
			
			|  | 31 | +    onShouldStartLoadWithRequest: PropTypes.func,
 | 
	
		
			
			|  | 32 | +    // add web/files... to project root
 | 
	
		
			
			|  | 33 | +    files: PropTypes.arrayOf(
 | 
	
		
			
			|  | 34 | +      PropTypes.shape({
 | 
	
		
			
			|  | 35 | +        href: PropTypes.string,
 | 
	
		
			
			|  | 36 | +        type: PropTypes.string,
 | 
	
		
			
			|  | 37 | +        rel: PropTypes.string
 | 
	
		
			
			|  | 38 | +      })
 | 
	
		
			
			|  | 39 | +    )
 | 
	
		
			
			|  | 40 | +  };
 | 
	
		
			
			|  | 41 | +
 | 
	
		
			
			|  | 42 | +  static defaultProps = {
 | 
	
		
			
			|  | 43 | +    scalesPageToFit: false,
 | 
	
		
			
			|  | 44 | +    enableAnimation: true,
 | 
	
		
			
			|  | 45 | +    animationDuration: 555,
 | 
	
		
			
			|  | 46 | +    heightOffset: 12
 | 
	
		
			
			|  | 47 | +  };
 | 
	
		
			
			|  | 48 | +
 | 
	
		
			
			|  | 49 | +  constructor(props) {
 | 
	
		
			
			|  | 50 | +    super(props);
 | 
	
		
			
			|  | 51 | +    props.enableAnimation && (this.opacityAnimatedValue = new Animated.Value(0));
 | 
	
		
			
			|  | 52 | +    this.state = {
 | 
	
		
			
			|  | 53 | +      height: 0,
 | 
	
		
			
			|  | 54 | +      script: getScript(props, BaseScript, IframeBaseScript)
 | 
	
		
			
			|  | 55 | +    };
 | 
	
		
			
			|  | 56 | +  }
 | 
	
		
			
			|  | 57 | +
 | 
	
		
			
			|  | 58 | +  componentWillReceiveProps(nextProps) {
 | 
	
		
			
			|  | 59 | +    this.setState({ script: getScript(nextProps, BaseScript, IframeBaseScript) });
 | 
	
		
			
			|  | 60 | +  }
 | 
	
		
			
			|  | 61 | +
 | 
	
		
			
			|  | 62 | +  handleNavigationStateChange = navState => {
 | 
	
		
			
			|  | 63 | +    const height = Number(navState.title);
 | 
	
		
			
			|  | 64 | +    const { enableAnimation, animationDuration } = this.props;
 | 
	
		
			
			|  | 65 | +    if (height && height !== this.state.height) {
 | 
	
		
			
			|  | 66 | +      if (enableAnimation) {
 | 
	
		
			
			|  | 67 | +        this.opacityAnimatedValue.setValue(0);
 | 
	
		
			
			| 99 | 68 |        }
 | 
	
		
			
			| 100 |  | -      // Escape any single quotes or newlines in the CSS with .replace()
 | 
	
		
			
			| 101 |  | -      const escaped = styles.replace(/\'/g, "\\'").replace(/\n/g, '\\n')
 | 
	
		
			
			| 102 |  | -      return `
 | 
	
		
			
			| 103 |  | -        var styleElement = document.createElement('style');
 | 
	
		
			
			| 104 |  | -        var styleText = document.createTextNode('${escaped}');
 | 
	
		
			
			| 105 |  | -        styleElement.appendChild(styleText);
 | 
	
		
			
			| 106 |  | -        document.head.appendChild(styleElement);
 | 
	
		
			
			| 107 |  | -        ${script}
 | 
	
		
			
			| 108 |  | -      `;
 | 
	
		
			
			| 109 |  | -    }
 | 
	
		
			
			| 110 |  | -
 | 
	
		
			
			| 111 |  | -    onHeightUpdated(height) {
 | 
	
		
			
			| 112 |  | -        if (this.props.onHeightUpdated) {
 | 
	
		
			
			| 113 |  | -            this.props.onHeightUpdated(height);
 | 
	
		
			
			| 114 |  | -        }
 | 
	
		
			
			| 115 |  | -    }
 | 
	
		
			
			| 116 |  | -
 | 
	
		
			
			| 117 |  | -    handleNavigationStateChange(navState) {
 | 
	
		
			
			| 118 |  | -        const height = Number(navState.title);
 | 
	
		
			
			| 119 |  | -        if (height && height !== this.state.height) {
 | 
	
		
			
			| 120 |  | -            if (this.props.enableAnimation) {
 | 
	
		
			
			| 121 |  | -                this.opacityAnimatedValue.setValue(0);
 | 
	
		
			
			| 122 |  | -            }
 | 
	
		
			
			| 123 |  | -            this.setState({ height }, () => {
 | 
	
		
			
			| 124 |  | -                if (this.props.enableAnimation) {
 | 
	
		
			
			| 125 |  | -                    Animated.timing(this.opacityAnimatedValue, {
 | 
	
		
			
			| 126 |  | -                        toValue: 1,
 | 
	
		
			
			| 127 |  | -                        duration: this.props.animationDuration
 | 
	
		
			
			| 128 |  | -                    }).start(() => this.onHeightUpdated(height));
 | 
	
		
			
			| 129 |  | -                }
 | 
	
		
			
			| 130 |  | -                else {
 | 
	
		
			
			| 131 |  | -                    this.onHeightUpdated(height);
 | 
	
		
			
			| 132 |  | -                }
 | 
	
		
			
			| 133 |  | -            });
 | 
	
		
			
			|  | 69 | +      this.setState({ height }, () => {
 | 
	
		
			
			|  | 70 | +        if (enableAnimation) {
 | 
	
		
			
			|  | 71 | +          Animated.timing(this.opacityAnimatedValue, {
 | 
	
		
			
			|  | 72 | +            toValue: 1,
 | 
	
		
			
			|  | 73 | +            duration: animationDuration
 | 
	
		
			
			|  | 74 | +          }).start(() => this.onHeightUpdated(height, this.props));
 | 
	
		
			
			|  | 75 | +        } else {
 | 
	
		
			
			|  | 76 | +          this.onHeightUpdated(height, this.props);
 | 
	
		
			
			| 134 | 77 |          }
 | 
	
		
			
			|  | 78 | +      });
 | 
	
		
			
			| 135 | 79 |      }
 | 
	
		
			
			| 136 |  | -
 | 
	
		
			
			| 137 |  | -    render() {
 | 
	
		
			
			| 138 |  | -        const { height, script } = this.state;
 | 
	
		
			
			| 139 |  | -        const { onError, onLoad, onLoadStart, onLoadEnd, onShouldStartLoadWithRequest, scalesPageToFit, enableAnimation, source, heightOffset, customScript, style } = this.props;
 | 
	
		
			
			| 140 |  | -        const webViewSource = Object.assign({}, source, { baseUrl: 'web/' });
 | 
	
		
			
			| 141 |  | -        return (
 | 
	
		
			
			| 142 |  | -            <Animated.View style={[Styles.container, {
 | 
	
		
			
			| 143 |  | -                opacity: enableAnimation ? this.opacityAnimatedValue : 1,
 | 
	
		
			
			| 144 |  | -                height: height + heightOffset,
 | 
	
		
			
			| 145 |  | -            }, style]}>
 | 
	
		
			
			| 146 |  | -                <WebView
 | 
	
		
			
			| 147 |  | -                    onError={onError}
 | 
	
		
			
			| 148 |  | -                    onLoad={onLoad}
 | 
	
		
			
			| 149 |  | -                    onLoadStart={onLoadStart}
 | 
	
		
			
			| 150 |  | -                    onLoadEnd={onLoadEnd}
 | 
	
		
			
			| 151 |  | -                    onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
 | 
	
		
			
			| 152 |  | -                    style={Styles.webView}
 | 
	
		
			
			| 153 |  | -                    injectedJavaScript={script + customScript}
 | 
	
		
			
			| 154 |  | -                    scrollEnabled={false}
 | 
	
		
			
			| 155 |  | -                    scalesPageToFit={scalesPageToFit}
 | 
	
		
			
			| 156 |  | -                    source={webViewSource}
 | 
	
		
			
			| 157 |  | -                    onNavigationStateChange={this.handleNavigationStateChange} />
 | 
	
		
			
			| 158 |  | -            </Animated.View>
 | 
	
		
			
			| 159 |  | -        );
 | 
	
		
			
			| 160 |  | -    }
 | 
	
		
			
			|  | 80 | +  };
 | 
	
		
			
			|  | 81 | +
 | 
	
		
			
			|  | 82 | +  render() {
 | 
	
		
			
			|  | 83 | +    const { height, script } = this.state;
 | 
	
		
			
			|  | 84 | +    const {
 | 
	
		
			
			|  | 85 | +      onError,
 | 
	
		
			
			|  | 86 | +      onLoad,
 | 
	
		
			
			|  | 87 | +      onLoadStart,
 | 
	
		
			
			|  | 88 | +      onLoadEnd,
 | 
	
		
			
			|  | 89 | +      onShouldStartLoadWithRequest,
 | 
	
		
			
			|  | 90 | +      scalesPageToFit,
 | 
	
		
			
			|  | 91 | +      enableAnimation,
 | 
	
		
			
			|  | 92 | +      source,
 | 
	
		
			
			|  | 93 | +      heightOffset,
 | 
	
		
			
			|  | 94 | +      customScript,
 | 
	
		
			
			|  | 95 | +      style
 | 
	
		
			
			|  | 96 | +    } = this.props;
 | 
	
		
			
			|  | 97 | +    const webViewSource = Object.assign({}, source, { baseUrl: 'web/' });
 | 
	
		
			
			|  | 98 | +    return (
 | 
	
		
			
			|  | 99 | +      <Animated.View
 | 
	
		
			
			|  | 100 | +        style={[
 | 
	
		
			
			|  | 101 | +          Styles.container,
 | 
	
		
			
			|  | 102 | +          {
 | 
	
		
			
			|  | 103 | +            opacity: enableAnimation ? this.opacityAnimatedValue : 1,
 | 
	
		
			
			|  | 104 | +            height: height + heightOffset
 | 
	
		
			
			|  | 105 | +          },
 | 
	
		
			
			|  | 106 | +          style
 | 
	
		
			
			|  | 107 | +        ]}
 | 
	
		
			
			|  | 108 | +      >
 | 
	
		
			
			|  | 109 | +        <WebView
 | 
	
		
			
			|  | 110 | +          onError={onError}
 | 
	
		
			
			|  | 111 | +          onLoad={onLoad}
 | 
	
		
			
			|  | 112 | +          onLoadStart={onLoadStart}
 | 
	
		
			
			|  | 113 | +          onLoadEnd={onLoadEnd}
 | 
	
		
			
			|  | 114 | +          onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
 | 
	
		
			
			|  | 115 | +          style={Styles.webView}
 | 
	
		
			
			|  | 116 | +          injectedJavaScript={script + customScript}
 | 
	
		
			
			|  | 117 | +          scrollEnabled={false}
 | 
	
		
			
			|  | 118 | +          scalesPageToFit={scalesPageToFit}
 | 
	
		
			
			|  | 119 | +          source={webViewSource}
 | 
	
		
			
			|  | 120 | +          onNavigationStateChange={this.handleNavigationStateChange}
 | 
	
		
			
			|  | 121 | +        />
 | 
	
		
			
			|  | 122 | +      </Animated.View>
 | 
	
		
			
			|  | 123 | +    );
 | 
	
		
			
			|  | 124 | +  }
 | 
	
		
			
			| 161 | 125 |  }
 | 
	
		
			
			| 162 | 126 |  
 | 
	
		
			
			| 163 | 127 |  const ScreenWidth = Dimensions.get('window').width;
 | 
	
		
			
			| 164 | 128 |  
 | 
	
		
			
			| 165 | 129 |  const Styles = StyleSheet.create({
 | 
	
		
			
			| 166 |  | -    container: {
 | 
	
		
			
			| 167 |  | -        width: ScreenWidth,
 | 
	
		
			
			| 168 |  | -        backgroundColor: 'transparent'
 | 
	
		
			
			| 169 |  | -    },
 | 
	
		
			
			| 170 |  | -    webView: {
 | 
	
		
			
			| 171 |  | -        flex: 1,
 | 
	
		
			
			| 172 |  | -        backgroundColor: 'transparent'
 | 
	
		
			
			| 173 |  | -    }
 | 
	
		
			
			|  | 130 | +  container: {
 | 
	
		
			
			|  | 131 | +    width: ScreenWidth,
 | 
	
		
			
			|  | 132 | +    backgroundColor: 'transparent'
 | 
	
		
			
			|  | 133 | +  },
 | 
	
		
			
			|  | 134 | +  webView: {
 | 
	
		
			
			|  | 135 | +    flex: 1,
 | 
	
		
			
			|  | 136 | +    backgroundColor: 'transparent'
 | 
	
		
			
			|  | 137 | +  }
 | 
	
		
			
			| 174 | 138 |  });
 | 
	
		
			
			| 175 | 139 |  
 | 
	
		
			
			| 176 |  | -const BaseScript =
 | 
	
		
			
			| 177 |  | -    `
 | 
	
		
			
			|  | 140 | +const BaseScript = `
 | 
	
		
			
			| 178 | 141 |      ;
 | 
	
		
			
			| 179 | 142 |      (function () {
 | 
	
		
			
			| 180 | 143 |          var i = 0;
 | 
	
	
		
			
			|  | @@ -192,20 +155,11 @@ const BaseScript =
 | 
	
		
			
			| 192 | 155 |                  window.location.hash = ++i;
 | 
	
		
			
			| 193 | 156 |              }
 | 
	
		
			
			| 194 | 157 |          }
 | 
	
		
			
			| 195 |  | -        updateHeight();
 | 
	
		
			
			| 196 |  | -        window.addEventListener('load', updateHeight);
 | 
	
		
			
			| 197 |  | -        window.addEventListener('resize', updateHeight);
 | 
	
		
			
			| 198 |  | -        MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
 | 
	
		
			
			| 199 |  | -        var observer = new MutationObserver(updateHeight);
 | 
	
		
			
			| 200 |  | -        observer.observe(document, {
 | 
	
		
			
			| 201 |  | -            subtree: true,
 | 
	
		
			
			| 202 |  | -            attributes: true
 | 
	
		
			
			| 203 |  | -        });
 | 
	
		
			
			|  | 158 | +        ${DomMutationObserveScript}
 | 
	
		
			
			| 204 | 159 |      } ());
 | 
	
		
			
			| 205 | 160 |      `;
 | 
	
		
			
			| 206 | 161 |  
 | 
	
		
			
			| 207 |  | -const IframeBaseScript =
 | 
	
		
			
			| 208 |  | -    `
 | 
	
		
			
			|  | 162 | +const IframeBaseScript = `
 | 
	
		
			
			| 209 | 163 |      ;
 | 
	
		
			
			| 210 | 164 |      (function () {
 | 
	
		
			
			| 211 | 165 |          var i = 0;
 | 
	
	
		
			
			|  | @@ -220,11 +174,6 @@ const IframeBaseScript =
 | 
	
		
			
			| 220 | 174 |          updateHeight();
 | 
	
		
			
			| 221 | 175 |          window.addEventListener('load', updateHeight);
 | 
	
		
			
			| 222 | 176 |          window.addEventListener('resize', updateHeight);
 | 
	
		
			
			| 223 |  | -        MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
 | 
	
		
			
			| 224 |  | -        var observer = new MutationObserver(updateHeight);
 | 
	
		
			
			| 225 |  | -        observer.observe(document, {
 | 
	
		
			
			| 226 |  | -            subtree: true,
 | 
	
		
			
			| 227 |  | -            attributes: true
 | 
	
		
			
			| 228 |  | -        });
 | 
	
		
			
			|  | 177 | +        ${DomMutationObserveScript}
 | 
	
		
			
			| 229 | 178 |      } ());
 | 
	
		
			
			| 230 | 179 |      `;
 |