|
@@ -1,3 +1,13 @@
|
|
1
|
+/**
|
|
2
|
+ * Copyright (c) 2015-present, Facebook, Inc.
|
|
3
|
+ *
|
|
4
|
+ * This source code is licensed under the MIT license found in the
|
|
5
|
+ * LICENSE file in the root directory of this source tree.
|
|
6
|
+ *
|
|
7
|
+ * @format
|
|
8
|
+ * @noflow
|
|
9
|
+ */
|
|
10
|
+
|
1
|
11
|
'use strict';
|
2
|
12
|
|
3
|
13
|
import React from 'react';
|
|
@@ -73,6 +83,9 @@ const DataDetectorTypes = [
|
73
|
83
|
'link',
|
74
|
84
|
'address',
|
75
|
85
|
'calendarEvent',
|
|
86
|
+ 'trackingNumber',
|
|
87
|
+ 'flightNumber',
|
|
88
|
+ 'lookupSuggestion',
|
76
|
89
|
'none',
|
77
|
90
|
'all',
|
78
|
91
|
];
|
|
@@ -117,7 +130,7 @@ class WebView extends React.Component {
|
117
|
130
|
static JSNavigationScheme = JSNavigationScheme;
|
118
|
131
|
static NavigationType = NavigationType;
|
119
|
132
|
static propTypes = {
|
120
|
|
- ...ViewPropTypes,
|
|
133
|
+ ...DeprecatedViewPropTypes,
|
121
|
134
|
|
122
|
135
|
html: deprecatedPropType(
|
123
|
136
|
PropTypes.string,
|
|
@@ -169,6 +182,12 @@ class WebView extends React.Component {
|
169
|
182
|
PropTypes.number,
|
170
|
183
|
]),
|
171
|
184
|
|
|
185
|
+ /**
|
|
186
|
+ * If true, use WKWebView instead of UIWebView.
|
|
187
|
+ * @platform ios
|
|
188
|
+ */
|
|
189
|
+ useWebKit: PropTypes.bool,
|
|
190
|
+
|
172
|
191
|
/**
|
173
|
192
|
* Function that returns a view to show if there's an error.
|
174
|
193
|
*/
|
|
@@ -254,7 +273,7 @@ class WebView extends React.Component {
|
254
|
273
|
/**
|
255
|
274
|
* The style to apply to the `WebView`.
|
256
|
275
|
*/
|
257
|
|
- style: ViewPropTypes.style,
|
|
276
|
+ style: DeprecatedViewPropTypes.style,
|
258
|
277
|
|
259
|
278
|
/**
|
260
|
279
|
* Determines the types of data converted to clickable URLs in the web view's content.
|
|
@@ -271,6 +290,11 @@ class WebView extends React.Component {
|
271
|
290
|
* - `'none'`
|
272
|
291
|
* - `'all'`
|
273
|
292
|
*
|
|
293
|
+ * With the new WebKit implementation, we have three new values:
|
|
294
|
+ * - `'trackingNumber'`,
|
|
295
|
+ * - `'flightNumber'`,
|
|
296
|
+ * - `'lookupSuggestion'`,
|
|
297
|
+ *
|
274
|
298
|
* @platform ios
|
275
|
299
|
*/
|
276
|
300
|
dataDetectorTypes: PropTypes.oneOfType([
|
|
@@ -316,6 +340,8 @@ class WebView extends React.Component {
|
316
|
340
|
* Boolean that controls whether the web content is scaled to fit
|
317
|
341
|
* the view and enables the user to change the scale. The default value
|
318
|
342
|
* is `true`.
|
|
343
|
+ *
|
|
344
|
+ * On iOS, when `useWebKit=true`, this prop will not work.
|
319
|
345
|
*/
|
320
|
346
|
scalesPageToFit: PropTypes.bool,
|
321
|
347
|
|
|
@@ -395,7 +421,6 @@ class WebView extends React.Component {
|
395
|
421
|
|
396
|
422
|
static defaultProps = {
|
397
|
423
|
originWhitelist: WebViewShared.defaultOriginWhitelist,
|
398
|
|
- scalesPageToFit: true,
|
399
|
424
|
};
|
400
|
425
|
|
401
|
426
|
state = {
|
|
@@ -408,11 +433,28 @@ class WebView extends React.Component {
|
408
|
433
|
if (this.props.startInLoadingState) {
|
409
|
434
|
this.setState({ viewState: WebViewState.LOADING });
|
410
|
435
|
}
|
|
436
|
+
|
|
437
|
+ if (
|
|
438
|
+ this.props.useWebKit === true &&
|
|
439
|
+ this.props.scalesPageToFit !== undefined
|
|
440
|
+ ) {
|
|
441
|
+ console.warn(
|
|
442
|
+ 'The scalesPageToFit property is not supported when useWebKit = true',
|
|
443
|
+ );
|
|
444
|
+ }
|
411
|
445
|
}
|
412
|
446
|
|
413
|
447
|
render() {
|
414
|
448
|
let otherView = null;
|
415
|
449
|
|
|
450
|
+ let scalesPageToFit;
|
|
451
|
+
|
|
452
|
+ if (this.props.useWebKit) {
|
|
453
|
+ ({ scalesPageToFit } = this.props);
|
|
454
|
+ } else {
|
|
455
|
+ ({ scalesPageToFit = true } = this.props);
|
|
456
|
+ }
|
|
457
|
+
|
416
|
458
|
if (this.state.viewState === WebViewState.LOADING) {
|
417
|
459
|
otherView = (this.props.renderLoading || defaultRenderLoading)();
|
418
|
460
|
} else if (this.state.viewState === WebViewState.ERROR) {
|
|
@@ -425,7 +467,7 @@ class WebView extends React.Component {
|
425
|
467
|
);
|
426
|
468
|
} else if (this.state.viewState !== WebViewState.IDLE) {
|
427
|
469
|
console.error(
|
428
|
|
- 'RNCWebView invalid state encountered: ' + this.state.loading,
|
|
470
|
+ 'RCTWebView invalid state encountered: ' + this.state.loading,
|
429
|
471
|
);
|
430
|
472
|
}
|
431
|
473
|
|
|
@@ -440,11 +482,18 @@ class WebView extends React.Component {
|
440
|
482
|
|
441
|
483
|
const nativeConfig = this.props.nativeConfig || {};
|
442
|
484
|
|
443
|
|
- const viewManager = nativeConfig.viewManager || RNCWebViewManager;
|
|
485
|
+ let viewManager = nativeConfig.viewManager;
|
444
|
486
|
|
445
|
|
- const compiledWhitelist = (this.props.originWhitelist || []).map(
|
446
|
|
- WebViewShared.originWhitelistToRegex,
|
447
|
|
- );
|
|
487
|
+ if (this.props.useWebKit) {
|
|
488
|
+ viewManager = viewManager || RCTWKWebViewManager;
|
|
489
|
+ } else {
|
|
490
|
+ viewManager = viewManager || RCTWebViewManager;
|
|
491
|
+ }
|
|
492
|
+
|
|
493
|
+ const compiledWhitelist = [
|
|
494
|
+ 'about:blank',
|
|
495
|
+ ...(this.props.originWhitelist || []),
|
|
496
|
+ ].map(WebViewShared.originWhitelistToRegex);
|
448
|
497
|
const onShouldStartLoadWithRequest = (event) => {
|
449
|
498
|
let shouldStart = true;
|
450
|
499
|
const { url } = event.nativeEvent;
|
|
@@ -480,7 +529,13 @@ class WebView extends React.Component {
|
480
|
529
|
|
481
|
530
|
const messagingEnabled = typeof this.props.onMessage === 'function';
|
482
|
531
|
|
483
|
|
- const NativeWebView = nativeConfig.component || RNCWebView;
|
|
532
|
+ let NativeWebView = nativeConfig.component;
|
|
533
|
+
|
|
534
|
+ if (this.props.useWebKit) {
|
|
535
|
+ NativeWebView = NativeWebView || RCTWKWebView;
|
|
536
|
+ } else {
|
|
537
|
+ NativeWebView = NativeWebView || RCTWebView;
|
|
538
|
+ }
|
484
|
539
|
|
485
|
540
|
const webView = (
|
486
|
541
|
<NativeWebView
|
|
@@ -502,7 +557,7 @@ class WebView extends React.Component {
|
502
|
557
|
messagingEnabled={messagingEnabled}
|
503
|
558
|
onMessage={this._onMessage}
|
504
|
559
|
onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
|
505
|
|
- scalesPageToFit={this.props.scalesPageToFit}
|
|
560
|
+ scalesPageToFit={scalesPageToFit}
|
506
|
561
|
allowsInlineMediaPlayback={this.props.allowsInlineMediaPlayback}
|
507
|
562
|
mediaPlaybackRequiresUserAction={
|
508
|
563
|
this.props.mediaPlaybackRequiresUserAction
|
|
@@ -520,13 +575,21 @@ class WebView extends React.Component {
|
520
|
575
|
);
|
521
|
576
|
}
|
522
|
577
|
|
|
578
|
+ _getCommands() {
|
|
579
|
+ if (!this.props.useWebKit) {
|
|
580
|
+ return UIManager.RCTWebView.Commands;
|
|
581
|
+ }
|
|
582
|
+
|
|
583
|
+ return UIManager.RCTWKWebView.Commands;
|
|
584
|
+ }
|
|
585
|
+
|
523
|
586
|
/**
|
524
|
587
|
* Go forward one page in the web view's history.
|
525
|
588
|
*/
|
526
|
589
|
goForward = () => {
|
527
|
590
|
UIManager.dispatchViewManagerCommand(
|
528
|
591
|
this.getWebViewHandle(),
|
529
|
|
- UIManager.RNCWebView.Commands.goForward,
|
|
592
|
+ this._getCommands().goForward,
|
530
|
593
|
null,
|
531
|
594
|
);
|
532
|
595
|
};
|
|
@@ -537,7 +600,7 @@ class WebView extends React.Component {
|
537
|
600
|
goBack = () => {
|
538
|
601
|
UIManager.dispatchViewManagerCommand(
|
539
|
602
|
this.getWebViewHandle(),
|
540
|
|
- UIManager.RNCWebView.Commands.goBack,
|
|
603
|
+ this._getCommands().goBack,
|
541
|
604
|
null,
|
542
|
605
|
);
|
543
|
606
|
};
|
|
@@ -549,7 +612,7 @@ class WebView extends React.Component {
|
549
|
612
|
this.setState({ viewState: WebViewState.LOADING });
|
550
|
613
|
UIManager.dispatchViewManagerCommand(
|
551
|
614
|
this.getWebViewHandle(),
|
552
|
|
- UIManager.RNCWebView.Commands.reload,
|
|
615
|
+ this._getCommands().reload,
|
553
|
616
|
null,
|
554
|
617
|
);
|
555
|
618
|
};
|
|
@@ -560,7 +623,7 @@ class WebView extends React.Component {
|
560
|
623
|
stopLoading = () => {
|
561
|
624
|
UIManager.dispatchViewManagerCommand(
|
562
|
625
|
this.getWebViewHandle(),
|
563
|
|
- UIManager.RNCWebView.Commands.stopLoading,
|
|
626
|
+ this._getCommands().stopLoading,
|
564
|
627
|
null,
|
565
|
628
|
);
|
566
|
629
|
};
|
|
@@ -578,7 +641,7 @@ class WebView extends React.Component {
|
578
|
641
|
postMessage = data => {
|
579
|
642
|
UIManager.dispatchViewManagerCommand(
|
580
|
643
|
this.getWebViewHandle(),
|
581
|
|
- UIManager.RNCWebView.Commands.postMessage,
|
|
644
|
+ this._getCommands().postMessage,
|
582
|
645
|
[String(data)],
|
583
|
646
|
);
|
584
|
647
|
};
|
|
@@ -592,7 +655,7 @@ class WebView extends React.Component {
|
592
|
655
|
injectJavaScript = data => {
|
593
|
656
|
UIManager.dispatchViewManagerCommand(
|
594
|
657
|
this.getWebViewHandle(),
|
595
|
|
- UIManager.RNCWebView.Commands.injectJavaScript,
|
|
658
|
+ this._getCommands().injectJavaScript,
|
596
|
659
|
[data],
|
597
|
660
|
);
|
598
|
661
|
};
|
|
@@ -647,9 +710,42 @@ class WebView extends React.Component {
|
647
|
710
|
const { onMessage } = this.props;
|
648
|
711
|
onMessage && onMessage(event);
|
649
|
712
|
};
|
|
713
|
+
|
|
714
|
+ componentDidUpdate(prevProps) {
|
|
715
|
+ if (!(prevProps.useWebKit && this.props.useWebKit)) {
|
|
716
|
+ return;
|
|
717
|
+ }
|
|
718
|
+
|
|
719
|
+ this._showRedboxOnPropChanges(prevProps, 'allowsInlineMediaPlayback');
|
|
720
|
+ this._showRedboxOnPropChanges(prevProps, 'mediaPlaybackRequiresUserAction');
|
|
721
|
+ this._showRedboxOnPropChanges(prevProps, 'dataDetectorTypes');
|
|
722
|
+
|
|
723
|
+ if (this.props.scalesPageToFit !== undefined) {
|
|
724
|
+ console.warn(
|
|
725
|
+ 'The scalesPageToFit property is not supported when useWebKit = true',
|
|
726
|
+ );
|
|
727
|
+ }
|
|
728
|
+ }
|
|
729
|
+
|
|
730
|
+ _showRedboxOnPropChanges(prevProps, propName: string) {
|
|
731
|
+ if (this.props[propName] !== prevProps[propName]) {
|
|
732
|
+ console.error(
|
|
733
|
+ `Changes to property ${propName} do nothing after the initial render.`,
|
|
734
|
+ );
|
|
735
|
+ }
|
|
736
|
+ }
|
650
|
737
|
}
|
651
|
738
|
|
652
|
|
-const RNCWebView = requireNativeComponent('RNCWebView');
|
|
739
|
+const RCTWebView = requireNativeComponent(
|
|
740
|
+ 'RCTWebView',
|
|
741
|
+ WebView,
|
|
742
|
+ WebView.extraNativeComponentConfig,
|
|
743
|
+);
|
|
744
|
+const RCTWKWebView = requireNativeComponent(
|
|
745
|
+ 'RCTWKWebView',
|
|
746
|
+ WebView,
|
|
747
|
+ WebView.extraNativeComponentConfig,
|
|
748
|
+);
|
653
|
749
|
|
654
|
750
|
const styles = StyleSheet.create({
|
655
|
751
|
container: {
|