Backed out changeset 894e40121370 (bug 917226) for mochitest-chrome failures
☠☠ backed out by 955336deb0ff ☠ ☠
authorEd Morley <emorley@mozilla.com>
Thu, 27 Mar 2014 16:11:59 +0000
changeset 175641 882b91ce5a9fee04ad015dcc8bf6bd40048aa414
parent 175640 c24b05af9a3999edc6cf2a760be54de8c7815f0e
child 175642 9c456120ed575d39e6a52543077992ec8c017521
push id5964
push useremorley@mozilla.com
push dateThu, 27 Mar 2014 16:12:19 +0000
treeherderfx-team@882b91ce5a9f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs917226
milestone31.0a1
backs out894e4012137063861210ef5372facd82a04b6798
Backed out changeset 894e40121370 (bug 917226) for mochitest-chrome failures
browser/app/profile/firefox.js
browser/devtools/canvasdebugger/canvasdebugger.js
browser/devtools/canvasdebugger/canvasdebugger.xul
browser/devtools/canvasdebugger/moz.build
browser/devtools/canvasdebugger/panel.js
browser/devtools/canvasdebugger/test/browser.ini
browser/devtools/canvasdebugger/test/browser_canvas-actor-test-01.js
browser/devtools/canvasdebugger/test/browser_canvas-actor-test-02.js
browser/devtools/canvasdebugger/test/browser_canvas-actor-test-03.js
browser/devtools/canvasdebugger/test/browser_canvas-actor-test-04.js
browser/devtools/canvasdebugger/test/browser_canvas-actor-test-05.js
browser/devtools/canvasdebugger/test/browser_canvas-actor-test-06.js
browser/devtools/canvasdebugger/test/browser_canvas-actor-test-07.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-highlight.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-list.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-search.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-stack-01.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-stack-02.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-stack-03.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-clear.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-img-screenshots.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-img-thumbnails-01.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-img-thumbnails-02.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-open.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-record-01.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-record-02.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-record-03.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-reload-01.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-reload-02.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-slider-01.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-slider-02.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-snapshot-select.js
browser/devtools/canvasdebugger/test/browser_canvas-frontend-stepping.js
browser/devtools/canvasdebugger/test/doc_simple-canvas-deep-stack.html
browser/devtools/canvasdebugger/test/doc_simple-canvas-transparent.html
browser/devtools/canvasdebugger/test/doc_simple-canvas.html
browser/devtools/canvasdebugger/test/head.js
browser/devtools/canvasdebugger/test/moz.build
browser/devtools/debugger/debugger-view.js
browser/devtools/debugger/debugger.xul
browser/devtools/debugger/panel.js
browser/devtools/debugger/test/head.js
browser/devtools/jar.mn
browser/devtools/main.js
browser/devtools/moz.build
browser/devtools/netmonitor/netmonitor-controller.js
browser/devtools/netmonitor/panel.js
browser/devtools/shadereditor/moz.build
browser/devtools/shadereditor/panel.js
browser/devtools/shadereditor/shadereditor.js
browser/devtools/shared/widgets/ViewHelpers.jsm
browser/locales/en-US/chrome/browser/devtools/canvasdebugger.dtd
browser/locales/en-US/chrome/browser/devtools/canvasdebugger.properties
browser/locales/jar.mn
browser/themes/linux/devtools/canvasdebugger.css
browser/themes/linux/jar.mn
browser/themes/osx/devtools/canvasdebugger.css
browser/themes/osx/jar.mn
browser/themes/shared/devtools/canvasdebugger.inc.css
browser/themes/shared/devtools/toolbars.inc.css
browser/themes/shared/devtools/widgets.inc.css
browser/themes/windows/devtools/canvasdebugger.css
browser/themes/windows/jar.mn
toolkit/devtools/DevToolsUtils.js
toolkit/devtools/Loader.jsm
toolkit/devtools/content-observer.js
toolkit/devtools/server/actors/call-watcher.js
toolkit/devtools/server/actors/canvas.js
toolkit/devtools/server/actors/webgl.js
toolkit/devtools/server/main.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1200,19 +1200,16 @@ pref("devtools.scratchpad.enableCodeFold
 // Enable the Style Editor.
 pref("devtools.styleeditor.enabled", true);
 pref("devtools.styleeditor.source-maps-enabled", false);
 pref("devtools.styleeditor.autocompletion-enabled", true);
 
 // Enable the Shader Editor.
 pref("devtools.shadereditor.enabled", false);
 
-// Enable the Canvas Debugger.
-pref("devtools.canvasdebugger.enabled", false);
-
 // Enable tools for Chrome development.
 pref("devtools.chrome.enabled", false);
 
 // Default theme ("dark" or "light")
 pref("devtools.theme", "light");
 
 // Display the introductory text
 pref("devtools.gcli.hideIntro", false);
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/canvasdebugger.js
+++ /dev/null
@@ -1,1270 +0,0 @@
-/* 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 { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-
-Cu.import("resource://gre/modules/Services.jsm");
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource:///modules/devtools/SideMenuWidget.jsm");
-Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
-
-const require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
-const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
-const EventEmitter = require("devtools/toolkit/event-emitter");
-const { CallWatcherFront } = require("devtools/server/actors/call-watcher");
-const { CanvasFront } = require("devtools/server/actors/canvas");
-
-XPCOMUtils.defineLazyModuleGetter(this, "Task",
-  "resource://gre/modules/Task.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
-  "resource://gre/modules/PluralForm.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
-  "resource://gre/modules/FileUtils.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "NetUtil",
-  "resource://gre/modules/NetUtil.jsm");
-
-XPCOMUtils.defineLazyModuleGetter(this, "DevToolsUtils",
-  "resource://gre/modules/devtools/DevToolsUtils.jsm");
-
-// The panel's window global is an EventEmitter firing the following events:
-const EVENTS = {
-  // When the UI is reset from tab navigation.
-  UI_RESET: "CanvasDebugger:UIReset",
-
-  // When all the animation frame snapshots are removed by the user.
-  SNAPSHOTS_LIST_CLEARED: "CanvasDebugger:SnapshotsListCleared",
-
-  // When an animation frame snapshot starts/finishes being recorded.
-  SNAPSHOT_RECORDING_STARTED: "CanvasDebugger:SnapshotRecordingStarted",
-  SNAPSHOT_RECORDING_FINISHED: "CanvasDebugger:SnapshotRecordingFinished",
-
-  // When an animation frame snapshot was selected and all its data displayed.
-  SNAPSHOT_RECORDING_SELECTED: "CanvasDebugger:SnapshotRecordingSelected",
-
-  // After all the function calls associated with an animation frame snapshot
-  // are displayed in the UI.
-  CALL_LIST_POPULATED: "CanvasDebugger:CallListPopulated",
-
-  // After the stack associated with a call in an animation frame snapshot
-  // is displayed in the UI.
-  CALL_STACK_DISPLAYED: "CanvasDebugger:CallStackDisplayed",
-
-  // After a screenshot associated with a call in an animation frame snapshot
-  // is displayed in the UI.
-  CALL_SCREENSHOT_DISPLAYED: "CanvasDebugger:ScreenshotDisplayed",
-
-  // After all the thumbnails associated with an animation frame snapshot
-  // are displayed in the UI.
-  THUMBNAILS_DISPLAYED: "CanvasDebugger:ThumbnailsDisplayed",
-
-  // When a source is shown in the JavaScript Debugger at a specific location.
-  SOURCE_SHOWN_IN_JS_DEBUGGER: "CanvasDebugger:SourceShownInJsDebugger",
-  SOURCE_NOT_FOUND_IN_JS_DEBUGGER: "CanvasDebugger:SourceNotFoundInJsDebugger"
-};
-
-const HTML_NS = "http://www.w3.org/1999/xhtml";
-const STRINGS_URI = "chrome://browser/locale/devtools/canvasdebugger.properties"
-
-const SNAPSHOT_START_RECORDING_DELAY = 10; // ms
-const SNAPSHOT_DATA_EXPORT_MAX_BLOCK = 1000; // ms
-const SNAPSHOT_DATA_DISPLAY_DELAY = 10; // ms
-const SCREENSHOT_DISPLAY_DELAY = 100; // ms
-const STACK_FUNC_INDENTATION = 14; // px
-
-// This identifier string is simply used to tentatively ascertain whether or not
-// a JSON loaded from disk is actually something generated by this tool or not.
-// It isn't, of course, a definitive verification, but a Good Enough™
-// approximation before continuing the import. Don't localize this.
-const CALLS_LIST_SERIALIZER_IDENTIFIER = "Recorded Animation Frame Snapshot";
-const CALLS_LIST_SERIALIZER_VERSION = 1;
-const CALLS_LIST_SLOW_SAVE_DELAY = 100; // ms
-
-/**
- * The current target and the Canvas front, set by this tool's host.
- */
-let gToolbox, gTarget, gFront;
-
-/**
- * Initializes the canvas debugger controller and views.
- */
-function startupCanvasDebugger() {
-  return promise.all([
-    EventsHandler.initialize(),
-    SnapshotsListView.initialize(),
-    CallsListView.initialize()
-  ]);
-}
-
-/**
- * Destroys the canvas debugger controller and views.
- */
-function shutdownCanvasDebugger() {
-  return promise.all([
-    EventsHandler.destroy(),
-    SnapshotsListView.destroy(),
-    CallsListView.destroy()
-  ]);
-}
-
-/**
- * Functions handling target-related lifetime events.
- */
-let EventsHandler = {
-  /**
-   * Listen for events emitted by the current tab target.
-   */
-  initialize: function() {
-    this._onTabNavigated = this._onTabNavigated.bind(this);
-    gTarget.on("will-navigate", this._onTabNavigated);
-    gTarget.on("navigate", this._onTabNavigated);
-  },
-
-  /**
-   * Remove events emitted by the current tab target.
-   */
-  destroy: function() {
-    gTarget.off("will-navigate", this._onTabNavigated);
-    gTarget.off("navigate", this._onTabNavigated);
-  },
-
-  /**
-   * Called for each location change in the debugged tab.
-   */
-  _onTabNavigated: function(event) {
-    if (event != "will-navigate") {
-      return;
-    }
-    // Make sure the backend is prepared to handle <canvas> contexts.
-    gFront.setup({ reload: false });
-
-    // Reset UI.
-    SnapshotsListView.empty();
-    CallsListView.empty();
-
-    $("#record-snapshot").removeAttribute("checked");
-    $("#record-snapshot").removeAttribute("disabled");
-    $("#record-snapshot").hidden = false;
-
-    $("#reload-notice").hidden = true;
-    $("#empty-notice").hidden = false;
-    $("#import-notice").hidden = true;
-
-    $("#debugging-pane-contents").hidden = true;
-    $("#screenshot-container").hidden = true;
-    $("#snapshot-filmstrip").hidden = true;
-
-    window.emit(EVENTS.UI_RESET);
-  }
-};
-
-/**
- * Functions handling the recorded animation frame snapshots UI.
- */
-let SnapshotsListView = Heritage.extend(WidgetMethods, {
-  /**
-   * Initialization function, called when the tool is started.
-   */
-  initialize: function() {
-    this.widget = new SideMenuWidget($("#snapshots-list"), {
-      showArrows: true
-    });
-
-    this._onSelect = this._onSelect.bind(this);
-    this._onClearButtonClick = this._onClearButtonClick.bind(this);
-    this._onRecordButtonClick = this._onRecordButtonClick.bind(this);
-    this._onImportButtonClick = this._onImportButtonClick.bind(this);
-    this._onSaveButtonClick = this._onSaveButtonClick.bind(this);
-
-    this.emptyText = L10N.getStr("noSnapshotsText");
-    this.widget.addEventListener("select", this._onSelect, false);
-  },
-
-  /**
-   * Destruction function, called when the tool is closed.
-   */
-  destroy: function() {
-    this.widget.removeEventListener("select", this._onSelect, false);
-  },
-
-  /**
-   * Adds a snapshot entry to this container.
-   *
-   * @return object
-   *         The newly inserted item.
-   */
-  addSnapshot: function() {
-    let contents = document.createElement("hbox");
-    contents.className = "snapshot-item";
-
-    let thumbnail = document.createElementNS(HTML_NS, "canvas");
-    thumbnail.className = "snapshot-item-thumbnail";
-    thumbnail.width = CanvasFront.THUMBNAIL_HEIGHT;
-    thumbnail.height = CanvasFront.THUMBNAIL_HEIGHT;
-
-    let title = document.createElement("label");
-    title.className = "plain snapshot-item-title";
-    title.setAttribute("value",
-      L10N.getFormatStr("snapshotsList.itemLabel", this.itemCount + 1));
-
-    let calls = document.createElement("label");
-    calls.className = "plain snapshot-item-calls";
-    calls.setAttribute("value",
-      L10N.getStr("snapshotsList.loadingLabel"));
-
-    let save = document.createElement("label");
-    save.className = "plain snapshot-item-save";
-    save.addEventListener("click", this._onSaveButtonClick, false);
-
-    let spacer = document.createElement("spacer");
-    spacer.setAttribute("flex", "1");
-
-    let footer = document.createElement("hbox");
-    footer.className = "snapshot-item-footer";
-    footer.appendChild(save);
-
-    let details = document.createElement("vbox");
-    details.className = "snapshot-item-details";
-    details.appendChild(title);
-    details.appendChild(calls);
-    details.appendChild(spacer);
-    details.appendChild(footer);
-
-    contents.appendChild(thumbnail);
-    contents.appendChild(details);
-
-    // Append a recorded snapshot item to this container.
-    return this.push([contents], {
-      attachment: {
-        // The snapshot and function call actors, along with the thumbnails
-        // will be available as soon as recording finishes.
-        actor: null,
-        calls: null,
-        thumbnails: null,
-        screenshot: null
-      }
-    });
-  },
-
-  /**
-   * Customizes a shapshot in this container.
-   *
-   * @param Item snapshotItem
-   *        An item inserted via `SnapshotsListView.addSnapshot`.
-   * @param object snapshotActor
-   *        The frame snapshot actor received from the backend.
-   * @param object snapshotOverview
-   *        Additional data about the snapshot received from the backend.
-   */
-  customizeSnapshot: function(snapshotItem, snapshotActor, snapshotOverview) {
-    // Make sure the function call actors are stored on the item,
-    // to be used when populating the CallsListView.
-    snapshotItem.attachment.actor = snapshotActor;
-    let functionCalls = snapshotItem.attachment.calls = snapshotOverview.calls;
-    let thumbnails = snapshotItem.attachment.thumbnails = snapshotOverview.thumbnails;
-    let screenshot = snapshotItem.attachment.screenshot = snapshotOverview.screenshot;
-
-    let lastThumbnail = thumbnails[thumbnails.length - 1];
-    let { width, height, flipped, pixels } = lastThumbnail;
-
-    let thumbnailNode = $(".snapshot-item-thumbnail", snapshotItem.target);
-    thumbnailNode.setAttribute("flipped", flipped);
-    drawImage(thumbnailNode, width, height, pixels, { centered: true });
-
-    let callsNode = $(".snapshot-item-calls", snapshotItem.target);
-    let drawCalls = functionCalls.filter(e => CanvasFront.DRAW_CALLS.has(e.name));
-
-    let drawCallsStr = PluralForm.get(drawCalls.length,
-      L10N.getStr("snapshotsList.drawCallsLabel"));
-    let funcCallsStr = PluralForm.get(functionCalls.length,
-      L10N.getStr("snapshotsList.functionCallsLabel"));
-
-    callsNode.setAttribute("value",
-      drawCallsStr.replace("#1", drawCalls.length) + ", " +
-      funcCallsStr.replace("#1", functionCalls.length));
-
-    let saveNode = $(".snapshot-item-save", snapshotItem.target);
-    saveNode.setAttribute("disabled", !!snapshotItem.isLoadedFromDisk);
-    saveNode.setAttribute("value", snapshotItem.isLoadedFromDisk
-      ? L10N.getStr("snapshotsList.loadedLabel")
-      : L10N.getStr("snapshotsList.saveLabel"));
-
-    // Make sure there's always a selected item available.
-    if (!this.selectedItem) {
-      this.selectedIndex = 0;
-    }
-  },
-
-  /**
-   * The select listener for this container.
-   */
-  _onSelect: function({ detail: snapshotItem }) {
-    if (!snapshotItem) {
-      return;
-    }
-    let { calls, thumbnails, screenshot } = snapshotItem.attachment;
-
-    $("#reload-notice").hidden = true;
-    $("#empty-notice").hidden = true;
-    $("#import-notice").hidden = false;
-
-    $("#debugging-pane-contents").hidden = true;
-    $("#screenshot-container").hidden = true;
-    $("#snapshot-filmstrip").hidden = true;
-
-    Task.spawn(function*() {
-      // Wait for a few milliseconds between presenting the function calls,
-      // screenshot and thumbnails, to allow each component being
-      // sequentially drawn. This gives the illusion of snappiness.
-
-      yield DevToolsUtils.waitForTime(SNAPSHOT_DATA_DISPLAY_DELAY);
-      CallsListView.showCalls(calls);
-      $("#debugging-pane-contents").hidden = false;
-      $("#import-notice").hidden = true;
-
-      yield DevToolsUtils.waitForTime(SNAPSHOT_DATA_DISPLAY_DELAY);
-      CallsListView.showThumbnails(thumbnails);
-      $("#snapshot-filmstrip").hidden = false;
-
-      yield DevToolsUtils.waitForTime(SNAPSHOT_DATA_DISPLAY_DELAY);
-      CallsListView.showScreenshot(screenshot);
-      $("#screenshot-container").hidden = false;
-
-      window.emit(EVENTS.SNAPSHOT_RECORDING_SELECTED);
-    });
-  },
-
-  /**
-   * The click listener for the "clear" button in this container.
-   */
-  _onClearButtonClick: function() {
-    Task.spawn(function*() {
-      SnapshotsListView.empty();
-      CallsListView.empty();
-
-      $("#reload-notice").hidden = true;
-      $("#empty-notice").hidden = true;
-      $("#import-notice").hidden = true;
-
-      if (yield gFront.isInitialized()) {
-        $("#empty-notice").hidden = false;
-      } else {
-        $("#reload-notice").hidden = false;
-      }
-
-      $("#debugging-pane-contents").hidden = true;
-      $("#screenshot-container").hidden = true;
-      $("#snapshot-filmstrip").hidden = true;
-
-      window.emit(EVENTS.SNAPSHOTS_LIST_CLEARED);
-    });
-  },
-
-  /**
-   * The click listener for the "record" button in this container.
-   */
-  _onRecordButtonClick: function() {
-    Task.spawn(function*() {
-      $("#record-snapshot").setAttribute("checked", "true");
-      $("#record-snapshot").setAttribute("disabled", "true");
-
-      // Insert a "dummy" snapshot item in the view, to hint that recording
-      // has now started. However, wait for a few milliseconds before actually
-      // starting the recording, since that might block rendering and prevent
-      // the dummy snapshot item from being drawn.
-      let snapshotItem = this.addSnapshot();
-
-      // If this is the first item, immediately show the "Loading…" notice.
-      if (this.itemCount == 1) {
-        $("#empty-notice").hidden = true;
-        $("#import-notice").hidden = false;
-      }
-
-      yield DevToolsUtils.waitForTime(SNAPSHOT_START_RECORDING_DELAY);
-      window.emit(EVENTS.SNAPSHOT_RECORDING_STARTED);
-
-      let snapshotActor = yield gFront.recordAnimationFrame();
-      let snapshotOverview = yield snapshotActor.getOverview();
-      this.customizeSnapshot(snapshotItem, snapshotActor, snapshotOverview);
-
-      $("#record-snapshot").removeAttribute("checked");
-      $("#record-snapshot").removeAttribute("disabled");
-
-      window.emit(EVENTS.SNAPSHOT_RECORDING_FINISHED);
-    }.bind(this));
-  },
-
-  /**
-   * The click listener for the "import" button in this container.
-   */
-  _onImportButtonClick: function() {
-    let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
-    fp.init(window, L10N.getStr("snapshotsList.saveDialogTitle"), Ci.nsIFilePicker.modeOpen);
-    fp.appendFilter(L10N.getStr("snapshotsList.saveDialogJSONFilter"), "*.json");
-    fp.appendFilter(L10N.getStr("snapshotsList.saveDialogAllFilter"), "*.*");
-
-    if (fp.show() != Ci.nsIFilePicker.returnOK) {
-      return;
-    }
-
-    let channel = NetUtil.newChannel(fp.file);
-    channel.contentType = "text/plain";
-
-    NetUtil.asyncFetch(channel, (inputStream, status) => {
-      if (!Components.isSuccessCode(status)) {
-        console.error("Could not import recorded animation frame snapshot file.");
-        return;
-      }
-      try {
-        let string = NetUtil.readInputStreamToString(inputStream, inputStream.available());
-        var data = JSON.parse(string);
-      } catch (e) {
-        console.error("Could not read animation frame snapshot file.");
-        return;
-      }
-      if (data.fileType != CALLS_LIST_SERIALIZER_IDENTIFIER) {
-        console.error("Unrecognized animation frame snapshot file.");
-        return;
-      }
-
-      // Add a `isLoadedFromDisk` flag on everything to avoid sending invalid
-      // requests to the backend, since we're not dealing with actors anymore.
-      let snapshotItem = this.addSnapshot();
-      snapshotItem.isLoadedFromDisk = true;
-      data.calls.forEach(e => e.isLoadedFromDisk = true);
-
-      // Create array buffers from the parsed pixel arrays.
-      for (let thumbnail of data.thumbnails) {
-        let thumbnailPixelsArray = thumbnail.pixels.split(",");
-        thumbnail.pixels = new Uint32Array(thumbnailPixelsArray);
-      }
-      let screenshotPixelsArray = data.screenshot.pixels.split(",");
-      data.screenshot.pixels = new Uint32Array(screenshotPixelsArray);
-
-      this.customizeSnapshot(snapshotItem, data.calls, data);
-    });
-  },
-
-  /**
-   * The click listener for the "save" button of each item in this container.
-   */
-  _onSaveButtonClick: function(e) {
-    let snapshotItem = this.getItemForElement(e.target);
-
-    let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
-    fp.init(window, L10N.getStr("snapshotsList.saveDialogTitle"), Ci.nsIFilePicker.modeSave);
-    fp.appendFilter(L10N.getStr("snapshotsList.saveDialogJSONFilter"), "*.json");
-    fp.appendFilter(L10N.getStr("snapshotsList.saveDialogAllFilter"), "*.*");
-    fp.defaultString = "snapshot.json";
-
-    // Start serializing all the function call actors for the specified snapshot,
-    // while the nsIFilePicker dialog is being opened. Snappy.
-    let serialized = Task.spawn(function*() {
-      let data = {
-        fileType: CALLS_LIST_SERIALIZER_IDENTIFIER,
-        version: CALLS_LIST_SERIALIZER_VERSION,
-        calls: [],
-        thumbnails: [],
-        screenshot: null
-      };
-      let functionCalls = snapshotItem.attachment.calls;
-      let thumbnails = snapshotItem.attachment.thumbnails;
-      let screenshot = snapshotItem.attachment.screenshot;
-
-      // Prepare all the function calls for serialization.
-      yield DevToolsUtils.yieldingEach(functionCalls, (call, i) => {
-        let { type, name, file, line, argsPreview, callerPreview } = call;
-        return call.getDetails().then(({ stack }) => {
-          data.calls[i] = {
-            type: type,
-            name: name,
-            file: file,
-            line: line,
-            stack: stack,
-            argsPreview: argsPreview,
-            callerPreview: callerPreview
-          };
-        });
-      });
-
-      // Prepare all the thumbnails for serialization.
-      yield DevToolsUtils.yieldingEach(thumbnails, (thumbnail, i) => {
-        let { index, width, height, flipped, pixels } = thumbnail;
-        data.thumbnails.push({
-          index: index,
-          width: width,
-          height: height,
-          flipped: flipped,
-          pixels: Array.join(pixels, ",")
-        });
-      });
-
-      // Prepare the screenshot for serialization.
-      let { index, width, height, flipped, pixels } = screenshot;
-      data.screenshot = {
-        index: index,
-        width: width,
-        height: height,
-        flipped: flipped,
-        pixels: Array.join(pixels, ",")
-      };
-
-      let string = JSON.stringify(data);
-      let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
-        createInstance(Ci.nsIScriptableUnicodeConverter);
-
-      converter.charset = "UTF-8";
-      return converter.convertToInputStream(string);
-    });
-
-    // Open the nsIFilePicker and wait for the function call actors to finish
-    // being serialized, in order to save the generated JSON data to disk.
-    fp.open({ done: result => {
-      if (result == Ci.nsIFilePicker.returnCancel) {
-        return;
-      }
-      let footer = $(".snapshot-item-footer", snapshotItem.target);
-      let save = $(".snapshot-item-save", snapshotItem.target);
-
-      // Show a throbber and a "Saving…" label if serializing isn't immediate.
-      setNamedTimeout("call-list-save", CALLS_LIST_SLOW_SAVE_DELAY, () => {
-        footer.setAttribute("saving", "");
-        save.setAttribute("disabled", "true");
-        save.setAttribute("value", L10N.getStr("snapshotsList.savingLabel"));
-      });
-
-      serialized.then(inputStream => {
-        let outputStream = FileUtils.openSafeFileOutputStream(fp.file);
-
-        NetUtil.asyncCopy(inputStream, outputStream, status => {
-          if (!Components.isSuccessCode(status)) {
-            console.error("Could not save recorded animation frame snapshot file.");
-          }
-          clearNamedTimeout("call-list-save");
-          footer.removeAttribute("saving");
-          save.removeAttribute("disabled");
-          save.setAttribute("value", L10N.getStr("snapshotsList.saveLabel"));
-        });
-      });
-    }});
-  }
-});
-
-/**
- * Functions handling details about a single recorded animation frame snapshot
- * (the calls list, rendering preview, thumbnails filmstrip etc.).
- */
-let CallsListView = Heritage.extend(WidgetMethods, {
-  /**
-   * Initialization function, called when the tool is started.
-   */
-  initialize: function() {
-    this.widget = new SideMenuWidget($("#calls-list"));
-    this._slider = $("#calls-slider");
-    this._searchbox = $("#calls-searchbox");
-    this._filmstrip = $("#snapshot-filmstrip");
-
-    this._onSelect = this._onSelect.bind(this);
-    this._onSlideMouseDown = this._onSlideMouseDown.bind(this);
-    this._onSlideMouseUp = this._onSlideMouseUp.bind(this);
-    this._onSlide = this._onSlide.bind(this);
-    this._onSearch = this._onSearch.bind(this);
-    this._onScroll = this._onScroll.bind(this);
-    this._onExpand = this._onExpand.bind(this);
-    this._onStackFileClick = this._onStackFileClick.bind(this);
-    this._onThumbnailClick = this._onThumbnailClick.bind(this);
-
-    this.widget.addEventListener("select", this._onSelect, false);
-    this._slider.addEventListener("mousedown", this._onSlideMouseDown, false);
-    this._slider.addEventListener("mouseup", this._onSlideMouseUp, false);
-    this._slider.addEventListener("change", this._onSlide, false);
-    this._searchbox.addEventListener("input", this._onSearch, false);
-    this._filmstrip.addEventListener("wheel", this._onScroll, false);
-  },
-
-  /**
-   * Destruction function, called when the tool is closed.
-   */
-  destroy: function() {
-    this.widget.removeEventListener("select", this._onSelect, false);
-    this._slider.removeEventListener("mousedown", this._onSlideMouseDown, false);
-    this._slider.removeEventListener("mouseup", this._onSlideMouseUp, false);
-    this._slider.removeEventListener("change", this._onSlide, false);
-    this._searchbox.removeEventListener("input", this._onSearch, false);
-    this._filmstrip.removeEventListener("wheel", this._onScroll, false);
-  },
-
-  /**
-   * Populates this container with a list of function calls.
-   *
-   * @param array functionCalls
-   *        A list of function call actors received from the backend.
-   */
-  showCalls: function(functionCalls) {
-    this.empty();
-
-    for (let i = 0, len = functionCalls.length; i < len; i++) {
-      let call = functionCalls[i];
-
-      let view = document.createElement("vbox");
-      view.className = "call-item-view devtools-monospace";
-      view.setAttribute("flex", "1");
-
-      let contents = document.createElement("hbox");
-      contents.className = "call-item-contents";
-      contents.setAttribute("align", "center");
-      contents.addEventListener("dblclick", this._onExpand);
-      view.appendChild(contents);
-
-      let index = document.createElement("label");
-      index.className = "plain call-item-index";
-      index.setAttribute("flex", "1");
-      index.setAttribute("value", i + 1);
-
-      let gutter = document.createElement("hbox");
-      gutter.className = "call-item-gutter";
-      gutter.appendChild(index);
-      contents.appendChild(gutter);
-
-      // Not all function calls have a caller that was stringified (e.g.
-      // context calls have a "gl" or "ctx" caller preview).
-      if (call.callerPreview) {
-        let context = document.createElement("label");
-        context.className = "plain call-item-context";
-        context.setAttribute("value", call.callerPreview);
-        contents.appendChild(context);
-
-        let separator = document.createElement("label");
-        separator.className = "plain call-item-separator";
-        separator.setAttribute("value", ".");
-        contents.appendChild(separator);
-      }
-
-      let name = document.createElement("label");
-      name.className = "plain call-item-name";
-      name.setAttribute("value", call.name);
-      contents.appendChild(name);
-
-      let argsPreview = document.createElement("label");
-      argsPreview.className = "plain call-item-args";
-      argsPreview.setAttribute("crop", "end");
-      argsPreview.setAttribute("flex", "100");
-      // Getters and setters are displayed differently from regular methods.
-      if (call.type == CallWatcherFront.METHOD_FUNCTION) {
-        argsPreview.setAttribute("value", "(" + call.argsPreview + ")");
-      } else {
-        argsPreview.setAttribute("value", " = " + call.argsPreview);
-      }
-      contents.appendChild(argsPreview);
-
-      let location = document.createElement("label");
-      location.className = "plain call-item-location";
-      location.setAttribute("value", getFileName(call.file) + ":" + call.line);
-      location.setAttribute("crop", "start");
-      location.setAttribute("flex", "1");
-      location.addEventListener("mousedown", this._onExpand);
-      contents.appendChild(location);
-
-      // Append a function call item to this container.
-      this.push([view], {
-        staged: true,
-        attachment: {
-          actor: call
-        }
-      });
-
-      // Highlight certain calls that are probably more interesting than
-      // everything else, making it easier to quickly glance over them.
-      if (CanvasFront.DRAW_CALLS.has(call.name)) {
-        view.setAttribute("draw-call", "");
-      }
-      if (CanvasFront.INTERESTING_CALLS.has(call.name)) {
-        view.setAttribute("interesting-call", "");
-      }
-    }
-
-    // Flushes all the prepared function call items into this container.
-    this.commit();
-    window.emit(EVENTS.CALL_LIST_POPULATED);
-
-    // Resetting the function selection slider's value (shown in this
-    // container's toolbar) would trigger a selection event, which should be
-    // ignored in this case.
-    this._ignoreSliderChanges = true;
-    this._slider.value = 0;
-    this._slider.max = functionCalls.length - 1;
-    this._ignoreSliderChanges = false;
-  },
-
-  /**
-   * Displays an image in the rendering preview of this container, generated
-   * for the specified draw call in the recorded animation frame snapshot.
-   *
-   * @param array screenshot
-   *        A single "snapshot-image" instance received from the backend.
-   */
-  showScreenshot: function(screenshot) {
-    let { index, width, height, flipped, pixels } = screenshot;
-
-    let screenshotNode = $("#screenshot-image");
-    screenshotNode.setAttribute("flipped", flipped);
-    drawBackground("screenshot-rendering", width, height, pixels);
-
-    let dimensionsNode = $("#screenshot-dimensions");
-    dimensionsNode.setAttribute("value", ~~width + " x " + ~~height);
-
-    window.emit(EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  },
-
-  /**
-   * Populates this container's footer with a list of thumbnails, one generated
-   * for each draw call in the recorded animation frame snapshot.
-   *
-   * @param array thumbnails
-   *        An array of "snapshot-image" instances received from the backend.
-   */
-  showThumbnails: function(thumbnails) {
-    while (this._filmstrip.hasChildNodes()) {
-      this._filmstrip.firstChild.remove();
-    }
-    for (let thumbnail of thumbnails) {
-      this.appendThumbnail(thumbnail);
-    }
-
-    window.emit(EVENTS.THUMBNAILS_DISPLAYED);
-  },
-
-  /**
-   * Displays an image in the thumbnails list of this container, generated
-   * for the specified draw call in the recorded animation frame snapshot.
-   *
-   * @param array thumbnail
-   *        A single "snapshot-image" instance received from the backend.
-   */
-  appendThumbnail: function(thumbnail) {
-    let { index, width, height, flipped, pixels } = thumbnail;
-
-    let thumbnailNode = document.createElementNS(HTML_NS, "canvas");
-    thumbnailNode.setAttribute("flipped", flipped);
-    thumbnailNode.width = Math.max(CanvasFront.THUMBNAIL_HEIGHT, width);
-    thumbnailNode.height = Math.max(CanvasFront.THUMBNAIL_HEIGHT, height);
-    drawImage(thumbnailNode, width, height, pixels, { centered: true });
-
-    thumbnailNode.className = "filmstrip-thumbnail";
-    thumbnailNode.onmousedown = e => this._onThumbnailClick(e, index);
-    thumbnailNode.setAttribute("index", index);
-    this._filmstrip.appendChild(thumbnailNode);
-  },
-
-  /**
-   * Sets the currently highlighted thumbnail in this container.
-   * A screenshot will always correlate to a thumbnail in the filmstrip,
-   * both being identified by the same 'index' of the context function call.
-   *
-   * @param number index
-   *        The context function call's index.
-   */
-  set highlightedThumbnail(index) {
-    let currHighlightedThumbnail = $(".filmstrip-thumbnail[index='" + index + "']");
-    if (currHighlightedThumbnail == null) {
-      return;
-    }
-
-    let prevIndex = this._highlightedThumbnailIndex
-    let prevHighlightedThumbnail = $(".filmstrip-thumbnail[index='" + prevIndex + "']");
-    if (prevHighlightedThumbnail) {
-      prevHighlightedThumbnail.removeAttribute("highlighted");
-    }
-
-    currHighlightedThumbnail.setAttribute("highlighted", "");
-    currHighlightedThumbnail.scrollIntoView();
-    this._highlightedThumbnailIndex = index;
-  },
-
-  /**
-   * Gets the currently highlighted thumbnail in this container.
-   * @return number
-   */
-  get highlightedThumbnail() {
-    return this._highlightedThumbnailIndex;
-  },
-
-  /**
-   * The select listener for this container.
-   */
-  _onSelect: function({ detail: callItem }) {
-    if (!callItem) {
-      return;
-    }
-
-    // Some of the stepping buttons don't make sense specifically while the
-    // last function call is selected.
-    if (this.selectedIndex == this.itemCount - 1) {
-      $("#resume").setAttribute("disabled", "true");
-      $("#step-over").setAttribute("disabled", "true");
-      $("#step-out").setAttribute("disabled", "true");
-    } else {
-      $("#resume").removeAttribute("disabled");
-      $("#step-over").removeAttribute("disabled");
-      $("#step-out").removeAttribute("disabled");
-    }
-
-    // Correlate the currently selected item with the function selection
-    // slider's value. Avoid triggering a redundant selection event.
-    this._ignoreSliderChanges = true;
-    this._slider.value = this.selectedIndex;
-    this._ignoreSliderChanges = false;
-
-    // Can't generate screenshots for function call actors loaded from disk.
-    // XXX: Bug 984844.
-    if (callItem.attachment.actor.isLoadedFromDisk) {
-      return;
-    }
-
-    // To keep continuous selection buttery smooth (for example, while pressing
-    // the DOWN key or moving the slider), only display the screenshot after
-    // any kind of user input stops.
-    setConditionalTimeout("screenshot-display", SCREENSHOT_DISPLAY_DELAY, () => {
-      return !this._isSliding;
-    }, () => {
-      let frameSnapshot = SnapshotsListView.selectedItem.attachment.actor
-      let functionCall = callItem.attachment.actor;
-      frameSnapshot.generateScreenshotFor(functionCall).then(screenshot => {
-        this.showScreenshot(screenshot);
-        this.highlightedThumbnail = screenshot.index;
-      });
-    });
-  },
-
-  /**
-   * The mousedown listener for the call selection slider.
-   */
-  _onSlideMouseDown: function() {
-    this._isSliding = true;
-  },
-
-  /**
-   * The mouseup listener for the call selection slider.
-   */
-  _onSlideMouseUp: function() {
-    this._isSliding = false;
-  },
-
-  /**
-   * The change listener for the call selection slider.
-   */
-  _onSlide: function() {
-    // Avoid performing any operations when programatically changing the value.
-    if (this._ignoreSliderChanges) {
-      return;
-    }
-    let selectedFunctionCallIndex = this.selectedIndex = this._slider.value;
-
-    // While sliding, immediately show the most relevant thumbnail for a
-    // function call, for a nice diff-like animation effect between draws.
-    let thumbnails = SnapshotsListView.selectedItem.attachment.thumbnails;
-    let thumbnail = getThumbnailForCall(thumbnails, selectedFunctionCallIndex);
-
-    // Avoid drawing and highlighting if the selected function call has the
-    // same thumbnail as the last one.
-    if (thumbnail.index == this.highlightedThumbnail) {
-      return;
-    }
-    // If a thumbnail wasn't found (e.g. the backend avoids creating thumbnails
-    // when rendering offscreen), simply defer to the first available one.
-    if (thumbnail.index == -1) {
-      thumbnail = thumbnails[0];
-    }
-
-    let { index, width, height, flipped, pixels } = thumbnail;
-    this.highlightedThumbnail = index;
-
-    let screenshotNode = $("#screenshot-image");
-    screenshotNode.setAttribute("flipped", flipped);
-    drawBackground("screenshot-rendering", width, height, pixels);
-  },
-
-  /**
-   * The input listener for the calls searchbox.
-   */
-  _onSearch: function(e) {
-    let lowerCaseSearchToken = this._searchbox.value.toLowerCase();
-
-    this.filterContents(e => {
-      let call = e.attachment.actor;
-      let name = call.name.toLowerCase();
-      let file = call.file.toLowerCase();
-      let line = call.line.toString().toLowerCase();
-      let args = call.argsPreview.toLowerCase();
-
-      return name.contains(lowerCaseSearchToken) ||
-             file.contains(lowerCaseSearchToken) ||
-             line.contains(lowerCaseSearchToken) ||
-             args.contains(lowerCaseSearchToken);
-    });
-  },
-
-  /**
-   * The wheel listener for the filmstrip that contains all the thumbnails.
-   */
-  _onScroll: function(e) {
-    this._filmstrip.scrollLeft += e.deltaX;
-  },
-
-  /**
-   * The click/dblclick listener for an item or location url in this container.
-   * When expanding an item, it's corresponding call stack will be displayed.
-   */
-  _onExpand: function(e) {
-    let callItem = this.getItemForElement(e.target);
-    let view = $(".call-item-view", callItem.target);
-
-    // If the call stack nodes were already created, simply re-show them
-    // or jump to the corresponding file and line in the Debugger if a
-    // location link was clicked.
-    if (view.hasAttribute("call-stack-populated")) {
-      let isExpanded = view.getAttribute("call-stack-expanded") == "true";
-
-      // If clicking on the location, jump to the Debugger.
-      if (e.target.classList.contains("call-item-location")) {
-        let { file, line } = callItem.attachment.actor;
-        viewSourceInDebugger(file, line);
-        return;
-      }
-      // Otherwise hide the call stack.
-      else {
-        view.setAttribute("call-stack-expanded", !isExpanded);
-        $(".call-item-stack", view).hidden = isExpanded;
-        return;
-      }
-    }
-
-    let list = document.createElement("vbox");
-    list.className = "call-item-stack";
-    view.setAttribute("call-stack-populated", "");
-    view.setAttribute("call-stack-expanded", "true");
-    view.appendChild(list);
-
-    /**
-     * Creates a function call nodes in this container for a stack.
-     */
-    let display = stack => {
-      for (let i = 1; i < stack.length; i++) {
-        let call = stack[i];
-
-        let contents = document.createElement("hbox");
-        contents.className = "call-item-stack-fn";
-        contents.style.MozPaddingStart = (i * STACK_FUNC_INDENTATION) + "px";
-
-        let name = document.createElement("label");
-        name.className = "plain call-item-stack-fn-name";
-        name.setAttribute("value", "↳ " + call.name + "()");
-        contents.appendChild(name);
-
-        let spacer = document.createElement("spacer");
-        spacer.setAttribute("flex", "100");
-        contents.appendChild(spacer);
-
-        let location = document.createElement("label");
-        location.className = "plain call-item-stack-fn-location";
-        location.setAttribute("value", getFileName(call.file) + ":" + call.line);
-        location.setAttribute("crop", "start");
-        location.setAttribute("flex", "1");
-        location.addEventListener("mousedown", e => this._onStackFileClick(e, call));
-        contents.appendChild(location);
-
-        list.appendChild(contents);
-      }
-
-      window.emit(EVENTS.CALL_STACK_DISPLAYED);
-    };
-
-    // If this animation snapshot is loaded from disk, there are no corresponding
-    // backend actors available and the data is immediately available.
-    let functionCall = callItem.attachment.actor;
-    if (functionCall.isLoadedFromDisk) {
-      display(functionCall.stack);
-    }
-    // ..otherwise we need to request the function call stack from the backend.
-    else {
-      callItem.attachment.actor.getDetails().then(fn => display(fn.stack));
-    }
-  },
-
-  /**
-   * The click listener for a location link in the call stack.
-   *
-   * @param string file
-   *        The url of the source owning the function.
-   * @param number line
-   *        The line of the respective function.
-   */
-  _onStackFileClick: function(e, { file, line }) {
-    viewSourceInDebugger(file, line);
-  },
-
-  /**
-   * The click listener for a thumbnail in the filmstrip.
-   *
-   * @param number index
-   *        The function index in the recorded animation frame snapshot.
-   */
-  _onThumbnailClick: function(e, index) {
-    this.selectedIndex = index;
-  },
-
-  /**
-   * The click listener for the "resume" button in this container's toolbar.
-   */
-  _onResume: function() {
-    // Jump to the next draw call in the recorded animation frame snapshot.
-    let drawCall = getNextDrawCall(this.items, this.selectedItem);
-    if (drawCall) {
-      this.selectedItem = drawCall;
-      return;
-    }
-
-    // If there are no more draw calls, just jump to the last context call.
-    this._onStepOut();
-  },
-
-  /**
-   * The click listener for the "step over" button in this container's toolbar.
-   */
-  _onStepOver: function() {
-    this.selectedIndex++;
-  },
-
-  /**
-   * The click listener for the "step in" button in this container's toolbar.
-   */
-  _onStepIn: function() {
-    if (this.selectedIndex == -1) {
-      this._onResume();
-      return;
-    }
-    let callItem = this.selectedItem;
-    let { file, line } = callItem.attachment.actor;
-    viewSourceInDebugger(file, line);
-  },
-
-  /**
-   * The click listener for the "step out" button in this container's toolbar.
-   */
-  _onStepOut: function() {
-    this.selectedIndex = this.itemCount - 1;
-  }
-});
-
-/**
- * Localization convenience methods.
- */
-let L10N = new ViewHelpers.L10N(STRINGS_URI);
-
-/**
- * Convenient way of emitting events from the panel window.
- */
-EventEmitter.decorate(this);
-
-/**
- * DOM query helpers.
- */
-function $(selector, target = document) target.querySelector(selector);
-function $all(selector, target = document) target.querySelectorAll(selector);
-
-/**
- * Helper for getting an nsIURL instance out of a string.
- */
-function nsIURL(url, store = nsIURL.store) {
-  if (store.has(url)) {
-    return store.get(url);
-  }
-  let uri = Services.io.newURI(url, null, null).QueryInterface(Ci.nsIURL);
-  store.set(url, uri);
-  return uri;
-}
-
-// The cache used in the `nsIURL` function.
-nsIURL.store = new Map();
-
-/**
- * Gets the fileName part of a string which happens to be an URL.
- */
-function getFileName(url) {
-  try {
-    let { fileName } = nsIURL(url);
-    return fileName || "/";
-  } catch (e) {
-    // This doesn't look like a url, or nsIURL can't handle it.
-    return "";
-  }
-}
-
-/**
- * Gets an image data object containing a buffer large enough to hold
- * width * height pixels.
- *
- * This method avoids allocating memory and tries to reuse a common buffer
- * as much as possible.
- *
- * @param number w
- *        The desired image data storage width.
- * @param number h
- *        The desired image data storage height.
- * @return ImageData
- *         The requested image data buffer.
- */
-function getImageDataStorage(ctx, w, h) {
-  let storage = getImageDataStorage.cache;
-  if (storage && storage.width == w && storage.height == h) {
-    return storage;
-  }
-  return getImageDataStorage.cache = ctx.createImageData(w, h);
-}
-
-// The cache used in the `getImageDataStorage` function.
-getImageDataStorage.cache = null;
-
-/**
- * Draws image data into a canvas.
- *
- * This method makes absolutely no assumptions about the canvas element
- * dimensions, or pre-existing rendering. It's a dumb proxy that copies pixels.
- *
- * @param HTMLCanvasElement canvas
- *        The canvas element to put the image data into.
- * @param number width
- *        The image data width.
- * @param number height
- *        The image data height.
- * @param pixels
- *        An array buffer view of the image data.
- * @param object options
- *        Additional options supported by this operation:
- *          - centered: specifies whether the image data should be centered
- *                      when copied in the canvas; this is useful when the
- *                      supplied pixels don't completely cover the canvas.
- */
-function drawImage(canvas, width, height, pixels, options = {}) {
-  let ctx = canvas.getContext("2d");
-
-  // FrameSnapshot actors return "snapshot-image" type instances with just an
-  // empty pixel array if the source image is completely transparent.
-  if (pixels.length <= 1) {
-    ctx.clearRect(0, 0, canvas.width, canvas.height);
-    return;
-  }
-
-  let arrayBuffer = new Uint8Array(pixels.buffer);
-  let imageData = getImageDataStorage(ctx, width, height);
-  imageData.data.set(arrayBuffer);
-
-  if (options.centered) {
-    let left = (canvas.width - width) / 2;
-    let top = (canvas.height - height) / 2;
-    ctx.putImageData(imageData, left, top);
-  } else {
-    ctx.putImageData(imageData, 0, 0);
-  }
-}
-
-/**
- * Draws image data into a canvas, and sets that as the rendering source for
- * an element with the specified id as the -moz-element background image.
- *
- * @param string id
- *        The id of the -moz-element background image.
- * @param number width
- *        The image data width.
- * @param number height
- *        The image data height.
- * @param pixels
- *        An array buffer view of the image data.
- */
-function drawBackground(id, width, height, pixels) {
-  let canvas = document.createElementNS(HTML_NS, "canvas");
-  canvas.width = width;
-  canvas.height = height;
-
-  drawImage(canvas, width, height, pixels);
-  document.mozSetImageElement(id, canvas);
-
-  // Used in tests. Not emitting an event because this shouldn't be "interesting".
-  if (window._onMozSetImageElement) {
-    window._onMozSetImageElement(pixels);
-  }
-}
-
-/**
- * Iterates forward to find the next draw call in a snapshot.
- */
-function getNextDrawCall(calls, call) {
-  for (let i = calls.indexOf(call) + 1, len = calls.length; i < len; i++) {
-    let nextCall = calls[i];
-    let name = nextCall.attachment.actor.name;
-    if (CanvasFront.DRAW_CALLS.has(name)) {
-      return nextCall;
-    }
-  }
-  return null;
-}
-
-/**
- * Iterates backwards to find the most recent screenshot for a function call
- * in a snapshot loaded from disk.
- */
-function getScreenshotFromCallLoadedFromDisk(calls, call) {
-  for (let i = calls.indexOf(call); i >= 0; i--) {
-    let prevCall = calls[i];
-    let screenshot = prevCall.screenshot;
-    if (screenshot) {
-      return screenshot;
-    }
-  }
-  return CanvasFront.INVALID_SNAPSHOT_IMAGE;
-}
-
-/**
- * Iterates backwards to find the most recent thumbnail for a function call.
- */
-function getThumbnailForCall(thumbnails, index) {
-  for (let i = thumbnails.length - 1; i >= 0; i--) {
-    let thumbnail = thumbnails[i];
-    if (thumbnail.index <= index) {
-      return thumbnail;
-    }
-  }
-  return CanvasFront.INVALID_SNAPSHOT_IMAGE;
-}
-
-/**
- * Opens/selects the debugger in this toolbox and jumps to the specified
- * file name and line number.
- */
-function viewSourceInDebugger(url, line) {
-  let showSource = ({ DebuggerView }) => {
-    if (DebuggerView.Sources.containsValue(url)) {
-      DebuggerView.setEditorLocation(url, line, { noDebug: true }).then(() => {
-        window.emit(EVENTS.SOURCE_SHOWN_IN_JS_DEBUGGER);
-      }, () => {
-        window.emit(EVENTS.SOURCE_NOT_FOUND_IN_JS_DEBUGGER);
-      });
-    }
-  }
-
-  // If the Debugger was already open, switch to it and try to show the
-  // source immediately. Otherwise, initialize it and wait for the sources
-  // to be added first.
-  let debuggerAlreadyOpen = gToolbox.getPanel("jsdebugger");
-  gToolbox.selectTool("jsdebugger").then(({ panelWin: dbg }) => {
-    if (debuggerAlreadyOpen) {
-      showSource(dbg);
-    } else {
-      dbg.once(dbg.EVENTS.SOURCES_ADDED, () => showSource(dbg));
-    }
-  });
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/canvasdebugger.xul
+++ /dev/null
@@ -1,131 +0,0 @@
-<?xml version="1.0"?>
-<!-- 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/. -->
-<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/content/devtools/widgets.css" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/skin/devtools/common.css" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/skin/devtools/widgets.css" type="text/css"?>
-<?xml-stylesheet href="chrome://browser/skin/devtools/canvasdebugger.css" type="text/css"?>
-<!DOCTYPE window [
-  <!ENTITY % canvasDebuggerDTD SYSTEM "chrome://browser/locale/devtools/canvasdebugger.dtd">
-  %canvasDebuggerDTD;
-]>
-
-<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-  <script src="chrome://browser/content/devtools/theme-switching.js"/>
-  <script type="application/javascript" src="canvasdebugger.js"/>
-
-  <hbox class="theme-body" flex="1">
-    <vbox id="snapshots-pane">
-      <toolbar id="snapshots-toolbar"
-               class="devtools-toolbar">
-        <hbox id="snapshots-controls"
-              class="devtools-toolbarbutton-group">
-          <toolbarbutton id="record-snapshot"
-                         class="devtools-toolbarbutton"
-                         oncommand="SnapshotsListView._onRecordButtonClick()"
-                         tooltiptext="&canvasDebuggerUI.recordSnapshot.tooltip;"
-                         hidden="true"/>
-          <toolbarbutton id="import-snapshot"
-                         class="devtools-toolbarbutton"
-                         oncommand="SnapshotsListView._onImportButtonClick()"
-                         label="&canvasDebuggerUI.importSnapshot;"/>
-          <toolbarbutton id="clear-snapshots"
-                         class="devtools-toolbarbutton"
-                         oncommand="SnapshotsListView._onClearButtonClick()"
-                         label="&canvasDebuggerUI.clearSnapshots;"/>
-        </hbox>
-      </toolbar>
-      <vbox id="snapshots-list" flex="1"/>
-    </vbox>
-
-    <vbox id="debugging-pane" flex="1">
-      <hbox id="reload-notice"
-            class="notice-container"
-            align="center"
-            pack="center"
-            flex="1">
-        <button id="reload-notice-button"
-                class="devtools-toolbarbutton"
-                label="&canvasDebuggerUI.reloadNotice1;"
-                oncommand="gFront.setup({ reload: true })"/>
-        <label id="reload-notice-label"
-               class="plain"
-               value="&canvasDebuggerUI.reloadNotice2;"/>
-      </hbox>
-
-      <hbox id="empty-notice"
-            class="notice-container"
-            align="center"
-            pack="center"
-            flex="1"
-            hidden="true">
-        <label value="&canvasDebuggerUI.emptyNotice1;"/>
-        <button id="canvas-debugging-empty-notice-button"
-                class="devtools-toolbarbutton"
-                oncommand="SnapshotsListView._onRecordButtonClick()"/>
-        <label value="&canvasDebuggerUI.emptyNotice2;"/>
-      </hbox>
-
-      <hbox id="import-notice"
-            class="notice-container"
-            align="center"
-            pack="center"
-            flex="1"
-            hidden="true">
-        <label value="&canvasDebuggerUI.importNotice;"/>
-      </hbox>
-
-      <box id="debugging-pane-contents"
-           class="devtools-responsive-container"
-           flex="1"
-           hidden="true">
-        <vbox id="calls-list-container" flex="1">
-          <toolbar id="debugging-toolbar"
-                   class="devtools-toolbar">
-            <hbox id="debugging-controls"
-                  class="devtools-toolbarbutton-group">
-              <toolbarbutton id="resume"
-                             class="devtools-toolbarbutton"
-                             oncommand="CallsListView._onResume()"/>
-              <toolbarbutton id="step-over"
-                             class="devtools-toolbarbutton"
-                             oncommand="CallsListView._onStepOver()"/>
-              <toolbarbutton id="step-in"
-                             class="devtools-toolbarbutton"
-                             oncommand="CallsListView._onStepIn()"/>
-              <toolbarbutton id="step-out"
-                             class="devtools-toolbarbutton"
-                             oncommand="CallsListView._onStepOut()"/>
-            </hbox>
-            <toolbarbutton id="debugging-toolbar-sizer-button"
-                           class="devtools-toolbarbutton"
-                           label=""/>
-            <scale id="calls-slider"
-                   movetoclick="true"
-                   flex="100"/>
-            <textbox id="calls-searchbox"
-                     class="devtools-searchinput"
-                     placeholder="&canvasDebuggerUI.searchboxPlaceholder;"
-                     type="search"
-                     flex="1"/>
-          </toolbar>
-          <vbox id="calls-list" flex="1"/>
-        </vbox>
-
-        <splitter class="devtools-side-splitter"/>
-
-        <vbox id="screenshot-container"
-              hidden="true">
-          <vbox id="screenshot-image" flex="1"/>
-          <label id="screenshot-dimensions" class="plain"/>
-        </vbox>
-      </box>
-
-      <hbox id="snapshot-filmstrip"
-            hidden="true"/>
-    </vbox>
-
-  </hbox>
-</window>
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/moz.build
+++ /dev/null
@@ -1,12 +0,0 @@
-# vim: set filetype=python:
-# 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/.
-
-TEST_DIRS += ['test']
-
-JS_MODULES_PATH = 'modules/devtools/canvasdebugger'
-
-EXTRA_JS_MODULES += [
-    'panel.js'
-]
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/panel.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
-/* 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 { Cc, Ci, Cu, Cr } = require("chrome");
-const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
-const EventEmitter = require("devtools/toolkit/event-emitter");
-const { CanvasFront } = require("devtools/server/actors/canvas");
-const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
-
-function CanvasDebuggerPanel(iframeWindow, toolbox) {
-  this.panelWin = iframeWindow;
-  this._toolbox = toolbox;
-  this._destroyer = null;
-
-  EventEmitter.decorate(this);
-};
-
-exports.CanvasDebuggerPanel = CanvasDebuggerPanel;
-
-CanvasDebuggerPanel.prototype = {
-  /**
-   * Open is effectively an asynchronous constructor.
-   *
-   * @return object
-   *         A promise that is resolved when the Canvas Debugger completes opening.
-   */
-  open: function() {
-    let targetPromise;
-
-    // Local debugging needs to make the target remote.
-    if (!this.target.isRemote) {
-      targetPromise = this.target.makeRemote();
-    } else {
-      targetPromise = promise.resolve(this.target);
-    }
-
-    return targetPromise
-      .then(() => {
-        this.panelWin.gToolbox = this._toolbox;
-        this.panelWin.gTarget = this.target;
-        this.panelWin.gFront = new CanvasFront(this.target.client, this.target.form);
-        return this.panelWin.startupCanvasDebugger();
-      })
-      .then(() => {
-        this.isReady = true;
-        this.emit("ready");
-        return this;
-      })
-      .then(null, function onError(aReason) {
-        DevToolsUtils.reportException("CanvasDebuggerPanel.prototype.open", aReason);
-      });
-  },
-
-  // DevToolPanel API
-
-  get target() this._toolbox.target,
-
-  destroy: function() {
-    // Make sure this panel is not already destroyed.
-    if (this._destroyer) {
-      return this._destroyer;
-    }
-
-    return this._destroyer = this.panelWin.shutdownCanvasDebugger().then(() => {
-      this.emit("destroyed");
-    });
-  }
-};
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser.ini
+++ /dev/null
@@ -1,34 +0,0 @@
-[DEFAULT]
-support-files =
-  doc_simple-canvas.html
-  doc_simple-canvas-deep-stack.html
-  doc_simple-canvas-transparent.html
-  head.js
-
-[browser_canvas-actor-test-01.js]
-[browser_canvas-actor-test-02.js]
-[browser_canvas-actor-test-03.js]
-[browser_canvas-actor-test-04.js]
-[browser_canvas-actor-test-05.js]
-[browser_canvas-actor-test-06.js]
-[browser_canvas-actor-test-07.js]
-[browser_canvas-frontend-call-highlight.js]
-[browser_canvas-frontend-call-list.js]
-[browser_canvas-frontend-call-search.js]
-[browser_canvas-frontend-call-stack-01.js]
-[browser_canvas-frontend-call-stack-02.js]
-[browser_canvas-frontend-call-stack-03.js]
-[browser_canvas-frontend-clear.js]
-[browser_canvas-frontend-img-screenshots.js]
-[browser_canvas-frontend-img-thumbnails-01.js]
-[browser_canvas-frontend-img-thumbnails-02.js]
-[browser_canvas-frontend-open.js]
-[browser_canvas-frontend-record-01.js]
-[browser_canvas-frontend-record-02.js]
-[browser_canvas-frontend-record-03.js]
-[browser_canvas-frontend-reload-01.js]
-[browser_canvas-frontend-reload-02.js]
-[browser_canvas-frontend-slider-01.js]
-[browser_canvas-frontend-slider-02.js]
-[browser_canvas-frontend-snapshot-select.js]
-[browser_canvas-frontend-stepping.js]
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-actor-test-01.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if the canvas debugger leaks on initialization and sudden destruction.
- * You can also use this initialization format as a template for other tests.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, front] = yield initCallWatcherBackend(SIMPLE_CANVAS_URL);
-
-  ok(target, "Should have a target available.");
-  ok(debuggee, "Should have a debuggee available.");
-  ok(front, "Should have a protocol front available.");
-
-  yield removeTab(target.tab);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-actor-test-02.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if functions calls are recorded and stored for a canvas context,
- * and that their stack is successfully retrieved.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, front] = yield initCallWatcherBackend(SIMPLE_CANVAS_URL);
-
-  let navigated = once(target, "navigate");
-
-  yield front.setup({
-    tracedGlobals: ["CanvasRenderingContext2D", "WebGLRenderingContext"],
-    startRecording: true,
-    performReload: true
-  });
-  ok(true, "The front was setup up successfully.");
-
-  yield navigated;
-  ok(true, "Target automatically navigated when the front was set up.");
-
-  // Allow the content to execute some functions.
-  yield waitForTick();
-
-  let functionCalls = yield front.pauseRecording();
-  ok(functionCalls,
-    "An array of function call actors was sent after reloading.");
-  ok(functionCalls.length > 0,
-    "There's at least one function call actor available.");
-
-  is(functionCalls[0].type, CallWatcherFront.METHOD_FUNCTION,
-    "The called function is correctly identified as a method.");
-  is(functionCalls[0].name, "clearRect",
-    "The called function's name is correct.");
-  is(functionCalls[0].file, SIMPLE_CANVAS_URL,
-    "The called function's file is correct.");
-  is(functionCalls[0].line, 25,
-    "The called function's line is correct.");
-
-  is(functionCalls[0].callerPreview, "ctx",
-    "The called function's caller preview is correct.");
-  is(functionCalls[0].argsPreview, "0, 0, 128, 128",
-    "The called function's args preview is correct.");
-
-  let details = yield functionCalls[1].getDetails();
-  ok(details,
-    "The first called function has some details available.")
-
-  is(details.stack.length, 3,
-    "The called function's stack depth is correct.");
-
-  is(details.stack[0].name, "fillStyle",
-    "The called function's stack is correct (1.1).");
-  is(details.stack[0].file, SIMPLE_CANVAS_URL,
-    "The called function's stack is correct (1.2).");
-  is(details.stack[0].line, 20,
-    "The called function's stack is correct (1.3).");
-
-  is(details.stack[1].name, "drawRect",
-    "The called function's stack is correct (2.1).");
-  is(details.stack[1].file, SIMPLE_CANVAS_URL,
-    "The called function's stack is correct (2.2).");
-  is(details.stack[1].line, 26,
-    "The called function's stack is correct (2.3).");
-
-  is(details.stack[2].name, "drawScene",
-    "The called function's stack is correct (3.1).");
-  is(details.stack[2].file, SIMPLE_CANVAS_URL,
-    "The called function's stack is correct (3.2).");
-  is(details.stack[2].line, 33,
-    "The called function's stack is correct (3.3).");
-
-  yield removeTab(target.tab);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-actor-test-03.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if functions inside a single animation frame are recorded and stored
- * for a canvas context.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, front] = yield initCanavsDebuggerBackend(SIMPLE_CANVAS_URL);
-
-  let navigated = once(target, "navigate");
-
-  yield front.setup({ reload: true });
-  ok(true, "The front was setup up successfully.");
-
-  yield navigated;
-  ok(true, "Target automatically navigated when the front was set up.");
-
-  let snapshotActor = yield front.recordAnimationFrame();
-  ok(snapshotActor,
-    "A snapshot actor was sent after recording.");
-
-  let animationOverview = yield snapshotActor.getOverview();
-  ok(snapshotActor,
-    "An animation overview could be retrieved after recording.");
-
-  let functionCalls = animationOverview.calls;
-  ok(functionCalls,
-    "An array of function call actors was sent after recording.");
-  is(functionCalls.length, 8,
-    "The number of function call actors is correct.");
-
-  is(functionCalls[0].type, CallWatcherFront.METHOD_FUNCTION,
-    "The first called function is correctly identified as a method.");
-  is(functionCalls[0].name, "clearRect",
-    "The first called function's name is correct.");
-  is(functionCalls[0].file, SIMPLE_CANVAS_URL,
-    "The first called function's file is correct.");
-  is(functionCalls[0].line, 25,
-    "The first called function's line is correct.");
-  is(functionCalls[0].argsPreview, "0, 0, 128, 128",
-    "The first called function's args preview is correct.");
-  is(functionCalls[0].callerPreview, "ctx",
-    "The first called function's caller preview is correct.");
-
-  is(functionCalls[6].type, CallWatcherFront.METHOD_FUNCTION,
-    "The penultimate called function is correctly identified as a method.");
-  is(functionCalls[6].name, "fillRect",
-    "The penultimate called function's name is correct.");
-  is(functionCalls[6].file, SIMPLE_CANVAS_URL,
-    "The penultimate called function's file is correct.");
-  is(functionCalls[6].line, 21,
-    "The penultimate called function's line is correct.");
-  is(functionCalls[6].argsPreview, "10, 10, 55, 50",
-    "The penultimate called function's args preview is correct.");
-  is(functionCalls[6].callerPreview, "ctx",
-    "The penultimate called function's caller preview is correct.");
-
-  is(functionCalls[7].type, CallWatcherFront.METHOD_FUNCTION,
-    "The last called function is correctly identified as a method.");
-  is(functionCalls[7].name, "requestAnimationFrame",
-    "The last called function's name is correct.");
-  is(functionCalls[7].file, SIMPLE_CANVAS_URL,
-    "The last called function's file is correct.");
-  is(functionCalls[7].line, 30,
-    "The last called function's line is correct.");
-  ok(functionCalls[7].argsPreview.contains("Function"),
-    "The last called function's args preview is correct.");
-  is(functionCalls[7].callerPreview, "",
-    "The last called function's caller preview is correct.");
-
-  yield removeTab(target.tab);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-actor-test-04.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if draw calls inside a single animation frame generate and retrieve
- * the correct thumbnails.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, front] = yield initCanavsDebuggerBackend(SIMPLE_CANVAS_URL);
-
-  let navigated = once(target, "navigate");
-
-  yield front.setup({ reload: true });
-  ok(true, "The front was setup up successfully.");
-
-  yield navigated;
-  ok(true, "Target automatically navigated when the front was set up.");
-
-  let snapshotActor = yield front.recordAnimationFrame();
-  ok(snapshotActor,
-    "A snapshot actor was sent after recording.");
-
-  let animationOverview = yield snapshotActor.getOverview();
-  ok(snapshotActor,
-    "An animation overview could be retrieved after recording.");
-
-  let thumbnails = animationOverview.thumbnails;
-  ok(thumbnails,
-    "An array of thumbnails was sent after recording.");
-  is(thumbnails.length, 4,
-    "The number of thumbnails is correct.");
-
-  is(thumbnails[0].index, 0,
-    "The first thumbnail's index is correct.");
-  is(thumbnails[0].width, 50,
-    "The first thumbnail's width is correct.");
-  is(thumbnails[0].height, 50,
-    "The first thumbnail's height is correct.");
-  is(thumbnails[0].flipped, false,
-    "The first thumbnail's flipped flag is correct.");
-  is([].find.call(thumbnails[0].pixels, e => e > 0), undefined,
-    "The first thumbnail's pixels seem to be completely transparent.");
-
-  is(thumbnails[1].index, 2,
-    "The second thumbnail's index is correct.");
-  is(thumbnails[1].width, 50,
-    "The second thumbnail's width is correct.");
-  is(thumbnails[1].height, 50,
-    "The second thumbnail's height is correct.");
-  is(thumbnails[1].flipped, false,
-    "The second thumbnail's flipped flag is correct.");
-  is([].find.call(thumbnails[1].pixels, e => e > 0), 4290822336,
-    "The second thumbnail's pixels seem to not be completely transparent.");
-
-  is(thumbnails[2].index, 4,
-    "The third thumbnail's index is correct.");
-  is(thumbnails[2].width, 50,
-    "The third thumbnail's width is correct.");
-  is(thumbnails[2].height, 50,
-    "The third thumbnail's height is correct.");
-  is(thumbnails[2].flipped, false,
-    "The third thumbnail's flipped flag is correct.");
-  is([].find.call(thumbnails[2].pixels, e => e > 0), 4290822336,
-    "The third thumbnail's pixels seem to not be completely transparent.");
-
-  is(thumbnails[3].index, 6,
-    "The fourth thumbnail's index is correct.");
-  is(thumbnails[3].width, 50,
-    "The fourth thumbnail's width is correct.");
-  is(thumbnails[3].height, 50,
-    "The fourth thumbnail's height is correct.");
-  is(thumbnails[3].flipped, false,
-    "The fourth thumbnail's flipped flag is correct.");
-  is([].find.call(thumbnails[3].pixels, e => e > 0), 4290822336,
-    "The fourth thumbnail's pixels seem to not be completely transparent.");
-
-  yield removeTab(target.tab);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-actor-test-05.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if draw calls inside a single animation frame generate and retrieve
- * the correct "end result" screenshot.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, front] = yield initCanavsDebuggerBackend(SIMPLE_CANVAS_URL);
-
-  let navigated = once(target, "navigate");
-
-  yield front.setup({ reload: true });
-  ok(true, "The front was setup up successfully.");
-
-  yield navigated;
-  ok(true, "Target automatically navigated when the front was set up.");
-
-  let snapshotActor = yield front.recordAnimationFrame();
-  ok(snapshotActor,
-    "A snapshot actor was sent after recording.");
-
-  let animationOverview = yield snapshotActor.getOverview();
-  ok(snapshotActor,
-    "An animation overview could be retrieved after recording.");
-
-  let screenshot = animationOverview.screenshot;
-  ok(screenshot,
-    "A screenshot was sent after recording.");
-
-  is(screenshot.index, 6,
-    "The screenshot's index is correct.");
-  is(screenshot.width, 128,
-    "The screenshot's width is correct.");
-  is(screenshot.height, 128,
-    "The screenshot's height is correct.");
-  is(screenshot.flipped, false,
-    "The screenshot's flipped flag is correct.");
-  is([].find.call(screenshot.pixels, e => e > 0), 4290822336,
-    "The screenshot's pixels seem to not be completely transparent.");
-
-  yield removeTab(target.tab);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-actor-test-06.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if screenshots for arbitrary draw calls are generated properly.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, front] = yield initCanavsDebuggerBackend(SIMPLE_CANVAS_TRANSPARENT_URL);
-
-  let navigated = once(target, "navigate");
-
-  yield front.setup({ reload: true });
-  ok(true, "The front was setup up successfully.");
-
-  yield navigated;
-  ok(true, "Target automatically navigated when the front was set up.");
-
-  let snapshotActor = yield front.recordAnimationFrame();
-  let animationOverview = yield snapshotActor.getOverview();
-
-  let functionCalls = animationOverview.calls;
-  ok(functionCalls,
-    "An array of function call actors was sent after recording.");
-  is(functionCalls.length, 8,
-    "The number of function call actors is correct.");
-
-  is(functionCalls[0].name, "clearRect",
-    "The first called function's name is correct.");
-  is(functionCalls[2].name, "fillRect",
-    "The second called function's name is correct.");
-  is(functionCalls[4].name, "fillRect",
-    "The third called function's name is correct.");
-  is(functionCalls[6].name, "fillRect",
-    "The fourth called function's name is correct.");
-
-  let firstDrawCallScreenshot = yield snapshotActor.generateScreenshotFor(functionCalls[0]);
-  let secondDrawCallScreenshot = yield snapshotActor.generateScreenshotFor(functionCalls[2]);
-  let thirdDrawCallScreenshot = yield snapshotActor.generateScreenshotFor(functionCalls[4]);
-  let fourthDrawCallScreenshot = yield snapshotActor.generateScreenshotFor(functionCalls[6]);
-
-  ok(firstDrawCallScreenshot,
-    "The first draw call has a screenshot attached.");
-  is(firstDrawCallScreenshot.index, 0,
-    "The first draw call has the correct screenshot index.");
-  is(firstDrawCallScreenshot.width, 128,
-    "The first draw call has the correct screenshot width.");
-  is(firstDrawCallScreenshot.height, 128,
-    "The first draw call has the correct screenshot height.");
-  is([].find.call(firstDrawCallScreenshot.pixels, e => e > 0), undefined,
-    "The first draw call's screenshot's pixels seems to be completely transparent.");
-
-  ok(secondDrawCallScreenshot,
-    "The second draw call has a screenshot attached.");
-  is(secondDrawCallScreenshot.index, 2,
-    "The second draw call has the correct screenshot index.");
-  is(secondDrawCallScreenshot.width, 128,
-    "The second draw call has the correct screenshot width.");
-  is(secondDrawCallScreenshot.height, 128,
-    "The second draw call has the correct screenshot height.");
-  is([].find.call(firstDrawCallScreenshot.pixels, e => e > 0), undefined,
-    "The second draw call's screenshot's pixels seems to be completely transparent.");
-
-  ok(thirdDrawCallScreenshot,
-    "The third draw call has a screenshot attached.");
-  is(thirdDrawCallScreenshot.index, 4,
-    "The third draw call has the correct screenshot index.");
-  is(thirdDrawCallScreenshot.width, 128,
-    "The third draw call has the correct screenshot width.");
-  is(thirdDrawCallScreenshot.height, 128,
-    "The third draw call has the correct screenshot height.");
-  is([].find.call(thirdDrawCallScreenshot.pixels, e => e > 0), 2160001024,
-    "The third draw call's screenshot's pixels seems to not be completely transparent.");
-
-  ok(fourthDrawCallScreenshot,
-    "The fourth draw call has a screenshot attached.");
-  is(fourthDrawCallScreenshot.index, 6,
-    "The fourth draw call has the correct screenshot index.");
-  is(fourthDrawCallScreenshot.width, 128,
-    "The fourth draw call has the correct screenshot width.");
-  is(fourthDrawCallScreenshot.height, 128,
-    "The fourth draw call has the correct screenshot height.");
-  is([].find.call(fourthDrawCallScreenshot.pixels, e => e > 0), 2147483839,
-    "The fourth draw call's screenshot's pixels seems to not be completely transparent.");
-
-  isnot(firstDrawCallScreenshot.pixels, secondDrawCallScreenshot.pixels,
-    "The screenshots taken on consecutive draw calls are different (1).");
-  isnot(secondDrawCallScreenshot.pixels, thirdDrawCallScreenshot.pixels,
-    "The screenshots taken on consecutive draw calls are different (2).");
-  isnot(thirdDrawCallScreenshot.pixels, fourthDrawCallScreenshot.pixels,
-    "The screenshots taken on consecutive draw calls are different (3).");
-
-  yield removeTab(target.tab);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-actor-test-07.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if screenshots for non-draw calls can still be retrieved properly,
- * by deferring the the most recent previous draw-call.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, front] = yield initCanavsDebuggerBackend(SIMPLE_CANVAS_URL);
-
-  let navigated = once(target, "navigate");
-
-  yield front.setup({ reload: true });
-  ok(true, "The front was setup up successfully.");
-
-  yield navigated;
-  ok(true, "Target automatically navigated when the front was set up.");
-
-  let snapshotActor = yield front.recordAnimationFrame();
-  let animationOverview = yield snapshotActor.getOverview();
-
-  let functionCalls = animationOverview.calls;
-  ok(functionCalls,
-    "An array of function call actors was sent after recording.");
-  is(functionCalls.length, 8,
-    "The number of function call actors is correct.");
-
-  let firstNonDrawCall = yield functionCalls[1].getDetails();
-  let secondNonDrawCall = yield functionCalls[3].getDetails();
-  let lastNonDrawCall = yield functionCalls[7].getDetails();
-
-  is(firstNonDrawCall.name, "fillStyle",
-    "The first non-draw function's name is correct.");
-  is(secondNonDrawCall.name, "fillStyle",
-    "The second non-draw function's name is correct.");
-  is(lastNonDrawCall.name, "requestAnimationFrame",
-    "The last non-draw function's name is correct.");
-
-  let firstScreenshot = yield snapshotActor.generateScreenshotFor(functionCalls[1]);
-  let secondScreenshot = yield snapshotActor.generateScreenshotFor(functionCalls[3]);
-  let lastScreenshot = yield snapshotActor.generateScreenshotFor(functionCalls[7]);
-
-  ok(firstScreenshot,
-    "A screenshot was successfully retrieved for the first non-draw function.");
-  ok(secondScreenshot,
-    "A screenshot was successfully retrieved for the second non-draw function.");
-  ok(lastScreenshot,
-    "A screenshot was successfully retrieved for the last non-draw function.");
-
-  let firstActualScreenshot = yield snapshotActor.generateScreenshotFor(functionCalls[0]);
-  ok(sameArray(firstScreenshot.pixels, firstActualScreenshot.pixels),
-    "The screenshot for the first non-draw function is correct.");
-  is(firstScreenshot.width, 128,
-    "The screenshot for the first non-draw function has the correct width.");
-  is(firstScreenshot.height, 128,
-    "The screenshot for the first non-draw function has the correct height.");
-
-  let secondActualScreenshot =  yield snapshotActor.generateScreenshotFor(functionCalls[2]);
-  ok(sameArray(secondScreenshot.pixels, secondActualScreenshot.pixels),
-    "The screenshot for the second non-draw function is correct.");
-  is(secondScreenshot.width, 128,
-    "The screenshot for the second non-draw function has the correct width.");
-  is(secondScreenshot.height, 128,
-    "The screenshot for the second non-draw function has the correct height.");
-
-  let lastActualScreenshot = yield snapshotActor.generateScreenshotFor(functionCalls[6]);
-  ok(sameArray(lastScreenshot.pixels, lastActualScreenshot.pixels),
-    "The screenshot for the last non-draw function is correct.");
-  is(lastScreenshot.width, 128,
-    "The screenshot for the last non-draw function has the correct width.");
-  is(lastScreenshot.height, 128,
-    "The screenshot for the last non-draw function has the correct height.");
-
-  ok(!sameArray(firstScreenshot.pixels, secondScreenshot.pixels),
-    "The screenshots taken on consecutive draw calls are different (1).");
-  ok(!sameArray(secondScreenshot.pixels, lastScreenshot.pixels),
-    "The screenshots taken on consecutive draw calls are different (2).");
-
-  yield removeTab(target.tab);
-  finish();
-}
-
-function sameArray(a, b) {
-  if (a.length != b.length) {
-    return false;
-  }
-  for (let i = 0; i < a.length; i++) {
-    if (a[i] !== b[i]) {
-      return false;
-    }
-  }
-  return true;
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-highlight.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if certain function calls are properly highlighted in the UI.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([recordingFinished, callListPopulated]);
-
-  is(CallsListView.itemCount, 8,
-    "All the function calls should now be displayed in the UI.");
-
-  is($(".call-item-view", CallsListView.getItemAtIndex(0).target).hasAttribute("draw-call"), true,
-    "The first item's node should have a draw-call attribute.");
-  is($(".call-item-view", CallsListView.getItemAtIndex(1).target).hasAttribute("draw-call"), false,
-    "The second item's node should not have a draw-call attribute.");
-  is($(".call-item-view", CallsListView.getItemAtIndex(2).target).hasAttribute("draw-call"), true,
-    "The third item's node should have a draw-call attribute.");
-  is($(".call-item-view", CallsListView.getItemAtIndex(3).target).hasAttribute("draw-call"), false,
-    "The fourth item's node should not have a draw-call attribute.");
-  is($(".call-item-view", CallsListView.getItemAtIndex(4).target).hasAttribute("draw-call"), true,
-    "The fifth item's node should have a draw-call attribute.");
-  is($(".call-item-view", CallsListView.getItemAtIndex(5).target).hasAttribute("draw-call"), false,
-    "The sixth item's node should not have a draw-call attribute.");
-  is($(".call-item-view", CallsListView.getItemAtIndex(6).target).hasAttribute("draw-call"), true,
-    "The seventh item's node should have a draw-call attribute.");
-  is($(".call-item-view", CallsListView.getItemAtIndex(7).target).hasAttribute("draw-call"), false,
-    "The eigth item's node should not have a draw-call attribute.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-list.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if all the function calls associated with an animation frame snapshot
- * are properly displayed in the UI.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([recordingFinished, callListPopulated]);
-
-  is(CallsListView.itemCount, 8,
-    "All the function calls should now be displayed in the UI.");
-
-  testItem(CallsListView.getItemAtIndex(0),
-    "1", "ctx", "clearRect", "(0, 0, 128, 128)", "doc_simple-canvas.html:25");
-
-  testItem(CallsListView.getItemAtIndex(1),
-    "2", "ctx", "fillStyle", " = rgb(192, 192, 192)", "doc_simple-canvas.html:20");
-  testItem(CallsListView.getItemAtIndex(2),
-    "3", "ctx", "fillRect", "(0, 0, 128, 128)", "doc_simple-canvas.html:21");
-
-  testItem(CallsListView.getItemAtIndex(3),
-    "4", "ctx", "fillStyle", " = rgba(0, 0, 192, 0.5)", "doc_simple-canvas.html:20");
-  testItem(CallsListView.getItemAtIndex(4),
-    "5", "ctx", "fillRect", "(30, 30, 55, 50)", "doc_simple-canvas.html:21");
-
-  testItem(CallsListView.getItemAtIndex(5),
-    "6", "ctx", "fillStyle", " = rgba(192, 0, 0, 0.5)", "doc_simple-canvas.html:20");
-  testItem(CallsListView.getItemAtIndex(6),
-    "7", "ctx", "fillRect", "(10, 10, 55, 50)", "doc_simple-canvas.html:21");
-
-  testItem(CallsListView.getItemAtIndex(7),
-    "8", "", "requestAnimationFrame", "(Function)", "doc_simple-canvas.html:30");
-
-  function testItem(item, index, context, name, args, location) {
-    let i = CallsListView.indexOfItem(item);
-    is(i, index - 1,
-      "The item at index " + index + " is correctly displayed in the UI.");
-
-    is($(".call-item-index", item.target).getAttribute("value"), index,
-      "The item's gutter label has the correct text.");
-
-    if (context) {
-      is($(".call-item-context", item.target).getAttribute("value"), context,
-        "The item's context label has the correct text.");
-    } else {
-      is($(".call-item-context", item.target), null,
-        "The item's context label should not be available.");
-    }
-
-    is($(".call-item-name", item.target).getAttribute("value"), name,
-      "The item's name label has the correct text.");
-    is($(".call-item-args", item.target).getAttribute("value"), args,
-      "The item's args label has the correct text.");
-    is($(".call-item-location", item.target).getAttribute("value"), location,
-      "The item's location label has the correct text.");
-  }
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-search.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if filtering the items in the call list works properly.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
-  let searchbox = $("#calls-searchbox");
-
-  yield reload(target);
-
-  let firstRecordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([firstRecordingFinished, callListPopulated]);
-
-  is(searchbox.value, "",
-    "The searchbox should be initially empty.");
-  is(CallsListView.visibleItems.length, 8,
-    "All the items should be initially visible in the calls list.");
-
-  searchbox.focus();
-  EventUtils.sendString("clear", window);
-
-  is(searchbox.value, "clear",
-    "The searchbox should now contain the 'clear' string.");
-  is(CallsListView.visibleItems.length, 1,
-    "Only one item should now be visible in the calls list.");
-
-  is(CallsListView.visibleItems[0].attachment.actor.type, CallWatcherFront.METHOD_FUNCTION,
-    "The visible item's type has the expected value.");
-  is(CallsListView.visibleItems[0].attachment.actor.name, "clearRect",
-    "The visible item's name has the expected value.");
-  is(CallsListView.visibleItems[0].attachment.actor.file, SIMPLE_CANVAS_URL,
-    "The visible item's file has the expected value.");
-  is(CallsListView.visibleItems[0].attachment.actor.line, 25,
-    "The visible item's line has the expected value.");
-  is(CallsListView.visibleItems[0].attachment.actor.argsPreview, "0, 0, 128, 128",
-    "The visible item's args have the expected value.");
-  is(CallsListView.visibleItems[0].attachment.actor.callerPreview, "ctx",
-    "The visible item's caller has the expected value.");
-
-  let secondRecordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-
-  SnapshotsListView._onRecordButtonClick();
-  yield secondRecordingFinished;
-
-  SnapshotsListView.selectedIndex = 1;
-  yield callListPopulated;
-
-  is(searchbox.value, "clear",
-    "The searchbox should still contain the 'clear' string.");
-  is(CallsListView.visibleItems.length, 1,
-    "Only one item should still be visible in the calls list.");
-
-  for (let i = 0; i < 5; i++) {
-    searchbox.focus();
-    EventUtils.sendKey("BACK_SPACE", window);
-  }
-
-  is(searchbox.value, "",
-    "The searchbox should now be emptied.");
-  is(CallsListView.visibleItems.length, 8,
-    "All the items should be initially visible again in the calls list.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-stack-01.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if the a function call's stack is properly displayed in the UI.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_DEEP_STACK_URL);
-  let { window, $, $all, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([recordingFinished, callListPopulated]);
-
-  let callItem = CallsListView.getItemAtIndex(2);
-  let locationLink = $(".call-item-location", callItem.target);
-
-  is($(".call-item-stack", callItem.target), null,
-    "There should be no stack container available yet for the draw call.");
-
-  let callStackDisplayed = once(window, EVENTS.CALL_STACK_DISPLAYED);
-  EventUtils.sendMouseEvent({ type: "mousedown" }, locationLink, window);
-  yield callStackDisplayed;
-
-  isnot($(".call-item-stack", callItem.target), null,
-    "There should be a stack container available now for the draw call.");
-  is($all(".call-item-stack-fn", callItem.target).length, 4,
-    "There should be 4 functions on the stack for the draw call.");
-
-  ok($all(".call-item-stack-fn-name", callItem.target)[0].getAttribute("value")
-    .contains("C()"),
-    "The first function on the stack has the correct name.");
-  ok($all(".call-item-stack-fn-name", callItem.target)[1].getAttribute("value")
-    .contains("B()"),
-    "The second function on the stack has the correct name.");
-  ok($all(".call-item-stack-fn-name", callItem.target)[2].getAttribute("value")
-    .contains("A()"),
-    "The third function on the stack has the correct name.");
-  ok($all(".call-item-stack-fn-name", callItem.target)[3].getAttribute("value")
-    .contains("drawRect()"),
-    "The fourth function on the stack has the correct name.");
-
-  is($all(".call-item-stack-fn-location", callItem.target)[0].getAttribute("value"),
-    "doc_simple-canvas-deep-stack.html:26",
-    "The first function on the stack has the correct location.");
-  is($all(".call-item-stack-fn-location", callItem.target)[1].getAttribute("value"),
-    "doc_simple-canvas-deep-stack.html:28",
-    "The second function on the stack has the correct location.");
-  is($all(".call-item-stack-fn-location", callItem.target)[2].getAttribute("value"),
-    "doc_simple-canvas-deep-stack.html:30",
-    "The third function on the stack has the correct location.");
-  is($all(".call-item-stack-fn-location", callItem.target)[3].getAttribute("value"),
-    "doc_simple-canvas-deep-stack.html:35",
-    "The fourth function on the stack has the correct location.");
-
-  let jumpedToSource = once(window, EVENTS.SOURCE_SHOWN_IN_JS_DEBUGGER);
-  EventUtils.sendMouseEvent({ type: "mousedown" }, $(".call-item-stack-fn-location", callItem.target));
-  yield jumpedToSource;
-
-  let toolbox = yield gDevTools.getToolbox(target);
-  let { panelWin: { DebuggerView: view } } = toolbox.getPanel("jsdebugger");
-
-  is(view.Sources.selectedValue, SIMPLE_CANVAS_DEEP_STACK_URL,
-    "The expected source was shown in the debugger.");
-  is(view.editor.getCursor().line, 25,
-    "The expected source line is highlighted in the debugger.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-stack-02.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if the a function call's stack is properly displayed in the UI
- * and jumping to source in the debugger for the topmost call item works.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_DEEP_STACK_URL);
-  let { window, $, $all, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([recordingFinished, callListPopulated]);
-
-  let callItem = CallsListView.getItemAtIndex(2);
-  let locationLink = $(".call-item-location", callItem.target);
-
-  is($(".call-item-stack", callItem.target), null,
-    "There should be no stack container available yet for the draw call.");
-
-  let callStackDisplayed = once(window, EVENTS.CALL_STACK_DISPLAYED);
-  EventUtils.sendMouseEvent({ type: "mousedown" }, locationLink, window);
-  yield callStackDisplayed;
-
-  isnot($(".call-item-stack", callItem.target), null,
-    "There should be a stack container available now for the draw call.");
-  is($all(".call-item-stack-fn", callItem.target).length, 4,
-    "There should be 4 functions on the stack for the draw call.");
-
-  let jumpedToSource = once(window, EVENTS.SOURCE_SHOWN_IN_JS_DEBUGGER);
-  EventUtils.sendMouseEvent({ type: "mousedown" }, $(".call-item-location", callItem.target));
-  yield jumpedToSource;
-
-  let toolbox = yield gDevTools.getToolbox(target);
-  let { panelWin: { DebuggerView: view } } = toolbox.getPanel("jsdebugger");
-
-  is(view.Sources.selectedValue, SIMPLE_CANVAS_DEEP_STACK_URL,
-    "The expected source was shown in the debugger.");
-  is(view.editor.getCursor().line, 23,
-    "The expected source line is highlighted in the debugger.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-call-stack-03.js
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if the a function call's stack can be shown/hidden by double-clicking
- * on a function call item.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_DEEP_STACK_URL);
-  let { window, $, $all, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([recordingFinished, callListPopulated]);
-
-  let callItem = CallsListView.getItemAtIndex(2);
-  let view = $(".call-item-view", callItem.target);
-  let contents = $(".call-item-contents", callItem.target);
-
-  is(view.hasAttribute("call-stack-populated"), false,
-    "The call item's view should not have the stack populated yet.");
-  is(view.hasAttribute("call-stack-expanded"), false,
-    "The call item's view should not have the stack populated yet.");
-  is($(".call-item-stack", callItem.target), null,
-    "There should be no stack container available yet for the draw call.");
-
-  let callStackDisplayed = once(window, EVENTS.CALL_STACK_DISPLAYED);
-  EventUtils.sendMouseEvent({ type: "dblclick" }, contents, window);
-  yield callStackDisplayed;
-
-  is(view.hasAttribute("call-stack-populated"), true,
-    "The call item's view should have the stack populated now.");
-  is(view.getAttribute("call-stack-expanded"), "true",
-    "The call item's view should have the stack expanded now.");
-  isnot($(".call-item-stack", callItem.target), null,
-    "There should be a stack container available now for the draw call.");
-  is($(".call-item-stack", callItem.target).hidden, false,
-    "The stack container should now be visible.");
-  is($all(".call-item-stack-fn", callItem.target).length, 4,
-    "There should be 4 functions on the stack for the draw call.");
-
-  EventUtils.sendMouseEvent({ type: "dblclick" }, contents, window);
-
-  is(view.hasAttribute("call-stack-populated"), true,
-    "The call item's view should still have the stack populated.");
-  is(view.getAttribute("call-stack-expanded"), "false",
-    "The call item's view should not have the stack expanded anymore.");
-  isnot($(".call-item-stack", callItem.target), null,
-    "There should still be a stack container available for the draw call.");
-  is($(".call-item-stack", callItem.target).hidden, true,
-    "The stack container should now be hidden.");
-  is($all(".call-item-stack-fn", callItem.target).length, 4,
-    "There should still be 4 functions on the stack for the draw call.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-clear.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if clearing the snapshots list works as expected.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, EVENTS, SnapshotsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let firstRecordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  SnapshotsListView._onRecordButtonClick();
-
-  yield firstRecordingFinished;
-  ok(true, "Finished recording a snapshot of the animation loop.");
-
-  is(SnapshotsListView.itemCount, 1,
-    "There should be one item available in the snapshots list.");
-
-  let secondRecordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  SnapshotsListView._onRecordButtonClick();
-
-  yield secondRecordingFinished;
-  ok(true, "Finished recording another snapshot of the animation loop.");
-
-  is(SnapshotsListView.itemCount, 2,
-    "There should be two items available in the snapshots list.");
-
-  let clearingFinished = once(window, EVENTS.SNAPSHOTS_LIST_CLEARED);
-  SnapshotsListView._onClearButtonClick();
-
-  yield clearingFinished;
-  ok(true, "Finished recording all snapshots.");
-
-  is(SnapshotsListView.itemCount, 0,
-    "There should be no items available in the snapshots list.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-img-screenshots.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if screenshots are properly displayed in the UI.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, EVENTS, SnapshotsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  let screenshotDisplayed = once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([recordingFinished, callListPopulated, screenshotDisplayed]);
-
-  is($("#screenshot-container").hidden, false,
-    "The screenshot container should now be visible.");
-
-  is($("#screenshot-dimensions").getAttribute("value"), "128 x 128",
-    "The screenshot dimensions label has the expected value.");
-
-  is($("#screenshot-image").getAttribute("flipped"), "false",
-    "The screenshot element should not be flipped vertically.");
-
-  ok(window.getComputedStyle($("#screenshot-image")).backgroundImage.contains("#screenshot-rendering"),
-    "The screenshot element should have an offscreen canvas element as a background.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-img-thumbnails-01.js
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if thumbnails are properly displayed in the UI.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, $all, EVENTS, SnapshotsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  let thumbnailsDisplayed = once(window, EVENTS.THUMBNAILS_DISPLAYED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([recordingFinished, callListPopulated, thumbnailsDisplayed]);
-
-  is($all(".filmstrip-thumbnail").length, 4,
-    "There should be 4 thumbnails displayed in the UI.");
-
-  let firstThumbnail = $(".filmstrip-thumbnail[index='0']");
-  ok(firstThumbnail,
-    "The first thumbnail element should be for the function call at index 0.");
-  is(firstThumbnail.width, 50,
-    "The first thumbnail's width is correct.");
-  is(firstThumbnail.height, 50,
-    "The first thumbnail's height is correct.");
-  is(firstThumbnail.getAttribute("flipped"), "false",
-    "The first thumbnail should not be flipped vertically.");
-
-  let secondThumbnail = $(".filmstrip-thumbnail[index='2']");
-  ok(secondThumbnail,
-    "The second thumbnail element should be for the function call at index 2.");
-  is(secondThumbnail.width, 50,
-    "The second thumbnail's width is correct.");
-  is(secondThumbnail.height, 50,
-    "The second thumbnail's height is correct.");
-  is(secondThumbnail.getAttribute("flipped"), "false",
-    "The second thumbnail should not be flipped vertically.");
-
-  let thirdThumbnail = $(".filmstrip-thumbnail[index='4']");
-  ok(thirdThumbnail,
-    "The third thumbnail element should be for the function call at index 4.");
-  is(thirdThumbnail.width, 50,
-    "The third thumbnail's width is correct.");
-  is(thirdThumbnail.height, 50,
-    "The third thumbnail's height is correct.");
-  is(thirdThumbnail.getAttribute("flipped"), "false",
-    "The third thumbnail should not be flipped vertically.");
-
-  let fourthThumbnail = $(".filmstrip-thumbnail[index='6']");
-  ok(fourthThumbnail,
-    "The fourth thumbnail element should be for the function call at index 6.");
-  is(fourthThumbnail.width, 50,
-    "The fourth thumbnail's width is correct.");
-  is(fourthThumbnail.height, 50,
-    "The fourth thumbnail's height is correct.");
-  is(fourthThumbnail.getAttribute("flipped"), "false",
-    "The fourth thumbnail should not be flipped vertically.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-img-thumbnails-02.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if thumbnails are correctly linked with other UI elements like
- * function call items and their respective screenshots.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, $all, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  let thumbnailsDisplayed = once(window, EVENTS.THUMBNAILS_DISPLAYED);
-  let screenshotDisplayed = once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([
-    recordingFinished,
-    callListPopulated,
-    thumbnailsDisplayed,
-    screenshotDisplayed
-  ]);
-
-  is($all(".filmstrip-thumbnail[highlighted]").length, 0,
-    "There should be no highlighted thumbnail available yet.");
-  is(CallsListView.selectedIndex, -1,
-    "There should be no selected item in the calls list view.");
-
-  EventUtils.sendMouseEvent({ type: "mousedown" }, $all(".filmstrip-thumbnail")[0], window);
-  yield once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  info("The first draw call was selected, by clicking the first thumbnail.");
-
-  isnot($(".filmstrip-thumbnail[highlighted][index='0']"), null,
-    "There should be a highlighted thumbnail available now, for the first draw call.");
-  is($all(".filmstrip-thumbnail[highlighted]").length, 1,
-    "There should be only one highlighted thumbnail available now.");
-  is(CallsListView.selectedIndex, 0,
-    "The first draw call should be selected in the calls list view.");
-
-  EventUtils.sendMouseEvent({ type: "mousedown" }, $all(".call-item-view")[1], window);
-  yield once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  info("The second context call was selected, by clicking the second call item.");
-
-  isnot($(".filmstrip-thumbnail[highlighted][index='0']"), null,
-    "There should be a highlighted thumbnail available, for the first draw call.");
-  is($all(".filmstrip-thumbnail[highlighted]").length, 1,
-    "There should be only one highlighted thumbnail available.");
-  is(CallsListView.selectedIndex, 1,
-    "The second draw call should be selected in the calls list view.");
-
-  EventUtils.sendMouseEvent({ type: "mousedown" }, $all(".call-item-view")[2], window);
-  yield once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  info("The second draw call was selected, by clicking the third call item.");
-
-  isnot($(".filmstrip-thumbnail[highlighted][index='2']"), null,
-    "There should be a highlighted thumbnail available, for the second draw call.");
-  is($all(".filmstrip-thumbnail[highlighted]").length, 1,
-    "There should be only one highlighted thumbnail available.");
-  is(CallsListView.selectedIndex, 2,
-    "The second draw call should be selected in the calls list view.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-open.js
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests that the frontend UI is properly configured when opening the tool.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { $ } = panel.panelWin;
-
-  is($("#snapshots-pane").hasAttribute("hidden"), false,
-    "The snapshots pane should initially be visible.");
-  is($("#debugging-pane").hasAttribute("hidden"), false,
-    "The debugging pane should initially be visible.");
-
-  is($("#record-snapshot").getAttribute("hidden"), "true",
-    "The 'record snapshot' button should initially be hidden.");
-  is($("#import-snapshot").hasAttribute("hidden"), false,
-    "The 'import snapshot' button should initially be visible.");
-  is($("#clear-snapshots").hasAttribute("hidden"), false,
-    "The 'clear snapshots' button should initially be visible.");
-
-  is($("#reload-notice").hasAttribute("hidden"), false,
-    "The reload notice should initially be visible.");
-  is($("#empty-notice").getAttribute("hidden"), "true",
-    "The empty notice should initially be hidden.");
-  is($("#import-notice").getAttribute("hidden"), "true",
-    "The import notice should initially be hidden.");
-
-  is($("#screenshot-container").getAttribute("hidden"), "true",
-    "The screenshot container should initially be hidden.");
-  is($("#snapshot-filmstrip").getAttribute("hidden"), "true",
-    "The snapshot filmstrip should initially be hidden.");
-
-  is($("#debugging-pane-contents").getAttribute("hidden"), "true",
-    "The rest of the UI should initially be hidden.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-record-01.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests whether the frontend behaves correctly while reording a snapshot.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, EVENTS, $, SnapshotsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  is($("#record-snapshot").hasAttribute("checked"), false,
-    "The 'record snapshot' button should initially be unchecked.");
-  is($("#record-snapshot").hasAttribute("disabled"), false,
-    "The 'record snapshot' button should initially be enabled.");
-  is($("#record-snapshot").hasAttribute("hidden"), false,
-    "The 'record snapshot' button should now be visible.");
-
-  is(SnapshotsListView.itemCount, 0,
-    "There should be no items available in the snapshots list view.");
-  is(SnapshotsListView.selectedIndex, -1,
-    "There should be no selected item in the snapshots list view.");
-
-  let recordingStarted = once(window, EVENTS.SNAPSHOT_RECORDING_STARTED);
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  SnapshotsListView._onRecordButtonClick();
-
-  yield recordingStarted;
-  ok(true, "Started recording a snapshot of the animation loop.");
-
-  is($("#record-snapshot").getAttribute("checked"), "true",
-    "The 'record snapshot' button should now be checked.");
-  is($("#record-snapshot").getAttribute("disabled"), "true",
-    "The 'record snapshot' button should now be disabled.");
-  is($("#record-snapshot").hasAttribute("hidden"), false,
-    "The 'record snapshot' button should still be visible.");
-
-  is(SnapshotsListView.itemCount, 1,
-    "There should be one item available in the snapshots list view now.");
-  is(SnapshotsListView.selectedIndex, -1,
-    "There should be no selected item in the snapshots list view yet.");
-
-  yield recordingFinished;
-  ok(true, "Finished recording a snapshot of the animation loop.");
-
-  is($("#record-snapshot").hasAttribute("checked"), false,
-    "The 'record snapshot' button should now be unchecked.");
-  is($("#record-snapshot").hasAttribute("disabled"), false,
-    "The 'record snapshot' button should now be re-enabled.");
-  is($("#record-snapshot").hasAttribute("hidden"), false,
-    "The 'record snapshot' button should still be visible.");
-
-  is(SnapshotsListView.itemCount, 1,
-    "There should still be only one item available in the snapshots list view.");
-  is(SnapshotsListView.selectedIndex, 0,
-    "There should be one selected item in the snapshots list view now.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-record-02.js
+++ /dev/null
@@ -1,73 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests whether the frontend displays a placeholder snapshot while recording.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, EVENTS, L10N, $, SnapshotsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingStarted = once(window, EVENTS.SNAPSHOT_RECORDING_STARTED);
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let recordingSelected = once(window, EVENTS.SNAPSHOT_RECORDING_SELECTED);
-  SnapshotsListView._onRecordButtonClick();
-
-  yield recordingStarted;
-  ok(true, "Started recording a snapshot of the animation loop.");
-
-  let item = SnapshotsListView.getItemAtIndex(0);
-
-  is($(".snapshot-item-title", item.target).getAttribute("value"),
-    L10N.getFormatStr("snapshotsList.itemLabel", 1),
-    "The placeholder item's title label is correct.");
-
-  is($(".snapshot-item-calls", item.target).getAttribute("value"),
-    L10N.getStr("snapshotsList.loadingLabel"),
-    "The placeholder item's calls label is correct.");
-
-  is($(".snapshot-item-save", item.target).getAttribute("value"), "",
-    "The placeholder item's save label should not have a value yet.");
-
-  is($("#reload-notice").getAttribute("hidden"), "true",
-    "The reload notice should now be hidden.");
-  is($("#empty-notice").getAttribute("hidden"), "true",
-    "The empty notice should now be hidden.");
-  is($("#import-notice").hasAttribute("hidden"), false,
-    "The import notice should now be visible.");
-
-  is($("#screenshot-container").getAttribute("hidden"), "true",
-    "The screenshot container should still be hidden.");
-  is($("#snapshot-filmstrip").getAttribute("hidden"), "true",
-    "The snapshot filmstrip should still be hidden.");
-
-  is($("#debugging-pane-contents").getAttribute("hidden"), "true",
-    "The rest of the UI should still be hidden.");
-
-  yield recordingFinished;
-  ok(true, "Finished recording a snapshot of the animation loop.");
-
-  yield recordingSelected;
-  ok(true, "Finished selecting a snapshot of the animation loop.");
-
-  is($("#reload-notice").getAttribute("hidden"), "true",
-    "The reload notice should now be hidden.");
-  is($("#empty-notice").getAttribute("hidden"), "true",
-    "The empty notice should now be hidden.");
-  is($("#import-notice").getAttribute("hidden"), "true",
-    "The import notice should now be hidden.");
-
-  is($("#screenshot-container").hasAttribute("hidden"), false,
-    "The screenshot container should now be visible.");
-  is($("#snapshot-filmstrip").hasAttribute("hidden"), false,
-    "The snapshot filmstrip should now be visible.");
-
-  is($("#debugging-pane-contents").hasAttribute("hidden"), false,
-    "The rest of the UI should now be visible.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-record-03.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests whether the frontend displays the correct info for a snapshot
- * after finishing recording.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, EVENTS, $, SnapshotsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  SnapshotsListView._onRecordButtonClick();
-
-  yield recordingFinished;
-  ok(true, "Finished recording a snapshot of the animation loop.");
-
-  let item = SnapshotsListView.getItemAtIndex(0);
-
-  is(SnapshotsListView.selectedItem, item,
-    "The first item should now be selected in the snapshots list view (1).");
-  is(SnapshotsListView.selectedIndex, 0,
-    "The first item should now be selected in the snapshots list view (2).");
-
-  is($(".snapshot-item-calls", item.target).getAttribute("value"), "4 draws, 8 calls",
-    "The placeholder item's calls label is correct.");
-  is($(".snapshot-item-save", item.target).getAttribute("value"), "Save",
-    "The placeholder item's save label is correct.");
-  is($(".snapshot-item-save", item.target).getAttribute("disabled"), "false",
-    "The placeholder item's save label should be clickable.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-reload-01.js
+++ /dev/null
@@ -1,55 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests that the frontend UI is properly reconfigured after reloading.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, EVENTS } = panel.panelWin;
-
-  let reset = once(window, EVENTS.UI_RESET);
-  let navigated = reload(target);
-
-  yield reset;
-  ok(true, "The UI was reset after the refresh button was clicked.");
-
-  yield navigated;
-  ok(true, "The target finished reloading.");
-
-  is($("#snapshots-pane").hasAttribute("hidden"), false,
-    "The snapshots pane should still be visible.");
-  is($("#debugging-pane").hasAttribute("hidden"), false,
-    "The debugging pane should still be visible.");
-
-  is($("#record-snapshot").hasAttribute("checked"), false,
-    "The 'record snapshot' button should not be checked.");
-  is($("#record-snapshot").hasAttribute("disabled"), false,
-    "The 'record snapshot' button should not be disabled.");
-
-  is($("#record-snapshot").hasAttribute("hidden"), false,
-    "The 'record snapshot' button should now be visible.");
-  is($("#import-snapshot").hasAttribute("hidden"), false,
-    "The 'import snapshot' button should still be visible.");
-  is($("#clear-snapshots").hasAttribute("hidden"), false,
-    "The 'clear snapshots' button should still be visible.");
-
-  is($("#reload-notice").getAttribute("hidden"), "true",
-    "The reload notice should now be hidden.");
-  is($("#empty-notice").hasAttribute("hidden"), false,
-    "The empty notice should now be visible.");
-  is($("#import-notice").getAttribute("hidden"), "true",
-    "The import notice should now be hidden.");
-
-  is($("#snapshot-filmstrip").getAttribute("hidden"), "true",
-    "The snapshot filmstrip should still be hidden.");
-  is($("#screenshot-container").getAttribute("hidden"), "true",
-    "The screenshot container should still be hidden.");
-
-  is($("#debugging-pane-contents").getAttribute("hidden"), "true",
-    "The rest of the UI should still be hidden.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-reload-02.js
+++ /dev/null
@@ -1,70 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests that the frontend UI is properly reconfigured after reloading.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, $all, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
-
-  is(SnapshotsListView.itemCount, 0,
-    "There should be no snapshots initially displayed in the UI.");
-  is(CallsListView.itemCount, 0,
-    "There should be no function calls initially displayed in the UI.");
-
-  is($("#screenshot-container").hidden, true,
-    "The screenshot should not be initially displayed in the UI.");
-  is($("#snapshot-filmstrip").hidden, true,
-    "There should be no thumbnails initially displayed in the UI (1).");
-  is($all(".filmstrip-thumbnail").length, 0,
-    "There should be no thumbnails initially displayed in the UI (2).");
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  let thumbnailsDisplayed = once(window, EVENTS.THUMBNAILS_DISPLAYED);
-  let screenshotDisplayed = once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([
-    recordingFinished,
-    callListPopulated,
-    thumbnailsDisplayed,
-    screenshotDisplayed
-  ]);
-
-  is(SnapshotsListView.itemCount, 1,
-    "There should be one snapshot displayed in the UI.");
-  is(CallsListView.itemCount, 8,
-    "All the function calls should now be displayed in the UI.");
-
-  is($("#screenshot-container").hidden, false,
-    "The screenshot should now be displayed in the UI.");
-  is($("#snapshot-filmstrip").hidden, false,
-    "All the thumbnails should now be displayed in the UI (1).");
-  is($all(".filmstrip-thumbnail").length, 4,
-    "All the thumbnails should now be displayed in the UI (2).");
-
-  let reset = once(window, EVENTS.UI_RESET);
-  let navigated = reload(target);
-
-  yield reset;
-  ok(true, "The UI was reset after the refresh button was clicked.");
-
-  is(SnapshotsListView.itemCount, 0,
-    "There should be no snapshots displayed in the UI after navigating.");
-  is(CallsListView.itemCount, 0,
-    "There should be no function calls displayed in the UI after navigating.");
-  is($("#snapshot-filmstrip").hidden, true,
-    "There should be no thumbnails displayed in the UI after navigating.");
-  is($("#screenshot-container").hidden, true,
-    "The screenshot should not be displayed in the UI after navigating.");
-
-  yield navigated;
-  ok(true, "The target finished reloading.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-slider-01.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if the slider in the calls list view works as advertised.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([recordingFinished, callListPopulated]);
-
-  is(CallsListView.selectedIndex, -1,
-    "No item in the function calls list should be initially selected.");
-
-  is($("#calls-slider").value, 0,
-    "The slider should be moved all the way to the start.");
-  is($("#calls-slider").min, 0,
-    "The slider minimum value should be 0.");
-  is($("#calls-slider").max, 7,
-    "The slider maximum value should be 7.");
-
-  CallsListView.selectedIndex = 1;
-  is($("#calls-slider").value, 1,
-    "The slider should be changed according to the current selection.");
-
-  $("#calls-slider").value = 2;
-  is(CallsListView.selectedIndex, 2,
-    "The calls selection should be changed according to the current slider value.");
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-slider-02.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if the slider in the calls list view works as advertised.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, EVENTS, gFront, SnapshotsListView, CallsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  let thumbnailsDisplayed = once(window, EVENTS.THUMBNAILS_DISPLAYED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([recordingFinished, callListPopulated, thumbnailsDisplayed]);
-
-  let firstSnapshot = SnapshotsListView.getItemAtIndex(0);
-  let firstSnapshotOverview = yield firstSnapshot.attachment.actor.getOverview();
-
-  let thumbnails = firstSnapshotOverview.thumbnails;
-  is(thumbnails.length, 4,
-    "There should be 4 thumbnails cached for the snapshot item.");
-
-  let thumbnailImageElementSet = waitForMozSetImageElement(window);
-  $("#calls-slider").value = 1;
-  let thumbnailPixels = yield thumbnailImageElementSet;
-
-  ok(sameArray(thumbnailPixels, thumbnails[0].pixels),
-    "The screenshot element should have a thumbnail as an immediate background.");
-
-  yield once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  ok(true, "The full-sized screenshot was displayed for the item at index 1.");
-
-  let thumbnailImageElementSet = waitForMozSetImageElement(window);
-  $("#calls-slider").value = 2;
-  let thumbnailPixels = yield thumbnailImageElementSet;
-
-  ok(sameArray(thumbnailPixels, thumbnails[1].pixels),
-    "The screenshot element should have a thumbnail as an immediate background.");
-
-  yield once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  ok(true, "The full-sized screenshot was displayed for the item at index 2.");
-
-  let thumbnailImageElementSet = waitForMozSetImageElement(window);
-  $("#calls-slider").value = 7;
-  let thumbnailPixels = yield thumbnailImageElementSet;
-
-  ok(sameArray(thumbnailPixels, thumbnails[3].pixels),
-    "The screenshot element should have a thumbnail as an immediate background.");
-
-  yield once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  ok(true, "The full-sized screenshot was displayed for the item at index 7.");
-
-  let thumbnailImageElementSet = waitForMozSetImageElement(window);
-  $("#calls-slider").value = 4;
-  let thumbnailPixels = yield thumbnailImageElementSet;
-
-  ok(sameArray(thumbnailPixels, thumbnails[2].pixels),
-    "The screenshot element should have a thumbnail as an immediate background.");
-
-  yield once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  ok(true, "The full-sized screenshot was displayed for the item at index 4.");
-
-  let thumbnailImageElementSet = waitForMozSetImageElement(window);
-  $("#calls-slider").value = 0;
-  let thumbnailPixels = yield thumbnailImageElementSet;
-
-  ok(sameArray(thumbnailPixels, thumbnails[0].pixels),
-    "The screenshot element should have a thumbnail as an immediate background.");
-
-  yield once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  ok(true, "The full-sized screenshot was displayed for the item at index 0.");
-
-  yield teardown(panel);
-  finish();
-}
-
-function waitForMozSetImageElement(panel) {
-  let deferred = promise.defer();
-  panel._onMozSetImageElement = deferred.resolve;
-  return deferred.promise;
-}
-
-function sameArray(a, b) {
-  if (a.length != b.length) {
-    return false;
-  }
-  for (let i = 0; i < a.length; i++) {
-    if (a[i] !== b[i]) {
-      return false;
-    }
-  }
-  return true;
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-snapshot-select.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if selecting snapshots in the frontend displays the appropriate data
- * respective to their recorded animation frame.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  yield recordAndWaitForFirstSnapshot();
-  info("First snapshot recorded.")
-
-  is(SnapshotsListView.selectedIndex, 0,
-    "A snapshot should be automatically selected after first recording.");
-  is(CallsListView.selectedIndex, -1,
-    "There should be no call item automatically selected in the snapshot.");
-
-  yield recordAndWaitForAnotherSnapshot();
-  info("Second snapshot recorded.")
-
-  is(SnapshotsListView.selectedIndex, 0,
-    "A snapshot should not be automatically selected after another recording.");
-  is(CallsListView.selectedIndex, -1,
-    "There should still be no call item automatically selected in the snapshot.");
-
-  let secondSnapshotTarget = SnapshotsListView.getItemAtIndex(1).target;
-  let snapshotSelected = waitForSnapshotSelection();
-  EventUtils.sendMouseEvent({ type: "mousedown" }, secondSnapshotTarget, window);
-
-  yield snapshotSelected;
-  info("Second snapshot selected.");
-
-  is(SnapshotsListView.selectedIndex, 1,
-    "The second snapshot should now be selected.");
-  is(CallsListView.selectedIndex, -1,
-    "There should still be no call item automatically selected in the snapshot.");
-
-  let firstDrawCallContents = $(".call-item-contents", CallsListView.getItemAtIndex(2).target);
-  let screenshotDisplayed = once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-  EventUtils.sendMouseEvent({ type: "mousedown" }, firstDrawCallContents, window);
-
-  yield screenshotDisplayed;
-  info("First draw call in the second snapshot selected.");
-
-  is(SnapshotsListView.selectedIndex, 1,
-    "The second snapshot should still be selected.");
-  is(CallsListView.selectedIndex, 2,
-    "The first draw call should now be selected in the snapshot.");
-
-  let firstSnapshotTarget = SnapshotsListView.getItemAtIndex(0).target;
-  let snapshotSelected = waitForSnapshotSelection();
-  EventUtils.sendMouseEvent({ type: "mousedown" }, firstSnapshotTarget, window);
-
-  yield snapshotSelected;
-  info("First snapshot re-selected.");
-
-  is(SnapshotsListView.selectedIndex, 0,
-    "The first snapshot should now be re-selected.");
-  is(CallsListView.selectedIndex, -1,
-    "There should still be no call item automatically selected in the snapshot.");
-
-  function recordAndWaitForFirstSnapshot() {
-    let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-    let snapshotSelected = waitForSnapshotSelection();
-    SnapshotsListView._onRecordButtonClick();
-    return promise.all([recordingFinished, snapshotSelected]);
-  }
-
-  function recordAndWaitForAnotherSnapshot() {
-    let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-    SnapshotsListView._onRecordButtonClick();
-    return recordingFinished;
-  }
-
-  function waitForSnapshotSelection() {
-    let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-    let thumbnailsDisplayed = once(window, EVENTS.THUMBNAILS_DISPLAYED);
-    let screenshotDisplayed = once(window, EVENTS.CALL_SCREENSHOT_DISPLAYED);
-    return promise.all([
-      callListPopulated,
-      thumbnailsDisplayed,
-      screenshotDisplayed
-    ]);
-  }
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/browser_canvas-frontend-stepping.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-
-/**
- * Tests if the stepping buttons in the call list toolbar work as advertised.
- */
-
-function ifTestingSupported() {
-  let [target, debuggee, panel] = yield initCanavsDebuggerFrontend(SIMPLE_CANVAS_URL);
-  let { window, $, EVENTS, SnapshotsListView, CallsListView } = panel.panelWin;
-
-  yield reload(target);
-
-  let recordingFinished = once(window, EVENTS.SNAPSHOT_RECORDING_FINISHED);
-  let callListPopulated = once(window, EVENTS.CALL_LIST_POPULATED);
-  SnapshotsListView._onRecordButtonClick();
-  yield promise.all([recordingFinished, callListPopulated]);
-
-  checkSteppingButtons(1, 1, 1, 1);
-  is(CallsListView.selectedIndex, -1,
-    "There should be no selected item in the calls list view initially.");
-
-  CallsListView._onResume();
-  checkSteppingButtons(1, 1, 1, 1);
-  is(CallsListView.selectedIndex, 0,
-    "The first draw call should now be selected.");
-
-  CallsListView._onResume();
-  checkSteppingButtons(1, 1, 1, 1);
-  is(CallsListView.selectedIndex, 2,
-    "The second draw call should now be selected.");
-
-  CallsListView._onStepOver();
-  checkSteppingButtons(1, 1, 1, 1);
-  is(CallsListView.selectedIndex, 3,
-    "The next context call should now be selected.");
-
-  CallsListView._onStepOut();
-  checkSteppingButtons(0, 0, 1, 0);
-  is(CallsListView.selectedIndex, 7,
-    "The last context call should now be selected.");
-
-  function checkSteppingButtons(resume, stepOver, stepIn, stepOut) {
-    if (!resume) {
-      is($("#resume").getAttribute("disabled"), "true",
-        "The resume button doesn't have the expected disabled state.");
-    } else {
-      is($("#resume").hasAttribute("disabled"), false,
-        "The resume button doesn't have the expected enabled state.");
-    }
-    if (!stepOver) {
-      is($("#step-over").getAttribute("disabled"), "true",
-        "The stepOver button doesn't have the expected disabled state.");
-    } else {
-      is($("#step-over").hasAttribute("disabled"), false,
-        "The stepOver button doesn't have the expected enabled state.");
-    }
-    if (!stepIn) {
-      is($("#step-in").getAttribute("disabled"), "true",
-        "The stepIn button doesn't have the expected disabled state.");
-    } else {
-      is($("#step-in").hasAttribute("disabled"), false,
-        "The stepIn button doesn't have the expected enabled state.");
-    }
-    if (!stepOut) {
-      is($("#step-out").getAttribute("disabled"), "true",
-        "The stepOut button doesn't have the expected disabled state.");
-    } else {
-      is($("#step-out").hasAttribute("disabled"), false,
-        "The stepOut button doesn't have the expected enabled state.");
-    }
-  }
-
-  yield teardown(panel);
-  finish();
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/doc_simple-canvas-deep-stack.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!-- Any copyright is dedicated to the Public Domain.
-     http://creativecommons.org/publicdomain/zero/1.0/ -->
-<!doctype html>
-
-<html>
-  <head>
-    <meta charset="utf-8"/>
-    <title>Canvas inspector test page</title>
-  </head>
-
-  <body>
-    <canvas width="128" height="128"></canvas>
-
-    <script type="text/javascript;version=1.8">
-      "use strict";
-
-      var ctx = document.querySelector("canvas").getContext("2d");
-
-      function drawRect(fill, size) {
-        function A() {
-          function B() {
-            function C() {
-              ctx.fillStyle = fill;
-              ctx.fillRect(size[0], size[1], size[2], size[3]);
-            }
-            C();
-          }
-          B();
-        }
-        A();
-      }
-
-      function drawScene() {
-        ctx.clearRect(0, 0, 128, 128);
-        drawRect("rgb(192, 192, 192)", [0, 0, 128, 128]);
-        drawRect("rgba(0, 0, 192, 0.5)", [30, 30, 55, 50]);
-        drawRect("rgba(192, 0, 0, 0.5)", [10, 10, 55, 50]);
-
-        window.requestAnimationFrame(drawScene);
-      }
-
-      drawScene();
-    </script>
-  </body>
-
-</html>
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/doc_simple-canvas-transparent.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!-- Any copyright is dedicated to the Public Domain.
-     http://creativecommons.org/publicdomain/zero/1.0/ -->
-<!doctype html>
-
-<html>
-  <head>
-    <meta charset="utf-8"/>
-    <title>Canvas inspector test page</title>
-  </head>
-
-  <body>
-    <canvas width="128" height="128"></canvas>
-
-    <script type="text/javascript;version=1.8">
-      "use strict";
-
-      var ctx = document.querySelector("canvas").getContext("2d");
-
-      function drawRect(fill, size) {
-        ctx.fillStyle = fill;
-        ctx.fillRect(size[0], size[1], size[2], size[3]);
-      }
-
-      function drawScene() {
-        ctx.clearRect(0, 0, 128, 128);
-        drawRect("rgba(255, 255, 255, 0)", [0, 0, 128, 128]);
-        drawRect("rgba(0, 0, 192, 0.5)", [30, 30, 55, 50]);
-        drawRect("rgba(192, 0, 0, 0.5)", [10, 10, 55, 50]);
-
-        window.requestAnimationFrame(drawScene);
-      }
-
-      drawScene();
-    </script>
-  </body>
-
-</html>
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/doc_simple-canvas.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!-- Any copyright is dedicated to the Public Domain.
-     http://creativecommons.org/publicdomain/zero/1.0/ -->
-<!doctype html>
-
-<html>
-  <head>
-    <meta charset="utf-8"/>
-    <title>Canvas inspector test page</title>
-  </head>
-
-  <body>
-    <canvas width="128" height="128"></canvas>
-
-    <script type="text/javascript;version=1.8">
-      "use strict";
-
-      var ctx = document.querySelector("canvas").getContext("2d");
-
-      function drawRect(fill, size) {
-        ctx.fillStyle = fill;
-        ctx.fillRect(size[0], size[1], size[2], size[3]);
-      }
-
-      function drawScene() {
-        ctx.clearRect(0, 0, 128, 128);
-        drawRect("rgb(192, 192, 192)", [0, 0, 128, 128]);
-        drawRect("rgba(0, 0, 192, 0.5)", [30, 30, 55, 50]);
-        drawRect("rgba(192, 0, 0, 0.5)", [10, 10, 55, 50]);
-
-        window.requestAnimationFrame(drawScene);
-      }
-
-      drawScene();
-    </script>
-  </body>
-
-</html>
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/head.js
+++ /dev/null
@@ -1,234 +0,0 @@
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
-
-let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
-
-// Disable logging for all the tests. Both the debugger server and frontend will
-// be affected by this pref.
-let gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log");
-Services.prefs.setBoolPref("devtools.debugger.log", false);
-
-let { Task } = Cu.import("resource://gre/modules/Task.jsm", {});
-let { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
-let { gDevTools } = Cu.import("resource:///modules/devtools/gDevTools.jsm", {});
-let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {});
-let { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {});
-let { DebuggerClient } = Cu.import("resource://gre/modules/devtools/dbg-client.jsm", {});
-
-let { CallWatcherFront } = devtools.require("devtools/server/actors/call-watcher");
-let { CanvasFront } = devtools.require("devtools/server/actors/canvas");
-let TiltGL = devtools.require("devtools/tilt/tilt-gl");
-let TargetFactory = devtools.TargetFactory;
-let Toolbox = devtools.Toolbox;
-
-const EXAMPLE_URL = "http://example.com/browser/browser/devtools/canvasdebugger/test/";
-const SIMPLE_CANVAS_URL = EXAMPLE_URL + "doc_simple-canvas.html";
-const SIMPLE_CANVAS_TRANSPARENT_URL = EXAMPLE_URL + "doc_simple-canvas-transparent.html";
-const SIMPLE_CANVAS_DEEP_STACK_URL = EXAMPLE_URL + "doc_simple-canvas-deep-stack.html";
-
-// All tests are asynchronous.
-waitForExplicitFinish();
-
-let gToolEnabled = Services.prefs.getBoolPref("devtools.canvasdebugger.enabled");
-
-registerCleanupFunction(() => {
-  info("finish() was called, cleaning up...");
-  Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging);
-  Services.prefs.setBoolPref("devtools.canvasdebugger.enabled", gToolEnabled);
-
-  // Some of yhese tests use a lot of memory due to GL contexts, so force a GC
-  // to help fragmentation.
-  info("Forcing GC after canvas debugger test.");
-  Cu.forceGC();
-});
-
-function addTab(aUrl, aWindow) {
-  info("Adding tab: " + aUrl);
-
-  let deferred = promise.defer();
-  let targetWindow = aWindow || window;
-  let targetBrowser = targetWindow.gBrowser;
-
-  targetWindow.focus();
-  let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl);
-  let linkedBrowser = tab.linkedBrowser;
-
-  linkedBrowser.addEventListener("load", function onLoad() {
-    linkedBrowser.removeEventListener("load", onLoad, true);
-    info("Tab added and finished loading: " + aUrl);
-    deferred.resolve(tab);
-  }, true);
-
-  return deferred.promise;
-}
-
-function removeTab(aTab, aWindow) {
-  info("Removing tab.");
-
-  let deferred = promise.defer();
-  let targetWindow = aWindow || window;
-  let targetBrowser = targetWindow.gBrowser;
-  let tabContainer = targetBrowser.tabContainer;
-
-  tabContainer.addEventListener("TabClose", function onClose(aEvent) {
-    tabContainer.removeEventListener("TabClose", onClose, false);
-    info("Tab removed and finished closing.");
-    deferred.resolve();
-  }, false);
-
-  targetBrowser.removeTab(aTab);
-  return deferred.promise;
-}
-
-function handleError(aError) {
-  ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
-  finish();
-}
-
-let gRequiresWebGL = false;
-
-function ifTestingSupported() {
-  ok(false, "You need to define a 'ifTestingSupported' function.");
-  finish();
-}
-
-function ifTestingUnsupported() {
-  todo(false, "Skipping test because some required functionality isn't supported.");
-  finish();
-}
-
-function test() {
-  let generator = isTestingSupported() ? ifTestingSupported : ifTestingUnsupported;
-  Task.spawn(generator).then(null, handleError);
-}
-
-function createCanvas() {
-  return document.createElementNS("http://www.w3.org/1999/xhtml", "canvas");
-}
-
-function isTestingSupported() {
-  if (!gRequiresWebGL) {
-    info("This test does not require WebGL support.");
-    return true;
-  }
-
-  let supported =
-    !TiltGL.isWebGLForceEnabled() &&
-     TiltGL.isWebGLSupported() &&
-     TiltGL.create3DContext(createCanvas());
-
-  info("This test requires WebGL support.");
-  info("Apparently, WebGL is" + (supported ? "" : " not") + " supported.");
-  return supported;
-}
-
-function once(aTarget, aEventName, aUseCapture = false) {
-  info("Waiting for event: '" + aEventName + "' on " + aTarget + ".");
-
-  let deferred = promise.defer();
-
-  for (let [add, remove] of [
-    ["on", "off"], // Use event emitter before DOM events for consistency
-    ["addEventListener", "removeEventListener"],
-    ["addListener", "removeListener"]
-  ]) {
-    if ((add in aTarget) && (remove in aTarget)) {
-      aTarget[add](aEventName, function onEvent(...aArgs) {
-        aTarget[remove](aEventName, onEvent, aUseCapture);
-        deferred.resolve(...aArgs);
-      }, aUseCapture);
-      break;
-    }
-  }
-
-  return deferred.promise;
-}
-
-function waitForTick() {
-  let deferred = promise.defer();
-  executeSoon(deferred.resolve);
-  return deferred.promise;
-}
-
-function navigateInHistory(aTarget, aDirection, aWaitForTargetEvent = "navigate") {
-  executeSoon(() => content.history[aDirection]());
-  return once(aTarget, aWaitForTargetEvent);
-}
-
-function navigate(aTarget, aUrl, aWaitForTargetEvent = "navigate") {
-  executeSoon(() => aTarget.activeTab.navigateTo(aUrl));
-  return once(aTarget, aWaitForTargetEvent);
-}
-
-function reload(aTarget, aWaitForTargetEvent = "navigate") {
-  executeSoon(() => aTarget.activeTab.reload());
-  return once(aTarget, aWaitForTargetEvent);
-}
-
-function initServer() {
-  if (!DebuggerServer.initialized) {
-    DebuggerServer.init(() => true);
-    DebuggerServer.addBrowserActors();
-  }
-}
-
-function initCallWatcherBackend(aUrl) {
-  info("Initializing a call watcher front.");
-  initServer();
-
-  return Task.spawn(function*() {
-    let tab = yield addTab(aUrl);
-    let target = TargetFactory.forTab(tab);
-    let debuggee = target.window.wrappedJSObject;
-
-    yield target.makeRemote();
-
-    let front = new CallWatcherFront(target.client, target.form);
-    return [target, debuggee, front];
-  });
-}
-
-function initCanavsDebuggerBackend(aUrl) {
-  info("Initializing a canvas debugger front.");
-  initServer();
-
-  return Task.spawn(function*() {
-    let tab = yield addTab(aUrl);
-    let target = TargetFactory.forTab(tab);
-    let debuggee = target.window.wrappedJSObject;
-
-    yield target.makeRemote();
-
-    let front = new CanvasFront(target.client, target.form);
-    return [target, debuggee, front];
-  });
-}
-
-function initCanavsDebuggerFrontend(aUrl) {
-  info("Initializing a canvas debugger pane.");
-
-  return Task.spawn(function*() {
-    let tab = yield addTab(aUrl);
-    let target = TargetFactory.forTab(tab);
-    let debuggee = target.window.wrappedJSObject;
-
-    yield target.makeRemote();
-
-    Services.prefs.setBoolPref("devtools.canvasdebugger.enabled", true);
-    let toolbox = yield gDevTools.showToolbox(target, "canvasdebugger");
-    let panel = toolbox.getCurrentPanel();
-    return [target, debuggee, panel];
-  });
-}
-
-function teardown(aPanel) {
-  info("Destroying the specified canvas debugger.");
-
-  return promise.all([
-    once(aPanel, "destroyed"),
-    removeTab(aPanel.target.tab)
-  ]);
-}
deleted file mode 100644
--- a/browser/devtools/canvasdebugger/test/moz.build
+++ /dev/null
@@ -1,6 +0,0 @@
-# vim: set filetype=python:
-# 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/.
-
-BROWSER_CHROME_MANIFESTS += ['browser.ini']
--- a/browser/devtools/debugger/debugger-view.js
+++ b/browser/devtools/debugger/debugger-view.js
@@ -385,17 +385,18 @@ let DebuggerView = {
     let histogram = Services.telemetry.getHistogramById(histogramId);
     let startTime = Date.now();
 
     let deferred = promise.defer();
 
     this._setEditorText(L10N.getStr("loadingText"));
     this._editorSource = { url: aSource.url, promise: deferred.promise };
 
-    DebuggerController.SourceScripts.getText(aSource).then(([, aText, aContentType]) => {
+    DebuggerController.SourceScripts.getText(aSource)
+                                    .then(([, aText, aContentType]) => {
       // Avoid setting an unexpected source. This may happen when switching
       // very fast between sources that haven't been fetched yet.
       if (this._editorSource.url != aSource.url) {
         return;
       }
 
       this._setEditorText(aText);
       this._setEditorMode(aSource.url, aContentType, aText);
@@ -463,17 +464,18 @@ let DebuggerView = {
       }
     }
 
     let sourceItem = this.Sources.getItemByValue(aUrl);
     let sourceForm = sourceItem.attachment.source;
 
     // Make sure the requested source client is shown in the editor, then
     // update the source editor's caret position and debug location.
-    return this._setEditorSource(sourceForm, aFlags).then(([,, aContentType]) => {
+    return this._setEditorSource(sourceForm, aFlags)
+               .then(([,, aContentType]) => {
       // Record the contentType learned from fetching
       sourceForm.contentType = aContentType;
       // Line numbers in the source editor should start from 1. If invalid
       // or not specified, then don't do anything.
       if (aLine < 1) {
         window.emit(EVENTS.EDITOR_LOCATION_SET);
         return;
       }
--- a/browser/devtools/debugger/debugger.xul
+++ b/browser/devtools/debugger/debugger.xul
@@ -429,17 +429,17 @@
               hidden="true">
         <tabs>
           <tab id="variables-tab" label="&debuggerUI.tabs.variables;"/>
           <tab id="events-tab" label="&debuggerUI.tabs.events;"/>
         </tabs>
         <tabpanels flex="1">
           <tabpanel id="variables-tabpanel">
             <vbox id="expressions"/>
-            <splitter class="devtools-horizontal-splitter devtools-invisible-splitter"/>
+            <splitter class="devtools-horizontal-splitter devtools-invisible splitter"/>
             <vbox id="variables" flex="1"/>
           </tabpanel>
           <tabpanel id="events-tabpanel">
             <vbox id="event-listeners" flex="1"/>
           </tabpanel>
         </tabpanels>
       </tabbox>
       <splitter id="vertical-layout-splitter"
--- a/browser/devtools/debugger/panel.js
+++ b/browser/devtools/debugger/panel.js
@@ -3,16 +3,17 @@
 /* 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 { Cc, Ci, Cu, Cr } = require("chrome");
 const promise = require("sdk/core/promise");
 const EventEmitter = require("devtools/toolkit/event-emitter");
+
 const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
 
 function DebuggerPanel(iframeWindow, toolbox) {
   this.panelWin = iframeWindow;
   this._toolbox = toolbox;
   this._destroyer = null;
 
   this._view = this.panelWin.DebuggerView;
@@ -54,17 +55,17 @@ DebuggerPanel.prototype = {
         this._toolbox.on("host-changed", this.handleHostChanged);
         this.target.on("thread-paused", this.highlightWhenPaused);
         this.target.on("thread-resumed", this.unhighlightWhenResumed);
         this.isReady = true;
         this.emit("ready");
         return this;
       })
       .then(null, function onError(aReason) {
-        DevToolsUtils.reportException("DebuggerPanel.prototype.open", aReason);
+        DevToolsUtils.reportException("DebuggerPane.prototype.open", aReason);
       });
   },
 
   // DevToolPanel API
 
   get target() this._toolbox.target,
 
   destroy: function() {
--- a/browser/devtools/debugger/test/head.js
+++ b/browser/devtools/debugger/test/head.js
@@ -240,17 +240,18 @@ function waitForSourceShown(aPanel, aUrl
       return waitForSourceShown(aPanel, aUrl);
     } else {
       ok(true, "The correct source has been shown.");
     }
   });
 }
 
 function waitForEditorLocationSet(aPanel) {
-  return waitForDebuggerEvents(aPanel, aPanel.panelWin.EVENTS.EDITOR_LOCATION_SET);
+  return waitForDebuggerEvents(aPanel,
+                               aPanel.panelWin.EVENTS.EDITOR_LOCATION_SET);
 }
 
 function ensureSourceIs(aPanel, aUrl, aWaitFlag = false) {
   if (aPanel.panelWin.DebuggerView.Sources.selectedValue.contains(aUrl)) {
     ok(true, "Expected source is shown: " + aUrl);
     return promise.resolve(null);
   }
   if (aWaitFlag) {
--- a/browser/devtools/jar.mn
+++ b/browser/devtools/jar.mn
@@ -55,18 +55,16 @@ browser.jar:
     content/browser/devtools/debugger.xul                              (debugger/debugger.xul)
     content/browser/devtools/debugger.css                              (debugger/debugger.css)
     content/browser/devtools/debugger-controller.js                    (debugger/debugger-controller.js)
     content/browser/devtools/debugger-view.js                          (debugger/debugger-view.js)
     content/browser/devtools/debugger-toolbar.js                       (debugger/debugger-toolbar.js)
     content/browser/devtools/debugger-panes.js                         (debugger/debugger-panes.js)
     content/browser/devtools/shadereditor.xul                          (shadereditor/shadereditor.xul)
     content/browser/devtools/shadereditor.js                           (shadereditor/shadereditor.js)
-    content/browser/devtools/canvasdebugger.xul                        (canvasdebugger/canvasdebugger.xul)
-    content/browser/devtools/canvasdebugger.js                         (canvasdebugger/canvasdebugger.js)
     content/browser/devtools/profiler.xul                              (profiler/profiler.xul)
     content/browser/devtools/cleopatra.html                            (profiler/cleopatra/cleopatra.html)
     content/browser/devtools/profiler/cleopatra/css/ui.css             (profiler/cleopatra/css/ui.css)
     content/browser/devtools/profiler/cleopatra/css/tree.css           (profiler/cleopatra/css/tree.css)
     content/browser/devtools/profiler/cleopatra/css/devtools.css       (profiler/cleopatra/css/devtools.css)
     content/browser/devtools/profiler/cleopatra/js/strings.js          (profiler/cleopatra/js/strings.js)
     content/browser/devtools/profiler/cleopatra/js/parser.js           (profiler/cleopatra/js/parser.js)
     content/browser/devtools/profiler/cleopatra/js/parserWorker.js     (profiler/cleopatra/js/parserWorker.js)
--- a/browser/devtools/main.js
+++ b/browser/devtools/main.js
@@ -23,38 +23,35 @@ let events = require("sdk/system/events"
 
 // Panels
 loader.lazyGetter(this, "OptionsPanel", () => require("devtools/framework/toolbox-options").OptionsPanel);
 loader.lazyGetter(this, "InspectorPanel", () => require("devtools/inspector/inspector-panel").InspectorPanel);
 loader.lazyGetter(this, "WebConsolePanel", () => require("devtools/webconsole/panel").WebConsolePanel);
 loader.lazyGetter(this, "DebuggerPanel", () => require("devtools/debugger/panel").DebuggerPanel);
 loader.lazyGetter(this, "StyleEditorPanel", () => require("devtools/styleeditor/styleeditor-panel").StyleEditorPanel);
 loader.lazyGetter(this, "ShaderEditorPanel", () => require("devtools/shadereditor/panel").ShaderEditorPanel);
-loader.lazyGetter(this, "CanvasDebuggerPanel", () => require("devtools/canvasdebugger/panel").CanvasDebuggerPanel);
 loader.lazyGetter(this, "ProfilerPanel", () => require("devtools/profiler/panel"));
 loader.lazyGetter(this, "NetMonitorPanel", () => require("devtools/netmonitor/panel").NetMonitorPanel);
 loader.lazyGetter(this, "ScratchpadPanel", () => require("devtools/scratchpad/scratchpad-panel").ScratchpadPanel);
 
 // Strings
 const toolboxProps = "chrome://browser/locale/devtools/toolbox.properties";
 const inspectorProps = "chrome://browser/locale/devtools/inspector.properties";
 const debuggerProps = "chrome://browser/locale/devtools/debugger.properties";
 const styleEditorProps = "chrome://browser/locale/devtools/styleeditor.properties";
 const shaderEditorProps = "chrome://browser/locale/devtools/shadereditor.properties";
-const canvasDebuggerProps = "chrome://browser/locale/devtools/canvasdebugger.properties";
 const webConsoleProps = "chrome://browser/locale/devtools/webconsole.properties";
 const profilerProps = "chrome://browser/locale/devtools/profiler.properties";
 const netMonitorProps = "chrome://browser/locale/devtools/netmonitor.properties";
 const scratchpadProps = "chrome://browser/locale/devtools/scratchpad.properties";
 loader.lazyGetter(this, "toolboxStrings", () => Services.strings.createBundle(toolboxProps));
 loader.lazyGetter(this, "webConsoleStrings", () => Services.strings.createBundle(webConsoleProps));
 loader.lazyGetter(this, "debuggerStrings", () => Services.strings.createBundle(debuggerProps));
 loader.lazyGetter(this, "styleEditorStrings", () => Services.strings.createBundle(styleEditorProps));
 loader.lazyGetter(this, "shaderEditorStrings", () => Services.strings.createBundle(shaderEditorProps));
-loader.lazyGetter(this, "canvasDebuggerStrings", () => Services.strings.createBundle(canvasDebuggerProps));
 loader.lazyGetter(this, "inspectorStrings", () => Services.strings.createBundle(inspectorProps));
 loader.lazyGetter(this, "profilerStrings",() => Services.strings.createBundle(profilerProps));
 loader.lazyGetter(this, "netMonitorStrings", () => Services.strings.createBundle(netMonitorProps));
 loader.lazyGetter(this, "scratchpadStrings", () => Services.strings.createBundle(scratchpadProps));
 
 let Tools = {};
 exports.Tools = Tools;
 
@@ -198,41 +195,21 @@ Tools.shaderEditor = {
   },
 
   build: function(iframeWindow, toolbox) {
     let panel = new ShaderEditorPanel(iframeWindow, toolbox);
     return panel.open();
   }
 };
 
-Tools.canvasDebugger = {
-  id: "canvasdebugger",
-  ordinal: 6,
-  visibilityswitch: "devtools.canvasdebugger.enabled",
-  icon: "chrome://browser/skin/devtools/tool-styleeditor.svg",
-  invertIconForLightTheme: true,
-  url: "chrome://browser/content/devtools/canvasdebugger.xul",
-  label: l10n("ToolboxCanvasDebugger.label", canvasDebuggerStrings),
-  tooltip: l10n("ToolboxCanvasDebugger.tooltip", canvasDebuggerStrings),
-
-  isTargetSupported: function(target) {
-    return true;
-  },
-
-  build: function(iframeWindow, toolbox) {
-    let panel = new CanvasDebuggerPanel(iframeWindow, toolbox);
-    return panel.open();
-  }
-};
-
 Tools.jsprofiler = {
   id: "jsprofiler",
   accesskey: l10n("profiler.accesskey", profilerStrings),
   key: l10n("profiler2.commandkey", profilerStrings),
-  ordinal: 7,
+  ordinal: 6,
   modifiers: "shift",
   visibilityswitch: "devtools.profiler.enabled",
   icon: "chrome://browser/skin/devtools/tool-profiler.svg",
   invertIconForLightTheme: true,
   url: "chrome://browser/content/devtools/profiler.xul",
   label: l10n("profiler.label", profilerStrings),
   tooltip: l10n("profiler.tooltip2", profilerStrings),
   inMenu: true,
@@ -246,17 +223,17 @@ Tools.jsprofiler = {
     return panel.open();
   }
 };
 
 Tools.netMonitor = {
   id: "netmonitor",
   accesskey: l10n("netmonitor.accesskey", netMonitorStrings),
   key: l10n("netmonitor.commandkey", netMonitorStrings),
-  ordinal: 8,
+  ordinal: 7,
   modifiers: osString == "Darwin" ? "accel,alt" : "accel,shift",
   visibilityswitch: "devtools.netmonitor.enabled",
   icon: "chrome://browser/skin/devtools/tool-network.svg",
   invertIconForLightTheme: true,
   url: "chrome://browser/content/devtools/netmonitor.xul",
   label: l10n("netmonitor.label", netMonitorStrings),
   tooltip: l10n("netmonitor.tooltip", netMonitorStrings),
   inMenu: true,
@@ -269,17 +246,17 @@ Tools.netMonitor = {
   build: function(iframeWindow, toolbox) {
     let panel = new NetMonitorPanel(iframeWindow, toolbox);
     return panel.open();
   }
 };
 
 Tools.scratchpad = {
   id: "scratchpad",
-  ordinal: 9,
+  ordinal: 8,
   visibilityswitch: "devtools.scratchpad.enabled",
   icon: "chrome://browser/skin/devtools/tool-scratchpad.svg",
   invertIconForLightTheme: true,
   url: "chrome://browser/content/devtools/scratchpad.xul",
   label: l10n("scratchpad.label", scratchpadStrings),
   tooltip: l10n("scratchpad.tooltip", scratchpadStrings),
   inMenu: false,
 
@@ -295,17 +272,16 @@ Tools.scratchpad = {
 
 let defaultTools = [
   Tools.options,
   Tools.webConsole,
   Tools.inspector,
   Tools.jsdebugger,
   Tools.styleEditor,
   Tools.shaderEditor,
-  Tools.canvasDebugger,
   Tools.jsprofiler,
   Tools.netMonitor,
   Tools.scratchpad
 ];
 
 exports.defaultTools = defaultTools;
 
 for (let definition of defaultTools) {
--- a/browser/devtools/moz.build
+++ b/browser/devtools/moz.build
@@ -1,17 +1,16 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 DIRS += [
     'app-manager',
-    'canvasdebugger',
     'commandline',
     'debugger',
     'fontinspector',
     'framework',
     'inspector',
     'layoutview',
     'markupview',
     'netmonitor',
--- a/browser/devtools/netmonitor/netmonitor-controller.js
+++ b/browser/devtools/netmonitor/netmonitor-controller.js
@@ -112,39 +112,42 @@ const require = Cu.import("resource://gr
 const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
 const EventEmitter = require("devtools/toolkit/event-emitter");
 const Editor = require("devtools/sourceeditor/editor");
 const {Tooltip} = require("devtools/shared/widgets/Tooltip");
 
 XPCOMUtils.defineLazyModuleGetter(this, "Chart",
   "resource:///modules/devtools/Chart.jsm");
 
-XPCOMUtils.defineLazyModuleGetter(this, "Curl",
-  "resource:///modules/devtools/Curl.jsm");
-
 XPCOMUtils.defineLazyModuleGetter(this, "Task",
   "resource://gre/modules/Task.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
   "resource://gre/modules/PluralForm.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "DevToolsUtils",
   "resource://gre/modules/devtools/DevToolsUtils.jsm");
 
-XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
-  "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
+XPCOMUtils.defineLazyModuleGetter(this, "devtools",
+  "resource://gre/modules/devtools/Loader.jsm");
 
 Object.defineProperty(this, "NetworkHelper", {
   get: function() {
-    return require("devtools/toolkit/webconsole/network-helper");
+    return devtools.require("devtools/toolkit/webconsole/network-helper");
   },
   configurable: true,
   enumerable: true
 });
 
+XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
+  "@mozilla.org/widget/clipboardhelper;1", "nsIClipboardHelper");
+
+XPCOMUtils.defineLazyModuleGetter(this, "Curl",
+  "resource:///modules/devtools/Curl.jsm");
+
 /**
  * Object defining the network monitor controller components.
  */
 let NetMonitorController = {
   /**
    * Initializes the view.
    *
    * @return object
--- a/browser/devtools/netmonitor/panel.js
+++ b/browser/devtools/netmonitor/panel.js
@@ -3,17 +3,16 @@
 /* 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 { Cc, Ci, Cu, Cr } = require("chrome");
 const { Promise: promise } = Cu.import("resource://gre/modules/Promise.jsm", {});
 const EventEmitter = require("devtools/toolkit/event-emitter");
-const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
 
 function NetMonitorPanel(iframeWindow, toolbox) {
   this.panelWin = iframeWindow;
   this._toolbox = toolbox;
   this._destroyer = null;
 
   this._view = this.panelWin.NetMonitorView;
   this._controller = this.panelWin.NetMonitorController;
@@ -45,17 +44,18 @@ NetMonitorPanel.prototype = {
       .then(() => this._controller.startupNetMonitor())
       .then(() => this._controller.connect())
       .then(() => {
         this.isReady = true;
         this.emit("ready");
         return this;
       })
       .then(null, function onError(aReason) {
-        DevToolsUtils.reportException("NetMonitorPanel.prototype.open", aReason);
+        Cu.reportError("NetMonitorPanel open failed. " +
+                       aReason.error + ": " + aReason.message);
       });
   },
 
   // DevToolPanel API
 
   get target() this._toolbox.target,
 
   destroy: function() {
--- a/browser/devtools/shadereditor/moz.build
+++ b/browser/devtools/shadereditor/moz.build
@@ -5,8 +5,9 @@
 
 TEST_DIRS += ['test']
 
 JS_MODULES_PATH = 'modules/devtools/shadereditor'
 
 EXTRA_JS_MODULES += [
     'panel.js'
 ]
+
--- a/browser/devtools/shadereditor/panel.js
+++ b/browser/devtools/shadereditor/panel.js
@@ -4,35 +4,28 @@
  * 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 { Cc, Ci, Cu, Cr } = require("chrome");
 const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
 const EventEmitter = require("devtools/toolkit/event-emitter");
 const { WebGLFront } = require("devtools/server/actors/webgl");
-const { DevToolsUtils } = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {});
 
 function ShaderEditorPanel(iframeWindow, toolbox) {
   this.panelWin = iframeWindow;
   this._toolbox = toolbox;
   this._destroyer = null;
 
   EventEmitter.decorate(this);
 };
 
 exports.ShaderEditorPanel = ShaderEditorPanel;
 
 ShaderEditorPanel.prototype = {
-  /**
-   * Open is effectively an asynchronous constructor.
-   *
-   * @return object
-   *         A promise that is resolved when the Shader Editor completes opening.
-   */
   open: function() {
     let targetPromise;
 
     // Local debugging needs to make the target remote.
     if (!this.target.isRemote) {
       targetPromise = this.target.makeRemote();
     } else {
       targetPromise = promise.resolve(this.target);
@@ -46,17 +39,18 @@ ShaderEditorPanel.prototype = {
         return this.panelWin.startupShaderEditor();
       })
       .then(() => {
         this.isReady = true;
         this.emit("ready");
         return this;
       })
       .then(null, function onError(aReason) {
-        DevToolsUtils.reportException("ShaderEditorPanel.prototype.open", aReason);
+        Cu.reportError("ShaderEditorPanel open failed. " +
+                       aReason.error + ": " + aReason.message);
       });
   },
 
   // DevToolPanel API
 
   get target() this._toolbox.target,
 
   destroy: function() {
--- a/browser/devtools/shadereditor/shadereditor.js
+++ b/browser/devtools/shadereditor/shadereditor.js
@@ -3,16 +3,17 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 "use strict";
 
 const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Task.jsm");
+Cu.import("resource://gre/modules/devtools/Loader.jsm");
 Cu.import("resource:///modules/devtools/SideMenuWidget.jsm");
 Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
 
 const require = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools.require;
 const promise = Cu.import("resource://gre/modules/Promise.jsm", {}).Promise;
 const EventEmitter = require("devtools/toolkit/event-emitter");
 const {Tooltip} = require("devtools/shared/widgets/Tooltip");
 const Editor = require("devtools/sourceeditor/editor");
--- a/browser/devtools/shared/widgets/ViewHelpers.jsm
+++ b/browser/devtools/shared/widgets/ViewHelpers.jsm
@@ -15,18 +15,17 @@ const WIDGET_FOCUSABLE_NODES = new Set([
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
 
 this.EXPORTED_SYMBOLS = [
   "Heritage", "ViewHelpers", "WidgetMethods",
-  "setNamedTimeout", "clearNamedTimeout",
-  "setConditionalTimeout", "clearConditionalTimeout",
+  "setNamedTimeout", "clearNamedTimeout"
 ];
 
 /**
  * Inheritance helpers from the addon SDK's core/heritage.
  * Remove these when all devtools are loadered.
  */
 this.Heritage = {
   /**
@@ -53,73 +52,38 @@ this.Heritage = {
  *
  * @param string aId
  *        A string identifier for the named timeout.
  * @param number aWait
  *        The amount of milliseconds to wait after no more events are fired.
  * @param function aCallback
  *        Invoked when no more events are fired after the specified time.
  */
-this.setNamedTimeout = function setNamedTimeout(aId, aWait, aCallback) {
+this.setNamedTimeout = function(aId, aWait, aCallback) {
   clearNamedTimeout(aId);
 
   namedTimeoutsStore.set(aId, setTimeout(() =>
     namedTimeoutsStore.delete(aId) && aCallback(), aWait));
 };
 
 /**
  * Clears a named timeout.
  * @see setNamedTimeout
  *
  * @param string aId
  *        A string identifier for the named timeout.
  */
-this.clearNamedTimeout = function clearNamedTimeout(aId) {
+this.clearNamedTimeout = function(aId) {
   if (!namedTimeoutsStore) {
     return;
   }
   clearTimeout(namedTimeoutsStore.get(aId));
   namedTimeoutsStore.delete(aId);
 };
 
-/**
- * Same as `setNamedTimeout`, but invokes the callback only if the provided
- * predicate function returns true. Otherwise, the timeout is re-triggered.
- *
- * @param string aId
- *        A string identifier for the conditional timeout.
- * @param number aWait
- *        The amount of milliseconds to wait after no more events are fired.
- * @param function aPredicate
- *        The predicate function used to determine whether the timeout restarts.
- * @param function aCallback
- *        Invoked when no more events are fired after the specified time, and
- *        the provided predicate function returns true.
- */
-this.setConditionalTimeout = function setConditionalTimeout(aId, aWait, aPredicate, aCallback) {
-  setNamedTimeout(aId, aWait, function maybeCallback() {
-    if (aPredicate()) {
-      aCallback();
-      return;
-    }
-    setConditionalTimeout(aId, aWait, aPredicate, aCallback);
-  });
-};
-
-/**
- * Clears a conditional timeout.
- * @see setConditionalTimeout
- *
- * @param string aId
- *        A string identifier for the conditional timeout.
- */
-this.clearConditionalTimeout = function clearConditionalTimeout(aId) {
-  clearNamedTimeout(aId);
-};
-
 XPCOMUtils.defineLazyGetter(this, "namedTimeoutsStore", () => new Map());
 
 /**
  * Helpers for creating and messaging between UI components.
  */
 this.ViewHelpers = {
   /**
    * Convenience method, dispatching a custom event.
deleted file mode 100644
--- a/browser/locales/en-US/chrome/browser/devtools/canvasdebugger.dtd
+++ /dev/null
@@ -1,45 +0,0 @@
-<!-- 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/. -->
-
-<!-- LOCALIZATION NOTE : FILE This file contains the Debugger strings -->
-<!-- LOCALIZATION NOTE : FILE Do not translate commandkey -->
-
-<!-- LOCALIZATION NOTE : FILE The correct localization of this file might be to
-  - keep it in English, or another language commonly spoken among web developers.
-  - You want to make that choice consistent across the developer tools.
-  - A good criteria is the language in which you'd find the best
-  - documentation on web development on the web. -->
-
-<!-- LOCALIZATION NOTE (canvasDebuggerUI.reloadNotice1): This is the label shown
-  -  on the button that triggers a page refresh. -->
-<!ENTITY canvasDebuggerUI.reloadNotice1   "Reload">
-
-<!-- LOCALIZATION NOTE (canvasDebuggerUI.reloadNotice2): This is the label shown
-  -  along with the button that triggers a page refresh. -->
-<!ENTITY canvasDebuggerUI.reloadNotice2   "the page to be able to debug &lt;canvas&gt; contexts.">
-
-<!-- LOCALIZATION NOTE (canvasDebuggerUI.emptyNotice1/2): This is the label shown
-  -  in the call list view when empty. -->
-<!ENTITY canvasDebuggerUI.emptyNotice1    "Click on the">
-<!ENTITY canvasDebuggerUI.emptyNotice2    "button to record an animation frame's call stack.">
-
-<!-- LOCALIZATION NOTE (canvasDebuggerUI.reloadNotice1): This is the label shown
-  -  in the call list view while loading a snapshot. -->
-<!ENTITY canvasDebuggerUI.importNotice    "Loading…">
-
-<!-- LOCALIZATION NOTE (canvasDebuggerUI.recordSnapshot): This string is displayed
-  -  on a button that starts a new snapshot. -->
-<!ENTITY canvasDebuggerUI.recordSnapshot.tooltip "Record the next frame in the animation loop.">
-
-<!-- LOCALIZATION NOTE (canvasDebuggerUI.importSnapshot): This string is displayed
-  -  on a button that opens a dialog to import a saved snapshot data file. -->
-<!ENTITY canvasDebuggerUI.importSnapshot "Import…">
-
-<!-- LOCALIZATION NOTE (canvasDebuggerUI.clearSnapshots): This string is displayed
-  -  on a button that remvoes all the snapshots. -->
-<!ENTITY canvasDebuggerUI.clearSnapshots "Clear">
-
-<!-- LOCALIZATION NOTE (canvasDebuggerUI.searchboxPlaceholder): This string is displayed
-  -  as a placeholder of the search box that filters the calls list. -->
-<!ENTITY canvasDebuggerUI.searchboxPlaceholder "Filter calls">
deleted file mode 100644
--- a/browser/locales/en-US/chrome/browser/devtools/canvasdebugger.properties
+++ /dev/null
@@ -1,74 +0,0 @@
-# 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/.
-
-# LOCALIZATION NOTE These strings are used inside the Canvas Debugger
-# which is available from the Web Developer sub-menu -> 'Canvas'.
-# The correct localization of this file might be to keep it in
-# English, or another language commonly spoken among web developers.
-# You want to make that choice consistent across the developer tools.
-# A good criteria is the language in which you'd find the best
-# documentation on web development on the web.
-
-# LOCALIZATION NOTE (ToolboxCanvasDebugger.label):
-# This string is displayed in the title of the tab when the Shader Editor is
-# displayed inside the developer tools window and in the Developer Tools Menu.
-ToolboxCanvasDebugger.label=Canvas
-
-# LOCALIZATION NOTE (ToolboxCanvasDebugger.tooltip):
-# This string is displayed in the tooltip of the tab when the Shader Editor is
-# displayed inside the developer tools window.
-ToolboxCanvasDebugger.tooltip=Tools to inspect and debug <canvas> contexts
-
-# LOCALIZATION NOTE (noSnapshotsText): The text to display in the snapshots menu
-# when there are no recorded snapshots yet.
-noSnapshotsText=There are no snapshots yet.
-
-# LOCALIZATION NOTE (snapshotsList.itemLabel):
-# This string is displayed in the snapshots list of the Canvas Debugger,
-# identifying a set of function calls of a recorded animation frame.
-snapshotsList.itemLabel=Snapshot #%S
-
-# LOCALIZATION NOTE (snapshotsList.loadingLabel):
-# This string is displayed in the snapshots list of the Canvas Debugger,
-# for an item that has not finished loading.
-snapshotsList.loadingLabel=Loading…
-
-# LOCALIZATION NOTE (snapshotsList.saveLabel):
-# This string is displayed in the snapshots list of the Canvas Debugger,
-# for saving an item to disk.
-snapshotsList.saveLabel=Save
-
-# LOCALIZATION NOTE (snapshotsList.savingLabel):
-# This string is displayed in the snapshots list of the Canvas Debugger,
-# while saving an item to disk.
-snapshotsList.savingLabel=Saving…
-
-# LOCALIZATION NOTE (snapshotsList.loadedLabel):
-# This string is displayed in the snapshots list of the Canvas Debugger,
-# for an item which was loaded from disk
-snapshotsList.loadedLabel=Loaded from disk
-
-# LOCALIZATION NOTE (snapshotsList.saveDialogTitle):
-# This string is displayed as a title for saving a snapshot to disk.
-snapshotsList.saveDialogTitle=Save animation frame snapshot…
-
-# LOCALIZATION NOTE (snapshotsList.saveDialogJSONFilter):
-# This string is displayed as a filter for saving a snapshot to disk.
-snapshotsList.saveDialogJSONFilter=JSON Files
-
-# LOCALIZATION NOTE (snapshotsList.saveDialogAllFilter):
-# This string is displayed as a filter for saving a snapshot to disk.
-snapshotsList.saveDialogAllFilter=All Files
-
-# LOCALIZATION NOTE (snapshotsList.drawCallsLabel):
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# This string is displayed in the snapshots list of the Canvas Debugger,
-# as a generic description about how many draw calls were made.
-snapshotsList.drawCallsLabel=#1 draw;#1 draws
-
-# LOCALIZATION NOTE (snapshotsList.functionCallsLabel):
-# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
-# This string is displayed in the snapshots list of the Canvas Debugger,
-# as a generic description about how many function calls were made in total.
-snapshotsList.functionCallsLabel=#1 call;#1 calls
--- a/browser/locales/jar.mn
+++ b/browser/locales/jar.mn
@@ -27,18 +27,16 @@
     locale/browser/customizableui/customizableWidgets.properties (%chrome/browser/customizableui/customizableWidgets.properties)
     locale/browser/devtools/appcacheutils.properties  (%chrome/browser/devtools/appcacheutils.properties)
     locale/browser/devtools/debugger.dtd              (%chrome/browser/devtools/debugger.dtd)
     locale/browser/devtools/debugger.properties       (%chrome/browser/devtools/debugger.properties)
     locale/browser/devtools/netmonitor.dtd            (%chrome/browser/devtools/netmonitor.dtd)
     locale/browser/devtools/netmonitor.properties     (%chrome/browser/devtools/netmonitor.properties)
     locale/browser/devtools/shadereditor.dtd          (%chrome/browser/devtools/shadereditor.dtd)
     locale/browser/devtools/shadereditor.properties   (%chrome/browser/devtools/shadereditor.properties)
-    locale/browser/devtools/canvasdebugger.dtd        (%chrome/browser/devtools/canvasdebugger.dtd)
-    locale/browser/devtools/canvasdebugger.properties (%chrome/browser/devtools/canvasdebugger.properties)
     locale/browser/devtools/gcli.properties           (%chrome/browser/devtools/gcli.properties)
     locale/browser/devtools/gclicommands.properties   (%chrome/browser/devtools/gclicommands.properties)
     locale/browser/devtools/webconsole.properties     (%chrome/browser/devtools/webconsole.properties)
     locale/browser/devtools/inspector.properties      (%chrome/browser/devtools/inspector.properties)
     locale/browser/devtools/tilt.properties           (%chrome/browser/devtools/tilt.properties)
     locale/browser/devtools/scratchpad.properties     (%chrome/browser/devtools/scratchpad.properties)
     locale/browser/devtools/scratchpad.dtd            (%chrome/browser/devtools/scratchpad.dtd)
     locale/browser/devtools/styleeditor.properties    (%chrome/browser/devtools/styleeditor.properties)
deleted file mode 100644
--- a/browser/themes/linux/devtools/canvasdebugger.css
+++ /dev/null
@@ -1,5 +0,0 @@
-/* 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/. */
-
-%include ../../shared/devtools/canvasdebugger.inc.css
--- a/browser/themes/linux/jar.mn
+++ b/browser/themes/linux/jar.mn
@@ -204,17 +204,16 @@ browser.jar:
   skin/classic/browser/devtools/editor-breakpoint.png  (devtools/editor-breakpoint.png)
   skin/classic/browser/devtools/editor-debug-location.png (devtools/editor-debug-location.png)
   skin/classic/browser/devtools/breadcrumbs-divider@2x.png      (../shared/devtools/images/breadcrumbs-divider@2x.png)
   skin/classic/browser/devtools/breadcrumbs-scrollbutton.png    (../shared/devtools/images/breadcrumbs-scrollbutton.png)
   skin/classic/browser/devtools/breadcrumbs-scrollbutton@2x.png (../shared/devtools/images/breadcrumbs-scrollbutton@2x.png)
 * skin/classic/browser/devtools/splitview.css         (../shared/devtools/splitview.css)
   skin/classic/browser/devtools/styleeditor.css       (../shared/devtools/styleeditor.css)
 * skin/classic/browser/devtools/shadereditor.css      (devtools/shadereditor.css)
-* skin/classic/browser/devtools/canvasdebugger.css    (devtools/canvasdebugger.css)
 * skin/classic/browser/devtools/debugger.css          (devtools/debugger.css)
 * skin/classic/browser/devtools/profiler.css          (devtools/profiler.css)
 * skin/classic/browser/devtools/netmonitor.css        (devtools/netmonitor.css)
 * skin/classic/browser/devtools/scratchpad.css        (devtools/scratchpad.css)
   skin/classic/browser/devtools/magnifying-glass.png        (../shared/devtools/images/magnifying-glass.png)
   skin/classic/browser/devtools/magnifying-glass@2x.png     (../shared/devtools/images/magnifying-glass@2x.png)
   skin/classic/browser/devtools/magnifying-glass-light.png  (../shared/devtools/images/magnifying-glass-light.png)
   skin/classic/browser/devtools/magnifying-glass-light@2x.png (../shared/devtools/images/magnifying-glass-light@2x.png)
deleted file mode 100644
--- a/browser/themes/osx/devtools/canvasdebugger.css
+++ /dev/null
@@ -1,6 +0,0 @@
-/* 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/. */
-
-%include ../shared.inc
-%include ../../shared/devtools/canvasdebugger.inc.css
--- a/browser/themes/osx/jar.mn
+++ b/browser/themes/osx/jar.mn
@@ -325,17 +325,16 @@ browser.jar:
   skin/classic/browser/devtools/webconsole_networkpanel.css     (devtools/webconsole_networkpanel.css)
   skin/classic/browser/devtools/webconsole.png                  (devtools/webconsole.png)
   skin/classic/browser/devtools/breadcrumbs-divider@2x.png      (../shared/devtools/images/breadcrumbs-divider@2x.png)
   skin/classic/browser/devtools/breadcrumbs-scrollbutton.png    (../shared/devtools/images/breadcrumbs-scrollbutton.png)
   skin/classic/browser/devtools/breadcrumbs-scrollbutton@2x.png (../shared/devtools/images/breadcrumbs-scrollbutton@2x.png)
 * skin/classic/browser/devtools/splitview.css               (../shared/devtools/splitview.css)
   skin/classic/browser/devtools/styleeditor.css             (../shared/devtools/styleeditor.css)
 * skin/classic/browser/devtools/shadereditor.css            (devtools/shadereditor.css)
-* skin/classic/browser/devtools/canvasdebugger.css          (devtools/canvasdebugger.css)
 * skin/classic/browser/devtools/debugger.css                (devtools/debugger.css)
 * skin/classic/browser/devtools/profiler.css                (devtools/profiler.css)
 * skin/classic/browser/devtools/netmonitor.css              (devtools/netmonitor.css)
 * skin/classic/browser/devtools/scratchpad.css              (devtools/scratchpad.css)
   skin/classic/browser/devtools/magnifying-glass.png        (../shared/devtools/images/magnifying-glass.png)
   skin/classic/browser/devtools/magnifying-glass@2x.png     (../shared/devtools/images/magnifying-glass@2x.png)
   skin/classic/browser/devtools/magnifying-glass-light.png  (../shared/devtools/images/magnifying-glass-light.png)
   skin/classic/browser/devtools/magnifying-glass-light@2x.png (../shared/devtools/images/magnifying-glass-light@2x.png)
deleted file mode 100644
--- a/browser/themes/shared/devtools/canvasdebugger.inc.css
+++ /dev/null
@@ -1,501 +0,0 @@
-/* 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/. */
-
-%filter substitution
-%define darkCheckerboardBackground #000
-%define lightCheckerboardBackground #fff
-%define checkerboardCell rgba(128,128,128,0.2)
-%define checkerboardPattern linear-gradient(45deg, @checkerboardCell@ 25%, transparent 25%, transparent 75%, @checkerboardCell@ 75%, @checkerboardCell@), linear-gradient(45deg, @checkerboardCell@ 25%, transparent 25%, transparent 75%, @checkerboardCell@ 75%, @checkerboardCell@)
-%define gutterWidth 3em
-%define gutterPaddingStart 22px
-
-/* Reload and waiting notices */
-
-.notice-container {
-  margin-top: -50vh;
-  font-size: 120%;
-}
-
-.theme-dark .notice-container {
-  background: url(background-noise-toolbar.png), #343c45; /* Toolbars */
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light .notice-container {
-  background: url(background-noise-toolbar.png), #f0f1f2; /* Toolbars */
-  color: #585959; /* Grey foreground text */
-}
-
-#reload-notice > button {
-  min-height: 2em;
-}
-
-#empty-notice > button {
-  min-width: 30px;
-  min-height: 28px;
-  margin: 0;
-  list-style-image: url(profiler-stopwatch.png);
-  -moz-image-region: rect(0px,16px,16px,0px);
-}
-
-#empty-notice > button .button-text {
-  display: none;
-}
-
-.theme-dark #import-notice {
-  font-size: 250%;
-  color: rgba(255,255,255,0.2);
-}
-
-.theme-light #import-notice {
-  font-size: 250%;
-  color: rgba(0,0,0,0.2);
-}
-
-/* Snapshots pane */
-
-#snapshots-pane > tabs {
-  -moz-border-end: 1px solid;
-}
-
-#snapshots-pane .devtools-toolbar {
-  -moz-border-end: 1px solid;
-}
-
-.theme-dark #snapshots-pane > tabs,
-.theme-dark #snapshots-pane .devtools-toolbar {
-  -moz-border-end-color: black; /* Match the splitter color. */
-}
-
-.theme-light #snapshots-pane > tabs,
-.theme-light #snapshots-pane .devtools-toolbar {
-  -moz-border-end-color: #aaa; /* Match the splitter color. */
-}
-
-#record-snapshot {
-  list-style-image: url("chrome://browser/skin/devtools/profiler-stopwatch.png");
-  -moz-image-region: rect(0px,16px,16px,0px);
-}
-
-#record-snapshot[checked] {
-  -moz-image-region: rect(0px,32px,16px,16px);
-}
-
-/* Snapshots items */
-
-.snapshot-item-thumbnail {
-  image-rendering: -moz-crisp-edges;
-  background-image: @checkerboardPattern@;
-  background-size: 12px 12px, 12px 12px;
-  background-position: 0px 0px, 6px 6px;
-  background-repeat: repeat, repeat;
-}
-
-.snapshot-item-thumbnail[flipped=true] {
-  transform: scaleY(-1);
-}
-
-.theme-dark .snapshot-item-thumbnail {
-  background-color: @darkCheckerboardBackground@;
-}
-
-.theme-light .snapshot-item-thumbnail {
-  background-color: @lightCheckerboardBackground@;
-}
-
-.snapshot-item-details {
-  -moz-padding-start: 6px;
-}
-
-.snapshot-item-calls {
-  padding-top: 4px;
-  font-size: 80%;
-}
-
-.snapshot-item-save {
-  padding-bottom: 2px;
-  font-size: 90%;
-}
-
-.theme-dark .snapshot-item-calls,
-.theme-dark .snapshot-item-save {
-  color: #b6babf; /* Foreground (Text) - Grey */
-}
-
-.theme-light .snapshot-item-calls,
-.theme-light .snapshot-item-save {
-  color: #585959; /* Foreground (Text) - Grey */
-}
-
-.snapshot-item-save {
-  text-decoration: underline;
-  cursor: pointer;
-}
-
-.snapshot-item-save[disabled=true] {
-  text-decoration: none;
-  pointer-events: none;
-}
-
-.snapshot-item-footer[saving]::before {
-  display: inline-block;
-  content: "";
-  background: url("chrome://global/skin/icons/loading_16.png") center no-repeat;
-  width: 16px;
-  height: 16px;
-  margin-top: -2px;
-  -moz-margin-end: 4px;
-}
-
-#snapshots-list .selected label {
-  /* Text inside a selected item should not be custom colored. */
-  color: inherit !important;
-}
-
-/* Debugging pane controls */
-
-#resume {
-  list-style-image: url(debugger-play.png);
-  -moz-image-region: rect(0px,32px,16px,16px);
-}
-
-#step-over {
-  list-style-image: url(debugger-step-over.png);
-}
-
-#step-in {
-  list-style-image: url(debugger-step-in.png);
-}
-
-#step-out {
-  list-style-image: url(debugger-step-out.png);
-}
-
-#debugging-controls > toolbarbutton {
-  transition: opacity 0.15s ease-in-out;
-}
-
-#debugging-controls > toolbarbutton[disabled=true] {
-  opacity: 0.5;
-}
-
-#calls-slider {
-  -moz-padding-end: 24px;
-}
-
-#calls-slider .scale-slider {
-  margin: 0;
-}
-
-#debugging-toolbar-sizer-button {
-  /* This button's only purpose in life is to make the
-     container .devtools-toolbar have the right height. */
-  visibility: hidden;
-  min-width: 1px;
-}
-
-/* Calls list pane */
-
-#calls-list .side-menu-widget-container {
-  background: transparent;
-}
-
-#calls-list .side-menu-widget-item {
-  padding: 0;
-}
-
-/* Calls list items */
-
-.theme-dark #calls-list .side-menu-widget-item {
-  border-color: #111;
-  border-bottom-color: transparent;
-}
-
-.theme-light #calls-list .side-menu-widget-item {
-  border-color: #eee;
-  border-bottom-color: transparent;
-}
-
-.theme-dark .call-item-view:hover {
-  background-color: rgba(255,255,255,.025);
-}
-
-.theme-light .call-item-view:hover {
-  background-color: rgba(0,0,0,.025);
-}
-
-.theme-dark .call-item-view[draw-call] {
-  background-color: rgba(112,191,83,0.15);
-}
-
-.theme-light .call-item-view[draw-call] {
-  background-color: rgba(44,187,15,0.1);
-}
-
-.theme-dark .call-item-view[interesting-call] {
-  background-color: rgba(223,128,255,0.15);
-}
-
-.theme-light .call-item-view[interesting-call] {
-  background-color: rgba(184,46,229,0.1);
-}
-
-.call-item-gutter {
-  width: calc(@gutterWidth@ + @gutterPaddingStart@);
-  -moz-padding-start: @gutterPaddingStart@;
-  -moz-padding-end: 4px;
-  padding-top: 2px;
-  padding-bottom: 2px;
-  -moz-border-end: 1px solid;
-  -moz-margin-end: 6px;
-}
-
-.selected .call-item-gutter {
-  background-image: url("editor-debug-location.png");
-  background-repeat: no-repeat;
-  background-position: 6px center;
-  background-size: 12px;
-}
-
-.theme-dark .call-item-gutter {
-  background-color: #181d20;
-  color: #5f7387;
-  border-color: #000;
-}
-
-.theme-light .call-item-gutter {
-  background-color: #f7f7f7;
-  color: #667380;
-  border-color: #aaa;
-}
-
-.call-item-index {
-  text-align: end;
-}
-
-.theme-dark .call-item-context {
-  color: #eb5368; /* Highlight Orange */
-}
-
-.theme-light .call-item-context {
-  color: #f13c00; /* Highlight Orange */
-}
-
-.theme-dark .call-item-name {
-  color: #46afe3; /* Highlight Blue */
-}
-
-.theme-light .call-item-name {
-  color: #0088cc; /* Highlight Blue */
-}
-
-.call-item-location {
-  -moz-padding-start: 2px;
-  -moz-padding-end: 6px;
-  text-align: end;
-  cursor: pointer;
-}
-
-.theme-dark .call-item-location:hover {
-  color: #0088cc; /* Highlight Blue */
-}
-
-.theme-light .call-item-location:hover {
-  color: #46afe3; /* Highlight Blue */
-}
-
-.call-item-view:hover .call-item-location,
-.call-item-view[expanded] .call-item-location {
-  text-decoration: underline;
-}
-
-.theme-dark .call-item-location {
-  border-color: #111;
-  color: #5e88b0; /* Highlight Blue-Grey */
-}
-
-.theme-light .call-item-location {
-  border-color: #eee;
-  color: #5f88b0; /* Highlight Blue-Grey */
-}
-
-.call-item-stack {
-  -moz-padding-start: calc(@gutterWidth@ + @gutterPaddingStart@);
-  padding-bottom: 10px;
-}
-
-.theme-dark .call-item-stack {
-  background: rgba(0,0,0,0.9);
-}
-
-.theme-light .call-item-stack {
-  background: rgba(255,255,255,0.9);
-}
-
-.call-item-stack-fn {
-  padding-top: 2px;
-  padding-bottom: 2px;
-}
-
-.call-item-stack-fn-location {
-  -moz-padding-start: 2px;
-  -moz-padding-end: 6px;
-  text-align: end;
-  cursor: pointer;
-  text-decoration: underline;
-}
-
-.theme-dark .call-item-stack-fn-name {
-  color: #a9bacb; /* Content (Text) - Light */
-}
-
-.theme-light .call-item-stack-fn-name {
-  color: #667380; /* Content (Text) - Dark Grey */
-}
-
-.theme-dark .call-item-stack-fn-location {
-  color: #5e88b0; /* Highlight Blue-Grey */
-}
-
-.theme-light .call-item-stack-fn-location {
-  color: #5e88b0; /* Highlight Blue-Grey */
-}
-
-.theme-dark .call-item-stack-fn-location:hover {
-  color: #0088cc; /* Highlight Blue */
-}
-
-.theme-light .call-item-stack-fn-location:hover {
-  color: #46afe3; /* Highlight Blue */
-}
-
-#calls-list .selected .call-item-contents > label:not(.call-item-gutter) {
-  /* Text inside a selected item should not be custom colored. */
-  color: inherit !important;
-}
-
-/* Rendering preview */
-
-#screenshot-container {
-  background-image: @checkerboardPattern@;
-  background-size: 30px 30px, 30px 30px;
-  background-position: 0px 0px, 15px 15px;
-  background-repeat: repeat, repeat;
-}
-
-.theme-dark #screenshot-container {
-  background-color: @darkCheckerboardBackground@;
-}
-
-.theme-light #screenshot-container {
-  background-color: @lightCheckerboardBackground@;
-}
-
-@media (min-width: 701px) {
-  #screenshot-container {
-    width: 30vw;
-    max-width: 50vw;
-    min-width: 100px;
-  }
-}
-
-@media (max-width: 700px) {
-  #screenshot-container {
-    height: 40vh;
-    max-height: 70vh;
-    min-height: 100px;
-  }
-}
-
-#screenshot-image {
-  background-image: -moz-element(#screenshot-rendering);
-  background-size: contain;
-  background-position: center, center;
-  background-repeat: no-repeat;
-}
-
-#screenshot-image[flipped=true] {
-  transform: scaleY(-1);
-}
-
-#screenshot-dimensions {
-  padding-top: 4px;
-  padding-bottom: 4px;
-  text-align: center;
-}
-
-.theme-dark #screenshot-dimensions {
-  background-color: rgba(0,0,0,0.4);
-}
-
-.theme-light #screenshot-dimensions {
-  background-color: rgba(255,255,255,0.8);
-}
-
-/* Snapshot filmstrip */
-
-#snapshot-filmstrip {
-  overflow: hidden;
-}
-
-.theme-dark #snapshot-filmstrip {
-  border-top: 1px solid #000;
-  background-image: url(background-noise-toolbar.png);
-  color: #f5f7fa; /* Light foreground text */
-}
-
-.theme-light #snapshot-filmstrip {
-  border-top: 1px solid #aaa;
-  background-image: url(background-noise-toolbar.png);
-  color: #585959; /* Grey foreground text */
-}
-
-.filmstrip-thumbnail {
-  image-rendering: -moz-crisp-edges;
-  background-image: @checkerboardPattern@;
-  background-size: 12px 12px, 12px 12px;
-  background-position: 0px -1px, 6px 5px;
-  background-repeat: repeat, repeat;
-  background-origin: content-box;
-  cursor: pointer;
-  padding-top: 1px;
-  padding-bottom: 1px;
-  transition: opacity 0.1s ease-in-out;
-}
-
-.filmstrip-thumbnail[flipped=true] {
-  transform: scaleY(-1);
-}
-
-.theme-dark .filmstrip-thumbnail {
-  background-color: @darkCheckerboardBackground@;
-}
-
-.theme-light .filmstrip-thumbnail {
-  background-color: @lightCheckerboardBackground@;
-}
-
-.theme-dark .filmstrip-thumbnail {
-  -moz-border-end: 1px solid #000;
-}
-
-.theme-light .filmstrip-thumbnail {
-  -moz-border-end: 1px solid #aaa;
-}
-
-.theme-dark #snapshot-filmstrip > .filmstrip-thumbnail:hover,
-.theme-dark #snapshot-filmstrip:not(:hover) > .filmstrip-thumbnail[highlighted] {
-  border: 1px solid #46afe3; /* Highlight Blue */
-  margin: 0 0 0 -1px;
-  padding: 0;
-  opacity: 0.66;
-}
-
-.theme-light #snapshot-filmstrip > .filmstrip-thumbnail:hover,
-.theme-light #snapshot-filmstrip:not(:hover) > .filmstrip-thumbnail[highlighted] {
-  border: 1px solid #0088cc; /* Highlight Blue */
-  margin: 0 0 0 -1px;
-  padding: 0;
-  opacity: 0.66;
-}
--- a/browser/themes/shared/devtools/toolbars.inc.css
+++ b/browser/themes/shared/devtools/toolbars.inc.css
@@ -769,17 +769,16 @@
 .theme-light .command-button-invertable:active > image,
 .theme-light .devtools-closebutton > image,
 .theme-light .devtools-toolbarbutton > image,
 .theme-light .devtools-option-toolbarbutton > image,
 .theme-light #breadcrumb-separator-normal,
 .theme-light .scrollbutton-up > .toolbarbutton-icon,
 .theme-light .scrollbutton-down > .toolbarbutton-icon,
 .theme-light #black-boxed-message-button .button-icon,
