diff --git a/.eslintrc.js b/.eslintrc.js index 58e3b32265..01f0faca84 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -28,12 +28,14 @@ module.exports = { 'import/no-unresolved': 'error', 'import/named': 'error', 'prettier/prettier': ['error', { singleQuote: true, trailingComma: 'es5' }], + 'react/button-has-type': 'error', 'react/no-access-state-in-setstate': 'error', 'react/no-danger': 'error', 'react/no-did-mount-set-state': 'error', 'react/no-did-update-set-state': 'error', 'react/no-will-update-set-state': 'error', 'react/no-redundant-should-component-update': 'error', + 'react/no-this-in-sfc': 'error', 'react/no-typos': 'error', // `no-unused-prop-types` is buggy when we use destructuring parameters in // functions as it misunderstands them as functional components. @@ -46,6 +48,13 @@ module.exports = { { ignorePureComponents: true }, ], 'react/jsx-no-bind': 'error', + // We still have too many files without the file annotation. Let's enable it + // once we flow-type everything. + // 'flowtype/require-valid-file-annotation': [ 'error', 'always', { annotationStyle: 'line' } ], + // no-dupe-keys crashes with recent eslint. See + // https://github.com/gajus/eslint-plugin-flowtype/pull/266 and + // https://github.com/gajus/eslint-plugin-flowtype/pull/302 + // 'flowtype/no-dupe-keys': 'error', // overriding recommended rules 'no-constant-condition': ['error', { checkLoops: false }], @@ -73,7 +82,9 @@ module.exports = { 'no-self-compare': 'error', 'no-throw-literal': 'error', 'no-unmodified-loop-condition': 'error', - 'no-unused-expressions': 'error', + // We use the version from the flowtype plugin so that flow assertions don't + // output an error. + 'flowtype/no-unused-expressions': 'error', 'no-useless-call': 'error', 'no-useless-computed-key': 'error', 'no-useless-concat': 'error', diff --git a/src/components/app/FooterLinks.js b/src/components/app/FooterLinks.js index 28845bf07d..d5287ee271 100644 --- a/src/components/app/FooterLinks.js +++ b/src/components/app/FooterLinks.js @@ -30,6 +30,7 @@ class FooterLinks extends PureComponent<{||}, State> { aria-label="Hide links to legal information" title="Hide links to legal information" className="appFooterLinksClose" + type="button" onClick={this._onClick} > ✕ diff --git a/src/components/header/SelectionScrubberOverlay.js b/src/components/header/SelectionScrubberOverlay.js index 529c15360b..b3108db5fd 100644 --- a/src/components/header/SelectionScrubberOverlay.js +++ b/src/components/header/SelectionScrubberOverlay.js @@ -132,6 +132,7 @@ export default class SelectionScrubberOverlay extends PureComponent { className={classNames('selectionScrubberZoomButton', { hidden: isModifying, })} + type="button" onMouseDown={this._zoomButtonOnMouseDown} onClick={this._zoomButtonOnClick} /> diff --git a/src/test/components/__snapshots__/Home.test.js.snap b/src/test/components/__snapshots__/Home.test.js.snap index bbf79dfd7f..72b7440410 100644 --- a/src/test/components/__snapshots__/Home.test.js.snap +++ b/src/test/components/__snapshots__/Home.test.js.snap @@ -116,6 +116,7 @@ exports[`app/Home renders the information screen for other browsers 1`] = ` className="appFooterLinksClose" onClick={[Function]} title="Hide links to legal information" + type="button" > ✕ @@ -271,6 +272,7 @@ exports[`app/Home renders the install screen for the extension 1`] = ` className="appFooterLinksClose" onClick={[Function]} title="Hide links to legal information" + type="button" > ✕ @@ -460,6 +462,7 @@ exports[`app/Home renders the install screen for the legacy add-on 1`] = ` className="appFooterLinksClose" onClick={[Function]} title="Hide links to legal information" + type="button" > ✕ @@ -633,6 +636,7 @@ exports[`app/Home renders the usage instructions for pages with the extension in className="appFooterLinksClose" onClick={[Function]} title="Hide links to legal information" + type="button" > ✕ diff --git a/src/utils/flow.js b/src/utils/flow.js index 47b2bea289..cd037096ec 100644 --- a/src/utils/flow.js +++ b/src/utils/flow.js @@ -48,7 +48,7 @@ export function toValidTabSlug(tabSlug: any): TabSlug | null { default: { // The coerced type SHOULD be empty here. If in reality we get // here, then it's not a valid transform type, so return null. - (coercedTabSlug: empty); // eslint-disable-line no-unused-expressions + (coercedTabSlug: empty); return null; } } @@ -76,7 +76,7 @@ export function convertToTransformType(type: string): TransformType | null { default: { // The coerced type SHOULD be empty here. If in reality we get // here, then it's not a valid transform type, so return null. - (coercedType: empty); // eslint-disable-line no-unused-expressions + (coercedType: empty); return null; } }