react-native-macos/Libraries/LogBox/UI/LogBoxInspectorReactFrames.js

187 строки
5.5 KiB
JavaScript
Исходник Ответственный История

Этот файл содержит невидимые символы Юникода!

Этот файл содержит невидимые символы Юникода, которые могут быть отображены не так, как показано ниже. Если это намеренно, можете спокойно проигнорировать это предупреждение. Используйте кнопку Экранировать, чтобы показать скрытые символы.

/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow strict-local
* @format
*/
'use strict';
import * as React from 'react';
import StyleSheet from '../../StyleSheet/StyleSheet';
import Platform from '../../Utilities/Platform';
import Text from '../../Text/Text';
import View from '../../Components/View/View';
import LogBoxButton from './LogBoxButton';
import * as LogBoxStyle from './LogBoxStyle';
import LogBoxInspectorSection from './LogBoxInspectorSection';
import openFileInEditor from '../../Core/Devtools/openFileInEditor';
import type LogBoxLog from '../Data/LogBoxLog';
type Props = $ReadOnly<{|
log: LogBoxLog,
|}>;
const BEFORE_SLASH_RE = /^(.*)[\\/]/;
// Taken from React https://github.com/facebook/react/blob/206d61f72214e8ae5b935f0bf8628491cb7f0797/packages/react-devtools-shared/src/backend/describeComponentFrame.js#L27-L41
function getPrettyFileName(path) {
let fileName = path.replace(BEFORE_SLASH_RE, '');
// In DEV, include code for a common special case:
// prefer "folder/index.js" instead of just "index.js".
if (/^index\./.test(fileName)) {
const match = path.match(BEFORE_SLASH_RE);
if (match) {
const pathBeforeSlash = match[1];
if (pathBeforeSlash) {
const folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
// Note the below string contains a zero width space after the "/" character.
// This is to prevent browsers like Chrome from formatting the file name as a link.
// (Since this is a source link, it would not work to open the source file anyway.)
fileName = folderName + '/' + fileName;
}
}
}
return fileName;
}
function LogBoxInspectorReactFrames(props: Props): React.Node {
const [collapsed, setCollapsed] = React.useState(true);
if (props.log.componentStack == null || props.log.componentStack.length < 1) {
return null;
}
function getStackList() {
if (collapsed) {
return props.log.componentStack.slice(0, 3);
} else {
return props.log.componentStack;
}
}
function getCollapseMessage() {
if (props.log.componentStack.length <= 3) {
return;
}
const count = props.log.componentStack.length - 3;
if (collapsed) {
return `See ${count} more components`;
} else {
return `Collapse ${count} components`;
}
}
return (
<LogBoxInspectorSection heading="Component Stack">
{getStackList().map((frame, index) => (
<View
// Unfortunately we don't have a unique identifier for stack traces.
key={index}
style={componentStyles.frameContainer}>
<LogBoxButton
backgroundColor={{
default: 'transparent',
pressed: LogBoxStyle.getBackgroundColor(1),
}}
onPress={
// Older versions of DevTools do not provide full path.
// This will not work on Windows, remove check once the
// DevTools return the full file path.
frame.fileName.startsWith('/')
? () =>
openFileInEditor(frame.fileName, frame.location?.row ?? 1)
: null
}
style={componentStyles.frame}>
<View style={componentStyles.component}>
<Text style={componentStyles.frameName}>
<Text style={componentStyles.bracket}>{'<'}</Text>
{frame.content}
<Text style={componentStyles.bracket}>{' />'}</Text>
</Text>
</View>
<Text style={componentStyles.frameLocation}>
{getPrettyFileName(frame.fileName)}
{frame.location ? `:${frame.location.row}` : ''}
</Text>
</LogBoxButton>
</View>
))}
<View style={componentStyles.collapseContainer}>
<LogBoxButton
backgroundColor={{
default: 'transparent',
pressed: LogBoxStyle.getBackgroundColor(1),
}}
onPress={() => setCollapsed(!collapsed)}
style={componentStyles.collapseButton}>
<Text style={componentStyles.collapse}>{getCollapseMessage()}</Text>
</LogBoxButton>
</View>
</LogBoxInspectorSection>
);
}
const componentStyles = StyleSheet.create({
collapseContainer: {
marginLeft: 15,
flexDirection: 'row',
},
collapseButton: {
borderRadius: 5,
},
collapse: {
color: LogBoxStyle.getTextColor(0.7),
fontSize: 12,
fontWeight: '300',
lineHeight: 20,
marginTop: 0,
paddingVertical: 5,
paddingHorizontal: 10,
},
frameContainer: {
flexDirection: 'row',
paddingHorizontal: 15,
},
frame: {
flex: 1,
paddingVertical: 4,
paddingHorizontal: 10,
borderRadius: 5,
},
component: {
flexDirection: 'row',
paddingRight: 10,
},
frameName: {
fontFamily: Platform.select({android: 'monospace', ios: 'Menlo'}),
color: LogBoxStyle.getTextColor(1),
fontSize: 14,
includeFontPadding: false,
lineHeight: 18,
},
bracket: {
fontFamily: Platform.select({android: 'monospace', ios: 'Menlo'}),
color: LogBoxStyle.getTextColor(0.4),
fontSize: 14,
fontWeight: '500',
includeFontPadding: false,
lineHeight: 18,
},
frameLocation: {
color: LogBoxStyle.getTextColor(0.7),
fontSize: 12,
fontWeight: '300',
includeFontPadding: false,
lineHeight: 16,
paddingLeft: 10,
},
});
export default LogBoxInspectorReactFrames;