No Description

index.js 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import React, { useState, useEffect, useRef, useImperativeHandle, forwardRef } from 'react';
  2. import { Platform, ViewPropTypes, View } from 'react-native';
  3. import PropTypes from 'prop-types';
  4. import { WebView } from 'react-native-webview';
  5. import { reduceData, getWidth, isSizeChanged, shouldUpdate } from './utils';
  6. const AutoHeightWebView = React.memo(
  7. forwardRef((props, ref) => {
  8. const { style, onMessage, onSizeUpdated, scrollEnabledWithZoomedin, scrollEnabled, source } = props;
  9. if (!source) {
  10. return null;
  11. }
  12. const webView = useRef();
  13. useImperativeHandle(ref, () => ({
  14. stopLoading: () => webView.current.stopLoading(),
  15. goForward: () => webView.current.goForward(),
  16. goBack: () => webView.current.goBack(),
  17. reload: () => webView.current.reload(),
  18. injectJavaScript: script => webView.current.injectJavaScript(script),
  19. }));
  20. const [size, setSize] = useState({
  21. height: style && style.height ? style.height : 0,
  22. width: getWidth(style),
  23. });
  24. const [scrollable, setScrollable] = useState(false);
  25. const handleMessage = (event) => {
  26. onMessage && onMessage(event);
  27. if (!event.nativeEvent) {
  28. return;
  29. }
  30. let data = {};
  31. // Sometimes the message is invalid JSON, so we ignore that case
  32. try {
  33. data = JSON.parse(event.nativeEvent.data);
  34. } catch (error) {
  35. console.error(error);
  36. return;
  37. }
  38. const { height, width, zoomedin } = data;
  39. !scrollEnabled && scrollEnabledWithZoomedin && setScrollable(!!zoomedin);
  40. const { height: previousHeight, width: previousWidth } = size;
  41. isSizeChanged({ height, previousHeight, width, previousWidth })
  42. && setSize({
  43. height,
  44. width,
  45. });
  46. };
  47. const currentScrollEnabled = scrollEnabled === false && scrollEnabledWithZoomedin ? scrollable : scrollEnabled;
  48. const { currentSource, script } = reduceData(props);
  49. const { width, height } = size;
  50. useEffect(
  51. () => onSizeUpdated
  52. && onSizeUpdated({
  53. height,
  54. width,
  55. }),
  56. [width, height, onSizeUpdated]
  57. );
  58. return (
  59. <View style={[props.style, { height: height || 50, transform: [{ translateX: -1 }] }]}>
  60. <WebView
  61. {...props}
  62. style={{ transform: [{ translateX: 1 }], backgroundColor: '#0000' }}
  63. ref={webView}
  64. onMessage={handleMessage}
  65. injectedJavaScript={script + props.injectedJavaScript}
  66. source={currentSource}
  67. scrollEnabled={currentScrollEnabled}
  68. />
  69. </View>
  70. );
  71. }),
  72. (prevProps, nextProps) => !shouldUpdate({ prevProps, nextProps })
  73. );
  74. AutoHeightWebView.propTypes = {
  75. onSizeUpdated: PropTypes.func,
  76. files: PropTypes.arrayOf(
  77. PropTypes.shape({
  78. href: PropTypes.string,
  79. type: PropTypes.string,
  80. rel: PropTypes.string,
  81. })
  82. ),
  83. style: ViewPropTypes.style,
  84. customScript: PropTypes.string,
  85. customStyle: PropTypes.string,
  86. viewportContent: PropTypes.string,
  87. scrollEnabledWithZoomedin: PropTypes.bool,
  88. // webview props
  89. originWhitelist: PropTypes.arrayOf(PropTypes.string),
  90. onMessage: PropTypes.func,
  91. scalesPageToFit: PropTypes.bool,
  92. source: PropTypes.object,
  93. };
  94. const defaultProps = {
  95. showsVerticalScrollIndicator: false,
  96. showsHorizontalScrollIndicator: false,
  97. originWhitelist: ['*'],
  98. };
  99. Platform.OS === 'android'
  100. && Object.assign(defaultProps, {
  101. scalesPageToFit: false,
  102. });
  103. Platform.OS === 'ios'
  104. && Object.assign(defaultProps, {
  105. viewportContent: 'width=device-width',
  106. });
  107. AutoHeightWebView.defaultProps = defaultProps;
  108. export default AutoHeightWebView;