HandlerProxy.ts 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. /* global document */
  2. import {
  3. addEventListener,
  4. removeEventListener,
  5. normalizeEvent,
  6. getNativeEvent
  7. } from '../core/event';
  8. import * as zrUtil from '../core/util';
  9. import Eventful from '../core/Eventful';
  10. import env from '../core/env';
  11. import { Dictionary, ZRRawEvent, ZRRawMouseEvent } from '../core/types';
  12. import { VectorArray } from '../core/vector';
  13. import Handler from '../Handler';
  14. type DomHandlersMap = Dictionary<(this: HandlerDomProxy, event: ZRRawEvent) => void>
  15. type DomExtended = Node & {
  16. domBelongToZr: boolean
  17. }
  18. const TOUCH_CLICK_DELAY = 300;
  19. const globalEventSupported = env.domSupported;
  20. const localNativeListenerNames = (function () {
  21. const mouseHandlerNames = [
  22. 'click', 'dblclick', 'mousewheel', 'wheel', 'mouseout',
  23. 'mouseup', 'mousedown', 'mousemove', 'contextmenu'
  24. ];
  25. const touchHandlerNames = [
  26. 'touchstart', 'touchend', 'touchmove'
  27. ];
  28. const pointerEventNameMap = {
  29. pointerdown: 1, pointerup: 1, pointermove: 1, pointerout: 1
  30. };
  31. const pointerHandlerNames = zrUtil.map(mouseHandlerNames, function (name) {
  32. const nm = name.replace('mouse', 'pointer');
  33. return pointerEventNameMap.hasOwnProperty(nm) ? nm : name;
  34. });
  35. return {
  36. mouse: mouseHandlerNames,
  37. touch: touchHandlerNames,
  38. pointer: pointerHandlerNames
  39. };
  40. })();
  41. const globalNativeListenerNames = {
  42. mouse: ['mousemove', 'mouseup'],
  43. pointer: ['pointermove', 'pointerup']
  44. };
  45. let wheelEventSupported = false;
  46. // Although firfox has 'DOMMouseScroll' event and do not has 'mousewheel' event,
  47. // the 'DOMMouseScroll' event do not performe the same behavior on touch pad device
  48. // (like on Mac) ('DOMMouseScroll' will be triggered only if a big wheel delta).
  49. // So we should not use it.
  50. // function eventNameFix(name: string) {
  51. // return (name === 'mousewheel' && env.browser.firefox) ? 'DOMMouseScroll' : name;
  52. // }
  53. function isPointerFromTouch(event: ZRRawEvent) {
  54. const pointerType = (event as any).pointerType;
  55. return pointerType === 'pen' || pointerType === 'touch';
  56. }
  57. // function useMSGuesture(handlerProxy, event) {
  58. // return isPointerFromTouch(event) && !!handlerProxy._msGesture;
  59. // }
  60. // function onMSGestureChange(proxy, event) {
  61. // if (event.translationX || event.translationY) {
  62. // // mousemove is carried by MSGesture to reduce the sensitivity.
  63. // proxy.handler.dispatchToElement(event.target, 'mousemove', event);
  64. // }
  65. // if (event.scale !== 1) {
  66. // event.pinchX = event.offsetX;
  67. // event.pinchY = event.offsetY;
  68. // event.pinchScale = event.scale;
  69. // proxy.handler.dispatchToElement(event.target, 'pinch', event);
  70. // }
  71. // }
  72. /**
  73. * Prevent mouse event from being dispatched after Touch Events action
  74. * @see <https://github.com/deltakosh/handjs/blob/master/src/hand.base.js>
  75. * 1. Mobile browsers dispatch mouse events 300ms after touchend.
  76. * 2. Chrome for Android dispatch mousedown for long-touch about 650ms
  77. * Result: Blocking Mouse Events for 700ms.
  78. *
  79. * @param {DOMHandlerScope} scope
  80. */
  81. function setTouchTimer(scope: DOMHandlerScope) {
  82. scope.touching = true;
  83. if (scope.touchTimer != null) {
  84. clearTimeout(scope.touchTimer);
  85. scope.touchTimer = null;
  86. }
  87. scope.touchTimer = setTimeout(function () {
  88. scope.touching = false;
  89. scope.touchTimer = null;
  90. }, 700);
  91. }
  92. // Mark touch, which is useful in distinguish touch and
  93. // mouse event in upper applicatoin.
  94. function markTouch(event: ZRRawEvent) {
  95. event && (event.zrByTouch = true);
  96. }
  97. // function markTriggeredFromLocal(event) {
  98. // event && (event.__zrIsFromLocal = true);
  99. // }
  100. // function isTriggeredFromLocal(instance, event) {
  101. // return !!(event && event.__zrIsFromLocal);
  102. // }
  103. function normalizeGlobalEvent(instance: HandlerDomProxy, event: ZRRawEvent) {
  104. // offsetX, offsetY still need to be calculated. They are necessary in the event
  105. // handlers of the upper applications. Set `true` to force calculate them.
  106. return normalizeEvent(
  107. instance.dom,
  108. // TODO ANY TYPE
  109. new FakeGlobalEvent(instance, event) as any as ZRRawEvent,
  110. true
  111. );
  112. }
  113. /**
  114. * Detect whether the given el is in `painterRoot`.
  115. */
  116. function isLocalEl(instance: HandlerDomProxy, el: Node) {
  117. let elTmp = el;
  118. let isLocal = false;
  119. while (elTmp && elTmp.nodeType !== 9
  120. && !(
  121. isLocal = (elTmp as DomExtended).domBelongToZr
  122. || (elTmp !== el && elTmp === instance.painterRoot)
  123. )
  124. ) {
  125. elTmp = elTmp.parentNode;
  126. }
  127. return isLocal;
  128. }
  129. /**
  130. * Make a fake event but not change the original event,
  131. * because the global event probably be used by other
  132. * listeners not belonging to zrender.
  133. * @class
  134. */
  135. class FakeGlobalEvent {
  136. type: string
  137. target: HTMLElement
  138. currentTarget: HTMLElement
  139. pointerType: string
  140. clientX: number
  141. clientY: number
  142. constructor(instance: HandlerDomProxy, event: ZRRawEvent) {
  143. this.type = event.type;
  144. this.target = this.currentTarget = instance.dom;
  145. this.pointerType = (event as any).pointerType;
  146. // Necessray for the force calculation of zrX, zrY
  147. this.clientX = (event as ZRRawMouseEvent).clientX;
  148. this.clientY = (event as ZRRawMouseEvent).clientY;
  149. // Because we do not mount global listeners to touch events,
  150. // we do not copy `targetTouches` and `changedTouches` here.
  151. }
  152. // we make the default methods on the event do nothing,
  153. // otherwise it is dangerous. See more details in
  154. // [DRAG_OUTSIDE] in `Handler.js`.
  155. stopPropagation = zrUtil.noop
  156. stopImmediatePropagation = zrUtil.noop
  157. preventDefault = zrUtil.noop
  158. }
  159. /**
  160. * Local DOM Handlers
  161. * @this {HandlerProxy}
  162. */
  163. const localDOMHandlers: DomHandlersMap = {
  164. mousedown(event: ZRRawEvent) {
  165. event = normalizeEvent(this.dom, event);
  166. this.__mayPointerCapture = [event.zrX, event.zrY];
  167. this.trigger('mousedown', event);
  168. },
  169. mousemove(event: ZRRawEvent) {
  170. event = normalizeEvent(this.dom, event);
  171. const downPoint = this.__mayPointerCapture;
  172. if (downPoint && (event.zrX !== downPoint[0] || event.zrY !== downPoint[1])) {
  173. this.__togglePointerCapture(true);
  174. }
  175. this.trigger('mousemove', event);
  176. },
  177. mouseup(event: ZRRawEvent) {
  178. event = normalizeEvent(this.dom, event);
  179. this.__togglePointerCapture(false);
  180. this.trigger('mouseup', event);
  181. },
  182. mouseout(event: ZRRawEvent) {
  183. event = normalizeEvent(this.dom, event);
  184. // There might be some doms created by upper layer application
  185. // at the same level of painter.getViewportRoot() (e.g., tooltip
  186. // dom created by echarts), where 'globalout' event should not
  187. // be triggered when mouse enters these doms. (But 'mouseout'
  188. // should be triggered at the original hovered element as usual).
  189. const element = (event as any).toElement || (event as ZRRawMouseEvent).relatedTarget;
  190. // For SVG rendering, there are SVG elements inside `this.dom`.
  191. // (especially in decal case). Should not to handle those "mouseout"..
  192. if (!isLocalEl(this, element)) {
  193. // Similarly to the browser did on `document` and touch event,
  194. // `globalout` will be delayed to final pointer cature release.
  195. if (this.__pointerCapturing) {
  196. event.zrEventControl = 'no_globalout';
  197. }
  198. this.trigger('mouseout', event);
  199. }
  200. },
  201. wheel(event: ZRRawEvent) {
  202. // Morden agent has supported event `wheel` instead of `mousewheel`.
  203. // About the polyfill of the props "delta", see "arc/core/event.ts".
  204. // Firefox only support `wheel` rather than `mousewheel`. Although firfox has been supporting
  205. // event `DOMMouseScroll`, it do not act the same behavior as `wheel` on touch pad device
  206. // like on Mac, where `DOMMouseScroll` will be triggered only if a big wheel delta occurs,
  207. // and it results in no chance to "preventDefault". So we should not use `DOMMouseScroll`.
  208. wheelEventSupported = true;
  209. event = normalizeEvent(this.dom, event);
  210. // Follow the definition of the previous version, the zrender event name is still 'mousewheel'.
  211. this.trigger('mousewheel', event);
  212. },
  213. mousewheel(event: ZRRawEvent) {
  214. // IE8- and some other lagacy agent do not support event `wheel`, so we still listen
  215. // to the legacy event `mouseevent`.
  216. // Typically if event `wheel` is supported and the handler has been mounted on a
  217. // DOM element, the legacy `mousewheel` event will not be triggered (Chrome and Safari).
  218. // But we still do this guard to avoid to duplicated handle.
  219. if (wheelEventSupported) {
  220. return;
  221. }
  222. event = normalizeEvent(this.dom, event);
  223. this.trigger('mousewheel', event);
  224. },
  225. touchstart(event: ZRRawEvent) {
  226. // Default mouse behaviour should not be disabled here.
  227. // For example, page may needs to be slided.
  228. event = normalizeEvent(this.dom, event);
  229. markTouch(event);
  230. this.__lastTouchMoment = new Date();
  231. this.handler.processGesture(event, 'start');
  232. // For consistent event listener for both touch device and mouse device,
  233. // we simulate "mouseover-->mousedown" in touch device. So we trigger
  234. // `mousemove` here (to trigger `mouseover` inside), and then trigger
  235. // `mousedown`.
  236. localDOMHandlers.mousemove.call(this, event);
  237. localDOMHandlers.mousedown.call(this, event);
  238. },
  239. touchmove(event: ZRRawEvent) {
  240. event = normalizeEvent(this.dom, event);
  241. markTouch(event);
  242. this.handler.processGesture(event, 'change');
  243. // Mouse move should always be triggered no matter whether
  244. // there is gestrue event, because mouse move and pinch may
  245. // be used at the same time.
  246. localDOMHandlers.mousemove.call(this, event);
  247. },
  248. touchend(event: ZRRawEvent) {
  249. event = normalizeEvent(this.dom, event);
  250. markTouch(event);
  251. this.handler.processGesture(event, 'end');
  252. localDOMHandlers.mouseup.call(this, event);
  253. // Do not trigger `mouseout` here, in spite of `mousemove`(`mouseover`) is
  254. // triggered in `touchstart`. This seems to be illogical, but by this mechanism,
  255. // we can conveniently implement "hover style" in both PC and touch device just
  256. // by listening to `mouseover` to add "hover style" and listening to `mouseout`
  257. // to remove "hover style" on an element, without any additional code for
  258. // compatibility. (`mouseout` will not be triggered in `touchend`, so "hover
  259. // style" will remain for user view)
  260. // click event should always be triggered no matter whether
  261. // there is gestrue event. System click can not be prevented.
  262. if (+new Date() - (+this.__lastTouchMoment) < TOUCH_CLICK_DELAY) {
  263. localDOMHandlers.click.call(this, event);
  264. }
  265. },
  266. pointerdown(event: ZRRawEvent) {
  267. localDOMHandlers.mousedown.call(this, event);
  268. // if (useMSGuesture(this, event)) {
  269. // this._msGesture.addPointer(event.pointerId);
  270. // }
  271. },
  272. pointermove(event: ZRRawEvent) {
  273. // FIXME
  274. // pointermove is so sensitive that it always triggered when
  275. // tap(click) on touch screen, which affect some judgement in
  276. // upper application. So, we don't support mousemove on MS touch
  277. // device yet.
  278. if (!isPointerFromTouch(event)) {
  279. localDOMHandlers.mousemove.call(this, event);
  280. }
  281. },
  282. pointerup(event: ZRRawEvent) {
  283. localDOMHandlers.mouseup.call(this, event);
  284. },
  285. pointerout(event: ZRRawEvent) {
  286. // pointerout will be triggered when tap on touch screen
  287. // (IE11+/Edge on MS Surface) after click event triggered,
  288. // which is inconsistent with the mousout behavior we defined
  289. // in touchend. So we unify them.
  290. // (check localDOMHandlers.touchend for detailed explanation)
  291. if (!isPointerFromTouch(event)) {
  292. localDOMHandlers.mouseout.call(this, event);
  293. }
  294. }
  295. };
  296. /**
  297. * Othere DOM UI Event handlers for zr dom.
  298. * @this {HandlerProxy}
  299. */
  300. zrUtil.each(['click', 'dblclick', 'contextmenu'], function (name) {
  301. localDOMHandlers[name] = function (event) {
  302. event = normalizeEvent(this.dom, event);
  303. this.trigger(name, event);
  304. };
  305. });
  306. /**
  307. * DOM UI Event handlers for global page.
  308. *
  309. * [Caution]:
  310. * those handlers should both support in capture phase and bubble phase!
  311. */
  312. const globalDOMHandlers: DomHandlersMap = {
  313. pointermove: function (event: ZRRawEvent) {
  314. // FIXME
  315. // pointermove is so sensitive that it always triggered when
  316. // tap(click) on touch screen, which affect some judgement in
  317. // upper application. So, we don't support mousemove on MS touch
  318. // device yet.
  319. if (!isPointerFromTouch(event)) {
  320. globalDOMHandlers.mousemove.call(this, event);
  321. }
  322. },
  323. pointerup: function (event: ZRRawEvent) {
  324. globalDOMHandlers.mouseup.call(this, event);
  325. },
  326. mousemove: function (event: ZRRawEvent) {
  327. this.trigger('mousemove', event);
  328. },
  329. mouseup: function (event: ZRRawEvent) {
  330. const pointerCaptureReleasing = this.__pointerCapturing;
  331. this.__togglePointerCapture(false);
  332. this.trigger('mouseup', event);
  333. if (pointerCaptureReleasing) {
  334. event.zrEventControl = 'only_globalout';
  335. this.trigger('mouseout', event);
  336. }
  337. }
  338. };
  339. function mountLocalDOMEventListeners(instance: HandlerDomProxy, scope: DOMHandlerScope) {
  340. const domHandlers = scope.domHandlers;
  341. if (env.pointerEventsSupported) { // Only IE11+/Edge
  342. // 1. On devices that both enable touch and mouse (e.g., MS Surface and lenovo X240),
  343. // IE11+/Edge do not trigger touch event, but trigger pointer event and mouse event
  344. // at the same time.
  345. // 2. On MS Surface, it probablely only trigger mousedown but no mouseup when tap on
  346. // screen, which do not occurs in pointer event.
  347. // So we use pointer event to both detect touch gesture and mouse behavior.
  348. zrUtil.each(localNativeListenerNames.pointer, function (nativeEventName) {
  349. mountSingleDOMEventListener(scope, nativeEventName, function (event) {
  350. // markTriggeredFromLocal(event);
  351. domHandlers[nativeEventName].call(instance, event);
  352. });
  353. });
  354. // FIXME
  355. // Note: MS Gesture require CSS touch-action set. But touch-action is not reliable,
  356. // which does not prevent defuault behavior occasionally (which may cause view port
  357. // zoomed in but use can not zoom it back). And event.preventDefault() does not work.
  358. // So we have to not to use MSGesture and not to support touchmove and pinch on MS
  359. // touch screen. And we only support click behavior on MS touch screen now.
  360. // MS Gesture Event is only supported on IE11+/Edge and on Windows 8+.
  361. // We don't support touch on IE on win7.
  362. // See <https://msdn.microsoft.com/en-us/library/dn433243(v=vs.85).aspx>
  363. // if (typeof MSGesture === 'function') {
  364. // (this._msGesture = new MSGesture()).target = dom; // jshint ignore:line
  365. // dom.addEventListener('MSGestureChange', onMSGestureChange);
  366. // }
  367. }
  368. else {
  369. if (env.touchEventsSupported) {
  370. zrUtil.each(localNativeListenerNames.touch, function (nativeEventName) {
  371. mountSingleDOMEventListener(scope, nativeEventName, function (event) {
  372. // markTriggeredFromLocal(event);
  373. domHandlers[nativeEventName].call(instance, event);
  374. setTouchTimer(scope);
  375. });
  376. });
  377. // Handler of 'mouseout' event is needed in touch mode, which will be mounted below.
  378. // addEventListener(root, 'mouseout', this._mouseoutHandler);
  379. }
  380. // 1. Considering some devices that both enable touch and mouse event (like on MS Surface
  381. // and lenovo X240, @see #2350), we make mouse event be always listened, otherwise
  382. // mouse event can not be handle in those devices.
  383. // 2. On MS Surface, Chrome will trigger both touch event and mouse event. How to prevent
  384. // mouseevent after touch event triggered, see `setTouchTimer`.
  385. zrUtil.each(localNativeListenerNames.mouse, function (nativeEventName) {
  386. mountSingleDOMEventListener(scope, nativeEventName, function (event: ZRRawEvent) {
  387. event = getNativeEvent(event);
  388. if (!scope.touching) {
  389. // markTriggeredFromLocal(event);
  390. domHandlers[nativeEventName].call(instance, event);
  391. }
  392. });
  393. });
  394. }
  395. }
  396. function mountGlobalDOMEventListeners(instance: HandlerDomProxy, scope: DOMHandlerScope) {
  397. // Only IE11+/Edge. See the comment in `mountLocalDOMEventListeners`.
  398. if (env.pointerEventsSupported) {
  399. zrUtil.each(globalNativeListenerNames.pointer, mount);
  400. }
  401. // Touch event has implemented "drag outside" so we do not mount global listener for touch event.
  402. // (see https://www.w3.org/TR/touch-events/#the-touchmove-event) (see also `DRAG_OUTSIDE`).
  403. // We do not consider "both-support-touch-and-mouse device" for this feature (see the comment of
  404. // `mountLocalDOMEventListeners`) to avoid bugs util some requirements come.
  405. else if (!env.touchEventsSupported) {
  406. zrUtil.each(globalNativeListenerNames.mouse, mount);
  407. }
  408. function mount(nativeEventName: string) {
  409. function nativeEventListener(event: ZRRawEvent) {
  410. event = getNativeEvent(event);
  411. // See the reason in [DRAG_OUTSIDE] in `Handler.js`
  412. // This checking supports both `useCapture` or not.
  413. // PENDING: if there is performance issue in some devices,
  414. // we probably can not use `useCapture` and change a easier
  415. // to judes whether local (mark).
  416. if (!isLocalEl(instance, event.target as Node)) {
  417. event = normalizeGlobalEvent(instance, event);
  418. scope.domHandlers[nativeEventName].call(instance, event);
  419. }
  420. }
  421. mountSingleDOMEventListener(
  422. scope, nativeEventName, nativeEventListener,
  423. {capture: true} // See [DRAG_OUTSIDE] in `Handler.js`
  424. );
  425. }
  426. }
  427. function mountSingleDOMEventListener(
  428. scope: DOMHandlerScope,
  429. nativeEventName: string,
  430. listener: EventListener,
  431. opt?: boolean | AddEventListenerOptions
  432. ) {
  433. scope.mounted[nativeEventName] = listener;
  434. scope.listenerOpts[nativeEventName] = opt;
  435. addEventListener(scope.domTarget, nativeEventName, listener, opt);
  436. }
  437. function unmountDOMEventListeners(scope: DOMHandlerScope) {
  438. const mounted = scope.mounted;
  439. for (let nativeEventName in mounted) {
  440. if (mounted.hasOwnProperty(nativeEventName)) {
  441. removeEventListener(
  442. scope.domTarget, nativeEventName, mounted[nativeEventName],
  443. scope.listenerOpts[nativeEventName]
  444. );
  445. }
  446. }
  447. scope.mounted = {};
  448. }
  449. class DOMHandlerScope {
  450. domTarget: HTMLElement | HTMLDocument
  451. domHandlers: DomHandlersMap
  452. // Key: eventName, value: mounted handler functions.
  453. // Used for unmount.
  454. mounted: Dictionary<EventListener> = {};
  455. listenerOpts: Dictionary<boolean | AddEventListenerOptions> = {};
  456. touchTimer: ReturnType<typeof setTimeout>;
  457. touching = false;
  458. constructor(
  459. domTarget: HTMLElement | HTMLDocument,
  460. domHandlers: DomHandlersMap
  461. ) {
  462. this.domTarget = domTarget;
  463. this.domHandlers = domHandlers;
  464. }
  465. }
  466. export default class HandlerDomProxy extends Eventful {
  467. dom: HTMLElement
  468. painterRoot: HTMLElement
  469. handler: Handler
  470. private _localHandlerScope: DOMHandlerScope
  471. private _globalHandlerScope: DOMHandlerScope
  472. __lastTouchMoment: Date
  473. // See [DRAG_OUTSIDE] in `Handler.ts`.
  474. __pointerCapturing = false
  475. // [x, y]
  476. __mayPointerCapture: VectorArray
  477. constructor(dom: HTMLElement, painterRoot: HTMLElement) {
  478. super();
  479. this.dom = dom;
  480. this.painterRoot = painterRoot;
  481. this._localHandlerScope = new DOMHandlerScope(dom, localDOMHandlers);
  482. if (globalEventSupported) {
  483. this._globalHandlerScope = new DOMHandlerScope(document, globalDOMHandlers);
  484. }
  485. mountLocalDOMEventListeners(this, this._localHandlerScope);
  486. }
  487. dispose() {
  488. unmountDOMEventListeners(this._localHandlerScope);
  489. if (globalEventSupported) {
  490. unmountDOMEventListeners(this._globalHandlerScope);
  491. }
  492. }
  493. setCursor(cursorStyle: string) {
  494. this.dom.style && (this.dom.style.cursor = cursorStyle || 'default');
  495. }
  496. /**
  497. * See [DRAG_OUTSIDE] in `Handler.js`.
  498. * @implement
  499. * @param isPointerCapturing Should never be `null`/`undefined`.
  500. * `true`: start to capture pointer if it is not capturing.
  501. * `false`: end the capture if it is capturing.
  502. */
  503. __togglePointerCapture(isPointerCapturing?: boolean) {
  504. this.__mayPointerCapture = null;
  505. if (globalEventSupported
  506. && ((+this.__pointerCapturing) ^ (+isPointerCapturing))
  507. ) {
  508. this.__pointerCapturing = isPointerCapturing;
  509. const globalHandlerScope = this._globalHandlerScope;
  510. isPointerCapturing
  511. ? mountGlobalDOMEventListeners(this, globalHandlerScope)
  512. : unmountDOMEventListeners(globalHandlerScope);
  513. }
  514. }
  515. }
  516. export interface HandlerProxyInterface extends Eventful {
  517. handler: Handler
  518. dispose: () => void
  519. setCursor: (cursorStyle?: string) => void
  520. }