260 lines
6.8 KiB
JavaScript
260 lines
6.8 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/>. */
|
|
|
|
const {
|
|
enumEntries,
|
|
enumIndexedProperties,
|
|
enumNonIndexedProperties,
|
|
enumPrivateProperties,
|
|
enumSymbols,
|
|
getPrototype,
|
|
getFullText,
|
|
getPromiseState,
|
|
getProxySlots,
|
|
} = require("resource://devtools/client/shared/components/object-inspector/utils/client.js");
|
|
|
|
const {
|
|
getClosestGripNode,
|
|
getClosestNonBucketNode,
|
|
getFront,
|
|
getValue,
|
|
nodeHasAccessors,
|
|
nodeHasProperties,
|
|
nodeIsBucket,
|
|
nodeIsDefaultProperties,
|
|
nodeIsEntries,
|
|
nodeIsMapEntry,
|
|
nodeIsPrimitive,
|
|
nodeIsPromise,
|
|
nodeIsProxy,
|
|
nodeNeedsNumericalBuckets,
|
|
nodeIsLongString,
|
|
} = require("resource://devtools/client/shared/components/object-inspector/utils/node.js");
|
|
|
|
function loadItemProperties(item, client, loadedProperties, threadActorID) {
|
|
const gripItem = getClosestGripNode(item);
|
|
const value = getValue(gripItem);
|
|
let front = getFront(gripItem);
|
|
|
|
if (!front && value && client && client.getFrontByID) {
|
|
front = client.getFrontByID(value.actor);
|
|
}
|
|
|
|
const getObjectFront = function() {
|
|
if (!front) {
|
|
front = client.createObjectFront(
|
|
value,
|
|
client.getFrontByID(threadActorID)
|
|
);
|
|
}
|
|
|
|
return front;
|
|
};
|
|
|
|
const [start, end] = item.meta
|
|
? [item.meta.startIndex, item.meta.endIndex]
|
|
: [];
|
|
|
|
const promises = [];
|
|
|
|
if (shouldLoadItemIndexedProperties(item, loadedProperties)) {
|
|
promises.push(enumIndexedProperties(getObjectFront(), start, end));
|
|
}
|
|
|
|
if (shouldLoadItemNonIndexedProperties(item, loadedProperties)) {
|
|
promises.push(enumNonIndexedProperties(getObjectFront(), start, end));
|
|
}
|
|
|
|
if (shouldLoadItemEntries(item, loadedProperties)) {
|
|
promises.push(enumEntries(getObjectFront(), start, end));
|
|
}
|
|
|
|
if (shouldLoadItemPrototype(item, loadedProperties)) {
|
|
promises.push(getPrototype(getObjectFront()));
|
|
}
|
|
|
|
if (shouldLoadItemPrivateProperties(item, loadedProperties)) {
|
|
promises.push(enumPrivateProperties(getObjectFront(), start, end));
|
|
}
|
|
|
|
if (shouldLoadItemSymbols(item, loadedProperties)) {
|
|
promises.push(enumSymbols(getObjectFront(), start, end));
|
|
}
|
|
|
|
if (shouldLoadItemFullText(item, loadedProperties)) {
|
|
const longStringFront = front || client.createLongStringFront(value);
|
|
promises.push(getFullText(longStringFront, item));
|
|
}
|
|
|
|
if (shouldLoadItemPromiseState(item, loadedProperties)) {
|
|
promises.push(getPromiseState(getObjectFront()));
|
|
}
|
|
|
|
if (shouldLoadItemProxySlots(item, loadedProperties)) {
|
|
promises.push(getProxySlots(getObjectFront()));
|
|
}
|
|
|
|
return Promise.all(promises).then(mergeResponses);
|
|
}
|
|
|
|
function mergeResponses(responses) {
|
|
const data = {};
|
|
|
|
for (const response of responses) {
|
|
if (response.hasOwnProperty("ownProperties")) {
|
|
data.ownProperties = { ...data.ownProperties, ...response.ownProperties };
|
|
}
|
|
|
|
if (response.privateProperties && response.privateProperties.length) {
|
|
data.privateProperties = response.privateProperties;
|
|
}
|
|
|
|
if (response.ownSymbols && response.ownSymbols.length) {
|
|
data.ownSymbols = response.ownSymbols;
|
|
}
|
|
|
|
if (response.prototype) {
|
|
data.prototype = response.prototype;
|
|
}
|
|
|
|
if (response.fullText) {
|
|
data.fullText = response.fullText;
|
|
}
|
|
|
|
if (response.promiseState) {
|
|
data.promiseState = response.promiseState;
|
|
}
|
|
|
|
if (response.proxyTarget && response.proxyHandler) {
|
|
data.proxyTarget = response.proxyTarget;
|
|
data.proxyHandler = response.proxyHandler;
|
|
}
|
|
}
|
|
|
|
return data;
|
|
}
|
|
|
|
function shouldLoadItemIndexedProperties(item, loadedProperties = new Map()) {
|
|
const gripItem = getClosestGripNode(item);
|
|
const value = getValue(gripItem);
|
|
|
|
return (
|
|
value &&
|
|
nodeHasProperties(gripItem) &&
|
|
!loadedProperties.has(item.path) &&
|
|
!nodeIsProxy(item) &&
|
|
!nodeNeedsNumericalBuckets(item) &&
|
|
!nodeIsEntries(getClosestNonBucketNode(item)) &&
|
|
// The data is loaded when expanding the window node.
|
|
!nodeIsDefaultProperties(item)
|
|
);
|
|
}
|
|
|
|
function shouldLoadItemNonIndexedProperties(
|
|
item,
|
|
loadedProperties = new Map()
|
|
) {
|
|
const gripItem = getClosestGripNode(item);
|
|
const value = getValue(gripItem);
|
|
|
|
return (
|
|
value &&
|
|
nodeHasProperties(gripItem) &&
|
|
!loadedProperties.has(item.path) &&
|
|
!nodeIsProxy(item) &&
|
|
!nodeIsEntries(getClosestNonBucketNode(item)) &&
|
|
!nodeIsBucket(item) &&
|
|
// The data is loaded when expanding the window node.
|
|
!nodeIsDefaultProperties(item)
|
|
);
|
|
}
|
|
|
|
function shouldLoadItemEntries(item, loadedProperties = new Map()) {
|
|
const gripItem = getClosestGripNode(item);
|
|
const value = getValue(gripItem);
|
|
|
|
return (
|
|
value &&
|
|
nodeIsEntries(getClosestNonBucketNode(item)) &&
|
|
!loadedProperties.has(item.path) &&
|
|
!nodeNeedsNumericalBuckets(item)
|
|
);
|
|
}
|
|
|
|
function shouldLoadItemPrototype(item, loadedProperties = new Map()) {
|
|
const value = getValue(item);
|
|
|
|
return (
|
|
value &&
|
|
!loadedProperties.has(item.path) &&
|
|
!nodeIsBucket(item) &&
|
|
!nodeIsMapEntry(item) &&
|
|
!nodeIsEntries(item) &&
|
|
!nodeIsDefaultProperties(item) &&
|
|
!nodeHasAccessors(item) &&
|
|
!nodeIsPrimitive(item) &&
|
|
!nodeIsLongString(item) &&
|
|
!nodeIsProxy(item)
|
|
);
|
|
}
|
|
|
|
function shouldLoadItemSymbols(item, loadedProperties = new Map()) {
|
|
const value = getValue(item);
|
|
|
|
return (
|
|
value &&
|
|
!loadedProperties.has(item.path) &&
|
|
!nodeIsBucket(item) &&
|
|
!nodeIsMapEntry(item) &&
|
|
!nodeIsEntries(item) &&
|
|
!nodeIsDefaultProperties(item) &&
|
|
!nodeHasAccessors(item) &&
|
|
!nodeIsPrimitive(item) &&
|
|
!nodeIsLongString(item) &&
|
|
!nodeIsProxy(item)
|
|
);
|
|
}
|
|
|
|
function shouldLoadItemPrivateProperties(item, loadedProperties = new Map()) {
|
|
const value = getValue(item);
|
|
|
|
return (
|
|
value &&
|
|
value?.preview?.privatePropertiesLength &&
|
|
!loadedProperties.has(item.path) &&
|
|
!nodeIsBucket(item) &&
|
|
!nodeIsMapEntry(item) &&
|
|
!nodeIsEntries(item) &&
|
|
!nodeIsDefaultProperties(item) &&
|
|
!nodeHasAccessors(item) &&
|
|
!nodeIsPrimitive(item) &&
|
|
!nodeIsLongString(item) &&
|
|
!nodeIsProxy(item)
|
|
);
|
|
}
|
|
|
|
function shouldLoadItemFullText(item, loadedProperties = new Map()) {
|
|
return !loadedProperties.has(item.path) && nodeIsLongString(item);
|
|
}
|
|
|
|
function shouldLoadItemPromiseState(item, loadedProperties = new Map()) {
|
|
return !loadedProperties.has(item.path) && nodeIsPromise(item);
|
|
}
|
|
|
|
function shouldLoadItemProxySlots(item, loadedProperties = new Map()) {
|
|
return !loadedProperties.has(item.path) && nodeIsProxy(item);
|
|
}
|
|
|
|
module.exports = {
|
|
loadItemProperties,
|
|
mergeResponses,
|
|
shouldLoadItemEntries,
|
|
shouldLoadItemIndexedProperties,
|
|
shouldLoadItemNonIndexedProperties,
|
|
shouldLoadItemPrototype,
|
|
shouldLoadItemSymbols,
|
|
shouldLoadItemFullText,
|
|
shouldLoadItemPromiseState,
|
|
shouldLoadItemProxySlots,
|
|
};
|