census-tree-item.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. "use strict";
  5. const { isSavedFrame } = require("devtools/shared/DevToolsUtils");
  6. const { DOM: dom, createClass, createFactory } = require("devtools/client/shared/vendor/react");
  7. const { L10N, formatNumber, formatPercent } = require("../utils");
  8. const Frame = createFactory(require("devtools/client/shared/components/frame"));
  9. const { TREE_ROW_HEIGHT } = require("../constants");
  10. const CensusTreeItem = module.exports = createClass({
  11. displayName: "CensusTreeItem",
  12. shouldComponentUpdate(nextProps, nextState) {
  13. return this.props.item != nextProps.item
  14. || this.props.depth != nextProps.depth
  15. || this.props.expanded != nextProps.expanded
  16. || this.props.focused != nextProps.focused
  17. || this.props.diffing != nextProps.diffing;
  18. },
  19. render() {
  20. let {
  21. item,
  22. depth,
  23. arrow,
  24. focused,
  25. getPercentBytes,
  26. getPercentCount,
  27. diffing,
  28. onViewSourceInDebugger,
  29. onViewIndividuals,
  30. inverted,
  31. } = this.props;
  32. const bytes = formatNumber(item.bytes, !!diffing);
  33. const percentBytes = formatPercent(getPercentBytes(item.bytes), !!diffing);
  34. const count = formatNumber(item.count, !!diffing);
  35. const percentCount = formatPercent(getPercentCount(item.count), !!diffing);
  36. const totalBytes = formatNumber(item.totalBytes, !!diffing);
  37. const percentTotalBytes = formatPercent(getPercentBytes(item.totalBytes), !!diffing);
  38. const totalCount = formatNumber(item.totalCount, !!diffing);
  39. const percentTotalCount = formatPercent(getPercentCount(item.totalCount), !!diffing);
  40. let pointer;
  41. if (inverted && depth > 0) {
  42. pointer = dom.span({ className: "children-pointer" }, "↖");
  43. } else if (!inverted && item.children && item.children.length) {
  44. pointer = dom.span({ className: "children-pointer" }, "↘");
  45. }
  46. let individualsCell;
  47. if (!diffing) {
  48. let individualsButton;
  49. if (item.reportLeafIndex !== undefined) {
  50. individualsButton = dom.button(
  51. {
  52. key: `individuals-button-${item.id}`,
  53. title: L10N.getStr("tree-item.view-individuals.tooltip"),
  54. className: "devtools-button individuals-button",
  55. onClick: e => {
  56. // Don't let the event bubble up to cause this item to focus after
  57. // we have switched views, which would lead to assertion failures.
  58. e.preventDefault();
  59. e.stopPropagation();
  60. onViewIndividuals(item);
  61. },
  62. },
  63. "⁂"
  64. );
  65. }
  66. individualsCell = dom.span(
  67. { className: "heap-tree-item-field heap-tree-item-individuals" },
  68. individualsButton
  69. );
  70. }
  71. return dom.div(
  72. { className: `heap-tree-item ${focused ? "focused" : ""}` },
  73. dom.span({ className: "heap-tree-item-field heap-tree-item-bytes" },
  74. dom.span({ className: "heap-tree-number" }, bytes),
  75. dom.span({ className: "heap-tree-percent" }, percentBytes)),
  76. dom.span({ className: "heap-tree-item-field heap-tree-item-count" },
  77. dom.span({ className: "heap-tree-number" }, count),
  78. dom.span({ className: "heap-tree-percent" }, percentCount)),
  79. dom.span({ className: "heap-tree-item-field heap-tree-item-total-bytes" },
  80. dom.span({ className: "heap-tree-number" }, totalBytes),
  81. dom.span({ className: "heap-tree-percent" }, percentTotalBytes)),
  82. dom.span({ className: "heap-tree-item-field heap-tree-item-total-count" },
  83. dom.span({ className: "heap-tree-number" }, totalCount),
  84. dom.span({ className: "heap-tree-percent" }, percentTotalCount)),
  85. individualsCell,
  86. dom.span(
  87. {
  88. className: "heap-tree-item-field heap-tree-item-name",
  89. style: { marginInlineStart: depth * TREE_ROW_HEIGHT }
  90. },
  91. arrow,
  92. pointer,
  93. this.toLabel(item.name, onViewSourceInDebugger)
  94. )
  95. );
  96. },
  97. toLabel(name, linkToDebugger) {
  98. if (isSavedFrame(name)) {
  99. return Frame({
  100. frame: name,
  101. onClick: () => linkToDebugger(name),
  102. showFunctionName: true,
  103. showHost: true,
  104. });
  105. }
  106. if (name === null) {
  107. return L10N.getStr("tree-item.root");
  108. }
  109. if (name === "noStack") {
  110. return L10N.getStr("tree-item.nostack");
  111. }
  112. if (name === "noFilename") {
  113. return L10N.getStr("tree-item.nofilename");
  114. }
  115. return String(name);
  116. },
  117. });