-.theme-light #canvas-debugging-empty-notice-button .button-icon,
 .theme-light #requests-menu-perf-notice-button .button-icon,
 .theme-light #requests-menu-network-summary-button .button-icon {
   filter: url(filters.svg#invert);
 }
 
 /* Since selected backgrounds are blue, we want to use the normal
  * (light) icons. */
 .theme-light .command-button-invertable[checked=true]:not(:active) > image,
--- a/browser/themes/shared/devtools/widgets.inc.css
+++ b/browser/themes/shared/devtools/widgets.inc.css
@@ -559,22 +559,20 @@
 
 /* SideMenuWidget misc */
 
 .side-menu-widget-empty-text {
   padding: 4px 8px;
 }
 
 .theme-dark .side-menu-widget-empty-text {
-  background: url(background-noise-toolbar.png), #343c45; /* Toolbars */
   color: #b6babf; /* Foreground (Text) - Grey */
 }
 
 .theme-light .side-menu-widget-empty-text {
-  background: #f7f7f7; /* Toolbars */
   color: #585959; /* Grey foreground text */
 }
 
 /* VariablesView */
 
 .variables-view-container {
   /* Hack: force hardware acceleration */
   transform: translateZ(1px);
deleted file mode 100644
--- a/browser/themes/windows/devtools/canvasdebugger.css
+++ /dev/null
@@ -1,5 +0,0 @@
-/* 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/. */
-
-%include ../../shared/devtools/canvasdebugger.inc.css
--- a/browser/themes/windows/jar.mn
+++ b/browser/themes/windows/jar.mn
@@ -237,17 +237,16 @@ browser.jar:
         skin/classic/browser/devtools/webconsole_networkpanel.css   (devtools/webconsole_networkpanel.css)
         skin/classic/browser/devtools/webconsole.png                (devtools/webconsole.png)
         skin/classic/browser/devtools/breadcrumbs-divider@2x.png    (../shared/devtools/images/breadcrumbs-divider@2x.png)
         skin/classic/browser/devtools/breadcrumbs-scrollbutton.png  (../shared/devtools/images/breadcrumbs-scrollbutton.png)
         skin/classic/browser/devtools/breadcrumbs-scrollbutton@2x.png (../shared/devtools/images/breadcrumbs-scrollbutton@2x.png)
 *       skin/classic/browser/devtools/splitview.css                 (../shared/devtools/splitview.css)
         skin/classic/browser/devtools/styleeditor.css               (../shared/devtools/styleeditor.css)
 *       skin/classic/browser/devtools/shadereditor.css              (devtools/shadereditor.css)
-*       skin/classic/browser/devtools/canvasdebugger.css            (devtools/canvasdebugger.css)
 *       skin/classic/browser/devtools/debugger.css                  (devtools/debugger.css)
 *       skin/classic/browser/devtools/profiler.css                  (devtools/profiler.css)
 *       skin/classic/browser/devtools/netmonitor.css                (devtools/netmonitor.css)
 *       skin/classic/browser/devtools/scratchpad.css                (devtools/scratchpad.css)
         skin/classic/browser/devtools/magnifying-glass.png          (../shared/devtools/images/magnifying-glass.png)
         skin/classic/browser/devtools/magnifying-glass@2x.png       (../shared/devtools/images/magnifying-glass@2x.png)
         skin/classic/browser/devtools/magnifying-glass-light.png    (../shared/devtools/images/magnifying-glass-light.png)
         skin/classic/browser/devtools/magnifying-glass-light@2x.png  (../shared/devtools/images/magnifying-glass-light@2x.png)
@@ -585,17 +584,16 @@ browser.jar:
         skin/classic/aero/browser/devtools/webconsole_networkpanel.css     (devtools/webconsole_networkpanel.css)
         skin/classic/aero/browser/devtools/webconsole.png                  (devtools/webconsole.png)
         skin/classic/aero/browser/devtools/breadcrumbs-divider@2x.png      (../shared/devtools/images/breadcrumbs-divider@2x.png)
         skin/classic/aero/browser/devtools/breadcrumbs-scrollbutton.png    (../shared/devtools/images/breadcrumbs-scrollbutton.png)
         skin/classic/aero/browser/devtools/breadcrumbs-scrollbutton@2x.png (../shared/devtools/images/breadcrumbs-scrollbutton@2x.png)
 *       skin/classic/aero/browser/devtools/splitview.css             (../shared/devtools/splitview.css)
         skin/classic/aero/browser/devtools/styleeditor.css           (../shared/devtools/styleeditor.css)
 *       skin/classic/aero/browser/devtools/shadereditor.css          (devtools/shadereditor.css)
-*       skin/classic/aero/browser/devtools/canvasdebugger.css        (devtools/canvasdebugger.css)
 *       skin/classic/aero/browser/devtools/debugger.css              (devtools/debugger.css)
 *       skin/classic/aero/browser/devtools/profiler.css              (devtools/profiler.css)
 *       skin/classic/aero/browser/devtools/netmonitor.css            (devtools/netmonitor.css)
 *       skin/classic/aero/browser/devtools/scratchpad.css            (devtools/scratchpad.css)
         skin/classic/aero/browser/devtools/magnifying-glass.png      (../shared/devtools/images/magnifying-glass.png)
         skin/classic/aero/browser/devtools/magnifying-glass@2x.png   (../shared/devtools/images/magnifying-glass@2x.png)
         skin/classic/aero/browser/devtools/magnifying-glass-light.png (../shared/devtools/images/magnifying-glass-light.png)
         skin/classic/aero/browser/devtools/magnifying-glass-light@2x.png  (../shared/devtools/images/magnifying-glass-light@2x.png)
--- a/toolkit/devtools/DevToolsUtils.js
+++ b/toolkit/devtools/DevToolsUtils.js
@@ -3,17 +3,16 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
 /* General utilities used throughout devtools. */
 const { Ci, Cu } = require("chrome");
 
 let { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
-let { setTimeout, clearTimeout } = Cu.import("resource://gre/modules/Timer.jsm", {});
 
 /**
  * Turn the error |aError| into a string, without fail.
  */
 exports.safeErrorString = function safeErrorString(aError) {
   try {
     let errorString = aError.toString();
     if (typeof errorString == "string") {
@@ -23,18 +22,16 @@ exports.safeErrorString = function safeE
         if (aError.stack) {
           let stack = aError.stack.toString();
           if (typeof stack == "string") {
             errorString += "\nStack: " + stack;
           }
         }
       } catch (ee) { }
 
-      // Append additional line and column number information to the output,
-      // since it might not be part of the stringified error.
       if (typeof aError.lineNumber == "number" && typeof aError.columnNumber == "number") {
         errorString += "Line: " + aError.lineNumber + ", column: " + aError.columnNumber;
       }
 
       return errorString;
     }
   } catch (ee) { }
 
@@ -111,100 +108,69 @@ exports.zip = function zip(a, b) {
   for (let i = 0, aLength = a.length, bLength = b.length;
        i < aLength || i < bLength;
        i++) {
     pairs.push([a[i], b[i]]);
   }
   return pairs;
 };
 
-/**
- * Waits for the next tick in the event loop to execute a callback.
- */
-exports.executeSoon = function executeSoon(aFn) {
+const executeSoon = aFn => {
   Services.tm.mainThread.dispatch({
     run: exports.makeInfallible(aFn)
   }, Ci.nsIThread.DISPATCH_NORMAL);
 };
 
 /**
- * Waits for the next tick in the event loop.
- *
- * @return Promise
- *         A promise that is resolved after the next tick in the event loop.
- */
-exports.waitForTick = function waitForTick() {
-  let deferred = promise.defer();
-  exports.executeSoon(deferred.resolve);
-  return deferred.promise;
-};
-
-/**
- * Waits for the specified amount of time to pass.
- *
- * @param number aDelay
- *        The amount of time to wait, in milliseconds.
- * @return Promise
- *         A promise that is resolved after the specified amount of time passes.
- */
-exports.waitForTime = function waitForTime(aDelay) {
-  let deferred = promise.defer();
-  setTimeout(deferred.resolve, aDelay);
-  return deferred.promise;
-};
-
-/**
  * Like Array.prototype.forEach, but doesn't cause jankiness when iterating over
  * very large arrays by yielding to the browser and continuing execution on the
  * next tick.
  *
  * @param Array aArray
  *        The array being iterated over.
  * @param Function aFn
- *        The function called on each item in the array. If a promise is
- *        returned by this function, iterating over the array will be paused
- *        until the respective promise is resolved.
+ *        The function called on each item in the array.
  * @returns Promise
  *          A promise that is resolved once the whole array has been iterated
- *          over, and all promises returned by the aFn callback are resolved.
+ *          over.
  */
 exports.yieldingEach = function yieldingEach(aArray, aFn) {
   const deferred = promise.defer();
 
   let i = 0;
   let len = aArray.length;
-  let outstanding = [deferred.promise];
 
   (function loop() {
     const start = Date.now();
 
     while (i < len) {
       // Don't block the main thread for longer than 16 ms at a time. To
       // maintain 60fps, you have to render every frame in at least 16ms; we
       // aren't including time spent in non-JS here, but this is Good
       // Enough(tm).
       if (Date.now() - start > 16) {
-        exports.executeSoon(loop);
+        executeSoon(loop);
         return;
       }
 
       try {
-        outstanding.push(aFn(aArray[i], i++));
+        aFn(aArray[i++]);
       } catch (e) {
         deferred.reject(e);
         return;
       }
     }
 
     deferred.resolve();
   }());
 
-  return promise.all(outstanding);
+  return deferred.promise;
 }
 
+
 /**
  * Like XPCOMUtils.defineLazyGetter, but with a |this| sensitive getter that
  * allows the lazy getter to be defined on a prototype and work correctly with
  * instances.
  *
  * @param Object aObject
  *        The prototype object to define the lazy getter on.
  * @param String aKey
@@ -295,8 +261,9 @@ exports.isSafeJSObject = function isSafe
 
   let principal = Services.scriptSecurityManager.getObjectPrincipal(aObj);
   if (Services.scriptSecurityManager.isSystemPrincipal(principal)) {
     return true; // allow chrome objects
   }
 
   return Cu.isXrayWrapper(aObj);
 };
+
--- a/toolkit/devtools/Loader.jsm
+++ b/toolkit/devtools/Loader.jsm
@@ -66,17 +66,16 @@ BuiltinProvider.prototype = {
         "devtools/app-actor-front": "resource://gre/modules/devtools/app-actor-front.js",
         "devtools/styleinspector/css-logic": "resource://gre/modules/devtools/styleinspector/css-logic",
         "devtools/css-color": "resource://gre/modules/devtools/css-color",
         "devtools/output-parser": "resource://gre/modules/devtools/output-parser",
         "devtools/touch-events": "resource://gre/modules/devtools/touch-events",
         "devtools/client": "resource://gre/modules/devtools/client",
         "devtools/pretty-fast": "resource://gre/modules/devtools/pretty-fast.js",
         "devtools/async-utils": "resource://gre/modules/devtools/async-utils",
-        "devtools/content-observer": "resource://gre/modules/devtools/content-observer",
         "gcli": "resource://gre/modules/devtools/gcli",
         "acorn": "resource://gre/modules/devtools/acorn",
         "acorn/util/walk": "resource://gre/modules/devtools/acorn/walk.js",
 
         // Allow access to xpcshell test items from the loader.
         "xpcshell-test": "resource://test"
       },
       globals: loaderGlobals,
deleted file mode 100644
--- a/toolkit/devtools/content-observer.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/* 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 {Cc, Ci, Cu, Cr} = require("chrome");
-const {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-
-const events = require("sdk/event/core");
-const promise = require("sdk/core/promise");
-
-/**
- * Handles adding an observer for the creation of content document globals,
- * event sent immediately after a web content document window has been set up,
- * but before any script code has been executed.
- */
-function ContentObserver(tabActor) {
-  this._contentWindow = tabActor.window;
-  this._onContentGlobalCreated = this._onContentGlobalCreated.bind(this);
-  this._onInnerWindowDestroyed = this._onInnerWindowDestroyed.bind(this);
-  this.startListening();
-}
-
-module.exports.ContentObserver = ContentObserver;
-
-ContentObserver.prototype = {
-  /**
-   * Starts listening for the required observer messages.
-   */
-  startListening: function() {
-    Services.obs.addObserver(
-      this._onContentGlobalCreated, "content-document-global-created", false);
-    Services.obs.addObserver(
-      this._onInnerWindowDestroyed, "inner-window-destroyed", false);
-  },
-
-  /**
-   * Stops listening for the required observer messages.
-   */
-  stopListening: function() {
-    Services.obs.removeObserver(
-      this._onContentGlobalCreated, "content-document-global-created", false);
-    Services.obs.removeObserver(
-      this._onInnerWindowDestroyed, "inner-window-destroyed", false);
-  },
-
-  /**
-   * Fired immediately after a web content document window has been set up.
-   */
-  _onContentGlobalCreated: function(subject, topic, data) {
-    if (subject == this._contentWindow) {
-      events.emit(this, "global-created", subject);
-    }
-  },
-
-  /**
-   * Fired when an inner window is removed from the backward/forward cache.
-   */
-  _onInnerWindowDestroyed: function(subject, topic, data) {
-    let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
-    events.emit(this, "global-destroyed", id);
-  }
-};
-
-// Utility functions.
-
-ContentObserver.GetInnerWindowID = function(window) {
-  return window
-    .QueryInterface(Ci.nsIInterfaceRequestor)
-    .getInterface(Ci.nsIDOMWindowUtils)
-    .currentInnerWindowID;
-};
deleted file mode 100644
--- a/toolkit/devtools/server/actors/call-watcher.js
+++ /dev/null
@@ -1,559 +0,0 @@
-/* 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 {Cc, Ci, Cu, Cr} = require("chrome");
-const events = require("sdk/event/core");
-const promise = require("sdk/core/promise");
-const protocol = require("devtools/server/protocol");
-const {ContentObserver} = require("devtools/content-observer");
-
-const {on, once, off, emit} = events;
-const {method, Arg, Option, RetVal} = protocol;
-
-exports.register = function(handle) {
-  handle.addTabActor(CallWatcherActor, "callWatcherActor");
-};
-
-exports.unregister = function(handle) {
-  handle.removeTabActor(CallWatcherActor);
-};
-
-/**
- * Type describing a single function call in a stack trace.
- */
-protocol.types.addDictType("call-stack-item", {
-  name: "string",
-  file: "string",
-  line: "number"
-});
-
-/**
- * Type describing an overview of a function call.
- */
-protocol.types.addDictType("call-details", {
-  type: "number",
-  name: "string",
-  stack: "array:call-stack-item"
-});
-
-/**
- * This actor contains information about a function call, like the function
- * type, name, stack, arguments, returned value etc.
- */
-let FunctionCallActor = protocol.ActorClass({
-  typeName: "function-call",
-
-  /**
-   * Creates the function call actor.
-   *
-   * @param DebuggerServerConnection conn
-   *        The server connection.
-   * @param DOMWindow window
-   *        The content window.
-   * @param string global
-   *        The name of the global object owning this function, like
-   *        "CanvasRenderingContext2D" or "WebGLRenderingContext".
-   * @param object caller
-   *        The object owning the function when it was called.
-   *        For example, in `foo.bar()`, the caller is `foo`.
-   * @param number type
-   *        Either METHOD_FUNCTION, METHOD_GETTER or METHOD_SETTER.
-   * @param string name
-   *        The called function's name.
-   * @param array stack
-   *        The called function's stack, as a list of { name, file, line } objects.
-   * @param array args
-   *        The called function's arguments.
-   * @param any result
-   *        The value returned by the function call.
-   */
-  initialize: function(conn, [window, global, caller, type, name, stack, args, result]) {
-    protocol.Actor.prototype.initialize.call(this, conn);
-
-    this.details = {
-      window: window,
-      caller: caller,
-      type: type,
-      name: name,
-      stack: stack,
-      args: args,
-      return: result
-    };
-
-    this.meta = {
-      global: -1,
-      previews: { caller: "", args: "" }
-    };
-
-    if (global == "WebGLRenderingContext") {
-      this.meta.global = CallWatcherFront.CANVAS_WEBGL_CONTEXT;
-    } else if (global == "CanvasRenderingContext2D") {
-      this.meta.global = CallWatcherFront.CANVAS_2D_CONTEXT;
-    } else if (global == "window") {
-      this.meta.global = CallWatcherFront.UNKNOWN_SCOPE;
-    } else {
-      this.meta.global = CallWatcherFront.GLOBAL_SCOPE;
-    }
-
-    this.meta.previews.caller = this._generateCallerPreview();
-    this.meta.previews.args = this._generateArgsPreview();
-  },
-
-  /**
-   * Customize the marshalling of this actor to provide some generic information
-   * directly on the Front instance.
-   */
-  form: function() {
-    return {
-      actor: this.actorID,
-      type: this.details.type,
-      name: this.details.name,
-      file: this.details.stack[0].file,
-      line: this.details.stack[0].line,
-      callerPreview: this.meta.previews.caller,
-      argsPreview: this.meta.previews.args
-    };
-  },
-
-  /**
-   * Gets more information about this function call, which is not necessarily
-   * available on the Front instance.
-   */
-  getDetails: method(function() {
-    let { type, name, stack } = this.details;
-
-    // Since not all calls on the stack have corresponding owner files (e.g.
-    // callbacks of a requestAnimationFrame etc.), there's no benefit in
-    // returning them, as the user can't jump to the Debugger from them.
-    for (let i = stack.length - 1;;) {
-      if (stack[i].file) {
-        break;
-      }
-      stack.pop();
-      i--;
-    }
-
-    // XXX: Use grips for objects and serialize them properly, in order
-    // to add the function's caller, arguments and return value. Bug 978957.
-    return {
-      type: type,
-      name: name,
-      stack: stack
-    };
-  }, {
-    response: { info: RetVal("call-details") }
-  }),
-
-  /**
-   * Serializes the caller's name so that it can be easily be transferred
-   * as a string, but still be useful when displayed in a potential UI.
-   *
-   * @return string
-   *         The caller's name as a string.
-   */
-  _generateCallerPreview: function() {
-    let global = this.meta.global;
-    if (global == CallWatcherFront.CANVAS_WEBGL_CONTEXT) {
-      return "gl";
-    }
-    if (global == CallWatcherFront.CANVAS_2D_CONTEXT) {
-      return "ctx";
-    }
-    return "";
-  },
-
-  /**
-   * Serializes the arguments so that they can be easily be transferred
-   * as a string, but still be useful when displayed in a potential UI.
-   *
-   * @return string
-   *         The arguments as a string.
-   */
-  _generateArgsPreview: function() {
-    let { caller, args } = this.details;
-    let { global } = this.meta;
-
-    // XXX: All of this sucks. Make this smarter, so that the frontend
-    // can inspect each argument, be it object or primitive. Bug 978960.
-    let serializeArgs = () => args.map(arg => {
-      if (typeof arg == "undefined") {
-        return "undefined";
-      }
-      if (typeof arg == "function") {
-        return "Function";
-      }
-      if (typeof arg == "object") {
-        return "Object";
-      }
-      if (global == CallWatcherFront.CANVAS_WEBGL_CONTEXT) {
-        // XXX: This doesn't handle combined bitmasks. Bug 978964.
-        return getEnumsLookupTable("webgl", caller)[arg] || arg;
-      }
-      if (global == CallWatcherFront.CANVAS_2D_CONTEXT) {
-        return getEnumsLookupTable("2d", caller)[arg] || arg;
-      }
-      return arg;
-    });
-
-    return serializeArgs().join(", ");
-  }
-});
-
-/**
- * The corresponding Front object for the FunctionCallActor.
- */
-let FunctionCallFront = protocol.FrontClass(FunctionCallActor, {
-  initialize: function(client, form) {
-    protocol.Front.prototype.initialize.call(this, client, form);
-  },
-
-  /**
-   * Adds some generic information directly to this instance,
-   * to avoid extra roundtrips.
-   */
-  form: function(form) {
-    this.actorID = form.actor;
-    this.type = form.type;
-    this.name = form.name;
-    this.file = form.file;
-    this.line = form.line;
-    this.callerPreview = form.callerPreview;
-    this.argsPreview = form.argsPreview;
-  }
-});
-
-/**
- * This actor observes function calls on certain objects or globals.
- */
-let CallWatcherActor = exports.CallWatcherActor = protocol.ActorClass({
-  typeName: "call-watcher",
-  initialize: function(conn, tabActor) {
-    protocol.Actor.prototype.initialize.call(this, conn);
-    this.tabActor = tabActor;
-    this._onGlobalCreated = this._onGlobalCreated.bind(this);
-    this._onGlobalDestroyed = this._onGlobalDestroyed.bind(this);
-    this._onContentFunctionCall = this._onContentFunctionCall.bind(this);
-  },
-  destroy: function(conn) {
-    protocol.Actor.prototype.destroy.call(this, conn);
-    this.finalize();
-  },
-
-  /**
-   * Starts waiting for the current tab actor's document global to be
-   * created, in order to instrument the specified objects and become
-   * aware of everything the content does with them.
-   */
-  setup: method(function({ tracedGlobals, tracedFunctions, startRecording, performReload }) {
-    if (this._initialized) {
-      return;
-    }
-    this._initialized = true;
-
-    this._functionCalls = [];
-    this._tracedGlobals = tracedGlobals || [];
-    this._tracedFunctions = tracedFunctions || [];
-    this._contentObserver = new ContentObserver(this.tabActor);
-
-    on(this._contentObserver, "global-created", this._onGlobalCreated);
-    on(this._contentObserver, "global-destroyed", this._onGlobalDestroyed);
-
-    if (startRecording) {
-      this.resumeRecording();
-    }
-    if (performReload) {
-      this.tabActor.window.location.reload();
-    }
-  }, {
-    request: {
-      tracedGlobals: Option(0, "nullable:array:string"),
-      tracedFunctions: Option(0, "nullable:array:string"),
-      startRecording: Option(0, "boolean"),
-      performReload: Option(0, "boolean")
-    },
-    oneway: true
-  }),
-
-  /**
-   * Stops listening for document global changes and puts this actor
-   * to hibernation. This method is called automatically just before the
-   * actor is destroyed.
-   */
-  finalize: method(function() {
-    if (!this._initialized) {
-      return;
-    }
-    this._initialized = false;
-
-    this._contentObserver.stopListening();
-    off(this._contentObserver, "global-created", this._onGlobalCreated);
-    off(this._contentObserver, "global-destroyed", this._onGlobalDestroyed);
-
-    this._tracedGlobals = null;
-    this._tracedFunctions = null;
-    this._contentObserver = null;
-  }, {
-    oneway: true
-  }),
-
-  /**
-   * Returns whether the instrumented function calls are currently recorded.
-   */
-  isRecording: method(function() {
-    return this._recording;
-  }, {
-    response: RetVal("boolean")
-  }),
-
-  /**
-   * Starts recording function calls.
-   */
-  resumeRecording: method(function() {
-    this._recording = true;
-  }),
-
-  /**
-   * Stops recording function calls.
-   */
-  pauseRecording: method(function() {
-    this._recording = false;
-    return this._functionCalls;
-  }, {
-    response: { calls: RetVal("array:function-call") }
-  }),
-
-  /**
-   * Erases all the recorded function calls.
-   * Calling `resumeRecording` or `pauseRecording` does not erase history.
-   */
-  eraseRecording: method(function() {
-    this._functionCalls = [];
-  }),
-
-  /**
-   * Lightweight listener invoked whenever an instrumented function is called
-   * while recording. We're doing this to avoid the event emitter overhead,
-   * since this is expected to be a very hot function.
-   */
-  onCall: function() {},
-
-  /**
-   * Invoked whenever the current tab actor's document global is created.
-   */
-  _onGlobalCreated: function(window) {
-    let self = this;
-
-    this._tracedWindowId = ContentObserver.GetInnerWindowID(window);
-    let unwrappedWindow = XPCNativeWrapper.unwrap(window);
-    let callback = this._onContentFunctionCall;
-
-    for (let global of this._tracedGlobals) {
-      let prototype = unwrappedWindow[global].prototype;
-      let properties = Object.keys(prototype);
-      properties.forEach(name => overrideSymbol(global, prototype, name, callback));
-    }
-
-    for (let name of this._tracedFunctions) {
-      overrideSymbol("window", unwrappedWindow, name, callback);
-    }
-
-    /**
-     * Instruments a method, getter or setter on the specified target object to
-     * invoke a callback whenever it is called.
-     */
-    function overrideSymbol(global, target, name, callback) {
-      let propertyDescriptor = Object.getOwnPropertyDescriptor(target, name);
-
-      if (propertyDescriptor.get || propertyDescriptor.set) {
-        overrideAccessor(global, target, name, propertyDescriptor, callback);
-        return;
-      }
-      if (propertyDescriptor.writable && typeof propertyDescriptor.value == "function") {
-        overrideFunction(global, target, name, propertyDescriptor, callback);
-        return;
-      }
-    }
-
-    /**
-     * Instruments a function on the specified target object.
-     */
-    function overrideFunction(global, target, name, descriptor, callback) {
-      let originalFunc = target[name];
-
-      Object.defineProperty(target, name, {
-        value: function(...args) {
-          let result = originalFunc.apply(this, args);
-
-          if (self._recording) {
-            let stack = getStack(name);
-            let type = CallWatcherFront.METHOD_FUNCTION;
-            callback(unwrappedWindow, global, this, type, name, stack, args, result);
-          }
-          return result;
-        },
-        configurable: descriptor.configurable,
-        enumerable: descriptor.enumerable,
-        writable: true
-      });
-    }
-
-    /**
-     * Instruments a getter or setter on the specified target object.
-     */
-    function overrideAccessor(global, target, name, descriptor, callback) {
-      let originalGetter = target.__lookupGetter__(name);
-      let originalSetter = target.__lookupSetter__(name);
-
-      Object.defineProperty(target, name, {
-        get: function(...args) {
-          if (!originalGetter) return undefined;
-          let result = originalGetter.apply(this, args);
-
-          if (self._recording) {
-            let stack = getStack(name);
-            let type = CallWatcherFront.GETTER_FUNCTION;
-            callback(unwrappedWindow, global, this, type, name, stack, args, result);
-          }
-          return result;
-        },
-        set: function(...args) {
-          if (!originalSetter) return;
-          originalSetter.apply(this, args);
-
-          if (self._recording) {
-            let stack = getStack(name);
-            let type = CallWatcherFront.SETTER_FUNCTION;
-            callback(unwrappedWindow, global, this, type, name, stack, args, undefined);
-          }
-        },
-        configurable: descriptor.configurable,
-        enumerable: descriptor.enumerable
-      });
-    }
-
-    /**
-     * Stores the relevant information about calls on the stack when
-     * a function is called.
-     */
-    function getStack(caller) {
-      try {
-        // Using Components.stack wouldn't be a better idea, since it's
-        // much slower because it attempts to retrieve the C++ stack as well.
-        throw new Error();
-      } catch (e) {
-        var stack = e.stack;
-      }
-
-      // Of course, using a simple regex like /(.*?)@(.*):(\d*):\d*/ would be
-      // much prettier, but this is a very hot function, so let's sqeeze
-      // every drop of performance out of it.
-      let calls = [];
-      let callIndex = 0;
-      let currNewLinePivot = stack.indexOf("\n") + 1;
-      let nextNewLinePivot = stack.indexOf("\n", currNewLinePivot);
-
-      while (nextNewLinePivot > 0) {
-        let nameDelimiterIndex = stack.indexOf("@", currNewLinePivot);
-        let columnDelimiterIndex = stack.lastIndexOf(":", nextNewLinePivot - 1);
-        let lineDelimiterIndex = stack.lastIndexOf(":", columnDelimiterIndex - 1);
-
-        if (!calls[callIndex]) {
-          calls[callIndex] = { name: "", file: "", line: 0 };
-        }
-        if (!calls[callIndex + 1]) {
-          calls[callIndex + 1] = { name: "", file: "", line: 0 };
-        }
-
-        if (callIndex > 0) {
-          let file = stack.substring(nameDelimiterIndex + 1, lineDelimiterIndex);
-          let line = stack.substring(lineDelimiterIndex + 1, columnDelimiterIndex);
-          let name = stack.substring(currNewLinePivot, nameDelimiterIndex);
-          calls[callIndex].name = name;
-          calls[callIndex - 1].file = file;
-          calls[callIndex - 1].line = line;
-        } else {
-          // Since the topmost stack frame is actually our overwritten function,
-          // it will not have the expected name.
-          calls[0].name = caller;
-        }
-
-        currNewLinePivot = nextNewLinePivot + 1;
-        nextNewLinePivot = stack.indexOf("\n", currNewLinePivot);
-        callIndex++;
-      }
-
-      return calls;
-    }
-  },
-
-  /**
-   * Invoked whenever the current tab actor's inner window is destroyed.
-   */
-  _onGlobalDestroyed: function(id) {
-    if (this._tracedWindowId == id) {
-      this.pauseRecording();
-      this.eraseRecording();
-    }
-  },
-
-  /**
-   * Invoked whenever an instrumented function is called.
-   */
-  _onContentFunctionCall: function(...details) {
-    let functionCall = new FunctionCallActor(this.conn, details);
-    this._functionCalls.push(functionCall);
-    this.onCall(functionCall);
-  }
-});
-
-/**
- * The corresponding Front object for the CallWatcherActor.
- */
-let CallWatcherFront = exports.CallWatcherFront = protocol.FrontClass(CallWatcherActor, {
-  initialize: function(client, { callWatcherActor }) {
-    protocol.Front.prototype.initialize.call(this, client, { actor: callWatcherActor });
-    client.addActorPool(this);
-    this.manage(this);
-  }
-});
-
-/**
- * Constants.
- */
-CallWatcherFront.METHOD_FUNCTION = 0;
-CallWatcherFront.GETTER_FUNCTION = 1;
-CallWatcherFront.SETTER_FUNCTION = 2;
-
-CallWatcherFront.GLOBAL_SCOPE = 0;
-CallWatcherFront.UNKNOWN_SCOPE = 1;
-CallWatcherFront.CANVAS_WEBGL_CONTEXT = 2;
-CallWatcherFront.CANVAS_2D_CONTEXT = 3;
-
-/**
- * A lookup table for cross-referencing flags or properties with their name
- * assuming they look LIKE_THIS most of the time.
- *
- * For example, when gl.clear(gl.COLOR_BUFFER_BIT) is called, the actual passed
- * argument's value is 16384, which we want identified as "COLOR_BUFFER_BIT".
- */
-var gEnumRegex = /^[A-Z_]+$/;
-var gEnumsLookupTable = {};
-
-function getEnumsLookupTable(type, object) {
-  let cachedEnum = gEnumsLookupTable[type];
-  if (cachedEnum) {
-    return cachedEnum;
-  }
-
-  let table = gEnumsLookupTable[type] = {};
-
-  for (let key in object) {
-    if (key.match(gEnumRegex)) {
-      table[object[key]] = key;
-    }
-  }
-
-  return table;
-}
deleted file mode 100644
--- a/toolkit/devtools/server/actors/canvas.js
+++ /dev/null
@@ -1,759 +0,0 @@
-/* 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 {Cc, Ci, Cu, Cr} = require("chrome");
-const events = require("sdk/event/core");
-const promise = require("sdk/core/promise");
-const protocol = require("devtools/server/protocol");
-const {CallWatcherActor, CallWatcherFront} = require("devtools/server/actors/call-watcher");
-const DevToolsUtils = require("devtools/toolkit/DevToolsUtils.js");
-
-const {on, once, off, emit} = events;
-const {method, custom, Arg, Option, RetVal} = protocol;
-
-const CANVAS_CONTEXTS = [
-  "CanvasRenderingContext2D",
-  "WebGLRenderingContext"
-];
-
-const ANIMATION_GENERATORS = [
-  "requestAnimationFrame",
-  "mozRequestAnimationFrame"
-];
-
-const DRAW_CALLS = [
-  // 2D canvas
-  "fill",
-  "stroke",
-  "clearRect",
-  "fillRect",
-  "strokeRect",
-  "fillText",
-  "strokeText",
-  "drawImage",
-
-  // WebGL
-  "clear",
-  "drawArrays",
-  "drawElements",
-  "finish",
-  "flush"
-];
-
-const INTERESTING_CALLS = [
-  // 2D canvas
-  "save",
-  "restore",
-
-  // WebGL
-  "useProgram"
-];
-
-exports.register = function(handle) {
-  handle.addTabActor(CanvasActor, "canvasActor");
-};
-
-exports.unregister = function(handle) {
-  handle.removeTabActor(CanvasActor);
-};
-
-/**
- * Type representing an Uint32Array buffer, serialized fast(er).
- *
- * XXX: It would be nice if on local connections (only), we could just *give*
- * the buffer directly to the front, instead of going through all this
- * serialization redundancy.
- */
-protocol.types.addType("uint32-array", {
-  write: (v) => "[" + Array.join(v, ",") + "]",
-  read: (v) => new Uint32Array(JSON.parse(v))
-});
-
-/**
- * Type describing a thumbnail or screenshot in a recorded animation frame.
- */
-protocol.types.addDictType("snapshot-image", {
-  index: "number",
-  width: "number",
-  height: "number",
-  flipped: "boolean",
-  pixels: "uint32-array"
-});
-
-/**
- * Type describing an overview of a recorded animation frame.
- */
-protocol.types.addDictType("snapshot-overview", {
-  calls: "array:function-call",
-  thumbnails: "array:snapshot-image",
-  screenshot: "snapshot-image"
-});
-
-/**
- * This actor represents a recorded animation frame snapshot, along with
- * all the corresponding canvas' context methods invoked in that frame,
- * thumbnails for each draw call and a screenshot of the end result.
- */
-let FrameSnapshotActor = protocol.ActorClass({
-  typeName: "frame-snapshot",
-
-  /**
-   * Creates the frame snapshot call actor.
-   *
-   * @param DebuggerServerConnection conn
-   *        The server connection.
-   * @param HTMLCanvasElement canvas
-   *        A reference to the content canvas.
-   * @param array calls
-   *        An array of "function-call" actor instances.
-   * @param object screenshot
-   *        A single "snapshot-image" type instance.
-   */
-  initialize: function(conn, { canvas, calls, screenshot }) {
-    protocol.Actor.prototype.initialize.call(this, conn);
-    this._contentCanvas = canvas;
-    this._functionCalls = calls;
-    this._lastDrawCallScreenshot = screenshot;
-  },
-
-  /**
-   * Gets as much data about this snapshot without computing anything costly.
-   */
-  getOverview: method(function() {
-    return {
-      calls: this._functionCalls,
-      thumbnails: this._functionCalls.map(e => e._thumbnail).filter(e => !!e),
-      screenshot: this._lastDrawCallScreenshot
-    };
-  }, {
-    response: { overview: RetVal("snapshot-overview") }
-  }),
-
-  /**
-   * Gets a screenshot of the canvas's contents after the specified
-   * function was called.
-   */
-  generateScreenshotFor: method(function(functionCall) {
-    let caller = functionCall.details.caller;
-    let global = functionCall.meta.global;
-
-    let canvas = this._contentCanvas;
-    let calls = this._functionCalls;
-    let index = calls.indexOf(functionCall);
-
-    // To get a screenshot, replay all the steps necessary to render the frame,
-    // by invoking the context calls up to and including the specified one.
-    // This will be done in a custom framebuffer in case of a WebGL context.
-    let { replayContext, lastDrawCallIndex } = ContextUtils.replayAnimationFrame({
-      contextType: global,
-      canvas: canvas,
-      calls: calls,
-      first: 0,
-      last: index
-    });
-
-    // To keep things fast, generate an image that's relatively small.
-    let dimensions = Math.min(CanvasFront.SCREENSHOT_HEIGHT_MAX, canvas.height);
-    let screenshot;
-
-    // Depending on the canvas' context, generating a screenshot is done
-    // in different ways. In case of the WebGL context, we also need to reset
-    // the framebuffer binding to the default value.
-    if (global == CallWatcherFront.CANVAS_WEBGL_CONTEXT) {
-      screenshot = ContextUtils.getPixelsForWebGL(replayContext);
-      replayContext.bindFramebuffer(replayContext.FRAMEBUFFER, null);
-      screenshot.flipped = true;
-    }
-    // In case of 2D contexts, no additional special treatment is necessary.
-    else if (global == CallWatcherFront.CANVAS_2D_CONTEXT) {
-      screenshot = ContextUtils.getPixelsFor2D(replayContext);
-      screenshot.flipped = false;
-    }
-
-    screenshot.index = lastDrawCallIndex;
-    return screenshot;
-  }, {
-    request: { call: Arg(0, "function-call") },
-    response: { screenshot: RetVal("snapshot-image") }
-  })
-});
-
-/**
- * The corresponding Front object for the FrameSnapshotActor.
- */
-let FrameSnapshotFront = protocol.FrontClass(FrameSnapshotActor, {
-  initialize: function(client, form) {
-    protocol.Front.prototype.initialize.call(this, client, form);
-    this._lastDrawCallScreenshot = null;
-    this._cachedScreenshots = new WeakMap();
-  },
-
-  /**
-   * This implementation caches the last draw call screenshot to optimize
-   * frontend requests to `generateScreenshotFor`.
-   */
-  getOverview: custom(function() {
-    return this._getOverview().then(data => {
-      this._lastDrawCallScreenshot = data.screenshot;
-      return data;
-    });
-  }, {
-    impl: "_getOverview"
-  }),
-
-  /**
-   * This implementation saves a roundtrip to the backend if the screenshot
-   * was already generated and retrieved once.
-   */
-  generateScreenshotFor: custom(function(functionCall) {
-    if (CanvasFront.ANIMATION_GENERATORS.has(functionCall.name)) {
-      return promise.resolve(this._lastDrawCallScreenshot);
-    }
-    let cachedScreenshot = this._cachedScreenshots.get(functionCall);
-    if (cachedScreenshot) {
-      return cachedScreenshot;
-    }
-    let screenshot = this._generateScreenshotFor(functionCall);
-    this._cachedScreenshots.set(functionCall, screenshot);
-    return screenshot;
-  }, {
-    impl: "_generateScreenshotFor"
-  })
-});
-
-/**
- * This Canvas Actor handles simple instrumentation of all the methods
- * of a 2D or WebGL context, to provide information regarding all the calls
- * made when drawing frame inside an animation loop.
- */
-let CanvasActor = exports.CanvasActor = protocol.ActorClass({
-  typeName: "canvas",
-  initialize: function(conn, tabActor) {
-    protocol.Actor.prototype.initialize.call(this, conn);
-    this.tabActor = tabActor;
-    this._onContentFunctionCall = this._onContentFunctionCall.bind(this);
-  },
-  destroy: function(conn) {
-    protocol.Actor.prototype.destroy.call(this, conn);
-    this.finalize();
-  },
-
-  /**
-   * Starts listening for function calls.
-   */
-  setup: method(function({ reload }) {
-    if (this._initialized) {
-      return;
-    }
-    this._initialized = true;
-
-    this._callWatcher = new CallWatcherActor(this.conn, this.tabActor);
-    this._callWatcher.onCall = this._onContentFunctionCall;
-    this._callWatcher.setup({
-      tracedGlobals: CANVAS_CONTEXTS,
-      tracedFunctions: ANIMATION_GENERATORS,
-      performReload: reload
-    });
-  }, {
-    request: { reload: Option(0, "boolean") },
-    oneway: true
-  }),
-
-  /**
-   * Stops listening for function calls.
-   */
-  finalize: method(function() {
-    if (!this._initialized) {
-      return;
-    }
-    this._initialized = false;
-
-    this._callWatcher.finalize();
-    this._callWatcher = null;
-  }, {
-    oneway: true
-  }),
-
-  /**
-   * Returns whether this actor has been set up.
-   */
-  isInitialized: method(function() {
-    return !!this._initialized;
-  }, {
-    response: { initialized: RetVal("boolean") }
-  }),
-
-  /**
-   * Records a snapshot of all the calls made during the next animation frame.
-   * The animation should be implemented via the de-facto requestAnimationFrame
-   * utility, not inside a `setInterval` or recursive `setTimeout`.
-   *
-   * XXX: Currently only supporting requestAnimationFrame. When this isn't used,
-   * it'd be a good idea to display a huge red flashing banner telling people to
-   * STOP USING `setInterval` OR `setTimeout` FOR ANIMATION. Bug 978948.
-   */
-  recordAnimationFrame: method(function() {
-    if (this._callWatcher.isRecording()) {
-      return this._currentAnimationFrameSnapshot.promise;
-    }
-
-    this._callWatcher.eraseRecording();
-    this._callWatcher.resumeRecording();
-
-    let deferred = this._currentAnimationFrameSnapshot = promise.defer();
-    return deferred.promise;
-  }, {
-    response: { snapshot: RetVal("frame-snapshot") }
-  }),
-
-  /**
-   * Invoked whenever an instrumented function is called, be it on a
-   * 2d or WebGL context, or an animation generator like requestAnimationFrame.
-   */
-  _onContentFunctionCall: function(functionCall) {
-    let { window, name, args } = functionCall.details;
-
-    // The function call arguments are required to replay animation frames,
-    // in order to generate screenshots. However, simply storing references to
-    // every kind of object is a bad idea, since their properties may change.
-    // Consider transformation matrices for example, which are typically
-    // Float32Arrays whose values can easily change across context calls.
-    // They need to be cloned.
-    inplaceShallowCloneArrays(args, window);
-
-    if (CanvasFront.ANIMATION_GENERATORS.has(name)) {
-      this._handleAnimationFrame(functionCall);
-      return;
-    }
-    if (CanvasFront.DRAW_CALLS.has(name) && this._animationStarted) {
-      this._handleDrawCall(functionCall);
-      return;
-    }
-  },
-
-  /**
-   * Handle animations generated using requestAnimationFrame.
-   */
-  _handleAnimationFrame: function(functionCall) {
-    if (!this._animationStarted) {
-      this._handleAnimationFrameBegin();
-    } else {
-      this._handleAnimationFrameEnd(functionCall);
-    }
-  },
-
-  /**
-   * Called whenever an animation frame rendering begins.
-   */
-  _handleAnimationFrameBegin: function() {
-    this._callWatcher.eraseRecording();
-    this._animationStarted = true;
-  },
-
-  /**
-   * Called whenever an animation frame rendering ends.
-   */
-  _handleAnimationFrameEnd: function() {
-    // Get a hold of all the function calls made during this animation frame.
-    // Since only one snapshot can be recorded at a time, erase all the
-    // previously recorded calls.
-    let functionCalls = this._callWatcher.pauseRecording();
-    this._callWatcher.eraseRecording();
-
-    // Since the animation frame finished, get a hold of the (already retrieved)
-    // canvas pixels to conveniently create a screenshot of the final rendering.
-    let index = this._lastDrawCallIndex;
-    let width = this._lastContentCanvasWidth;
-    let height = this._lastContentCanvasHeight;
-    let flipped = this._lastThumbnailFlipped;
-    let pixels = ContextUtils.getPixelStorage()["32bit"];
-    let lastDrawCallScreenshot = {
-      index: index,
-      width: width,
-      height: height,
-      flipped: flipped,
-      pixels: pixels.subarray(0, width * height)
-    };
-
-    // Wrap the function calls and screenshot in a FrameSnapshotActor instance,
-    // which will resolve the promise returned by `recordAnimationFrame`.
-    let frameSnapshot = new FrameSnapshotActor(this.conn, {
-      canvas: this._lastDrawCallCanvas,
-      calls: functionCalls,
-      screenshot: lastDrawCallScreenshot
-    });
-
-    this._currentAnimationFrameSnapshot.resolve(frameSnapshot);
-    this._currentAnimationFrameSnapshot = null;
-    this._animationStarted = false;
-  },
-
-  /**
-   * Invoked whenever a draw call is detected in the animation frame which is
-   * currently being recorded.
-   */
-  _handleDrawCall: function(functionCall) {
-    let functionCalls = this._callWatcher.pauseRecording();
-    let caller = functionCall.details.caller;
-    let global = functionCall.meta.global;
-
-    let contentCanvas = this._lastDrawCallCanvas = caller.canvas;
-    let index = this._lastDrawCallIndex = functionCalls.indexOf(functionCall);
-    let w = this._lastContentCanvasWidth = contentCanvas.width;
-    let h = this._lastContentCanvasHeight = contentCanvas.height;
-
-    // To keep things fast, generate images of small and fixed dimensions.
-    let dimensions = CanvasFront.THUMBNAIL_HEIGHT;
-    let thumbnail;
-
-    // Create a thumbnail on every draw call on the canvas context, to augment
-    // the respective function call actor with this additional data.
-    if (global == CallWatcherFront.CANVAS_WEBGL_CONTEXT) {
-      // Check if drawing to a custom framebuffer (when rendering to texture).
-      // Don't create a thumbnail in this particular case.
-      let framebufferBinding = caller.getParameter(caller.FRAMEBUFFER_BINDING);
-      if (framebufferBinding == null) {
-        thumbnail = ContextUtils.getPixelsForWebGL(caller, 0, 0, w, h, dimensions);
-        thumbnail.flipped = this._lastThumbnailFlipped = true;
-        thumbnail.index = index;
-      }
-    } else if (global == CallWatcherFront.CANVAS_2D_CONTEXT) {
-      thumbnail = ContextUtils.getPixelsFor2D(caller, 0, 0, w, h, dimensions);
-      thumbnail.flipped = this._lastThumbnailFlipped = false;
-      thumbnail.index = index;
-    }
-
-    functionCall._thumbnail = thumbnail;
-    this._callWatcher.resumeRecording();
-  }
-});
-
-/**
- * A collection of methods for manipulating canvas contexts.
- */
-let ContextUtils = {
-  /**
-   * WebGL contexts are sensitive to how they're queried. Use this function
-   * to make sure the right context is always retrieved, if available.
-   *
-   * @param HTMLCanvasElement canvas
-   *        The canvas element for which to get a WebGL context.
-   * @param WebGLRenderingContext gl
-   *        The queried WebGL context, or null if unavailable.
-   */
-  getWebGLContext: function(canvas) {
-    return canvas.getContext("webgl") ||
-           canvas.getContext("experimental-webgl");
-  },
-
-  /**
-   * Gets a hold of the rendered pixels in the most efficient way possible for
-   * a canvas with a WebGL context.
-   *
-   * @param WebGLRenderingContext gl
-   *        The WebGL context to get a screenshot from.
-   * @param number srcX [optional]
-   *        The first left pixel that is read from the framebuffer.
-   * @param number srcY [optional]
-   *        The first top pixel that is read from the framebuffer.
-   * @param number srcWidth [optional]
-   *        The number of pixels to read on the X axis.
-   * @param number srcHeight [optional]
-   *        The number of pixels to read on the Y axis.
-   * @param number dstHeight [optional]
-   *        The desired generated screenshot height.
-   * @return object
-   *         An objet containing the screenshot's width, height and pixel data.
-   */
-  getPixelsForWebGL: function(gl,
-    srcX = 0, srcY = 0,
-    srcWidth = gl.canvas.width,
-    srcHeight = gl.canvas.height,
-    dstHeight = srcHeight)
-  {
-    let contentPixels = ContextUtils.getPixelStorage(srcWidth, srcHeight);
-    let { "8bit": charView, "32bit": intView } = contentPixels;
-    gl.readPixels(srcX, srcY, srcWidth, srcHeight, gl.RGBA, gl.UNSIGNED_BYTE, charView);
-    return this.resizePixels(intView, srcWidth, srcHeight, dstHeight);
-  },
-
-  /**
-   * Gets a hold of the rendered pixels in the most efficient way possible for
-   * a canvas with a 2D context.
-   *
-   * @param CanvasRenderingContext2D ctx
-   *        The 2D context to get a screenshot from.
-   * @param number srcX [optional]
-   *        The first left pixel that is read from the canvas.
-   * @param number srcY [optional]
-   *        The first top pixel that is read from the canvas.
-   * @param number srcWidth [optional]
-   *        The number of pixels to read on the X axis.
-   * @param number srcHeight [optional]
-   *        The number of pixels to read on the Y axis.
-   * @param number dstHeight [optional]
-   *        The desired generated screenshot height.
-   * @return object
-   *         An objet containing the screenshot's width, height and pixel data.
-   */
-  getPixelsFor2D: function(ctx,
-    srcX = 0, srcY = 0,
-    srcWidth = ctx.canvas.width,
-    srcHeight = ctx.canvas.height,
-    dstHeight = srcHeight)
-  {
-    let { data } = ctx.getImageData(srcX, srcY, srcWidth, srcHeight);
-    let { "32bit": intView } = ContextUtils.usePixelStorage(data.buffer);
-    return this.resizePixels(intView, srcWidth, srcHeight, dstHeight);
-  },
-
-  /**
-   * Resizes the provided pixels to fit inside a rectangle with the specified
-   * height and the same aspect ratio as the source.
-   *
-   * @param Uint32Array srcPixels
-   *        The source pixel data, assuming 32bit/pixel and 4 color components.
-   * @param number srcWidth
-   *        The source pixel data width.
-   * @param number srcHeight
-   *        The source pixel data height.
-   * @param number dstHeight [optional]
-   *        The desired resized pixel data height.
-   * @return object
-   *         An objet containing the resized pixels width, height and data.
-   */
-  resizePixels: function(srcPixels, srcWidth, srcHeight, dstHeight) {
-    let screenshotRatio = dstHeight / srcHeight;
-    let dstWidth = Math.floor(srcWidth * screenshotRatio);
-
-    // Use a plain array instead of a Uint32Array to make serializing faster.
-    let dstPixels = new Array(dstWidth * dstHeight);
-
-    // If the resized image ends up being completely transparent, returning
-    // an empty array will skip some redundant serialization cycles.
-    let isTransparent = true;
-
-    for (let dstX = 0; dstX < dstWidth; dstX++) {
-      for (let dstY = 0; dstY < dstHeight; dstY++) {
-        let srcX = Math.floor(dstX / screenshotRatio);
-        let srcY = Math.floor(dstY / screenshotRatio);
-        let cPos = srcX + srcWidth * srcY;
-        let dPos = dstX + dstWidth * dstY;
-        let color = dstPixels[dPos] = srcPixels[cPos];
-        if (color) {
-          isTransparent = false;
-        }
-      }
-    }
-
-    return {
-      width: dstWidth,
-      height: dstHeight,
-      pixels: isTransparent ? [] : dstPixels
-    };
-  },
-
-  /**
-   * Invokes a series of canvas context calls, to "replay" an animation frame
-   * and generate a screenshot.
-   *
-   * In case of a WebGL context, an offscreen framebuffer is created for
-   * the respective canvas, and the rendering will be performed into it.
-   * This is necessary because some state (like shaders, textures etc.) can't
-   * be shared between two different WebGL contexts.
-   * Hopefully, once SharedResources are a thing this won't be necessary:
-   * http://www.khronos.org/webgl/wiki/SharedResouces
-   *
-   * In case of a 2D context, a new canvas is created, since there's no
-   * intrinsic state that can't be easily duplicated.
-   *
-   * @param number contexType
-   *        The type of context to use. See the CallWatcherFront scope types.
-   * @param HTMLCanvasElement canvas
-   *        The canvas element which is the source of all context calls.
-   * @param array calls
-   *        An array of function call actors.
-   * @param number first
-   *        The first function call to start from.
-   * @param number last
-   *        The last (inclusive) function call to end at.
-   * @return object
-   *         The context on which the specified calls were invoked and the
-   *         last registered draw call's index.
-   */
-  replayAnimationFrame: function({ contextType, canvas, calls, first, last }) {
-    let w = canvas.width;
-    let h = canvas.height;
-
-    let replayCanvas;
-    let replayContext;
-    let customFramebuffer;
-    let lastDrawCallIndex = -1;
-
-    // In case of WebGL contexts, rendering will be done offscreen, in a
-    // custom framebuffer, but on the provided canvas context.
-    if (contextType == CallWatcherFront.CANVAS_WEBGL_CONTEXT) {
-      replayCanvas = canvas;
-      replayContext = this.getWebGLContext(replayCanvas);
-      customFramebuffer = this.createBoundFramebuffer(replayContext, w, h);
-    }
-    // In case of 2D contexts, draw everything on a separate canvas context.
-    else if (contextType == CallWatcherFront.CANVAS_2D_CONTEXT) {
-      let contentDocument = canvas.ownerDocument;
-      replayCanvas = contentDocument.createElement("canvas");
-      replayCanvas.width = w;
-      replayCanvas.height = h;
-      replayContext = replayCanvas.getContext("2d");
-      replayContext.clearRect(0, 0, w, h);
-    }
-
-    // Replay all the context calls up to and including the specified one.
-    for (let i = first; i <= last; i++) {
-      let { type, name, args } = calls[i].details;
-
-      // Prevent WebGL context calls that try to reset the framebuffer binding
-      // to the default value, since we want to perform the rendering offscreen.
-      if (name == "bindFramebuffer" && args[1] == null) {
-        replayContext.bindFramebuffer(replayContext.FRAMEBUFFER, customFramebuffer);
-      } else {
-        if (type == CallWatcherFront.METHOD_FUNCTION) {
-          replayContext[name].apply(replayContext, args);
-        } else if (type == CallWatcherFront.SETTER_FUNCTION) {
-          replayContext[name] = args;
-        } else {
-          // Ignore getter calls.
-        }
-        if (CanvasFront.DRAW_CALLS.has(name)) {
-          lastDrawCallIndex = i;
-        }
-      }
-    }
-
-    return {
-      replayContext: replayContext,
-      lastDrawCallIndex: lastDrawCallIndex
-    };
-  },
-
-  /**
-   * Gets an object containing a buffer large enough to hold width * height
-   * pixels, assuming 32bit/pixel and 4 color components.
-   *
-   * This method avoids allocating memory and tries to reuse a common buffer
-   * as much as possible.
-   *
-   * @param number w
-   *        The desired pixel array storage width.
-   * @param number h
-   *        The desired pixel array storage height.
-   * @return object
-   *         The requested pixel array buffer.
-   */
-  getPixelStorage: function(w = 0, h = 0) {
-    let storage = this._currentPixelStorage;
-    if (storage && storage["32bit"].length >= w * h) {
-      return storage;
-    }
-    return this.usePixelStorage(new ArrayBuffer(w * h * 4));
-  },
-
-  /**
-   * Creates and saves the array buffer views used by `getPixelStorage`.
-   *
-   * @param ArrayBuffer buffer
-   *        The raw buffer used as storage for various array buffer views.
-   */
-  usePixelStorage: function(buffer) {
-    let array8bit = new Uint8Array(buffer);
-    let array32bit = new Uint32Array(buffer);
-    return this._currentPixelStorage = {
-      "8bit": array8bit,
-      "32bit": array32bit
-    };
-  },
-
-  /**
-   * Creates a framebuffer of the specified dimensions for a WebGL context,
-   * assuming a RGBA color buffer, a depth buffer and no stencil buffer.
-   *
-   * @param WebGLRenderingContext gl
-   *        The WebGL context to create and bind a framebuffer for.
-   * @param number width
-   *        The desired width of the renderbuffers.
-   * @param number height
-   *        The desired height of the renderbuffers.
-   * @return WebGLFramebuffer
-   *         The generated framebuffer object.
-   */
-  createBoundFramebuffer: function(gl, width, height) {
-    let framebuffer = gl.createFramebuffer();
-    gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
-
-    // Use a texture as the color rendebuffer attachment, since consumenrs of
-    // this function will most likely want to read the rendered pixels back.
-    let colorBuffer = gl.createTexture();
-    gl.bindTexture(gl.TEXTURE_2D, colorBuffer);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
-    gl.generateMipmap(gl.TEXTURE_2D);
-    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
-
-    let depthBuffer = gl.createRenderbuffer();
-    gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
-    gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
-
-    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorBuffer, 0);
-    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);
-
-    gl.bindTexture(gl.TEXTURE_2D, null);
-    gl.bindRenderbuffer(gl.RENDERBUFFER, null);
-
-    return framebuffer;
-  }
-};
-
-/**
- * The corresponding Front object for the CanvasActor.
- */
-let CanvasFront = exports.CanvasFront = protocol.FrontClass(CanvasActor, {
-  initialize: function(client, { canvasActor }) {
-    protocol.Front.prototype.initialize.call(this, client, { actor: canvasActor });
-    client.addActorPool(this);
-    this.manage(this);
-  }
-});
-
-/**
- * Constants.
- */
-CanvasFront.CANVAS_CONTEXTS = new Set(CANVAS_CONTEXTS);
-CanvasFront.ANIMATION_GENERATORS = new Set(ANIMATION_GENERATORS);
-CanvasFront.DRAW_CALLS = new Set(DRAW_CALLS);
-CanvasFront.INTERESTING_CALLS = new Set(INTERESTING_CALLS);
-CanvasFront.THUMBNAIL_HEIGHT = 50; // px
-CanvasFront.SCREENSHOT_HEIGHT_MAX = 256; // px
-CanvasFront.INVALID_SNAPSHOT_IMAGE = {
-  index: -1,
-  width: 0,
-  height: 0,
-  pixels: []
-};
-
-/**
- * Goes through all the arguments and creates a one-level shallow copy
- * of all arrays and array buffers.
- */
-function inplaceShallowCloneArrays(functionArguments, contentWindow) {
-  let { Object, Array, ArrayBuffer } = contentWindow;
-
-  functionArguments.forEach((arg, index, store) => {
-    if (arg instanceof Array) {
-      store[index] = arg.slice();
-    }
-    if (arg instanceof Object && arg.buffer instanceof ArrayBuffer) {
-      store[index] = new arg.constructor(arg);
-    }
-  });
-}
--- a/toolkit/devtools/server/actors/webgl.js
+++ b/toolkit/devtools/server/actors/webgl.js
@@ -1,17 +1,17 @@
 /* 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 {Cc, Ci, Cu, Cr} = require("chrome");
+const Services = require("Services");
 const events = require("sdk/event/core");
 const protocol = require("devtools/server/protocol");
-const { ContentObserver } = require("devtools/content-observer");
 
 const { on, once, off, emit } = events;
 const { method, Arg, Option, RetVal } = protocol;
 
 const WEBGL_CONTEXT_NAMES = ["webgl", "experimental-webgl", "moz-webgl"];
 
 // These traits are bit masks. Make sure they're powers of 2.
 const PROGRAM_DEFAULT_TRAITS = 0;
@@ -288,17 +288,17 @@ let WebGLActor = exports.WebGLActor = pr
    oneway: true
   }),
 
   /**
    * Gets an array of cached program actors for the current tab actor's window.
    * This is useful for dealing with bfcache, when no new programs are linked.
    */
   getPrograms: method(function() {
-    let id = ContentObserver.GetInnerWindowID(this.tabActor.window);
+    let id = getInnerWindowID(this.tabActor.window);
     return this._programActorsCache.filter(e => e.ownerWindow == id);
   }, {
     response: { programs: RetVal("array:gl-program") }
   }),
 
   /**
    * Events emitted by this actor. The "program-linked" event is fired
    * every time a WebGL program was linked with its respective two shaders.
@@ -342,31 +342,83 @@ let WebGLFront = exports.WebGLFront = pr
   initialize: function(client, { webglActor }) {
     protocol.Front.prototype.initialize.call(this, client, { actor: webglActor });
     client.addActorPool(this);
     this.manage(this);
   }
 });
 
 /**
+ * Handles adding an observer for the creation of content document globals,
+ * event sent immediately after a web content document window has been set up,
+ * but before any script code has been executed. This will allow us to
+ * instrument the HTMLCanvasElement with the appropriate inspection methods.
+ */
+function ContentObserver(tabActor) {
+  this._contentWindow = tabActor.window;
+  this._onContentGlobalCreated = this._onContentGlobalCreated.bind(this);
+  this._onInnerWindowDestroyed = this._onInnerWindowDestroyed.bind(this);
+  this.startListening();
+}
+
+ContentObserver.prototype = {
+  /**
+   * Starts listening for the required observer messages.
+   */
+  startListening: function() {
+    Services.obs.addObserver(
+      this._onContentGlobalCreated, "content-document-global-created", false);
+    Services.obs.addObserver(
+      this._onInnerWindowDestroyed, "inner-window-destroyed", false);
+  },
+
+  /**
+   * Stops listening for the required observer messages.
+   */
+  stopListening: function() {
+    Services.obs.removeObserver(
+      this._onContentGlobalCreated, "content-document-global-created", false);
+    Services.obs.removeObserver(
+      this._onInnerWindowDestroyed, "inner-window-destroyed", false);
+  },
+
+  /**
+   * Fired immediately after a web content document window has been set up.
+   */
+  _onContentGlobalCreated: function(subject, topic, data) {
+    if (subject == this._contentWindow) {
+      emit(this, "global-created", subject);
+    }
+  },
+
+  /**
+   * Fired when an inner window is removed from the backward/forward cache.
+   */
+  _onInnerWindowDestroyed: function(subject, topic, data) {
+    let id = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
+    emit(this, "global-destroyed", id);
+  }
+};
+
+/**
  * Instruments a HTMLCanvasElement with the appropriate inspection methods.
  */
 let WebGLInstrumenter = {
   /**
    * Overrides the getContext method in the HTMLCanvasElement prototype.
    *
    * @param nsIDOMWindow window
    *        The window to perform the instrumentation in.
    * @param WebGLObserver observer
    *        The observer watching function calls in the context.
    */
   handle: function(window, observer) {
     let self = this;
 
-    let id = ContentObserver.GetInnerWindowID(window);
+    let id = getInnerWindowID(window);
     let canvasElem = XPCNativeWrapper.unwrap(window.HTMLCanvasElement);
     let canvasPrototype = canvasElem.prototype;
     let originalGetContext = canvasPrototype.getContext;
 
     /**
      * Returns a drawing context on the canvas, or null if the context ID is
      * not supported. This override creates an observer for the targeted context
      * type and instruments specific functions in the targeted context instance.
@@ -1297,16 +1349,23 @@ WebGLProxy.prototype = {
     this._observer.suppressHandlers = prevState;
 
     return result;
   }
 };
 
 // Utility functions.
 
+function getInnerWindowID(window) {
+  return window
+    .QueryInterface(Ci.nsIInterfaceRequestor)
+    .getInterface(Ci.nsIDOMWindowUtils)
+    .currentInnerWindowID;
+}
+
 function removeFromMap(map, predicate) {
   for (let [key, value] of map) {
     if (predicate(value)) {
       map.delete(key);
     }
   }
 };
 
--- a/toolkit/devtools/server/main.js
+++ b/toolkit/devtools/server/main.js
@@ -387,29 +387,26 @@ var DebuggerServer = {
 
   /**
    * Install tab actors.
    */
   addTabActors: function() {
     this.addActors("resource://gre/modules/devtools/server/actors/script.js");
     this.addActors("resource://gre/modules/devtools/server/actors/webconsole.js");
     this.registerModule("devtools/server/actors/inspector");
-    this.registerModule("devtools/server/actors/call-watcher");
-    this.registerModule("devtools/server/actors/canvas");
     this.registerModule("devtools/server/actors/webgl");
     this.registerModule("devtools/server/actors/stylesheets");
     this.registerModule("devtools/server/actors/styleeditor");
     this.registerModule("devtools/server/actors/storage");
     this.registerModule("devtools/server/actors/gcli");
     this.registerModule("devtools/server/actors/tracer");
     this.registerModule("devtools/server/actors/memory");
     this.registerModule("devtools/server/actors/eventlooplag");
-    if ("nsIProfiler" in Ci) {
+    if ("nsIProfiler" in Ci)
       this.addActors("resource://gre/modules/devtools/server/actors/profiler.js");
-    }
   },
 
   /**
    * Listens on the given port or socket file for remote debugger connections.
    *
    * @param aPortOrPath int, string
    *        If given an integer, the port to listen on.
    *        Otherwise, the path to the unix socket domain file to listen on.