From 0cedcd4201baf525b75d51b8da04223e020f59cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Wed, 23 Jan 2019 22:06:01 +0100 Subject: [PATCH 1/4] Switch eslint to eslint-config-airbnb --- .eslintrc.js | 17 ++++++++++++++--- package.json | 8 +++++--- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 3451522..ec9b33b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,7 +1,18 @@ module.exports = { - 'extends': 'eslint-config-brigade/react', + 'extends': 'eslint-config-airbnb', 'parserOptions': { - 'ecmaVersion': 6, - 'sourceType': 'module' + 'ecmaVersion': 2018, + 'sourceType': 'module', + 'ecmaFeatures': { + 'jsx': true, + }, + }, + 'rules': { + 'no-restricted-globals': 'off', + 'no-plusplus': 'off', + 'no-underscore-dangle': 'off' + }, + 'env': { + 'browser': true, }, }; diff --git a/package.json b/package.json index 0a9ef58..f7773bb 100644 --- a/package.json +++ b/package.json @@ -43,9 +43,11 @@ "babel-core": "^6.26.3", "babel-loader": "^6.4.0", "babel-preset-airbnb": "^2.5.1", - "eslint": "^3.17.1", - "eslint-config-brigade": "^3.2.1", - "eslint-plugin-react": "^6.10.0", + "eslint": "^4.19.1", + "eslint-config-airbnb": "^17.1.0", + "eslint-plugin-import": "^2.15.0", + "eslint-plugin-jsx-a11y": "^6.1.2", + "eslint-plugin-react": "^7.12.4", "in-publish": "^2.0.0", "jasmine-core": "2.6.4", "karma": "^1.5.0", From 0d9ea4778e9412c4370e371812737f505a38dd5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Wed, 23 Jan 2019 22:20:22 +0100 Subject: [PATCH 2/4] Eslint automated fixes --- karma.conf.js | 20 ++-- rollup.config.js | 10 +- src/ensureChildrenIsValid.js | 5 +- src/ensureRefIsUsedByChild.js | 7 +- src/getCurrentPosition.js | 16 +-- src/parseOffsetAsPixels.js | 2 +- src/waypoint.jsx | 38 +++--- test/performance-test.jsx | 42 ++++--- test/waypoint_test.jsx | 214 +++++++++++++++++----------------- 9 files changed, 182 insertions(+), 172 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index bed2785..235cb73 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,7 +1,7 @@ /* global process */ // Karma configuration -module.exports = function(config) { +module.exports = function (config) { config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) @@ -13,7 +13,7 @@ module.exports = function(config) { // list of files / patterns to load in the browser files: [ - 'tests.webpack.js' + 'tests.webpack.js', ], // list of files to exclude @@ -24,7 +24,7 @@ module.exports = function(config) { // available preprocessors: // https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { - 'tests.webpack.js': ['webpack'] + 'tests.webpack.js': ['webpack'], }, webpack: { @@ -33,14 +33,14 @@ module.exports = function(config) { { test: /\.jsx?$/, loaders: ['babel-loader?cacheDirectory=true'], - exclude: /node_modules/ - } - ] - } + exclude: /node_modules/, + }, + ], + }, }, webpackMiddleware: { - noInfo: true + noInfo: true, }, // test results reporter to use @@ -66,8 +66,8 @@ module.exports = function(config) { // start these browsers // available browser launchers: // https://npmjs.org/browse/keyword/karma-launcher - browsers: process.env.CONTINUOUS_INTEGRATION === 'true' ? - ['Firefox'] : ['Chrome'], + browsers: process.env.CONTINUOUS_INTEGRATION === 'true' + ? ['Firefox'] : ['Chrome'], // if true, Karma captures browsers, runs the tests and exits singleRun: true, diff --git a/rollup.config.js b/rollup.config.js index 0c45ff2..1264f91 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -10,12 +10,12 @@ export default [ ], output: [ { file: pkg.main, format: 'cjs' }, - { file: pkg.module, format: 'es' } + { file: pkg.module, format: 'es' }, ], plugins: [ babel({ - exclude: ['node_modules/**'] - }) - ] - } + exclude: ['node_modules/**'], + }), + ], + }, ]; diff --git a/src/ensureChildrenIsValid.js b/src/ensureChildrenIsValid.js index b2fa36c..fc9b416 100644 --- a/src/ensureChildrenIsValid.js +++ b/src/ensureChildrenIsValid.js @@ -1,8 +1,7 @@ import React from 'react'; -export const errorMessage = - ' expected to receive a single React element child.\n\n' + - 'See https://goo.gl/LrBNgw for more info.'; +export const errorMessage = ' expected to receive a single React element child.\n\n' + + 'See https://goo.gl/LrBNgw for more info.'; /** * Raise an error if more that one child was provided to "children" diff --git a/src/ensureRefIsUsedByChild.js b/src/ensureRefIsUsedByChild.js index 498191b..e52b6e6 100644 --- a/src/ensureRefIsUsedByChild.js +++ b/src/ensureRefIsUsedByChild.js @@ -1,9 +1,8 @@ import isDOMElement from './isDOMElement'; -export const errorMessage = - ' needs a DOM element to compute boundaries. The child you passed is neither a ' + - 'DOM element (e.g.
) nor does it use the innerRef prop.\n\n' + - 'See https://goo.gl/LrBNgw for more info.'; +export const errorMessage = ' needs a DOM element to compute boundaries. The child you passed is neither a ' + + 'DOM element (e.g.
) nor does it use the innerRef prop.\n\n' + + 'See https://goo.gl/LrBNgw for more info.'; /** * Raise an error if "children" is not a DOM Element and there is no ref provided to Waypoint diff --git a/src/getCurrentPosition.js b/src/getCurrentPosition.js index dcf3da1..767021c 100644 --- a/src/getCurrentPosition.js +++ b/src/getCurrentPosition.js @@ -1,4 +1,6 @@ -import { INVISIBLE, INSIDE, BELOW, ABOVE } from './constants'; +import { + INVISIBLE, INSIDE, BELOW, ABOVE, +} from './constants'; /** * @param {object} bounds An object with bounds data for the waypoint and @@ -13,20 +15,20 @@ export default function getCurrentPosition(bounds) { } // top is within the viewport - if (bounds.viewportTop <= bounds.waypointTop && - bounds.waypointTop <= bounds.viewportBottom) { + if (bounds.viewportTop <= bounds.waypointTop + && bounds.waypointTop <= bounds.viewportBottom) { return INSIDE; } // bottom is within the viewport - if (bounds.viewportTop <= bounds.waypointBottom && - bounds.waypointBottom <= bounds.viewportBottom) { + if (bounds.viewportTop <= bounds.waypointBottom + && bounds.waypointBottom <= bounds.viewportBottom) { return INSIDE; } // top is above the viewport and bottom is below the viewport - if (bounds.waypointTop <= bounds.viewportTop && - bounds.viewportBottom <= bounds.waypointBottom) { + if (bounds.waypointTop <= bounds.viewportTop + && bounds.viewportBottom <= bounds.waypointBottom) { return INSIDE; } diff --git a/src/parseOffsetAsPixels.js b/src/parseOffsetAsPixels.js index 28c5551..073d883 100644 --- a/src/parseOffsetAsPixels.js +++ b/src/parseOffsetAsPixels.js @@ -14,7 +14,7 @@ export default function parseOffsetAsPixels(str) { if (!isNaN(parseFloat(str)) && isFinite(str)) { return parseFloat(str); - } else if (str.slice(-2) === 'px') { + } if (str.slice(-2) === 'px') { return parseFloat(str.slice(0, -2)); } } diff --git a/src/waypoint.jsx b/src/waypoint.jsx index faca849..83dfc93 100644 --- a/src/waypoint.jsx +++ b/src/waypoint.jsx @@ -4,7 +4,9 @@ import React from 'react'; import { isForwardRef } from 'react-is'; import computeOffsetPixels from './computeOffsetPixels'; -import { INVISIBLE, INSIDE, BELOW, ABOVE } from './constants'; +import { + INVISIBLE, INSIDE, BELOW, ABOVE, +} from './constants'; import debugLog from './debugLog'; import ensureChildrenIsValid from './ensureChildrenIsValid'; import ensureRefIsUsedByChild from './ensureRefIsUsedByChild'; @@ -28,7 +30,7 @@ export class Waypoint extends React.PureComponent { constructor(props) { super(props); - this.refElement = (e) => this._ref = e; + this.refElement = e => this._ref = e; } componentWillMount() { @@ -62,14 +64,14 @@ export class Waypoint extends React.PureComponent { this.scrollableAncestor, 'scroll', this._handleScroll, - { passive: true } + { passive: true }, ); this.resizeEventListenerUnsubscribe = addEventListener( window, 'resize', this._handleScroll, - { passive: true } + { passive: true }, ); this._handleScroll(null); @@ -155,9 +157,9 @@ export class Waypoint extends React.PureComponent { } const style = window.getComputedStyle(node); - const overflowDirec = horizontal ? - style.getPropertyValue('overflow-x') : - style.getPropertyValue('overflow-y'); + const overflowDirec = horizontal + ? style.getPropertyValue('overflow-x') + : style.getPropertyValue('overflow-y'); const overflow = overflowDirec || style.getPropertyValue('overflow'); if (overflow === 'auto' || overflow === 'scroll') { @@ -215,10 +217,10 @@ export class Waypoint extends React.PureComponent { this.props.onLeave.call(this, callbackArg); } - const isRapidScrollDown = previousPosition === BELOW && - currentPosition === ABOVE; - const isRapidScrollUp = previousPosition === ABOVE && - currentPosition === BELOW; + const isRapidScrollDown = previousPosition === BELOW + && currentPosition === ABOVE; + const isRapidScrollUp = previousPosition === ABOVE + && currentPosition === BELOW; if (this.props.fireOnRapidScroll && (isRapidScrollDown || isRapidScrollUp)) { // If the scroll event isn't fired often enough to occur while the @@ -246,7 +248,9 @@ export class Waypoint extends React.PureComponent { _getBounds() { const horizontal = this.props.horizontal; - const { left, top, right, bottom } = this._ref.getBoundingClientRect(); + const { + left, top, right, bottom, + } = this._ref.getBoundingClientRect(); const waypointTop = horizontal ? left : top; const waypointBottom = horizontal ? right : bottom; @@ -256,11 +260,11 @@ export class Waypoint extends React.PureComponent { contextHeight = horizontal ? window.innerWidth : window.innerHeight; contextScrollTop = 0; } else { - contextHeight = horizontal ? this.scrollableAncestor.offsetWidth : - this.scrollableAncestor.offsetHeight; - contextScrollTop = horizontal ? - this.scrollableAncestor.getBoundingClientRect().left : - this.scrollableAncestor.getBoundingClientRect().top; + contextHeight = horizontal ? this.scrollableAncestor.offsetWidth + : this.scrollableAncestor.offsetHeight; + contextScrollTop = horizontal + ? this.scrollableAncestor.getBoundingClientRect().left + : this.scrollableAncestor.getBoundingClientRect().top; } if (process.env.NODE_ENV !== 'production' && this.props.debug) { diff --git a/test/performance-test.jsx b/test/performance-test.jsx index 19f5f8b..92586cc 100644 --- a/test/performance-test.jsx +++ b/test/performance-test.jsx @@ -8,15 +8,18 @@ const WAYPOINT_COUNT = 1000; function Foo() { return ( -
- + - - - Birds + Birds
); } @@ -62,11 +65,15 @@ class PerformanceTest extends Component { for (let i = 0; i < WAYPOINT_COUNT; i++) { elements.push(
-

Container {i}

- {this.state[`active-${i}`] && - +

+Container + {i} +

+ {this.state[`active-${i}`] + && } - {!this.state[`active-${i}`] && + {!this.state[`active-${i}`] + && (
+ ) } -
+
, ); } return ( @@ -91,6 +99,6 @@ class PerformanceTest extends Component { } ReactDOM.render( - , - document.getElementById('app') + , + document.getElementById('app'), ); diff --git a/test/waypoint_test.jsx b/test/waypoint_test.jsx index 137ad33..37da84d 100644 --- a/test/waypoint_test.jsx +++ b/test/waypoint_test.jsx @@ -8,14 +8,14 @@ import { errorMessage as refNotUsedErrorMessage } from '../src/ensureRefIsUsedBy let div; -const renderAttached = function(component) { +const renderAttached = function (component) { div = document.createElement('div'); document.body.appendChild(div); const renderedComponent = ReactDOM.render(component, div); return renderedComponent; }; -const scrollNodeTo = function(node, scrollTop) { +const scrollNodeTo = function (node, scrollTop) { if (node === window) { window.scroll(0, scrollTop); } else { @@ -26,7 +26,7 @@ const scrollNodeTo = function(node, scrollTop) { node.dispatchEvent(event); }; -describe('', function() { +describe('', function () { beforeEach(() => { jasmine.clock().install(); spyOn(console, 'log'); @@ -44,7 +44,7 @@ describe('', function() { overflow: 'auto', position: 'relative', width: 100, - margin: this.margin, //Normalize the space above the viewport. + margin: this.margin, // Normalize the space above the viewport. }; this.topSpacerHeight = 0; @@ -56,7 +56,7 @@ describe('', function() {
-
+
, ); jasmine.clock().tick(1); @@ -104,8 +104,8 @@ describe('', function() { }); it('calls the onPositionChange handler', () => { - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: undefined, event: null, @@ -144,8 +144,8 @@ describe('', function() { }); it('calls the onPositionChange handler', () => { - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: undefined, event: null, @@ -184,8 +184,8 @@ describe('', function() { }); it('calls the onPositionChange handler', () => { - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: undefined, event: null, @@ -225,8 +225,8 @@ describe('', function() { }); it('calls the onPositionChange handler', () => { - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: undefined, event: null, @@ -274,8 +274,8 @@ describe('', function() { }); it('the onLeave handler is called', () => { - expect(this.props.onLeave). - toHaveBeenCalledWith({ + expect(this.props.onLeave) + .toHaveBeenCalledWith({ currentPosition: Waypoint.above, previousPosition: Waypoint.inside, event: jasmine.any(Event), @@ -291,8 +291,8 @@ describe('', function() { }); it('the onPositionChange is called', () => { - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.above, previousPosition: Waypoint.inside, event: jasmine.any(Event), @@ -325,8 +325,8 @@ describe('', function() { it('calls the onPositionChange handler', () => { this.subject(); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.below, previousPosition: undefined, event: null, @@ -353,8 +353,8 @@ describe('', function() { this.props.onPositionChange.calls.reset(); scrollNodeTo(this.component, 100); - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -389,8 +389,8 @@ describe('', function() { it('calls the onEnter handler when scrolling down past the threshold', () => { scrollNodeTo(this.subject(), 100); - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -404,8 +404,8 @@ describe('', function() { it('calls the onPositionChange handler when scrolling down past the threshold', () => { scrollNodeTo(this.subject(), 100); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -429,8 +429,8 @@ describe('', function() { it('calls the onEnter handler when scrolling down past the threshold', () => { scrollNodeTo(this.subject(), 100); - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -444,8 +444,8 @@ describe('', function() { it('calls the onPositionChange handler when scrolling down past the threshold', () => { scrollNodeTo(this.subject(), 100); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -478,8 +478,8 @@ describe('', function() { it('calls the onEnter handler', () => { this.scrollQuicklyPast(); - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -492,8 +492,8 @@ describe('', function() { it('calls the onLeave handler', () => { this.scrollQuicklyPast(); - expect(this.props.onLeave). - toHaveBeenCalledWith({ + expect(this.props.onLeave) + .toHaveBeenCalledWith({ currentPosition: Waypoint.above, previousPosition: Waypoint.inside, event: jasmine.any(Event), @@ -506,8 +506,8 @@ describe('', function() { it('calls the onPositionChange handler', () => { this.scrollQuicklyPast(); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.above, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -535,8 +535,8 @@ describe('', function() { it('calls the onPositionChange handler', () => { this.scrollQuicklyPast(); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.above, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -560,8 +560,8 @@ describe('', function() { this.props.onPositionChange.calls.reset(); scrollNodeTo(this.component, 211); - expect(this.props.onLeave). - toHaveBeenCalledWith({ + expect(this.props.onLeave) + .toHaveBeenCalledWith({ currentPosition: Waypoint.above, previousPosition: Waypoint.inside, event: jasmine.any(Event), @@ -609,8 +609,8 @@ describe('', function() { this.props.onPositionChange.calls.reset(); scrollNodeTo(this.component, 90); - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -634,8 +634,8 @@ describe('', function() { this.props.onPositionChange.calls.reset(); scrollNodeTo(this.component, 90); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -681,8 +681,8 @@ describe('', function() { this.props.onPositionChange.calls.reset(); scrollNodeTo(this.component, 90); - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -706,8 +706,8 @@ describe('', function() { this.props.onPositionChange.calls.reset(); scrollNodeTo(this.component, 90); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -753,8 +753,8 @@ describe('', function() { this.props.onPositionChange.calls.reset(); scrollNodeTo(this.component, 90); - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -778,8 +778,8 @@ describe('', function() { this.props.onPositionChange.calls.reset(); scrollNodeTo(this.component, 90); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -825,8 +825,8 @@ describe('', function() { this.props.onPositionChange.calls.reset(); scrollNodeTo(this.component, 90); - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -850,8 +850,8 @@ describe('', function() { this.props.onPositionChange.calls.reset(); scrollNodeTo(this.component, 90); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -886,9 +886,9 @@ describe('', function() { ]; // eslint-disable-next-line no-console - console.error('NOTE: Expect an error log below. You can ignore it. ' + - "We're testing errors thrown and it seems hard to prevent things " + - 'from being logged.'); + console.error('NOTE: Expect an error log below. You can ignore it. ' + + "We're testing errors thrown and it seems hard to prevent things " + + 'from being logged.'); expect(this.subject).toThrowError(notValidErrorMessage); window.onerror = prevOnError; @@ -917,7 +917,7 @@ describe('', function() { }); it('does not throw with a Stateless Component as a child', () => { - const StatelessComponent = (props) =>
; + const StatelessComponent = props =>
; this.props.children = ; expect(this.subject).not.toThrow(); @@ -959,8 +959,8 @@ describe('', function() { it('calls the onEnter handler when scrolled back up just past the bottom', () => { scrollNodeTo(this.scrollable, this.topSpacerHeight + 50); - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.above, event: jasmine.any(Event), @@ -1030,8 +1030,8 @@ describe('', function() { }); it('calls the onEnter handler', () => { - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.above, event: jasmine.any(Event), @@ -1047,8 +1047,8 @@ describe('', function() { }); it('calls the onPositionChange handler', () => { - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.above, event: jasmine.any(Event), @@ -1062,8 +1062,8 @@ describe('', function() { it('calls the onLeave handler when scrolling up past the waypoint', () => { scrollNodeTo(this.scrollable, 99); - expect(this.props.onLeave). - toHaveBeenCalledWith({ + expect(this.props.onLeave) + .toHaveBeenCalledWith({ currentPosition: Waypoint.below, previousPosition: Waypoint.inside, event: jasmine.any(Event), @@ -1083,8 +1083,8 @@ describe('', function() { it('calls the onPositionChange handler when scrolling up past the waypoint', () => { scrollNodeTo(this.scrollable, 99); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.below, previousPosition: Waypoint.inside, event: jasmine.any(Event), @@ -1106,8 +1106,8 @@ describe('', function() { }); it('calls the onEnter handler', () => { - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.above, event: jasmine.any(Event), @@ -1119,8 +1119,8 @@ describe('', function() { }); it('calls the onLeave handler', () => { - expect(this.props.onLeave). - toHaveBeenCalledWith({ + expect(this.props.onLeave) + .toHaveBeenCalledWith({ currentPosition: Waypoint.below, previousPosition: Waypoint.inside, event: jasmine.any(Event), @@ -1132,8 +1132,8 @@ describe('', function() { }); it('calls the onPositionChange handler', () => { - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.below, previousPosition: Waypoint.above, event: jasmine.any(Event), @@ -1152,16 +1152,16 @@ describe('', function() { const node = ReactDOM.findDOMNode(this.component); node.style.display = 'none'; scrollNodeTo(this.component, 0); - expect(this.props.onLeave). - toHaveBeenCalledWith({ - currentPosition: Waypoint.invisible, - previousPosition: Waypoint.inside, - event: jasmine.any(Event), - waypointTop: 0, - waypointBottom: 0, - viewportTop: 0, - viewportBottom: 0, - }); + expect(this.props.onLeave) + .toHaveBeenCalledWith({ + currentPosition: Waypoint.invisible, + previousPosition: Waypoint.inside, + event: jasmine.any(Event), + waypointTop: 0, + waypointBottom: 0, + viewportTop: 0, + viewportBottom: 0, + }); }); }); @@ -1191,8 +1191,8 @@ describe('', function() { it('fires the onPositionChange handler on mount', () => { this.subject(); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.below, previousPosition: undefined, event: null, @@ -1207,8 +1207,8 @@ describe('', function() { this.subject(); scrollNodeTo(window, this.topSpacerHeight - window.innerHeight / 2); - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -1223,8 +1223,8 @@ describe('', function() { this.subject(); scrollNodeTo(window, this.topSpacerHeight - window.innerHeight / 2); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: Waypoint.below, event: jasmine.any(Event), @@ -1259,16 +1259,14 @@ describe('', function() { }; return ( -
+
); } } - this.subject = () => { - return renderAttached(); - }; + this.subject = () => renderAttached(); }); it('only calls onEnter once', () => { @@ -1311,8 +1309,8 @@ describe('', function() { }); it('calls the onEnter handler', () => { - expect(this.props.onEnter). - toHaveBeenCalledWith({ + expect(this.props.onEnter) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: undefined, event: null, @@ -1328,8 +1326,8 @@ describe('', function() { }); it('calls the onPositionChange handler', () => { - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.inside, previousPosition: undefined, event: null, @@ -1361,8 +1359,8 @@ describe('', function() { it('the onLeave handler is called when scrolling past the waypoint', () => { scrollNodeTo(window, 25); - expect(this.props.onLeave). - toHaveBeenCalledWith({ + expect(this.props.onLeave) + .toHaveBeenCalledWith({ currentPosition: Waypoint.above, previousPosition: Waypoint.inside, event: jasmine.any(Event), @@ -1382,8 +1380,8 @@ describe('', function() { it('the onPositionChange handler is called when scrolling past the waypoint', () => { scrollNodeTo(window, 25); - expect(this.props.onPositionChange). - toHaveBeenCalledWith({ + expect(this.props.onPositionChange) + .toHaveBeenCalledWith({ currentPosition: Waypoint.above, previousPosition: Waypoint.inside, event: jasmine.any(Event), @@ -1398,7 +1396,7 @@ describe('', function() { }); // smoke tests for horizontal scrolling -const scrollNodeToHorizontal = function(node, scrollLeft) { +const scrollNodeToHorizontal = function (node, scrollLeft) { if (node === window) { window.scroll(scrollLeft, 0); } else { @@ -1409,7 +1407,7 @@ const scrollNodeToHorizontal = function(node, scrollLeft) { node.dispatchEvent(event); }; -describe(' Horizontal', function() { +describe(' Horizontal', function () { beforeEach(() => { jasmine.clock().install(); document.body.style.margin = 'auto'; // should be no horizontal margin @@ -1417,7 +1415,7 @@ describe(' Horizontal', function() { this.props = { onEnter: jasmine.createSpy('onEnter'), onLeave: jasmine.createSpy('onLeave'), - horizontal: true + horizontal: true, }; this.margin = 10; @@ -1428,7 +1426,7 @@ describe(' Horizontal', function() { overflow: 'auto', whiteSpace: 'nowrap', width: this.parentWidth, - margin: this.margin, //Normalize the space left of the viewport. + margin: this.margin, // Normalize the space left of the viewport. }; this.leftSpacerWidth = 0; @@ -1440,7 +1438,7 @@ describe(' Horizontal', function() {
-
+
, ); jasmine.clock().tick(1); From 72405b502fe1254e183e0cc14f8910fce83d0d58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Sat, 26 Jan 2019 19:17:05 +0100 Subject: [PATCH 3/4] Manual fixes to conform to airbnb rules --- karma.conf.js | 2 +- src/computeOffsetPixels.js | 2 ++ src/debugLog.js | 4 ++-- src/parseOffsetAsPercentage.js | 2 ++ src/parseOffsetAsPixels.js | 2 ++ src/waypoint.jsx | 44 ++++++++++++++++++++++++---------- test/performance-test.jsx | 9 ++++--- test/waypoint_test.jsx | 35 +++++++++++++++------------ 8 files changed, 66 insertions(+), 34 deletions(-) diff --git a/karma.conf.js b/karma.conf.js index 235cb73..d6d6667 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,7 +1,7 @@ /* global process */ // Karma configuration -module.exports = function (config) { +module.exports = (config) => { config.set({ // base path that will be used to resolve all patterns (eg. files, exclude) diff --git a/src/computeOffsetPixels.js b/src/computeOffsetPixels.js index beb43fb..13db326 100644 --- a/src/computeOffsetPixels.js +++ b/src/computeOffsetPixels.js @@ -17,4 +17,6 @@ export default function computeOffsetPixels(offset, contextHeight) { if (typeof percentOffset === 'number') { return percentOffset * contextHeight; } + + return undefined; } diff --git a/src/debugLog.js b/src/debugLog.js index 807547f..4abc047 100644 --- a/src/debugLog.js +++ b/src/debugLog.js @@ -1,5 +1,5 @@ -export default function debugLog() { +export default function debugLog(...args) { if (process.env.NODE_ENV !== 'production') { - console.log(arguments); // eslint-disable-line no-console + console.log(...args); // eslint-disable-line no-console } } diff --git a/src/parseOffsetAsPercentage.js b/src/parseOffsetAsPercentage.js index 981f7de..1d27a13 100644 --- a/src/parseOffsetAsPercentage.js +++ b/src/parseOffsetAsPercentage.js @@ -14,4 +14,6 @@ export default function parseOffsetAsPercentage(str) { if (str.slice(-1) === '%') { return parseFloat(str.slice(0, -1)) / 100; } + + return undefined; } diff --git a/src/parseOffsetAsPixels.js b/src/parseOffsetAsPixels.js index 073d883..4fa6cad 100644 --- a/src/parseOffsetAsPixels.js +++ b/src/parseOffsetAsPixels.js @@ -17,4 +17,6 @@ export default function parseOffsetAsPixels(str) { } if (str.slice(-2) === 'px') { return parseFloat(str.slice(0, -2)); } + + return undefined; } diff --git a/src/waypoint.jsx b/src/waypoint.jsx index 83dfc93..2e55642 100644 --- a/src/waypoint.jsx +++ b/src/waypoint.jsx @@ -1,3 +1,5 @@ +/* eslint-disable import/prefer-default-export */ + import { addEventListener } from 'consolidated-events'; import PropTypes from 'prop-types'; import React from 'react'; @@ -16,6 +18,9 @@ import onNextTick from './onNextTick'; import resolveScrollableAncestorProp from './resolveScrollableAncestorProp'; const defaultProps = { + debug: false, + scrollableAncestor: undefined, + children: undefined, topOffset: '0px', bottomOffset: '0px', horizontal: false, @@ -30,12 +35,15 @@ export class Waypoint extends React.PureComponent { constructor(props) { super(props); - this.refElement = e => this._ref = e; + this.refElement = (e) => { + this._ref = e; + }; } componentWillMount() { + const { children } = this.props; if (process.env.NODE_ENV !== 'production') { - ensureChildrenIsValid(this.props.children); + ensureChildrenIsValid(children); } } @@ -49,14 +57,15 @@ export class Waypoint extends React.PureComponent { // initial execution until the next tick. this.cancelOnNextTick = onNextTick(() => { this.cancelOnNextTick = null; + const { children, debug } = this.props; // Berofe doing anything, we want to check that this._ref is avaliable in Waypoint - ensureRefIsUsedByChild(this.props.children, this._ref); + ensureRefIsUsedByChild(children, this._ref); this._handleScroll = this._handleScroll.bind(this); this.scrollableAncestor = this._findScrollableAncestor(); - if (process.env.NODE_ENV !== 'production' && this.props.debug) { + if (process.env.NODE_ENV !== 'production' && debug) { debugLog('scrollableAncestor', this.scrollableAncestor); } @@ -186,8 +195,15 @@ export class Waypoint extends React.PureComponent { const bounds = this._getBounds(); const currentPosition = getCurrentPosition(bounds); const previousPosition = this._previousPosition; + const { + debug, + onPositionChange, + onEnter, + onLeave, + fireOnRapidScroll, + } = this.props; - if (process.env.NODE_ENV !== 'production' && this.props.debug) { + if (process.env.NODE_ENV !== 'production' && debug) { debugLog('currentPosition', currentPosition); debugLog('previousPosition', previousPosition); } @@ -209,12 +225,12 @@ export class Waypoint extends React.PureComponent { viewportTop: bounds.viewportTop, viewportBottom: bounds.viewportBottom, }; - this.props.onPositionChange.call(this, callbackArg); + onPositionChange.call(this, callbackArg); if (currentPosition === INSIDE) { - this.props.onEnter.call(this, callbackArg); + onEnter.call(this, callbackArg); } else if (previousPosition === INSIDE) { - this.props.onLeave.call(this, callbackArg); + onLeave.call(this, callbackArg); } const isRapidScrollDown = previousPosition === BELOW @@ -222,10 +238,10 @@ export class Waypoint extends React.PureComponent { const isRapidScrollUp = previousPosition === ABOVE && currentPosition === BELOW; - if (this.props.fireOnRapidScroll && (isRapidScrollDown || isRapidScrollUp)) { + if (fireOnRapidScroll && (isRapidScrollDown || isRapidScrollUp)) { // If the scroll event isn't fired often enough to occur while the // waypoint was visible, we trigger both callbacks anyway. - this.props.onEnter.call(this, { + onEnter.call(this, { currentPosition: INSIDE, previousPosition, event, @@ -234,7 +250,7 @@ export class Waypoint extends React.PureComponent { viewportTop: bounds.viewportTop, viewportBottom: bounds.viewportBottom, }); - this.props.onLeave.call(this, { + onLeave.call(this, { currentPosition, previousPosition: INSIDE, event, @@ -247,7 +263,7 @@ export class Waypoint extends React.PureComponent { } _getBounds() { - const horizontal = this.props.horizontal; + const { horizontal, debug } = this.props; const { left, top, right, bottom, } = this._ref.getBoundingClientRect(); @@ -267,7 +283,7 @@ export class Waypoint extends React.PureComponent { : this.scrollableAncestor.getBoundingClientRect().top; } - if (process.env.NODE_ENV !== 'production' && this.props.debug) { + if (process.env.NODE_ENV !== 'production' && debug) { debugLog('waypoint top', waypointTop); debugLog('waypoint bottom', waypointBottom); debugLog('scrollableAncestor height', contextHeight); @@ -326,6 +342,7 @@ if (process.env.NODE_ENV !== 'production') { onLeave: PropTypes.func, onPositionChange: PropTypes.func, fireOnRapidScroll: PropTypes.bool, + // eslint-disable-next-line react/forbid-prop-types scrollableAncestor: PropTypes.any, horizontal: PropTypes.bool, @@ -357,6 +374,7 @@ Waypoint.getWindow = () => { if (typeof window !== 'undefined') { return window; } + return undefined; }; Waypoint.defaultProps = defaultProps; Waypoint.displayName = 'Waypoint'; diff --git a/test/performance-test.jsx b/test/performance-test.jsx index 92586cc..69106ba 100644 --- a/test/performance-test.jsx +++ b/test/performance-test.jsx @@ -1,4 +1,4 @@ -/* eslint-disable max-len, react/no-multi-comp */ +/* eslint-disable max-len, react/no-multi-comp, react/jsx-no-bind */ import React, { Component } from 'react'; import ReactDOM from 'react-dom'; @@ -63,16 +63,19 @@ class PerformanceTest extends Component { render() { const elements = []; for (let i = 0; i < WAYPOINT_COUNT; i++) { + // eslint-disable-next-line react/destructuring-assignment + const isActive = this.state[`active-${i}`]; + elements.push(

Container {i}

- {this.state[`active-${i}`] + {isActive && } - {!this.state[`active-${i}`] + {!isActive && (
', function () { +describe('', () => { beforeEach(() => { jasmine.clock().install(); spyOn(console, 'log'); @@ -897,7 +898,8 @@ describe('', function () { it('does not throw with a Stateful Component as a child', () => { class StatefulComponent extends React.Component { render() { - return
; + const { innerRef } = this.props; + return
; } } @@ -906,6 +908,7 @@ describe('', function () { }); it('errors when a Stateful Component does not provide ref to Waypoint', () => { + // eslint-disable-next-line react/prefer-stateless-function class StatefulComponent extends React.Component { render() { return
; @@ -917,7 +920,7 @@ describe('', function () { }); it('does not throw with a Stateless Component as a child', () => { - const StatelessComponent = props =>
; + const StatelessComponent = ({ innerRef }) =>
; this.props.children = ; expect(this.subject).not.toThrow(); @@ -1253,14 +1256,15 @@ describe('', function () { beforeEach(() => { class Wrapper extends React.Component { render() { - const onEnter = () => { - this.props.onEnter(); + const doOnEnter = () => { + const { onEnter } = this.props; + onEnter(); this.forceUpdate(); }; return (
- +
); } @@ -1396,18 +1400,19 @@ describe('', function () { }); // smoke tests for horizontal scrolling -const scrollNodeToHorizontal = function (node, scrollLeft) { +function scrollNodeToHorizontal(node, scrollLeft) { if (node === window) { window.scroll(scrollLeft, 0); } else { + // eslint-disable-next-line no-param-reassign node.scrollLeft = scrollLeft; } const event = document.createEvent('Event'); event.initEvent('scroll', false, false); node.dispatchEvent(event); -}; +} -describe(' Horizontal', function () { +describe(' Horizontal', () => { beforeEach(() => { jasmine.clock().install(); document.body.style.margin = 'auto'; // should be no horizontal margin From 636dbb476a8f936785dee2cf8731cfaee243944d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rouven=20We=C3=9Fling?= Date: Sat, 26 Jan 2019 19:57:01 +0100 Subject: [PATCH 4/4] Fix tests to work with the AirBnB code style --- karma.conf.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/karma.conf.js b/karma.conf.js index d6d6667..75c7499 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -37,6 +37,9 @@ module.exports = (config) => { }, ], }, + resolve: { + extensions: ['.js', '.jsx', '.json'], + }, }, webpackMiddleware: {