tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DominatorTreeItem.js (5006B)


      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 file,
      3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const {
      8  assert,
      9  isSavedFrame,
     10 } = require("resource://devtools/shared/DevToolsUtils.js");
     11 const {
     12  Component,
     13  createFactory,
     14 } = require("resource://devtools/client/shared/vendor/react.mjs");
     15 const dom = require("resource://devtools/client/shared/vendor/react-dom-factories.js");
     16 const PropTypes = require("resource://devtools/client/shared/vendor/react-prop-types.mjs");
     17 const {
     18  L10N,
     19  formatNumber,
     20  formatPercent,
     21 } = require("resource://devtools/client/memory/utils.js");
     22 const Frame = createFactory(
     23  require("resource://devtools/client/shared/components/Frame.js")
     24 );
     25 const {
     26  TREE_ROW_HEIGHT,
     27 } = require("resource://devtools/client/memory/constants.js");
     28 
     29 class SeparatorClass extends Component {
     30  render() {
     31    return dom.span({ className: "separator" }, "›");
     32  }
     33 }
     34 
     35 const Separator = createFactory(SeparatorClass);
     36 
     37 class DominatorTreeItem extends Component {
     38  static get propTypes() {
     39    return {
     40      item: PropTypes.object.isRequired,
     41      depth: PropTypes.number.isRequired,
     42      arrow: PropTypes.object,
     43      expanded: PropTypes.bool.isRequired,
     44      focused: PropTypes.bool.isRequired,
     45      getPercentSize: PropTypes.func.isRequired,
     46      onViewSourceInDebugger: PropTypes.func.isRequired,
     47    };
     48  }
     49 
     50  shouldComponentUpdate(nextProps) {
     51    return (
     52      this.props.item != nextProps.item ||
     53      this.props.depth != nextProps.depth ||
     54      this.props.expanded != nextProps.expanded ||
     55      this.props.focused != nextProps.focused
     56    );
     57  }
     58 
     59  render() {
     60    const {
     61      item,
     62      depth,
     63      arrow,
     64      focused,
     65      getPercentSize,
     66      onViewSourceInDebugger,
     67    } = this.props;
     68 
     69    const retainedSize = formatNumber(item.retainedSize);
     70    const percentRetainedSize = formatPercent(
     71      getPercentSize(item.retainedSize)
     72    );
     73 
     74    const shallowSize = formatNumber(item.shallowSize);
     75    const percentShallowSize = formatPercent(getPercentSize(item.shallowSize));
     76 
     77    // Build up our label UI as an array of each label piece, which is either a
     78    // string or a frame, and separators in between them.
     79 
     80    assert(!!item.label.length, "Our label should not be empty");
     81    const label = Array(item.label.length * 2 - 1);
     82    label.fill(undefined);
     83 
     84    for (let i = 0, length = item.label.length; i < length; i++) {
     85      const piece = item.label[i];
     86      const key = `${item.nodeId}-label-${i}`;
     87 
     88      // `i` is the index of the label piece we are rendering, `label[i*2]` is
     89      // where the rendered label piece belngs, and `label[i*2+1]` (if it isn't
     90      // out of bounds) is where the separator belongs.
     91 
     92      if (isSavedFrame(piece)) {
     93        label[i * 2] = Frame({
     94          key,
     95          onClick: onViewSourceInDebugger,
     96          frame: piece,
     97          showFunctionName: true,
     98        });
     99      } else if (piece === "noStack") {
    100        label[i * 2] = dom.span(
    101          { key, className: "not-available" },
    102          L10N.getStr("tree-item.nostack")
    103        );
    104      } else if (piece === "noFilename") {
    105        label[i * 2] = dom.span(
    106          { key, className: "not-available" },
    107          L10N.getStr("tree-item.nofilename")
    108        );
    109      } else if (piece === "JS::ubi::RootList") {
    110        // Don't use the usual labeling machinery for root lists: replace it
    111        // with the "GC Roots" string.
    112        label.splice(0, label.length);
    113        label.push(L10N.getStr("tree-item.rootlist"));
    114        break;
    115      } else {
    116        label[i * 2] = piece;
    117      }
    118 
    119      // If this is not the last piece of the label, add a separator.
    120      if (i < length - 1) {
    121        label[i * 2 + 1] = Separator({ key: `${item.nodeId}-separator-${i}` });
    122      }
    123    }
    124 
    125    return dom.div(
    126      {
    127        className: `heap-tree-item ${focused ? "focused" : ""} node-${
    128          item.nodeId
    129        }`,
    130      },
    131 
    132      dom.span(
    133        {
    134          className: "heap-tree-item-field heap-tree-item-bytes",
    135        },
    136        dom.span(
    137          {
    138            className: "heap-tree-number",
    139          },
    140          retainedSize
    141        ),
    142        dom.span({ className: "heap-tree-percent" }, percentRetainedSize)
    143      ),
    144 
    145      dom.span(
    146        {
    147          className: "heap-tree-item-field heap-tree-item-bytes",
    148        },
    149        dom.span(
    150          {
    151            className: "heap-tree-number",
    152          },
    153          shallowSize
    154        ),
    155        dom.span({ className: "heap-tree-percent" }, percentShallowSize)
    156      ),
    157 
    158      dom.span(
    159        {
    160          className: "heap-tree-item-field heap-tree-item-name",
    161          style: { marginInlineStart: depth * TREE_ROW_HEIGHT },
    162        },
    163        arrow,
    164        label,
    165        dom.span(
    166          { className: "heap-tree-item-address" },
    167          `@ 0x${item.nodeId.toString(16)}`
    168        )
    169      )
    170    );
    171  }
    172 }
    173 
    174 module.exports = DominatorTreeItem;