fix: Annotate potentially blocking event listeners with passivity (#9555)

* fix: Annotate potentially blocking event listeners with passivity

* fix: Improve typings for `options` arg to `bind()`/`conditionalBind()`
This commit is contained in:
Aaron Dodson
2026-01-20 11:20:12 -08:00
committed by GitHub
parent e4b2f0a746
commit c2cb695a8f
4 changed files with 29 additions and 8 deletions

View File

@@ -46,6 +46,9 @@ const PAGE_MODE_MULTIPLIER = 125;
* @param opt_noCaptureIdentifier True if triggering on this event should not
* block execution of other event handlers on this touch or other
* simultaneous touches. False by default.
* @param options An object with options controlling the behavior of the event
* listener. Passed through directly as the third argument to
* `addEventListener`.
* @returns Opaque data that can be passed to unbindEvent_.
*/
export function conditionalBind(
@@ -54,6 +57,7 @@ export function conditionalBind(
thisObject: object | null,
func: Function,
opt_noCaptureIdentifier?: boolean,
options?: AddEventListenerOptions,
): Data {
/**
*
@@ -75,11 +79,11 @@ export function conditionalBind(
if (name in Touch.TOUCH_MAP) {
for (let i = 0; i < Touch.TOUCH_MAP[name].length; i++) {
const type = Touch.TOUCH_MAP[name][i];
node.addEventListener(type, wrapFunc, false);
node.addEventListener(type, wrapFunc, {capture: false, ...options});
bindData.push([node, type, wrapFunc]);
}
} else {
node.addEventListener(name, wrapFunc, false);
node.addEventListener(name, wrapFunc, {capture: false, ...options});
bindData.push([node, name, wrapFunc]);
}
return bindData;
@@ -95,6 +99,9 @@ export function conditionalBind(
* @param name Event name to listen to (e.g. 'mousedown').
* @param thisObject The value of 'this' in the function.
* @param func Function to call when event is triggered.
* @param options An object with options controlling the behavior of the event
* listener. Passed through directly as the third argument to
* `addEventListener`.
* @returns Opaque data that can be passed to unbindEvent_.
*/
export function bind(
@@ -102,6 +109,7 @@ export function bind(
name: string,
thisObject: object | null,
func: Function,
options?: AddEventListenerOptions,
): Data {
/**
*
@@ -119,11 +127,11 @@ export function bind(
if (name in Touch.TOUCH_MAP) {
for (let i = 0; i < Touch.TOUCH_MAP[name].length; i++) {
const type = Touch.TOUCH_MAP[name][i];
node.addEventListener(type, wrapFunc, false);
node.addEventListener(type, wrapFunc, {capture: false, ...options});
bindData.push([node, type, wrapFunc]);
}
} else {
node.addEventListener(name, wrapFunc, false);
node.addEventListener(name, wrapFunc, {capture: false, ...options});
bindData.push([node, name, wrapFunc]);
}
return bindData;

View File

@@ -95,9 +95,16 @@ export class CommentEditor implements IFocusableNode {
);
// Don't zoom with mousewheel; let it scroll instead.
browserEvents.conditionalBind(this.textArea, 'wheel', this, (e: Event) => {
e.stopPropagation();
});
browserEvents.conditionalBind(
this.textArea,
'wheel',
this,
(e: Event) => {
e.stopPropagation();
},
false,
{passive: true},
);
// Register listener for keydown events that would finish editing.
browserEvents.conditionalBind(

View File

@@ -357,6 +357,8 @@ export abstract class Flyout
'wheel',
this,
this.wheel_,
false,
{passive: false},
),
);

View File

@@ -809,12 +809,16 @@ export class WorkspaceSvg
// which otherwise prevents zoom/scroll events from being observed in
// Safari. Once that bug is fixed it should be removed.
this.dummyWheelListener = () => {};
document.body.addEventListener('wheel', this.dummyWheelListener);
document.body.addEventListener('wheel', this.dummyWheelListener, {
passive: true,
});
browserEvents.conditionalBind(
this.svgGroup_,
'wheel',
this,
this.onMouseWheel,
false,
{passive: false},
);
}