From bb4418d6470b95c7d487f3b73a9dc980edff6f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Mon, 21 Jul 2025 17:36:37 -0400 Subject: [PATCH] [DevTools] Linkify Source View (#33954) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes it so you can click the source location itself to view the source. This is similar styling as the link to jump to function props like events and actions. We're going to need a lot more linkifying to jump to various source locations. Also, I always was trying to click this file anyway. Hover state: Screenshot 2025-07-21 at 4 36 10 PM --- .../InspectedElementSourcePanel.css | 15 ++++++ .../Components/InspectedElementSourcePanel.js | 47 ++++++++++++++----- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSourcePanel.css b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSourcePanel.css index 444e070c37..3c96c2bf2c 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSourcePanel.css +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSourcePanel.css @@ -18,3 +18,18 @@ max-width: 100%; margin-left: 1rem; } + +.Link { + color: var(--color-link); + white-space: pre; + overflow: hidden; + text-overflow: ellipsis; + flex: 1; + cursor: pointer; + border-radius: 0.125rem; + padding: 0px 2px; +} + +.Link:hover { + background-color: var(--color-background-hover); +} diff --git a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSourcePanel.js b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSourcePanel.js index 0f7203b12a..1ca2fc917b 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSourcePanel.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/InspectedElementSourcePanel.js @@ -8,6 +8,7 @@ */ import * as React from 'react'; +import {useCallback, useContext} from 'react'; import {copy} from 'clipboard-js'; import {toNormalUrl} from 'jsc-safe-url'; @@ -16,6 +17,8 @@ import ButtonIcon from '../ButtonIcon'; import Skeleton from './Skeleton'; import {withPermissionsCheck} from 'react-devtools-shared/src/frontend/utils/withPermissionsCheck'; +import ViewElementSourceContext from './ViewElementSourceContext'; + import type {Source as InspectedElementSource} from 'react-devtools-shared/src/shared/types'; import styles from './InspectedElementSourcePanel.css'; @@ -87,25 +90,45 @@ function CopySourceButton({source, symbolicatedSourcePromise}: Props) { function FormattedSourceString({source, symbolicatedSourcePromise}: Props) { const symbolicatedSource = React.use(symbolicatedSourcePromise); + + const {canViewElementSourceFunction, viewElementSourceFunction} = useContext( + ViewElementSourceContext, + ); + + // In some cases (e.g. FB internal usage) the standalone shell might not be able to view the source. + // To detect this case, we defer to an injected helper function (if present). + const linkIsEnabled = + viewElementSourceFunction != null && + source != null && + (canViewElementSourceFunction == null || + canViewElementSourceFunction(source, symbolicatedSource)); + + const viewSource = useCallback(() => { + if (viewElementSourceFunction != null && source != null) { + viewElementSourceFunction(source, symbolicatedSource); + } + }, [source, symbolicatedSource]); + + let sourceURL, line; if (symbolicatedSource == null) { - const {sourceURL, line} = source; - - return ( -
- {formatSourceForDisplay(sourceURL, line)} -
- ); + sourceURL = source.sourceURL; + line = source.line; + } else { + sourceURL = symbolicatedSource.sourceURL; + line = symbolicatedSource.line; } - const {sourceURL, line} = symbolicatedSource; - return (
- {formatSourceForDisplay(sourceURL, line)} + {linkIsEnabled ? ( + + {formatSourceForDisplay(sourceURL, line)} + + ) : ( + formatSourceForDisplay(sourceURL, line) + )}
); }