Browse Source

Use es6 class instead of createClass

Kai Guo 4 years ago
parent
commit
a8bb6334c0
2 changed files with 144 additions and 98 deletions
  1. 129
    98
      src/WebView.windows.tsx
  2. 15
    0
      src/WebViewTypes.ts

+ 129
- 98
src/WebView.windows.tsx View File

@@ -17,58 +17,62 @@ import {
17 17
   requireNativeComponent,
18 18
   StyleSheet,
19 19
   Image,
20
+  ImageSourcePropType,
20 21
   findNodeHandle,
21 22
 } from 'react-native';
22 23
 import {
24
+  createOnShouldStartLoadWithRequest,
25
+} from './WebViewShared';
26
+import {
27
+  NativeWebViewWindows,
28
+  WindowsWebViewProps,
29
+  WebViewProgressEvent,
23 30
   WebViewNavigationEvent,
31
+  WebViewErrorEvent,
32
+  WebViewHttpErrorEvent,
33
+  WebViewMessageEvent,
24 34
   RNCWebViewUIManagerWindows,
35
+  State,
25 36
 } from './WebViewTypes';
26 37
 
27 38
 const UIManager = NotTypedUIManager as RNCWebViewUIManagerWindows;
28
-var keyMirror = require('fbjs/lib/keyMirror');
29 39
 const { resolveAssetSource } = Image;
