Skip to content

Commit 604cc29

Browse files
committed
ENG-41103 - Support Frame/Message Communication
Generalizes the functionality of al-conduit-client into a more generic form, `AlFrameMessageStream.` This class will dynamically create an iframe and dispatch different messages to different handlers.
1 parent e99c135 commit 604cc29

File tree

3 files changed

+89
-1
lines changed

3 files changed

+89
-1
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@al/core",
3-
"version": "1.0.187",
3+
"version": "1.0.188",
44
"description": "Node Enterprise Packages for Alert Logic (NEPAL) Core Library",
55
"main": "./dist/index.cjs.js",
66
"types": "./dist/index.d.ts",
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/**
2+
* This is a utility class for interacting with a framed document using `postMessage`.
3+
*/
4+
5+
import { AlBehaviorPromise } from "../promises";
6+
import { AlStopwatch } from './al-stopwatch';
7+
8+
export class AlFrameMessageStream
9+
{
10+
protected isReady = new AlBehaviorPromise( false );
11+
protected container:HTMLElement;
12+
protected handlers:{[messageType:string]:{(data:any,rawEvent?:any,stream?:AlFrameMessageStream):void}} = {};
13+
14+
/**
15+
* Constructor
16+
*
17+
* @param frameURI: where the iframe should be pointed to
18+
* @param waitForMessage: if truthy, the `start()` method will not resolve until the first message is received from the frame.
19+
* @param messagePrefix: if provided, only messages whose bodies include a `type` property starting with this value will be handled.
20+
*/
21+
constructor( public frameURI:string,
22+
public waitForMessage?:boolean,
23+
public messagePrefix?:string ) {
24+
}
25+
26+
public async start() {
27+
if ( document && document.body && typeof( document.body.appendChild ) === 'function' ) {
28+
document.body.appendChild( this.render() );
29+
} else {
30+
throw new Error(`Cannot start frame message stream to [${this.frameURI}] without access to DOM` );
31+
}
32+
window.addEventListener( "message", this.onReceiveMessage, false );
33+
if ( this.waitForMessage ) {
34+
await this.ready();
35+
}
36+
}
37+
38+
public async ready() {
39+
await this.isReady;
40+
}
41+
42+
public stop() {
43+
document.body.removeChild( this.container );
44+
window.removeEventListener( "message", this.onReceiveMessage);
45+
}
46+
47+
public on( messageType:string, handler:{(data:any,rawEvent?:any,stream?:AlFrameMessageStream):void} ):AlFrameMessageStream {
48+
if ( this.messagePrefix ) {
49+
messageType = `${this.messagePrefix}.${messageType}`;
50+
}
51+
this.handlers[messageType] = handler;
52+
return this;
53+
}
54+
55+
private onReceiveMessage = ( event:any ):void => {
56+
if ( ! this.frameURI.startsWith( event.origin ) ) {
57+
return;
58+
}
59+
60+
if ( ! event.data || typeof( event.data.type ) !== 'string' ) {
61+
return;
62+
}
63+
64+
if ( this.messagePrefix && ! event.data.type.startsWith( this.messagePrefix ) ) {
65+
return;
66+
}
67+
68+
this.isReady.resolve( true );
69+
70+
if ( event.data.type in this.handlers ) {
71+
this.handlers[event.data.type]( event.data, event, this );
72+
} else {
73+
console.log(`Notice: received unhandled message of type '${event.data.type}' from ${event.origin}` );
74+
}
75+
}
76+
77+
private render():DocumentFragment {
78+
const fragment = document.createDocumentFragment();
79+
this.container = document.createElement( "div" );
80+
this.container.setAttribute("class", "message-frame" );
81+
fragment.appendChild( this.container );
82+
this.container.innerHTML = `<iframe frameborder="0" src="${this.frameURI}" style="width:1px;height:1px;position:absolute;left:-1px;top:-1px;"></iframe>`;
83+
return fragment;
84+
}
85+
86+
87+
}

src/common/utility/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ export * from "./json-utilities";
88
export * from './al-merge-helper';
99
export * from './timezone-utilities';
1010
export * from './al-mutex';
11+
export * from './al-frame-message-stream';

0 commit comments

Comments
 (0)