Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: [Violation] Added non-passive event listener to a scroll-blocking 'wheel' event #27429

Merged
6 changes: 4 additions & 2 deletions src/components/Composer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import isEnterWhileComposition from '../../libs/KeyboardShortcut/isEnterWhileCom
import CONST from '../../CONST';
import withNavigation from '../withNavigation';
import ReportActionComposeFocusManager from '../../libs/ReportActionComposeFocusManager';
import * as DeviceCapabilities from '../../libs/DeviceCapabilities';

const propTypes = {
/** Maximum number of lines in the text input */
Expand Down Expand Up @@ -140,6 +141,8 @@ const getNextChars = (str, cursorPos) => {
return substr.substring(0, spaceIndex);
};

const supportsPassive = DeviceCapabilities.hasPassiveEventListenerSupport();

// Enable Markdown parsing.
// On web we like to have the Text Input field always focused so the user can easily type a new chat
function Composer({
Expand Down Expand Up @@ -339,7 +342,6 @@ function Composer({
}

textInput.current.scrollTop += event.deltaY;
event.preventDefault();
event.stopPropagation();
}, []);

Expand Down Expand Up @@ -384,7 +386,7 @@ function Composer({

if (textInput.current) {
document.addEventListener('paste', handlePaste);
textInput.current.addEventListener('wheel', handleWheel);
textInput.current.addEventListener('wheel', handleWheel, supportsPassive ? {passive: true} : false);
}

return () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import * as DeviceCapabilities from '../../../../libs/DeviceCapabilities';
import htmlRendererPropTypes from '../htmlRendererPropTypes';
import BasePreRenderer from './BasePreRenderer';

const supportsPassive = DeviceCapabilities.hasPassiveEventListenerSupport();

const isScrollingVertically = (event) =>
// Mark as vertical scrolling only when absolute value of deltaY is more than the double of absolute
// value of deltaX, so user can use trackpad scroll on the code block horizontally at a wide angle.
Expand All @@ -32,7 +34,6 @@ function PreRenderer(props) {
const horizontalOverflow = node.scrollWidth > node.offsetWidth;
if (event.currentTarget === node && horizontalOverflow && !debouncedIsScrollingVertically(event)) {
node.scrollLeft += event.deltaX;
event.preventDefault();
event.stopPropagation();
}
}, []);
Expand All @@ -42,7 +43,7 @@ function PreRenderer(props) {
if (!eventListenerRefValue) {
return;
}
eventListenerRefValue.getScrollableNode().addEventListener('wheel', scrollNode);
eventListenerRefValue.getScrollableNode().addEventListener('wheel', scrollNode, supportsPassive ? {passive: true} : false);

return () => {
if (!eventListenerRefValue.getScrollableNode()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import HasPassiveEventListenerSupport from './types';

/**
* Allows us to identify whether the browser supports passive event listener.
*/
const hasPassiveEventListenerSupport: HasPassiveEventListenerSupport = () => false;

export default hasPassiveEventListenerSupport;
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Allows us to identify whether the browser supports passive event listener.
*/
export default function hasPassiveEventListenerSupport(): boolean {
let supportsPassive = false;
try {
const opts = Object.defineProperty({}, 'passive', {
// eslint-disable-next-line getter-return
get() {
supportsPassive = true;
},
});
window.addEventListener('testPassive', () => {}, opts);
window.removeEventListener('testPassive', () => {}, opts);
// eslint-disable-next-line no-empty
} catch (e) {}
return supportsPassive;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type HasPassiveEventListenerSupport = () => boolean;

export default HasPassiveEventListenerSupport;
3 changes: 2 additions & 1 deletion src/libs/DeviceCapabilities/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import canUseTouchScreen from './canUseTouchScreen';
import hasHoverSupport from './hasHoverSupport';
import hasPassiveEventListenerSupport from './hasPassiveEventListenerSupport';

export {canUseTouchScreen, hasHoverSupport};
export {canUseTouchScreen, hasHoverSupport, hasPassiveEventListenerSupport};
Loading