@samitouri / QOS-React-1 / commits / bc6184dd99

[devtools] Fix "View source" for sources with URLs that aren't normalized (#32951)

Sebastian "Sebbie" Silbermann committed Apr 17, 2025 at 21:56 UTC bc6184dd993e6ea0efdee7553293676db774c3ca
4 files changed +20 -9
packages/react-devtools-extensions/src/main/fetchFileWithCaching.js
+2 -2
@@ -1,6 +1,6 @@
1 /* global chrome */
2
3 -import {normalizeUrl} from 'react-devtools-shared/src/utils';
3 +import {normalizeUrlIfValid} from 'react-devtools-shared/src/utils';
4 import {__DEBUG__} from 'react-devtools-shared/src/constants';
5
6 let debugIDCounter = 0;
@@ -117,7 +117,7 @@ async function fetchFileWithCaching(url: string): Promise<string> {
117 chrome.devtools.inspectedWindow.getResources(r => resolve(r)),
118 );
119
120 - const normalizedReferenceURL = normalizeUrl(url);
120 + const normalizedReferenceURL = normalizeUrlIfValid(url);
121 const resource = resources.find(r => r.url === normalizedReferenceURL);
122
123 if (resource != null) {
packages/react-devtools-extensions/src/main/index.js
+6 -1
@@ -16,6 +16,7 @@ import {
16 LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY,
17 } from 'react-devtools-shared/src/constants';
18 import {logEvent} from 'react-devtools-shared/src/Logger';
19 +import {normalizeUrlIfValid} from 'react-devtools-shared/src/utils';
20
21 import {
22 setBrowserSelectionFromReact,
@@ -128,7 +129,11 @@ function createBridgeAndStore() {
129 : source;
130
131 // We use 1-based line and column, Chrome expects them 0-based.
131 - chrome.devtools.panels.openResource(sourceURL, line - 1, column - 1);
132 + chrome.devtools.panels.openResource(
133 + normalizeUrlIfValid(sourceURL),
134 + line - 1,
135 + column - 1,
136 + );
137 };
138
139 // TODO (Webpack 5) Hopefully we can remove this prop after the Webpack 5 migration.
packages/react-devtools-shared/src/symbolicateSource.js
+1 -3
@@ -7,7 +7,6 @@
7 * @flow
8 */
9
10 -import {normalizeUrl} from 'react-devtools-shared/src/utils';
10 import SourceMapConsumer from 'react-devtools-shared/src/hooks/SourceMapConsumer';
11
12 import type {Source} from 'react-devtools-shared/src/shared/types';
@@ -91,9 +90,8 @@ export async function symbolicateSource(
90 try {
91 // sourceMapURL = https://react.dev/script.js.map
92 void new URL(possiblyURL); // test if it is a valid URL
94 - const normalizedURL = normalizeUrl(possiblyURL);
93
96 - return {sourceURL: normalizedURL, line, column};
94 + return {sourceURL: possiblyURL, line, column};
95 } catch (e) {
96 // This is not valid URL
97 if (
packages/react-devtools-shared/src/utils.js
+11 -3
@@ -996,9 +996,17 @@ export function backendToFrontendSerializedElementMapper(
996 };
997 }
998
999 -// Chrome normalizes urls like webpack-internals:// but new URL don't, so cannot use new URL here.
1000 -export function normalizeUrl(url: string): string {
1001 - return url.replace('/./', '/');
999 +/**
1000 + * Should be used when treating url as a Chrome Resource URL.
1001 + */
1002 +export function normalizeUrlIfValid(url: string): string {
1003 + try {
1004 + // TODO: Chrome will use the basepath to create a Resource URL.
1005 + return new URL(url).toString();
1006 + } catch {
1007 + // Giving up if it's not a valid URL without basepath
1008 + return url;
1009 + }
1010 }
1011
1012 export function getIsReloadAndProfileSupported(): boolean {