iou90 6 years ago
parent
commit
819b4c7275

+ 4
- 4
android/build.gradle View File

1
 apply plugin: 'com.android.library'
1
 apply plugin: 'com.android.library'
2
 
2
 
3
 android {
3
 android {
4
-    compileSdkVersion 23
5
-    buildToolsVersion "23.0.1"
4
+    compileSdkVersion 26
5
+    buildToolsVersion "27.0.3"
6
 
6
 
7
     defaultConfig {
7
     defaultConfig {
8
         minSdkVersion 16
8
         minSdkVersion 16
9
-        targetSdkVersion 22
9
+        targetSdkVersion 26
10
         versionCode 1
10
         versionCode 1
11
         versionName "1.0"
11
         versionName "1.0"
12
 
12
 
26
     androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
26
     androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
27
         exclude group: 'com.android.support', module: 'support-annotations'
27
         exclude group: 'com.android.support', module: 'support-annotations'
28
     })
28
     })
29
-    compile 'com.android.support:appcompat-v7:23.0.1'
29
+    compile 'com.android.support:appcompat-v7:26.1.0'
30
     compile "com.facebook.react:react-native:+"  // From node_modules
30
     compile "com.facebook.react:react-native:+"  // From node_modules
31
     testCompile 'junit:junit:4.12'
31
     testCompile 'junit:junit:4.12'
32
 }
32
 }

+ 23
- 25
autoHeightWebView/common.js View File

23
 
23
 
24
 const screenWidth = Dimensions.get('window').width;
24
 const screenWidth = Dimensions.get('window').width;
25
 
25
 
26
-function getWidth(style) {
27
-  return style && style.width ? style.width : screenWidth;
28
-}
29
-
30
 const bodyStyle = `
26
 const bodyStyle = `
31
 body {
27
 body {
32
   margin: 0;
28
   margin: 0;
62
   return !Immutable.is(Immutable.fromJS(newValue), Immutable.fromJS(oldValue));
58
   return !Immutable.is(Immutable.fromJS(newValue), Immutable.fromJS(oldValue));
63
 }
59
 }
64
 
60
 
65
-function getScript(props, getBaseScript, getIframeBaseScript) {
66
-  const { hasIframe, files, customStyle, customScript, style } = getReloadRelatedData(props);
67
-  const baseScript = getBaseScript(style);
68
-  let script = hasIframe ? baseScript : getIframeBaseScript(style);
69
-  script = files ? appendFilesToHead(files, baseScript) : baseScript;
70
-  script = appendStylesToHead(customStyle, script);
71
-  customScript && (script = customScript + script);
72
-  return script;
73
-}
74
-
75
-function isEqual(newProps, oldProps) {
76
-  return isChanged(getReloadRelatedData(newProps), getReloadRelatedData(oldProps));
77
-}
78
-
79
 function insertStringAfterAnotherString(raw, searchValue, insertValue) {
61
 function insertStringAfterAnotherString(raw, searchValue, insertValue) {
80
   const position = raw.indexOf(searchValue) + searchValue.length;
62
   const position = raw.indexOf(searchValue) + searchValue.length;
81
   return [raw.slice(0, position), insertValue, raw.slice(position)].join('');
63
   return [raw.slice(0, position), insertValue, raw.slice(position)].join('');
97
   }
79
   }
98
 }
80
 }
99
 
81
 
