function stringifyLabel(label, id) { const sanitized = []; for (let i = 0, length = label.length; i < length; i++) { const piece = label[i]; if (isSavedFrame(piece)) { const { short } = getSourceNames(piece.source); sanitized[i] = `${piece.functionDisplayName} @ ${short}:${piece.line}:${piece.column}`; } else if (piece === NO_STACK) { sanitized[i] = L10N.getStr("tree-item.nostack"); } else if (piece === NO_FILENAME) { sanitized[i] = L10N.getStr("tree-item.nofilename"); } else if (piece === ROOT_LIST) { // Don't use the usual labeling machinery for root lists: replace it // with the "GC Roots" string. sanitized.splice(0, label.length); sanitized.push(L10N.getStr("tree-item.rootlist")); break; } else { sanitized[i] = "" + piece; } } return `${sanitized.join(" › ")} @ 0x${id.toString(16)}`; }
render() { const { item, depth, arrow, focused, getPercentSize, onViewSourceInDebugger, } = this.props; const retainedSize = formatNumber(item.retainedSize); const percentRetainedSize = formatPercent(getPercentSize(item.retainedSize)); const shallowSize = formatNumber(item.shallowSize); const percentShallowSize = formatPercent(getPercentSize(item.shallowSize)); // Build up our label UI as an array of each label piece, which is either a // string or a frame, and separators in between them. assert(item.label.length > 0, "Our label should not be empty"); const label = Array(item.label.length * 2 - 1); label.fill(undefined); for (let i = 0, length = item.label.length; i < length; i++) { const piece = item.label[i]; const key = `${item.nodeId}-label-${i}`; // `i` is the index of the label piece we are rendering, `label[i*2]` is // where the rendered label piece belngs, and `label[i*2+1]` (if it isn't // out of bounds) is where the separator belongs. if (isSavedFrame(piece)) { label[i * 2] = Frame({ key, onClick: () => onViewSourceInDebugger(piece), frame: piece, showFunctionName: true }); } else if (piece === "noStack") { label[i * 2] = dom.span({ key, className: "not-available" }, L10N.getStr("tree-item.nostack")); } else if (piece === "noFilename") { label[i * 2] = dom.span({ key, className: "not-available" }, L10N.getStr("tree-item.nofilename")); } else if (piece === "JS::ubi::RootList") { // Don't use the usual labeling machinery for root lists: replace it // with the "GC Roots" string. label.splice(0, label.length); label.push(L10N.getStr("tree-item.rootlist")); break; } else { label[i * 2] = piece; } // If this is not the last piece of the label, add a separator. if (i < length - 1) { label[i * 2 + 1] = Separator({ key: `${item.nodeId}-separator-${i}` }); } } return dom.div( { className: `heap-tree-item ${focused ? "focused" : ""} node-${item.nodeId}` }, dom.span( { className: "heap-tree-item-field heap-tree-item-bytes" }, dom.span( { className: "heap-tree-number" }, retainedSize ), dom.span({ className: "heap-tree-percent" }, percentRetainedSize) ), dom.span( { className: "heap-tree-item-field heap-tree-item-bytes" }, dom.span( { className: "heap-tree-number" }, shallowSize ), dom.span({ className: "heap-tree-percent" }, percentShallowSize) ), dom.span( { className: "heap-tree-item-field heap-tree-item-name", style: { marginInlineStart: depth * TREE_ROW_HEIGHT } }, arrow, label, dom.span({ className: "heap-tree-item-address" }, `@ 0x${item.nodeId.toString(16)}`) ) ); }
dom.span({ className: "heap-tree-percent" }, percentCount)), dom.span({ className: "heap-tree-item-field heap-tree-item-total-bytes" }, dom.span({ className: "heap-tree-number" }, totalBytes), dom.span({ className: "heap-tree-percent" }, percentTotalBytes)), dom.span({ className: "heap-tree-item-field heap-tree-item-total-count" }, dom.span({ className: "heap-tree-number" }, totalCount), dom.span({ className: "heap-tree-percent" }, percentTotalCount)), dom.span({ className: "heap-tree-item-field heap-tree-item-name", style: { marginLeft: depth * INDENT }}, arrow, this.toLabel(item.name, onViewSourceInDebugger) ) ); }, toLabel(name, linkToDebugger) { if (isSavedFrame(name)) { let onClickTooltipString = L10N.getFormatStr("viewsourceindebugger",`${name.source}:${name.line}:${name.column}`); return FrameView({ frame: name, onClick: () => linkToDebugger(name), onClickTooltipString, unknownSourceString }); } if (name === null) { return L10N.getStr("tree-item.root"); } if (name === "noStack") {