penpal 6.1.0 → 6.2.2
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/README.md +104 -25
- package/dist/penpal.js +28 -20
- package/dist/penpal.min.js +1 -1
- package/dist/penpal.min.js.map +1 -1
- package/es5/child/handleSynAckMessageFactory.js +1 -1
- package/es5/connectCallReceiver.js +5 -5
- package/es5/connectCallSender.js +6 -6
- package/es5/createDestructor.js +1 -1
- package/es5/parent/getOriginFromSrc.js +2 -2
- package/es5/parent/handleAckMessageFactory.js +2 -2
- package/es5/parent/handleSynMessageFactory.js +10 -2
- package/es5/startConnectionTimeout.js +1 -1
- package/lib/connectCallReceiver.js +1 -1
- package/lib/connectCallSender.js +2 -1
- package/lib/parent/handleAckMessageFactory.js +1 -1
- package/lib/parent/handleSynMessageFactory.js +8 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,6 +47,9 @@ import { connectToChild } from 'penpal';
|
|
|
47
47
|
|
|
48
48
|
const iframe = document.createElement('iframe');
|
|
49
49
|
iframe.src = 'http://example.com/iframe.html';
|
|
50
|
+
|
|
51
|
+
// This conditional is not Penpal-specific. It's merely
|
|
52
|
+
// an example of how you can add an iframe to the document.
|
|
50
53
|
if (
|
|
51
54
|
document.readyState === 'complete' ||
|
|
52
55
|
document.readyState === 'interactive'
|
|
@@ -58,10 +61,11 @@ if (
|
|
|
58
61
|
});
|
|
59
62
|
}
|
|
60
63
|
|
|
64
|
+
// This is where the magic begins.
|
|
61
65
|
const connection = connectToChild({
|
|
62
|
-
// The iframe to which a connection should be made
|
|
66
|
+
// The iframe to which a connection should be made.
|
|
63
67
|
iframe,
|
|
64
|
-
// Methods the parent is exposing to the child
|
|
68
|
+
// Methods the parent is exposing to the child.
|
|
65
69
|
methods: {
|
|
66
70
|
add(num1, num2) {
|
|
67
71
|
return num1 + num2;
|
|
@@ -81,13 +85,14 @@ connection.promise.then((child) => {
|
|
|
81
85
|
import { connectToParent } from 'penpal';
|
|
82
86
|
|
|
83
87
|
const connection = connectToParent({
|
|
84
|
-
// Methods child is exposing to parent
|
|
88
|
+
// Methods child is exposing to parent.
|
|
85
89
|
methods: {
|
|
86
90
|
multiply(num1, num2) {
|
|
87
91
|
return num1 * num2;
|
|
88
92
|
},
|
|
89
93
|
divide(num1, num2) {
|
|
90
|
-
// Return a promise if the value being
|
|
94
|
+
// Return a promise if the value being
|
|
95
|
+
// returned requires asynchronous processing.
|
|
91
96
|
return new Promise((resolve) => {
|
|
92
97
|
setTimeout(() => {
|
|
93
98
|
resolve(num1 / num2);
|
|
@@ -106,47 +111,79 @@ connection.promise.then((parent) => {
|
|
|
106
111
|
|
|
107
112
|
### `connectToChild(options: Object) => Object`
|
|
108
113
|
|
|
109
|
-
**For Penpal to operate correctly, you must ensure that `connectToChild` is called before the iframe
|
|
114
|
+
**For Penpal to operate correctly, you must ensure that `connectToChild` is called before the iframe calls `connectToParent`.** As shown in the example above, it is safe to set the `src` or `srcdoc` property of the iframe and append the iframe to the document before calling `connectToChild` as long as they are both done in the same [JavaScript event loop](https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop). Alternatively, you can always append the iframe to the document _after_ calling `connectToChild` instead of _before_.
|
|
110
115
|
|
|
111
116
|
#### Options
|
|
112
117
|
|
|
113
|
-
`options.iframe: HTMLIFrameElement` (required)
|
|
118
|
+
`options.iframe: HTMLIFrameElement` (required)
|
|
119
|
+
|
|
120
|
+
The iframe element to which Penpal should connect. Unless you provide the `childOrigin` option, you will need to have set either the `src` or `srcdoc` property on the iframe prior to calling `connectToChild` so that Penpal can automatically derive the child origin. In addition to regular URLs, [data URIs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) and [file URIs](https://en.wikipedia.org/wiki/File_URI_scheme) are also supported.
|
|
121
|
+
|
|
122
|
+
`options.methods: Object` (optional)
|
|
123
|
+
|
|
124
|
+
An object containing methods which should be exposed for the child iframe to call. The keys of the object are the method names and the values are the functions. Nested objects with function values are recursively included. If a function requires asynchronous processing to determine its return value, make the function immediately return a promise and resolve the promise once the value has been determined.
|
|
125
|
+
|
|
126
|
+
`options.childOrigin: string` (optional)
|
|
127
|
+
|
|
128
|
+
In the vast majority of cases, Penpal can automatically determine the child origin based on the `src` or `srcdoc` property that you have set on the iframe. Communication will automatically be restricted to that origin.
|
|
129
|
+
|
|
130
|
+
In some rare cases, particularly when using the `file://` protocol on various devices, browsers are inconsistent in how they report and handle origins. If you receive an error saying that the parent received a handshake from an unexpected origin, you may need to manually pass the child origin using this option.
|
|
131
|
+
|
|
132
|
+
In other [niche scenarios](https://github.com/Aaronius/penpal/issues/73), you may want the parent to be able to communicate with any child origin. In this case, you can set `childOrigin` to `*`. **This is discouraged.** To illustrate the risk, if a nefarious attacker manages to create a link within the child page that another user can click (for example, if you fail to inadequately escape HTML in a message board comment), and that link navigates the unsuspecting user's iframe to a nefarious URL, then the page at the nefarious URL could start communicating with your parent window.
|
|
133
|
+
|
|
134
|
+
Regardless of how you configure `childOrigin`, communication will always be restricted to only the iframe to which you are connecting.
|
|
114
135
|
|
|
115
|
-
`options.
|
|
136
|
+
`options.timeout: number` (optional)
|
|
116
137
|
|
|
117
|
-
|
|
138
|
+
The amount of time, in milliseconds, Penpal should wait for the child to respond before rejecting the connection promise. There is no timeout by default.
|
|
118
139
|
|
|
119
|
-
`options.
|
|
140
|
+
`options.debug: boolean` (optional)
|
|
120
141
|
|
|
121
|
-
|
|
142
|
+
Enables or disables debug logging. Debug logging is disabled by default.
|
|
122
143
|
|
|
123
144
|
#### Return value
|
|
124
145
|
|
|
125
146
|
The return value of `connectToChild` is a `connection` object with the following properties:
|
|
126
147
|
|
|
127
|
-
`connection.promise: Promise`
|
|
148
|
+
`connection.promise: Promise`
|
|
128
149
|
|
|
129
|
-
|
|
150
|
+
A promise which will be resolved once communication has been established. The promise will be resolved with an object containing the methods which the child has exposed. Note that these aren't actual memory references to the methods the child exposed, but instead proxy methods Penpal has created with the same names and signatures. When one of these methods is called, Penpal will immediately return a promise and then go to work sending a message to the child, calling the actual method within the child with the arguments you have passed, and then sending the return value back to the parent. The promise you received will then be resolved with the return value.
|
|
151
|
+
|
|
152
|
+
`connection.destroy: Function`
|
|
153
|
+
|
|
154
|
+
A method that, when called, will disconnect any messaging channels. You may call this even before a connection has been established.
|
|
130
155
|
|
|
131
156
|
### `connectToParent([options: Object]) => Object`
|
|
132
157
|
|
|
133
158
|
#### Options
|
|
134
159
|
|
|
135
|
-
`options.parentOrigin: string | RegExp` (optional
|
|
160
|
+
`options.parentOrigin: string | RegExp` (optional **but highly recommended!**)
|
|
161
|
+
|
|
162
|
+
The origin of the parent window which your iframe will be communicating with. If this is not provided, communication will not be restricted to any particular parent origin resulting in any webpage being able to load your webpage into an iframe and communicate with it.
|
|
163
|
+
|
|
164
|
+
`options.methods: Object` (optional)
|
|
165
|
+
|
|
166
|
+
An object containing methods which should be exposed for the parent window to call. The keys of the object are the method names and the values are the functions. Nested objects with function values are recursively included. If a function requires asynchronous processing to determine its return value, make the function immediately return a promise and resolve the promise once the value has been determined.
|
|
136
167
|
|
|
137
|
-
`options.
|
|
168
|
+
`options.timeout: number` (optional)
|
|
138
169
|
|
|
139
|
-
|
|
170
|
+
The amount of time, in milliseconds, Penpal should wait for the parent to respond before rejecting the connection promise. There is no timeout by default.
|
|
140
171
|
|
|
141
|
-
`options.debug: boolean` (optional)
|
|
172
|
+
`options.debug: boolean` (optional)
|
|
173
|
+
|
|
174
|
+
Enables or disables debug logging. Debug logging is disabled by default.
|
|
142
175
|
|
|
143
176
|
#### Return value
|
|
144
177
|
|
|
145
|
-
The return value of `connectToParent` is a `connection` object with the following
|
|
178
|
+
The return value of `connectToParent` is a `connection` object with the following properties:
|
|
179
|
+
|
|
180
|
+
`connection.promise: Promise`
|
|
146
181
|
|
|
147
|
-
|
|
182
|
+
A promise which will be resolved once communication has been established. The promise will be resolved with an object containing the methods which the parent has exposed. Note that these aren't actual memory references to the methods the parent exposed, but instead proxy methods Penpal has created with the same names and signatures. When one of these methods is called, Penpal will immediately return a promise and then go to work sending a message to the parent, calling the actual method within the parent with the arguments you have passed, and then sending the return value back to the child. The promise you received will then be resolved with the return value.
|
|
148
183
|
|
|
149
|
-
`connection.destroy: Function`
|
|
184
|
+
`connection.destroy: Function`
|
|
185
|
+
|
|
186
|
+
A method that, when called, will disconnect any messaging channels. You may call this even before a connection has been established.
|
|
150
187
|
|
|
151
188
|
## Reconnection
|
|
152
189
|
|
|
@@ -158,12 +195,17 @@ NOTE: Currently there is no API to notify consumers of a reconnection. If this i
|
|
|
158
195
|
|
|
159
196
|
Penpal will throw (or reject promises with) errors in certain situations. Each error will have a `code` property which may be used for programmatic decisioning (e.g., do something if the error was due to a connection timing out) along with a `message` describing the problem. Errors may be thrown with the following codes:
|
|
160
197
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
198
|
+
`ConnectionDestroyed`
|
|
199
|
+
|
|
200
|
+
This error will be thrown when attempting to call a method on `child` or `parent` objects and the connection was previously destroyed.
|
|
201
|
+
|
|
202
|
+
`ConnectionTimeout`
|
|
203
|
+
|
|
204
|
+
The promise found at `connection.promise` will be rejected with this error after the `timeout` duration has elapsed and a connection has not been established.
|
|
205
|
+
|
|
206
|
+
`NoIframeSrc`
|
|
207
|
+
|
|
208
|
+
This error will be thrown when the iframe passed into `connectToChild` does not have `src` or `srcdoc` set.
|
|
167
209
|
|
|
168
210
|
For your convenience, these error codes can be imported as follows:
|
|
169
211
|
|
|
@@ -174,6 +216,43 @@ import { ErrorCode } from 'penpal';
|
|
|
174
216
|
// ErrorCode.NoIframeSrc
|
|
175
217
|
```
|
|
176
218
|
|
|
219
|
+
## TypeScript
|
|
220
|
+
|
|
221
|
+
When calling `connectToChild` or `connectToParent`, you may pass a generic type argument. This will be used to type the `child` or `parent` object that `connection.promise` is resolved with. This is better explained in code:
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
import { connectToChild } from 'penpal';
|
|
225
|
+
|
|
226
|
+
// This interace could be imported from a code library
|
|
227
|
+
// that both the parent and child share.
|
|
228
|
+
interface ChildApi {
|
|
229
|
+
multiply(...args: number[]): number;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Supply the interface as a generic argument.
|
|
233
|
+
const connection = connectToChild<ChildApi>({
|
|
234
|
+
iframe: new HTMLIFrameElement(),
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
// The resulting child object will contain properly
|
|
238
|
+
// typed methods.
|
|
239
|
+
const child = await connection.promise;
|
|
240
|
+
// The result variable is typed as a number.
|
|
241
|
+
const result = await child.multiply(1, 3);
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
The following TypeScript types are also exported as named constants for your use:
|
|
245
|
+
|
|
246
|
+
- `Connection`
|
|
247
|
+
- `Methods`
|
|
248
|
+
- `AsyncMethodReturns`
|
|
249
|
+
- `CallSender`
|
|
250
|
+
- `PenpalError`
|
|
251
|
+
|
|
252
|
+
## React
|
|
253
|
+
|
|
254
|
+
If you're using Penpal within a React app, please check out [react-penpal](https://github.com/Lunuy/react-penpal).
|
|
255
|
+
|
|
177
256
|
## Supported Browsers
|
|
178
257
|
|
|
179
258
|
Penpal is designed to run successfully on the most recent versions of Chrome, Firefox, Safari, and Edge. If you need to support Internet Explorer 11, feel free to use version 3.x of Penpal. See the [3.x README](https://github.com/Aaronius/penpal/tree/3.x) for documentation.
|
package/dist/penpal.js
CHANGED
|
@@ -45,7 +45,7 @@ var Penpal = (function () {
|
|
|
45
45
|
destroy(error) {
|
|
46
46
|
if (!destroyed) {
|
|
47
47
|
destroyed = true;
|
|
48
|
-
log(
|
|
48
|
+
log(`${localName}: Destroying connection`);
|
|
49
49
|
callbacks.forEach(callback => {
|
|
50
50
|
callback(error);
|
|
51
51
|
});
|
|
@@ -112,8 +112,8 @@ var Penpal = (function () {
|
|
|
112
112
|
// or it won't match the message's event.origin.
|
|
113
113
|
|
|
114
114
|
|
|
115
|
-
const portSuffix = port && port !== DEFAULT_PORT_BY_PROTOCOL[protocol] ?
|
|
116
|
-
return
|
|
115
|
+
const portSuffix = port && port !== DEFAULT_PORT_BY_PROTOCOL[protocol] ? `:${port}` : '';
|
|
116
|
+
return `${protocol}//${hostname}${portSuffix}`;
|
|
117
117
|
});
|
|
118
118
|
|
|
119
119
|
/**
|
|
@@ -159,8 +159,8 @@ var Penpal = (function () {
|
|
|
159
159
|
return;
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
if (event.origin !== originForReceiving) {
|
|
163
|
-
log(
|
|
162
|
+
if (originForReceiving !== '*' && event.origin !== originForReceiving) {
|
|
163
|
+
log(`${localName} received message from origin ${event.origin} which did not match expected origin ${originForReceiving}`);
|
|
164
164
|
return;
|
|
165
165
|
}
|
|
166
166
|
|
|
@@ -170,11 +170,11 @@ var Penpal = (function () {
|
|
|
170
170
|
args,
|
|
171
171
|
id
|
|
172
172
|
} = callMessage;
|
|
173
|
-
log(
|
|
173
|
+
log(`${localName}: Received ${methodName}() call`);
|
|
174
174
|
|
|
175
175
|
const createPromiseHandler = resolution => {
|
|
176
176
|
return returnValue => {
|
|
177
|
-
log(
|
|
177
|
+
log(`${localName}: Sending ${methodName}() reply`);
|
|
178
178
|
|
|
179
179
|
if (destroyed) {
|
|
180
180
|
// It's possible to throw an error here, but it would need to be thrown asynchronously
|
|
@@ -182,7 +182,7 @@ var Penpal = (function () {
|
|
|
182
182
|
// is merely returning a value from their method and not calling any function
|
|
183
183
|
// that they could wrap in a try-catch. Even if the consumer were to catch the error,
|
|
184
184
|
// the value of doing so is questionable. Instead, we'll just log a message.
|
|
185
|
-
log(
|
|
185
|
+
log(`${localName}: Unable to send ${methodName}() reply due to destroyed connection`);
|
|
186
186
|
return;
|
|
187
187
|
}
|
|
188
188
|
|
|
@@ -338,11 +338,11 @@ var Penpal = (function () {
|
|
|
338
338
|
originForReceiving
|
|
339
339
|
} = info;
|
|
340
340
|
let destroyed = false;
|
|
341
|
-
log(
|
|
341
|
+
log(`${localName}: Connecting call sender`);
|
|
342
342
|
|
|
343
343
|
const createMethodProxy = methodName => {
|
|
344
344
|
return (...args) => {
|
|
345
|
-
log(
|
|
345
|
+
log(`${localName}: Sending ${methodName}() call`); // This handles the case where the iframe has been removed from the DOM
|
|
346
346
|
// (and therefore its window closed), the consumer has not yet
|
|
347
347
|
// called destroy(), and the user calls a method exposed by
|
|
348
348
|
// the remote. We detect the iframe has been removed and force
|
|
@@ -367,7 +367,7 @@ var Penpal = (function () {
|
|
|
367
367
|
}
|
|
368
368
|
|
|
369
369
|
if (destroyed) {
|
|
370
|
-
const error = new Error(
|
|
370
|
+
const error = new Error(`Unable to send ${methodName}() call due ` + `to destroyed connection`);
|
|
371
371
|
error.code = ErrorCode.ConnectionDestroyed;
|
|
372
372
|
throw error;
|
|
373
373
|
}
|
|
@@ -380,13 +380,13 @@ var Penpal = (function () {
|
|
|
380
380
|
return;
|
|
381
381
|
}
|
|
382
382
|
|
|
383
|
-
if (event.origin !== originForReceiving) {
|
|
384
|
-
log(
|
|
383
|
+
if (originForReceiving !== '*' && event.origin !== originForReceiving) {
|
|
384
|
+
log(`${localName} received message from origin ${event.origin} which did not match expected origin ${originForReceiving}`);
|
|
385
385
|
return;
|
|
386
386
|
}
|
|
387
387
|
|
|
388
388
|
const replyMessage = event.data;
|
|
389
|
-
log(
|
|
389
|
+
log(`${localName}: Received ${methodName}() reply`);
|
|
390
390
|
local.removeEventListener(NativeEventType.Message, handleMessageEvent);
|
|
391
391
|
let returnValue = replyMessage.returnValue;
|
|
392
392
|
|
|
@@ -439,8 +439,8 @@ var Penpal = (function () {
|
|
|
439
439
|
|
|
440
440
|
const callSender = {};
|
|
441
441
|
return event => {
|
|
442
|
-
if (event.origin !== childOrigin) {
|
|
443
|
-
log(
|
|
442
|
+
if (childOrigin !== '*' && event.origin !== childOrigin) {
|
|
443
|
+
log(`Parent: Handshake - Received ACK message from origin ${event.origin} which did not match expected origin ${childOrigin}`);
|
|
444
444
|
return;
|
|
445
445
|
}
|
|
446
446
|
|
|
@@ -481,8 +481,16 @@ var Penpal = (function () {
|
|
|
481
481
|
|
|
482
482
|
var handleSynMessageFactory = ((log, serializedMethods, childOrigin, originForSending) => {
|
|
483
483
|
return event => {
|
|
484
|
-
|
|
485
|
-
|
|
484
|
+
// Under specific timing circumstances, we can receive an event
|
|
485
|
+
// whose source is null. This seems to happen when the child iframe is
|
|
486
|
+
// removed from the DOM about the same time it has sent the SYN event.
|
|
487
|
+
// https://github.com/Aaronius/penpal/issues/85
|
|
488
|
+
if (!event.source) {
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
if (childOrigin !== '*' && event.origin !== childOrigin) {
|
|
493
|
+
log(`Parent: Handshake - Received SYN message from origin ${event.origin} which did not match expected origin ${childOrigin}`);
|
|
486
494
|
return;
|
|
487
495
|
}
|
|
488
496
|
|
|
@@ -532,7 +540,7 @@ var Penpal = (function () {
|
|
|
532
540
|
|
|
533
541
|
if (timeout !== undefined) {
|
|
534
542
|
timeoutId = window.setTimeout(() => {
|
|
535
|
-
const error = new Error(
|
|
543
|
+
const error = new Error(`Connection timed out after ${timeout}ms`);
|
|
536
544
|
error.code = ErrorCode.ConnectionTimeout;
|
|
537
545
|
callback(error);
|
|
538
546
|
}, timeout);
|
|
@@ -642,7 +650,7 @@ var Penpal = (function () {
|
|
|
642
650
|
let originQualifies = parentOrigin instanceof RegExp ? parentOrigin.test(event.origin) : parentOrigin === '*' || parentOrigin === event.origin;
|
|
643
651
|
|
|
644
652
|
if (!originQualifies) {
|
|
645
|
-
log(
|
|
653
|
+
log(`Child: Handshake - Received SYN-ACK from origin ${event.origin} which did not match expected origin ${parentOrigin}`);
|
|
646
654
|
return;
|
|
647
655
|
}
|
|
648
656
|
|
package/dist/penpal.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var Penpal=function(){"use strict";var e;(function(e){e["Call"]="call";e["Reply"]="reply";e["Syn"]="syn";e["SynAck"]="synAck";e["Ack"]="ack"})(e||(e={}));var n;(function(e){e["Fulfilled"]="fulfilled";e["Rejected"]="rejected"})(n||(n={}));var t;(function(e){e["ConnectionDestroyed"]="ConnectionDestroyed";e["ConnectionTimeout"]="ConnectionTimeout";e["NoIframeSrc"]="NoIframeSrc"})(t||(t={}));var o;(function(e){e["DataCloneError"]="DataCloneError"})(o||(o={}));var r;(function(e){e["Message"]="message"})(r||(r={}));var
|
|
1
|
+
var Penpal=function(){"use strict";var e;(function(e){e["Call"]="call";e["Reply"]="reply";e["Syn"]="syn";e["SynAck"]="synAck";e["Ack"]="ack"})(e||(e={}));var n;(function(e){e["Fulfilled"]="fulfilled";e["Rejected"]="rejected"})(n||(n={}));var t;(function(e){e["ConnectionDestroyed"]="ConnectionDestroyed";e["ConnectionTimeout"]="ConnectionTimeout";e["NoIframeSrc"]="NoIframeSrc"})(t||(t={}));var o;(function(e){e["DataCloneError"]="DataCloneError"})(o||(o={}));var r;(function(e){e["Message"]="message"})(r||(r={}));var s=(e,n)=>{const t=[];let o=false;return{destroy(r){if(!o){o=true;n(`${e}: Destroying connection`);t.forEach(e=>{e(r)})}},onDestroy(e){o?e():t.push(e)}}};var i=e=>(...n)=>{if(e){console.log("[Penpal]",...n)}};const c={"http:":"80","https:":"443"};const a=/^(https?:)?\/\/([^/:]+)?(:(\d+))?/;const d=["file:","data:"];var l=e=>{if(e&&d.find(n=>e.startsWith(n))){return"null"}const n=document.location;const t=a.exec(e);let o;let r;let s;if(t){o=t[1]?t[1]:n.protocol;r=t[2];s=t[4]}else{o=n.protocol;r=n.hostname;s=n.port}const i=s&&s!==c[o]?`:${s}`:"";return`${o}//${r}${i}`};const u=({name:e,message:n,stack:t})=>({name:e,message:n,stack:t});const f=e=>{const n=new Error;Object.keys(e).forEach(t=>n[t]=e[t]);return n};var g=(t,s,i)=>{const{localName:c,local:a,remote:d,originForSending:l,originForReceiving:f}=t;let g=false;const m=t=>{if(t.source!==d||t.data.penpal!==e.Call){return}if(f!=="*"&&t.origin!==f){i(`${c} received message from origin ${t.origin} which did not match expected origin ${f}`);return}const r=t.data;const{methodName:a,args:m,id:p}=r;i(`${c}: Received ${a}() call`);const h=t=>r=>{i(`${c}: Sending ${a}() reply`);if(g){i(`${c}: Unable to send ${a}() reply due to destroyed connection`);return}const s={penpal:e.Reply,id:p,resolution:t,returnValue:r};if(t===n.Rejected&&r instanceof Error){s.returnValue=u(r);s.returnValueIsError=true}try{d.postMessage(s,l)}catch(t){if(t.name===o.DataCloneError){const o={penpal:e.Reply,id:p,resolution:n.Rejected,returnValue:u(t),returnValueIsError:true};d.postMessage(o,l)}throw t}};new Promise(e=>e(s[a].apply(s,m))).then(h(n.Fulfilled),h(n.Rejected))};a.addEventListener(r.Message,m);return()=>{g=true;a.removeEventListener(r.Message,m)}};let m=0;var p=()=>++m;const h=".";const v=e=>e?e.split(h):[];const y=e=>e.join(h);const w=(e,n)=>{const t=v(n||"");t.push(e);return y(t)};const $=(e,n,t)=>{const o=v(n);o.reduce((e,n,r)=>{if(typeof e[n]==="undefined"){e[n]={}}if(r===o.length-1){e[n]=t}return e[n]},e);return e};const C=(e,n)=>{const t={};Object.keys(e).forEach(o=>{const r=e[o];const s=w(o,n);if(typeof r==="object"){Object.assign(t,C(r,s))}if(typeof r==="function"){t[s]=r}});return t};const E=e=>{const n={};for(const t in e){$(n,t,e[t])}return n};var k=(o,s,i,c,a)=>{const{localName:d,local:l,remote:u,originForSending:g,originForReceiving:m}=s;let h=false;a(`${d}: Connecting call sender`);const v=o=>(...s)=>{a(`${d}: Sending ${o}() call`);let i;try{if(u.closed){i=true}}catch(e){i=true}if(i){c()}if(h){const e=new Error(`Unable to send ${o}() call due `+`to destroyed connection`);e.code=t.ConnectionDestroyed;throw e}return new Promise((t,i)=>{const c=p();const h=s=>{if(s.source!==u||s.data.penpal!==e.Reply||s.data.id!==c){return}if(m!=="*"&&s.origin!==m){a(`${d} received message from origin ${s.origin} which did not match expected origin ${m}`);return}const g=s.data;a(`${d}: Received ${o}() reply`);l.removeEventListener(r.Message,h);let p=g.returnValue;if(g.returnValueIsError){p=f(p)}(g.resolution===n.Fulfilled?t:i)(p)};l.addEventListener(r.Message,h);const v={penpal:e.Call,id:c,methodName:o,args:s};u.postMessage(v,g)})};const y=i.reduce((e,n)=>{e[n]=v(n);return e},{});Object.assign(o,E(y));return()=>{h=true}};var R=(e,n,t,o,r)=>{const{destroy:s,onDestroy:i}=o;let c;let a;const d={};return o=>{if(n!=="*"&&o.origin!==n){r(`Parent: Handshake - Received ACK message from origin ${o.origin} which did not match expected origin ${n}`);return}r("Parent: Handshake - Received ACK");const l={localName:"Parent",local:window,remote:o.source,originForSending:t,originForReceiving:n};if(c){c()}c=g(l,e,r);i(c);if(a){a.forEach(e=>{delete d[e]})}a=o.data.methodNames;const u=k(d,l,a,s,r);i(u);return d}};var S=(n,t,o,r)=>s=>{if(!s.source){return}if(o!=="*"&&s.origin!==o){n(`Parent: Handshake - Received SYN message from origin ${s.origin} which did not match expected origin ${o}`);return}n("Parent: Handshake - Received SYN, responding with SYN-ACK");const i={penpal:e.SynAck,methodNames:Object.keys(t)};s.source.postMessage(i,r)};const N=6e4;var M=(e,n)=>{const{destroy:t,onDestroy:o}=n;const r=setInterval(()=>{if(!e.isConnected){clearInterval(r);t()}},N);o(()=>{clearInterval(r)})};var A=(e,n)=>{let o;if(e!==undefined){o=window.setTimeout(()=>{const o=new Error(`Connection timed out after ${e}ms`);o.code=t.ConnectionTimeout;n(o)},e)}return()=>{clearTimeout(o)}};var P=e=>{if(!e.src&&!e.srcdoc){const e=new Error("Iframe must have src or srcdoc property defined.");e.code=t.NoIframeSrc;throw e}};var j=n=>{let{iframe:t,methods:o={},childOrigin:c,timeout:a,debug:d=false}=n;const u=i(d);const f=s("Parent",u);const{onDestroy:g,destroy:m}=f;if(!c){P(t);c=l(t.src)}const p=c==="null"?"*":c;const h=C(o);const v=S(u,h,c,p);const y=R(h,c,p,f,u);const w=new Promise((n,o)=>{const s=A(a,m);const i=o=>{if(o.source!==t.contentWindow||!o.data){return}if(o.data.penpal===e.Syn){v(o);return}if(o.data.penpal===e.Ack){const e=y(o);if(e){s();n(e)}return}};window.addEventListener(r.Message,i);u("Parent: Awaiting handshake");M(t,f);g(e=>{window.removeEventListener(r.Message,i);if(e){o(e)}})});return{promise:w,destroy(){m()}}};var D=(n,t,o,r)=>{const{destroy:s,onDestroy:i}=o;return o=>{let c=n instanceof RegExp?n.test(o.origin):n==="*"||n===o.origin;if(!c){r(`Child: Handshake - Received SYN-ACK from origin ${o.origin} which did not match expected origin ${n}`);return}r("Child: Handshake - Received SYN-ACK, responding with ACK");const a=o.origin==="null"?"*":o.origin;const d={penpal:e.Ack,methodNames:Object.keys(t)};window.parent.postMessage(d,a);const l={localName:"Child",local:window,remote:window.parent,originForSending:a,originForReceiving:o.origin};const u=g(l,t,r);i(u);const f={};const m=k(f,l,o.data.methodNames,s,r);i(m);return f}};const b=()=>{try{clearTimeout()}catch(e){return false}return true};var F=(n={})=>{const{parentOrigin:t="*",methods:o={},timeout:c,debug:a=false}=n;const d=i(a);const l=s("Child",d);const{destroy:u,onDestroy:f}=l;const g=C(o);const m=D(t,g,l,d);const p=()=>{d("Child: Handshake - Sending SYN");const n={penpal:e.Syn};const o=t instanceof RegExp?"*":t;window.parent.postMessage(n,o)};const h=new Promise((n,t)=>{const o=A(c,u);const s=t=>{if(!b()){return}if(t.source!==parent||!t.data){return}if(t.data.penpal===e.SynAck){const e=m(t);if(e){window.removeEventListener(r.Message,s);o();n(e)}}};window.addEventListener(r.Message,s);p();f(e=>{window.removeEventListener(r.Message,s);if(e){t(e)}})});return{promise:h,destroy(){u()}}};var I={connectToChild:j,connectToParent:F,ErrorCode:t};return I}();
|
package/dist/penpal.min.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["dist/penpal.js"],"names":["Penpal","MessageType","Resolution","ErrorCode","NativeErrorName","NativeEventType","createDestructor","localName","log","callbacks","destroyed","[object Object]","error","concat","forEach","callback","push","createLogger","debug","args","console","DEFAULT_PORT_BY_PROTOCOL","http:","https:","URL_REGEX","opaqueOriginSchemes","getOriginFromSrc","src","find","scheme","startsWith","location","document","regexResult","exec","protocol","hostname","port","portSuffix","serializeError","name","message","stack","deserializeError","obj","deserializedError","Error","Object","keys","key","connectCallReceiver","info","serializedMethods","local","remote","originForSending","originForReceiving","handleMessageEvent","event","source","data","penpal","Call","origin","callMessage","methodName","id","createPromiseHandler","resolution","returnValue","Reply","Rejected","returnValueIsError","postMessage","err","DataCloneError","errorReplyMessage","Promise","resolve","apply","then","Fulfilled","addEventListener","Message","removeEventListener","generateId","KEY_PATH_DELIMITER","keyPathToSegments","keyPath","split","segmentsToKeyPath","segments","join","createKeyPath","prefix","setAtKeyPath","subject","value","reduce","prevSubject","idx","length","serializeMethods","methods","flattenedMethods","assign","deserializeMethods","connectCallSender","callSender","methodKeyPaths","destroyConnection","createMethodProxy","iframeRemoved","closed","e","code","ConnectionDestroyed","reject","replyMessage","api","handleAckMessageFactory","childOrigin","destructor","destroy","onDestroy","destroyCallReceiver","receiverMethodNames","window","receiverMethodName","methodNames","destroyCallSender","handleSynMessageFactory","synAckMessage","SynAck","CHECK_IFRAME_IN_DOC_INTERVAL","monitorIframeRemoval","iframe","checkIframeInDocIntervalId","setInterval","isConnected","clearInterval","startConnectionTimeout","timeout","timeoutId","undefined","setTimeout","ConnectionTimeout","clearTimeout","validateIframeHasSrcOrSrcDoc","srcdoc","NoIframeSrc","connectToChild","options","handleSynMessage","handleAckMessage","promise","stopConnectionTimeout","handleMessage","contentWindow","Syn","Ack","handleSynAckMessageFactory","parentOrigin","originQualifies","RegExp","test","ackMessage","parent","areGlobalsAccessible","connectToParent","handleSynAckMessage","sendSynMessage","synMessage","parentOriginForSyn","indexForBundle"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["dist/penpal.js"],"names":["Penpal","MessageType","Resolution","ErrorCode","NativeErrorName","NativeEventType","createDestructor","localName","log","callbacks","destroyed","[object Object]","error","forEach","callback","push","createLogger","debug","args","console","DEFAULT_PORT_BY_PROTOCOL","http:","https:","URL_REGEX","opaqueOriginSchemes","getOriginFromSrc","src","find","scheme","startsWith","location","document","regexResult","exec","protocol","hostname","port","portSuffix","serializeError","name","message","stack","deserializeError","obj","deserializedError","Error","Object","keys","key","connectCallReceiver","info","serializedMethods","local","remote","originForSending","originForReceiving","handleMessageEvent","event","source","data","penpal","Call","origin","callMessage","methodName","id","createPromiseHandler","resolution","returnValue","Reply","Rejected","returnValueIsError","postMessage","err","DataCloneError","errorReplyMessage","Promise","resolve","apply","then","Fulfilled","addEventListener","Message","removeEventListener","generateId","KEY_PATH_DELIMITER","keyPathToSegments","keyPath","split","segmentsToKeyPath","segments","join","createKeyPath","prefix","setAtKeyPath","subject","value","reduce","prevSubject","idx","length","serializeMethods","methods","flattenedMethods","assign","deserializeMethods","connectCallSender","callSender","methodKeyPaths","destroyConnection","createMethodProxy","iframeRemoved","closed","e","code","ConnectionDestroyed","reject","replyMessage","api","handleAckMessageFactory","childOrigin","destructor","destroy","onDestroy","destroyCallReceiver","receiverMethodNames","window","receiverMethodName","methodNames","destroyCallSender","handleSynMessageFactory","synAckMessage","SynAck","CHECK_IFRAME_IN_DOC_INTERVAL","monitorIframeRemoval","iframe","checkIframeInDocIntervalId","setInterval","isConnected","clearInterval","startConnectionTimeout","timeout","timeoutId","undefined","setTimeout","ConnectionTimeout","clearTimeout","validateIframeHasSrcOrSrcDoc","srcdoc","NoIframeSrc","connectToChild","options","handleSynMessage","handleAckMessage","promise","stopConnectionTimeout","handleMessage","contentWindow","Syn","Ack","handleSynAckMessageFactory","parentOrigin","originQualifies","RegExp","test","ackMessage","parent","areGlobalsAccessible","connectToParent","handleSynAckMessage","sendSynMessage","synMessage","parentOriginForSyn","indexForBundle"],"mappings":"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"}
|
|
@@ -25,7 +25,7 @@ var _default = (parentOrigin, serializedMethods, destructor, log) => {
|
|
|
25
25
|
let originQualifies = parentOrigin instanceof RegExp ? parentOrigin.test(event.origin) : parentOrigin === '*' || parentOrigin === event.origin;
|
|
26
26
|
|
|
27
27
|
if (!originQualifies) {
|
|
28
|
-
log(
|
|
28
|
+
log(`Child: Handshake - Received SYN-ACK from origin ${event.origin} which did not match expected origin ${parentOrigin}`);
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -28,8 +28,8 @@ var _default = (info, serializedMethods, log) => {
|
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
if (event.origin !== originForReceiving) {
|
|
32
|
-
log(
|
|
31
|
+
if (originForReceiving !== '*' && event.origin !== originForReceiving) {
|
|
32
|
+
log(`${localName} received message from origin ${event.origin} which did not match expected origin ${originForReceiving}`);
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
|
|
@@ -39,11 +39,11 @@ var _default = (info, serializedMethods, log) => {
|
|
|
39
39
|
args,
|
|
40
40
|
id
|
|
41
41
|
} = callMessage;
|
|
42
|
-
log(
|
|
42
|
+
log(`${localName}: Received ${methodName}() call`);
|
|
43
43
|
|
|
44
44
|
const createPromiseHandler = resolution => {
|
|
45
45
|
return returnValue => {
|
|
46
|
-
log(
|
|
46
|
+
log(`${localName}: Sending ${methodName}() reply`);
|
|
47
47
|
|
|
48
48
|
if (destroyed) {
|
|
49
49
|
// It's possible to throw an error here, but it would need to be thrown asynchronously
|
|
@@ -51,7 +51,7 @@ var _default = (info, serializedMethods, log) => {
|
|
|
51
51
|
// is merely returning a value from their method and not calling any function
|
|
52
52
|
// that they could wrap in a try-catch. Even if the consumer were to catch the error,
|
|
53
53
|
// the value of doing so is questionable. Instead, we'll just log a message.
|
|
54
|
-
log(
|
|
54
|
+
log(`${localName}: Unable to send ${methodName}() reply due to destroyed connection`);
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
|
package/es5/connectCallSender.js
CHANGED
|
@@ -35,11 +35,11 @@ var _default = (callSender, info, methodKeyPaths, destroyConnection, log) => {
|
|
|
35
35
|
originForReceiving
|
|
36
36
|
} = info;
|
|
37
37
|
let destroyed = false;
|
|
38
|
-
log(
|
|
38
|
+
log(`${localName}: Connecting call sender`);
|
|
39
39
|
|
|
40
40
|
const createMethodProxy = methodName => {
|
|
41
41
|
return (...args) => {
|
|
42
|
-
log(
|
|
42
|
+
log(`${localName}: Sending ${methodName}() call`); // This handles the case where the iframe has been removed from the DOM
|
|
43
43
|
// (and therefore its window closed), the consumer has not yet
|
|
44
44
|
// called destroy(), and the user calls a method exposed by
|
|
45
45
|
// the remote. We detect the iframe has been removed and force
|
|
@@ -64,7 +64,7 @@ var _default = (callSender, info, methodKeyPaths, destroyConnection, log) => {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
if (destroyed) {
|
|
67
|
-
const error = new Error(
|
|
67
|
+
const error = new Error(`Unable to send ${methodName}() call due ` + `to destroyed connection`);
|
|
68
68
|
error.code = _enums.ErrorCode.ConnectionDestroyed;
|
|
69
69
|
throw error;
|
|
70
70
|
}
|
|
@@ -77,13 +77,13 @@ var _default = (callSender, info, methodKeyPaths, destroyConnection, log) => {
|
|
|
77
77
|
return;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
if (event.origin !== originForReceiving) {
|
|
81
|
-
log(
|
|
80
|
+
if (originForReceiving !== '*' && event.origin !== originForReceiving) {
|
|
81
|
+
log(`${localName} received message from origin ${event.origin} which did not match expected origin ${originForReceiving}`);
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
const replyMessage = event.data;
|
|
86
|
-
log(
|
|
86
|
+
log(`${localName}: Received ${methodName}() reply`);
|
|
87
87
|
local.removeEventListener(_enums.NativeEventType.Message, handleMessageEvent);
|
|
88
88
|
let returnValue = replyMessage.returnValue;
|
|
89
89
|
|
package/es5/createDestructor.js
CHANGED
|
@@ -12,7 +12,7 @@ var _default = (localName, log) => {
|
|
|
12
12
|
destroy(error) {
|
|
13
13
|
if (!destroyed) {
|
|
14
14
|
destroyed = true;
|
|
15
|
-
log(
|
|
15
|
+
log(`${localName}: Destroying connection`);
|
|
16
16
|
callbacks.forEach(callback => {
|
|
17
17
|
callback(error);
|
|
18
18
|
});
|
|
@@ -46,8 +46,8 @@ var _default = src => {
|
|
|
46
46
|
// or it won't match the message's event.origin.
|
|
47
47
|
|
|
48
48
|
|
|
49
|
-
const portSuffix = port && port !== DEFAULT_PORT_BY_PROTOCOL[protocol] ?
|
|
50
|
-
return
|
|
49
|
+
const portSuffix = port && port !== DEFAULT_PORT_BY_PROTOCOL[protocol] ? `:${port}` : '';
|
|
50
|
+
return `${protocol}//${hostname}${portSuffix}`;
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
exports.default = _default;
|
|
@@ -27,8 +27,8 @@ var _default = (serializedMethods, childOrigin, originForSending, destructor, lo
|
|
|
27
27
|
|
|
28
28
|
const callSender = {};
|
|
29
29
|
return event => {
|
|
30
|
-
if (event.origin !== childOrigin) {
|
|
31
|
-
log(
|
|
30
|
+
if (childOrigin !== '*' && event.origin !== childOrigin) {
|
|
31
|
+
log(`Parent: Handshake - Received ACK message from origin ${event.origin} which did not match expected origin ${childOrigin}`);
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
34
|
|
|
@@ -12,8 +12,16 @@ var _enums = require("../enums");
|
|
|
12
12
|
*/
|
|
13
13
|
var _default = (log, serializedMethods, childOrigin, originForSending) => {
|
|
14
14
|
return event => {
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
// Under specific timing circumstances, we can receive an event
|
|
16
|
+
// whose source is null. This seems to happen when the child iframe is
|
|
17
|
+
// removed from the DOM about the same time it has sent the SYN event.
|
|
18
|
+
// https://github.com/Aaronius/penpal/issues/85
|
|
19
|
+
if (!event.source) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (childOrigin !== '*' && event.origin !== childOrigin) {
|
|
24
|
+
log(`Parent: Handshake - Received SYN message from origin ${event.origin} which did not match expected origin ${childOrigin}`);
|
|
17
25
|
return;
|
|
18
26
|
}
|
|
19
27
|
|
|
@@ -16,7 +16,7 @@ var _default = (timeout, callback) => {
|
|
|
16
16
|
|
|
17
17
|
if (timeout !== undefined) {
|
|
18
18
|
timeoutId = window.setTimeout(() => {
|
|
19
|
-
const error = new Error(
|
|
19
|
+
const error = new Error(`Connection timed out after ${timeout}ms`);
|
|
20
20
|
error.code = _enums.ErrorCode.ConnectionTimeout;
|
|
21
21
|
callback(error);
|
|
22
22
|
}, timeout);
|
|
@@ -11,7 +11,7 @@ export default (info, serializedMethods, log) => {
|
|
|
11
11
|
if (event.source !== remote || event.data.penpal !== MessageType.Call) {
|
|
12
12
|
return;
|
|
13
13
|
}
|
|
14
|
-
if (event.origin !== originForReceiving) {
|
|
14
|
+
if (originForReceiving !== '*' && event.origin !== originForReceiving) {
|
|
15
15
|
log(`${localName} received message from origin ${event.origin} which did not match expected origin ${originForReceiving}`);
|
|
16
16
|
return;
|
|
17
17
|
}
|
package/lib/connectCallSender.js
CHANGED
|
@@ -54,7 +54,8 @@ export default (callSender, info, methodKeyPaths, destroyConnection, log) => {
|
|
|
54
54
|
event.data.id !== id) {
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
|
-
if (
|
|
57
|
+
if (originForReceiving !== '*' &&
|
|
58
|
+
event.origin !== originForReceiving) {
|
|
58
59
|
log(`${localName} received message from origin ${event.origin} which did not match expected origin ${originForReceiving}`);
|
|
59
60
|
return;
|
|
60
61
|
}
|
|
@@ -13,7 +13,7 @@ export default (serializedMethods, childOrigin, originForSending, destructor, lo
|
|
|
13
13
|
// latest provided by the child.
|
|
14
14
|
const callSender = {};
|
|
15
15
|
return (event) => {
|
|
16
|
-
if (event.origin !== childOrigin) {
|
|
16
|
+
if (childOrigin !== '*' && event.origin !== childOrigin) {
|
|
17
17
|
log(`Parent: Handshake - Received ACK message from origin ${event.origin} which did not match expected origin ${childOrigin}`);
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
@@ -4,7 +4,14 @@ import { MessageType } from '../enums';
|
|
|
4
4
|
*/
|
|
5
5
|
export default (log, serializedMethods, childOrigin, originForSending) => {
|
|
6
6
|
return (event) => {
|
|
7
|
-
|
|
7
|
+
// Under specific timing circumstances, we can receive an event
|
|
8
|
+
// whose source is null. This seems to happen when the child iframe is
|
|
9
|
+
// removed from the DOM about the same time it has sent the SYN event.
|
|
10
|
+
// https://github.com/Aaronius/penpal/issues/85
|
|
11
|
+
if (!event.source) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (childOrigin !== '*' && event.origin !== childOrigin) {
|
|
8
15
|
log(`Parent: Handshake - Received SYN message from origin ${event.origin} which did not match expected origin ${childOrigin}`);
|
|
9
16
|
return;
|
|
10
17
|
}
|