Skip to content

Commit 97e8179

Browse files
Le SaoutYannick Le Saout
Le Saout
authored and
Yannick Le Saout
committed
Added iframe optional parameter to connectToChild
1 parent 3811461 commit 97e8179

File tree

4 files changed

+339
-239
lines changed

4 files changed

+339
-239
lines changed

src/index.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const DATA_CLONE_ERROR = 'DataCloneError';
1010
export const ERR_CONNECTION_DESTROYED = 'ConnectionDestroyed';
1111
export const ERR_CONNECTION_TIMEOUT = 'ConnectionTimeout';
1212
export const ERR_NOT_IN_IFRAME = 'NotInIframe';
13+
export const ERR_IFRAME_ALREADY_ATTACHED_TO_DOM = 'IframeAlreadyAttachedToDom';
1314

1415
const DEFAULT_PORTS = {
1516
'http:': '80',
@@ -22,6 +23,7 @@ const Penpal = {
2223
ERR_CONNECTION_DESTROYED,
2324
ERR_CONNECTION_TIMEOUT,
2425
ERR_NOT_IN_IFRAME,
26+
ERR_IFRAME_ALREADY_ATTACHED_TO_DOM,
2527

2628
/**
2729
* Promise implementation.
@@ -336,26 +338,33 @@ const connectCallReceiver = (info, methods, destructionPromise) => {
336338
* for the child to respond before rejecting the connection promise.
337339
* @return {Child}
338340
*/
339-
Penpal.connectToChild = ({ url, appendTo, methods = {}, timeout }) => {
341+
Penpal.connectToChild = ({ url, appendTo, iframe, methods = {}, timeout }) => {
342+
if (iframe && iframe.parentNode) {
343+
const error = new Error(
344+
'connectToChild() must not be called with an iframe already attached to DOM'
345+
);
346+
error.code = ERR_IFRAME_ALREADY_ATTACHED_TO_DOM;
347+
throw error;
348+
}
349+
340350
let destroy;
351+
341352
const connectionDestructionPromise = new DestructionPromise(
342353
resolveConnectionDestructionPromise => {
343354
destroy = resolveConnectionDestructionPromise;
344355
}
345356
);
346357

347358
const parent = window;
348-
const iframe = document.createElement('iframe');
349-
350-
(appendTo || document.body).appendChild(iframe);
359+
iframe = iframe || document.createElement('iframe');
360+
iframe.src = url;
351361

352362
connectionDestructionPromise.then(() => {
353363
if (iframe.parentNode) {
354364
iframe.parentNode.removeChild(iframe);
355365
}
356366
});
357367

358-
const child = iframe.contentWindow || iframe.contentDocument.parentWindow;
359368
const childOrigin = getOriginFromUrl(url);
360369
const promise = new Penpal.Promise((resolveConnectionPromise, reject) => {
361370
let connectionTimeoutId;
@@ -380,6 +389,7 @@ Penpal.connectToChild = ({ url, appendTo, methods = {}, timeout }) => {
380389
let destroyCallReceiver;
381390

382391
const handleMessage = event => {
392+
const child = iframe.contentWindow || iframe.contentDocument.parentWindow;
383393
if (
384394
event.source === child &&
385395
event.origin === childOrigin &&
@@ -456,7 +466,7 @@ Penpal.connectToChild = ({ url, appendTo, methods = {}, timeout }) => {
456466
});
457467

458468
log('Parent: Loading iframe');
459-
iframe.src = url;
469+
(appendTo || document.body).appendChild(iframe);
460470
});
461471

462472
return {

0 commit comments

Comments
 (0)