Developed disable navigation mechanism
[sdc.git] / catalog-ui / src / app / models / base-pubsub.ts
1 declare const window: Window;
2
3 export class BasePubSub {
4
5     subscribers: Map<string, ISubscriber>;
6     eventsCallbacks: Array<Function>;
7     clientId: string;
8     eventsToWait: Map<string, Array<string>>;
9     lastEventNotified: string;
10
11     constructor(pluginId: string) {
12         this.subscribers = new Map<string, ISubscriber>();
13         this.eventsCallbacks = [];
14         this.eventsToWait = new Map<string, Array<string>>();
15         this.clientId = pluginId;
16         this.lastEventNotified = "";
17         this.onMessage = this.onMessage.bind(this);
18
19         window.addEventListener("message", this.onMessage);
20     }
21
22     public register(subscriberId: string, subscriberWindow: Window, subscriberUrl: string) {
23         const subscriber = {
24             window: subscriberWindow,
25             locationUrl: subscriberUrl || subscriberWindow.location.href
26         } as ISubscriber;
27
28         this.subscribers.set(subscriberId, subscriber);
29     }
30
31     public unregister(subscriberId: string) {
32         this.subscribers.delete(subscriberId);
33     }
34
35     public on(callback: Function) {
36         let functionExists = this.eventsCallbacks.find((func: Function) => {
37             return callback.toString() == func.toString()
38         });
39
40         if (!functionExists) {
41             this.eventsCallbacks.push(callback);
42         }
43     }
44
45     public off(callback: Function) {
46         let index = this.eventsCallbacks.indexOf(callback);
47         this.eventsCallbacks.splice(index, 1)
48     }
49
50     public notify(eventType:string, eventData?:any) {
51         let eventObj = {
52             type: eventType,
53             data: eventData,
54             originId: this.clientId
55         } as IPubSubEvent;
56
57         this.subscribers.forEach( (subscriber: ISubscriber, subscriberId: string) => {
58             subscriber.window.postMessage(eventObj, subscriber.locationUrl);
59         });
60
61         this.lastEventNotified = eventType;
62
63         return {
64             subscribe: function(callbackFn) {
65
66                 if(this.subscribers.size !== 0) {
67                     let subscribersToNotify = Array.from(this.subscribers.keys());
68
69                     const checkNotifyComplete = (subscriberId: string) => {
70
71                         let index = subscribersToNotify.indexOf(subscriberId);
72                         subscribersToNotify.splice(index, 1);
73
74                         if (subscribersToNotify.length === 0) {
75                             callbackFn();
76                         }
77                     };
78
79                     this.subscribers.forEach((subscriber: ISubscriber, subscriberId: string) => {
80                         if (this.eventsToWait.has(subscriberId) && this.eventsToWait.get(subscriberId).indexOf(eventType) !== -1) {
81
82                             const actionCompletedFunction = (eventData, subId = subscriberId) => {
83                                 if (eventData.type == "ACTION_COMPLETED") {
84                                     checkNotifyComplete(subId);
85                                 }
86                                 this.off(actionCompletedFunction);
87
88                             };
89                             this.on(actionCompletedFunction);
90                         }
91                         else {
92                             checkNotifyComplete(subscriberId);
93                         }
94                     });
95                 }
96                 else {
97                     callbackFn();
98                 }
99             }.bind(this)
100         }
101     }
102
103     public isWaitingForEvent(eventName: string) : boolean {
104         return Array.from(this.eventsToWait.values()).some((eventsList: Array<string>) =>
105             eventsList.indexOf(eventName) !== -1
106         );
107     }
108
109     protected onMessage(event: any) {
110         if (this.subscribers.has(event.data.originId)) {
111             this.eventsCallbacks.forEach((callback: Function) => {
112                 callback(event.data, event);
113             })
114         }
115     }
116 }
117
118 export interface IPubSubEvent {
119     type: string;
120     originId: string;
121     data: any;
122 }
123
124 export interface ISubscriber {
125     window: Window;
126     locationUrl: string;
127 }