UNPKG

maplair

Version:

JavaScript library for mobile-friendly interactive maps

135 lines (134 loc) • 5.51 kB
import { __exportAll } from "../_virtual/_rolldown/runtime.js"; import { splitWords, stamp } from "../core/Util.js"; import { Point } from "../geometry/Point.js"; import Browser_default from "../core/Browser.js"; import { addDoubleTapListener, removeDoubleTapListener } from "./DomEvent.DoubleTap.js"; import { DomEvent_PointerEvents_exports } from "./DomEvent.PointerEvents.js"; import { getScale } from "./DomUtil.js"; //#region src/dom/DomEvent.js var DomEvent_exports = /* @__PURE__ */ __exportAll({ PointerEvents: () => DomEvent_PointerEvents_exports, disableClickPropagation: () => disableClickPropagation, disableScrollPropagation: () => disableScrollPropagation, getPointerPosition: () => getPointerPosition, getPropagationPath: () => getPropagationPath, getWheelDelta: () => getWheelDelta, getWheelPxFactor: () => getWheelPxFactor, isExternalTarget: () => isExternalTarget, off: () => off, on: () => on, preventDefault: () => preventDefault, stop: () => stop, stopPropagation: () => stopPropagation }); function on(obj, types, fn, context) { if (types && typeof types === "object") for (const [type, listener] of Object.entries(types)) addOne(obj, type, listener, fn); else for (const type of splitWords(types)) addOne(obj, type, fn, context); return this; } const eventsKey = "_maplair_events"; function off(obj, types, fn, context) { if (arguments.length === 1) { batchRemove(obj); delete obj[eventsKey]; } else if (types && typeof types === "object") for (const [type, listener] of Object.entries(types)) removeOne(obj, type, listener, fn); else { types = splitWords(types); if (arguments.length === 2) batchRemove(obj, (type) => types.includes(type)); else for (const type of types) removeOne(obj, type, fn, context); } return this; } const DIGIT_RE = /\d/; function batchRemove(obj, filterFn) { for (const id of Object.keys(obj[eventsKey] ?? {})) { const type = id.split(DIGIT_RE)[0]; if (!filterFn || filterFn(type)) removeOne(obj, type, null, null, id); } } const pointerSubst = { pointerenter: "pointerover", pointerleave: "pointerout", wheel: typeof window === "undefined" ? false : !("onwheel" in window) && "mousewheel" }; function addOne(obj, type, fn, context) { const id = type + stamp(fn) + (context ? `_${stamp(context)}` : ""); if (obj[eventsKey] && obj[eventsKey][id]) return this; let handler = function(e) { return fn.call(context || obj, e); }; const originalHandler = handler; if (Browser_default.touch && type === "dblclick") handler = addDoubleTapListener(obj, handler); else if ("addEventListener" in obj) { if (type === "wheel" || type === "mousewheel") obj.addEventListener(pointerSubst[type] || type, handler, { passive: false }); else if (type === "pointerenter" || type === "pointerleave") { handler = function(e) { if (isExternalTarget(obj, e)) originalHandler(e); }; obj.addEventListener(pointerSubst[type], handler, false); } else obj.addEventListener(type, originalHandler, false); } else obj.attachEvent(`on${type}`, handler); obj[eventsKey] ??= {}; obj[eventsKey][id] = handler; } function removeOne(obj, type, fn, context, id) { id ??= type + stamp(fn) + (context ? `_${stamp(context)}` : ""); const handler = obj[eventsKey] && obj[eventsKey][id]; if (!handler) return this; if (Browser_default.touch && type === "dblclick") removeDoubleTapListener(obj, handler); else if ("removeEventListener" in obj) obj.removeEventListener(pointerSubst[type] || type, handler, false); else obj.detachEvent(`on${type}`, handler); obj[eventsKey][id] = null; } function stopPropagation(e) { if (e.stopPropagation) e.stopPropagation(); else if (e.originalEvent) e.originalEvent._stopped = true; else console.debug("Unsupported event", e); return this; } function disableScrollPropagation(el) { addOne(el, "wheel", stopPropagation); return this; } function disableClickPropagation(el) { on(el, "pointerdown dblclick contextmenu", stopPropagation); el["_maplair_disable_click"] = true; return this; } function preventDefault(e) { e.preventDefault?.(); return this; } function stop(e) { preventDefault(e); stopPropagation(e); return this; } function getPropagationPath(ev) { return ev.composedPath(); } function getPointerPosition(e, container) { if (!container) return new Point(e.clientX, e.clientY); const scale = getScale(container), offset = scale.boundingClientRect; return new Point((e.clientX - offset.left) / scale.x - container.clientLeft, (e.clientY - offset.top) / scale.y - container.clientTop); } function getWheelPxFactor() { const ratio = window.devicePixelRatio; return Browser_default.linux && Browser_default.chrome ? ratio : Browser_default.mac ? ratio * 3 : ratio > 0 ? 2 * ratio : 1; } function getWheelDelta(e) { return e.deltaY && e.deltaMode === 0 ? -e.deltaY / getWheelPxFactor() : e.deltaY && e.deltaMode === 1 ? -e.deltaY * 20 : e.deltaY && e.deltaMode === 2 ? -e.deltaY * 60 : e.deltaX || e.deltaZ ? 0 : 0; } function isExternalTarget(el, e) { let related = e.relatedTarget; if (!related) return true; try { while (related && related !== el) related = related.parentNode; } catch (err) { return false; } return related !== el; } //#endregion export { DomEvent_exports, DomEvent_PointerEvents_exports as PointerEvents, disableClickPropagation, disableScrollPropagation, getPointerPosition, getPropagationPath, getWheelDelta, getWheelPxFactor, isExternalTarget, off, on, preventDefault, stop, stopPropagation }; //# sourceMappingURL=DomEvent.js.map