Group.js (5017B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */ 4 5 import React, { Component } from "devtools/client/shared/vendor/react"; 6 import PropTypes from "devtools/client/shared/vendor/react-prop-types"; 7 8 import { getLibraryFromUrl } from "../../../utils/pause/frames/index"; 9 10 import DebuggerImage from "../../shared/DebuggerImage"; 11 import FrameComponent from "./Frame"; 12 import Badge from "../../shared/Badge"; 13 import FrameIndent from "./FrameIndent"; 14 15 const classnames = require("resource://devtools/client/shared/classnames.js"); 16 17 function FrameLocation({ frame, expanded }) { 18 const library = frame.library || getLibraryFromUrl(frame); 19 if (!library) { 20 return null; 21 } 22 return React.createElement( 23 "span", 24 { 25 className: "group-description", 26 }, 27 React.createElement(DebuggerImage, { 28 name: "arrow", 29 className: classnames({ 30 expanded, 31 }), 32 }), 33 React.createElement(DebuggerImage, { 34 name: library.toLowerCase(), 35 className: "annotation-logo", 36 }), 37 React.createElement( 38 "span", 39 { 40 className: "group-description-name", 41 }, 42 library 43 ) 44 ); 45 } 46 47 FrameLocation.propTypes = { 48 expanded: PropTypes.any.isRequired, 49 frame: PropTypes.object.isRequired, 50 }; 51 52 FrameLocation.displayName = "FrameLocation"; 53 54 export default class Group extends Component { 55 constructor(...args) { 56 super(...args); 57 } 58 59 static get propTypes() { 60 return { 61 disableContextMenu: PropTypes.bool.isRequired, 62 displayFullUrl: PropTypes.bool.isRequired, 63 getFrameTitle: PropTypes.func, 64 group: PropTypes.array.isRequired, 65 groupTitle: PropTypes.string.isRequired, 66 groupId: PropTypes.string.isRequired, 67 expanded: PropTypes.bool.isRequired, 68 frameIndex: PropTypes.number.isRequired, 69 panel: PropTypes.oneOf(["debugger", "webconsole"]).isRequired, 70 selectFrame: PropTypes.func.isRequired, 71 selectLocation: PropTypes.func, 72 selectedFrame: PropTypes.object, 73 isTracerFrameSelected: PropTypes.bool.isRequired, 74 showFrameContextMenu: PropTypes.func.isRequired, 75 }; 76 } 77 78 get isSelectable() { 79 return this.props.panel == "webconsole"; 80 } 81 82 onContextMenu(event) { 83 const { group } = this.props; 84 const frame = group[0]; 85 this.props.showFrameContextMenu(event, frame, true); 86 } 87 88 renderFrames() { 89 const { 90 group, 91 groupId, 92 selectFrame, 93 selectLocation, 94 selectedFrame, 95 isTracerFrameSelected, 96 displayFullUrl, 97 getFrameTitle, 98 disableContextMenu, 99 panel, 100 showFrameContextMenu, 101 expanded, 102 } = this.props; 103 104 if (!expanded) { 105 return null; 106 } 107 108 return React.createElement( 109 "div", 110 { 111 className: "frames-list", 112 role: "listbox", 113 "aria-labelledby": groupId, 114 }, 115 group.map((frame, index) => 116 React.createElement(FrameComponent, { 117 frame, 118 frameIndex: index, 119 showFrameContextMenu, 120 hideLocation: true, 121 selectedFrame, 122 isTracerFrameSelected, 123 selectFrame, 124 selectLocation, 125 shouldMapDisplayName: false, 126 displayFullUrl, 127 getFrameTitle, 128 disableContextMenu, 129 panel, 130 isInGroup: true, 131 }) 132 ) 133 ); 134 } 135 136 render() { 137 const { l10n } = this.context; 138 const { group, groupTitle, groupId, expanded, selectedFrame } = this.props; 139 140 const isGroupFrameSelected = group.some( 141 frame => frame.id == selectedFrame?.id 142 ); 143 144 let l10NEntry; 145 if (expanded) { 146 if (isGroupFrameSelected) { 147 l10NEntry = "callStack.group.collapseTooltipWithSelectedFrame"; 148 } else { 149 l10NEntry = "callStack.group.collapseTooltip"; 150 } 151 } else { 152 l10NEntry = "callStack.group.expandTooltip"; 153 } 154 155 const title = l10n.getFormatStr(l10NEntry, groupTitle); 156 157 return React.createElement( 158 React.Fragment, 159 null, 160 React.createElement( 161 "div", 162 { 163 className: classnames("frames-group frame", { 164 expanded, 165 }), 166 id: groupId, 167 tabIndex: -1, 168 role: "presentation", 169 onClick: this.toggleFrames, 170 title, 171 }, 172 this.isSelectable && React.createElement(FrameIndent, null), 173 React.createElement(FrameLocation, { 174 frame: group[0], 175 expanded, 176 }), 177 this.isSelectable && 178 React.createElement("span", { className: "clipboard-only" }, " "), 179 React.createElement(Badge, { badgeText: this.props.group.length }), 180 this.isSelectable && 181 React.createElement("br", { 182 className: "clipboard-only", 183 }) 184 ), 185 this.renderFrames() 186 ); 187 } 188 } 189 190 Group.displayName = "Group"; 191 Group.contextTypes = { l10n: PropTypes.object };