Files
create-react-app/packages/react-error-overlay/src/containers/StackFrame.js
Ade Viankakrisna Fadlil 44cfbccfda Rerun prettier and pin version (#3058)
* rerun prettier for all files

* pin prettier to 1.6.1
2017-09-10 01:12:38 -04:00

188 lines
4.5 KiB
JavaScript

/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
/* @flow */
import React, { Component } from 'react';
import CodeBlock from './StackFrameCodeBlock';
import { getPrettyURL } from '../utils/getPrettyURL';
import { darkGray } from '../styles';
const linkStyle = {
fontSize: '0.9em',
marginBottom: '0.9em',
};
const anchorStyle = {
textDecoration: 'none',
color: darkGray,
cursor: 'pointer',
};
const codeAnchorStyle = {
cursor: 'pointer',
};
const toggleStyle = {
marginBottom: '1.5em',
color: darkGray,
cursor: 'pointer',
border: 'none',
display: 'block',
width: '100%',
textAlign: 'left',
background: '#fff',
fontFamily: 'Consolas, Menlo, monospace',
fontSize: '1em',
padding: '0px',
lineHeight: '1.5',
};
class StackFrame extends Component {
state = {
compiled: false,
};
toggleCompiled = () => {
this.setState(state => ({
compiled: !state.compiled,
}));
};
canOpenInEditor() {
if (!this.props.launchEditorEndpoint) {
return;
}
const { _originalFileName: sourceFileName } = this.props.frame;
// Unknown file
if (!sourceFileName) {
return false;
}
// e.g. "/path-to-my-app/webpack/bootstrap eaddeb46b67d75e4dfc1"
const isInternalWebpackBootstrapCode =
sourceFileName.trim().indexOf(' ') !== -1;
if (isInternalWebpackBootstrapCode) {
return false;
}
// Code is in a real file
return true;
}
openInEditor = () => {
if (!this.canOpenInEditor()) {
return;
}
const {
_originalFileName: sourceFileName,
_originalLineNumber: sourceLineNumber,
} = this.props.frame;
// Keep this in sync with react-error-overlay/middleware.js
fetch(
`${this.props.launchEditorEndpoint}?fileName=` +
window.encodeURIComponent(sourceFileName) +
'&lineNumber=' +
window.encodeURIComponent(sourceLineNumber || 1)
).then(() => {}, () => {});
};
onKeyDown = (e: SyntheticKeyboardEvent) => {
if (e.key === 'Enter') {
this.openInEditor();
}
};
render() {
const { frame, contextSize, critical, showCode } = this.props;
const {
fileName,
lineNumber,
columnNumber,
_scriptCode: scriptLines,
_originalFileName: sourceFileName,
_originalLineNumber: sourceLineNumber,
_originalColumnNumber: sourceColumnNumber,
_originalScriptCode: sourceLines,
} = frame;
const functionName = frame.getFunctionName();
const compiled = this.state.compiled;
const url = getPrettyURL(
sourceFileName,
sourceLineNumber,
sourceColumnNumber,
fileName,
lineNumber,
columnNumber,
compiled
);
let codeBlockProps = null;
if (showCode) {
if (
compiled &&
scriptLines &&
scriptLines.length !== 0 &&
lineNumber != null
) {
codeBlockProps = {
lines: scriptLines,
lineNum: lineNumber,
columnNum: columnNumber,
contextSize,
main: critical,
};
} else if (
!compiled &&
sourceLines &&
sourceLines.length !== 0 &&
sourceLineNumber != null
) {
codeBlockProps = {
lines: sourceLines,
lineNum: sourceLineNumber,
columnNum: sourceColumnNumber,
contextSize,
main: critical,
};
}
}
const canOpenInEditor = this.canOpenInEditor();
return (
<div>
<div>{functionName}</div>
<div style={linkStyle}>
<a
style={canOpenInEditor ? anchorStyle : null}
onClick={canOpenInEditor ? this.openInEditor : null}
onKeyDown={canOpenInEditor ? this.onKeyDown : null}
tabIndex={canOpenInEditor ? '0' : null}
>
{url}
</a>
</div>
{codeBlockProps && (
<span>
<a
onClick={canOpenInEditor ? this.openInEditor : null}
style={canOpenInEditor ? codeAnchorStyle : null}
>
<CodeBlock {...codeBlockProps} />
</a>
<button style={toggleStyle} onClick={this.toggleCompiled}>
{'View ' + (compiled ? 'source' : 'compiled')}
</button>
</span>
)}
</div>
);
}
}
export default StackFrame;