|
@@ -20,6 +20,8 @@ import PropTypes from 'prop-types';
|
20
|
20
|
|
21
|
21
|
import Immutable from 'immutable';
|
22
|
22
|
|
|
23
|
+import { getScript, onHeightUpdated, DomMutationObserveScript } from './common.js';
|
|
24
|
+
|
23
|
25
|
const RCTAutoHeightWebView = requireNativeComponent('RCTAutoHeightWebView', AutoHeightWebView, {
|
24
|
26
|
nativeOnly: {
|
25
|
27
|
nativeOnly: {
|
|
@@ -72,27 +74,17 @@ export default class AutoHeightWebView extends PureComponent {
|
72
|
74
|
|
73
|
75
|
constructor(props) {
|
74
|
76
|
super(props);
|
75
|
|
- this.onMessage = this.onMessage.bind(this);
|
76
|
|
- if (this.props.enableAnimation) {
|
77
|
|
- this.opacityAnimatedValue = new Animated.Value(0);
|
78
|
|
- }
|
79
|
|
- if (IsBelowKitKat) {
|
80
|
|
- this.listenWebViewBridgeMessage = this.listenWebViewBridgeMessage.bind(this);
|
81
|
|
- }
|
82
|
|
- let initialScript = props.files ? this.appendFilesToHead(props.files, BaseScript) : BaseScript;
|
83
|
|
- initialScript = props.customStyle ? this.appendStylesToHead(props.customStyle, initialScript) : initialScript;
|
|
77
|
+ props.enableAnimation && (this.opacityAnimatedValue = new Animated.Value(0));
|
84
|
78
|
this.state = {
|
85
|
79
|
isChangingSource: false,
|
86
|
80
|
height: 0,
|
87
|
81
|
heightOffset: 0,
|
88
|
|
- script: initialScript
|
|
82
|
+ script: getScript(props, BaseScript)
|
89
|
83
|
};
|
90
|
84
|
}
|
91
|
85
|
|
92
|
86
|
componentWillMount() {
|
93
|
|
- if (IsBelowKitKat) {
|
94
|
|
- DeviceEventEmitter.addListener('webViewBridgeMessage', this.listenWebViewBridgeMessage);
|
95
|
|
- }
|
|
87
|
+ IsBelowKitKat && DeviceEventEmitter.addListener('webViewBridgeMessage', this.listenWebViewBridgeMessage);
|
96
|
88
|
}
|
97
|
89
|
|
98
|
90
|
componentDidMount() {
|
|
@@ -116,27 +108,16 @@ export default class AutoHeightWebView extends PureComponent {
|
116
|
108
|
}
|
117
|
109
|
);
|
118
|
110
|
}
|
119
|
|
- let currentScript = BaseScript;
|
120
|
|
- if (nextProps.files) {
|
121
|
|
- currentScript = this.appendFilesToHead(nextProps.files, BaseScript);
|
122
|
|
- }
|
123
|
|
- currentScript = nextProps.customStyle
|
124
|
|
- ? this.appendStylesToHead(nextProps.customStyle, currentScript)
|
125
|
|
- : currentScript;
|
126
|
|
- this.setState({ script: currentScript });
|
|
111
|
+ this.setState({ script: getScript(nextProps, BaseScript) });
|
127
|
112
|
}
|
128
|
113
|
|
129
|
114
|
componentWillUnmount() {
|
130
|
115
|
this.stopInterval();
|
131
|
|
- if (IsBelowKitKat) {
|
132
|
|
- DeviceEventEmitter.removeListener('webViewBridgeMessage', this.listenWebViewBridgeMessage);
|
133
|
|
- }
|
|
116
|
+ IsBelowKitKat && DeviceEventEmitter.removeListener('webViewBridgeMessage', this.listenWebViewBridgeMessage);
|
134
|
117
|
}
|
135
|
118
|
|
136
|
119
|
// below kitkat
|
137
|
|
- listenWebViewBridgeMessage(body) {
|
138
|
|
- this.onMessage(body.message);
|
139
|
|
- }
|
|
120
|
+ listenWebViewBridgeMessage = body => this.onMessage(body.message);
|
140
|
121
|
|
141
|
122
|
// below kitkat
|
142
|
123
|
sendToWebView(message) {
|
|
@@ -169,84 +150,47 @@ export default class AutoHeightWebView extends PureComponent {
|
169
|
150
|
clearInterval(this.interval);
|
170
|
151
|
}
|
171
|
152
|
|
172
|
|
- onHeightUpdated(height) {
|
173
|
|
- if (this.props.onHeightUpdated) {
|
174
|
|
- this.props.onHeightUpdated(height);
|
175
|
|
- }
|
176
|
|
- }
|
177
|
|
-
|
178
|
|
- onMessage(e) {
|
|
153
|
+ onMessage = e => {
|
179
|
154
|
const height = parseInt(IsBelowKitKat ? e.nativeEvent.message : e.nativeEvent.data);
|
180
|
155
|
if (height) {
|
181
|
|
- if (this.props.enableAnimation) {
|
|
156
|
+ const { enableAnimation, animationDuration, heightOffset } = this.props;
|
|
157
|
+ if (enableAnimation) {
|
182
|
158
|
this.opacityAnimatedValue.setValue(0);
|
183
|
159
|
}
|
184
|
160
|
this.stopInterval();
|
185
|
161
|
this.setState(
|
186
|
162
|
{
|
187
|
|
- heightOffset: this.props.heightOffset,
|
|
163
|
+ heightOffset,
|
188
|
164
|
height
|
189
|
165
|
},
|
190
|
166
|
() => {
|
191
|
|
- if (this.props.enableAnimation) {
|
|
167
|
+ if (enableAnimation) {
|
192
|
168
|
Animated.timing(this.opacityAnimatedValue, {
|
193
|
169
|
toValue: 1,
|
194
|
|
- duration: this.props.animationDuration
|
195
|
|
- }).start(() => this.onHeightUpdated(height));
|
|
170
|
+ duration: animationDuration
|
|
171
|
+ }).start(() => onHeightUpdated(height, this.props));
|
196
|
172
|
} else {
|
197
|
|
- this.onHeightUpdated(height);
|
|
173
|
+ onHeightUpdated(height, this.props);
|
198
|
174
|
}
|
199
|
175
|
}
|
200
|
176
|
);
|
201
|
177
|
}
|
202
|
|
- }
|
203
|
|
-
|
204
|
|
- appendFilesToHead(files, script) {
|
205
|
|
- if (!files) {
|
206
|
|
- return script;
|
207
|
|
- }
|
208
|
|
- return files.reduceRight(
|
209
|
|
- (file, combinedScript) => `
|
210
|
|
- var link = document.createElement('link');
|
211
|
|
- link.rel = '${file.rel}';
|
212
|
|
- link.type = '${file.type}';
|
213
|
|
- link.href = '${file.href}';
|
214
|
|
- document.head.appendChild(link);
|
215
|
|
- ${combinedScript}
|
216
|
|
- `,
|
217
|
|
- script
|
218
|
|
- );
|
219
|
|
- }
|
220
|
|
-
|
221
|
|
- appendStylesToHead(styles, script) {
|
222
|
|
- if (!styles) {
|
223
|
|
- return script;
|
224
|
|
- }
|
225
|
|
- // Escape any single quotes or newlines in the CSS with .replace()
|
226
|
|
- const escaped = styles.replace(/\'/g, "\\'").replace(/\n/g, '\\n');
|
227
|
|
- return `
|
228
|
|
- var styleElement = document.createElement('style');
|
229
|
|
- var styleText = document.createTextNode('${escaped}');
|
230
|
|
- styleElement.appendChild(styleText);
|
231
|
|
- document.head.appendChild(styleElement);
|
232
|
|
- ${script}
|
233
|
|
- `;
|
234
|
|
- }
|
|
178
|
+ };
|
235
|
179
|
|
236
|
180
|
onLoadingStart = event => {
|
237
|
|
- var onLoadStart = this.props.onLoadStart;
|
|
181
|
+ const { onLoadStart } = this.props;
|
238
|
182
|
onLoadStart && onLoadStart(event);
|
239
|
183
|
};
|
240
|
184
|
|
241
|
185
|
onLoadingError = event => {
|
242
|
|
- var { onError, onLoadEnd } = this.props;
|
|
186
|
+ const { onError, onLoadEnd } = this.props;
|
243
|
187
|
onError && onError(event);
|
244
|
188
|
onLoadEnd && onLoadEnd(event);
|
245
|
189
|
console.warn('Encountered an error loading page', event.nativeEvent);
|
246
|
190
|
};
|
247
|
191
|
|
248
|
192
|
onLoadingFinish = event => {
|
249
|
|
- var { onLoad, onLoadEnd } = this.props;
|
|
193
|
+ const { onLoad, onLoadEnd } = this.props;
|
250
|
194
|
onLoad && onLoad(event);
|
251
|
195
|
onLoadEnd && onLoadEnd(event);
|
252
|
196
|
};
|
|
@@ -324,14 +268,7 @@ const BaseScript = IsBelowKitKat
|
324
|
268
|
AutoHeightWebView.onMessage = function (message) {
|
325
|
269
|
AutoHeightWebView.send(String(document.body.offsetHeight));
|
326
|
270
|
};
|
327
|
|
- MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
|
328
|
|
- var observer = new MutationObserver(function() {
|
329
|
|
- AutoHeightWebView.send(String(document.body.offsetHeight));
|
330
|
|
- });
|
331
|
|
- observer.observe(document, {
|
332
|
|
- subtree: true,
|
333
|
|
- attributes: true
|
334
|
|
- });
|
|
271
|
+ ${DomMutationObserveScript}
|
335
|
272
|
} ());
|
336
|
273
|
`
|
337
|
274
|
: `
|
|
@@ -339,13 +276,6 @@ const BaseScript = IsBelowKitKat
|
339
|
276
|
document.addEventListener('message', function (e) {
|
340
|
277
|
window.postMessage(String(document.body.offsetHeight));
|
341
|
278
|
});
|
342
|
|
- MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
|
343
|
|
- var observer = new MutationObserver(function() {
|
344
|
|
- window.postMessage(String(document.body.offsetHeight));
|
345
|
|
- });
|
346
|
|
- observer.observe(document, {
|
347
|
|
- subtree: true,
|
348
|
|
- attributes: true
|
349
|
|
- });
|
|
279
|
+ ${DomMutationObserveScript}
|
350
|
280
|
} ());
|
351
|
281
|
`;
|