Skip to content

Instantly share code, notes, and snippets.

@cbrem
Last active August 29, 2015 14:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cbrem/4c17d7e278412412b12c to your computer and use it in GitHub Desktop.
Save cbrem/4c17d7e278412412b12c to your computer and use it in GitHub Desktop.
Inspector High-Level API

Model

The Inspector API models an Inspector as a group of trees. Each tree has a root, which corresponds to a Scope in the VariablesView. Each tree is componsed of Nodes, one of which is the root. A tree is a UI element.

A tree is similar to, but distinct from, the object under inspection which it represents. Programmers can traverse trees using the parent and children properties of Nodes. The values of these properties represent what is shown in the UI, not necessarily what is true about the object under inspection. All information about the object under inspection must be retrived via ansynchronous object clients, which are bound to Nodes when the Nodes are created.

Communication between an Inspector tree UI and the object under inspection happens via two methods:

  • Inspector.onEdit: fires when a (key, value) pair changes in the UI, and causes changes to the object under inspection.
  • Inspector.addChild: is set from the object under inspection as part of populating the tree UI. It binds a Node to a client, which will be used to query the object under inspection for further UI population.

Objects under inspection can come from one of many Inspector.sources, such as the Webconsole or Debugger backends.

Static Properties

/*
 * An enum of sources for input to the Inspector.
 */
sources: Object

Properties

/* The tab to which this VariablesView is attached. */
tab : Tab

/*
 * The component in which this VariablesView is embedded.
 * Could be Webconsole, Debugger, etc.
 */
source : Inspector.sources

/*
 * The label which this VariablesView displays.
 */
label : string

Static Methods

/*
 * Retrieves a map from `Inspector` sources to `Inspector`s within the given SDK `Tab`.
 */
getInspectors( tab : Tab ) : { Inspector.source : Inspector }

Methods

/*
 * Manage the `Inspector`'s roots (i.e. `Scopes` from the `VariablesView`.)
 */
getRoots() : promise([Node])

/*
 * Adds a child to the given `parent` (which may be a root).
 * This child will be another `Node` with the given `name`.
 * Whenever this client is first expanded, it will populate itself with the given `client`.
 *
 * This call may originate from an `Inspector.source`, and will cause updates to the UI.
 */
addChild(parent : Node, name : string, client : client.Object) : promise()

/*
 * Called when the `Inspector` UI updates a `(key, value)` pair.
 * `Node` is the parent of this pair.
 * 
 * Unlike `addChild`, this call originates from the UI and will cause updates to an `Inspector.source`.
 * 
 * TODO: maybe take client as an input instead of Node?
 */
onEdit(node : Node, key : string, value : string) : promise()

Node

A node is a struct that contains information about one tree element. Nodes have the following properties.

/*
 * The `Node` above this one, or null if it is a root.
 * Not settable.
 */
parent : Node | null

/*
 * This node's children.
 * Not settable.
 */
children : [Node]

/*
 * The `Node`'s name.
 * Not settable later.
 */
name : string

/*
 * A handle for asynchronously retrieving information about this `Node`'s value.
 * Set in `addChild`.
 * Not settable later.
 */
client : client.Object

/*
 * Determines whether the `Node` is expanded.
 * Settable.
 */
expanded : boolean

##Overview

An Inspector will be a high-level, extensible representation of the VariablesView. It breaks out the VariablesView into a simpler object, but retains the VariablesView's basic structure: the view contains Scopes, which contain Variables, which contain Properties. Users (addon developers) can define their own class, which should inherit from Inspector in order to override some of the default VariablesView behavior.

Inspectors use a client.Object to allow users to interface with debugees across the devtools barrier.

const isPrivate = x => x.startsWith("_");
const isntPrivate = x => !isPrivate(x);
const pick = (x, names) => names.reduce((y, name) => {
y[name] = x[name];
return y;
}, {});
const publicFields = x => pick(x, Object.keys(x).filter(isntPrivate));
const isClient = x => x instanceof client.Object
const PublicFieldsClient = Class({
initialize: function initialize(client) {
this._client = client;
},
keys: function keys() {
let deferred = promise.defer();
this._client.keys().then(keys => {
deferred.resolve(publicFields(keys));
});
return deferred.promise;
},
descriptor: function descriptor(key) this._client.descriptor(key),
prototype: function prototype() this._client.prototype()
});
const PublicFieldsInspector = Class({
extends: Inspector,
sources: [Inspector.sources.Webconsole, Inspector.sources.Debugger],
addChild: (node, name, client) => {
let publicFieldsClient = PublicFieldsClient(client);
return Inspector.prototype.addChild.call(this, node, name, publicFieldsClient);
}
});
const publicFieldsTool = new Tool({
inspectors: { publicFields: PublicFieldsInspector }
});
@jsantell
Copy link

What is Inspector.properties in the getProperties override? is that a static method? is that the prototype original, in which case Inspector.prototype.properties method? And I think that the resolve there should be a filter over properties, not prototype (undefined), right?

@jsantell
Copy link

What is the Tool constructor? Is inspectors are defined special property, and is an object of different inspector mutators, where the key is a just a named value?

@cbrem
Copy link
Author

cbrem commented Jul 15, 2014

Jordan, the things that you pointed out in your first comment were typos. My bad! I fixed those. It's work noting that this interface condenses ownProperties and prototype into just properties for simplicity.
And the Tool constructor is from Irakli's devtools SDK work. Currently it just takes Panels as input, but it seems to make sense that a Tool can include Inspector objects, too. I'll update the Tool constructor to contain inspectors as a named property.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment