dumpReactTree.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @format
  8. * @flow strict
  9. */
  10. 'use strict';
  11. /*
  12. const getReactData = require('getReactData');
  13. const INDENTATION_SIZE = 2;
  14. const MAX_DEPTH = 2;
  15. const MAX_STRING_LENGTH = 50;
  16. */
  17. /**
  18. * Dump all React Native root views and their content. This function tries
  19. * it best to get the content but ultimately relies on implementation details
  20. * of React and will fail in future versions.
  21. */
  22. function dumpReactTree(): string {
  23. try {
  24. return getReactTree();
  25. } catch (e) {
  26. return 'Failed to dump react tree: ' + e;
  27. }
  28. }
  29. function getReactTree() {
  30. // TODO(sema): Reenable tree dumps using the Fiber tree structure. #15945684
  31. return (
  32. 'React tree dumps have been temporarily disabled while React is ' +
  33. 'upgraded to Fiber.'
  34. );
  35. /*
  36. let output = '';
  37. const rootIds = Object.getOwnPropertyNames(ReactNativeMount._instancesByContainerID);
  38. for (const rootId of rootIds) {
  39. const instance = ReactNativeMount._instancesByContainerID[rootId];
  40. output += `============ Root ID: ${rootId} ============\n`;
  41. output += dumpNode(instance, 0);
  42. output += `============ End root ID: ${rootId} ============\n`;
  43. }
  44. return output;
  45. */
  46. }
  47. /*
  48. function dumpNode(node: Object, indentation: number) {
  49. const data = getReactData(node);
  50. if (data.nodeType === 'Text') {
  51. return indent(indentation) + data.text + '\n';
  52. } else if (data.nodeType === 'Empty') {
  53. return '';
  54. }
  55. let output = indent(indentation) + `<${data.name}`;
  56. if (data.nodeType === 'Composite') {
  57. for (const propName of Object.getOwnPropertyNames(data.props || {})) {
  58. if (isNormalProp(propName)) {
  59. try {
  60. const value = convertValue(data.props[propName]);
  61. if (value) {
  62. output += ` ${propName}=${value}`;
  63. }
  64. } catch (e) {
  65. const message = `[Failed to get property: ${e}]`;
  66. output += ` ${propName}=${message}`;
  67. }
  68. }
  69. }
  70. }
  71. let childOutput = '';
  72. for (const child of data.children || []) {
  73. childOutput += dumpNode(child, indentation + 1);
  74. }
  75. if (childOutput) {
  76. output += '>\n' + childOutput + indent(indentation) + `</${data.name}>\n`;
  77. } else {
  78. output += ' />\n';
  79. }
  80. return output;
  81. }
  82. function isNormalProp(name: string): boolean {
  83. switch (name) {
  84. case 'children':
  85. case 'key':
  86. case 'ref':
  87. return false;
  88. default:
  89. return true;
  90. }
  91. }
  92. function convertObject(object: Object, depth: number) {
  93. if (depth >= MAX_DEPTH) {
  94. return '[...omitted]';
  95. }
  96. let output = '{';
  97. let first = true;
  98. for (const key of Object.getOwnPropertyNames(object)) {
  99. if (!first) {
  100. output += ', ';
  101. }
  102. output += `${key}: ${convertValue(object[key], depth + 1)}`;
  103. first = false;
  104. }
  105. return output + '}';
  106. }
  107. function convertValue(value, depth = 0): ?string {
  108. if (!value) {
  109. return null;
  110. }
  111. switch (typeof value) {
  112. case 'string':
  113. return JSON.stringify(possiblyEllipsis(value).replace('\n', '\\n'));
  114. case 'boolean':
  115. case 'number':
  116. return JSON.stringify(value);
  117. case 'function':
  118. return '[function]';
  119. case 'object':
  120. return convertObject(value, depth);
  121. default:
  122. return null;
  123. }
  124. }
  125. function possiblyEllipsis(value: string) {
  126. if (value.length > MAX_STRING_LENGTH) {
  127. return value.slice(0, MAX_STRING_LENGTH) + '...';
  128. } else {
  129. return value;
  130. }
  131. }
  132. function indent(size: number) {
  133. return ' '.repeat(size * INDENTATION_SIZE);
  134. }
  135. */
  136. module.exports = dumpReactTree;