UNPKG

2.19 kBPlain TextView Raw
1import {Stream, Producer, Listener} from 'xstream';
2
3export type Predicate = (ev: any) => boolean;
4export type PreventDefaultOpt = boolean | Predicate | Comparator;
5export type Comparator = {[key: string]: any};
6
7export function fromEvent(
8 element: Element | Document,
9 eventName: string,
10 useCapture = false,
11 preventDefault: PreventDefaultOpt = false,
12 passive = false
13): Stream<Event> {
14 let next: ((e: Event) => void) | null = null;
15 return Stream.create<Event>({
16 start: function start(listener: Listener<Event>) {
17 if (preventDefault) {
18 next = function _next(event: Event) {
19 preventDefaultConditional(event, preventDefault);
20 listener.next(event);
21 };
22 } else {
23 next = function _next(event: Event) {
24 listener.next(event);
25 };
26 }
27 element.addEventListener(eventName, next, {
28 capture: useCapture,
29 passive,
30 });
31 },
32 stop: function stop() {
33 element.removeEventListener(eventName, next as any, useCapture);
34 next = null;
35 },
36 } as Producer<Event>);
37}
38
39function matchObject(matcher: object, obj: object): boolean {
40 const keys = Object.keys(matcher);
41 const n = keys.length;
42 for (let i = 0; i < n; i++) {
43 const k = keys[i];
44 if (typeof matcher[k] === 'object' && typeof obj[k] === 'object') {
45 if (!matchObject(matcher[k], obj[k])) {
46 return false;
47 }
48 } else if (matcher[k] !== obj[k]) {
49 return false;
50 }
51 }
52 return true;
53}
54
55export function preventDefaultConditional(
56 event: any,
57 preventDefault: PreventDefaultOpt
58): void {
59 if (preventDefault) {
60 if (typeof preventDefault === 'boolean') {
61 event.preventDefault();
62 } else if (isPredicate(preventDefault)) {
63 if (preventDefault(event)) {
64 event.preventDefault();
65 }
66 } else if (typeof preventDefault === 'object') {
67 if (matchObject(preventDefault, event)) {
68 event.preventDefault();
69 }
70 } else {
71 throw new Error(
72 'preventDefault has to be either a boolean, predicate function or object'
73 );
74 }
75 }
76}
77
78function isPredicate(fn: any): fn is Predicate {
79 return typeof fn === 'function';
80}
81
\No newline at end of file