object-inspector.js (4840B)
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 "use strict"; 6 7 const { 8 createFactory, 9 createElement, 10 } = require("resource://devtools/client/shared/vendor/react.mjs"); 11 12 loader.lazyGetter(this, "REPS", function () { 13 return ChromeUtils.importESModule( 14 "resource://devtools/client/shared/components/reps/index.mjs", 15 { global: "current" } 16 ).REPS; 17 }); 18 loader.lazyGetter(this, "MODE", function () { 19 return ChromeUtils.importESModule( 20 "resource://devtools/client/shared/components/reps/index.mjs", 21 { global: "current" } 22 ).MODE; 23 }); 24 loader.lazyGetter(this, "ObjectInspector", function () { 25 const objectInspector = require("resource://devtools/client/shared/components/object-inspector/index.js"); 26 return createFactory(objectInspector.ObjectInspector); 27 }); 28 29 loader.lazyRequireGetter( 30 this, 31 "SmartTrace", 32 "resource://devtools/client/shared/components/SmartTrace.js" 33 ); 34 35 loader.lazyRequireGetter( 36 this, 37 "LongStringFront", 38 "resource://devtools/client/fronts/string.js", 39 true 40 ); 41 42 loader.lazyRequireGetter( 43 this, 44 "ObjectFront", 45 "resource://devtools/client/fronts/object.js", 46 true 47 ); 48 49 /** 50 * Create and return an ObjectInspector for the given front. 51 * 52 * @param {object} grip 53 * The object grip to create an ObjectInspector for. 54 * @param {object} serviceContainer 55 * Object containing various utility functions 56 * @param {object} override 57 * Object containing props that should override the default props passed to 58 * ObjectInspector. 59 * @returns {ObjectInspector} 60 * An ObjectInspector for the given grip. 61 */ 62 function getObjectInspector( 63 frontOrPrimitiveGrip, 64 serviceContainer, 65 override = {} 66 ) { 67 let onDOMNodeMouseOver; 68 let onDOMNodeMouseOut; 69 let onInspectIconClick; 70 71 if (serviceContainer) { 72 onDOMNodeMouseOver = serviceContainer.highlightDomElement 73 ? object => serviceContainer.highlightDomElement(object) 74 : null; 75 onDOMNodeMouseOut = serviceContainer.unHighlightDomElement 76 ? object => serviceContainer.unHighlightDomElement(object) 77 : null; 78 onInspectIconClick = serviceContainer.openNodeInInspector 79 ? (object, e) => { 80 // Stop the event propagation so we don't trigger ObjectInspector expand/collapse. 81 e.stopPropagation(); 82 serviceContainer.openNodeInInspector(object); 83 } 84 : null; 85 } 86 87 const roots = createRoots(frontOrPrimitiveGrip, override.pathPrefix); 88 89 const objectInspectorProps = { 90 autoExpandDepth: 0, 91 mode: MODE.LONG, 92 standalone: true, 93 roots, 94 onViewSourceInDebugger: serviceContainer.onViewSourceInDebugger, 95 recordTelemetryEvent: serviceContainer.recordTelemetryEvent, 96 openLink: serviceContainer.openLink, 97 sourceMapURLService: serviceContainer.sourceMapURLService, 98 customFormat: override.customFormat !== false, 99 setExpanded: override.setExpanded, 100 getInitiallyExpanded: override.getInitiallyExpanded, 101 queueActorsForCleanup: override.queueActorsForCleanup, 102 cachedNodes: override.cachedNodes, 103 urlCropLimit: 120, 104 renderStacktrace: stacktrace => { 105 const attrs = { 106 key: "stacktrace", 107 stacktrace, 108 onViewSourceInDebugger: serviceContainer 109 ? serviceContainer.onViewSourceInDebugger || 110 serviceContainer.onViewSource 111 : null, 112 onViewSource: serviceContainer.onViewSource, 113 onReady: override.maybeScrollToBottom, 114 sourceMapURLService: serviceContainer 115 ? serviceContainer.sourceMapURLService 116 : null, 117 }; 118 119 if (serviceContainer?.preventStacktraceInitialRenderDelay) { 120 attrs.initialRenderDelay = 0; 121 } 122 return createElement(SmartTrace, attrs); 123 }, 124 onDOMNodeMouseOver, 125 onDOMNodeMouseOut, 126 onInspectIconClick, 127 defaultRep: REPS.Grip, 128 createElement: serviceContainer?.createElement, 129 mayUseCustomFormatter: true, 130 ...override, 131 }; 132 133 if (override.autoFocusRoot) { 134 Object.assign(objectInspectorProps, { 135 focusedItem: objectInspectorProps.roots[0], 136 }); 137 } 138 139 return ObjectInspector(objectInspectorProps); 140 } 141 142 function createRoots(frontOrPrimitiveGrip, pathPrefix = "") { 143 const isFront = 144 frontOrPrimitiveGrip instanceof ObjectFront || 145 frontOrPrimitiveGrip instanceof LongStringFront; 146 const grip = isFront ? frontOrPrimitiveGrip.getGrip() : frontOrPrimitiveGrip; 147 148 return [ 149 { 150 path: `${pathPrefix}${ 151 frontOrPrimitiveGrip 152 ? frontOrPrimitiveGrip.actorID || frontOrPrimitiveGrip.actor 153 : null 154 }`, 155 contents: { value: grip, front: isFront ? frontOrPrimitiveGrip : null }, 156 }, 157 ]; 158 } 159 160 module.exports = { 161 getObjectInspector, 162 };