説明なし

WebViewShared.tsx 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import escapeStringRegexp from 'escape-string-regexp';
  2. import React from 'react';
  3. import {
  4. Linking,
  5. UIManager as NotTypedUIManager,
  6. View,
  7. ActivityIndicator,
  8. Text,
  9. } from 'react-native';
  10. import {
  11. WebViewNavigationEvent,
  12. OnShouldStartLoadWithRequest,
  13. CustomUIManager,
  14. } from './WebViewTypes';
  15. import styles from './WebView.styles';
  16. const UIManager = NotTypedUIManager as CustomUIManager;
  17. const defaultOriginWhitelist = ['http://*', 'https://*'];
  18. const extractOrigin = (url: string): string => {
  19. const result = /^[A-Za-z][A-Za-z0-9+\-.]+:(\/\/)?[^/]*/.exec(url);
  20. return result === null ? '' : result[0];
  21. };
  22. const originWhitelistToRegex = (originWhitelist: string): string =>
  23. `^${escapeStringRegexp(originWhitelist).replace(/\\\*/g, '.*')}`;
  24. const passesWhitelist = (
  25. compiledWhitelist: ReadonlyArray<string>,
  26. url: string,
  27. ) => {
  28. const origin = extractOrigin(url);
  29. return compiledWhitelist.some(x => new RegExp(x).test(origin));
  30. };
  31. const compileWhitelist = (
  32. originWhitelist: ReadonlyArray<string>,
  33. ): ReadonlyArray<string> =>
  34. ['about:blank', ...(originWhitelist || [])].map(originWhitelistToRegex);
  35. const createOnShouldStartLoadWithRequest = (
  36. loadRequest: (
  37. shouldStart: boolean,
  38. url: string,
  39. lockIdentifier: number,
  40. ) => void,
  41. originWhitelist: ReadonlyArray<string>,
  42. onShouldStartLoadWithRequest?: OnShouldStartLoadWithRequest,
  43. ) => {
  44. return ({ nativeEvent }: WebViewNavigationEvent) => {
  45. let shouldStart = true;
  46. const { url, lockIdentifier } = nativeEvent;
  47. if (!passesWhitelist(compileWhitelist(originWhitelist), url)) {
  48. Linking.openURL(url);
  49. shouldStart = false;
  50. }
  51. if (onShouldStartLoadWithRequest) {
  52. shouldStart = onShouldStartLoadWithRequest(nativeEvent);
  53. }
  54. loadRequest(shouldStart, url, lockIdentifier);
  55. };
  56. };
  57. const getViewManagerConfig = (
  58. viewManagerName: 'RNCUIWebView' | 'RNCWKWebView' | 'RNCWebView',
  59. ) => {
  60. if (!UIManager.getViewManagerConfig) {
  61. return UIManager[viewManagerName];
  62. }
  63. return UIManager.getViewManagerConfig(viewManagerName);
  64. };
  65. const defaultRenderLoading = () => (
  66. <View style={styles.loadingView}>
  67. <ActivityIndicator />
  68. </View>
  69. );
  70. const defaultRenderError = (
  71. errorDomain: string | undefined,
  72. errorCode: number,
  73. errorDesc: string,
  74. ) => (
  75. <View style={styles.errorContainer}>
  76. <Text style={styles.errorTextTitle}>Error loading page</Text>
  77. <Text style={styles.errorText}>{`Domain: ${errorDomain}`}</Text>
  78. <Text style={styles.errorText}>{`Error Code: ${errorCode}`}</Text>
  79. <Text style={styles.errorText}>{`Description: ${errorDesc}`}</Text>
  80. </View>
  81. );
  82. export {
  83. defaultOriginWhitelist,
  84. createOnShouldStartLoadWithRequest,
  85. getViewManagerConfig,
  86. defaultRenderLoading,
  87. defaultRenderError,
  88. };