Skip to content

Commit c890107

Browse files
author
Daniel Brain
committed
Refactor and clean up initial child payload serialization
1 parent 24949fb commit c890107

22 files changed

+496
-325
lines changed

src/child/child.js

+22-90
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
/* @flow */
22
/* eslint max-lines: 0 */
33

4-
import { isSameDomain, matchDomain, getDomain, getOpener,
5-
getNthParentFromTop, getAncestor, getAllFramesInWindow,
6-
type CrossDomainWindowType, onCloseWindow, assertSameDomain } from 'cross-domain-utils/src';
7-
import { markWindowKnown, deserializeMessage, type CrossDomainFunctionType } from 'post-robot/src';
4+
import { isSameDomain, matchDomain, getAllFramesInWindow, type CrossDomainWindowType,
5+
onCloseWindow, assertSameDomain } from 'cross-domain-utils/src';
6+
import { markWindowKnown, type CrossDomainFunctionType } from 'post-robot/src';
87
import { ZalgoPromise } from 'zalgo-promise/src';
9-
import { extend, onResize, elementReady, assertExists, noop } from 'belter/src';
8+
import { extend, onResize, elementReady, noop } from 'belter/src';
109

11-
import { getGlobal, tryGlobal } from '../lib';
12-
import { CONTEXT, INITIAL_PROPS, WINDOW_REFERENCES } from '../constants';
10+
import { getGlobal, tryGlobal, getInitialParentPayload } from '../lib';
11+
import { CONTEXT } from '../constants';
1312
import type { NormalizedComponentOptionsType, getSiblingsPropType } from '../component';
1413
import type { PropsType, ChildPropsType } from '../component/props';
15-
import type { WindowRef, PropRef, ParentExportsType } from '../parent';
1614
import type { StringMatcherType } from '../types';
1715

1816
import { normalizeChildProps } from './props';
19-
import { getChildPayload } from './window';
2017

