Repository: facebook/react
Pull request: fix[react-devtools/extensions]: fixed tabs API calls and displaying restricted access popup

Stacked on https://github.com/facebook/react/pull/30824. See [this commit](https://github.com/facebook/react/pull/30825/commits/c9830d64749cf8fd592ea30a1cd65842cf83f6df).

Turns out we should be listing `tabs` in our permissions, if we want to be able to receive tab url, once its updated.
This also fixes `chrome.tabs.onCreated` event subscription, because [it should receive only tab object](https://developer.chrome.com/docs/extensions/reference/api/tabs#event-onCreated), and not 3 arguments, as expected in the previous implementation.

Changed files:
filename: packages/react-devtools-extensions/chrome/manifest.json
patch: @@ -42,7 +42,8 @@
   },
   "permissions": [
     "storage",
-    "scripting"
+    "scripting",
+    "tabs"
   ],
   "host_permissions": [
     "<all_urls>"

filename: packages/react-devtools-extensions/edge/manifest.json
patch: @@ -42,7 +42,8 @@
   },
   "permissions": [
     "storage",
-    "scripting"
+    "scripting",
+    "tabs"
   ],
   "host_permissions": [
     "<all_urls>"

filename: packages/react-devtools-extensions/firefox/manifest.json
patch: @@ -48,7 +48,8 @@
     ]
   },
   "permissions": [
-    "scripting"
+    "scripting",
+    "tabs"
   ],
   "host_permissions": [
     "<all_urls>"

filename: packages/react-devtools-extensions/src/background/tabsManager.js
patch: @@ -5,7 +5,12 @@
 import setExtensionIconAndPopup from './setExtensionIconAndPopup';
 
 function isRestrictedBrowserPage(url) {
-  return !url || new URL(url).protocol === 'chrome:';
+  if (!url) {
+    return true;
+  }
+
+  const urlProtocol = new URL(url).protocol;
+  return urlProtocol === 'chrome:' || urlProtocol === 'about:';
 }
 
 function checkAndHandleRestrictedPageIfSo(tab) {
@@ -14,16 +19,13 @@ function checkAndHandleRestrictedPageIfSo(tab) {
   }
 }
 
-// update popup page of any existing open tabs, if they are restricted browser pages.
-// we can't update for any other types (prod,dev,outdated etc)
-// as the content script needs to be injected at document_start itself for those kinds of detection
-// TODO: Show a different popup page(to reload current page probably) for old tabs, opened before the extension is installed
+// Update popup page of any existing open tabs, if they are restricted browser pages
 chrome.tabs.query({}, tabs => tabs.forEach(checkAndHandleRestrictedPageIfSo));
-chrome.tabs.onCreated.addListener((tabId, changeInfo, tab) =>
-  checkAndHandleRestrictedPageIfSo(tab),
-);
+chrome.tabs.onCreated.addListener(tab => checkAndHandleRestrictedPageIfSo(tab));
 
 // Listen to URL changes on the active tab and update the DevTools icon.
 chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
-  checkAndHandleRestrictedPageIfSo(tab);
+  if (changeInfo.url && isRestrictedBrowserPage(changeInfo.url)) {
+    setExtensionIconAndPopup('restricted', tabId);
+  }
 });

filename: packages/react-devtools-extensions/src/main/registerEventsLogger.js
patch: @@ -4,14 +4,8 @@ import {registerDevToolsEventLogger} from 'react-devtools-shared/src/registerDev
 
 function registerEventsLogger() {
   registerDevToolsEventLogger('extension', async () => {
-    // TODO: after we upgrade to Firefox Manifest V3, chrome.tabs.query returns a Promise without the callback.
-    return new Promise(resolve => {
-      chrome.tabs.query({active: true}, tabs => {
-        resolve({
-          page_url: tabs[0]?.url,
-        });
-      });
-    });
+    const tabs = await chrome.tabs.query({active: true});
+    return {page_url: tabs[0]?.url};
   });
 }