ngx-modialog
Version:
Modal / Dialog for Angular
108 lines (107 loc) • 4.59 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
// heavily inspired by:
// http://www.bennadel.com/blog/3025-creating-custom-dom-and-host-event-bindings-in-angular-2-beta-6.htm
import { Injectable } from '@angular/core';
import { noop } from '../framework/utils';
// TODO: use DI factory for this.
// TODO: consolidate dup code
var /** @type {?} */ isDoc = !(typeof document === 'undefined' || !document);
var /** @type {?} */ eventMap = {
clickOutside: 'click',
mousedownOutside: 'mousedown',
mouseupOutside: 'mouseup',
mousemoveOutside: 'mousemove'
};
/**
* An event handler factory for event handlers that bubble the event to a given handler
* if the event target is not an ancestor of the given element.
* @param {?} element
* @param {?} handler
* @return {?}
*/
function bubbleNonAncestorHandlerFactory(element, handler) {
return function (event) {
var /** @type {?} */ current = event.target;
do {
if (current === element) {
return;
}
} while (current.parentNode && (current = current.parentNode));
handler(event);
};
}
var DOMOutsideEventPlugin = /** @class */ (function () {
function DOMOutsideEventPlugin() {
if (!isDoc || typeof document.addEventListener !== 'function') {
this.addEventListener = /** @type {?} */ (noop);
}
}
/**
* @param {?} eventName
* @return {?}
*/
DOMOutsideEventPlugin.prototype.supports = function (eventName) {
return eventMap.hasOwnProperty(eventName);
};
/**
* @param {?} element
* @param {?} eventName
* @param {?} handler
* @return {?}
*/
DOMOutsideEventPlugin.prototype.addEventListener = function (element, eventName, handler) {
var /** @type {?} */ zone = this.manager.getZone();
// A Factory that registers the event on the document, instead of the element.
// the handler is created at runtime, and it acts as a propagation/bubble predicate, it will
// bubble up the event (i.e: execute our original event handler) only if the event targer
// is an ancestor of our element.
// The event is fired inside the angular zone so change detection can kick into action.
var /** @type {?} */ onceOnOutside = function () {
var /** @type {?} */ listener = bubbleNonAncestorHandlerFactory(element, function (evt) { return zone.runGuarded(function () { return handler(evt); }); });
// mimic BrowserDomAdapter.onAndCancel
document.addEventListener(eventMap[eventName], listener, false);
return function () { return document.removeEventListener(eventMap[eventName], listener, false); };
};
// we run the event registration for the document in a different zone, this will make sure
// change detection is off.
// It turns out that if a component that use DOMOutsideEventPlugin is built from a click
// event, we might get here before the event reached the document, causing a quick false
// positive handling (when stopPropagation() was'nt invoked). To workaround this we wait
// for the next vm turn and register.
// Event registration returns a dispose function for that event, angular use it to clean
// up after component get's destroyed. Since we need to return a dispose function
// synchronously we have to put a wrapper for it since we will get it asynchronously,
// i.e: after we need to return it.
//
return zone.runOutsideAngular(function () {
var /** @type {?} */ fn;
setTimeout(function () { return fn = onceOnOutside(); }, 0);
return function () {
if (fn)
fn();
};
});
};
return DOMOutsideEventPlugin;
}());
export { DOMOutsideEventPlugin };
DOMOutsideEventPlugin.decorators = [
{ type: Injectable },
];
/** @nocollapse */
DOMOutsideEventPlugin.ctorParameters = function () { return []; };
function DOMOutsideEventPlugin_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
DOMOutsideEventPlugin.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
DOMOutsideEventPlugin.ctorParameters;
/** @type {?} */
DOMOutsideEventPlugin.prototype.manager;
}
//# sourceMappingURL=outside-event-plugin.js.map