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

Commit 06c205d

Browse files
author
Daniel Brain
committed
Use WeakMap to get references by window
1 parent dd8f138 commit 06c205d

21 files changed

+271
-149
lines changed

demo/bridge.htm

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
window.mockDomain = 'mock://foo.com';
55
</script>
66

7-
<script src="../dist/post-robot.js"></script>
7+
<script src="../dist/post-robot.ie.js"></script>

demo/child.htm

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
</script>
88

9-
<script src="../dist/post-robot.js"></script>
9+
<script src="../dist/post-robot.ie.js"></script>
1010

1111

1212
<button onclick="sendMessage()">post</button>

demo/parent.htm

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
<!DOCTYPE html>
22

3-
<script src="../dist/post-robot.js"></script>
3+
<script src="../dist/post-robot.ie.js"></script>
44

55
<button onclick="openWindow()">open</button>
66

77
<div id="messages"></div>
88

99
<script>
10-
postRobot.openBridge('./bridge.htm', 'mock://foo.com');
10+
postRobot.bridge.openBridge('./bridge.htm', 'mock://foo.com');
1111

1212
function openWindow() {
1313
window.open('mock://foo.com|./child.htm', Math.random().toString().replace(/[^a-z0-9]+/g, ''));

karma.conf.js

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ module.exports = function(config) {
5858
query: {
5959
presets: ['es2015'],
6060
plugins: [
61+
'transform-flow-strip-types',
6162
'transform-object-rest-spread',
6263
'syntax-object-rest-spread',
6364
'transform-es3-property-literals',

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
"yargs": "^4.7.1"
6969
},
7070
"dependencies": {
71+
"cross-domain-safe-weakmap": "^1.0.1",
7172
"sync-browser-mocks": "^1.0.3"
7273
}
7374
}

src/bridge/child.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11

22
import { SyncPromise as Promise } from 'sync-browser-mocks/src/promise';
33
import { CONSTANTS } from '../conf';
4-
import { isSameDomain, getOpener, getFrames, util, getFrameByName } from '../lib';
4+
import { isSameDomain, getOpener, getFrames, util, getFrameByName, weakMapMemoize } from '../lib';
55
import { receiveMessage } from '../drivers';
66

77
import { needsBridge, registerRemoteWindow, rejectRemoteSendMessage, registerRemoteSendMessage, getBridgeName } from './common';
88

9-
function getRemoteBridgeForWindow(win) {
9+
let awaitRemoteBridgeForWindow = weakMapMemoize(win => {
1010
return Promise.try(() => {
1111
for (let frame of getFrames(win)) {
1212
try {
@@ -53,7 +53,7 @@ function getRemoteBridgeForWindow(win) {
5353
return;
5454
}
5555
});
56-
}
56+
});
5757

5858
export function openTunnelToOpener() {
5959
return Promise.try(() => {
@@ -70,7 +70,7 @@ export function openTunnelToOpener() {
7070

7171
registerRemoteWindow(opener);
7272

73-
return getRemoteBridgeForWindow(opener).then(bridge => {
73+
return awaitRemoteBridgeForWindow(opener).then(bridge => {
7474

7575
if (!bridge) {
7676
return rejectRemoteSendMessage(opener, new Error(`Can not register with opener: no bridge found in opener`));

src/bridge/common.js

+5-8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11

2+
import { WeakMap } from 'cross-domain-safe-weakmap/src';
3+
24
import { CONFIG, CONSTANTS } from '../conf';
35
import { util, promise, isSameDomain, isOpener, isSameTopWindow, getUserAgent, matchDomain } from '../lib';
46
import { global } from '../global';
@@ -72,19 +74,14 @@ export let documentBodyReady = new promise.Promise(resolve => {
7274
}, 10);
7375
});
7476

75-
global.remoteWindows = global.remoteWindows || [];
77+
global.remoteWindows = global.remoteWindows || new WeakMap();
7678

7779
export function registerRemoteWindow(win, timeout = CONFIG.BRIDGE_TIMEOUT) {
78-
let sendMessagePromise = new promise.Promise();
79-
global.clean.push(global.remoteWindows, { win, sendMessagePromise });
80+
global.clean.setItem(global.remoteWindows, win, { sendMessagePromise: new promise.Promise() });
8081
}
8182

8283
export function findRemoteWindow(win) {
83-
for (let i = 0; i < global.remoteWindows.length; i++) {
84-
if (global.remoteWindows[i].win === win) {
85-
return global.remoteWindows[i];
86-
}
87-
}
84+
return global.remoteWindows.get(win);
8885
}
8986

9087
export function registerRemoteSendMessage(win, domain, sendMessage) {

src/bridge/parent.js

+14-14
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11

2+
import { WeakMap } from 'cross-domain-safe-weakmap/src';
3+
24
import { CONFIG, CONSTANTS } from '../conf';
35
import { util, promise, log, onWindowReady, getFrameByName } from '../lib';
46
import { global } from '../global';
57
import { on } from '../interface';
68
import { receiveMessage } from '../drivers';
79

10+
import { getBridgeName, documentBodyReady, registerRemoteSendMessage, registerRemoteWindow } from './common';
11+
812
global.bridges = global.bridges || {};
913

10-
import { getBridgeName, documentBodyReady, registerRemoteSendMessage, registerRemoteWindow } from './common';
14+
global.popupWindowsByWin = global.popupWindowsByWin || new WeakMap();
15+
global.popupWindowsByName = global.popupWindowsByName || {};
1116

1217
function listenForRegister(source, domain) {
1318
on(CONSTANTS.POST_MESSAGE_NAMES.OPEN_TUNNEL, { source, domain }, ({ origin, data }) => {
@@ -24,7 +29,7 @@ function listenForRegister(source, domain) {
2429
throw new Error(`Register window expected to be passed sendMessage method`);
2530
}
2631

27-
let winDetails = global.popupWindows[data.name];
32+
let winDetails = global.popupWindowsByName[data.name];
2833

2934
if (!winDetails) {
3035
throw new Error(`Window with name ${data.name} does not exist, or was not opened by this window`);
@@ -146,8 +151,6 @@ export function destroyBridges() {
146151
return global.clean.run('bridgeFrames');
147152
}
148153

149-
global.popupWindows = global.popupWindows || {};
150-
151154
let windowOpen = window.open;
152155

153156
window.open = function(url, name, options, last) {
@@ -169,23 +172,20 @@ window.open = function(url, name, options, last) {
169172
}
170173

171174
if (name) {
172-
global.clean.setItem(global.popupWindows, name, { win, domain });
175+
let winOptions = { name, domain, win };
176+
global.clean.setItem(global.popupWindowsByWin, win, winOptions);
177+
global.clean.setItem(global.popupWindowsByName, name, winOptions);
173178
}
174179

175180
return win;
176181
};
177182

178183
export function linkUrl(win, url) {
179184

180-
for (let name of Object.keys(global.popupWindows)) {
181-
let winOptions = global.popupWindows[name];
185+
let winOptions = global.popupWindowsByWin.get(win);
182186

183-
if (winOptions.win === win) {
184-
winOptions.domain = util.getDomainFromUrl(url);
185-
186-
registerRemoteWindow(win);
187-
188-
break;
189-
}
187+
if (winOptions) {
188+
winOptions.domain = util.getDomainFromUrl(url);
189+
registerRemoteWindow(win);
190190
}
191191
}

0 commit comments

Comments
 (0)