Browse Source

update index.ios.js to support auto width

iou90 5 years ago
parent
commit
6071298135
1 changed files with 81 additions and 74 deletions
  1. 81
    74
      autoHeightWebView/index.ios.js

+ 81
- 74
autoHeightWebView/index.ios.js View File

@@ -2,33 +2,29 @@
2 2
 
3 3
 import React, { PureComponent } from 'react';
4 4
 
5
-import { Animated, Dimensions, StyleSheet, ViewPropTypes, WebView } from 'react-native';
5
+import { Animated, StyleSheet, ViewPropTypes, WebView } from 'react-native';
6 6
 
7 7
 import PropTypes from 'prop-types';
8 8
 
9
-import { getScript, onHeightUpdated, onWidthUpdated, onHeightWidthUpdated, domMutationObserveScript } from './common.js';
10
-
11
-const screenWidth = Dimensions.get('window').width;
9
+import { getWidth, getScript, handleSizeUpdated, domMutationObserveScript } from './common.js';
12 10
 
13 11
 export default class AutoHeightWebView extends PureComponent {
14 12
   static propTypes = {
15 13
     hasIframe: PropTypes.bool,
16 14
     source: WebView.propTypes.source,
17
-      onHeightUpdated: PropTypes.func,
18
-      onWidthUpdated: PropTypes.func,
19
-      onHeightWidthUpdated: PropTypes.func,
20
-      shouldResizeWidth: PropTypes.bool,
21 15
     customScript: PropTypes.string,
22 16
     customStyle: PropTypes.string,
23 17
     enableAnimation: PropTypes.bool,
18
+    style: ViewPropTypes.style,
19
+    scrollEnabled: PropTypes.bool,
20
+    // either height or width updated will trigger this
21
+    onSizeUpdated: PropTypes.func,
24 22
     // if set to true may cause some layout issues (smaller font size)
25 23
     scalesPageToFit: PropTypes.bool,
26 24
     // only works on enable animation
27 25
     animationDuration: PropTypes.number,
28 26
     // offset of rn webview margin
29
-      heightOffset: PropTypes.number,
30
-      widthOffset: PropTypes.number,
31
-    style: ViewPropTypes.style,
27
+    heightOffset: PropTypes.number,
32 28
     //  rn WebView callback
33 29
     onError: PropTypes.func,
34 30
     onLoad: PropTypes.func,
@@ -49,43 +45,57 @@ export default class AutoHeightWebView extends PureComponent {
49 45
     scalesPageToFit: false,
50 46
     enableAnimation: true,
51 47
     animationDuration: 555,
52
-      heightOffset: 12,
53
-      widthOffset: 12,
54
-      shouldResizeWidth: false
48
+    heightOffset: 12
55 49
   };
56 50
 
57 51
   constructor(props) {
58 52
     super(props);
59
-    props.enableAnimation && (this.opacityAnimatedValue = new Animated.Value(0));
53
+    const { enableAnimation, style } = props;
54
+    enableAnimation && (this.opacityAnimatedValue = new Animated.Value(0));
60 55
     this.state = {
61
-        height: 0,
62
-        //heightOffset: 0, //?? I added this
63
-        width: screenWidth,
64
-        //widthOffset: 0,
65
-      script: getScript(props, baseScript, iframeBaseScript)
56
+      width: getWidth(style),
57
+      height: style && style.height ? style.height : 0,
58
+      script: getScript(props, getBaseScript, getIframeBaseScript)
66 59
     };
67 60
   }
68 61
 
69 62
   componentWillReceiveProps(nextProps) {
70
-    this.setState({ script: getScript(nextProps, baseScript, iframeBaseScript) });
63
+    if (nextProps.style) {
64
+      const { width, height } = nextProps.style;
65
+      width && this.setState({ width });
66
+      height && this.setState({ height });
67
+    }
68
+    this.setState({ script: getScript(nextProps, getBaseScript, getIframeBaseScript) });
71 69
   }
72 70
 
73
-    handleNavigationStateChange = navState => {
74
-        var [width, height] = navState.title.split(',');
75
-        width = Number(width);
76
-        height = Number(height);
77
-        const { enableAnimation, animationDuration } = this.props;
78
-        if (height && height !== this.state.height) {       // ??? add to logic ??? width && width !== this.state.width
79
-            enableAnimation && this.opacityAnimatedValue.setValue(0);
80
-            this.setState({ height, width }, () => {
81
-                enableAnimation
82
-                    ? Animated.timing(this.opacityAnimatedValue, {
83
-                        toValue: 1,
84
-                        duration: animationDuration
85
-                    }).start(() => onHeightWidthUpdated(height, width, this.props))
86
-                    : onHeightWidthUpdated(height, width, this.props);
87
-            });
71
+  handleNavigationStateChange = navState => {
72
+    const { title } = navState;
73
+    if (!title) {
74
+      return;
75
+    }
76
+    const [heightValue, widthValue] = title.split(',');
77
+    const width = Number(widthValue);
78
+    const height = Number(heightValue);
79
+    const { height: oldHeight, width: oldWidth } = this.state;
80
+    if ((height && height !== oldHeight) || (width && width !== oldWidth)) {
81
+      // if ((height && height !== oldHeight)) {
82
+      const { enableAnimation, animationDuration, onSizeUpdated } = this.props;
83
+      enableAnimation && this.opacityAnimatedValue.setValue(0);
84
+      this.setState(
85
+        {
86
+          height,
87
+          width
88
+        },
89
+        () => {
90
+          enableAnimation
91
+            ? Animated.timing(this.opacityAnimatedValue, {
92
+                toValue: 1,
93
+                duration: animationDuration
94
+              }).start(() => handleSizeUpdated(height, width, onSizeUpdated))
95
+            : handleSizeUpdated(height, width, onSizeUpdated);
88 96
         }
97
+      );
98
+    }
89 99
   };
90 100
 
91 101
   getWebView = webView => (this.webView = webView);
@@ -106,9 +116,9 @@ export default class AutoHeightWebView extends PureComponent {
106 116
       enableAnimation,
107 117
       source,
108 118
       heightOffset,
109
-      widthOffset,
110 119
       customScript,
111
-      style
120
+      style,
121
+      scrollEnabled
112 122
     } = this.props;
113 123
     const webViewSource = Object.assign({}, source, { baseUrl: 'web/' });
114 124
     return (
@@ -117,8 +127,8 @@ export default class AutoHeightWebView extends PureComponent {
117 127
           styles.container,
118 128
           {
119 129
             opacity: enableAnimation ? this.opacityAnimatedValue : 1,
120
-              height: height + heightOffset,
121
-              width: width + widthOffset
130
+            width,
131
+            height: height + heightOffset
122 132
           },
123 133
           style
124 134
         ]}
@@ -132,7 +142,7 @@ export default class AutoHeightWebView extends PureComponent {
132 142
           onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
133 143
           style={styles.webView}
134 144
           injectedJavaScript={script + customScript}
135
-          scrollEnabled={false}
145
+          scrollEnabled={scrollEnabled}
136 146
           scalesPageToFit={scalesPageToFit}
137 147
           source={webViewSource}
138 148
           onNavigationStateChange={this.handleNavigationStateChange}
@@ -158,41 +168,37 @@ const commonScript = `
158 168
     window.addEventListener('resize', updateSize);
159 169
     `;
160 170
 
161
-const _getter = `
162
-    function getHeight(height) {
163
-      if(height < 1) {
164
-        return document.body.offsetHeight;
165
-      }
166
-      return height;
167
-    }
168
-    function getWidth(width) {
169
-      if(width < 1) {
170
-        return document.body.clientWidth; // maybe should be .offsetWidth ??
171
-      }
172
-      return width;
171
+const getSize = `
172
+    function getSize(container) {
173
+      var height = container.clientHeight || document.body.offsetHeight;
174
+      var width = container.clientWidth || document.body.offsetWidth;
175
+      return {
176
+        height,
177
+        width
178
+      };
173 179
     }
174 180
     `;
175
-const baseScript = `
181
+
182
+function getBaseScript(style) {
183
+  return `
176 184
     ;
177
-    ${_getter}
185
+    ${getSize}
178 186
     (function () {
179 187
         var i = 0;
180 188
         var height = 0;
181
-        var width = ${screenWidth};
189
+        var width = ${getWidth(style)};
182 190
         var wrapper = document.createElement('div');
183
-        wrapper.id = 'height-wrapper';
191
+        wrapper.id = 'rnahw-wrapper';
184 192
         while (document.body.firstChild instanceof Node) {
185 193
             wrapper.appendChild(document.body.firstChild);
186 194
         }
187 195
         document.body.appendChild(wrapper);
188 196
         function updateSize() {
189
-            var rect = document.body.firstElementChild.getBoundingClientRect().toJSON();
190
-            var newWidth = Math.round(rect.width);
191
-            var newHeight = Math.round(rect.height);
192
-            if(newHeight !== height) {
193
-                //height = getHeight(wrapper.clientHeight);
194
-                //width = getWidth(wrapper.clientWidth);
195
-                document.title = newWidth + ',' + newHeight;
197
+            if(document.body.offsetHeight !== height || document.body.offsetWidth !== width) {
198
+                var size = getSize(wrapper);
199
+                height = size.height;
200
+                width = size.width;
201
+                document.title = height.toString() + ',' + width.toString();
196 202
                 window.location.hash = ++i;
197 203
             }
198 204
         }
@@ -200,22 +206,22 @@ const baseScript = `
200 206
         ${domMutationObserveScript}
201 207
     } ());
202 208
     `;
209
+}
203 210
 
204
-const iframeBaseScript = `
211
+function getIframeBaseScript(style) {
212
+  return `
205 213
     ;
206
-    ${_getter}
214
+    ${getSize}
207 215
     (function () {
208 216
         var i = 0;
209 217
         var height = 0;
210
-        var width = ${screenWidth};
218
+        var width = ${getWidth(style)};
211 219
         function updateSize() {
212
-            var rect = document.body.firstElementChild.getBoundingClientRect().toJSON();
213
-            var newWidth = Math.round(rect.width);
214
-            var newHeight = Math.round(rect.height);
215
-            if(newHeight !== height) {
216
-                //height = getHeight(document.body.firstChild.clientHeight);
217
-                //width = getWidth(document.body.firstChild.clientHeight);
218
-                document.title = newWidth + ',' + newHeight;
220
+            if(document.body.offsetHeight !== height || document.body.offsetWidth !== width) {
221
+                var size = getSize(document.body.firstChild);
222
+                height = size.height;
223
+                width = size.width;
224
+                document.title = height.toString() + ',' + width.toString();
219 225
                 window.location.hash = ++i;
220 226
             }
221 227
         }
@@ -223,3 +229,4 @@ const iframeBaseScript = `
223 229
         ${domMutationObserveScript}
224 230
     } ());
225 231
     `;
232
+}