/* 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 . */
import React, { Component } from "react";
import { connect } from "../../../utils/connect";
import PropTypes from "prop-types";
import FrameComponent from "./Frame";
import Group from "./Group";
import actions from "../../../actions";
import { collapseFrames, formatCopyName } from "../../../utils/pause/frames";
import { copyToTheClipboard } from "../../../utils/clipboard";
import {
getFrameworkGroupingState,
getSelectedFrame,
getCallStackFrames,
getCurrentThread,
getThreadContext,
} from "../../../selectors";
import "./Frames.css";
const NUM_FRAMES_SHOWN = 7;
class Frames extends Component {
constructor(props) {
super(props);
this.state = {
showAllFrames: !!props.disableFrameTruncate,
};
}
static get propTypes() {
return {
cx: PropTypes.object,
disableContextMenu: PropTypes.bool.isRequired,
disableFrameTruncate: PropTypes.bool.isRequired,
displayFullUrl: PropTypes.bool.isRequired,
frames: PropTypes.array.isRequired,
frameworkGroupingOn: PropTypes.bool.isRequired,
getFrameTitle: PropTypes.func,
panel: PropTypes.oneOf(["debugger", "webconsole"]).isRequired,
restart: PropTypes.func,
selectFrame: PropTypes.func.isRequired,
selectLocation: PropTypes.func,
selectedFrame: PropTypes.object,
toggleBlackBox: PropTypes.func,
toggleFrameworkGrouping: PropTypes.func,
};
}
shouldComponentUpdate(nextProps, nextState) {
const { frames, selectedFrame, frameworkGroupingOn } = this.props;
const { showAllFrames } = this.state;
return (
frames !== nextProps.frames ||
selectedFrame !== nextProps.selectedFrame ||
showAllFrames !== nextState.showAllFrames ||
frameworkGroupingOn !== nextProps.frameworkGroupingOn
);
}
toggleFramesDisplay = () => {
this.setState(prevState => ({
showAllFrames: !prevState.showAllFrames,
}));
};
collapseFrames(frames) {
const { frameworkGroupingOn } = this.props;
if (!frameworkGroupingOn) {
return frames;
}
return collapseFrames(frames);
}
truncateFrames(frames) {
const numFramesToShow = this.state.showAllFrames
? frames.length
: NUM_FRAMES_SHOWN;
return frames.slice(0, numFramesToShow);
}
copyStackTrace = () => {
const { frames } = this.props;
const { l10n } = this.context;
const framesToCopy = frames.map(f => formatCopyName(f, l10n)).join("\n");
copyToTheClipboard(framesToCopy);
};
toggleFrameworkGrouping = () => {
const { toggleFrameworkGrouping, frameworkGroupingOn } = this.props;
toggleFrameworkGrouping(!frameworkGroupingOn);
};
renderFrames(frames) {
const {
cx,
selectFrame,
selectLocation,
selectedFrame,
toggleBlackBox,
frameworkGroupingOn,
displayFullUrl,
getFrameTitle,
disableContextMenu,
panel,
restart,
} = this.props;
const framesOrGroups = this.truncateFrames(this.collapseFrames(frames));
// We're not using a
because it adds new lines before and after when
// the user copies the trace. Needed for the console which has several
// places where we don't want to have those new lines.
return (