2118
export type ChildExportsType<P> = {|
2219
updateProps : CrossDomainFunctionType<[ PropsType<P> ], void>,
@@ -39,37 +36,6 @@ export type ChildHelpers<P, X> = {|
3936
getSiblings : getSiblingsPropType
4037
|};
4138

42-
function getParentComponentWindow(ref : WindowRef) : CrossDomainWindowType {
43-
const { type } = ref;
44-
45-
if (type === WINDOW_REFERENCES.OPENER) {
46-
return assertExists('opener', getOpener(window));
47-
48-
} else if (type === WINDOW_REFERENCES.PARENT && typeof ref.distance === 'number') {
49-
return assertExists('parent', getNthParentFromTop(window, ref.distance));
50-
51-
} else if (type === WINDOW_REFERENCES.GLOBAL && ref.uid && typeof ref.uid === 'string') {
52-
const { uid } = ref;
53-
const ancestor = getAncestor(window);
54-
55-
if (!ancestor) {
56-
throw new Error(`Can not find ancestor window`);
57-
}
58-
59-
for (const frame of getAllFramesInWindow(ancestor)) {
60-
if (isSameDomain(frame)) {
61-
const win = tryGlobal(frame, global => global.windows && global.windows[uid]);
62-
63-
if (win) {
64-
return win;
65-
}
66-
}
67-
}
68-
}
69-
70-
throw new Error(`Unable to find ${ type } parent component window`);
71-
}
72-
7339
function checkParentDomain(allowedParentDomains : StringMatcherType, domain : string) {
7440
if (!matchDomain(allowedParentDomains, domain)) {
7541
throw new Error(`Can not be rendered by domain: ${ domain }`);
@@ -88,27 +54,6 @@ function destroy() : ZalgoPromise<void> {
8854
});
8955
}
9056

91-
function getPropsByRef<P>(parentComponentWindow : CrossDomainWindowType, domain : string, propRef : PropRef) : (PropsType<P>) {
92-
let props;
93-
94-
if (propRef.type === INITIAL_PROPS.RAW) {
95-
props = propRef.value;
96-
} else if (propRef.type === INITIAL_PROPS.UID) {
97-
if (!isSameDomain(parentComponentWindow)) {
98-
throw new Error(`Parent component window is on a different domain - expected ${ getDomain() } - can not retrieve props`);
99-
}
100-
101-
const global = getGlobal(parentComponentWindow);
102-
props = assertExists('props', global && global.props[propRef.uid]);
103-
}
104-
105-
if (!props) {
106-
throw new Error(`Could not find props`);
107-
}
108-
109-
return deserializeMessage(parentComponentWindow, domain, props);
110-
}
111-
11257
export type ChildComponent<P, X> = {|
11358
getProps : () => ChildPropsType<P, X>,
11459
init : () => ZalgoPromise<void>
@@ -118,23 +63,20 @@ export function childComponent<P, X, C>(options : NormalizedComponentOptionsType
11863
const { tag, propsDef, autoResize, allowedParentDomains } = options;
11964

12065
const onPropHandlers = [];
121-
const childPayload = getChildPayload();
66+
67+
const { parent, payload } = getInitialParentPayload();
68+
const { win: parentComponentWindow, domain: parentDomain } = parent;
69+
12270
let props : ChildPropsType<P, X>;
12371
const exportsPromise = new ZalgoPromise();
12472

125-
if (!childPayload) {
126-
throw new Error(`No child payload found`);
127-
}
73+
const { version, uid, exports: parentExports, context, props: initialProps } = payload;
12874

129-
if (childPayload.version !== __ZOID__.__VERSION__) {
130-
throw new Error(`Parent window has zoid version ${ childPayload.version }, child window has version ${ __ZOID__.__VERSION__ }`);
75+
if (version !== __ZOID__.__VERSION__) {
76+
throw new Error(`Parent window has zoid version ${ version }, child window has version ${ __ZOID__.__VERSION__ }`);
13177
}
13278

133-
const { uid, parent: parentRef, parentDomain, exports: parentExports, context, props: propsRef } = childPayload;
134-
const parentComponentWindow = getParentComponentWindow(parentRef);
135-
const parent : ParentExportsType<P, X> = deserializeMessage(parentComponentWindow, parentDomain, parentExports);
136-
137-
const { show, hide, close } = parent;
79+
const { show, hide, close, onError, checkClose, export: parentExport, resize: parentResize, init: parentInit } = parentExports;
13880

13981
const getParent = () => parentComponentWindow;
14082
const getParentDomain = () => parentDomain;
@@ -143,23 +85,13 @@ export function childComponent<P, X, C>(options : NormalizedComponentOptionsType
14385
onPropHandlers.push(handler);
14486
};
14587

146-
const onError = (err : mixed) : ZalgoPromise<void> => {
147-
return ZalgoPromise.try(() => {
148-
if (parent && parent.onError) {
149-
return parent.onError(err);
150-
} else {
151-
throw err;
152-
}
153-
});
154-
};
155-
15688
const resize = ({ width, height } : {| width : ?number, height : ?number |}) : ZalgoPromise<void> => {
157-
return parent.resize.fireAndForget({ width, height });
89+
return parentResize.fireAndForget({ width, height });
15890
};
15991

16092
const xport = (xports : X) : ZalgoPromise<void> => {
16193
exportsPromise.resolve(xports);
162-
return parent.export(xports);
94+
return parentExport(xports);
16395
};
16496

16597
const getSiblings = ({ anyParent } = {}) => {
@@ -213,11 +145,11 @@ export function childComponent<P, X, C>(options : NormalizedComponentOptionsType
213145

214146
const watchForClose = () => {
215147
window.addEventListener('beforeunload', () => {
216-
parent.checkClose.fireAndForget();
148+
checkClose.fireAndForget();
217149
});
218150

219151
window.addEventListener('unload', () => {
220-
parent.checkClose.fireAndForget();
152+
checkClose.fireAndForget();
221153
});
222154

223155
onCloseWindow(parentComponentWindow, () => {
@@ -276,7 +208,7 @@ export function childComponent<P, X, C>(options : NormalizedComponentOptionsType
276208
markWindowKnown(parentComponentWindow);
277209
watchForClose();
278210

279-
return parent.init({ updateProps, close: destroy });
211+
return parentInit({ updateProps, close: destroy });
280212

281213
}).then(() => {
282214
return watchForResize();
@@ -289,10 +221,10 @@ export function childComponent<P, X, C>(options : NormalizedComponentOptionsType
289221
const getProps = () => {
290222
if (props) {
291223
return props;
224+
} else {
225+
setProps(initialProps, parentDomain);
226+
return props;
292227
}
293-
294-
setProps(getPropsByRef(parentComponentWindow, parentDomain, propsRef), parentDomain);
295-
return props;
296228
};
297229

298230
return {

src/child/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
/* @flow */
22

33
export * from './child';
4-
export * from './window';
4+

src/child/window.js

-42
This file was deleted.

src/component/component.js

+13-7
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33

44
import { setup as setupPostRobot, on, send, bridge, toProxyWindow, destroy as destroyPostRobot } from 'post-robot/src';
55
import { ZalgoPromise } from 'zalgo-promise/src';
6-
import { isWindow, getDomain, type CrossDomainWindowType } from 'cross-domain-utils/src';
6+
import { isWindow, getDomain, matchDomain, type CrossDomainWindowType, type DomainMatcher } from 'cross-domain-utils/src';
77
import { noop, isElement, cleanup, memoize, identity, extend, uniqueID } from 'belter/src';
88

9-
import { getChildPayload, childComponent, type ChildComponent } from '../child';
9+
import { childComponent, type ChildComponent } from '../child';
1010
import { type RenderOptionsType, type ParentHelpers, parentComponent } from '../parent/parent';
1111
import { ZOID, CONTEXT, POST_MESSAGE, WILDCARD, METHOD, PROP_TYPE } from '../constants';
1212
import { react, angular, vue, vue3, angular2 } from '../drivers';
13-
import { getGlobal, destroyGlobal } from '../lib';
13+
import { getGlobal, destroyGlobal, getInitialParentPayload, isChildComponentWindow } from '../lib';
1414
import type { CssDimensionsType, StringMatcherType } from '../types';
1515

1616
import { validateOptions } from './validate';
@@ -57,7 +57,7 @@ export type ComponentOptionsType<P, X, C> = {|
5757
tag : string,
5858

5959
url : string | ({| props : PropsType<P> |}) => string,
60-
domain? : string | RegExp,
60+
domain? : DomainMatcher,
6161
bridgeUrl? : string,
6262
method? : $Values<typeof METHOD>,
6363

@@ -102,7 +102,7 @@ export type NormalizedComponentOptionsType<P, X, C> = {|
102102
name : string,
103103

104104
url : string | ({| props : PropsType<P> |}) => string,
105-
domain : ?(string | RegExp),
105+
domain : ?DomainMatcher,
106106
bridgeUrl : ?string,
107107
method : ?$Values<typeof METHOD>,
108108

@@ -287,8 +287,14 @@ export function component<P, X, C>(opts : ComponentOptionsType<P, X, C>) : Compo
287287
const instances = [];
288288

289289
const isChild = () : boolean => {
290-
const payload = getChildPayload();
291-
return Boolean(payload && payload.tag === tag && payload.childDomain === getDomain());
290+
if (isChildComponentWindow()) {
291+
const { payload } = getInitialParentPayload();
292+
if (payload.tag === tag && matchDomain(payload.childDomainMatch, getDomain())) {
293+
return true;
294+
}
295+
}
296+
297+
return false;
292298
};
293299

294300
const registerChild = memoize(() : ?ChildComponent<P, X> => {

src/constants.js

+3-7
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,11 @@ export const PROP_TYPE = {
1818
ARRAY: ('array' : 'array')
1919
};
2020

21-
export const INITIAL_PROPS = {
22-
RAW: 'raw',
23-
UID: 'uid'
24-
};
25-
26-
export const WINDOW_REFERENCES = {
21+
export const WINDOW_REFERENCE = {
2722
OPENER: ('opener' : 'opener'),
2823
PARENT: ('parent' : 'parent'),
29-
GLOBAL: ('global' : 'global')
24+
GLOBAL: ('global' : 'global'),
25+
NAME: ('name' : 'name')
3026
};
3127

3228
export const PROP_SERIALIZATION = {

src/lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22

33
export * from './global';
44
export * from './serialize';
5+
export * from './window';

0 commit comments

Comments
 (0)