wip
This commit is contained in:
parent
2072aac5ee
commit
2e4cb88132
55
.eslintrc.js
55
.eslintrc.js
|
@ -1,8 +1,8 @@
|
|||
module.exports = {
|
||||
// Airbnb is the base, prettier is here so that eslint doesn't conflict with prettier
|
||||
extends: ['airbnb', 'prettier'],
|
||||
parser: 'babel-eslint',
|
||||
plugins: ['react', 'import'],
|
||||
extends: ['airbnb-base', 'prettier', 'prettier/react'],
|
||||
parser: 'typescript-eslint-parser',
|
||||
plugins: ['react', 'react-native', 'typescript'],
|
||||
rules: {
|
||||
// Parens will be needed for arrow functions
|
||||
'arrow-parens': ['error', 'as-needed', { requireForBlockBody: true }],
|
||||
|
@ -14,7 +14,7 @@ module.exports = {
|
|||
{ devDependencies: true, peerDependencies: true },
|
||||
],
|
||||
// Allows writing JSX in JS & TS files
|
||||
// 'react/jsx-filename-extension': ['error', { extensions: ['.js', '.ts'] }],
|
||||
'react/jsx-filename-extension': ['error', { extensions: ['.tsx'] }],
|
||||
// This rule doesn't play nice with Prettier
|
||||
'react/jsx-one-expression-per-line': 'off',
|
||||
// This rule doesn't play nice with Prettier
|
||||
|
@ -22,34 +22,41 @@ module.exports = {
|
|||
// Remove this rule because we only destructure props, but never state
|
||||
'react/destructuring-assignment': 'off',
|
||||
// Restrict imports that should be used carefully. Usually we have created a wrapper around them
|
||||
|
||||
'typescript/adjacent-overload-signatures': 'error',
|
||||
'typescript/explicit-function-return-type': 'error',
|
||||
'typescript/no-angle-bracket-type-assertion': 'error',
|
||||
'typescript/no-empty-interface': 'error',
|
||||
'typescript/no-explicit-any': 'error',
|
||||
'typescript/no-inferrable-types': 'error',
|
||||
'typescript/no-namespace': 'error',
|
||||
'typescript/no-non-null-assertion': 'error',
|
||||
'typescript/no-triple-slash-reference': 'error',
|
||||
'typescript/no-type-alias': 'error',
|
||||
'typescript/prefer-namespace-keyword': 'error',
|
||||
'typescript/type-annotation-spacing': 'error',
|
||||
|
||||
'no-unused-vars': 'off',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.ts', '*.tsx'],
|
||||
files: ['*.ts?(x)'],
|
||||
parser: 'typescript-eslint-parser',
|
||||
plugins: ['react', 'import', 'typescript'],
|
||||
rules: {
|
||||
'typescript/adjacent-overload-signatures': 'error',
|
||||
'typescript/explicit-function-return-type': 'error',
|
||||
'typescript/no-angle-bracket-type-assertion': 'error',
|
||||
'typescript/no-empty-interface': 'error',
|
||||
'typescript/no-explicit-any': 'error',
|
||||
'typescript/no-inferrable-types': 'error',
|
||||
'typescript/no-namespace': 'error',
|
||||
'typescript/no-non-null-assertion': 'error',
|
||||
'typescript/no-triple-slash-reference': 'error',
|
||||
'typescript/no-type-alias': 'error',
|
||||
'typescript/prefer-namespace-keyword': 'error',
|
||||
'typescript/type-annotation-spacing': 'error',
|
||||
},
|
||||
plugins: ['react', 'react-native', 'typescript'],
|
||||
},
|
||||
],
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
node: { extensions: ['.tsx', '.ts'] },
|
||||
},
|
||||
'import/cache:': {
|
||||
lifetime: 2,
|
||||
node: {
|
||||
extensions: [
|
||||
'.tsx',
|
||||
'.ts',
|
||||
'.android.tsx',
|
||||
'.android.ts',
|
||||
'.ios.tsx',
|
||||
'.ios.ts',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// https://prettier.io/docs/en/options.html
|
||||
|
||||
module.exports = {
|
||||
// Allow to parse .ts files and TS annotations
|
||||
parser: 'typescript',
|
||||
// Enables semicolons at the end of statements
|
||||
semi: true,
|
||||
// Formats strings with single quotes ('') instead of quotes ("")
|
||||
|
|
|
@ -1,9 +1,22 @@
|
|||
{
|
||||
"prettier.disableLanguages": [
|
||||
"json"
|
||||
],
|
||||
"files.associations": {
|
||||
"*.test.js": "javascript",
|
||||
"*.js": "javascriptreact",
|
||||
"*.test.ts": "typescript",
|
||||
"*.ts": "typescript",
|
||||
"*.tsx": "typescriptreact"
|
||||
},
|
||||
"prettier.disableLanguages": ["json"],
|
||||
"prettier.eslintIntegration": true,
|
||||
"prettier.stylelintIntegration": true,
|
||||
"prettier.singleQuote": true,
|
||||
"prettier.trailingComma": "all",
|
||||
"eslint.options": {
|
||||
"extensions": [".js", ".ts", ".tsx"]
|
||||
},
|
||||
"eslint.validate": [
|
||||
"javascript",
|
||||
"javascriptreact",
|
||||
"typescript",
|
||||
"typescriptreact"
|
||||
]
|
||||
}
|
||||
|
|
5
index.js
5
index.js
|
@ -1,3 +1,6 @@
|
|||
import WebView from "./WebView";
|
||||
import WebView from './src/WebView';
|
||||
|
||||
// We keep this for compatibility reasons.
|
||||
export { WebView };
|
||||
|
||||
export default WebView;
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
* @flow
|
||||
*/
|
||||
|
||||
/* eslint-disable */
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {Node, Element, ComponentType} from 'react';
|
||||
|
|
16
package.json
16
package.json
|
@ -12,8 +12,10 @@
|
|||
"homepage": "https://github.com/react-native-community/react-native-webview#readme",
|
||||
"scripts": {
|
||||
"ci:publish": "yarn semantic-release",
|
||||
"ci:test": "yarn ci:test:tsc",
|
||||
"ci:test:tsc": "yarn tsc --noEmit -p tsconfig.json",
|
||||
"ci:test": "yarn ci:test:types && yarn ci:test:lint",
|
||||
"ci:test:types": "yarn tsc",
|
||||
"ci:test:lint": "yarn eslint . --max-warnings=0 --ext .js,.ts,.tsx",
|
||||
"eslint-check": "eslint --print-config . | eslint-config-prettier-check",
|
||||
"semantic-release": "semantic-release"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
@ -27,16 +29,18 @@
|
|||
"devDependencies": {
|
||||
"@semantic-release/git": "7.0.5",
|
||||
"@types/invariant": "^2.2.29",
|
||||
"@types/react": "16.7.7",
|
||||
"@types/react-native": "^0.57.6",
|
||||
"eslint": "5.9.0",
|
||||
"eslint-config-airbnb": "17.1.0",
|
||||
"eslint-config-airbnb-base": "13.1.0",
|
||||
"eslint-config-prettier": "3.3.0",
|
||||
"eslint-plugin-import": "2.14.0",
|
||||
"eslint-plugin-jsx-a11y": "6.1.2",
|
||||
"eslint-plugin-react": "7.11.1",
|
||||
"eslint-plugin-react-native": "3.5.0",
|
||||
"eslint-plugin-typescript": "0.13.0",
|
||||
"prettier-eslint-cli": "4.7.1",
|
||||
"eslint-plugin-typescript": "0.14.0",
|
||||
"prettier-eslint-cli": "^4.7.1",
|
||||
"react": "16.6.1",
|
||||
"react-native": "0.57.5",
|
||||
"semantic-release": "15.10.3",
|
||||
"typescript": "3.1.6",
|
||||
"typescript-eslint-parser": "21.0.1"
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import React from 'react';
|
||||
|
||||
import ReactNative from 'react-native';
|
||||
import {
|
||||
ActivityIndicator,
|
||||
StyleSheet,
|
||||
|
@ -10,6 +9,7 @@ import {
|
|||
NativeModules,
|
||||
Image,
|
||||
NativeSyntheticEvent,
|
||||
findNodeHandle,
|
||||
} from 'react-native';
|
||||
|
||||
import invariant from 'invariant';
|
||||
|
@ -33,7 +33,7 @@ enum WebViewState {
|
|||
ERROR = 'ERROR',
|
||||
}
|
||||
|
||||
const defaultRenderLoading = () => (
|
||||
const defaultRenderLoading = (): React.ReactNode => (
|
||||
<View style={styles.loadingView}>
|
||||
<ActivityIndicator style={styles.loadingProgressBar} />
|
||||
</View>
|
||||
|
@ -61,10 +61,9 @@ export default class WebView extends React.Component<
|
|||
originWhitelist: WebViewShared.defaultOriginWhitelist,
|
||||
};
|
||||
|
||||
static isFileUploadSupported = async () => {
|
||||
static isFileUploadSupported = async (): Promise<boolean> =>
|
||||
// native implementation should return "true" only for Android 5+
|
||||
return NativeModules.RNCWebView.isFileUploadSupported();
|
||||
};
|
||||
NativeModules.RNCWebView.isFileUploadSupported();
|
||||
|
||||
state: State = {
|
||||
viewState: this.props.startInLoadingState
|
||||
|
@ -75,31 +74,34 @@ export default class WebView extends React.Component<
|
|||
|
||||
webViewRef = React.createRef<React.ComponentClass>();
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
let otherView = null;
|
||||
|
||||
if (this.state.viewState === WebViewState.LOADING) {
|
||||
otherView = (this.props.renderLoading || defaultRenderLoading)();
|
||||
} else if (this.state.viewState === WebViewState.ERROR) {
|
||||
const errorEvent = this.state.lastErrorEvent;
|
||||
invariant(errorEvent != null, 'lastErrorEvent expected to be non-null');
|
||||
otherView =
|
||||
this.props.renderError &&
|
||||
this.props.renderError(
|
||||
errorEvent!.domain,
|
||||
errorEvent!.code,
|
||||
errorEvent!.description,
|
||||
);
|
||||
if (errorEvent) {
|
||||
otherView
|
||||
= this.props.renderError
|
||||
&& this.props.renderError(
|
||||
errorEvent.domain,
|
||||
errorEvent.code,
|
||||
errorEvent.description,
|
||||
);
|
||||
} else {
|
||||
invariant(errorEvent != null, 'lastErrorEvent expected to be non-null');
|
||||
}
|
||||
} else if (this.state.viewState !== WebViewState.IDLE) {
|
||||
console.error(
|
||||
'RNCWebView invalid state encountered: ' + this.state.viewState,
|
||||
`RNCWebView invalid state encountered: ${this.state.viewState}`,
|
||||
);
|
||||
}
|
||||
|
||||
const webViewStyles = [styles.container, this.props.style];
|
||||
if (
|
||||
this.state.viewState === WebViewState.LOADING ||
|
||||
this.state.viewState === WebViewState.ERROR
|
||||
this.state.viewState === WebViewState.LOADING
|
||||
|| this.state.viewState === WebViewState.ERROR
|
||||
) {
|
||||
// if we're in either LOADING or ERROR states, don't show the webView
|
||||
webViewStyles.push(styles.hidden);
|
||||
|
@ -128,7 +130,7 @@ export default class WebView extends React.Component<
|
|||
WebViewShared.originWhitelistToRegex,
|
||||
);
|
||||
|
||||
let NativeWebView = nativeConfig.component || RNCWebView;
|
||||
const NativeWebView = nativeConfig.component || RNCWebView;
|
||||
|
||||
const webView = (
|
||||
<NativeWebView
|
||||
|
@ -246,9 +248,7 @@ export default class WebView extends React.Component<
|
|||
}
|
||||
};
|
||||
|
||||
getWebViewHandle = () => {
|
||||
return ReactNative.findNodeHandle(this.webViewRef.current);
|
||||
};
|
||||
getWebViewHandle = () => findNodeHandle(this.webViewRef.current);
|
||||
|
||||
onLoadingStart = (event: WebViewNavigationEvent) => {
|
||||
const onLoadStart = this.props.onLoadStart;
|
||||
|
|
|
@ -79,9 +79,9 @@ const defaultRenderError = (
|
|||
) => (
|
||||
<View style={styles.errorContainer}>
|
||||
<Text style={styles.errorTextTitle}>Error loading page</Text>
|
||||
<Text style={styles.errorText}>{'Domain: ' + errorDomain}</Text>
|
||||
<Text style={styles.errorText}>{'Error Code: ' + errorCode}</Text>
|
||||
<Text style={styles.errorText}>{'Description: ' + errorDesc}</Text>
|
||||
<Text style={styles.errorText}>{`Domain: ${errorDomain}`}</Text>
|
||||
<Text style={styles.errorText}>{`Error Code: ${errorCode}`}</Text>
|
||||
<Text style={styles.errorText}>{`Description: ${errorDesc}`}</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
|
@ -112,6 +112,7 @@ export default class WebView extends React.Component<
|
|||
State
|
||||
> {
|
||||
static JSNavigationScheme = JSNavigationScheme;
|
||||
|
||||
static NavigationType = NavigationType;
|
||||
|
||||
static defaultProps = {
|
||||
|
@ -119,10 +120,9 @@ export default class WebView extends React.Component<
|
|||
originWhitelist: WebViewShared.defaultOriginWhitelist,
|
||||
};
|
||||
|
||||
static isFileUploadSupported = async () => {
|
||||
static isFileUploadSupported = async () =>
|
||||
// no native implementation for iOS, depends only on permissions
|
||||
return true;
|
||||
};
|
||||
true;
|
||||
|
||||
state: State = {
|
||||
viewState: this.props.startInLoadingState
|
||||
|
@ -135,16 +135,16 @@ export default class WebView extends React.Component<
|
|||
|
||||
UNSAFE_componentWillMount() {
|
||||
if (
|
||||
this.props.useWebKit === true &&
|
||||
this.props.scalesPageToFit !== undefined
|
||||
this.props.useWebKit === true
|
||||
&& this.props.scalesPageToFit !== undefined
|
||||
) {
|
||||
console.warn(
|
||||
'The scalesPageToFit property is not supported when useWebKit = true',
|
||||
);
|
||||
}
|
||||
if (
|
||||
!this.props.useWebKit &&
|
||||
this.props.allowsBackForwardNavigationGestures
|
||||
!this.props.useWebKit
|
||||
&& this.props.allowsBackForwardNavigationGestures
|
||||
) {
|
||||
console.warn(
|
||||
'The allowsBackForwardNavigationGestures property is not supported when useWebKit = false',
|
||||
|
@ -152,7 +152,7 @@ export default class WebView extends React.Component<
|
|||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
render(): React.ReactNode {
|
||||
let otherView = null;
|
||||
|
||||
let scalesPageToFit;
|
||||
|
@ -175,14 +175,14 @@ export default class WebView extends React.Component<
|
|||
);
|
||||
} else if (this.state.viewState !== WebViewState.IDLE) {
|
||||
console.error(
|
||||
'RNCWebView invalid state encountered: ' + this.state.viewState,
|
||||
`RNCWebView invalid state encountered: ${this.state.viewState}`,
|
||||
);
|
||||
}
|
||||
|
||||
const webViewStyles = [styles.container, styles.webView, this.props.style];
|
||||
if (
|
||||
this.state.viewState === WebViewState.LOADING ||
|
||||
this.state.viewState === WebViewState.ERROR
|
||||
this.state.viewState === WebViewState.LOADING
|
||||
|| this.state.viewState === WebViewState.ERROR
|
||||
) {
|
||||
// if we're in either LOADING or ERROR states, don't show the webView
|
||||
webViewStyles.push(styles.hidden);
|
||||
|
@ -216,9 +216,9 @@ export default class WebView extends React.Component<
|
|||
Linking.openURL(url);
|
||||
}
|
||||
if (this.props.onShouldStartLoadWithRequest) {
|
||||
shouldStart =
|
||||
shouldStart &&
|
||||
this.props.onShouldStartLoadWithRequest(event.nativeEvent);
|
||||
shouldStart
|
||||
= shouldStart
|
||||
&& this.props.onShouldStartLoadWithRequest(event.nativeEvent);
|
||||
}
|
||||
invariant(viewManager != null, 'viewManager expected to be non-null');
|
||||
viewManager.startLoadWithResult(
|
||||
|
@ -392,9 +392,7 @@ export default class WebView extends React.Component<
|
|||
/**
|
||||
* Returns the native `WebView` node.
|
||||
*/
|
||||
getWebViewHandle = () => {
|
||||
return findNodeHandle(this.webViewRef.current);
|
||||
};
|
||||
getWebViewHandle = () => findNodeHandle(this.webViewRef.current);
|
||||
|
||||
_onLoadingStart = (event: WebViewNavigationEvent) => {
|
||||
const onLoadStart = this.props.onLoadStart;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const escapeStringRegexp = require('escape-string-regexp');
|
||||
import escapeStringRegexp from 'escape-string-regexp';
|
||||
|
||||
const WebViewShared = {
|
||||
defaultOriginWhitelist: ['http://*', 'https://*'],
|
||||
|
@ -6,9 +6,8 @@ const WebViewShared = {
|
|||
const result = /^[A-Za-z0-9]+:(\/\/)?[^/]*/.exec(url);
|
||||
return result === null ? '' : result[0];
|
||||
},
|
||||
originWhitelistToRegex: (originWhitelist: string): string => {
|
||||
return escapeStringRegexp(originWhitelist).replace(/\\\*/g, '.*');
|
||||
},
|
||||
originWhitelistToRegex: (originWhitelist: string): string =>
|
||||
escapeStringRegexp(originWhitelist).replace(/\\\*/g, '.*'),
|
||||
};
|
||||
|
||||
export default WebViewShared;
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
export * from './types/WebViewTypes'
|
||||
export * from './WebView.ios'
|
||||
export * from './types/WebViewTypes';
|
||||
export * from './WebView.ios';
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
const a
|
||||
= 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
|
||||
|
||||
console.log(a);
|
|
@ -0,0 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
const Test: React.SFC<{
|
||||
show: boolean;
|
||||
}> = ({ show }): React.ReactElement<string> => show && <div />;
|
||||
|
||||
const a =
|
||||
'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
|
||||
|
||||
console.log(a);
|
||||
|
||||
export default Test;
|
|
@ -68,8 +68,8 @@ export type WebViewMessageEvent = NativeSyntheticEvent<WebViewMessage>;
|
|||
|
||||
export type WebViewErrorEvent = NativeSyntheticEvent<WebViewError>;
|
||||
|
||||
export type DataDetectorTypes =
|
||||
| 'phoneNumber'
|
||||
export type DataDetectorTypes
|
||||
= | 'phoneNumber'
|
||||
| 'link'
|
||||
| 'address'
|
||||
| 'calendarEvent'
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { WebViewSourceUri } from "./types/WebViewTypes";
|
||||
import { WebViewSourceUri } from './types/WebViewTypes';
|
||||
|
||||
export const isWebViewUriSource = (source: any): source is WebViewSourceUri =>
|
||||
typeof source !== "number" && !("html" in source);
|
||||
typeof source !== 'number' && !('html' in source);
|
||||
|
|
|
@ -3,27 +3,18 @@
|
|||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
"jsx": "react-native",
|
||||
"lib": ["es6"],
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"noEmit": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"pretty": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"strict": true
|
||||
},
|
||||
"include": [
|
||||
"src",
|
||||
"./typings.d.ts",
|
||||
"types",
|
||||
"test"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"dist"
|
||||
]
|
||||
}
|
||||
"include": ["src", "./typings.d.ts", "types", "test"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue