iframe.io 0.0.8 → 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 CHANGED
@@ -62,11 +62,11 @@ 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');
@@ -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
+ IFrameIO.prototype.fire = function (_event, payload, callback) {
113
113
  var _this = this;
114
114
  // Volatile event
115
115
  if (!this.Events[_event]
@@ -129,12 +129,12 @@ 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
140
  IFrameIO.prototype.emit = function (_event, payload, fn) {
package/package.json CHANGED
@@ -1,16 +1,9 @@
1
1
  {
2
2
  "name": "iframe.io",
3
- "version": "0.0.8",
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/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": "./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
+ }