100
-function setState(props, getBaseScript, getIframeBaseScript) {
82
+export function getScript(props, getBaseScript, getIframeBaseScript) {
83
+  const { hasIframe, files, customStyle, customScript, style } = getReloadRelatedData(props);
84
+  const baseScript = getBaseScript(style);
85
+  let script = hasIframe ? getIframeBaseScript(style) : baseScript;
86
+  script = files ? appendFilesToHead(files, baseScript) : baseScript;
87
+  script = appendStylesToHead(customStyle, script);
88
+  customScript && (script = customScript + script);
89
+  return script;
90
+}
91
+
92
+export function getWidth(style) {
93
+  return style && style.width ? style.width : screenWidth;
94
+}
95
+
96
+export function isEqual(newProps, oldProps) {
97
+  return isChanged(getReloadRelatedData(newProps), getReloadRelatedData(oldProps));
98
+}
99
+
100
+export function setState(props, getBaseScript, getIframeBaseScript) {
101
   const { source, style } = props;
101
   const { source, style } = props;
102
   const script = getScript(props, getBaseScript, getIframeBaseScript);
102
   const script = getScript(props, getBaseScript, getIframeBaseScript);
103
   let state = {
103
   let state = {
123
   return state;
123
   return state;
124
 }
124
 }
125
 
125
 
126
-function handleSizeUpdated(height, width, onSizeUpdated) {
126
+export function handleSizeUpdated(height, width, onSizeUpdated) {
127
   onSizeUpdated &&
127
   onSizeUpdated &&
128
     onSizeUpdated({
128
     onSizeUpdated({
129
       height,
129
       height,
131
     });
131
     });
132
 }
132
 }
133
 
133
 
134
-function getSize(newHeight, newWidth, height, width, updatingSize, calledOnce) {
134
+export function getSize(newHeight, newWidth, height, width, updatingSize, calledOnce) {
135
   if (!calledOnce || updatingSize) {
135
   if (!calledOnce || updatingSize) {
136
     return {
136
     return {
137
       h: height,
137
       h: height,
144
   };
144
   };
145
 }
145
 }
146
 
146
 
147
-const domMutationObserveScript = `
147
+export const domMutationObserveScript = `
148
 var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
148
 var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
149
 var observer = new MutationObserver(updateSize);
149
 var observer = new MutationObserver(updateSize);
150
 observer.observe(document, {
150
 observer.observe(document, {
151
     subtree: true,
151
     subtree: true,
152
     attributes: true
152
     attributes: true
153
 });
153
 });
154
-`;
155
-
156
-export { isEqual, setState, getWidth, handleSizeUpdated, domMutationObserveScript, getSize };
154
+`;

+ 105
- 108
autoHeightWebView/index.android.js View File

7
   requireNativeComponent,
7
   requireNativeComponent,
8
   Animated,
8
   Animated,
9
   DeviceEventEmitter,
9
   DeviceEventEmitter,
10
-  Dimensions,
11
   StyleSheet,
10
   StyleSheet,
12
   Platform,
11
   Platform,
13
   UIManager,
12
   UIManager,
19
 
18
 
20
 import Immutable from 'immutable';
19
 import Immutable from 'immutable';
21
 
20
 
22
-import { getScript, onHeightUpdated, onWidthUpdated, onHeightWidthUpdated, domMutationObserveScript } from './common.js';
21
+import { handleSizeUpdated, getWidth, getScript, domMutationObserveScript } from './common.js';
23
 
22
 
24
 const RCTAutoHeightWebView = requireNativeComponent('RCTAutoHeightWebView', AutoHeightWebView, {
23
 const RCTAutoHeightWebView = requireNativeComponent('RCTAutoHeightWebView', AutoHeightWebView, {
25
   nativeOnly: {
24
   nativeOnly: {
32
   }
31
   }
33
 });
32
 });
34
 
33
 
35
-const screenWidth = Dimensions.get('window').width;
36
-
37
 export default class AutoHeightWebView extends PureComponent {
34
 export default class AutoHeightWebView extends PureComponent {
38
   static propTypes = {
35
   static propTypes = {
36
+    onMessage: PropTypes.func,
37
+    scrollEnabled: PropTypes.bool,
39
     source: WebView.propTypes.source,
38
     source: WebView.propTypes.source,
40
-      onHeightUpdated: PropTypes.func,
41
-      onWidthUpdated: PropTypes.func,
42
-      onHeightWidthUpdated: PropTypes.func,
43
-      shouldResizeWidth: PropTypes.bool,
44
     customScript: PropTypes.string,
39
     customScript: PropTypes.string,
45
     customStyle: PropTypes.string,
40
     customStyle: PropTypes.string,
46
     enableAnimation: PropTypes.bool,
41
     enableAnimation: PropTypes.bool,
42
+    // either height or width updated will trigger this
43
+    onSizeUpdated: PropTypes.func,
47
     // if set to false may cause some layout issues (width of container will be than width of screen)
44
     // if set to false may cause some layout issues (width of container will be than width of screen)
48
     scalesPageToFit: PropTypes.bool,
45
     scalesPageToFit: PropTypes.bool,
49
     // only works on enable animation
46
     // only works on enable animation
50
     animationDuration: PropTypes.number,
47
     animationDuration: PropTypes.number,
51
     // offset of rn webView margin
48
     // offset of rn webView margin
52
-      heightOffset: PropTypes.number,
53
-      widthOffset: PropTypes.number,
49
+    heightOffset: PropTypes.number,
54
     // baseUrl not work in android 4.3 or below version
50
     // baseUrl not work in android 4.3 or below version
55
     enableBaseUrl: PropTypes.bool,
51
     enableBaseUrl: PropTypes.bool,
56
     style: ViewPropTypes.style,
52
     style: ViewPropTypes.style,
74
     enableBaseUrl: false,
70
     enableBaseUrl: false,
75
     enableAnimation: true,
71
     enableAnimation: true,
76
     animationDuration: 555,
72
     animationDuration: 555,
77
-      heightOffset: 20,
78
-      widthOffset: 20,
79
-      shouldResizeWidth: false
73
+    heightOffset: 20
80
   };
74
   };
81
 
75
 
82
   constructor(props) {
76
   constructor(props) {
83
     super(props);
77
     super(props);
84
-    props.enableAnimation && (this.opacityAnimatedValue = new Animated.Value(0));
78
+    const { enableAnimation, style } = props;
79
+    enableAnimation && (this.opacityAnimatedValue = new Animated.Value(0));
80
+    this.webView = React.createRef();
85
     isBelowKitKat && DeviceEventEmitter.addListener('webViewBridgeMessage', this.listenWebViewBridgeMessage);
81
     isBelowKitKat && DeviceEventEmitter.addListener('webViewBridgeMessage', this.listenWebViewBridgeMessage);
86
     this.state = {
82
     this.state = {
87
       isChangingSource: false,
83
       isChangingSource: false,
88
       height: 0,
84
       height: 0,
89
-        heightOffset: 0,
90
-        width: screenWidth,
91
-        widthOffset: 0,
92
-      script: getScript(props, baseScript)
85
+      heightOffset: 0,
86
+      width: getWidth(style),
87
+      script: getScript(props, getBaseScript)
93
     };
88
     };
94
   }
89
   }
95
 
90
 
97
     this.startInterval();
92
     this.startInterval();
98
   }
93
   }
99
 
94
 
100
-  componentWillReceiveProps(nextProps) {
95
+  UNSAFE_componentWillReceiveProps(nextProps) {
101
     // injectedJavaScript only works when webView reload (source changed)
96
     // injectedJavaScript only works when webView reload (source changed)
102
-      if (Immutable.is(Immutable.fromJS(this.props.source), Immutable.fromJS(nextProps.source))) {
103
-          return;
104
-      }
105
-      else {
106
-          this.setState(
107
-              {
108
-                  isChangingSource: true,
109
-                  height: 0,
110
-                  heightOffset: 0,
111
-                  width: 0,
112
-                  widthOffset: 0,
113
-              },
114
-              () => {
115
-                  this.startInterval();
116
-                  this.setState({ isChangingSource: false });
117
-              }
118
-          );
119
-      }
120
-    this.setState({ script: getScript(nextProps, baseScript) });
97
+    if (Immutable.is(Immutable.fromJS(this.props.source), Immutable.fromJS(nextProps.source))) {
98
+      return;
99
+    } else {
100
+      this.setState(
101
+        {
102
+          isChangingSource: true,
103
+          height: 0,
104
+          heightOffset: 0,
105
+          width: 0
106
+        },
107
+        () => {
108
+          this.startInterval();
109
+          this.setState({ isChangingSource: false });
110
+        }
111
+      );
112
+    }
113
+    this.setState({ script: getScript(nextProps, getBaseScript) });
121
   }
114
   }
122
 
115
 
123
   componentWillUnmount() {
116
   componentWillUnmount() {
160
   }
153
   }
161
 
154
 
162
   onMessage = e => {
155
   onMessage = e => {
163
-      const { height, width } = JSON.parse(isBelowKitKat ? e.nativeEvent.message : e.nativeEvent.data);
164
-      if (height && height !== this.state.height && width && width !== this.state.width) {
165
-          const { enableAnimation, animationDuration, heightOffset, widthOffset } = this.props;
166
-          enableAnimation && this.opacityAnimatedValue.setValue(0);
167
-          this.stopInterval();
168
-          
169
-          this.setState(
170
-              {
171
-                  heightOffset,
172
-                  height,
173
-                  widthOffset,
174
-                  width
175
-              },
176
-              () => {
177
-                  enableAnimation
178
-                      ? Animated.timing(this.opacityAnimatedValue, {
179
-                          toValue: 1,
180
-                          duration: animationDuration
181
-                      }).start(() => onHeightWidthUpdated(height, width, this.props))
182
-                      : onHeightWidthUpdated(height, width, this.props);
183
-              }
184
-          );
185
-      }
156
+    const { height, width } = JSON.parse(isBelowKitKat ? e.nativeEvent.message : e.nativeEvent.data);
157
+    const { height: oldHeight, width: oldWidth } = this.state;
158
+    if ((height && height !== oldHeight) || (width && width !== oldWidth)) {
159
+      const { enableAnimation, animationDuration, heightOffset, onSizeUpdated } = this.props;
160
+      enableAnimation && this.opacityAnimatedValue.setValue(0);
161
+      this.stopInterval();
162
+      this.setState(
163
+        {
164
+          heightOffset,
165
+          height,
166
+          width
167
+        },
168
+        () => {
169
+          if (enableAnimation) {
170
+            Animated.timing(this.opacityAnimatedValue, {
171
+              toValue: 1,
172
+              duration: animationDuration
173
+            }).start(() => {
174
+              handleSizeUpdated(height, width, onSizeUpdated);
175
+            });
176
+          } else {
177
+            handleSizeUpdated(height, width, onSizeUpdated);
178
+          }
179
+        }
180
+      );
181
+    }
182
+    const { onMessage } = this.props;
183
+    onMessage && onMessage(e);
186
   };
184
   };
187
 
185
 
188
   onLoadingStart = event => {
186
   onLoadingStart = event => {
203
     onLoadEnd && onLoadEnd(event);
201
     onLoadEnd && onLoadEnd(event);
204
   };
202
   };
205
 
203
 
206
-  getWebView = webView => (this.webView = webView);
207
-
208
   stopLoading() {
204
   stopLoading() {
209
     UIManager.dispatchViewManagerCommand(
205
     UIManager.dispatchViewManagerCommand(
210
       findNodeHandle(this.webView),
206
       findNodeHandle(this.webView),
214
   }
210
   }
215
 
211
 
216
   render() {
212
   render() {
217
-      const { height, width, script, isChangingSource, heightOffset, widthOffset } = this.state;
218
-    const { scalesPageToFit, enableAnimation, source, customScript, style, enableBaseUrl } = this.props;
213
+    const { height, width, script, isChangingSource, heightOffset } = this.state;
214
+    const { scalesPageToFit, enableAnimation, source, customScript, style, enableBaseUrl, scrollEnabled } = this.props;
219
     let webViewSource = source;
215
     let webViewSource = source;
220
     if (enableBaseUrl) {
216
     if (enableBaseUrl) {
221
       webViewSource = Object.assign({}, source, {
217
       webViewSource = Object.assign({}, source, {
222
         baseUrl: 'file:///android_asset/web/'
218
         baseUrl: 'file:///android_asset/web/'
223
       });
219
       });
224
     }
220
     }
225
-      
226
     return (
221
     return (
227
       <Animated.View
222
       <Animated.View
228
         style={[
223
         style={[
229
           styles.container,
224
           styles.container,
230
           {
225
           {
231
             opacity: enableAnimation ? this.opacityAnimatedValue : 1,
226
             opacity: enableAnimation ? this.opacityAnimatedValue : 1,
232
-              height: height + heightOffset,
233
-              width: width + widthOffset
227
+            height: height + heightOffset,
228
+            width: width
234
           },
229
           },
235
           style
230
           style
236
         ]}
231
         ]}
240
             onLoadingStart={this.onLoadingStart}
235
             onLoadingStart={this.onLoadingStart}
241
             onLoadingFinish={this.onLoadingFinish}
236
             onLoadingFinish={this.onLoadingFinish}
242
             onLoadingError={this.onLoadingError}
237
             onLoadingError={this.onLoadingError}
243
-            ref={this.getWebView}
238
+            originWhitelist={['*']}
239
+            ref={this.webView}
244
             style={styles.webView}
240
             style={styles.webView}
245
             javaScriptEnabled={true}
241
             javaScriptEnabled={true}
246
             injectedJavaScript={script + customScript}
242
             injectedJavaScript={script + customScript}
247
             scalesPageToFit={scalesPageToFit}
243
             scalesPageToFit={scalesPageToFit}
244
+            scrollEnabled={!!scrollEnabled}
248
             source={webViewSource}
245
             source={webViewSource}
249
             onMessage={this.onMessage}
246
             onMessage={this.onMessage}
250
             messagingEnabled={true}
247
             messagingEnabled={true}
261
 
258
 
262
 const styles = StyleSheet.create({
259
 const styles = StyleSheet.create({
263
   container: {
260
   container: {
264
-    //width: screenWidth,
265
     backgroundColor: 'transparent'
261
     backgroundColor: 'transparent'
266
   },
262
   },
267
   webView: {
263
   webView: {
270
   }
266
   }
271
 });
267
 });
272
 
268
 
273
-const baseScript = isBelowKitKat
274
-  ? `
275
-    ; (function () {
276
-        var wrapper = document.createElement('div');
277
-        wrapper.id = 'wrapper';
278
-        while (document.body.firstChild instanceof Node) {
279
-            wrapper.appendChild(document.body.firstChild);
280
-        }
281
-        document.body.appendChild(wrapper);
282
-
283
-        AutoHeightWebView.onMessage = function (message) {
284
-            var rect = document.body.firstElementChild.getBoundingClientRect().toJSON();
285
-            var width = Math.round(rect.width);
286
-            var height = Math.round(rect.height);
287
-            AutoHeightWebView.send(JSON.stringify({ width, height }));
288
-        };
289
-        ${domMutationObserveScript}
290
-    } ());
291
-    `
292
-  : `
293
-    ; (function () {
294
-        var wrapper = document.createElement('div');
295
-        wrapper.id = 'wrapper';
296
-        while (document.body.firstChild instanceof Node) {
297
-            wrapper.appendChild(document.body.firstChild);
298
-        }
299
-        document.body.appendChild(wrapper);
300
-
301
-        document.addEventListener('message', function (e) {
302
-            var rect = document.body.firstElementChild.getBoundingClientRect().toJSON();
303
-            var width = Math.round(rect.width);
304
-            var height = Math.round(rect.height);
305
-            window.postMessage(JSON.stringify({ width, height }));
306
-        });
307
-        ${domMutationObserveScript}
308
-    } ());
309
-    `;
310
-
269
+const getBaseScript = isBelowKitKat
270
+  ? function() {
271
+      return `
272
+  ; (function () {
273
+    var wrapper = document.createElement('div');
274
+    wrapper.id = 'wrapper';
275
+    while (document.body.firstChild instanceof Node) {
276
+        wrapper.appendChild(document.body.firstChild);
277
+    }
278
+    document.body.appendChild(wrapper);
279
+    AutoHeightWebView.onMessage = function (message) {
280
+        var rect = document.body.firstElementChild.getBoundingClientRect().toJSON();
281
+        var width = Math.round(rect.width);
282
+        var height = Math.round(rect.height);
283
+        AutoHeightWebView.send(JSON.stringify({ width, height }));
284
+    };
285
+    ${domMutationObserveScript}
286
+} ());
287
+  `;
288
+    }
289
+  : function() {
290
+      return `
291
+  ; (function () {
292
+    var wrapper = document.createElement('div');
293
+    wrapper.id = 'wrapper';
294
+    while (document.body.firstChild instanceof Node) {
295
+        wrapper.appendChild(document.body.firstChild);
296
+    }
297
+    document.body.appendChild(wrapper);
298
+    document.addEventListener('message', function (e) {
299
+        var rect = document.body.firstElementChild.getBoundingClientRect().toJSON();
300
+        var width = Math.round(rect.width);
301
+        var height = Math.round(rect.height);
302
+        window.postMessage(JSON.stringify({ width, height }));
303
+    });
304
+    ${domMutationObserveScript}
305
+} ());
306
+  `;
307
+    };

+ 4
- 4
demo/android/app/build.gradle View File

94
 def enableProguardInReleaseBuilds = false
94
 def enableProguardInReleaseBuilds = false
95
 
95
 
96
 android {
96
 android {
97
-    compileSdkVersion 23
98
-    buildToolsVersion "23.0.1"
97
+    compileSdkVersion 26
98
+    buildToolsVersion "27.0.3"
99
 
99
 
100
     defaultConfig {
100
     defaultConfig {
101
         applicationId "com.demo"
101
         applicationId "com.demo"
102
         minSdkVersion 16
102
         minSdkVersion 16
103
-        targetSdkVersion 22
103
+        targetSdkVersion 26
104
         versionCode 1
104
         versionCode 1
105
         versionName "1.0"
105
         versionName "1.0"
106
         ndk {
106
         ndk {
139
 dependencies {
139
 dependencies {
140
     compile project(':react-native-autoheight-webview')
140
     compile project(':react-native-autoheight-webview')
141
     compile fileTree(dir: "libs", include: ["*.jar"])
141
     compile fileTree(dir: "libs", include: ["*.jar"])
142
-    compile "com.android.support:appcompat-v7:23.0.1"
142
+    compile "com.android.support:appcompat-v7:26.1.0"
143
     compile "com.facebook.react:react-native:+"  // From node_modules
143
     compile "com.facebook.react:react-native:+"  // From node_modules
144
 }
144
 }
145
 
145
 

+ 9
- 1
demo/android/build.gradle View File

3
 buildscript {
3
 buildscript {
4
     repositories {
4
     repositories {
5
         jcenter()
5
         jcenter()
6
+        maven {
7
+            url 'https://maven.google.com/'
8
+            name 'Google'
9
+        }
6
     }
10
     }
7
     dependencies {
11
     dependencies {
8
         classpath 'com.android.tools.build:gradle:2.2.3'
12
         classpath 'com.android.tools.build:gradle:2.2.3'
20
             // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
24
             // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
21
             url "$rootDir/../node_modules/react-native/android"
25
             url "$rootDir/../node_modules/react-native/android"
22
         }
26
         }
27
+        maven {
28
+            url 'https://maven.google.com/'
29
+            name 'Google'
30
+        }
23
     }
31
     }
24
-}
32
+}