30
-
31
-const createReactClass = require('create-react-class');
32
-
33
-var RCT_WEBVIEW_REF = 'webview';
34
-
35
-var WebViewState = keyMirror({
36
-  IDLE: null,
37
-  LOADING: null,
38
-  ERROR: null,
39
-});
40
-
41
-/**
42
- * Renders a native WebView.
43
- */
44
-var WebView = createReactClass({
45
-  getInitialState: function() {
46
-    return {
47
-      viewState: WebViewState.IDLE,
48
-      lastErrorEvent: null,
49
-      startInLoadingState: true,
50
-    };
51
-  },
52
-
53
-  getDefaultProps: function() {
54
-    return {
55
-      javaScriptEnabled: true,
56
-    };
57
-  },
58
-
59
-  componentDidMount: function() {
60
-    if (this.props.startInLoadingState) {
61
-      this.setState({viewState: WebViewState.LOADING});
62
-    }
63
-  },
64
-
65
-  render: function() {
66
-    var otherView = null;
67
-
68
-    if (this.state.viewState === WebViewState.LOADING) {
40
+const RCTWebView: typeof NativeWebViewWindows = requireNativeComponent(
41
+  'RCTWebView',
42
+);
43
+
44
+export default class WebView extends React.Component<WindowsWebViewProps, State> {
45
+
46
+  static defaultProps = {
47
+    javaScriptEnabled: true,
48
+  };
49
+
50
+  state: State = {
51
+    viewState: this.props.startInLoadingState ? 'LOADING' : 'IDLE',
52
+    lastErrorEvent: null,
53
+  }
54
+
55
+  webViewRef = React.createRef<NativeWebViewWindows>();
56
+
57
+  render = () => {
58
+    const {
59
+      nativeConfig = {},
60
+      onMessage,
61
+      onShouldStartLoadWithRequest: onShouldStartLoadWithRequestProp,
62
+      originWhitelist,
63
+      renderError,
64
+      renderLoading,
65
+      style,
66
+      containerStyle,
67
+      ...otherProps
68
+    } = this.props;
69
+
70
+    let otherView = null;
71
+
72
+    if (this.state.viewState === 'LOADING') {
69 73
       otherView = this.props.renderLoading && this.props.renderLoading();
70
-    } else if (this.state.viewState === WebViewState.ERROR) {
71
-      var errorEvent = this.state.lastErrorEvent;
74
+    } else if (this.state.viewState === 'ERROR') {
75
+      const errorEvent = this.state.lastErrorEvent;
72 76
       otherView =
73 77
         this.props.renderError &&
74 78
         this.props.renderError(
@@ -76,48 +80,49 @@ var WebView = createReactClass({
76 80
           errorEvent.code,
77 81
           errorEvent.description,
78 82
         );
79
-    } else if (this.state.viewState !== WebViewState.IDLE) {
83
+    } else if (this.state.viewState !== 'IDLE') {
80 84
       console.error(
81
-        'RCTWebView invalid state encountered: ' + this.state.loading,
85
+        'RCTWebView invalid state encountered: ' + this.state.viewState,
82 86
       );
83 87
     }
84 88
 
85
-    var webViewStyles = [styles.container, this.props.style];
89
+    let webViewStyles = [styles.container, this.props.style];
86 90
     if (
87
-      this.state.viewState === WebViewState.LOADING ||
88
-      this.state.viewState === WebViewState.ERROR
91
+      this.state.viewState === 'LOADING' ||
92
+      this.state.viewState === 'ERROR'
89 93
     ) {
90 94
       // if we're in either LOADING or ERROR states, don't show the webView
91 95
       webViewStyles.push(styles.hidden);
92 96
     }
93 97
 
94
-    var source = this.props.source || {};
95
-    if (this.props.html) {
96
-      source.html = this.props.html;
97
-    } else if (this.props.url) {
98
-      source.uri = this.props.url;
99
-    }
98
+    const onShouldStartLoadWithRequest = createOnShouldStartLoadWithRequest(
99
+      this.onShouldStartLoadWithRequestCallback,
100
+      // casting cause it's in the default props
101
+      originWhitelist as readonly string[],
102
+      onShouldStartLoadWithRequestProp,
103
+    );
104
+
105
+    const NativeWebView
106
+    = (nativeConfig.component as typeof NativeWebViewWindows | undefined)
107
+    || RCTWebView;
100 108
 
101
-    var webView = (
102
-      <RCTWebView
103
-        ref={RCT_WEBVIEW_REF}
109
+    const webView = (
110
+      <NativeWebView
111
+        ref={this.webViewRef}
104 112
         key="webViewKey"
105
-        style={webViewStyles}
106
-        source={resolveAssetSource(source)}
107
-        injectedJavaScript={this.props.injectedJavaScript}
108
-        javaScriptEnabled={this.props.javaScriptEnabled}
109
-        indexedDbEnabled={this.props.indexedDbEnabled}
110
-        contentInset={this.props.contentInset}
111
-        automaticallyAdjustContentInsets={
112
-          this.props.automaticallyAdjustContentInsets
113
-        }
114
-        onLoadingStart={this.onLoadingStart}
115
-        onLoadingFinish={this.onLoadingFinish}
113
+        {...otherProps}
114
+        messagingEnabled={typeof onMessage === 'function'}
116 115
         onLoadingError={this.onLoadingError}
117
-        goBack={this.goBack}
118
-        goForward={this.goForward}
119
-        reload={this.reload}
120
-        testID={this.props.testID}
116
+        onLoadingFinish={this.onLoadingFinish}
117
+        onLoadingProgress={this.onLoadingProgress}
118
+        onLoadingStart={this.onLoadingStart}
119
+        onHttpError={this.onHttpError}
120
+        onMessage={this.onMessage}
121
+        onScroll={this.props.onScroll}
122
+        onShouldStartLoadWithRequest={onShouldStartLoadWithRequest}
123
+        source={resolveAssetSource(this.props.source as ImageSourcePropType)}
124
+        style={webViewStyles}
125
+        {...nativeConfig.props}
121 126
       />
122 127
     );
123 128
 
@@ -127,80 +132,106 @@ var WebView = createReactClass({
127 132
         {otherView}
128 133
       </View>
129 134
     );
130
-  },
135
+  }
131 136
 
132
-  goForward: function() {
137
+  goForward = () => {
133 138
     UIManager.dispatchViewManagerCommand(
134 139
       this.getWebViewHandle(),
135 140
       UIManager.getViewManagerConfig('RCTWebView').Commands.goForward,
136 141
       undefined,
137 142
     );
138
-  },
143
+  }
139 144
 
140
-  goBack: function() {
145
+  goBack = () => {
141 146
     UIManager.dispatchViewManagerCommand(
142 147
       this.getWebViewHandle(),
143 148
       UIManager.getViewManagerConfig('RCTWebView').Commands.goBack,
144 149
       undefined,
145 150
     );
146
-  },
151
+  }
147 152
 
148
-  reload: function() {
153
+  reload = () => {
149 154
     UIManager.dispatchViewManagerCommand(
150 155
       this.getWebViewHandle(),
151 156
       UIManager.getViewManagerConfig('RCTWebView').Commands.reload,
152 157
       undefined,
153 158
     );
154
-  },
159
+  }
155 160
 
156 161
   /**
157 162
    * We return an event with a bunch of fields including:
158 163
    *  url, title, loading, canGoBack, canGoForward
159 164
    */
160
-  updateNavigationState: function(event: WebViewNavigationEvent) {
165
+  updateNavigationState = (event: WebViewNavigationEvent) => {
161 166
     if (this.props.onNavigationStateChange) {
162 167
       this.props.onNavigationStateChange(event.nativeEvent);
163 168
     }
164
-  },
169
+  }
165 170
 
166
-  getWebViewHandle: function() {
171
+  getWebViewHandle = () => {
167 172
     // eslint-disable-next-line react/no-string-refs
168
-    return findNodeHandle(this.refs[RCT_WEBVIEW_REF]);
169
-  },
173
+    return findNodeHandle(this.webViewRef.current);
174
+  }
170 175
 
171
-  onLoadingStart: function(event: WebViewNavigationEvent) {
172
-    var onLoadStart = this.props.onLoadStart;
176
+  onLoadingStart = (event: WebViewNavigationEvent) => {
177
+    const { onLoadStart } = this.props;
173 178
     onLoadStart && onLoadStart(event);
174 179
     this.updateNavigationState(event);
175
-  },
180
+  }
176 181
 
177
-  onLoadingError: function(event: WebViewNavigationEvent) {
182
+  onLoadingProgress = (event: WebViewProgressEvent) => {
183
+    const { onLoadProgress } = this.props;
184
+    if (onLoadProgress) {
185
+      onLoadProgress(event);
186
+    }
187
+  };
188
+
189
+  onLoadingError = (event: WebViewErrorEvent) => {
178 190
     event.persist(); // persist this event because we need to store it
179
-    var {onError, onLoadEnd} = this.props;
191
+    const {onError, onLoadEnd} = this.props;
180 192
     onError && onError(event);
181 193
     onLoadEnd && onLoadEnd(event);
182 194
     console.error('Encountered an error loading page', event.nativeEvent);
183
-    // $FlowFixMe : Not sure what the issue here is, disabling to get flow check turned on
184 195
     this.setState({
185 196
       lastErrorEvent: event.nativeEvent,
186
-      viewState: WebViewState.ERROR,
197
+      viewState: 'ERROR',
187 198
     });
188
-  },
199
+  }
189 200
 
190
-  onLoadingFinish: function(event: WebViewNavigationEvent) {
191
-    var {onLoad, onLoadEnd} = this.props;
201
+  onLoadingFinish =(event: WebViewNavigationEvent) => {
202
+    const {onLoad, onLoadEnd} = this.props;
192 203
     onLoad && onLoad(event);
193 204
     onLoadEnd && onLoadEnd(event);
194 205
     this.setState({
195
-      viewState: WebViewState.IDLE,
206
+      viewState: 'IDLE',
196 207
     });
197 208
     this.updateNavigationState(event);
198
-  },
199
-});
209
+  }
210
+
211
+  onMessage = (event: WebViewMessageEvent) => {
212
+    const { onMessage } = this.props;
213
+    if (onMessage) {
214
+      onMessage(event);
215
+    }
216
+  };
217
+
218
+  onHttpError = (event: WebViewHttpErrorEvent) => {
219
+    const { onHttpError } = this.props;
220
+    if (onHttpError) {
221
+      onHttpError(event);
222
+    }
223
+  }
224
+
225
+  onShouldStartLoadWithRequestCallback = (
226
+    _shouldStart: boolean,
227
+    _url: string,
228
+    _lockIdentifier: number,
229
+  ) => {
230
+  };
200 231
 
201
-var RCTWebView = requireNativeComponent('RCTWebView');
232
+}
202 233
 
203
-var styles = StyleSheet.create({
234
+const styles = StyleSheet.create({
204 235
   container: {
205 236
     flex: 1,
206 237
   },

+ 15
- 0
src/WebViewTypes.ts View File

@@ -74,6 +74,14 @@ declare const NativeWebViewAndroidBase: Constructor<NativeMethodsMixin> &
74 74
   typeof NativeWebViewAndroidComponent;
75 75
 export class NativeWebViewAndroid extends NativeWebViewAndroidBase {}
76 76
 
77
+// eslint-disable-next-line react/prefer-stateless-function
78
+declare class NativeWebViewWindowsComponent extends Component<
79
+  WindowsNativeWebViewProps
80
+> {}
81
+declare const NativeWebViewWindowsBase: Constructor<NativeMethodsMixin> &
82
+  typeof NativeWebViewWindowsComponent;
83
+export class NativeWebViewWindows extends NativeWebViewWindowsBase {}
84
+
77 85
 export interface ContentInsetProp {
78 86
   top?: number;
79 87
   left?: number;
@@ -310,6 +318,10 @@ export interface MacOSNativeWebViewProps extends CommonNativeWebViewProps {
310 318
   onContentProcessDidTerminate?: (event: WebViewTerminatedEvent) => void;
311 319
 }
312 320
 
321
+export interface WindowsNativeWebViewProps extends CommonNativeWebViewProps {
322
+  testID?:string
323
+}
324
+
313 325
 export interface IOSWebViewProps extends WebViewSharedProps {
314 326
   /**
315 327
    * Does not store any data within the lifetime of the WebView.
@@ -754,6 +766,9 @@ export interface AndroidWebViewProps extends WebViewSharedProps {
754 766
   allowsFullscreenVideo?: boolean;
755 767
 }
756 768
 
769
+export interface WindowsWebViewProps extends WebViewSharedProps{
770
+}
771
+
757 772
 export interface WebViewSharedProps extends ViewProps {
758 773
   /**
759 774
    * Loads static html or a uri (with optional headers) in the WebView.