maplair
Version:
JavaScript library for mobile-friendly interactive maps
135 lines (134 loc) • 5.51 kB
JavaScript
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