Skip to content

Commit 980903c

Browse files
committed
type chrome.tabs
1 parent c892c93 commit 980903c

2 files changed

Lines changed: 88 additions & 29 deletions

File tree

packages/react-devtools-extensions/src/background/index.js

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
/* global chrome */
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
/* global chrome, ExtensionRuntimePort */
210

311
'use strict';
412

@@ -12,20 +20,19 @@ import {
1220
handleFetchResourceContentScriptMessage,
1321
} from './messageHandlers';
1422

15-
/*
16-
{
17-
[tabId]: {
18-
extension: ExtensionPort,
19-
proxy: ProxyPort,
20-
disconnectPipe: Function,
21-
},
22-
...
23-
}
24-
*/
25-
const ports = {};
26-
27-
function registerTab(tabId) {
23+
const ports: {
24+
// TODO: Check why we convert tab IDs to strings, and if we can avoid it
25+
[tabId: string]: {
26+
extension: ExtensionRuntimePort | null,
27+
proxy: ExtensionRuntimePort | null,
28+
disconnectPipe: Function | null,
29+
},
30+
} = {};
31+
32+
function registerTab(tabId: number) {
33+
// $FlowFixMe[incompatible-type]
2834
if (!ports[tabId]) {
35+
// $FlowFixMe[incompatible-type]
2936
ports[tabId] = {
3037
extension: null,
3138
proxy: null,
@@ -34,18 +41,21 @@ function registerTab(tabId) {
3441
}
3542
}
3643

37-
function registerExtensionPort(port, tabId) {
44+
function registerExtensionPort(port: ExtensionRuntimePort, tabId: number) {
45+
// $FlowFixMe[incompatible-type]
3846
ports[tabId].extension = port;
3947

4048
port.onDisconnect.addListener(() => {
4149
// This should delete disconnectPipe from ports dictionary
50+
// $FlowFixMe[incompatible-type]
4251
ports[tabId].disconnectPipe?.();
4352

44-
delete ports[tabId].extension;
53+
// $FlowFixMe[incompatible-type]
54+
ports[tabId].extension = null;
4555
});
4656
}
4757

48-
function registerProxyPort(port, tabId) {
58+
function registerProxyPort(port: ExtensionRuntimePort, tabId: string) {
4959
ports[tabId].proxy = port;
5060

5161
// In case proxy port was disconnected from the other end, from content script
@@ -54,7 +64,7 @@ function registerProxyPort(port, tabId) {
5464
port.onDisconnect.addListener(() => {
5565
ports[tabId].disconnectPipe?.();
5666

57-
delete ports[tabId].proxy;
67+
ports[tabId].proxy = null;
5868
});
5969
}
6070

@@ -73,14 +83,22 @@ chrome.runtime.onConnect.addListener(port => {
7383
// Proxy content script is executed in tab, so it should have it specified.
7484
const tabId = port.sender.tab.id;
7585

76-
if (ports[tabId]?.proxy) {
77-
ports[tabId].disconnectPipe?.();
78-
ports[tabId].proxy.disconnect();
86+
// $FlowFixMe[incompatible-type]
87+
const registeredPort = ports[tabId];
88+
const proxy = registeredPort?.proxy;
89+
if (proxy) {
90+
registeredPort.disconnectPipe?.();
91+
proxy.disconnect();
7992
}
8093

8194
registerTab(tabId);
82-
registerProxyPort(port, tabId);
95+
registerProxyPort(
96+
port,
97+
// $FlowFixMe[incompatible-call]
98+
tabId,
99+
);
83100

101+
// $FlowFixMe[incompatible-type]
84102
if (ports[tabId].extension) {
85103
connectExtensionAndProxyPorts(
86104
ports[tabId].extension,
@@ -97,8 +115,13 @@ chrome.runtime.onConnect.addListener(port => {
97115
const tabId = +port.name;
98116

99117
registerTab(tabId);
100-
registerExtensionPort(port, tabId);
118+
registerExtensionPort(
119+
port,
120+
// $FlowFixMe[incompatible-call]
121+
tabId,
122+
);
101123

124+
// $FlowFixMe[incompatible-type]
102125
if (ports[tabId].proxy) {
103126
connectExtensionAndProxyPorts(
104127
ports[tabId].extension,
@@ -114,26 +137,33 @@ chrome.runtime.onConnect.addListener(port => {
114137
console.warn(`Unknown port ${port.name} connected`);
115138
});
116139

117-
function connectExtensionAndProxyPorts(extensionPort, proxyPort, tabId) {
118-
if (!extensionPort) {
140+
function connectExtensionAndProxyPorts(
141+
maybeExtensionPort: ExtensionRuntimePort | null,
142+
maybeProxyPort: ExtensionRuntimePort | null,
143+
tabId: number,
144+
) {
145+
if (!maybeExtensionPort) {
119146
throw new Error(
120147
`Attempted to connect ports, when extension port is not present`,
121148
);
122149
}
150+
const extensionPort = maybeExtensionPort;
123151

124-
if (!proxyPort) {
152+
if (!maybeProxyPort) {
125153
throw new Error(
126154
`Attempted to connect ports, when proxy port is not present`,
127155
);
128156
}
157+
const proxyPort = maybeProxyPort;
129158

159+
// $FlowFixMe[incompatible-type]
130160
if (ports[tabId].disconnectPipe) {
131161
throw new Error(
132162
`Attempted to connect already connected ports for tab with id ${tabId}`,
133163
);
134164
}
135165

136-
function extensionPortMessageListener(message) {
166+
function extensionPortMessageListener(message: any) {
137167
try {
138168
proxyPort.postMessage(message);
139169
} catch (e) {
@@ -145,7 +175,7 @@ function connectExtensionAndProxyPorts(extensionPort, proxyPort, tabId) {
145175
}
146176
}
147177

148-
function proxyPortMessageListener(message) {
178+
function proxyPortMessageListener(message: any) {
149179
try {
150180
extensionPort.postMessage(message);
151181
} catch (e) {
@@ -164,6 +194,7 @@ function connectExtensionAndProxyPorts(extensionPort, proxyPort, tabId) {
164194
// We handle disconnect() calls manually, based on each specific case
165195
// No need to disconnect other port here
166196

197+
// $FlowFixMe[incompatible-type]
167198
delete ports[tabId].disconnectPipe;
168199
}
169200

scripts/flow/react-devtools.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,27 @@ interface ExtensionEvent<Listener: Function> {
3131
removeListener(callback: Listener): void;
3232
}
3333

34+
/** @see {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/Tab} */
35+
// TODO: Only covers used properties. Extend as needed.
36+
interface ExtensionTab {
37+
id?: number;
38+
}
39+
40+
/** @see {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/MessageSender} */
41+
// TODO: Only covers used properties. Extend as needed.
42+
interface ExtensionRuntimeSender {
43+
tab?: ExtensionTab;
44+
}
45+
3446
/** @see {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/Port} */
47+
// TODO: Only covers used properties. Extend as needed.
3548
interface ExtensionRuntimePort {
49+
disconnect(): void;
50+
name: string;
3651
onMessage: ExtensionEvent<(message: any, port: ExtensionRuntimePort) => void>;
3752
onDisconnect: ExtensionEvent<(port: ExtensionRuntimePort) => void>;
3853
postMessage(message: mixed, transferable?: Array<mixed>): void;
39-
disconnect(): void;
54+
sender?: ExtensionRuntimeSender;
4055
}
4156

4257
interface ExtensionMessageSender {
@@ -81,6 +96,17 @@ interface ExtensionRuntime {
8196
): Promise<any>;
8297
}
8398

99+
interface ExtensionTabs {
100+
/** @see {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/onActivated} */
101+
onActivated: ExtensionEvent<
102+
(activeInfo: {
103+
previousTabId: number,
104+
tabId: number,
105+
windowId: number,
106+
}) => void,
107+
>;
108+
}
109+
84110
interface ExtensionAPI {
85111
devtools: ExtensionDevtools;
86112
/** @see {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/permissions} */
@@ -91,6 +117,8 @@ interface ExtensionAPI {
91117
scripting: $FlowFixMe;
92118
/** @see {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/storage} */
93119
storage: $FlowFixMe;
120+
/** @see {@link https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs} */
121+
tabs: ExtensionTabs;
94122
}
95123

96124
declare const chrome: ExtensionAPI;

0 commit comments

Comments
 (0)