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