UNPKG

@enact/core

Version:

Enact is an open source JavaScript framework containing everything you need to create a fast, scalable mobile or web application.

162 lines (153 loc) 4.43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.setDefaultTargetById = exports.once = exports.on = exports.off = void 0; var _curry = _interopRequireDefault(require("ramda/src/curry")); var _listeners = require("./listeners"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; } /** * Provides methods to add and remove global event listeners. * * @module core/dispatcher * @exports off * @exports on * @exports once */ var defaultTarget = typeof document === 'object' && document; var rootId; /* * Sets a selector for the default target. If no selector is set, `document` is the default target. * * @function * @param {String} id Node id of the default target * * @returns {undefined} * @memberof core/dispatcher * @private */ var setDefaultTargetById = exports.setDefaultTargetById = function setDefaultTargetById(id) { defaultTarget = typeof document === 'object' && document.querySelector('#' + id) || defaultTarget; rootId = id; }; /* * Checks if the default target of `document` exists before returning it, otherwise returns `false`. * If the default target is falsy and the stored id of the root exists, it tries to find the * default target based on the id. * * @function * * @returns {Node|Boolean} * @memberof core/dispatcher * @private */ var getDefaultTarget = function getDefaultTarget() { if (!defaultTarget && rootId) { setDefaultTargetById(rootId); } return defaultTarget; }; /* * Wraps event callbacks with a try-catch block to prevent unrelated code from blocking. * * @function * @param {Event} ev Event payload * @param {Function} fn Event callback * * @returns {undefined} * @memberof core/dispatcher * @private */ var invoker = (0, _curry["default"])(function (ev, fn) { try { fn(ev); } catch (e) { // eslint-disable-next-line no-console console.error("A ".concat(e.name, " occurred during event handling with the message '").concat(e.message, "'")); } }); /* * Dispatches an event to the registered handlers. * * @function * @param {Event} ev Event payload * * @returns {undefined} * @memberof core/dispatcher * @private */ var dispatcher = function dispatcher(ev) { var name = ev.type; var listeners = (0, _listeners.getListeners)(ev.currentTarget, name); if (listeners) { var inv = invoker(ev); listeners.forEach(inv); } }; /** * Adds a new global event listener. Duplicate event handlers will be discarded. * * @function * @param {String} name Event name * @param {Function} fn Event handler * @param {Node} [target='document'] Event listener target * * @returns {undefined} * @memberof core/dispatcher * @public */ var on = exports.on = function on(name, fn) { var target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getDefaultTarget(); if (target) { var added = (0, _listeners.addListener)(target, name, fn); if (added && (0, _listeners.getListeners)(target, name).length === 1) { target.addEventListener(name, dispatcher); } } }; /** * Removes a global event listener. * * @function * @param {String} name Event name * @param {Function} fn Event handler * @param {Node} [target=`document`] Event listener target * * @returns {undefined} * @memberof core/dispatcher * @public */ var off = exports.off = function off(name, fn) { var target = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getDefaultTarget(); if (target) { var listeners = (0, _listeners.getListeners)(target, name); var index = listeners.indexOf(fn); if (index >= 0) { listeners.splice(index, 1); if (listeners.length === 0) { target.removeEventListener(name, dispatcher); } } } }; /** * Adds a new global event listener that removes itself after handling one event. * * @function * @param {String} name Event name * @param {Function} fn Event handler * @param {Node} [target] Event listener target * * @returns {Function} The single-use handler. To remove the handler manually, call * the `off()` function with this as the 2nd parameter. * @memberof core/dispatcher * @public */ var once = exports.once = function once(name, fn, target) { var _onceFn = function onceFn(ev) { fn(ev); off(name, _onceFn, target); }; on(name, _onceFn, target); return _onceFn; };