diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /devtools/client/debugger/src/components/Editor/Preview/ExceptionPopup.js | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/debugger/src/components/Editor/Preview/ExceptionPopup.js')
-rw-r--r-- | devtools/client/debugger/src/components/Editor/Preview/ExceptionPopup.js | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/components/Editor/Preview/ExceptionPopup.js b/devtools/client/debugger/src/components/Editor/Preview/ExceptionPopup.js new file mode 100644 index 0000000000..0789b82694 --- /dev/null +++ b/devtools/client/debugger/src/components/Editor/Preview/ExceptionPopup.js @@ -0,0 +1,142 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ + +import React, { Component } from "devtools/client/shared/vendor/react"; +import { div, span } from "devtools/client/shared/vendor/react-dom-factories"; +import PropTypes from "devtools/client/shared/vendor/react-prop-types"; +import { connect } from "devtools/client/shared/vendor/react-redux"; + +import Reps from "devtools/client/shared/components/reps/index"; +const { + REPS: { StringRep }, +} = Reps; + +import actions from "../../../actions/index"; + +import AccessibleImage from "../../shared/AccessibleImage"; +const classnames = require("resource://devtools/client/shared/classnames.js"); +const ANONYMOUS_FN_NAME = "<anonymous>"; + +// The exception popup works in two modes: +// a. when the stacktrace is closed the exception popup +// gets closed when the mouse leaves the popup. +// b. when the stacktrace is opened the exception popup +// gets closed only by clicking outside the popup. +class ExceptionPopup extends Component { + constructor(props) { + super(props); + this.state = { + isStacktraceExpanded: true, + }; + } + + static get propTypes() { + return { + mouseout: PropTypes.func.isRequired, + selectSourceURL: PropTypes.func.isRequired, + exception: PropTypes.object.isRequired, + }; + } + + onExceptionMessageClick() { + const isStacktraceExpanded = this.state.isStacktraceExpanded; + this.setState({ isStacktraceExpanded: !isStacktraceExpanded }); + } + + buildStackFrame(frame) { + const { filename, lineNumber } = frame; + const functionName = frame.functionName || ANONYMOUS_FN_NAME; + return div( + { + className: "frame", + onClick: () => + this.props.selectSourceURL(filename, { + line: lineNumber, + }), + }, + span( + { + className: "title", + }, + functionName + ), + span( + { + className: "location", + }, + span( + { + className: "filename", + }, + filename + ), + ":", + span( + { + className: "line", + }, + lineNumber + ) + ) + ); + } + + renderStacktrace(stacktrace) { + const isStacktraceExpanded = this.state.isStacktraceExpanded; + + if (stacktrace.length && isStacktraceExpanded) { + return div( + { + className: "exception-stacktrace", + }, + stacktrace.map(frame => this.buildStackFrame(frame)) + ); + } + return null; + } + + renderArrowIcon(stacktrace) { + if (stacktrace.length) { + return React.createElement(AccessibleImage, { + className: classnames("arrow", { + expanded: this.state.isStacktraceExpanded, + }), + }); + } + return null; + } + + render() { + const { + exception: { stacktrace, errorMessage }, + mouseout, + } = this.props; + return div( + { + className: "preview-popup exception-popup", + dir: "ltr", + onMouseLeave: () => mouseout(true, this.state.isStacktraceExpanded), + }, + div( + { + className: "exception-message", + onClick: () => this.onExceptionMessageClick(), + }, + this.renderArrowIcon(stacktrace), + StringRep.rep({ + object: errorMessage, + useQuotes: false, + className: "exception-text", + }) + ), + this.renderStacktrace(stacktrace) + ); + } +} + +const mapDispatchToProps = { + selectSourceURL: actions.selectSourceURL, +}; + +export default connect(null, mapDispatchToProps)(ExceptionPopup); |