forked from mirrors/gecko-dev
At the moment, the ObjectInspector, while having its own reducer and actions, has its state located in the state of its consumer application (e.g. webconsole, debugger). This patch, by adding a `standalone` prop to the ObjectInspector, will allow the said consumer to not have the object inspector state shared anymore. This makes interaction in a given objectInspector much faster as only one instance will have its lifecycle methods triggered. It also prevent cloning the consumer's state on each object inspector interaction. This new props is only used in the webconsole for now, as the debugger might need to have access to its objectInspector state (this is also less of a problem, because the debugger won't hold that much instances at a given point in time, unlike the console). The DAMP data seems to indicate a 40% improvement in the console when expanding an object while there are a thousand instances in the console. Differential Revision: https://phabricator.services.mozilla.com/D99472
146 lines
4.1 KiB
JavaScript
146 lines
4.1 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
const {
|
|
createFactory,
|
|
createElement,
|
|
} = require("devtools/client/shared/vendor/react");
|
|
|
|
loader.lazyGetter(this, "REPS", function() {
|
|
return require("devtools/client/shared/components/reps/index").REPS;
|
|
});
|
|
loader.lazyGetter(this, "MODE", function() {
|
|
return require("devtools/client/shared/components/reps/index").MODE;
|
|
});
|
|
loader.lazyGetter(this, "ObjectInspector", function() {
|
|
const reps = require("devtools/client/shared/components/reps/index");
|
|
return createFactory(reps.objectInspector.ObjectInspector);
|
|
});
|
|
|
|
loader.lazyRequireGetter(
|
|
this,
|
|
"SmartTrace",
|
|
"devtools/client/shared/components/SmartTrace"
|
|
);
|
|
|
|
loader.lazyRequireGetter(
|
|
this,
|
|
"LongStringFront",
|
|
"devtools/client/fronts/string",
|
|
true
|
|
);
|
|
|
|
loader.lazyRequireGetter(
|
|
this,
|
|
"ObjectFront",
|
|
"devtools/client/fronts/object",
|
|
true
|
|
);
|
|
|
|
/**
|
|
* Create and return an ObjectInspector for the given front.
|
|
*
|
|
* @param {Object} grip
|
|
* The object grip to create an ObjectInspector for.
|
|
* @param {Object} serviceContainer
|
|
* Object containing various utility functions
|
|
* @param {Object} override
|
|
* Object containing props that should override the default props passed to
|
|
* ObjectInspector.
|
|
* @returns {ObjectInspector}
|
|
* An ObjectInspector for the given grip.
|
|
*/
|
|
function getObjectInspector(
|
|
frontOrPrimitiveGrip,
|
|
serviceContainer,
|
|
override = {}
|
|
) {
|
|
let onDOMNodeMouseOver;
|
|
let onDOMNodeMouseOut;
|
|
let onInspectIconClick;
|
|
|
|
if (serviceContainer) {
|
|
onDOMNodeMouseOver = serviceContainer.highlightDomElement
|
|
? object => serviceContainer.highlightDomElement(object)
|
|
: null;
|
|
onDOMNodeMouseOut = serviceContainer.unHighlightDomElement
|
|
? object => serviceContainer.unHighlightDomElement(object)
|
|
: null;
|
|
onInspectIconClick = serviceContainer.openNodeInInspector
|
|
? (object, e) => {
|
|
// Stop the event propagation so we don't trigger ObjectInspector expand/collapse.
|
|
e.stopPropagation();
|
|
serviceContainer.openNodeInInspector(object);
|
|
}
|
|
: null;
|
|
}
|
|
|
|
const roots = createRoots(frontOrPrimitiveGrip, override.pathPrefix);
|
|
|
|
const objectInspectorProps = {
|
|
autoExpandDepth: 0,
|
|
mode: MODE.LONG,
|
|
standalone: true,
|
|
roots,
|
|
onViewSourceInDebugger: serviceContainer.onViewSourceInDebugger,
|
|
recordTelemetryEvent: serviceContainer.recordTelemetryEvent,
|
|
openLink: serviceContainer.openLink,
|
|
sourceMapURLService: serviceContainer.sourceMapURLService,
|
|
customFormat: override.customFormat !== false,
|
|
urlCropLimit: 120,
|
|
renderStacktrace: stacktrace =>
|
|
createElement(SmartTrace, {
|
|
key: "stacktrace",
|
|
stacktrace,
|
|
onViewSourceInDebugger: serviceContainer
|
|
? serviceContainer.onViewSourceInDebugger ||
|
|
serviceContainer.onViewSource
|
|
: null,
|
|
onViewSource: serviceContainer.onViewSource,
|
|
onReady: override.maybeScrollToBottom,
|
|
sourceMapURLService: serviceContainer
|
|
? serviceContainer.sourceMapURLService
|
|
: null,
|
|
}),
|
|
};
|
|
|
|
Object.assign(objectInspectorProps, {
|
|
onDOMNodeMouseOver,
|
|
onDOMNodeMouseOut,
|
|
onInspectIconClick,
|
|
defaultRep: REPS.Grip,
|
|
});
|
|
|
|
if (override.autoFocusRoot) {
|
|
Object.assign(objectInspectorProps, {
|
|
focusedItem: objectInspectorProps.roots[0],
|
|
});
|
|
}
|
|
|
|
return ObjectInspector({ ...objectInspectorProps, ...override });
|
|
}
|
|
|
|
function createRoots(frontOrPrimitiveGrip, pathPrefix = "") {
|
|
const isFront =
|
|
frontOrPrimitiveGrip instanceof ObjectFront ||
|
|
frontOrPrimitiveGrip instanceof LongStringFront;
|
|
const grip = isFront ? frontOrPrimitiveGrip.getGrip() : frontOrPrimitiveGrip;
|
|
|
|
return [
|
|
{
|
|
path: `${pathPrefix}${
|
|
frontOrPrimitiveGrip
|
|
? frontOrPrimitiveGrip.actorID || frontOrPrimitiveGrip.actor
|
|
: null
|
|
}`,
|
|
contents: { value: grip, front: isFront ? frontOrPrimitiveGrip : null },
|
|
},
|
|
];
|
|
}
|
|
|
|
module.exports = {
|
|
getObjectInspector,
|
|
};
|