summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/src/components/SecondaryPanes/WhyPaused.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /devtools/client/debugger/src/components/SecondaryPanes/WhyPaused.js
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'devtools/client/debugger/src/components/SecondaryPanes/WhyPaused.js')
-rw-r--r--devtools/client/debugger/src/components/SecondaryPanes/WhyPaused.js173
1 files changed, 173 insertions, 0 deletions
diff --git a/devtools/client/debugger/src/components/SecondaryPanes/WhyPaused.js b/devtools/client/debugger/src/components/SecondaryPanes/WhyPaused.js
new file mode 100644
index 0000000000..9371483621
--- /dev/null
+++ b/devtools/client/debugger/src/components/SecondaryPanes/WhyPaused.js
@@ -0,0 +1,173 @@
+/* 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/>. */
+
+// @flow
+import React, { PureComponent } from "react";
+import { connect } from "../../utils/connect";
+import AccessibleImage from "../shared/AccessibleImage";
+import actions from "../../actions";
+
+// $FlowIgnore
+import Reps from "devtools/client/shared/components/reps/index";
+const {
+ REPS: { Rep },
+ MODE,
+} = Reps;
+
+import { getPauseReason } from "../../utils/pause";
+import {
+ getCurrentThread,
+ getPaneCollapse,
+ getPauseReason as getWhy,
+} from "../../selectors";
+import type { Grip, Why } from "../../types";
+
+import "./WhyPaused.css";
+
+type OwnProps = {|
+ +delay?: number,
+|};
+type Props = {
+ endPanelCollapsed: boolean,
+ +delay: ?number,
+ why: ?Why,
+ openElementInInspector: typeof actions.openElementInInspectorCommand,
+ highlightDomElement: typeof actions.highlightDomElement,
+ unHighlightDomElement: typeof actions.unHighlightDomElement,
+};
+
+type State = {
+ hideWhyPaused: string,
+};
+
+class WhyPaused extends PureComponent<Props, State> {
+ constructor(props: Props) {
+ super(props);
+ this.state = { hideWhyPaused: "" };
+ }
+
+ componentDidUpdate() {
+ const { delay } = this.props;
+
+ if (delay) {
+ setTimeout(() => {
+ this.setState({ hideWhyPaused: "" });
+ }, delay);
+ } else {
+ this.setState({ hideWhyPaused: "pane why-paused" });
+ }
+ }
+
+ renderExceptionSummary(exception: string | Grip) {
+ if (typeof exception === "string") {
+ return exception;
+ }
+
+ const { preview } = exception;
+ if (!preview || !preview.name || !preview.message) {
+ return;
+ }
+
+ return `${preview.name}: ${preview.message}`;
+ }
+
+ renderMessage(why: Why) {
+ const { type, exception, message } = why;
+
+ if (type == "exception" && exception) {
+ // Our types for 'Why' are too general because 'type' can be 'string'.
+ // $FlowFixMe - We should have a proper discriminating union of reasons.
+ const summary = this.renderExceptionSummary(exception);
+ return <div className="message warning">{summary}</div>;
+ }
+
+ if (type === "mutationBreakpoint" && why.nodeGrip) {
+ const { nodeGrip, ancestorGrip, action } = why;
+ const {
+ openElementInInspector,
+ highlightDomElement,
+ unHighlightDomElement,
+ } = this.props;
+
+ const targetRep = Rep({
+ object: nodeGrip,
+ mode: MODE.TINY,
+ onDOMNodeClick: () => openElementInInspector(nodeGrip),
+ onInspectIconClick: () => openElementInInspector(nodeGrip),
+ onDOMNodeMouseOver: () => highlightDomElement(nodeGrip),
+ onDOMNodeMouseOut: () => unHighlightDomElement(),
+ });
+
+ const ancestorRep = ancestorGrip
+ ? Rep({
+ object: ancestorGrip,
+ mode: MODE.TINY,
+ onDOMNodeClick: () => openElementInInspector(ancestorGrip),
+ onInspectIconClick: () => openElementInInspector(ancestorGrip),
+ onDOMNodeMouseOver: () => highlightDomElement(ancestorGrip),
+ onDOMNodeMouseOut: () => unHighlightDomElement(),
+ })
+ : null;
+
+ return (
+ <div>
+ <div className="message">{why.message}</div>
+ <div className="mutationNode">
+ {ancestorRep}
+ {ancestorGrip ? (
+ <span className="why-paused-ancestor">
+ {action === "remove"
+ ? L10N.getStr("whyPaused.mutationBreakpointRemoved")
+ : L10N.getStr("whyPaused.mutationBreakpointAdded")}
+ {targetRep}
+ </span>
+ ) : (
+ targetRep
+ )}
+ </div>
+ </div>
+ );
+ }
+
+ if (typeof message == "string") {
+ return <div className="message">{message}</div>;
+ }
+
+ return null;
+ }
+
+ render() {
+ const { endPanelCollapsed, why } = this.props;
+ const reason = getPauseReason(why);
+
+ if (!why || !reason || endPanelCollapsed) {
+ return <div className={this.state.hideWhyPaused} />;
+ }
+
+ return (
+ <div className="pane why-paused">
+ <div>
+ <div className="info icon">
+ <AccessibleImage className="info" />
+ </div>
+ <div className="pause reason">
+ {L10N.getStr(reason)}
+ {this.renderMessage(why)}
+ </div>
+ </div>
+ </div>
+ );
+ }
+}
+
+const mapStateToProps = state => ({
+ endPanelCollapsed: getPaneCollapse(state, "end"),
+ why: getWhy(state, getCurrentThread(state)),
+});
+
+export default connect<Props, OwnProps, _, _, _, _>(mapStateToProps, {
+ openElementInInspector: actions.openElementInInspectorCommand,
+ highlightDomElement: actions.highlightDomElement,
+ unHighlightDomElement: actions.unHighlightDomElement,
+})(WhyPaused);