/* 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/. */
/** * A ObjectFront is used as a front end for the ObjectActor that is * created on the server, hiding implementation details.
*/ class ObjectFront extends FrontClassWithSpec(objectSpec) {
constructor(conn = null, targetFront = null, parentFront = null, data) { if (!parentFront) { thrownew Error("ObjectFront require a parent front");
}
skipDestroy() { // Object fronts are simple fronts, they don't need to be cleaned up on // toolbox destroy. `conn` is a DebuggerClient instance, check the // `isToolboxDestroy` flag to skip the destroy. returnthis.conn && this.conn.isToolboxDestroy;
}
getGrip() { returnthis._grip;
}
get isFrozen() { returnthis._grip.frozen;
}
get isSealed() { returnthis._grip.sealed;
}
get isExtensible() { returnthis._grip.extensible;
}
/** * Request the prototype and own properties of the object.
*/
async getPrototypeAndProperties() { const result = await super.prototypeAndProperties();
if (result.prototype) {
result.prototype = getAdHocFrontOrPrimitiveGrip(result.prototype, this);
}
// The result packet can have multiple properties that hold grips which we may need // to turn into fronts. const gripKeys = ["value", "getterValue", "get", "set"];
if (result.ownProperties) {
Object.entries(result.ownProperties).forEach(([key, descriptor]) => { if (descriptor) { for (const gripKey of gripKeys) { if (descriptor.hasOwnProperty(gripKey)) {
result.ownProperties[key][gripKey] = getAdHocFrontOrPrimitiveGrip(
descriptor[gripKey], this
);
}
}
}
});
}
if (result.safeGetterValues) {
Object.entries(result.safeGetterValues).forEach(([key, descriptor]) => { if (descriptor) { for (const gripKey of gripKeys) { if (descriptor.hasOwnProperty(gripKey)) {
result.safeGetterValues[key][gripKey] =
getAdHocFrontOrPrimitiveGrip(descriptor[gripKey], this);
}
}
}
});
}
if (result.ownSymbols) {
result.ownSymbols.forEach((descriptor, i, arr) => { if (descriptor) { for (const gripKey of gripKeys) { if (descriptor.hasOwnProperty(gripKey)) {
arr[i][gripKey] = getAdHocFrontOrPrimitiveGrip(
descriptor[gripKey], this
);
}
}
}
});
}
return result;
}
/** * Request a PropertyIteratorFront instance to ease listing * properties for this object. * * @param options Object * A dictionary object with various boolean attributes: * - ignoreIndexedProperties Boolean * If true, filters out Array items. * e.g. properties names between `0` and `object.length`. * - ignoreNonIndexedProperties Boolean * If true, filters out items that aren't array items * e.g. properties names that are not a number between `0` * and `object.length`. * - sort Boolean * If true, the iterator will sort the properties by name * before dispatching them.
*/
enumProperties(options) { returnsuper.enumProperties(options);
}
/** * Request a PropertyIteratorFront instance to enumerate entries in a * Map/Set-like object.
*/
enumEntries() { if (!SUPPORT_ENUM_ENTRIES_SET.has(this._grip.class)) {
console.error(
`enumEntries can't be called for "${ this._grip.class
}" grips. Supported grips are: ${[...SUPPORT_ENUM_ENTRIES_SET].join( ", "
)}.`
); returnnull;
} returnsuper.enumEntries();
}
/** * Request a SymbolIteratorFront instance to enumerate symbols in an object.
*/
enumSymbols() { if (this._grip.type !== "object") {
console.error("enumSymbols is only valid for objects grips."); returnnull;
} returnsuper.enumSymbols();
}
/** * Request the property descriptor of the object's specified property. * * @param name string The name of the requested property.
*/
getProperty(name) { returnsuper.property(name);
}
/** * Request the value of the object's specified property. * * @param name string The name of the requested property. * @param receiverId string|null The actorId of the receiver to be used for getters.
*/
async getPropertyValue(name, receiverId) { const response = await super.propertyValue(name, receiverId);
if (response.value) { const { value } = response; if (value.return) {
response.value.return = getAdHocFrontOrPrimitiveGrip(
value.return, this
);
}
/** * Request the state of a promise.
*/
async getPromiseState() { if (this._grip.class !== "Promise") {
console.error("getPromiseState is only valid for promise grips."); returnnull;
}
let response, promiseState; try {
response = await super.promiseState();
promiseState = response.promiseState;
} catch (error) { // @backward-compat { version 85 } On older server, the promiseState request didn't // didn't exist (bug 1552648). The promise state was directly included in the grip. if (error.message.includes("unrecognizedPacketType")) {
promiseState = this._grip.promiseState;
response = { promiseState };
} else { throw error;
}
}
const { value, reason } = promiseState;
if (value) {
promiseState.value = getAdHocFrontOrPrimitiveGrip(value, this);
}
if (reason) {
promiseState.reason = getAdHocFrontOrPrimitiveGrip(reason, this);
}
return response;
}
/** * Request the target and handler internal slots of a proxy.
*/
async getProxySlots() { if (this._grip.class !== "Proxy") {
console.error("getProxySlots is only valid for proxy grips."); returnnull;
}
if (proxyHandler) {
response.proxyHandler = getAdHocFrontOrPrimitiveGrip(proxyHandler, this);
}
if (proxyTarget) {
response.proxyTarget = getAdHocFrontOrPrimitiveGrip(proxyTarget, this);
}
return response;
}
get isSyntaxError() { returnthis._grip.preview && this._grip.preview.name == "SyntaxError";
}
}
/** * When we are asking the server for the value of a given variable, we might get different * type of objects: * - a primitive (string, number, null, false, boolean) * - a long string * - an "object" (i.e. not primitive nor long string) * * Each of those type need a different front, or none: * - a primitive does not allow further interaction with the server, so we don't need * to have a dedicated front. * - a long string needs a longStringFront to be able to retrieve the full string. * - an object need an objectFront to retrieve properties, symbols and prototype. * * In the case an ObjectFront is created, we also check if the object has properties * that should be turned into fronts as well. * * @param {String|Number|Object} options: The packet returned by the server. * @param {Front} parentFront * * @returns {Number|String|Object|LongStringFront|ObjectFront}
*/ function getAdHocFrontOrPrimitiveGrip(packet, parentFront) { // We only want to try to create a front when it makes sense, i.e when it has an // actorID, unless: // - it's a Symbol (See Bug 1600299) // - it's a mapEntry (the preview.key and preview.value properties can hold actors) // - it's a highlightRegistryEntry (the preview.value properties can hold actors) // - or it is already a front (happens when we are using the legacy listeners in the ResourceCommand) const isPacketAnObject = packet && typeof packet === "object"; const isFront = !!packet?.typeName; if (
!isPacketAnObject ||
packet.type == "symbol" ||
(packet.type !== "mapEntry" &&
packet.type !== "highlightRegistryEntry" &&
!packet.actor) ||
isFront
) { return packet;
}
const { conn } = parentFront; // If the parent front is a target, consider it as the target to use for all objects const targetFront = parentFront.isTargetFront
? parentFront
: parentFront.targetFront;
// We may have already created a front for this object actor since some actor (e.g. the // thread actor) cache the object actors they create. const existingFront = conn.getFrontByID(packet.actor); if (existingFront) { // This methods replicates Protocol.js logic when we receive an actor "form" (here `packet`): // https://searchfox.org/mozilla-central/rev/aecbd5cdd28a09e11872bc829d9e6e4b943e6e49/devtools/shared/protocol/types.js#346 // We notify the Object Front about the new "form" so that it can update itself // with latest data provided by the server. // This will help ensure that the object previews get updated.
existingFront.form(packet);
// The `packet` may contain nested actor forms which should be converted into Fronts.
createChildFronts(existingFront, packet);
return existingFront;
}
const { type } = packet;
if (type === "longString") { const longStringFront = new LongStringFront(conn, targetFront, parentFront);
longStringFront.form(packet);
parentFront.manage(longStringFront); return longStringFront;
}
/** * Create child fronts of the passed object front given a packet. Those child fronts are * usually mapping actors of the packet sub-properties (preview items, promise fullfilled * values, …). * * @param {ObjectFront} objectFront * @param {String|Number|Object} packet: The packet returned by the server
*/ function createChildFronts(objectFront, packet) { if (packet.preview) { const { message, entries } = packet.preview;
// The message could be a longString. if (packet.preview.message) {
packet.preview.message = getAdHocFrontOrPrimitiveGrip(
message,
objectFront
);
}
// Handle Map/WeakMap preview entries (the preview might be directly used if has all the // items needed, i.e. if the Map has less than 10 items). if (entries && Array.isArray(entries)) {
packet.preview.entries = entries.map(([key, value]) => [
getAdHocFrontOrPrimitiveGrip(key, objectFront),
getAdHocFrontOrPrimitiveGrip(value, objectFront),
]);
}
}
if (packet && typeof packet.ownProperties === "object") { for (const [name, descriptor] of Object.entries(packet.ownProperties)) { // The descriptor can have multiple properties that hold grips which we may need // to turn into fronts. const gripKeys = ["value", "getterValue", "get", "set"]; for (const key of gripKeys) { if (
descriptor && typeof descriptor === "object" &&
descriptor.hasOwnProperty(key)
) {
packet.ownProperties[name][key] = getAdHocFrontOrPrimitiveGrip(
descriptor[key],
objectFront
);
}
}
}
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.7Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.