mirror of
https://github.com/google/blockly.git
synced 2025-12-16 06:10:12 +01:00
* chore(deps): bump @typescript-eslint/eslint-plugin from 7.17.0 to 8.0.1 Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.17.0 to 8.0.1. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.0.1/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> * fix: lint plugin versions * chore: fix linting --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Beka Westberg <bwestberg@google.com>
249 lines
6.7 KiB
TypeScript
249 lines
6.7 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2021 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
// Former goog.module ID: Blockly.browserEvents
|
|
|
|
// Theoretically we could figure out a way to type the event params correctly,
|
|
// but it's not high priority.
|
|
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
|
|
|
import * as Touch from './touch.js';
|
|
import * as userAgent from './utils/useragent.js';
|
|
|
|
/**
|
|
* Blockly opaque event data used to unbind events when using
|
|
* `bind` and `conditionalBind`.
|
|
*/
|
|
export type Data = [EventTarget, string, (e: Event) => void][];
|
|
|
|
/**
|
|
* The multiplier for scroll wheel deltas using the line delta mode.
|
|
* See https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/deltaMode
|
|
* for more information on deltaMode.
|
|
*/
|
|
const LINE_MODE_MULTIPLIER = 40;
|
|
|
|
/**
|
|
* The multiplier for scroll wheel deltas using the page delta mode.
|
|
* See https://developer.mozilla.org/en-US/docs/Web/API/WheelEvent/deltaMode
|
|
* for more information on deltaMode.
|
|
*/
|
|
const PAGE_MODE_MULTIPLIER = 125;
|
|
|
|
/**
|
|
* Bind an event handler that can be ignored if it is not part of the active
|
|
* touch stream.
|
|
* Use this for events that either start or continue a multi-part gesture (e.g.
|
|
* mousedown or mousemove, which may be part of a drag or click).
|
|
*
|
|
* @param node Node upon which to listen.
|
|
* @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 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.
|
|
* @returns Opaque data that can be passed to unbindEvent_.
|
|
*/
|
|
export function conditionalBind(
|
|
node: EventTarget,
|
|
name: string,
|
|
thisObject: object | null,
|
|
func: Function,
|
|
opt_noCaptureIdentifier?: boolean,
|
|
): Data {
|
|
/**
|
|
*
|
|
* @param e
|
|
*/
|
|
function wrapFunc(e: Event) {
|
|
const captureIdentifier = !opt_noCaptureIdentifier;
|
|
|
|
if (!(captureIdentifier && !Touch.shouldHandleEvent(e))) {
|
|
if (thisObject) {
|
|
func.call(thisObject, e);
|
|
} else {
|
|
func(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
const bindData: Data = [];
|
|
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);
|
|
bindData.push([node, type, wrapFunc]);
|
|
}
|
|
} else {
|
|
node.addEventListener(name, wrapFunc, false);
|
|
bindData.push([node, name, wrapFunc]);
|
|
}
|
|
return bindData;
|
|
}
|
|
|
|
/**
|
|
* Bind an event handler that should be called regardless of whether it is part
|
|
* of the active touch stream.
|
|
* Use this for events that are not part of a multi-part gesture (e.g.
|
|
* mouseover for tooltips).
|
|
*
|
|
* @param node Node upon which to listen.
|
|
* @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.
|
|
* @returns Opaque data that can be passed to unbindEvent_.
|
|
*/
|
|
export function bind(
|
|
node: EventTarget,
|
|
name: string,
|
|
thisObject: object | null,
|
|
func: Function,
|
|
): Data {
|
|
/**
|
|
*
|
|
* @param e
|
|
*/
|
|
function wrapFunc(e: Event) {
|
|
if (thisObject) {
|
|
func.call(thisObject, e);
|
|
} else {
|
|
func(e);
|
|
}
|
|
}
|
|
|
|
const bindData: Data = [];
|
|
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);
|
|
bindData.push([node, type, wrapFunc]);
|
|
}
|
|
} else {
|
|
node.addEventListener(name, wrapFunc, false);
|
|
bindData.push([node, name, wrapFunc]);
|
|
}
|
|
return bindData;
|
|
}
|
|
|
|
/**
|
|
* Unbind one or more events event from a function call.
|
|
*
|
|
* @param bindData Opaque data from bindEvent_.
|
|
* This list is emptied during the course of calling this function.
|
|
* @returns The function call.
|
|
*/
|
|
export function unbind(bindData: Data): (e: Event) => void {
|
|
// Accessing an element of the last property of the array is unsafe if the
|
|
// bindData is an empty array. But that should never happen because developers
|
|
// should only pass Data from bind or conditionalBind.
|
|
const callback = bindData[bindData.length - 1][2];
|
|
while (bindData.length) {
|
|
const [node, name, func] = bindData.pop()!;
|
|
node.removeEventListener(name, func, false);
|
|
}
|
|
return callback;
|
|
}
|
|
|
|
/**
|
|
* Returns true if this event is targeting a text input widget?
|
|
*
|
|
* @param e An event.
|
|
* @returns True if text input.
|
|
*/
|
|
export function isTargetInput(e: Event): boolean {
|
|
if (e.target instanceof HTMLElement) {
|
|
if (
|
|
e.target.isContentEditable ||
|
|
e.target.getAttribute('data-is-text-input') === 'true'
|
|
) {
|
|
return true;
|
|
}
|
|
|
|
if (e.target instanceof HTMLInputElement) {
|
|
const target = e.target;
|
|
return (
|
|
target.type === 'text' ||
|
|
target.type === 'number' ||
|
|
target.type === 'email' ||
|
|
target.type === 'password' ||
|
|
target.type === 'search' ||
|
|
target.type === 'tel' ||
|
|
target.type === 'url'
|
|
);
|
|
}
|
|
|
|
if (e.target instanceof HTMLTextAreaElement) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns true this event is a right-click.
|
|
*
|
|
* @param e Mouse event.
|
|
* @returns True if right-click.
|
|
*/
|
|
export function isRightButton(e: MouseEvent): boolean {
|
|
if (e.ctrlKey && userAgent.MAC) {
|
|
// Control-clicking on Mac OS X is treated as a right-click.
|
|
// WebKit on Mac OS X fails to change button to 2 (but Gecko does).
|
|
return true;
|
|
}
|
|
return e.button === 2;
|
|
}
|
|
|
|
/**
|
|
* Returns the converted coordinates of the given mouse event.
|
|
* The origin (0,0) is the top-left corner of the Blockly SVG.
|
|
*
|
|
* @param e Mouse event.
|
|
* @param svg SVG element.
|
|
* @param matrix Inverted screen CTM to use.
|
|
* @returns Object with .x and .y properties.
|
|
*/
|
|
export function mouseToSvg(
|
|
e: MouseEvent,
|
|
svg: SVGSVGElement,
|
|
matrix: SVGMatrix | null,
|
|
): SVGPoint {
|
|
const svgPoint = svg.createSVGPoint();
|
|
svgPoint.x = e.clientX;
|
|
svgPoint.y = e.clientY;
|
|
|
|
if (!matrix) {
|
|
matrix = svg.getScreenCTM()!.inverse();
|
|
}
|
|
return svgPoint.matrixTransform(matrix);
|
|
}
|
|
|
|
/**
|
|
* Returns the scroll delta of a mouse event in pixel units.
|
|
*
|
|
* @param e Mouse event.
|
|
* @returns Scroll delta object with .x and .y properties.
|
|
*/
|
|
export function getScrollDeltaPixels(e: WheelEvent): {x: number; y: number} {
|
|
switch (e.deltaMode) {
|
|
case 0x00: // Pixel mode.
|
|
default:
|
|
return {x: e.deltaX, y: e.deltaY};
|
|
case 0x01: // Line mode.
|
|
return {
|
|
x: e.deltaX * LINE_MODE_MULTIPLIER,
|
|
y: e.deltaY * LINE_MODE_MULTIPLIER,
|
|
};
|
|
case 0x02: // Page mode.
|
|
return {
|
|
x: e.deltaX * PAGE_MODE_MULTIPLIER,
|
|
y: e.deltaY * PAGE_MODE_MULTIPLIER,
|
|
};
|
|
}
|
|
}
|