Преглед на файлове

🦉 WIP: Update to WKWebView - WebView.ios.js

Jamon Holmgren преди 5 години
родител
ревизия
86ec597ea2
променени са 1 файла, в които са добавени 113 реда и са изтрити 17 реда
  1. 113
    17
      js/WebView.ios.js

+ 113
- 17
js/WebView.ios.js Целия файл

@@ -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: {