Skip to content

Instantly share code, notes, and snippets.

@rpl rpl/.gitignore
Last active Aug 29, 2015

What would you like to do?
JEP DevTools SDK Director



DevTools Addons should be able to support remote targets (e.g. Firefox OS Devices/Simulators, Firefox for Android) and local targets without changes in their own addon code, the Director helps addons developers to inject their instrumentation code to the target tab, local or remote.

Using the Director API an addon developer can install/uninstall instrumentation code modules.

The instrumentation code modules live in a Content Script running on the remote target side:

  • can be activated (instrumenter.setup) and deactivated (instrumenter.finalize)
  • will be automatically attached/detached on tab navigation
  • has direct access to target tab window and document objects
  • evaluate javascript in the target tab javascript context (using the evalInWindow function)
  • send and receive custom events with the devtool addon using a MessagePort


PROPOSED: Install a new Instrumenter


const { Panel } = require("dev/panel");
const { Tool } = require("dev/toolbox");
const { ContentScriptInstrumenter } = require("devtools/director");

const customInstrumenter = ContentScriptInstrumenter({
  id: "customInstrumenter",
  contentScriptOptions: {
    inPageScript: "...",
    enabledFeatureX: false

const CustomPanel = ...

const myCustomDevTools = new Tool({
  instrumenters: [customInstrumenter],
  panels: { custom: CustomPanel }


// NOTE: temporary solution to give a MessagePort to the instrumenter content script
self.on("connectPort", function (port) {
  port.onmessage = function (evt) {
    ... // react to the evt, use
    evt.source.postMessage(reply); // reply using evt.source
  // and/or send a message immediately
  port.postMessage("your instrumenter is ready");

Use an installed Instrumenter (in the devtool panel using volcan)

var root = yield volcan.connect(dbgPort);
var list = yield root.listTabs();
var selectedTab = list.tabs[list.selected];

var instrumenter = selectedTab.directorActor.getInstrumenter("customInstrumenter");

instrumenter.on("attach", function ({innerId, url, port) {
  // handle message from the received messageport client
  var handleMessage = function (evt) {
    console.log("RECEIVED EVT",;
    evt.source.postMessage({"attr": "reply"});
  // remove event handler from messageport client on detach
  instrumenter.once("detach", () =>"meesage", handleMessage));
  // add event handler on messageport client event  
  port.on("message", handleMessage);
  // start queue messages

PROPOSED: Configure support for remote target on Devtool Panels


MyDevtoolPanel = Class({
  extends: Panel,
  name: "my-devtool-panel",
  label: "MyDevtoolPanel",
  tooltip: "My Devtool Panel",
  icon: "./img/webstore-icon.png",
  url: "./panel.html",
  // NOTE: this panel supports local and remote tabs and apps
  // and does not support addons at all
  supportedTarget: {
    local: true,
    remote: true,
    tab: true,
    app: true,
    addon: false
  setup: function({debuggee, toolboxTarget}) {
    this.debuggee = debuggee;
    this.toolboxTarget = toolboxTarget;
  dispose: function() {
    delete this.debuggee;
  onReady: function() {
      type: "RDP",
      // NOTE: we should pass to volcan enough info to be able to detect the
      // toolbox target on the debugee connection (which currently is not the toolbox connection)
      toolboxTarget: this.toolboxTarget
    }, [this.debuggee]);

Possible New Features

  • expose CallWatcher features to the instrumenter content script (it could help in a lot of common instrumentation use cases)


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.