Source code

Revision control

Copy as Markdown

Other Tools

/* 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 DevToolsUtils = require("resource://devtools/shared/DevToolsUtils.js");
const {
isStorage,
} = require("resource://devtools/server/actors/object/utils.js");
/**
* A helper method that creates a property descriptor for the provided object,
* properly formatted for sending in a protocol response.
*
* @param ObjectActor objectActor
* The object actor of the object we are current listing properties.
* @param string name
* The property that the descriptor is generated for.
* @param {Number} depth
* Current depth in the generated preview object sent to the client.
* @param boolean [onlyEnumerable]
* Optional: true if you want a descriptor only for an enumerable
* property, false otherwise.
* @return object|undefined
* The property descriptor, or undefined if objectActor is not an enumerable
* property and onlyEnumerable=true.
*/
function propertyDescriptor(objectActor, name, depth, onlyEnumerable) {
if (!DevToolsUtils.isSafeDebuggerObject(objectActor.obj)) {
return undefined;
}
let desc;
try {
desc = objectActor.obj.getOwnPropertyDescriptor(name);
} catch (e) {
// Calling getOwnPropertyDescriptor on wrapped native prototypes is not
// allowed (bug 560072). Inform the user with a bogus, but hopefully
// explanatory, descriptor.
return {
configurable: false,
writable: false,
enumerable: false,
value: e.name,
};
}
if (isStorage(objectActor.obj)) {
if (name === "length") {
return undefined;
}
return desc;
}
if (!desc || (onlyEnumerable && !desc.enumerable)) {
return undefined;
}
const retval = {
configurable: desc.configurable,
enumerable: desc.enumerable,
};
const { rawObj } = objectActor;
if ("value" in desc) {
retval.writable = desc.writable;
retval.value = objectActor.createValueGrip(desc.value, depth);
} else if (objectActor.threadActor.getWatchpoint(rawObj, name.toString())) {
const watchpoint = objectActor.threadActor.getWatchpoint(rawObj, name.toString());
retval.value = objectActor.createValueGrip(watchpoint.desc.value, depth);
retval.watchpoint = watchpoint.watchpointType;
} else {
if ("get" in desc) {
retval.get = objectActor.createValueGrip(desc.get, depth);
}
if ("set" in desc) {
retval.set = objectActor.createValueGrip(desc.set, depth);
}
}
return retval;
}
exports.propertyDescriptor = propertyDescriptor;