|
@@ -7,12 +7,12 @@ import {
|
7
|
7
|
requireNativeComponent,
|
8
|
8
|
Animated,
|
9
|
9
|
DeviceEventEmitter,
|
|
10
|
+ Easing,
|
10
|
11
|
StyleSheet,
|
11
|
12
|
Platform,
|
12
|
13
|
UIManager,
|
13
|
14
|
ViewPropTypes,
|
14
|
|
- WebView,
|
15
|
|
- View
|
|
15
|
+ WebView
|
16
|
16
|
} from 'react-native';
|
17
|
17
|
|
18
|
18
|
import PropTypes from 'prop-types';
|
|
@@ -59,6 +59,7 @@ export default class AutoHeightWebView extends PureComponent {
|
59
|
59
|
scalesPageToFit: PropTypes.bool,
|
60
|
60
|
// only works on enable animation
|
61
|
61
|
animationDuration: PropTypes.number,
|
|
62
|
+ animationEasing: PropTypes.func,
|
62
|
63
|
// offset of rn webView margin
|
63
|
64
|
heightOffset: PropTypes.number,
|
64
|
65
|
// baseUrl not work in android 4.3 or below version
|
|
@@ -83,23 +84,33 @@ export default class AutoHeightWebView extends PureComponent {
|
83
|
84
|
scalesPageToFit: true,
|
84
|
85
|
enableBaseUrl: false,
|
85
|
86
|
enableAnimation: true,
|
86
|
|
- animationDuration: 555,
|
87
|
|
- heightOffset: 20
|
|
87
|
+ animationDuration: 255,
|
|
88
|
+ heightOffset: 20,
|
|
89
|
+ animationEasing: Easing.out(Easing.quad)
|
88
|
90
|
};
|
89
|
91
|
|
90
|
92
|
constructor(props) {
|
91
|
93
|
super(props);
|
92
|
|
- const { enableAnimation, style, source, enableBaseUrl } = props;
|
93
|
|
- enableAnimation && (this.opacityAnimatedValue = new Animated.Value(0));
|
|
94
|
+ const { enableAnimation, style, source, enableBaseUrl, heightOffset } = props;
|
94
|
95
|
isBelowKitKat && DeviceEventEmitter.addListener('webViewBridgeMessage', this.listenWebViewBridgeMessage);
|
95
|
|
- this.state = {
|
|
96
|
+ this.finishInterval = true;
|
|
97
|
+ const initWidth = getWidth(style);
|
|
98
|
+ const height = style ? (style.height ? style.height : 0) : 0;
|
|
99
|
+ let state = {
|
96
|
100
|
isSizeChanged: false,
|
97
|
101
|
isSizeMayChange: false,
|
98
|
|
- height: 0,
|
99
|
|
- width: getWidth(style),
|
|
102
|
+ height: height,
|
|
103
|
+ width: initWidth,
|
100
|
104
|
script: getScript(props, getBaseScript),
|
101
|
105
|
source: enableBaseUrl ? Object.assign({}, source, { baseUrl }) : source
|
102
|
106
|
};
|
|
107
|
+ if (enableAnimation) {
|
|
108
|
+ Object.assign(state, {
|
|
109
|
+ heightValue: new Animated.Value(height + heightOffset),
|
|
110
|
+ widthValue: new Animated.Value(initWidth)
|
|
111
|
+ });
|
|
112
|
+ }
|
|
113
|
+ this.state = state;
|
103
|
114
|
}
|
104
|
115
|
|
105
|
116
|
componentDidMount() {
|
|
@@ -112,14 +123,13 @@ export default class AutoHeightWebView extends PureComponent {
|
112
|
123
|
const { source, script } = getUpdatedState(props, enableBaseUrl ? baseUrl : null, getBaseScript);
|
113
|
124
|
const height = style ? style.height : null;
|
114
|
125
|
const width = style ? style.width : null;
|
115
|
|
- // if (source !== prevSource || script !== prevScript) {
|
116
|
|
- // console.log(1)
|
117
|
|
- // return {
|
118
|
|
- // source,
|
119
|
|
- // script,
|
120
|
|
- // isSizeMayChange: true
|
121
|
|
- // };
|
122
|
|
- // }
|
|
126
|
+ if (source.html !== prevSource.html || source.uri !== prevSource.uri || script !== prevScript) {
|
|
127
|
+ return {
|
|
128
|
+ source,
|
|
129
|
+ script,
|
|
130
|
+ isSizeMayChange: true
|
|
131
|
+ };
|
|
132
|
+ }
|
123
|
133
|
if (isSizeChanged(height, oldHeight, width, oldWidth)) {
|
124
|
134
|
return {
|
125
|
135
|
height,
|
|
@@ -131,18 +141,26 @@ export default class AutoHeightWebView extends PureComponent {
|
131
|
141
|
}
|
132
|
142
|
|
133
|
143
|
componentDidUpdate() {
|
134
|
|
- const { height, width, isSizeChanged, isSizeMayChange } = this.state;
|
|
144
|
+ const { height, width, isSizeChanged, isSizeMayChange, heightValue, widthValue } = this.state;
|
135
|
145
|
if (isSizeMayChange) {
|
136
|
146
|
this.startInterval();
|
137
|
147
|
this.setState({ isSizeMayChange: false });
|
138
|
148
|
}
|
139
|
149
|
if (isSizeChanged) {
|
140
|
|
- const { enableAnimation, animationDuration, onSizeUpdated } = this.props;
|
|
150
|
+ const { enableAnimation, animationDuration, animationEasing, onSizeUpdated, heightOffset } = this.props;
|
141
|
151
|
if (enableAnimation) {
|
142
|
|
- Animated.timing(this.opacityAnimatedValue, {
|
143
|
|
- toValue: 1,
|
144
|
|
- duration: animationDuration
|
145
|
|
- }).start(() => {
|
|
152
|
+ Animated.parallel([
|
|
153
|
+ Animated.timing(heightValue, {
|
|
154
|
+ toValue: height + heightOffset,
|
|
155
|
+ easing: animationEasing,
|
|
156
|
+ duration: animationDuration
|
|
157
|
+ }),
|
|
158
|
+ Animated.timing(widthValue, {
|
|
159
|
+ toValue: width,
|
|
160
|
+ easing: animationEasing,
|
|
161
|
+ duration: animationDuration
|
|
162
|
+ })
|
|
163
|
+ ]).start(() => {
|
146
|
164
|
handleSizeUpdated(height, width, onSizeUpdated);
|
147
|
165
|
});
|
148
|
166
|
} else {
|
|
@@ -178,6 +196,9 @@ export default class AutoHeightWebView extends PureComponent {
|
178
|
196
|
}
|
179
|
197
|
|
180
|
198
|
startInterval() {
|
|
199
|
+ if (this.finishInterval === false) {
|
|
200
|
+ return;
|
|
201
|
+ }
|
181
|
202
|
this.finishInterval = false;
|
182
|
203
|
this.interval = setInterval(() => {
|
183
|
204
|
if (!this.finishInterval) {
|
|
@@ -198,7 +219,6 @@ export default class AutoHeightWebView extends PureComponent {
|
198
|
219
|
const { height, width } = JSON.parse(isBelowKitKat ? e.nativeEvent.message : e.nativeEvent.data);
|
199
|
220
|
const { height: oldHeight, width: oldWidth } = this.state;
|
200
|
221
|
if (isSizeChanged(height, oldHeight, width, oldWidth)) {
|
201
|
|
- this.props.enableAnimation && this.opacityAnimatedValue.setValue(0);
|
202
|
222
|
this.stopInterval();
|
203
|
223
|
this.setState({
|
204
|
224
|
isSizeChanged: true,
|
|
@@ -239,16 +259,15 @@ export default class AutoHeightWebView extends PureComponent {
|
239
|
259
|
getWebView = webView => (this.webView = webView);
|
240
|
260
|
|
241
|
261
|
render() {
|
242
|
|
- const { height, width, script, source } = this.state;
|
243
|
|
- const { scalesPageToFit, style, scrollEnabled, heightOffset } = this.props;
|
|
262
|
+ const { height, width, script, source, heightValue, widthValue } = this.state;
|
|
263
|
+ const { scalesPageToFit, style, scrollEnabled, heightOffset, enableAnimation } = this.props;
|
244
|
264
|
return (
|
245
|
|
- <View
|
|
265
|
+ <Animated.View
|
246
|
266
|
style={[
|
247
|
267
|
styles.container,
|
248
|
268
|
{
|
249
|
|
- opacity: 1,
|
250
|
|
- height: height ? height + heightOffset : 0,
|
251
|
|
- width: width
|
|
269
|
+ height: enableAnimation ? heightValue : height ? height + heightOffset : 0,
|
|
270
|
+ width: enableAnimation ? widthValue : width
|
252
|
271
|
},
|
253
|
272
|
style
|
254
|
273
|
]}
|
|
@@ -270,7 +289,7 @@ export default class AutoHeightWebView extends PureComponent {
|
270
|
289
|
// below kitkat
|
271
|
290
|
onChange={this.onMessage}
|
272
|
291
|
/>
|
273
|
|
- </View>
|
|
292
|
+ </Animated.View>
|
274
|
293
|
);
|
275
|
294
|
}
|
276
|
295
|
}
|
|
@@ -289,11 +308,13 @@ const styles = StyleSheet.create({
|
289
|
308
|
|
290
|
309
|
const commonScript = `
|
291
|
310
|
${getCurrentSize}
|
292
|
|
- var wrapper = document.createElement('div');
|
293
|
|
- wrapper.id = 'wrapper';
|
|
311
|
+ var wrapper = document.createElement("div");
|
|
312
|
+ wrapper.id = "wrapper";
|
294
|
313
|
while (document.body.firstChild instanceof Node) {
|
295
|
314
|
wrapper.appendChild(document.body.firstChild);
|
296
|
315
|
}
|
|
316
|
+ document.body.appendChild(wrapper);
|
|
317
|
+ var height = 0;
|
297
|
318
|
`;
|
298
|
319
|
|
299
|
320
|
const getBaseScript = isBelowKitKat
|
|
@@ -301,7 +322,6 @@ const getBaseScript = isBelowKitKat
|
301
|
322
|
return `
|
302
|
323
|
;
|
303
|
324
|
${commonScript}
|
304
|
|
- var height = 0;
|
305
|
325
|
var width = ${getWidth(style)};
|
306
|
326
|
function updateSize() {
|
307
|
327
|
if(document.body.offsetHeight !== height || document.body.offsetWidth !== width) {
|
|
@@ -312,7 +332,6 @@ const getBaseScript = isBelowKitKat
|
312
|
332
|
}
|
313
|
333
|
}
|
314
|
334
|
(function () {
|
315
|
|
- document.body.appendChild(wrapper);
|
316
|
335
|
AutoHeightWebView.onMessage = updateSize;
|
317
|
336
|
${domMutationObserveScript}
|
318
|
337
|
} ());
|
|
@@ -322,19 +341,17 @@ const getBaseScript = isBelowKitKat
|
322
|
341
|
return `
|
323
|
342
|
;
|
324
|
343
|
${commonScript}
|
325
|
|
- var height = 0;
|
326
|
344
|
var width = ${getWidth(style)};
|
327
|
345
|
function updateSize() {
|
328
|
346
|
if(document.body.offsetHeight !== height || document.body.offsetWidth !== width) {
|
329
|
347
|
var size = getSize(document.body.firstChild);
|
330
|
348
|
height = size.height;
|
331
|
349
|
width = size.width;
|
332
|
|
- window.postMessage(JSON.stringify({ width, height }));
|
|
350
|
+ window.postMessage(JSON.stringify({ width, height }), '*');
|
333
|
351
|
}
|
334
|
352
|
}
|
335
|
353
|
(function () {
|
336
|
|
- document.body.appendChild(wrapper);
|
337
|
|
- document.addEventListener('message', updateSize);
|
|
354
|
+ document.addEventListener("message", updateSize);
|
338
|
355
|
${domMutationObserveScript}
|
339
|
356
|
} ());
|
340
|
357
|
`;
|