From 70a4a14ed46fe07a66bddb5de76f52e7c816815a Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 14 Sep 2023 18:15:11 +0700 Subject: [PATCH 1/6] fix: warning - non-passive event listener --- src/components/Composer/index.js | 6 +++-- .../HTMLRenderers/PreRenderer/index.js | 6 +++-- .../hasPassiveEventListenerSupport/index.js | 22 +++++++++++++++++++ .../index.native.js | 10 +++++++++ 4 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js create mode 100644 src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 44075a4ec1eb..9ab32b549917 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -19,6 +19,7 @@ import isEnterWhileComposition from '../../libs/KeyboardShortcut/isEnterWhileCom import CONST from '../../CONST'; import withNavigation from '../withNavigation'; import ReportActionComposeFocusManager from '../../libs/ReportActionComposeFocusManager'; +import hasPassiveEventListenerSupport from '../../libs/DeviceCapabilities/hasPassiveEventListenerSupport'; const propTypes = { /** Maximum number of lines in the text input */ @@ -140,6 +141,8 @@ const getNextChars = (str, cursorPos) => { return substr.substring(0, spaceIndex); }; +const supportsPassive = 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({ @@ -339,7 +342,6 @@ function Composer({ } textInput.current.scrollTop += event.deltaY; - event.preventDefault(); event.stopPropagation(); }, []); @@ -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 () => { diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js index efc9e432cba8..c9e6796902bd 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js @@ -5,6 +5,9 @@ import htmlRendererPropTypes from '../htmlRendererPropTypes'; import BasePreRenderer from './BasePreRenderer'; import * as DeviceCapabilities from '../../../../libs/DeviceCapabilities'; import ControlSelection from '../../../../libs/ControlSelection'; +import hasPassiveEventListenerSupport from '../../../../libs/DeviceCapabilities/hasPassiveEventListenerSupport'; + +const supportsPassive = hasPassiveEventListenerSupport(); class PreRenderer extends React.Component { constructor(props) { @@ -18,7 +21,7 @@ class PreRenderer extends React.Component { if (!this.ref) { return; } - this.ref.getScrollableNode().addEventListener('wheel', this.scrollNode); + this.ref.getScrollableNode().addEventListener('wheel', this.scrollNode, supportsPassive ? {passive: true} : false); } componentWillUnmount() { @@ -47,7 +50,6 @@ class PreRenderer extends React.Component { const isScrollingVertically = this.debouncedIsScrollingVertically(event); if (event.currentTarget === node && horizontalOverflow && !isScrollingVertically) { node.scrollLeft += event.deltaX; - event.preventDefault(); event.stopPropagation(); } } diff --git a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js new file mode 100644 index 000000000000..3f836b951abc --- /dev/null +++ b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js @@ -0,0 +1,22 @@ +/** + * Allows us to identify whether the browser supports passive event listener. + * Because older browsers will interpret any object in the 3rd argument of an event listener as capture=true. + * + * @returns {Boolean} + */ + +export default function hasPassiveEventListenerSupport() { + let supportsPassive = false; + try { + const opts = Object.defineProperty({}, 'passive', { + // eslint-disable-next-line getter-return + get() { + supportsPassive = true; + }, + }); + window.addEventListener('testPassive', null, opts); + window.removeEventListener('testPassive', null, opts); + // eslint-disable-next-line no-empty + } catch (e) {} + return supportsPassive; +} diff --git a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js new file mode 100644 index 000000000000..0e1bb5616040 --- /dev/null +++ b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js @@ -0,0 +1,10 @@ +/** + * Allows us to identify whether the browser supports passive event listener. + * Because older browsers will interpret any object in the 3rd argument of an event listener as capture=true. + * + * @returns {Boolean} + */ + +const hasPassiveEventListenerSupport = () => false; + +export default hasPassiveEventListenerSupport; From c6fd83e30562c2e5708679754935b5a448504c28 Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 18 Sep 2023 12:17:53 +0700 Subject: [PATCH 2/6] update comment --- .../DeviceCapabilities/hasPassiveEventListenerSupport/index.js | 1 - .../hasPassiveEventListenerSupport/index.native.js | 1 - 2 files changed, 2 deletions(-) diff --git a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js index 3f836b951abc..fdd329451321 100644 --- a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js +++ b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js @@ -1,6 +1,5 @@ /** * Allows us to identify whether the browser supports passive event listener. - * Because older browsers will interpret any object in the 3rd argument of an event listener as capture=true. * * @returns {Boolean} */ diff --git a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js index 0e1bb5616040..555d34063ea7 100644 --- a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js +++ b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js @@ -1,6 +1,5 @@ /** * Allows us to identify whether the browser supports passive event listener. - * Because older browsers will interpret any object in the 3rd argument of an event listener as capture=true. * * @returns {Boolean} */ From 2c5815fe3a3b493d52aca6430f6dd715199d527f Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 18 Oct 2023 14:20:12 +0700 Subject: [PATCH 3/6] fix warning in PreRenderer --- .../HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js index 782ad82f643c..06d73fc7f3d9 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js @@ -5,6 +5,9 @@ import ControlSelection from '../../../../libs/ControlSelection'; import * as DeviceCapabilities from '../../../../libs/DeviceCapabilities'; import htmlRendererPropTypes from '../htmlRendererPropTypes'; import BasePreRenderer from './BasePreRenderer'; +import hasPassiveEventListenerSupport from '../../../../libs/DeviceCapabilities/hasPassiveEventListenerSupport'; + +const supportsPassive = hasPassiveEventListenerSupport(); const isScrollingVertically = (event) => // Mark as vertical scrolling only when absolute value of deltaY is more than the double of absolute @@ -42,7 +45,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()) { From 87f112b7715d16d09d03bb28c5548cb711e91d65 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 18 Oct 2023 14:22:34 +0700 Subject: [PATCH 4/6] remove preventDefault --- .../HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js index 06d73fc7f3d9..8296880fa1d1 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js @@ -35,7 +35,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(); } }, []); From 505869d3f43debc87e1096e191ff0ebb2da97429 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 18 Oct 2023 15:37:07 +0700 Subject: [PATCH 5/6] remove feature detection --- src/components/Composer/index.js | 5 +---- .../HTMLRenderers/PreRenderer/index.js | 5 +---- .../hasPassiveEventListenerSupport/index.js | 21 ------------------- .../index.native.js | 9 -------- 4 files changed, 2 insertions(+), 38 deletions(-) delete mode 100644 src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js delete mode 100644 src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index d6c5aeda84d8..08747f324dbe 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -19,7 +19,6 @@ import isEnterWhileComposition from '../../libs/KeyboardShortcut/isEnterWhileCom import CONST from '../../CONST'; import withNavigation from '../withNavigation'; import ReportActionComposeFocusManager from '../../libs/ReportActionComposeFocusManager'; -import hasPassiveEventListenerSupport from '../../libs/DeviceCapabilities/hasPassiveEventListenerSupport'; const propTypes = { /** Maximum number of lines in the text input */ @@ -141,8 +140,6 @@ const getNextChars = (str, cursorPos) => { return substr.substring(0, spaceIndex); }; -const supportsPassive = 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({ @@ -386,7 +383,7 @@ function Composer({ if (textInput.current) { document.addEventListener('paste', handlePaste); - textInput.current.addEventListener('wheel', handleWheel, supportsPassive ? {passive: true} : false); + textInput.current.addEventListener('wheel', handleWheel, {passive: true}); } return () => { diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js index 8296880fa1d1..52715e8ead4b 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js @@ -5,9 +5,6 @@ import ControlSelection from '../../../../libs/ControlSelection'; import * as DeviceCapabilities from '../../../../libs/DeviceCapabilities'; import htmlRendererPropTypes from '../htmlRendererPropTypes'; import BasePreRenderer from './BasePreRenderer'; -import hasPassiveEventListenerSupport from '../../../../libs/DeviceCapabilities/hasPassiveEventListenerSupport'; - -const supportsPassive = hasPassiveEventListenerSupport(); const isScrollingVertically = (event) => // Mark as vertical scrolling only when absolute value of deltaY is more than the double of absolute @@ -44,7 +41,7 @@ function PreRenderer(props) { if (!eventListenerRefValue) { return; } - eventListenerRefValue.getScrollableNode().addEventListener('wheel', scrollNode, supportsPassive ? {passive: true} : false); + eventListenerRefValue.getScrollableNode().addEventListener('wheel', scrollNode, {passive: true}); return () => { if (!eventListenerRefValue.getScrollableNode()) { diff --git a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js deleted file mode 100644 index fdd329451321..000000000000 --- a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Allows us to identify whether the browser supports passive event listener. - * - * @returns {Boolean} - */ - -export default function hasPassiveEventListenerSupport() { - let supportsPassive = false; - try { - const opts = Object.defineProperty({}, 'passive', { - // eslint-disable-next-line getter-return - get() { - supportsPassive = true; - }, - }); - window.addEventListener('testPassive', null, opts); - window.removeEventListener('testPassive', null, opts); - // eslint-disable-next-line no-empty - } catch (e) {} - return supportsPassive; -} diff --git a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js deleted file mode 100644 index 555d34063ea7..000000000000 --- a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.js +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Allows us to identify whether the browser supports passive event listener. - * - * @returns {Boolean} - */ - -const hasPassiveEventListenerSupport = () => false; - -export default hasPassiveEventListenerSupport; From 425de8a3458ff259f81564185ab4738ff2b88856 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 19 Oct 2023 03:28:11 +0700 Subject: [PATCH 6/6] ts migration --- src/components/Composer/index.js | 5 ++++- .../HTMLRenderers/PreRenderer/index.js | 4 +++- .../index.native.ts | 8 ++++++++ .../hasPassiveEventListenerSupport/index.ts | 18 ++++++++++++++++++ .../hasPassiveEventListenerSupport/types.ts | 3 +++ src/libs/DeviceCapabilities/index.ts | 3 ++- 6 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.ts create mode 100644 src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.ts create mode 100644 src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/types.ts diff --git a/src/components/Composer/index.js b/src/components/Composer/index.js index 08747f324dbe..9d36285cb574 100755 --- a/src/components/Composer/index.js +++ b/src/components/Composer/index.js @@ -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 */ @@ -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({ @@ -383,7 +386,7 @@ function Composer({ if (textInput.current) { document.addEventListener('paste', handlePaste); - textInput.current.addEventListener('wheel', handleWheel, {passive: true}); + textInput.current.addEventListener('wheel', handleWheel, supportsPassive ? {passive: true} : false); } return () => { diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js index 52715e8ead4b..ca86b957e55b 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js +++ b/src/components/HTMLEngineProvider/HTMLRenderers/PreRenderer/index.js @@ -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. @@ -41,7 +43,7 @@ function PreRenderer(props) { if (!eventListenerRefValue) { return; } - eventListenerRefValue.getScrollableNode().addEventListener('wheel', scrollNode, {passive: true}); + eventListenerRefValue.getScrollableNode().addEventListener('wheel', scrollNode, supportsPassive ? {passive: true} : false); return () => { if (!eventListenerRefValue.getScrollableNode()) { diff --git a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.ts b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.ts new file mode 100644 index 000000000000..a5e57675fcf5 --- /dev/null +++ b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.native.ts @@ -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; diff --git a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.ts b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.ts new file mode 100644 index 000000000000..d3c6af0766af --- /dev/null +++ b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/index.ts @@ -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; +} diff --git a/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/types.ts b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/types.ts new file mode 100644 index 000000000000..2987bba0b28c --- /dev/null +++ b/src/libs/DeviceCapabilities/hasPassiveEventListenerSupport/types.ts @@ -0,0 +1,3 @@ +type HasPassiveEventListenerSupport = () => boolean; + +export default HasPassiveEventListenerSupport; diff --git a/src/libs/DeviceCapabilities/index.ts b/src/libs/DeviceCapabilities/index.ts index 3759e4ade730..51c65fef3d5b 100644 --- a/src/libs/DeviceCapabilities/index.ts +++ b/src/libs/DeviceCapabilities/index.ts @@ -1,4 +1,5 @@ import canUseTouchScreen from './canUseTouchScreen'; import hasHoverSupport from './hasHoverSupport'; +import hasPassiveEventListenerSupport from './hasPassiveEventListenerSupport'; -export {canUseTouchScreen, hasHoverSupport}; +export {canUseTouchScreen, hasHoverSupport, hasPassiveEventListenerSupport};