Skip to content

Commit

Permalink
refactor(message-core): AvMessage
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Remove message-angular to use subscribers from core
  • Loading branch information
KaseyPowers authored and robmcguinness committed Sep 5, 2018
1 parent c2bf35e commit 4d2d0be
Show file tree
Hide file tree
Showing 9 changed files with 122 additions and 232 deletions.
48 changes: 0 additions & 48 deletions packages/message-angular/README.md

This file was deleted.

16 changes: 0 additions & 16 deletions packages/message-angular/package-lock.json

This file was deleted.

21 changes: 0 additions & 21 deletions packages/message-angular/package.json

This file was deleted.

12 changes: 0 additions & 12 deletions packages/message-angular/src/index.js

This file was deleted.

19 changes: 0 additions & 19 deletions packages/message-angular/src/tests/test.js

This file was deleted.

4 changes: 4 additions & 0 deletions packages/message-core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ A package wrapping the postMessage function with helper functions and security c

`npm install @availity/message-core`

## how to use

`import avMessage from '@availity/message-core`

## Methods

### subscribe
Expand Down
115 changes: 115 additions & 0 deletions packages/message-core/src/AvMessage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
class AvMessage {
subscribers = {};

constructor() {
this.isEnabled = true;
this.DEFAULT_EVENT = 'avMessage';
this.DOMAIN = /https?:\/\/([\w\d-]+\.)?availity\.(com|net)/;
window.addEventListener('message', this.getEventData);
}

enabled(value) {
if (arguments.length) {
this.isEnabled = !!value;
}
return this.isEnabled;
}

getEventData = event => {
if (
!this.isEnabled || // do nothing if not enabled
!event ||
!event.data ||
!event.origin ||
!event.source || // check event exists and has necesary properties
event.source === window || // don't process messages emitted from the same window
!this.isDomain(event.origin)
) {
// check origin as trusted domain
return;
}

let { data } = event;

if (typeof data === 'string') {
try {
data = JSON.parse(data);
} catch (e) {
// warn about error
}
}

if (typeof data === 'string') {
event = data;
data = undefined;
} else {
event = (data && data.event) || this.DEFAULT_EVENT;
}

this.onMessage(event, data);
};

subscribe(event, fn) {
if (!this.subscribers[event]) {
this.subscribers[event] = [];
}
this.subscribers[event].push(fn);
return () => {
this.subscribers[event] = this.subscribers[event].filter(
val => val !== fn
);
};
}

// remove all subscribers for this event
unsubscribe(event) {
delete this.subscribers[event];
}

unsubscribeAll() {
this.subscribers = {};
}

onMessage(event, data) {
if (this.subscribers[event]) {
this.subscribers[event].forEach(fn => {
fn(data);
});
}
}

// if current domain doesn't match regex DOMAIN, return true.
isDomain(url) {
return !this.DOMAIN.test(this.domain()) || this.DOMAIN.test(url);
}

domain() {
if (window.location.origin) {
return window.location.origin;
}

if (window.location.hostname) {
return `${window.location.protocol}//${window.location.hostname}${
window.location.port ? `:${window.location.port}` : ''
}`;
}

return '*';
}

send(payload, target = window.top) {
if (!this.isEnabled || !payload) {
// ingore send calls if not enabled
return;
}
try {
const message =
typeof payload === 'string' ? payload : JSON.stringify(payload);
target.postMessage(message, this.domain());
} catch (err) {
console.warn('AvMessage.send() ', err); // eslint-disable-line
}
}
}

export default AvMessage;
117 changes: 2 additions & 115 deletions packages/message-core/src/index.js
Original file line number Diff line number Diff line change
@@ -1,116 +1,3 @@
class AvMessage {
subscribers = {};
import AvMessage from './AvMessage';

constructor() {
this.isEnabled = true;
this.DEFAULT_EVENT = 'avMessage';
this.DOMAIN = /https?:\/\/([\w\d-]+\.)?availity\.(com|net)/;
window.addEventListener('message', ::this.getEventData);
}

enabled(value) {
if (arguments.length) {
this.isEnabled = !!value;
}
return this.isEnabled;
}

getEventData(event) {
if (
!this.isEnabled || // do nothing if not enabled
!event ||
!event.data ||
!event.origin ||
!event.source || // check event exists and has necesary properties
event.source === window || // don't process messages emitted from the same window
!this.isDomain(event.origin)
) {
// check origin as trusted domain
return;
}

let { data } = event;

if (typeof data === 'string') {
try {
data = JSON.parse(data);
} catch (e) {
// warn about error
}
}

if (typeof data === 'string') {
event = data;
data = undefined;
} else {
event = (data && data.event) || this.DEFAULT_EVENT;
}

this.onMessage(event, data);
}

subscribe(event, fn) {
if (!this.subscribers[event]) {
this.subscribers[event] = [];
}
this.subscribers[event].push(fn);
return () => {
this.subscribers[event] = this.subscribers[event].filter(
val => val !== fn
);
};
}

// remove all subscribers for this event
unsubscribe(event) {
delete this.subscribers[event];
}

unsubscribeAll() {
this.subscribers = {};
}

onMessage(event, data) {
if (this.subscribers[event]) {
this.subscribers[event].forEach(fn => {
fn(data);
});
}
}

// if current domain doesn't match regex DOMAIN, return true.
isDomain(url) {
return !this.DOMAIN.test(this.domain()) || this.DOMAIN.test(url);
}

domain() {
if (window.location.origin) {
return window.location.origin;
}

if (window.location.hostname) {
return `${window.location.protocol}//${window.location.hostname}${
window.location.port ? `:${window.location.port}` : ''
}`;
}

return '*';
}

send(payload, target) {
if (!this.isEnabled || !payload) {
// ingore send calls if not enabled
return;
}
try {
const message =
typeof payload === 'string' ? payload : JSON.stringify(payload);
target = target || window.parent;
target.postMessage(message, this.domain());
} catch (err) {
console.warn('AvMessage.send() ', err); // eslint-disable-line
}
}
}

export default AvMessage;
export default new AvMessage();
2 changes: 1 addition & 1 deletion packages/message-core/src/tests/message.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import AvMessage from '../';
import AvMessage from '../AvMessage';

let avMessage;
const URL = 'https://dev.local:9999';
Expand Down

0 comments on commit 4d2d0be

Please sign in to comment.