/* 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