summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/components/object-inspector/utils/load-properties.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/shared/components/object-inspector/utils/load-properties.js')
-rw-r--r--devtools/client/shared/components/object-inspector/utils/load-properties.js260
1 files changed, 260 insertions, 0 deletions
diff --git a/devtools/client/shared/components/object-inspector/utils/load-properties.js b/devtools/client/shared/components/object-inspector/utils/load-properties.js
new file mode 100644
index 0000000000..42525e54f1
--- /dev/null
+++ b/devtools/client/shared/components/object-inspector/utils/load-properties.js
@@ -0,0 +1,260 @@
+/* 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 > 0) {
+ data.privateProperties = response.privateProperties;
+ }
+
+ if (response.ownSymbols && response.ownSymbols.length > 0) {
+ 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,
+};