1
This commit is contained in:
634
ems-frontend/node_modules/zrender/src/dom/HandlerProxy.ts
generated
vendored
Normal file
634
ems-frontend/node_modules/zrender/src/dom/HandlerProxy.ts
generated
vendored
Normal file
@@ -0,0 +1,634 @@
|
||||
|
||||
/* global document */
|
||||
|
||||
import {
|
||||
addEventListener,
|
||||
removeEventListener,
|
||||
normalizeEvent,
|
||||
getNativeEvent
|
||||
} from '../core/event';
|
||||
import * as zrUtil from '../core/util';
|
||||
import Eventful from '../core/Eventful';
|
||||
import env from '../core/env';
|
||||
import { Dictionary, ZRRawEvent, ZRRawMouseEvent } from '../core/types';
|
||||
import { VectorArray } from '../core/vector';
|
||||
import Handler from '../Handler';
|
||||
|
||||
type DomHandlersMap = Dictionary<(this: HandlerDomProxy, event: ZRRawEvent) => void>
|
||||
|
||||
type DomExtended = Node & {
|
||||
domBelongToZr: boolean
|
||||
}
|
||||
|
||||
const TOUCH_CLICK_DELAY = 300;
|
||||
|
||||
const globalEventSupported = env.domSupported;
|
||||
|
||||
|
||||
const localNativeListenerNames = (function () {
|
||||
const mouseHandlerNames = [
|
||||
'click', 'dblclick', 'mousewheel', 'wheel', 'mouseout',
|
||||
'mouseup', 'mousedown', 'mousemove', 'contextmenu'
|
||||
];
|
||||
const touchHandlerNames = [
|
||||
'touchstart', 'touchend', 'touchmove'
|
||||
];
|
||||
const pointerEventNameMap = {
|
||||
pointerdown: 1, pointerup: 1, pointermove: 1, pointerout: 1
|
||||
};
|
||||
const pointerHandlerNames = zrUtil.map(mouseHandlerNames, function (name) {
|
||||
const nm = name.replace('mouse', 'pointer');
|
||||
return pointerEventNameMap.hasOwnProperty(nm) ? nm : name;
|
||||
});
|
||||
|
||||
return {
|
||||
mouse: mouseHandlerNames,
|
||||
touch: touchHandlerNames,
|
||||
pointer: pointerHandlerNames
|
||||
};
|
||||
})();
|
||||
|
||||
const globalNativeListenerNames = {
|
||||
mouse: ['mousemove', 'mouseup'],
|
||||
pointer: ['pointermove', 'pointerup']
|
||||
};
|
||||
|
||||
let wheelEventSupported = false;
|
||||
|
||||
|
||||
// Although firfox has 'DOMMouseScroll' event and do not has 'mousewheel' event,
|
||||
// the 'DOMMouseScroll' event do not performe the same behavior on touch pad device
|
||||
// (like on Mac) ('DOMMouseScroll' will be triggered only if a big wheel delta).
|
||||
// So we should not use it.
|
||||
// function eventNameFix(name: string) {
|
||||
// return (name === 'mousewheel' && env.browser.firefox) ? 'DOMMouseScroll' : name;
|
||||
// }
|
||||
|
||||
function isPointerFromTouch(event: ZRRawEvent) {
|
||||
const pointerType = (event as any).pointerType;
|
||||
return pointerType === 'pen' || pointerType === 'touch';
|
||||
}
|
||||
|
||||
// function useMSGuesture(handlerProxy, event) {
|
||||
// return isPointerFromTouch(event) && !!handlerProxy._msGesture;
|
||||
// }
|
||||
|
||||
// function onMSGestureChange(proxy, event) {
|
||||
// if (event.translationX || event.translationY) {
|
||||
// // mousemove is carried by MSGesture to reduce the sensitivity.
|
||||
// proxy.handler.dispatchToElement(event.target, 'mousemove', event);
|
||||
// }
|
||||
// if (event.scale !== 1) {
|
||||
// event.pinchX = event.offsetX;
|
||||
// event.pinchY = event.offsetY;
|
||||
// event.pinchScale = event.scale;
|
||||
// proxy.handler.dispatchToElement(event.target, 'pinch', event);
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* Prevent mouse event from being dispatched after Touch Events action
|
||||
* @see <https://github.com/deltakosh/handjs/blob/master/src/hand.base.js>
|
||||
* 1. Mobile browsers dispatch mouse events 300ms after touchend.
|
||||
* 2. Chrome for Android dispatch mousedown for long-touch about 650ms
|
||||
* Result: Blocking Mouse Events for 700ms.
|
||||
*
|
||||
* @param {DOMHandlerScope} scope
|
||||
*/
|
||||
function setTouchTimer(scope: DOMHandlerScope) {
|
||||
scope.touching = true;
|
||||
if (scope.touchTimer != null) {
|
||||
clearTimeout(scope.touchTimer);
|
||||
scope.touchTimer = null;
|
||||
}
|
||||
scope.touchTimer = setTimeout(function () {
|
||||
scope.touching = false;
|
||||
scope.touchTimer = null;
|
||||
}, 700);
|
||||
}
|
||||
|
||||
// Mark touch, which is useful in distinguish touch and
|
||||
// mouse event in upper applicatoin.
|
||||
function markTouch(event: ZRRawEvent) {
|
||||
event && (event.zrByTouch = true);
|
||||
}
|
||||
|
||||
|
||||
// function markTriggeredFromLocal(event) {
|
||||
// event && (event.__zrIsFromLocal = true);
|
||||
// }
|
||||
|
||||
// function isTriggeredFromLocal(instance, event) {
|
||||
// return !!(event && event.__zrIsFromLocal);
|
||||
// }
|
||||
|
||||
function normalizeGlobalEvent(instance: HandlerDomProxy, event: ZRRawEvent) {
|
||||
// offsetX, offsetY still need to be calculated. They are necessary in the event
|
||||
// handlers of the upper applications. Set `true` to force calculate them.
|
||||
return normalizeEvent(
|
||||
instance.dom,
|
||||
// TODO ANY TYPE
|
||||
new FakeGlobalEvent(instance, event) as any as ZRRawEvent,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect whether the given el is in `painterRoot`.
|
||||
*/
|
||||
function isLocalEl(instance: HandlerDomProxy, el: Node) {
|
||||
let elTmp = el;
|
||||
let isLocal = false;
|
||||
while (elTmp && elTmp.nodeType !== 9
|
||||
&& !(
|
||||
isLocal = (elTmp as DomExtended).domBelongToZr
|
||||
|| (elTmp !== el && elTmp === instance.painterRoot)
|
||||
)
|
||||
) {
|
||||
elTmp = elTmp.parentNode;
|
||||
}
|
||||
return isLocal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a fake event but not change the original event,
|
||||
* because the global event probably be used by other
|
||||
* listeners not belonging to zrender.
|
||||
* @class
|
||||
*/
|
||||
class FakeGlobalEvent {
|
||||
type: string
|
||||
target: HTMLElement
|
||||
currentTarget: HTMLElement
|
||||
|
||||
pointerType: string
|
||||
clientX: number
|
||||
clientY: number
|
||||
|
||||
constructor(instance: HandlerDomProxy, event: ZRRawEvent) {
|
||||
this.type = event.type;
|
||||
this.target = this.currentTarget = instance.dom;
|
||||
this.pointerType = (event as any).pointerType;
|
||||
// Necessray for the force calculation of zrX, zrY
|
||||
this.clientX = (event as ZRRawMouseEvent).clientX;
|
||||
this.clientY = (event as ZRRawMouseEvent).clientY;
|
||||
// Because we do not mount global listeners to touch events,
|
||||
// we do not copy `targetTouches` and `changedTouches` here.
|
||||
}
|
||||
|
||||
// we make the default methods on the event do nothing,
|
||||
// otherwise it is dangerous. See more details in
|
||||
// [DRAG_OUTSIDE] in `Handler.js`.
|
||||
stopPropagation = zrUtil.noop
|
||||
stopImmediatePropagation = zrUtil.noop
|
||||
preventDefault = zrUtil.noop
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Local DOM Handlers
|
||||
* @this {HandlerProxy}
|
||||
*/
|
||||
const localDOMHandlers: DomHandlersMap = {
|
||||
|
||||
mousedown(event: ZRRawEvent) {
|
||||
event = normalizeEvent(this.dom, event);
|
||||
|
||||
this.__mayPointerCapture = [event.zrX, event.zrY];
|
||||
|
||||
this.trigger('mousedown', event);
|
||||
},
|
||||
|
||||
mousemove(event: ZRRawEvent) {
|
||||
event = normalizeEvent(this.dom, event);
|
||||
|
||||
const downPoint = this.__mayPointerCapture;
|
||||
if (downPoint && (event.zrX !== downPoint[0] || event.zrY !== downPoint[1])) {
|
||||
this.__togglePointerCapture(true);
|
||||
}
|
||||
|
||||
this.trigger('mousemove', event);
|
||||
},
|
||||
|
||||
mouseup(event: ZRRawEvent) {
|
||||
event = normalizeEvent(this.dom, event);
|
||||
|
||||
this.__togglePointerCapture(false);
|
||||
|
||||
this.trigger('mouseup', event);
|
||||
},
|
||||
|
||||
mouseout(event: ZRRawEvent) {
|
||||
event = normalizeEvent(this.dom, event);
|
||||
|
||||
// There might be some doms created by upper layer application
|
||||
// at the same level of painter.getViewportRoot() (e.g., tooltip
|
||||
// dom created by echarts), where 'globalout' event should not
|
||||
// be triggered when mouse enters these doms. (But 'mouseout'
|
||||
// should be triggered at the original hovered element as usual).
|
||||
const element = (event as any).toElement || (event as ZRRawMouseEvent).relatedTarget;
|
||||
|
||||
// For SVG rendering, there are SVG elements inside `this.dom`.
|
||||
// (especially in decal case). Should not to handle those "mouseout"..
|
||||
if (!isLocalEl(this, element)) {
|
||||
// Similarly to the browser did on `document` and touch event,
|
||||
// `globalout` will be delayed to final pointer cature release.
|
||||
if (this.__pointerCapturing) {
|
||||
event.zrEventControl = 'no_globalout';
|
||||
}
|
||||
|
||||
this.trigger('mouseout', event);
|
||||
}
|
||||
},
|
||||
|
||||
wheel(event: ZRRawEvent) {
|
||||
// Morden agent has supported event `wheel` instead of `mousewheel`.
|
||||
// About the polyfill of the props "delta", see "arc/core/event.ts".
|
||||
|
||||
// Firefox only support `wheel` rather than `mousewheel`. Although firfox has been supporting
|
||||
// event `DOMMouseScroll`, it do not act the same behavior as `wheel` on touch pad device
|
||||
// like on Mac, where `DOMMouseScroll` will be triggered only if a big wheel delta occurs,
|
||||
// and it results in no chance to "preventDefault". So we should not use `DOMMouseScroll`.
|
||||
|
||||
wheelEventSupported = true;
|
||||
event = normalizeEvent(this.dom, event);
|
||||
// Follow the definition of the previous version, the zrender event name is still 'mousewheel'.
|
||||
this.trigger('mousewheel', event);
|
||||
},
|
||||
|
||||
mousewheel(event: ZRRawEvent) {
|
||||
// IE8- and some other lagacy agent do not support event `wheel`, so we still listen
|
||||
// to the legacy event `mouseevent`.
|
||||
// Typically if event `wheel` is supported and the handler has been mounted on a
|
||||
// DOM element, the legacy `mousewheel` event will not be triggered (Chrome and Safari).
|
||||
// But we still do this guard to avoid to duplicated handle.
|
||||
if (wheelEventSupported) {
|
||||
return;
|
||||
}
|
||||
event = normalizeEvent(this.dom, event);
|
||||
this.trigger('mousewheel', event);
|
||||
},
|
||||
|
||||
touchstart(event: ZRRawEvent) {
|
||||
// Default mouse behaviour should not be disabled here.
|
||||
// For example, page may needs to be slided.
|
||||
event = normalizeEvent(this.dom, event);
|
||||
|
||||
markTouch(event);
|
||||
|
||||
this.__lastTouchMoment = new Date();
|
||||
|
||||
this.handler.processGesture(event, 'start');
|
||||
|
||||
// For consistent event listener for both touch device and mouse device,
|
||||
// we simulate "mouseover-->mousedown" in touch device. So we trigger
|
||||
// `mousemove` here (to trigger `mouseover` inside), and then trigger
|
||||
// `mousedown`.
|
||||
localDOMHandlers.mousemove.call(this, event);
|
||||
localDOMHandlers.mousedown.call(this, event);
|
||||
},
|
||||
|
||||
touchmove(event: ZRRawEvent) {
|
||||
event = normalizeEvent(this.dom, event);
|
||||
|
||||
markTouch(event);
|
||||
|
||||
this.handler.processGesture(event, 'change');
|
||||
|
||||
// Mouse move should always be triggered no matter whether
|
||||
// there is gestrue event, because mouse move and pinch may
|
||||
// be used at the same time.
|
||||
localDOMHandlers.mousemove.call(this, event);
|
||||
},
|
||||
|
||||
touchend(event: ZRRawEvent) {
|
||||
event = normalizeEvent(this.dom, event);
|
||||
|
||||
markTouch(event);
|
||||
|
||||
this.handler.processGesture(event, 'end');
|
||||
|
||||
localDOMHandlers.mouseup.call(this, event);
|
||||
|
||||
// Do not trigger `mouseout` here, in spite of `mousemove`(`mouseover`) is
|
||||
// triggered in `touchstart`. This seems to be illogical, but by this mechanism,
|
||||
// we can conveniently implement "hover style" in both PC and touch device just
|
||||
// by listening to `mouseover` to add "hover style" and listening to `mouseout`
|
||||
// to remove "hover style" on an element, without any additional code for
|
||||
// compatibility. (`mouseout` will not be triggered in `touchend`, so "hover
|
||||
// style" will remain for user view)
|
||||
|
||||
// click event should always be triggered no matter whether
|
||||
// there is gestrue event. System click can not be prevented.
|
||||
if (+new Date() - (+this.__lastTouchMoment) < TOUCH_CLICK_DELAY) {
|
||||
localDOMHandlers.click.call(this, event);
|
||||
}
|
||||
},
|
||||
|
||||
pointerdown(event: ZRRawEvent) {
|
||||
localDOMHandlers.mousedown.call(this, event);
|
||||
|
||||
// if (useMSGuesture(this, event)) {
|
||||
// this._msGesture.addPointer(event.pointerId);
|
||||
// }
|
||||
},
|
||||
|
||||
pointermove(event: ZRRawEvent) {
|
||||
// FIXME
|
||||
// pointermove is so sensitive that it always triggered when
|
||||
// tap(click) on touch screen, which affect some judgement in
|
||||
// upper application. So, we don't support mousemove on MS touch
|
||||
// device yet.
|
||||
if (!isPointerFromTouch(event)) {
|
||||
localDOMHandlers.mousemove.call(this, event);
|
||||
}
|
||||
},
|
||||
|
||||
pointerup(event: ZRRawEvent) {
|
||||
localDOMHandlers.mouseup.call(this, event);
|
||||
},
|
||||
|
||||
pointerout(event: ZRRawEvent) {
|
||||
// pointerout will be triggered when tap on touch screen
|
||||
// (IE11+/Edge on MS Surface) after click event triggered,
|
||||
// which is inconsistent with the mousout behavior we defined
|
||||
// in touchend. So we unify them.
|
||||
// (check localDOMHandlers.touchend for detailed explanation)
|
||||
if (!isPointerFromTouch(event)) {
|
||||
localDOMHandlers.mouseout.call(this, event);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Othere DOM UI Event handlers for zr dom.
|
||||
* @this {HandlerProxy}
|
||||
*/
|
||||
zrUtil.each(['click', 'dblclick', 'contextmenu'], function (name) {
|
||||
localDOMHandlers[name] = function (event) {
|
||||
event = normalizeEvent(this.dom, event);
|
||||
this.trigger(name, event);
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* DOM UI Event handlers for global page.
|
||||
*
|
||||
* [Caution]:
|
||||
* those handlers should both support in capture phase and bubble phase!
|
||||
*/
|
||||
const globalDOMHandlers: DomHandlersMap = {
|
||||
|
||||
pointermove: function (event: ZRRawEvent) {
|
||||
// FIXME
|
||||
// pointermove is so sensitive that it always triggered when
|
||||
// tap(click) on touch screen, which affect some judgement in
|
||||
// upper application. So, we don't support mousemove on MS touch
|
||||
// device yet.
|
||||
if (!isPointerFromTouch(event)) {
|
||||
globalDOMHandlers.mousemove.call(this, event);
|
||||
}
|
||||
},
|
||||
|
||||
pointerup: function (event: ZRRawEvent) {
|
||||
globalDOMHandlers.mouseup.call(this, event);
|
||||
},
|
||||
|
||||
mousemove: function (event: ZRRawEvent) {
|
||||
this.trigger('mousemove', event);
|
||||
},
|
||||
|
||||
mouseup: function (event: ZRRawEvent) {
|
||||
const pointerCaptureReleasing = this.__pointerCapturing;
|
||||
|
||||
this.__togglePointerCapture(false);
|
||||
|
||||
this.trigger('mouseup', event);
|
||||
|
||||
if (pointerCaptureReleasing) {
|
||||
event.zrEventControl = 'only_globalout';
|
||||
this.trigger('mouseout', event);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
function mountLocalDOMEventListeners(instance: HandlerDomProxy, scope: DOMHandlerScope) {
|
||||
const domHandlers = scope.domHandlers;
|
||||
|
||||
if (env.pointerEventsSupported) { // Only IE11+/Edge
|
||||
// 1. On devices that both enable touch and mouse (e.g., MS Surface and lenovo X240),
|
||||
// IE11+/Edge do not trigger touch event, but trigger pointer event and mouse event
|
||||
// at the same time.
|
||||
// 2. On MS Surface, it probablely only trigger mousedown but no mouseup when tap on
|
||||
// screen, which do not occurs in pointer event.
|
||||
// So we use pointer event to both detect touch gesture and mouse behavior.
|
||||
zrUtil.each(localNativeListenerNames.pointer, function (nativeEventName) {
|
||||
mountSingleDOMEventListener(scope, nativeEventName, function (event) {
|
||||
// markTriggeredFromLocal(event);
|
||||
domHandlers[nativeEventName].call(instance, event);
|
||||
});
|
||||
});
|
||||
|
||||
// FIXME
|
||||
// Note: MS Gesture require CSS touch-action set. But touch-action is not reliable,
|
||||
// which does not prevent defuault behavior occasionally (which may cause view port
|
||||
// zoomed in but use can not zoom it back). And event.preventDefault() does not work.
|
||||
// So we have to not to use MSGesture and not to support touchmove and pinch on MS
|
||||
// touch screen. And we only support click behavior on MS touch screen now.
|
||||
|
||||
// MS Gesture Event is only supported on IE11+/Edge and on Windows 8+.
|
||||
// We don't support touch on IE on win7.
|
||||
// See <https://msdn.microsoft.com/en-us/library/dn433243(v=vs.85).aspx>
|
||||
// if (typeof MSGesture === 'function') {
|
||||
// (this._msGesture = new MSGesture()).target = dom; // jshint ignore:line
|
||||
// dom.addEventListener('MSGestureChange', onMSGestureChange);
|
||||
// }
|
||||
}
|
||||
else {
|
||||
if (env.touchEventsSupported) {
|
||||
zrUtil.each(localNativeListenerNames.touch, function (nativeEventName) {
|
||||
mountSingleDOMEventListener(scope, nativeEventName, function (event) {
|
||||
// markTriggeredFromLocal(event);
|
||||
domHandlers[nativeEventName].call(instance, event);
|
||||
setTouchTimer(scope);
|
||||
});
|
||||
});
|
||||
// Handler of 'mouseout' event is needed in touch mode, which will be mounted below.
|
||||
// addEventListener(root, 'mouseout', this._mouseoutHandler);
|
||||
}
|
||||
|
||||
// 1. Considering some devices that both enable touch and mouse event (like on MS Surface
|
||||
// and lenovo X240, @see #2350), we make mouse event be always listened, otherwise
|
||||
// mouse event can not be handle in those devices.
|
||||
// 2. On MS Surface, Chrome will trigger both touch event and mouse event. How to prevent
|
||||
// mouseevent after touch event triggered, see `setTouchTimer`.
|
||||
zrUtil.each(localNativeListenerNames.mouse, function (nativeEventName) {
|
||||
mountSingleDOMEventListener(scope, nativeEventName, function (event: ZRRawEvent) {
|
||||
event = getNativeEvent(event);
|
||||
if (!scope.touching) {
|
||||
// markTriggeredFromLocal(event);
|
||||
domHandlers[nativeEventName].call(instance, event);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function mountGlobalDOMEventListeners(instance: HandlerDomProxy, scope: DOMHandlerScope) {
|
||||
// Only IE11+/Edge. See the comment in `mountLocalDOMEventListeners`.
|
||||
if (env.pointerEventsSupported) {
|
||||
zrUtil.each(globalNativeListenerNames.pointer, mount);
|
||||
}
|
||||
// Touch event has implemented "drag outside" so we do not mount global listener for touch event.
|
||||
// (see https://www.w3.org/TR/touch-events/#the-touchmove-event) (see also `DRAG_OUTSIDE`).
|
||||
// We do not consider "both-support-touch-and-mouse device" for this feature (see the comment of
|
||||
// `mountLocalDOMEventListeners`) to avoid bugs util some requirements come.
|
||||
else if (!env.touchEventsSupported) {
|
||||
zrUtil.each(globalNativeListenerNames.mouse, mount);
|
||||
}
|
||||
|
||||
function mount(nativeEventName: string) {
|
||||
function nativeEventListener(event: ZRRawEvent) {
|
||||
event = getNativeEvent(event);
|
||||
// See the reason in [DRAG_OUTSIDE] in `Handler.js`
|
||||
// This checking supports both `useCapture` or not.
|
||||
// PENDING: if there is performance issue in some devices,
|
||||
// we probably can not use `useCapture` and change a easier
|
||||
// to judes whether local (mark).
|
||||
if (!isLocalEl(instance, event.target as Node)) {
|
||||
event = normalizeGlobalEvent(instance, event);
|
||||
scope.domHandlers[nativeEventName].call(instance, event);
|
||||
}
|
||||
}
|
||||
mountSingleDOMEventListener(
|
||||
scope, nativeEventName, nativeEventListener,
|
||||
{capture: true} // See [DRAG_OUTSIDE] in `Handler.js`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mountSingleDOMEventListener(
|
||||
scope: DOMHandlerScope,
|
||||
nativeEventName: string,
|
||||
listener: EventListener,
|
||||
opt?: boolean | AddEventListenerOptions
|
||||
) {
|
||||
scope.mounted[nativeEventName] = listener;
|
||||
scope.listenerOpts[nativeEventName] = opt;
|
||||
addEventListener(scope.domTarget, nativeEventName, listener, opt);
|
||||
}
|
||||
|
||||
function unmountDOMEventListeners(scope: DOMHandlerScope) {
|
||||
const mounted = scope.mounted;
|
||||
for (let nativeEventName in mounted) {
|
||||
if (mounted.hasOwnProperty(nativeEventName)) {
|
||||
removeEventListener(
|
||||
scope.domTarget, nativeEventName, mounted[nativeEventName],
|
||||
scope.listenerOpts[nativeEventName]
|
||||
);
|
||||
}
|
||||
}
|
||||
scope.mounted = {};
|
||||
}
|
||||
|
||||
|
||||
class DOMHandlerScope {
|
||||
domTarget: HTMLElement | HTMLDocument
|
||||
domHandlers: DomHandlersMap
|
||||
|
||||
// Key: eventName, value: mounted handler functions.
|
||||
// Used for unmount.
|
||||
mounted: Dictionary<EventListener> = {};
|
||||
|
||||
listenerOpts: Dictionary<boolean | AddEventListenerOptions> = {};
|
||||
|
||||
touchTimer: ReturnType<typeof setTimeout>;
|
||||
touching = false;
|
||||
|
||||
constructor(
|
||||
domTarget: HTMLElement | HTMLDocument,
|
||||
domHandlers: DomHandlersMap
|
||||
) {
|
||||
this.domTarget = domTarget;
|
||||
this.domHandlers = domHandlers;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default class HandlerDomProxy extends Eventful {
|
||||
|
||||
dom: HTMLElement
|
||||
painterRoot: HTMLElement
|
||||
|
||||
handler: Handler
|
||||
|
||||
private _localHandlerScope: DOMHandlerScope
|
||||
private _globalHandlerScope: DOMHandlerScope
|
||||
|
||||
__lastTouchMoment: Date
|
||||
|
||||
// See [DRAG_OUTSIDE] in `Handler.ts`.
|
||||
__pointerCapturing = false
|
||||
// [x, y]
|
||||
__mayPointerCapture: VectorArray
|
||||
|
||||
|
||||
constructor(dom: HTMLElement, painterRoot: HTMLElement) {
|
||||
super();
|
||||
|
||||
this.dom = dom;
|
||||
this.painterRoot = painterRoot;
|
||||
|
||||
this._localHandlerScope = new DOMHandlerScope(dom, localDOMHandlers);
|
||||
|
||||
if (globalEventSupported) {
|
||||
this._globalHandlerScope = new DOMHandlerScope(document, globalDOMHandlers);
|
||||
}
|
||||
|
||||
mountLocalDOMEventListeners(this, this._localHandlerScope);
|
||||
}
|
||||
|
||||
dispose() {
|
||||
unmountDOMEventListeners(this._localHandlerScope);
|
||||
if (globalEventSupported) {
|
||||
unmountDOMEventListeners(this._globalHandlerScope);
|
||||
}
|
||||
}
|
||||
|
||||
setCursor(cursorStyle: string) {
|
||||
this.dom.style && (this.dom.style.cursor = cursorStyle || 'default');
|
||||
}
|
||||
|
||||
/**
|
||||
* See [DRAG_OUTSIDE] in `Handler.js`.
|
||||
* @implement
|
||||
* @param isPointerCapturing Should never be `null`/`undefined`.
|
||||
* `true`: start to capture pointer if it is not capturing.
|
||||
* `false`: end the capture if it is capturing.
|
||||
*/
|
||||
__togglePointerCapture(isPointerCapturing?: boolean) {
|
||||
this.__mayPointerCapture = null;
|
||||
|
||||
if (globalEventSupported
|
||||
&& ((+this.__pointerCapturing) ^ (+isPointerCapturing))
|
||||
) {
|
||||
this.__pointerCapturing = isPointerCapturing;
|
||||
|
||||
const globalHandlerScope = this._globalHandlerScope;
|
||||
isPointerCapturing
|
||||
? mountGlobalDOMEventListeners(this, globalHandlerScope)
|
||||
: unmountDOMEventListeners(globalHandlerScope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface HandlerProxyInterface extends Eventful {
|
||||
handler: Handler
|
||||
dispose: () => void
|
||||
setCursor: (cursorStyle?: string) => void
|
||||
}
|
||||
Reference in New Issue
Block a user