Skip to content
This repository was archived by the owner on Jan 31, 2025. It is now read-only.

Commit bf7d76f

Browse files
committed
Allow serializing using proxy window
1 parent 2e4b086 commit bf7d76f

File tree

6 files changed

+139
-129
lines changed

6 files changed

+139
-129
lines changed

src/lib/hello.js

+3-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { global } from '../global';
1010

1111
global.instanceID = global.instanceID || uniqueID();
1212
global.helloPromises = global.helloPromises || new WeakMap();
13+
global.onHello = global.onHello || [];
1314

1415
function getHelloPromise(win : CrossDomainWindowType) : ZalgoPromise<{ win : CrossDomainWindowType, domain : string }> {
1516
return global.helloPromises.getOrSet(win, () => new ZalgoPromise());
@@ -18,14 +19,12 @@ function getHelloPromise(win : CrossDomainWindowType) : ZalgoPromise<{ win : Cro
1819
const listenForHello = once(() => {
1920
global.on(MESSAGE_NAME.HELLO, { domain: WILDCARD }, ({ source, origin }) => {
2021
getHelloPromise(source).resolve({ win: source, domain: origin });
21-
return {
22-
instanceID: global.instanceID
23-
};
22+
return { instanceID: global.instanceID };
2423
});
2524
});
2625

2726
export function sayHello(win : CrossDomainWindowType) : ZalgoPromise<{ win : CrossDomainWindowType, domain : string, instanceID : string }> {
28-
return global.send(win, MESSAGE_NAME.HELLO, {}, { domain: WILDCARD, timeout: -1 })
27+
return global.send(win, MESSAGE_NAME.HELLO, { instanceID: global.instanceID }, { domain: WILDCARD, timeout: -1 })
2928
.then(({ origin, data: { instanceID } }) => {
3029
getHelloPromise(win).resolve({ win, domain: origin });
3130
return { win, domain: origin, instanceID };

src/lib/windows.js

+5-22
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,14 @@
11
/* @flow */
22

3-
import { type CrossDomainWindowType, isWindowClosed } from 'cross-domain-utils/src';
3+
import { WeakMap } from 'cross-domain-safe-weakmap/src';
4+
import { type CrossDomainWindowType } from 'cross-domain-utils/src';
45

5-
global.knownWindows = global.knownWindows || [];
6-
global.onKnownWindow = global.onKnownWindow || [];
6+
global.knownWindows = global.knownWindows || new WeakMap();
77

88
export function markWindowKnown(win : CrossDomainWindowType) {
9-
global.knownWindows = global.knownWindows.filter(knownWindow => !isWindowClosed(knownWindow));
10-
if (global.knownWindows.indexOf(win) === -1) {
11-
global.knownWindows.push(win);
12-
for (let handler of global.onKnownWindow) {
13-
handler(win);
14-
}
15-
}
9+
global.knownWindows.set(win, true);
1610
}
1711

1812
export function isWindowKnown(win : CrossDomainWindowType) : boolean {
19-
return global.knownWindows.indexOf(win) !== -1;
20-
}
21-
22-
export function getKnownWindows() : $ReadOnlyArray<CrossDomainWindowType> {
23-
return global.knownWindows;
24-
}
25-
26-
export function onKnownWindow(handler : (CrossDomainWindowType) => void) {
27-
global.onKnownWindow.push(handler);
28-
for (let win of global.knownWindows) {
29-
handler(win);
30-
}
13+
return global.knownWindows.get(win, false);
3114
}

src/serialize/function.js

+39-24
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,46 @@ import { serializeType, type CustomSerializedType } from 'universal-serialize/sr
99
import { MESSAGE_NAME, WILDCARD, SERIALIZATION_TYPE } from '../conf';
1010
import { global } from '../global';
1111

12+
import { ProxyWindow } from './window';
13+
1214
global.methods = global.methods || new WeakMap();
15+
global.proxyWindowMethods = global.proxyWindowMethods || {};
1316

1417
const listenForFunctionCalls = once(() => {
1518
global.on(MESSAGE_NAME.METHOD, { origin: WILDCARD }, ({ source, origin, data } : { source : CrossDomainWindowType, origin : string, data : Object }) => {
16-
let methods = global.methods.get(source);
19+
let { id, name } = data;
20+
21+
return ZalgoPromise.try(() => {
22+
let methods = global.methods.get(source) || {};
23+
let meth = methods[data.id] || global.proxyWindowMethods[id];
1724

18-
if (!methods) {
19-
throw new Error(`Could not find any methods this window has privileges to call`);
20-
}
25+
if (!meth) {
26+
throw new Error(`Could not find method with id: ${ data.id }`);
27+
}
2128

22-
let meth = methods[data.id];
29+
let { proxy, domain, val } = meth;
2330

24-
if (!meth) {
25-
throw new Error(`Could not find method with id: ${ data.id }`);
26-
}
31+
if (!matchDomain(domain, origin)) {
32+
throw new Error(`Method domain ${ meth.domain } does not match origin ${ origin }`);
33+
}
34+
35+
if (proxy) {
36+
return proxy.matchWindow(source).then(match => {
37+
if (!match) {
38+
throw new Error(`Proxy window does not match source`);
39+
}
2740

28-
if (!matchDomain(meth.domain, origin)) {
29-
throw new Error(`Method domain ${ meth.domain } does not match origin ${ origin }`);
30-
}
41+
delete global.proxyWindowMethods[id];
42+
return val;
43+
});
44+
}
45+
46+
return val;
47+
48+
}).then(method => {
49+
return method.apply({ source, origin, data }, data.args);
3150

32-
return ZalgoPromise.try(() => {
33-
return meth.val.apply({ source, origin, data }, data.args);
3451
}).then(result => {
35-
const { id, name } = data;
3652
return { result, id, name };
3753
});
3854
});
@@ -43,20 +59,19 @@ export type SerializedFunction = CustomSerializedType<typeof SERIALIZATION_TYPE.
4359
name : string
4460
}>;
4561

46-
export function serializeFunction<T>(destination : CrossDomainWindowType, domain : string | Array<string>, val : () => ZalgoPromise<T> | T, key : string) : SerializedFunction {
62+
export function serializeFunction<T>(destination : CrossDomainWindowType | ProxyWindow, domain : string | Array<string>, val : () => ZalgoPromise<T> | T, key : string) : SerializedFunction {
63+
listenForFunctionCalls();
64+
4765
let id = uniqueID();
66+
destination = ProxyWindow.unwrap(destination);
4867

49-
let methods = global.methods.get(destination);
50-
51-
if (!methods) {
52-
methods = {};
53-
global.methods.set(destination, methods);
68+
if (ProxyWindow.isProxyWindow(destination)) {
69+
global.proxyWindowMethods[id] = { proxy: destination, domain, val };
70+
} else {
71+
let methods = global.methods.getOrSet(destination, () => ({}));
72+
methods[id] = { domain, val };
5473
}
5574

56-
methods[id] = { domain, val };
57-
58-
listenForFunctionCalls();
59-
6075
return serializeType(SERIALIZATION_TYPE.CROSS_DOMAIN_FUNCTION, { id, name: val.name || key });
6176
}
6277

src/serialize/promise.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ import { serializeType, type CustomSerializedType, type Thenable } from 'univers
77
import { SERIALIZATION_TYPE } from '../conf';
88

99
import { serializeFunction, type SerializedFunction } from './function';
10+
import { ProxyWindow } from './window';
1011

1112
export type SerializedPromise = CustomSerializedType<typeof SERIALIZATION_TYPE.CROSS_DOMAIN_ZALGO_PROMISE, {
1213
then : SerializedFunction
1314
}>;
1415

15-
export function serializePromise(destination : CrossDomainWindowType, domain : string | Array<string>, val : Thenable, key : string) : SerializedPromise {
16+
export function serializePromise(destination : CrossDomainWindowType | ProxyWindow, domain : string | Array<string>, val : Thenable, key : string) : SerializedPromise {
1617
return serializeType(SERIALIZATION_TYPE.CROSS_DOMAIN_ZALGO_PROMISE, {
1718
then: serializeFunction(destination, domain, (resolve, reject) => val.then(resolve, reject), key)
1819
});

src/serialize/serialize.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,12 @@ import { serializeFunction, deserializeFunction, type SerializedFunction } from
99
import { serializePromise, deserializePromise, type SerializedPromise } from './promise';
1010
import { serializeWindow, deserializeWindow, type SerializedWindow, ProxyWindow } from './window';
1111

12-
export function serializeMessage<T : mixed>(destination : CrossDomainWindowType, domain : string | Array<string>, obj : T) : string {
12+
export function serializeMessage<T : mixed>(destination : CrossDomainWindowType | ProxyWindow, domain : string | Array<string>, obj : T) : string {
1313
return serialize(obj, {
1414
[ TYPE.PROMISE ]: (val : Thenable, key : string) : SerializedPromise => serializePromise(destination, domain, val, key),
1515
[ TYPE.FUNCTION ]: (val : Function, key : string) : SerializedFunction => serializeFunction(destination, domain, val, key),
1616
[ TYPE.OBJECT ]: (val : CrossDomainWindowType) : Object | SerializedWindow => {
17-
return (isWindow(val) || ProxyWindow.isProxyWindow(val))
18-
? serializeWindow(destination, domain, val)
19-
: val;
17+
return (isWindow(val) || ProxyWindow.isProxyWindow(val)) ? serializeWindow(destination, domain, val) : val;
2018
}
2119
});
2220
}

0 commit comments

Comments
 (0)