UNPKG

2.61 kBJavaScriptView Raw
1class AvMessage {
2 subscribers = {};
3
4 constructor() {
5 this.isEnabled = true;
6 this.DEFAULT_EVENT = 'avMessage';
7 this.DOMAIN = /https?:\/\/([\w-]+\.)?availity\.(com|net)/;
8 window.addEventListener('message', this.getEventData);
9 }
10
11 enabled(value) {
12 if (arguments.length > 0) {
13 this.isEnabled = !!value;
14 }
15 return this.isEnabled;
16 }
17
18 getEventData = (event) => {
19 if (
20 !this.isEnabled || // do nothing if not enabled
21 !event ||
22 !event.data ||
23 !event.origin ||
24 !event.source || // check event exists and has necessary properties
25 event.source === window || // don't process messages emitted from the same window
26 !this.isDomain(event.origin)
27 ) {
28 // check origin as trusted domain
29 return;
30 }
31
32 let { data } = event;
33
34 if (typeof data === 'string') {
35 try {
36 data = JSON.parse(data);
37 } catch {
38 // no op
39 }
40 }
41
42 if (typeof data === 'string') {
43 event = data;
44 data = undefined;
45 } else {
46 event = (data && data.event) || this.DEFAULT_EVENT;
47 }
48
49 this.onMessage(event, data);
50 };
51
52 subscribe(event, fn) {
53 if (!this.subscribers[event]) {
54 this.subscribers[event] = [];
55 }
56 this.subscribers[event].push(fn);
57 return () => {
58 this.subscribers[event] = this.subscribers[event].filter((val) => val !== fn);
59 };
60 }
61
62 // remove all subscribers for this event
63 unsubscribe(event) {
64 delete this.subscribers[event];
65 }
66
67 unsubscribeAll() {
68 this.subscribers = {};
69 }
70
71 onMessage(event, data) {
72 if (this.subscribers[event]) {
73 for (const fn of this.subscribers[event]) {
74 fn(data);
75 }
76 }
77 }
78
79 // if current domain doesn't match regex DOMAIN, return true.
80 isDomain(url) {
81 return !this.DOMAIN.test(this.domain()) || this.DOMAIN.test(url);
82 }
83
84 domain() {
85 if (window.location.origin) {
86 return window.location.origin;
87 }
88
89 if (window.location.hostname) {
90 return `${window.location.protocol}//${window.location.hostname}${
91 window.location.port ? `:${window.location.port}` : ''
92 }`;
93 }
94
95 return '*';
96 }
97
98 send(payload, target = window.top) {
99 if (!this.isEnabled || !payload) {
100 // ingore send calls if not enabled
101 return;
102 }
103 try {
104 const message = typeof payload === 'string' ? payload : JSON.stringify(payload);
105 target.postMessage(message, this.domain());
106 } catch (error) {
107 // eslint-disable-next-line no-console
108 console.warn('AvMessage.send()', error);
109 }
110 }
111}
112
113export default AvMessage;