Skip to content

Commit de95032

Browse files
committed
Use long-lived connections in order to support simultaneous instances
1 parent ce7e477 commit de95032

File tree

5 files changed

+69
-49
lines changed

5 files changed

+69
-49
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"webpack": "^1.12.2"
5454
},
5555
"dependencies": {
56-
"crossmessaging": "^0.2.0",
56+
"crossmessaging": "^0.2.1",
5757
"jsan": "^3.1.1",
5858
"react": "^0.14.6",
5959
"react-dom": "^0.14.6",

src/browser/extension/background/messaging.js

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,44 @@ import updateState from 'remotedev-app/lib/store/updateState';
33
import syncOptions from '../options/syncOptions';
44
import createMenu from './contextMenus';
55
import openDevToolsWindow from './openWindow';
6-
let connections = {};
6+
let panelConnections = {};
7+
let tabConnections = {};
78
let catchedErrors = {};
89

910
window.syncOptions = syncOptions; // Used in the options page
1011

1112
const naMessage = { type: 'NA' };
1213

13-
// Connect to devpanel
14-
onConnect((tabId) => {
15-
if (tabId !== store.id) return naMessage;
16-
return {};
17-
}, {}, connections);
14+
function initPanel(msg, port) {
15+
panelConnections[msg.tabId] = port;
16+
if (msg.tabId !== store.id) return naMessage;
17+
}
18+
19+
function initInstance(msg, port) {
20+
const id = port.sender.tab.id;
21+
tabConnections[id] = port;
22+
store.liftedStore.instances[id] = msg.instance;
23+
store.id = id;
24+
if (typeof id === 'number') chrome.pageAction.show(id);
25+
return { type: 'START' };
26+
}
27+
28+
function disconnect(port) {
29+
if (!port.sender.tab) return;
30+
const id = port.sender.tab.id;
31+
delete tabConnections[id];
32+
if (panelConnections[id]) panelConnections[id].postMessage(naMessage);
33+
if (window.store.liftedStore.instances[id]) {
34+
delete window.store.liftedStore.instances[id];
35+
window.store.liftedStore.deleteInstance(id);
36+
}
37+
}
38+
39+
onConnect(undefined, {
40+
INIT_PANEL: initPanel,
41+
INIT_INSTANCE: initInstance,
42+
RELAY: (msg, port) => { messaging(msg.message, port.sender); }
43+
}, panelConnections, disconnect);
1844

1945
function handleInstancesChanged(instance, name) {
2046
window.store.liftedStore.instances[instance] = name || instance;
@@ -24,15 +50,6 @@ function handleInstancesChanged(instance, name) {
2450
function messaging(request, sender, sendResponse) {
2551
const tabId = sender.tab ? sender.tab.id : sender.id;
2652
if (tabId) {
27-
if (request.type === 'PAGE_UNLOADED') {
28-
handleInstancesChanged(tabId, undefined, true);
29-
if (connections[tabId]) connections[tabId].postMessage(naMessage);
30-
if (window.store.liftedStore.instances[tabId]) {
31-
delete window.store.liftedStore.instances[tabId];
32-
window.store.liftedStore.deleteInstance(tabId);
33-
}
34-
return true;
35-
}
3653
if (request.type === 'GET_OPTIONS') {
3754
syncOptions.get(options => {
3855
sendResponse({options: options});
@@ -60,14 +77,9 @@ function messaging(request, sender, sendResponse) {
6077
const payload = updateState(store, request, handleInstancesChanged, store.liftedStore.instance);
6178
if (!payload) return true;
6279

63-
if (request.init) {
64-
store.id = tabId;
65-
createMenu(sender.url, tabId);
66-
}
67-
68-
// Relay the message to the devTools page
69-
if (tabId in connections) {
70-
connections[tabId].postMessage(request);
80+
// Relay the message to the devTools panel
81+
if (tabId in panelConnections) {
82+
panelConnections[tabId].postMessage(request);
7183
}
7284

7385
// Notify when errors occur in the app
@@ -107,9 +119,9 @@ export function toContentScript(action) {
107119
const message = { type: 'DISPATCH', action: action };
108120
let id = store.liftedStore.instance;
109121
if (!id || id === 'auto') id = store.id;
110-
if (id in connections) {
111-
connections[id].postMessage(message);
122+
if (id in panelConnections) {
123+
panelConnections[id].postMessage(message);
112124
} else {
113-
sendToTab(Number(id), message);
125+
tabConnections[id].postMessage(message);
114126
}
115127
}

src/browser/extension/devpanel/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ function init(id) {
5656
'source: \'redux-cs\'' +
5757
'}, \'*\');'
5858
);
59-
backgroundPageConnection.postMessage({ name: 'init', tabId: id });
59+
backgroundPageConnection.postMessage({ name: 'INIT_PANEL', tabId: id });
6060
}
6161

6262
if (chrome.devtools.inspectedWindow.tabId) {
Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,33 @@
1-
import { onMessage, sendToBg } from 'crossmessaging';
21
import { getOptionsFromBg, isAllowed } from '../options/syncOptions';
2+
let bg;
33
let payload;
4-
let sendMessage;
54

65
if (!window.devToolsOptions) getOptionsFromBg();
76

8-
// Relay background script massages to the page script
9-
onMessage((message) => {
10-
if (message.action) {
11-
window.postMessage({
12-
type: 'DISPATCH',
13-
payload: message.action,
14-
source: 'redux-cs'
15-
}, '*');
7+
function connect(instance) {
8+
// Connect to the background script
9+
if (window.devToolsExtensionID) {
10+
bg = chrome.runtime.connect(window.devToolsExtensionID);
11+
} else {
12+
bg = chrome.runtime.connect();
1613
}
17-
});
14+
bg.postMessage({name: 'INIT_INSTANCE', instance});
1815

19-
if (window.devToolsExtensionID) { // Send external messages
20-
sendMessage = function(message) {
21-
chrome.runtime.sendMessage(window.devToolsExtensionID, message);
22-
};
23-
} else {
24-
sendMessage = sendToBg;
16+
// Relay background script massages to the page script
17+
bg.onMessage.addListener((message) => {
18+
if (message.action) {
19+
window.postMessage({
20+
type: 'DISPATCH',
21+
payload: message.action,
22+
source: 'redux-cs'
23+
}, '*');
24+
} else if (message.type === 'START') {
25+
window.postMessage({
26+
type: 'START',
27+
source: 'redux-cs'
28+
}, '*');
29+
}
30+
});
2531
}
2632

2733
// Resend messages from the page to the background script
@@ -32,7 +38,9 @@ window.addEventListener('message', function(event) {
3238
if (message.source !== 'redux-page') return;
3339
if (message.payload) payload = message.payload;
3440
try {
35-
sendMessage(message);
41+
if (message.type === 'INIT_INSTANCE') {
42+
connect(message.name);
43+
} else bg.postMessage({ name: 'RELAY', message });
3644
} catch (err) {
3745
if (process.env.NODE_ENV !== 'production') console.error('Failed to send message', err);
3846
}
@@ -42,6 +50,6 @@ if (typeof window.onbeforeunload !== 'undefined') {
4250
// Prevent adding beforeunload listener for Chrome apps
4351
window.onbeforeunload = function() {
4452
if (!isAllowed()) return;
45-
sendMessage({ type: 'PAGE_UNLOADED' });
53+
bg.postMessage({ type: 'PAGE_UNLOADED' });
4654
};
4755
}

src/browser/extension/inject/pageScript.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ window.devToolsExtension = function(config = {}) {
2020
}
2121

2222
function relaySerialized(message) {
23-
message.payload = stringify(message.payload);
23+
if (message.payload) message.payload = stringify(message.payload);
2424
if (message.action !== '') message.action = stringify(message.action);
2525
window.postMessage(message, '*');
2626
}
@@ -103,7 +103,7 @@ window.devToolsExtension = function(config = {}) {
103103

104104
function init() {
105105
window.addEventListener('message', onMessage, false);
106-
relay('STATE', store.liftedStore.getState());
106+
relay('INIT_INSTANCE');
107107
notifyErrors(() => {
108108
errorOccurred = true;
109109
const state = store.liftedStore.getState();

0 commit comments

Comments
 (0)