123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- // import Core from './core';
- import { polymerWrap, closest } from './helpers/dom/element';
- import { isWebComponentSupportedNatively } from './helpers/feature';
- import { stopImmediatePropagation as _stopImmediatePropagation } from './helpers/dom/event';
- /**
- * Counter which tracks unregistered listeners (useful for detecting memory leaks).
- *
- * @type {Number}
- */
- var listenersCounter = 0;
- /**
- * Event DOM manager for internal use in Handsontable.
- *
- * @class EventManager
- * @util
- */
- var EventManager = function () {
- /**
- * @param {Object} [context=null]
- * @private
- */
- function EventManager() {
- var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
- _classCallCheck(this, EventManager);
- this.context = context || this;
- if (!this.context.eventListeners) {
- this.context.eventListeners = [];
- }
- }
- /**
- * Register specified listener (`eventName`) to the element.
- *
- * @param {Element} element Target element.
- * @param {String} eventName Event name.
- * @param {Function} callback Function which will be called after event occur.
- * @returns {Function} Returns function which you can easily call to remove that event
- */
- _createClass(EventManager, [{
- key: 'addEventListener',
- value: function addEventListener(element, eventName, callback) {
- var _this = this;
- var context = this.context;
- function callbackProxy(event) {
- event = extendEvent(context, event);
- callback.call(this, event);
- }
- this.context.eventListeners.push({
- element: element,
- event: eventName,
- callback: callback,
- callbackProxy: callbackProxy
- });
- if (window.addEventListener) {
- element.addEventListener(eventName, callbackProxy, false);
- } else {
- element.attachEvent('on' + eventName, callbackProxy);
- }
- listenersCounter++;
- return function () {
- _this.removeEventListener(element, eventName, callback);
- };
- }
- /**
- * Remove the event listener previously registered.
- *
- * @param {Element} element Target element.
- * @param {String} eventName Event name.
- * @param {Function} callback Function to remove from the event target. It must be the same as during registration listener.
- */
- }, {
- key: 'removeEventListener',
- value: function removeEventListener(element, eventName, callback) {
- var len = this.context.eventListeners.length;
- var tmpEvent = void 0;
- while (len--) {
- tmpEvent = this.context.eventListeners[len];
- if (tmpEvent.event == eventName && tmpEvent.element == element) {
- if (callback && callback != tmpEvent.callback) {
- /* eslint-disable no-continue */
- continue;
- }
- this.context.eventListeners.splice(len, 1);
- if (tmpEvent.element.removeEventListener) {
- tmpEvent.element.removeEventListener(tmpEvent.event, tmpEvent.callbackProxy, false);
- } else {
- tmpEvent.element.detachEvent('on' + tmpEvent.event, tmpEvent.callbackProxy);
- }
- listenersCounter--;
- }
- }
- }
- /**
- * Clear all previously registered events.
- *
- * @private
- * @since 0.15.0-beta3
- */
- }, {
- key: 'clearEvents',
- value: function clearEvents() {
- if (!this.context) {
- return;
- }
- var len = this.context.eventListeners.length;
- while (len--) {
- var event = this.context.eventListeners[len];
- if (event) {
- this.removeEventListener(event.element, event.event, event.callback);
- }
- }
- }
- /**
- * Clear all previously registered events.
- */
- }, {
- key: 'clear',
- value: function clear() {
- this.clearEvents();
- }
- /**
- * Destroy instance of EventManager.
- */
- }, {
- key: 'destroy',
- value: function destroy() {
- this.clearEvents();
- this.context = null;
- }
- /**
- * Trigger event at the specified target element.
- *
- * @param {Element} element Target element.
- * @param {String} eventName Event name.
- */
- }, {
- key: 'fireEvent',
- value: function fireEvent(element, eventName) {
- var options = {
- bubbles: true,
- cancelable: eventName !== 'mousemove',
- view: window,
- detail: 0,
- screenX: 0,
- screenY: 0,
- clientX: 1,
- clientY: 1,
- ctrlKey: false,
- altKey: false,
- shiftKey: false,
- metaKey: false,
- button: 0,
- relatedTarget: undefined
- };
- var event;
- if (document.createEvent) {
- event = document.createEvent('MouseEvents');
- event.initMouseEvent(eventName, options.bubbles, options.cancelable, options.view, options.detail, options.screenX, options.screenY, options.clientX, options.clientY, options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, options.relatedTarget || document.body.parentNode);
- } else {
- event = document.createEventObject();
- }
- if (element.dispatchEvent) {
- element.dispatchEvent(event);
- } else {
- element.fireEvent('on' + eventName, event);
- }
- }
- }]);
- return EventManager;
- }();
- /**
- * @param {Object} context
- * @param {Event} event
- * @private
- * @returns {*}
- */
- function extendEvent(context, event) {
- var componentName = 'HOT-TABLE';
- var isHotTableSpotted = void 0;
- var fromElement = void 0;
- var realTarget = void 0;
- var target = void 0;
- var len = void 0;
- var nativeStopImmediatePropagation = void 0;
- event.isTargetWebComponent = false;
- event.realTarget = event.target;
- nativeStopImmediatePropagation = event.stopImmediatePropagation;
- event.stopImmediatePropagation = function () {
- nativeStopImmediatePropagation.apply(this);
- _stopImmediatePropagation(this);
- };
- if (!EventManager.isHotTableEnv) {
- return event;
- }
- event = polymerWrap(event);
- len = event.path ? event.path.length : 0;
- while (len--) {
- if (event.path[len].nodeName === componentName) {
- isHotTableSpotted = true;
- } else if (isHotTableSpotted && event.path[len].shadowRoot) {
- target = event.path[len];
- break;
- }
- if (len === 0 && !target) {
- target = event.path[len];
- }
- }
- if (!target) {
- target = event.target;
- }
- event.isTargetWebComponent = true;
- if (isWebComponentSupportedNatively()) {
- event.realTarget = event.srcElement || event.toElement;
- } else if (context instanceof Core || context instanceof Walkontable) {
- // Polymer doesn't support `event.target` property properly we must emulate it ourselves
- if (context instanceof Core) {
- fromElement = context.view ? context.view.wt.wtTable.TABLE : null;
- } else if (context instanceof Walkontable) {
- // .wtHider
- fromElement = context.wtTable.TABLE.parentNode.parentNode;
- }
- realTarget = closest(event.target, [componentName], fromElement);
- if (realTarget) {
- event.realTarget = fromElement.querySelector(componentName) || event.target;
- } else {
- event.realTarget = event.target;
- }
- }
- Object.defineProperty(event, 'target', {
- get: function get() {
- return polymerWrap(target);
- },
- enumerable: true,
- configurable: true
- });
- return event;
- }
- export default EventManager;
- export function getListenersCounter() {
- return listenersCounter;
- };
|