ng2-events
Version:
Supercharge your Angular2+ event handling
798 lines (776 loc) • 33.6 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, Inject, NgModule, Directive, Input, EventEmitter, Output, InjectionToken } from '@angular/core';
import { EVENT_MANAGER_PLUGINS } from '@angular/platform-browser';
import { DOCUMENT } from '@angular/common';
import { Subject } from 'rxjs';
import { auditTime } from 'rxjs/operators';
class MyEventManagerPlugin {
constructor(_doc) {
this._doc = _doc;
}
addGlobalEventListener(element, eventName, handler) {
let target;
if (element === 'document')
target = this._doc;
else if (element === 'window' && typeof (window) !== undefined)
target = window;
if (!target) {
throw new Error(`Unsupported event target ${target} for event ${eventName}`);
}
return this.addEventListener(target, eventName, handler);
}
;
}
/**
* Listen to events that are fired outside of the current element and its children
*
* Usage:
* <div (outside.click)="close()"></div>
*
*/
class OutsideEventPlugin extends MyEventManagerPlugin {
constructor(doc) {
super(doc);
}
supports(eventName) {
return eventName.indexOf('outside.') === 0;
}
addEventListener(element, eventName, handler) {
const realEventName = eventName.slice(8);
return this.manager.addEventListener((element.ownerDocument || document), realEventName, (e) => {
if (element !== e.target && !element.contains(e.target)) {
handler(e);
}
});
}
}
OutsideEventPlugin.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OutsideEventPlugin, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
OutsideEventPlugin.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OutsideEventPlugin });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OutsideEventPlugin, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }]; } });
class OutsideEventModule {
}
OutsideEventModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OutsideEventModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
OutsideEventModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OutsideEventModule });
OutsideEventModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OutsideEventModule, providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: OutsideEventPlugin,
multi: true
}
] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OutsideEventModule, decorators: [{
type: NgModule,
args: [{
providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: OutsideEventPlugin,
multi: true
}
]
}]
}] });
/**
* Listen to events without triggering change detection
*
* Usage:
* <button (undetected.click)="handleClick()"></button>
*
* ...
*
* export class ExampleComponent implements OnInit {
*
* constructor(private zone: NgZone) {}
*
* handleClick() {
* if(someCondition) {
* this.zone.run(() => {
* ...
* });
* }
* }
* }
*
*/
class UndetectedEventPlugin extends MyEventManagerPlugin {
constructor(doc) {
super(doc);
}
supports(eventName) {
return eventName.indexOf('undetected.') === 0;
}
addEventListener(element, eventName, handler) {
const realEventName = eventName.slice(11);
return this.manager.getZone().runOutsideAngular(() => this.manager.addEventListener(element, realEventName, handler));
}
}
UndetectedEventPlugin.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: UndetectedEventPlugin, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
UndetectedEventPlugin.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: UndetectedEventPlugin });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: UndetectedEventPlugin, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }]; } });
class UndetectedEventModule {
}
UndetectedEventModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: UndetectedEventModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
UndetectedEventModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: UndetectedEventModule });
UndetectedEventModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: UndetectedEventModule, providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: UndetectedEventPlugin,
multi: true
}
] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: UndetectedEventModule, decorators: [{
type: NgModule,
args: [{
providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: UndetectedEventPlugin,
multi: true
}
]
}]
}] });
/**
* Register multiple event listeners
*
* Usage:
* <button (multi.focus,select)="foo($event)"></button>
*
*/
class MultiEventPlugin extends MyEventManagerPlugin {
constructor(doc) {
super(doc);
}
supports(eventName) {
return eventName.indexOf('multi.') === 0;
}
addEventListener(element, eventName, handler) {
const eventNames = eventName.slice(6).split(',');
const eventListeners = eventNames.map(x => this.manager.addEventListener(element, x, handler));
return () => {
eventListeners.forEach(x => x());
};
}
}
MultiEventPlugin.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: MultiEventPlugin, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
MultiEventPlugin.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: MultiEventPlugin });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: MultiEventPlugin, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }]; } });
class MultiEventModule {
}
MultiEventModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: MultiEventModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
MultiEventModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: MultiEventModule });
MultiEventModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: MultiEventModule, providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: MultiEventPlugin,
multi: true
}
] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: MultiEventModule, decorators: [{
type: NgModule,
args: [{
providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: MultiEventPlugin,
multi: true
}
]
}]
}] });
/**
* Control event listeners with an observable operator without triggering change detection
* every time the event fires
*
* Usage:
* <button (observe.throttleTime-500.click)="foo()"></button>
*
* The method used must be present on the Observable object
* e.g. through an explicit import:
* import 'rxjs/add/operator/throttleTime';
*
*
* To get finer-grained control and the possibility to add multiple observable operators
* use the ObserveEventDirective.
*/
class ObserveEventPlugin extends MyEventManagerPlugin {
constructor(doc) {
super(doc);
}
supports(eventName) {
return eventName.indexOf('observe.') === 0;
}
addEventListener(element, eventName, handler) {
return this.manager.getZone().runOutsideAngular(() => {
const eventRest = eventName.slice(8).split('.');
const fnParts = eventRest[0].split('-');
const fnName = fnParts[0];
const fnArg = (fnParts.length > 1) ? +fnParts[1] : undefined;
const delegateEvent = eventRest.slice(1).join('.');
const subject = new Subject();
let observable = subject.asObservable();
if (observable[fnName]) {
observable = (fnArg !== undefined)
? observable[fnName](fnArg)
: observable[fnName]();
}
else {
console.error('The function "' + fnName + '" does not exist on Observable!');
return () => { };
}
observable.subscribe(x => this.manager.getZone().run(() => handler(x)));
const listener = this.manager.addEventListener(element, delegateEvent, ($event) => {
subject.next($event);
});
return () => {
listener();
subject.complete();
};
});
}
}
ObserveEventPlugin.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventPlugin, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
ObserveEventPlugin.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventPlugin });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventPlugin, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }]; } });
class ObserveEventModule {
}
ObserveEventModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
ObserveEventModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventModule });
ObserveEventModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventModule, providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: ObserveEventPlugin,
multi: true
}
] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventModule, decorators: [{
type: NgModule,
args: [{
providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: ObserveEventPlugin,
multi: true
}
]
}]
}] });
/**
* Pass events to a given observable subject without triggering change detection
*
* Usage:
* <button [ev-observe]="subject" ev-events="click"></button>
*
* ...
*
* export class ExampleComponent implements OnInit {
* public subject = new Subject();
*
* constructor(private zone: NgZone) {}
*
* ngOnInit() {
* this.subject
* .throttleTime(300)
* .filter(someCondition)
* ...
* .subscribe($event => this.zone.run(() => this.handleEvent($event)));
* }
* }
*
* Notes:
* The [ev-events] property can be either a string or an array of strings to handle multiple events
*
*/
class ObserveEventDirective {
constructor(elm, renderer, zone) {
this.elm = elm;
this.renderer = renderer;
this.zone = zone;
this.listeners = [];
}
set events(e) {
this.unregisterAll();
const events = (typeof (e) === 'string')
? [e]
: e;
this.zone.runOutsideAngular(() => {
this.listeners = events.map(x => this.addListener(x));
});
}
ngOnDestroy() {
this.unregisterAll();
}
unregisterAll() {
this.listeners.forEach(x => x());
this.listeners = [];
}
addListener(eventName) {
const colon = eventName.indexOf(':');
const handler = ($event) => this.fireEvent($event);
if (colon === -1) {
return this.renderer.listen(this.elm.nativeElement, eventName, handler);
}
else {
const scope = eventName.slice(0, colon);
const realEventName = eventName.slice(colon + 1);
return this.renderer.listen(scope, realEventName, handler);
}
}
fireEvent($event) {
if (!this.observe)
return;
this.observe.next($event);
}
}
ObserveEventDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
ObserveEventDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.0.2", type: ObserveEventDirective, selector: "[ev-observe]", inputs: { observe: ["ev-observe", "observe"], events: ["ev-events", "events"] }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventDirective, decorators: [{
type: Directive,
args: [{
selector: '[ev-observe]'
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }]; }, propDecorators: { observe: [{
type: Input,
args: ['ev-observe']
}], events: [{
type: Input,
args: ['ev-events']
}] } });
class ObserveEventDirectiveModule {
}
ObserveEventDirectiveModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventDirectiveModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
ObserveEventDirectiveModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventDirectiveModule, declarations: [ObserveEventDirective], exports: [ObserveEventDirective] });
ObserveEventDirectiveModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventDirectiveModule });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ObserveEventDirectiveModule, decorators: [{
type: NgModule,
args: [{
declarations: [
ObserveEventDirective
],
exports: [
ObserveEventDirective
]
}]
}] });
function getNativeEventNames(eventName) {
const supportsPointerEvents = typeof (window) !== 'undefined' && 'PointerEvent' in window;
switch (eventName) {
case 'up':
return supportsPointerEvents
? ['pointerup']
: ['mouseup', 'touchend'];
case 'down':
return supportsPointerEvents
? ['pointerdown']
: ['mousedown', 'touchstart'];
case 'move':
return supportsPointerEvents
? ['pointermove']
: ['mousemove', 'touchmove'];
default:
return [];
}
}
/**
* Quick-firing 'up' and 'down' events that work cross-browser for mouse and touch events
*
* Usage:
* <button (down)="activate()" (up)="deactivate()"></button>
*
*/
class TouchEventPlugin extends MyEventManagerPlugin {
constructor(doc) {
super(doc);
}
supports(eventName) {
return eventName === 'down' || eventName === 'up' || eventName === 'move';
}
addEventListener(element, eventName, handler) {
const eventListeners = getNativeEventNames(eventName).map(x => this.manager.addEventListener(element, x, (e) => {
// prevent default so only one of the event listeners is fired
e.preventDefault();
handler(e);
}));
return () => {
eventListeners.forEach(x => x());
};
}
}
TouchEventPlugin.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: TouchEventPlugin, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
TouchEventPlugin.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: TouchEventPlugin });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: TouchEventPlugin, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }]; } });
class TouchEventModule {
}
TouchEventModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: TouchEventModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
TouchEventModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: TouchEventModule });
TouchEventModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: TouchEventModule, providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: TouchEventPlugin,
multi: true
}
] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: TouchEventModule, decorators: [{
type: NgModule,
args: [{
providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: TouchEventPlugin,
multi: true
}
]
}]
}] });
/**
* Automatically unregister an event listener after the event fired once
*
* Usage:
* <button (once.click)="foo()">...</button>
*
*/
class OnceEventPlugin extends MyEventManagerPlugin {
constructor(doc) {
super(doc);
}
supports(eventName) {
return eventName.indexOf('once.') === 0;
}
addEventListener(element, eventName, handler) {
const realEventName = eventName.slice(5);
let active = true;
const eventListener = this.manager.addEventListener(element, realEventName, ($event) => {
eventListener();
active = false;
handler($event);
});
return () => {
if (active)
eventListener();
};
}
}
OnceEventPlugin.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OnceEventPlugin, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable });
OnceEventPlugin.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OnceEventPlugin });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OnceEventPlugin, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }]; } });
class OnceEventModule {
}
OnceEventModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OnceEventModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
OnceEventModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OnceEventModule });
OnceEventModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OnceEventModule, providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: OnceEventPlugin,
multi: true
}
] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: OnceEventModule, decorators: [{
type: NgModule,
args: [{
providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: OnceEventPlugin,
multi: true
}
]
}]
}] });
/**
* Conditionally apply event listeners to an element
*
* Usage:
* <button [ev-condition]="isActive()"
* ev-events="click"
* (ev-fire)="handleClick($event)">...</button>
*
* Notes:
* The [ev-events] property can be either a string or an array of strings to handle multiple events
*/
class ConditionEventDirective {
constructor(elm, renderer) {
this.elm = elm;
this.renderer = renderer;
this.fire = new EventEmitter();
this.listeners = [];
}
ngOnChanges(changes) {
this.unregisterAll();
if (!this.condition || !this.events)
return;
const events = (typeof (this.events) === 'string')
? [this.events]
: this.events;
this.listeners = events.map(x => this.addListener(x));
}
ngOnDestroy() {
this.unregisterAll();
}
unregisterAll() {
this.listeners.forEach(x => x());
this.listeners = [];
}
addListener(eventName) {
const colon = eventName.indexOf(':');
const handler = ($event) => this.fire.next($event);
if (colon === -1) {
return this.renderer.listen(this.elm.nativeElement, eventName, handler);
}
else {
const scope = eventName.slice(0, colon);
const realEventName = eventName.slice(colon + 1);
return this.renderer.listen(scope, realEventName, handler);
}
}
}
ConditionEventDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ConditionEventDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
ConditionEventDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.0.2", type: ConditionEventDirective, selector: "[ev-condition]", inputs: { condition: ["ev-condition", "condition"], events: ["ev-events", "events"] }, outputs: { fire: "ev-fire" }, usesOnChanges: true, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ConditionEventDirective, decorators: [{
type: Directive,
args: [{
selector: '[ev-condition]'
}]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { condition: [{
type: Input,
args: ['ev-condition']
}], events: [{
type: Input,
args: ['ev-events']
}], fire: [{
type: Output,
args: ['ev-fire']
}] } });
class ConditionEventDirectiveModule {
}
ConditionEventDirectiveModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ConditionEventDirectiveModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
ConditionEventDirectiveModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ConditionEventDirectiveModule, declarations: [ConditionEventDirective], exports: [ConditionEventDirective] });
ConditionEventDirectiveModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ConditionEventDirectiveModule });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ConditionEventDirectiveModule, decorators: [{
type: NgModule,
args: [{
declarations: [
ConditionEventDirective
],
exports: [
ConditionEventDirective
]
}]
}] });
const SCROLL_EVENT_TIME = new InjectionToken('ScrollEventTime');
/**
* Detects when an element is scrolled into or out of the viewport
*
* Usage:
* <div (scroll-in)="activate()" (scroll-out)="deactivate()">...</div>
*
* The matching handler of the initial status is called upon attaching
* to notify the element of its current status. $event is true for the
* initial call, false otherwise
*
*/
class ScrollEventPlugin extends MyEventManagerPlugin {
constructor(doc, time) {
super(doc);
this.listeners = [];
this.globalListener = undefined;
this.subject = new Subject();
this.subject
.pipe(auditTime(time))
.subscribe(() => {
this.listeners.forEach(x => x());
});
}
supports(eventName) {
return eventName === 'scroll-in' || eventName === 'scroll-out';
}
addEventListener(element, eventName, handler) {
const isScrollIn = (eventName === 'scroll-in');
let status = undefined;
setTimeout(() => {
status = this.getStatus(element);
if ((isScrollIn && status) || (!isScrollIn && !status)) {
handler(true);
}
}, 0);
const listener = () => {
const newStatus = this.getStatus(element);
if (status === newStatus)
return;
if ((isScrollIn && newStatus) || (!isScrollIn && !newStatus)) {
this.manager.getZone().run(() => handler(false));
}
status = newStatus;
};
this.listeners.push(listener);
this.updateGlobalListener();
return () => {
const index = this.listeners.indexOf(listener);
if (index === -1)
return;
this.listeners.splice(index, 1);
this.updateGlobalListener();
};
}
updateGlobalListener() {
if (this.listeners.length && this.globalListener === undefined) {
this.manager.getZone().runOutsideAngular(() => {
const handler = () => {
this.subject.next();
};
const listeners = ['scroll', 'resize', 'orientationchange']
.map(x => this.manager.addEventListener(this._doc.defaultView || window, x, handler));
this.globalListener = () => {
listeners.forEach(x => x());
};
});
}
else if (!this.listeners.length && this.globalListener !== undefined) {
this.globalListener();
this.globalListener = undefined;
}
}
getStatus(element) {
const rect = element.getBoundingClientRect();
return (rect.bottom >= 0 && rect.top <= window.innerHeight);
}
}
ScrollEventPlugin.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ScrollEventPlugin, deps: [{ token: DOCUMENT }, { token: SCROLL_EVENT_TIME }], target: i0.ɵɵFactoryTarget.Injectable });
ScrollEventPlugin.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ScrollEventPlugin });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ScrollEventPlugin, decorators: [{
type: Injectable
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }, { type: undefined, decorators: [{
type: Inject,
args: [SCROLL_EVENT_TIME]
}] }]; } });
class ScrollEventModule {
}
ScrollEventModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ScrollEventModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
ScrollEventModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ScrollEventModule });
ScrollEventModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ScrollEventModule, providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: ScrollEventPlugin,
multi: true
},
{
provide: SCROLL_EVENT_TIME,
useValue: 200
}
] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: ScrollEventModule, decorators: [{
type: NgModule,
args: [{
providers: [
{
provide: EVENT_MANAGER_PLUGINS,
useClass: ScrollEventPlugin,
multi: true
},
{
provide: SCROLL_EVENT_TIME,
useValue: 200
}
]
}]
}] });
class Ng2EventsModule {
}
Ng2EventsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: Ng2EventsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
Ng2EventsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: Ng2EventsModule, imports: [OutsideEventModule,
TouchEventModule,
MultiEventModule,
UndetectedEventModule,
ObserveEventModule,
ObserveEventDirectiveModule,
OnceEventModule,
ConditionEventDirectiveModule,
ScrollEventModule], exports: [OutsideEventModule,
TouchEventModule,
MultiEventModule,
UndetectedEventModule,
ObserveEventModule,
ObserveEventDirectiveModule,
OnceEventModule,
ConditionEventDirectiveModule,
ScrollEventModule] });
Ng2EventsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: Ng2EventsModule, imports: [[
OutsideEventModule,
TouchEventModule,
MultiEventModule,
UndetectedEventModule,
ObserveEventModule,
ObserveEventDirectiveModule,
OnceEventModule,
ConditionEventDirectiveModule,
ScrollEventModule
], OutsideEventModule,
TouchEventModule,
MultiEventModule,
UndetectedEventModule,
ObserveEventModule,
ObserveEventDirectiveModule,
OnceEventModule,
ConditionEventDirectiveModule,
ScrollEventModule] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.0.2", ngImport: i0, type: Ng2EventsModule, decorators: [{
type: NgModule,
args: [{
imports: [
OutsideEventModule,
TouchEventModule,
MultiEventModule,
UndetectedEventModule,
ObserveEventModule,
ObserveEventDirectiveModule,
OnceEventModule,
ConditionEventDirectiveModule,
ScrollEventModule
],
exports: [
OutsideEventModule,
TouchEventModule,
MultiEventModule,
UndetectedEventModule,
ObserveEventModule,
ObserveEventDirectiveModule,
OnceEventModule,
ConditionEventDirectiveModule,
ScrollEventModule
]
}]
}] });
export default Ng2EventsModule;
export { ConditionEventDirective, ConditionEventDirectiveModule, MultiEventModule, Ng2EventsModule, ObserveEventDirective, ObserveEventDirectiveModule, ObserveEventModule, OnceEventModule, OutsideEventModule, SCROLL_EVENT_TIME, ScrollEventModule, TouchEventModule, UndetectedEventModule };