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.
@@ -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 IFrameIO = /** @class */ (function () {
27
- function IFrameIO(options) {
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
- IFrameIO.prototype.debug = function () {
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
- IFrameIO.prototype.initiate = function (contentWindow, iframeOrigin) {
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.trigger('connect');
65
+ _this.fire('connect');
66
66
  return _this.debug("[".concat(_this.peer.type, "] connected"));
67
67
  }
68
- // Trigger available event listeners
69
- _this.trigger(_event, payload, callback);
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
- IFrameIO.prototype.listen = function (hostOrigin) {
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.trigger('connect');
104
+ _this.fire('connect');
105
105
  return _this.debug("[".concat(_this.peer.type, "] connected"));
106
106
  }
107
- // Trigger available event listeners
108
- _this.trigger(_event, payload, callback);
107
+ // Fire available event listeners
108
+ _this.fire(_event, payload, callback);
109
109
  }, false);
110
110
  return this;
111
111
  };
112
- IFrameIO.prototype.trigger = function (_event, payload, callback) {
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 triggered
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
- // Trigger listeners
137
+ // Fire listeners
138
138
  listeners.map(function (fn) { return payload ? fn(payload, callbackFn) : fn(callbackFn); });
139
139
  };
140
- IFrameIO.prototype.emit = function (_event, payload, fn) {
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
- IFrameIO.prototype.on = function (_event, fn) {
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
- IFrameIO.prototype.once = function (_event, fn) {
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
- IFrameIO.prototype.off = function (_event, fn) {
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
- IFrameIO.prototype.removeListeners = function (fn) {
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 IFrameIO;
191
+ return IOF;
192
192
  }());
193
- exports.default = IFrameIO;
193
+ exports.default = IOF;
package/package.json CHANGED
@@ -1,16 +1,9 @@
1
1
  {
2
2
  "name": "iframe.io",
3
- "version": "0.0.8",
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": "./src/index.d.ts",
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
+ }