Browse Source

change update height method on android; update version to 0.0.11

iou90 7 years ago
parent
commit
1c8f2880c1

+ 74
- 39
autoHeightWebView/index.android.js View File

@@ -6,28 +6,47 @@ import React, {
6 6
 } from 'react';
7 7
 
8 8
 import {
9
+    findNodeHandle,
9 10
     requireNativeComponent,
10 11
     Dimensions,
12
+    UIManager,
11 13
     View,
12 14
     WebView
13 15
 } from 'react-native';
14 16
 
15
-const RCTAutoHeightWebView = requireNativeComponent('RCTAutoHeightWebView', AutoHeightWebView);
17
+const RCTAutoHeightWebView = requireNativeComponent('RCTAutoHeightWebView', AutoHeightWebView, { nativeOnly: { messagingEnabled: PropTypes.bool } });
16 18
 
17 19
 export default class AutoHeightWebView extends Component {
18 20
     constructor(props) {
19 21
         super(props);
22
+        this.onMessage = this.onMessage.bind(this);
20 23
         this.onLoadingStart = this.onLoadingStart.bind(this);
21
-        this.onLoadingFinish = this.onLoadingStart.bind(this);
22
-        this.handleNavigationStateChanged = this.handleNavigationStateChanged.bind(this);
23 24
         const initialScript = props.files ? this.appendFilesToHead(props.files, BaseScript) : BaseScript;
24 25
         this.state = {
26
+            isOnLoadingStart: false,
25 27
             height: 0,
28
+            heightOffset: 0,
26 29
             script: initialScript
27 30
         };
28 31
     }
29 32
 
33
+    componentDidMount() {
34
+        this.intervalPostMessage();
35
+    }
36
+
30 37
     componentWillReceiveProps(nextProps) {
38
+        // injectedJavaScript only works when webview reload (html changed)
39
+        if (nextProps.html === this.props.html) {
40
+            this.htmlHasChanged = false;
41
+            return;
42
+        }
43
+        else {
44
+            this.htmlHasChanged = true;
45
+            this.setState({
46
+                height: 0,
47
+                heightOffset: 0
48
+            });
49
+        }
31 50
         let currentScript = BaseScript;
32 51
         if ((nextProps.files && !this.props.files) || (nextProps.files && this.props.files && JSON.stringify(nextProps.files) !== JSON.stringify(this.props.files))) {
33 52
             currentScript = this.appendFilesToHead(nextProps.files, BaseScript);
@@ -35,16 +54,53 @@ export default class AutoHeightWebView extends Component {
35 54
         this.setState({ script: currentScript });
36 55
     }
37 56
 
38
-    onLoadingStart(event) {
39
-        this.updateNavigationState(event);
57
+    componentDidUpdate(prevProps, prevState) {
58
+        if (this.htmlHasChanged) {
59
+            if (this.state.isOnLoadingStart && this.state.height === 0 && this.state.heightOffset === 0) {
60
+                this.intervalPostMessage();
61
+                this.htmlHasChanged = false;
62
+                this.setState({ isOnLoadingStart: false });
63
+            }
64
+        }
40 65
     }
41 66
 
42
-    onLoadingFinish(event) {
43
-        this.updateNavigationState(event);
67
+    componentWillUnmount() {
68
+        clearInterval(this.interval);
44 69
     }
45 70
 
46
-    updateNavigationState(event) {
47
-        this.handleNavigationStateChanged(event.nativeEvent);
71
+    onLoadingStart() {
72
+        if (this.htmlHasChanged) {
73
+            this.setState({ isOnLoadingStart: true });
74
+        }
75
+    }
76
+
77
+    postMessage(data) {
78
+        UIManager.dispatchViewManagerCommand(
79
+            findNodeHandle(this.webview),
80
+            UIManager.RCTWebView.Commands.postMessage,
81
+            [String(data)]
82
+        );
83
+    };
84
+
85
+    intervalPostMessage() {
86
+        this.interval = setInterval(() => {
87
+            this.postMessage('getBodyHeight');
88
+        }, 205);
89
+    }
90
+
91
+    onMessage(e) {
92
+        const height = parseInt(e.nativeEvent.data);
93
+        console.log(height);
94
+        if (height) {
95
+            clearInterval(this.interval);
96
+            this.setState({
97
+                heightOffset: this.props.heightOffset,
98
+                height
99
+            });
100
+            if (this.props.onHeightUpdated) {
101
+                this.props.onHeightUpdated(height);
102
+            }
103
+        }
48 104
     }
49 105
 
50 106
     appendFilesToHead(files, script) {
@@ -64,16 +120,6 @@ export default class AutoHeightWebView extends Component {
64 120
         return script;
65 121
     }
66 122
 
67
-    handleNavigationStateChanged(navState) {
68
-        const height = Number(navState.title);
69
-        if (height) {
70
-            this.setState({ height });
71
-            if (this.props.onHeightUpdated) {
72
-                this.props.onHeightUpdated(height);
73
-            }
74
-        }
75
-    }
76
-
77 123
     render() {
78 124
         const source = this.props.enableBaseUrl ? {
79 125
             html: this.props.html,
@@ -82,16 +128,18 @@ export default class AutoHeightWebView extends Component {
82 128
         return (
83 129
             <View style={[{
84 130
                 width: ScreenWidth,
85
-                height: this.state.height + this.props.heightOffset
131
+                height: this.state.height + this.state.heightOffset
86 132
             }, this.props.style]}>
87 133
                 <RCTAutoHeightWebView
134
+                    ref={webview => this.webview = webview}
88 135
                     style={{ flex: 1 }}
89 136
                     javaScriptEnabled={true}
90 137
                     injectedJavaScript={this.state.script + this.props.customScript}
138
+                    onLoadingStart={this.onLoadingStart}
91 139
                     scrollEnabled={false}
92 140
                     source={source}
93
-                    onLoadingStart={this.onLoadingStart}
94
-                    onLoadingFinish={this.onLoadingFinish} />
141
+                    onMessage={this.onMessage}
142
+                    messagingEnabled={true} />
95 143
             </View>
96 144
         );
97 145
     }
@@ -116,7 +164,7 @@ AutoHeightWebView.propTypes = {
116 164
 
117 165
 AutoHeightWebView.defaultProps = {
118 166
     enableBaseUrl: false,
119
-    heightOffset: 25
167
+    heightOffset: 20
120 168
 }
121 169
 
122 170
 const ScreenWidth = Dimensions.get('window').width;
@@ -124,21 +172,8 @@ const ScreenWidth = Dimensions.get('window').width;
124 172
 const BaseScript =
125 173
     `
126 174
     ; (function () {
127
-        var wrapper = document.createElement('div');
128
-        wrapper.id = 'height-wrapper';
129
-        while (document.body.firstChild) {
130
-            wrapper.appendChild(document.body.firstChild);
131
-        }
132
-        document.body.appendChild(wrapper);
133
-        var i = 0;
134
-        function updateHeight() {
135
-            document.title = wrapper.clientHeight;
136
-            window.location.hash = ++i;
137
-        }
138
-        updateHeight();
139
-        window.addEventListener('load', function () {
140
-            updateHeight();
175
+        document.addEventListener('message', function (e) {
176
+            window.postMessage(String(document.body.offsetHeight));
141 177
         });
142
-        window.addEventListener('resize', updateHeight);
143
-    } ());
178
+    } ()); 
144 179
     `;

+ 1
- 0
autoHeightWebView/index.ios.js View File

@@ -64,6 +64,7 @@ export default class AutoHeightWebView extends Component {
64 64
                 height: this.state.height + this.props.heightOffset,
65 65
             }, this.props.style]}>
66 66
                 <WebView
67
+                    style={{ flex: 1 }}
67 68
                     injectedJavaScript={this.state.script + this.props.customScript}
68 69
                     scrollEnabled={false}
69 70
                     source={{

+ 7
- 5
examples/autoHeightWebViewExplorer/explorer.js View File

@@ -6,6 +6,10 @@ import React, {
6 6
 } from 'react';
7 7
 
8 8
 import {
9
+    findNodeHandle,
10
+    requireNativeComponent,
11
+    Dimensions,
12
+    UIManager,
9 13
     Platform,
10 14
     ScrollView,
11 15
     StyleSheet,
@@ -55,11 +59,9 @@ export default class Explorer extends Component {
55 59
                     justifyContent: 'center',
56 60
                     alignItems: 'center'
57 61
                 }}>
58
-                {
59
-                    <AutoHeightWebView
60
-                        html={this.state.html}
61
-                        customScript={this.state.script} />
62
-                }
62
+                <AutoHeightWebView
63
+                    html={this.state.html}
64
+                    customScript={this.state.script} />
63 65
                 <TouchableOpacity
64 66
                     onPress={this.changeHtml}
65 67
                     style={Styles.button}>

+ 1
- 1
examples/autoHeightWebViewExplorer/package.json View File

@@ -9,7 +9,7 @@
9 9
   "dependencies": {
10 10
     "react": "15.4.2",
11 11
     "react-native": "0.40.0",
12
-    "react-native-autoheightwebview": "../.."
12
+    "react-native-autoheightwebview": "0.0.11"
13 13
   },
14 14
   "devDependencies": {
15 15
     "babel-jest": "18.0.0",

+ 1
- 1
package.json View File

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "name": "react-native-autoheightwebview",
3
-  "version": "0.0.7",
3
+  "version": "0.0.11",
4 4
   "description": "An auto height webview for React Native",
5 5
   "main": "autoHeightWebView",
6 6
   "files": ["android/", "autoHeightWebView/"],