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 444e070c37e..3c96c2bf2cf 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 0f7203b12a7..1ca2fc917bb 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); - if (symbolicatedSource == null) { - const {sourceURL, line} = source; - return ( -
- {formatSourceForDisplay(sourceURL, line)} -
- ); - } + 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]); - const {sourceURL, line} = symbolicatedSource; + let sourceURL, line; + if (symbolicatedSource == null) { + sourceURL = source.sourceURL; + line = source.line; + } else { + sourceURL = symbolicatedSource.sourceURL; + line = symbolicatedSource.line; + } return (
- {formatSourceForDisplay(sourceURL, line)} + {linkIsEnabled ? ( + + {formatSourceForDisplay(sourceURL, line)} + + ) : ( + formatSourceForDisplay(sourceURL, line) + )}
); }