Browse Source

update index.ios.js to support auto width

iou90 6 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
 
2
 
3
 import React, { PureComponent } from 'react';
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
 import PropTypes from 'prop-types';
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
 export default class AutoHeightWebView extends PureComponent {
11
 export default class AutoHeightWebView extends PureComponent {
14
   static propTypes = {
12
   static propTypes = {
15
     hasIframe: PropTypes.bool,
13
     hasIframe: PropTypes.bool,
16
     source: WebView.propTypes.source,
14
     source: WebView.propTypes.source,
17
-      onHeightUpdated: PropTypes.func,
18
-      onWidthUpdated: PropTypes.func,
19
-      onHeightWidthUpdated: PropTypes.func,
20
-      shouldResizeWidth: PropTypes.bool,
21
     customScript: PropTypes.string,
15
     customScript: PropTypes.string,
22
     customStyle: PropTypes.string,
16
     customStyle: PropTypes.string,
23
     enableAnimation: PropTypes.bool,
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
     // if set to true may cause some layout issues (smaller font size)
22
     // if set to true may cause some layout issues (smaller font size)
25
     scalesPageToFit: PropTypes.bool,
23
     scalesPageToFit: PropTypes.bool,
26
     // only works on enable animation
24
     // only works on enable animation
27
     animationDuration: PropTypes.number,
25
     animationDuration: PropTypes.number,
28
     // offset of rn webview margin
26
     // offset of rn webview margin
29
-      heightOffset: PropTypes.number,
30
-      widthOffset: PropTypes.number,
31
-    style: ViewPropTypes.style,
27
+    heightOffset: PropTypes.number,
32
     //  rn WebView callback
28
     //  rn WebView callback
33
     onError: PropTypes.func,
29
     onError: PropTypes.func,
34
     onLoad: PropTypes.func,
30
     onLoad: PropTypes.func,
49
     scalesPageToFit: false,
45
     scalesPageToFit: false,
50
     enableAnimation: true,
46
     enableAnimation: true,
51
     animationDuration: 555,
47
     animationDuration: 555,
52
-      heightOffset: 12,
53
-      widthOffset: 12,
54
-      shouldResizeWidth: false
48
+    heightOffset: 12
55
   };
49
   };
56
 
50
 
57
   constructor(props) {
51
   constructor(props) {
58
     super(props);
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
     this.state = {
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
   componentWillReceiveProps(nextProps) {
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
   getWebView = webView => (this.webView = webView);
101
   getWebView = webView => (this.webView = webView);
106
       enableAnimation,
116
       enableAnimation,
107
       source,
117
       source,
108
       heightOffset,
118
       heightOffset,
109
-      widthOffset,
110
       customScript,
119
       customScript,
111
-      style
120
+      style,
121
+      scrollEnabled
112
     } = this.props;
122
     } = this.props;
113
     const webViewSource = Object.assign({}, source, { baseUrl: 'web/' });
123
     const webViewSource = Object.assign({}, source, { baseUrl: 'web/' });
114
     return (
124
     return (
117
           styles.container,
127
           styles.container,
118
           {
128
           {
119
             opacity: enableAnimation ? this.opacityAnimatedValue : 1,
129
             opacity: enableAnimation ? this.opacityAnimatedValue : 1,
120
-              height: height + heightOffset,
121
-              width: width + widthOffset
130
+            width,
131
+            height: height + heightOffset
122
           },
132
           },
123
           style
133
           style
124
         ]}
134
         ]}
132
           onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
142
           onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
133
           style={styles.webView}
143
           style={styles.webView}
134
           injectedJavaScript={script + customScript}
144
           injectedJavaScript={script + customScript}
135
-          scrollEnabled={false}
145
+          scrollEnabled={scrollEnabled}
136
           scalesPageToFit={scalesPageToFit}
146
           scalesPageToFit={scalesPageToFit}
137
           source={webViewSource}
147
           source={webViewSource}
138
           onNavigationStateChange={this.handleNavigationStateChange}
148
           onNavigationStateChange={this.handleNavigationStateChange}
158
     window.addEventListener('resize', updateSize);
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
     (function () {
186
     (function () {
179
         var i = 0;
187
         var i = 0;
180
         var height = 0;
188
         var height = 0;
181
-        var width = ${screenWidth};
189
+        var width = ${getWidth(style)};
182
         var wrapper = document.createElement('div');
190
         var wrapper = document.createElement('div');
183
-        wrapper.id = 'height-wrapper';
191
+        wrapper.id = 'rnahw-wrapper';
184
         while (document.body.firstChild instanceof Node) {
192
         while (document.body.firstChild instanceof Node) {
185
             wrapper.appendChild(document.body.firstChild);
193
             wrapper.appendChild(document.body.firstChild);
186
         }
194
         }
187
         document.body.appendChild(wrapper);
195
         document.body.appendChild(wrapper);
188
         function updateSize() {
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
                 window.location.hash = ++i;
202
                 window.location.hash = ++i;
197
             }
203
             }
198
         }
204
         }
200
         ${domMutationObserveScript}
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
     (function () {
215
     (function () {
208
         var i = 0;
216
         var i = 0;
209
         var height = 0;
217
         var height = 0;
210
-        var width = ${screenWidth};
218
+        var width = ${getWidth(style)};
211
         function updateSize() {
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
                 window.location.hash = ++i;
225
                 window.location.hash = ++i;
220
             }
226
             }
221
         }
227
         }
223
         ${domMutationObserveScript}
229
         ${domMutationObserveScript}
224
     } ());
230
     } ());
225
     `;
231
     `;
232
+}