iframe.io 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +40 -0
- package/dist/index.js +21 -21
- package/package.json +4 -10
- package/src/index.ts +229 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare type PeerType = 'WINDOW' | 'IFRAME';
|
|
2
|
+
export declare type CallbackFunction = (error: boolean | string, ...args: any[]) => void;
|
|
3
|
+
export declare type Listener = (payload?: any, callback?: CallbackFunction) => void;
|
|
4
|
+
export declare type Options = {
|
|
5
|
+
type?: PeerType;
|
|
6
|
+
debug?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export interface RegisteredEvents {
|
|
9
|
+
[index: string]: Listener[];
|
|
10
|
+
}
|
|
11
|
+
export declare type Peer = {
|
|
12
|
+
type: PeerType;
|
|
13
|
+
source?: Window;
|
|
14
|
+
origin?: string;
|
|
15
|
+
};
|
|
16
|
+
export declare type MessageData = {
|
|
17
|
+
_event: string;
|
|
18
|
+
payload: any;
|
|
19
|
+
callback: boolean;
|
|
20
|
+
};
|
|
21
|
+
export declare type Message = {
|
|
22
|
+
origin: string;
|
|
23
|
+
data: MessageData;
|
|
24
|
+
source: Window;
|
|
25
|
+
};
|
|
26
|
+
export default class IOF {
|
|
27
|
+
Events: RegisteredEvents;
|
|
28
|
+
peer: Peer;
|
|
29
|
+
options: Options;
|
|
30
|
+
constructor(options: Options);
|
|
31
|
+
debug(...args: any[]): void;
|
|
32
|
+
initiate(contentWindow: MessageEventSource, iframeOrigin: string): this;
|
|
33
|
+
listen(hostOrigin?: string): this;
|
|
34
|
+
fire(_event: string, payload?: MessageData['payload'], callback?: boolean): void;
|
|
35
|
+
emit(_event: string, payload?: MessageData['payload'], fn?: Listener): this;
|
|
36
|
+
on(_event: string, fn: Listener): this;
|
|
37
|
+
once(_event: string, fn: Listener): this;
|
|
38
|
+
off(_event: string, fn: Listener): this;
|
|
39
|
+
removeListeners(fn: Listener): this;
|
|
40
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -23,8 +23,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
23
23
|
function newObject(data) {
|
|
24
24
|
return JSON.parse(JSON.stringify(data));
|
|
25
25
|
}
|
|
26
|
-
var
|
|
27
|
-
function
|
|
26
|
+
var IOF = /** @class */ (function () {
|
|
27
|
+
function IOF(options) {
|
|
28
28
|
if (options && typeof options !== 'object')
|
|
29
29
|
throw new Error('Invalid Options');
|
|
30
30
|
this.options = options;
|
|
@@ -33,14 +33,14 @@ var IFrameIO = /** @class */ (function () {
|
|
|
33
33
|
if (options.type)
|
|
34
34
|
this.peer.type = options.type.toUpperCase();
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
IOF.prototype.debug = function () {
|
|
37
37
|
var args = [];
|
|
38
38
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
39
39
|
args[_i] = arguments[_i];
|
|
40
40
|
}
|
|
41
41
|
this.options && this.options.debug && console.log.apply(console, args);
|
|
42
42
|
};
|
|
43
|
-
|
|
43
|
+
IOF.prototype.initiate = function (contentWindow, iframeOrigin) {
|
|
44
44
|
var _this = this;
|
|
45
45
|
// Establish a connection with an iframe containing in the current window
|
|
46
46
|
if (!contentWindow || !iframeOrigin)
|
|
@@ -62,17 +62,17 @@ var IFrameIO = /** @class */ (function () {
|
|
|
62
62
|
// Handshake or availability check events
|
|
63
63
|
if (_event == 'pong') {
|
|
64
64
|
// Content Window is connected to iframe
|
|
65
|
-
_this.
|
|
65
|
+
_this.fire('connect');
|
|
66
66
|
return _this.debug("[".concat(_this.peer.type, "] connected"));
|
|
67
67
|
}
|
|
68
|
-
//
|
|
69
|
-
_this.
|
|
68
|
+
// Fire available event listeners
|
|
69
|
+
_this.fire(_event, payload, callback);
|
|
70
70
|
}, false);
|
|
71
71
|
this.debug("[".concat(this.peer.type, "] Initiate connection: IFrame origin <").concat(iframeOrigin, ">"));
|
|
72
72
|
this.emit('ping');
|
|
73
73
|
return this;
|
|
74
74
|
};
|
|
75
|
-
|
|
75
|
+
IOF.prototype.listen = function (hostOrigin) {
|
|
76
76
|
// Listening to connection from the content window
|
|
77
77
|
var _this = this;
|
|
78
78
|
this.peer.type = 'IFRAME'; // iframe.io connection listener is automatically set as IFRAME
|
|
@@ -101,15 +101,15 @@ var IFrameIO = /** @class */ (function () {
|
|
|
101
101
|
if (_event == 'ping') {
|
|
102
102
|
_this.emit('pong');
|
|
103
103
|
// Iframe is connected to content window
|
|
104
|
-
_this.
|
|
104
|
+
_this.fire('connect');
|
|
105
105
|
return _this.debug("[".concat(_this.peer.type, "] connected"));
|
|
106
106
|
}
|
|
107
|
-
//
|
|
108
|
-
_this.
|
|
107
|
+
// Fire available event listeners
|
|
108
|
+
_this.fire(_event, payload, callback);
|
|
109
109
|
}, false);
|
|
110
110
|
return this;
|
|
111
111
|
};
|
|
112
|
-
|
|
112
|
+
IOF.prototype.fire = function (_event, payload, callback) {
|
|
113
113
|
var _this = this;
|
|
114
114
|
// Volatile event
|
|
115
115
|
if (!this.Events[_event]
|
|
@@ -129,15 +129,15 @@ var IFrameIO = /** @class */ (function () {
|
|
|
129
129
|
// Once triggable event
|
|
130
130
|
_event += '--@once';
|
|
131
131
|
listeners = this.Events[_event];
|
|
132
|
-
// Delete once event listeners after
|
|
132
|
+
// Delete once event listeners after fired
|
|
133
133
|
delete this.Events[_event];
|
|
134
134
|
}
|
|
135
135
|
else
|
|
136
136
|
listeners = this.Events[_event];
|
|
137
|
-
//
|
|
137
|
+
// Fire listeners
|
|
138
138
|
listeners.map(function (fn) { return payload ? fn(payload, callbackFn) : fn(callbackFn); });
|
|
139
139
|
};
|
|
140
|
-
|
|
140
|
+
IOF.prototype.emit = function (_event, payload, fn) {
|
|
141
141
|
if (!this.peer.source)
|
|
142
142
|
throw new Error('No Connection initiated');
|
|
143
143
|
if (typeof payload == 'function') {
|
|
@@ -157,7 +157,7 @@ var IFrameIO = /** @class */ (function () {
|
|
|
157
157
|
this.peer.source.postMessage(newObject({ _event: _event, payload: payload, callback: hasCallback }), this.peer.origin);
|
|
158
158
|
return this;
|
|
159
159
|
};
|
|
160
|
-
|
|
160
|
+
IOF.prototype.on = function (_event, fn) {
|
|
161
161
|
// Add Event listener
|
|
162
162
|
if (!this.Events[_event])
|
|
163
163
|
this.Events[_event] = [];
|
|
@@ -165,7 +165,7 @@ var IFrameIO = /** @class */ (function () {
|
|
|
165
165
|
this.debug("[".concat(this.peer.type, "] New <").concat(_event, "> listener on"));
|
|
166
166
|
return this;
|
|
167
167
|
};
|
|
168
|
-
|
|
168
|
+
IOF.prototype.once = function (_event, fn) {
|
|
169
169
|
// Add Once Event listener
|
|
170
170
|
_event += '--@once';
|
|
171
171
|
if (!this.Events[_event])
|
|
@@ -174,20 +174,20 @@ var IFrameIO = /** @class */ (function () {
|
|
|
174
174
|
this.debug("[".concat(this.peer.type, "] New <").concat(_event, " once> listener on"));
|
|
175
175
|
return this;
|
|
176
176
|
};
|
|
177
|
-
|
|
177
|
+
IOF.prototype.off = function (_event, fn) {
|
|
178
178
|
// Remove Event listener
|
|
179
179
|
delete this.Events[_event];
|
|
180
180
|
typeof fn == 'function' && fn();
|
|
181
181
|
this.debug("[".concat(this.peer.type, "] <").concat(_event, "> listener off"));
|
|
182
182
|
return this;
|
|
183
183
|
};
|
|
184
|
-
|
|
184
|
+
IOF.prototype.removeListeners = function (fn) {
|
|
185
185
|
// Clear all event listeners
|
|
186
186
|
this.Events = {};
|
|
187
187
|
typeof fn == 'function' && fn();
|
|
188
188
|
this.debug("[".concat(this.peer.type, "] All listeners removed"));
|
|
189
189
|
return this;
|
|
190
190
|
};
|
|
191
|
-
return
|
|
191
|
+
return IOF;
|
|
192
192
|
}());
|
|
193
|
-
exports.default =
|
|
193
|
+
exports.default = IOF;
|
package/package.json
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "iframe.io",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.10",
|
|
4
4
|
"description": "Easy and friendly API to connect and interact between content window and its containing iframe",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
|
-
"types": "./
|
|
7
|
-
"exports": {
|
|
8
|
-
".": {
|
|
9
|
-
"import": "./dist/index.js",
|
|
10
|
-
"require": "./dist/index.js",
|
|
11
|
-
"types": "./src/index.d.ts"
|
|
12
|
-
}
|
|
13
|
-
},
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
14
7
|
"private": false,
|
|
15
8
|
"scripts": {
|
|
16
9
|
"compile": "rimraf ./dist && tsc",
|
|
@@ -27,7 +20,8 @@
|
|
|
27
20
|
"typescript": "^4.5.5"
|
|
28
21
|
},
|
|
29
22
|
"files": [
|
|
30
|
-
"dist/"
|
|
23
|
+
"dist/",
|
|
24
|
+
"src/"
|
|
31
25
|
],
|
|
32
26
|
"directories": {
|
|
33
27
|
"example": "example/",
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
|
|
2
|
+
export type PeerType = 'WINDOW' | 'IFRAME'
|
|
3
|
+
|
|
4
|
+
export type CallbackFunction = ( error: boolean | string, ...args: any[] ) => void
|
|
5
|
+
export type Listener = ( payload?: any, callback?: CallbackFunction ) => void
|
|
6
|
+
|
|
7
|
+
export type Options = {
|
|
8
|
+
type?: PeerType
|
|
9
|
+
debug?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface RegisteredEvents {
|
|
13
|
+
[index: string]: Listener[]
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export type Peer = {
|
|
17
|
+
type: PeerType
|
|
18
|
+
source?: Window
|
|
19
|
+
origin?: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type MessageData = {
|
|
23
|
+
_event: string
|
|
24
|
+
payload: any
|
|
25
|
+
callback: boolean
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type Message = {
|
|
29
|
+
origin: string
|
|
30
|
+
data: MessageData,
|
|
31
|
+
source: Window
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function newObject( data: object ){
|
|
35
|
+
return JSON.parse( JSON.stringify( data ) )
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default class IOF {
|
|
39
|
+
|
|
40
|
+
Events: RegisteredEvents
|
|
41
|
+
peer: Peer
|
|
42
|
+
options: Options
|
|
43
|
+
|
|
44
|
+
constructor( options: Options ){
|
|
45
|
+
|
|
46
|
+
if( options && typeof options !== 'object' )
|
|
47
|
+
throw new Error('Invalid Options')
|
|
48
|
+
|
|
49
|
+
this.options = options
|
|
50
|
+
this.Events = {}
|
|
51
|
+
this.peer = { type: 'IFRAME' }
|
|
52
|
+
|
|
53
|
+
if( options.type )
|
|
54
|
+
this.peer.type = options.type.toUpperCase() as PeerType
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
debug( ...args: any[] ){ this.options && this.options.debug && console.log( ...args ) }
|
|
58
|
+
|
|
59
|
+
initiate( contentWindow: MessageEventSource, iframeOrigin: string ){
|
|
60
|
+
// Establish a connection with an iframe containing in the current window
|
|
61
|
+
if( !contentWindow || !iframeOrigin )
|
|
62
|
+
throw new Error('Invalid Connection initiation arguments')
|
|
63
|
+
|
|
64
|
+
if( this.peer.type === 'IFRAME' )
|
|
65
|
+
throw new Error('Expect IFRAME to <listen> and WINDOW to <initiate> a connection')
|
|
66
|
+
|
|
67
|
+
this.peer.source = contentWindow as Window
|
|
68
|
+
this.peer.origin = iframeOrigin
|
|
69
|
+
|
|
70
|
+
window.addEventListener( 'message', ({ origin, data, source }) => {
|
|
71
|
+
// Check valid message
|
|
72
|
+
if( origin !== this.peer.origin
|
|
73
|
+
|| !source
|
|
74
|
+
|| typeof data !== 'object'
|
|
75
|
+
|| !data.hasOwnProperty('_event') ) return
|
|
76
|
+
|
|
77
|
+
const { _event, payload, callback } = data as Message['data']
|
|
78
|
+
this.debug( `[${this.peer.type}] Message: ${_event}`, payload || '' )
|
|
79
|
+
|
|
80
|
+
// Handshake or availability check events
|
|
81
|
+
if( _event == 'pong' ){
|
|
82
|
+
// Content Window is connected to iframe
|
|
83
|
+
this.fire('connect')
|
|
84
|
+
return this.debug(`[${this.peer.type}] connected`)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Fire available event listeners
|
|
88
|
+
this.fire( _event, payload, callback )
|
|
89
|
+
}, false )
|
|
90
|
+
|
|
91
|
+
this.debug(`[${this.peer.type}] Initiate connection: IFrame origin <${iframeOrigin}>`)
|
|
92
|
+
this.emit('ping')
|
|
93
|
+
|
|
94
|
+
return this
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
listen( hostOrigin?: string ){
|
|
98
|
+
// Listening to connection from the content window
|
|
99
|
+
|
|
100
|
+
this.peer.type = 'IFRAME' // iframe.io connection listener is automatically set as IFRAME
|
|
101
|
+
this.debug(`[${this.peer.type}] Listening to connect${hostOrigin ? `: Host <${hostOrigin}>` : ''}`)
|
|
102
|
+
|
|
103
|
+
window.addEventListener( 'message', ({ origin, data, source }) => {
|
|
104
|
+
// Check host origin where event must only come from.
|
|
105
|
+
if( hostOrigin && hostOrigin !== origin )
|
|
106
|
+
throw new Error('Invalid Event Origin')
|
|
107
|
+
|
|
108
|
+
// Check valid message
|
|
109
|
+
if( !source
|
|
110
|
+
|| typeof data !== 'object'
|
|
111
|
+
|| !data.hasOwnProperty('_event') ) return
|
|
112
|
+
|
|
113
|
+
// Define peer source window and origin
|
|
114
|
+
if( !this.peer.source ){
|
|
115
|
+
this.peer = { ...this.peer, source: source as Window, origin }
|
|
116
|
+
this.debug(`[${this.peer.type}] Connect to ${origin}`)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Origin different from handshaked source origin
|
|
120
|
+
else if( origin !== this.peer.origin )
|
|
121
|
+
throw new Error('Invalid Origin')
|
|
122
|
+
|
|
123
|
+
const { _event, payload, callback } = data
|
|
124
|
+
this.debug( `[${this.peer.type}] Message: ${_event}`, payload || '' )
|
|
125
|
+
|
|
126
|
+
// Handshake or availability check events
|
|
127
|
+
if( _event == 'ping' ){
|
|
128
|
+
this.emit('pong')
|
|
129
|
+
|
|
130
|
+
// Iframe is connected to content window
|
|
131
|
+
this.fire('connect')
|
|
132
|
+
return this.debug(`[${this.peer.type}] connected`)
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Fire available event listeners
|
|
136
|
+
this.fire( _event, payload, callback )
|
|
137
|
+
}, false )
|
|
138
|
+
|
|
139
|
+
return this
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
fire( _event: string, payload?: MessageData['payload'], callback?: boolean ){
|
|
143
|
+
// Volatile event
|
|
144
|
+
if( !this.Events[ _event ]
|
|
145
|
+
&& !this.Events[ _event +'--@once'] )
|
|
146
|
+
return this.debug(`[${this.peer.type}] No <${_event}> listener defined`)
|
|
147
|
+
|
|
148
|
+
const callbackFn = callback ?
|
|
149
|
+
( error: boolean | string, ...args: any[] ): void => {
|
|
150
|
+
this.emit( _event +'--@callback', { error: error || false, args } )
|
|
151
|
+
return
|
|
152
|
+
} : undefined
|
|
153
|
+
let listeners: Listener[] = []
|
|
154
|
+
|
|
155
|
+
if( this.Events[ _event +'--@once'] ){
|
|
156
|
+
// Once triggable event
|
|
157
|
+
_event += '--@once'
|
|
158
|
+
listeners = this.Events[ _event ]
|
|
159
|
+
// Delete once event listeners after fired
|
|
160
|
+
delete this.Events[ _event ]
|
|
161
|
+
}
|
|
162
|
+
else listeners = this.Events[ _event ]
|
|
163
|
+
|
|
164
|
+
// Fire listeners
|
|
165
|
+
listeners.map( fn => payload ? fn( payload, callbackFn ) : fn( callbackFn ) )
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
emit( _event: string, payload?: MessageData['payload'], fn?: Listener ){
|
|
169
|
+
|
|
170
|
+
if( !this.peer.source )
|
|
171
|
+
throw new Error('No Connection initiated')
|
|
172
|
+
|
|
173
|
+
if( typeof payload == 'function' ){
|
|
174
|
+
fn = payload
|
|
175
|
+
payload = null
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Acknowledge/callback event listener
|
|
179
|
+
let hasCallback = false
|
|
180
|
+
if( typeof fn === 'function' ){
|
|
181
|
+
const callbackFunction = fn as CallbackFunction
|
|
182
|
+
|
|
183
|
+
this.once( _event +'--@callback', ({ error, args }) => callbackFunction( error, ...args ) )
|
|
184
|
+
hasCallback = true
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
this.peer.source.postMessage( newObject({ _event, payload, callback: hasCallback }), this.peer.origin as string )
|
|
188
|
+
|
|
189
|
+
return this
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
on( _event: string, fn: Listener ){
|
|
193
|
+
// Add Event listener
|
|
194
|
+
if( !this.Events[ _event ] ) this.Events[ _event ] = []
|
|
195
|
+
this.Events[ _event ].push( fn )
|
|
196
|
+
|
|
197
|
+
this.debug(`[${this.peer.type}] New <${_event}> listener on`)
|
|
198
|
+
return this
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
once( _event: string, fn: Listener ){
|
|
202
|
+
// Add Once Event listener
|
|
203
|
+
_event += '--@once'
|
|
204
|
+
|
|
205
|
+
if( !this.Events[ _event ] ) this.Events[ _event ] = []
|
|
206
|
+
this.Events[ _event ].push( fn )
|
|
207
|
+
|
|
208
|
+
this.debug(`[${this.peer.type}] New <${_event} once> listener on`)
|
|
209
|
+
return this
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
off( _event: string, fn: Listener ){
|
|
213
|
+
// Remove Event listener
|
|
214
|
+
delete this.Events[ _event ]
|
|
215
|
+
typeof fn == 'function' && fn()
|
|
216
|
+
|
|
217
|
+
this.debug(`[${this.peer.type}] <${_event}> listener off`)
|
|
218
|
+
return this
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
removeListeners( fn: Listener ){
|
|
222
|
+
// Clear all event listeners
|
|
223
|
+
this.Events = {}
|
|
224
|
+
typeof fn == 'function' && fn()
|
|
225
|
+
|
|
226
|
+
this.debug(`[${this.peer.type}] All listeners removed`)
|
|
227
|
+
return this
|
|
228
|
+
}
|
|
229
|
+
}
|