Beispiel #1
0
var openToolboxForTab = Task.async(function*(tab, toolId, hostType) {
  info("Opening the toolbox");

  let toolbox;
  let target = TargetFactory.forTab(tab);

  // Check if the toolbox is already loaded.
  toolbox = gDevTools.getToolbox(target);
  if (toolbox) {
    if (!toolId || (toolId && toolbox.getPanel(toolId))) {
      info("Toolbox is already opened");
      return toolbox;
    }
  }

  // If not, load it now.
  toolbox = yield gDevTools.showToolbox(target, toolId, hostType);

  // Make sure that the toolbox frame is focused.
  yield new Promise(resolve => waitForFocus(resolve, toolbox.frame.contentWindow));

  info("Toolbox opened and focused");

  return toolbox;
});
var openToolboxForTab = async function(tab, toolId, hostType) {
  info("Opening the toolbox");

  let toolbox;
  let target = await TargetFactory.forTab(tab);
  await target.attach();

  // Check if the toolbox is already loaded.
  toolbox = gDevTools.getToolbox(target);
  if (toolbox) {
    if (!toolId || (toolId && toolbox.getPanel(toolId))) {
      info("Toolbox is already opened");
      return toolbox;
    }
  }

  // If not, load it now.
  toolbox = await gDevTools.showToolbox(target, toolId, hostType);

  // Make sure that the toolbox frame is focused.
  await new Promise(resolve => waitForFocus(resolve, toolbox.win));

  info("Toolbox opened and focused");

  return toolbox;
};
  const testPanelShowAndHide = async ({
    target, panelId, isFirstPanelLoad, expectedResults,
  }) => {
    info("Wait Addon Devtools Panel to be shown");

    await gDevTools.showToolbox(target, panelId);
    const {devtoolsPageTabId} = await extension.awaitMessage("devtools_panel_shown");

    // If the panel is loaded for the first time, we expect to also
    // receive the test messages and assert that both the page and the panel
    // have the same devtools.inspectedWindow.tabId value.
    if (isFirstPanelLoad) {
      const devtoolsPanelTabId = await extension.awaitMessage("devtools_panel_inspectedWindow_tabId");
      is(devtoolsPanelTabId, devtoolsPageTabId,
         "Got the same devtools.inspectedWindow.tabId from devtools page and panel");
    }

    info("Wait Addon Devtools Panel to be shown");

    await gDevTools.showToolbox(target, "testBlankPanel");
    const results = await extension.awaitMessage("devtools_panel_hidden");

    // We already checked the tabId, remove it from the results, so that we can check
    // the remaining properties using a single Assert.deepEqual.
    delete results.devtoolsPageTabId;

    Assert.deepEqual(
      results, expectedResults,
      "Got the expected number of created panels and shown/hidden events"
    );
  };
Beispiel #4
0
async function initToolbox(url, host) {
  const { gDevTools } = require("devtools/client/framework/devtools");
  const { targetFromURL } = require("devtools/client/framework/target-from-url");
  const { Toolbox } = require("devtools/client/framework/toolbox");
  const { DebuggerServer } = require("devtools/server/main");
  const { DebuggerClient } = require("devtools/shared/client/debugger-client");

  // Specify the default tool to open
  const tool = url.searchParams.get("tool");

  try {
    let target;
    if (url.searchParams.has("target")) {
      // Attach toolbox to a given browser iframe (<xul:browser> or <html:iframe
      // mozbrowser>) whose reference is set on the host iframe.

      // `iframe` is the targeted document to debug
      let iframe = host.wrappedJSObject ? host.wrappedJSObject.target
                                        : host.target;
      if (!iframe) {
        throw new Error("Unable to find the targeted iframe to debug");
      }

      // Need to use a xray to have attributes and behavior expected by
      // devtools codebase
      iframe = XPCNativeWrapper(iframe);

      // Fake a xul:tab object as we don't have one.
      // linkedBrowser is the only one attribute being queried by client.getTab
      const tab = { linkedBrowser: iframe };

      DebuggerServer.init();
      DebuggerServer.registerAllActors();
      const client = new DebuggerClient(DebuggerServer.connectPipe());

      await client.connect();
      // Creates a target for a given browser iframe.
      target = await client.mainRoot.getTab({ tab });
    } else {
      target = await targetFromURL(url);
      const toolbox = gDevTools.getToolbox(target);
      if (toolbox && toolbox.isDestroying()) {
        // If a toolbox already exists for the target, wait for current toolbox destroy to
        // be finished and retrieve a new valid target. The ongoing toolbox destroy will
        // destroy the target, so it can not be reused.
        await toolbox.destroy();
        target = await targetFromURL(url);
      }
    }
    const options = { customIframe: host };
    await gDevTools.showToolbox(target, tool, Toolbox.HostType.PAGE, options);
  } catch (error) {
    // When an error occurs, show error page with message.
    console.error("Exception while loading the toolbox", error);
    showErrorPage(host.contentDocument, `${error}`);
  }
}
Beispiel #5
0
 let onCheckboxClick = function(id) {
   let toolDefinition = gDevTools._tools.get(id);
   // Set the kill switch pref boolean to true
   Services.prefs.setBoolPref(toolDefinition.visibilityswitch, this.checked);
   if (this.checked) {
     gDevTools.emit("tool-registered", id);
   } else {
     gDevTools.emit("tool-unregistered", toolDefinition);
   }
 };
add_task(async function test_theme_name_no_panel() {
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, "http://mochi.test:8888/");

  async function devtools_page() {
    browser.devtools.panels.onThemeChanged.addListener(themeName => {
      browser.test.sendMessage("devtools_theme_changed_page", themeName);
      browser.test.sendMessage("current_theme_page", browser.devtools.panels.themeName);
    });

    browser.test.sendMessage("initial_theme", browser.devtools.panels.themeName);
  }

  let extension = ExtensionTestUtils.loadExtension({
    manifest: {
      devtools_page: "devtools_page.html",
    },
    files: {
      "devtools_page.html": `<!DOCTYPE html>
      <html>
       <head>
         <meta charset="utf-8">
       </head>
       <body>
         <script src="devtools_page.js"></script>
       </body>
      </html>`,
      "devtools_page.js": devtools_page,
    },
  });

  // Ensure that the initial value of the devtools theme is "light".
  await SpecialPowers.pushPrefEnv({set: [[DEVTOOLS_THEME_PREF, "light"]]});

  await extension.startup();

  let target = gDevTools.getTargetForTab(tab);
  await gDevTools.showToolbox(target, "webconsole");
  info("developer toolbox opened");

  is(await extension.awaitMessage("initial_theme"),
    "light",
    "The initial theme is reported as expected.");

  await testThemeSwitching(extension);

  await gDevTools.closeToolbox(target);
  await target.destroy();

  await extension.unload();

  await BrowserTestUtils.removeTab(tab);
});
// Small helper which provides the common steps to the following reload test cases.
async function runReloadTestCase({urlParams, background, devtoolsPage, testCase}) {
  const BASE = "http://mochi.test:8888/browser/browser/components/extensions/test/browser/";
  const TEST_TARGET_URL = `${BASE}file_inspectedwindow_reload_target.sjs?${urlParams}`;
  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_TARGET_URL);

  let extension = ExtensionTestUtils.loadExtension({
    background,
    manifest: {
      devtools_page: "devtools_page.html",
      permissions: ["webNavigation", "<all_urls>"],
    },
    files: {
      "devtools_page.html": `<!DOCTYPE html>
      <html>
       <head>
         <meta charset="utf-8">
         <script type="text/javascript" src="devtools_page.js"></script>
       </head>
       <body>
       </body>
      </html>`,
      "devtools_page.js": devtoolsPage,
    },
  });

  await extension.startup();

  let target = await gDevTools.getTargetForTab(tab);

  await gDevTools.showToolbox(target, "webconsole");
  info("developer toolbox opened");

  // Wait the test extension to be ready.
  await extension.awaitMessage("devtools_inspected_window_reload.ready");

  info("devtools page ready");

  // Run the test case.
  await testCase(extension);

  await gDevTools.closeToolbox(target);

  await target.destroy();

  BrowserTestUtils.removeTab(tab);

  await extension.unload();
}
 handleDevToolsFlag: function (window) {
   const {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
   const {gDevTools} = require("devtools/client/framework/devtools");
   const {TargetFactory} = require("devtools/client/framework/target");
   let target = TargetFactory.forTab(window.gBrowser.selectedTab);
   gDevTools.showToolbox(target);
 },
Beispiel #9
0
  init() {
    if (!this.inspector) {
      return;
    }

    let fontsApp = FontsApp({
      onPreviewFonts: this.onPreviewFonts,
      onShowAllFont: this.onShowAllFont,
    });

    let provider = createElement(Provider, {
      id: "fontinspector",
      key: "fontinspector",
      store: this.store,
      title: INSPECTOR_L10N.getStr("inspector.sidebar.fontInspectorTitle"),
    }, fontsApp);

    // Expose the provider to let inspector.js use it in setupSidebar.
    this.provider = provider;

    this.inspector.selection.on("new-node-front", this.onNewNode);
    this.inspector.sidebar.on("fontinspector-selected", this.onNewNode);

    // Listen for theme changes as the color of the previews depend on the theme
    gDevTools.on("theme-switched", this.onThemeChanged);

    this.store.dispatch(updatePreviewText(""));
    this.store.dispatch(updateShowAllFonts(false));
    this.update(false, "");
  }
Beispiel #10
0
  destroy() {
    if (this._destroyer) {
      return this._destroyer.promise;
    }
    this._destroyer = defer();
    Services.prefs.removeObserver(PREF_MESSAGE_TIMESTAMP, this._onToolboxPrefChanged);
    this.React = this.ReactDOM = this.FrameView = null;
    if (this.jsterm) {
      this.jsterm.destroy();
      this.jsterm = null;
    }

    const toolbox = gDevTools.getToolbox(this.hud.target);
    if (toolbox) {
      toolbox.off("webconsole-selected", this._onPanelSelected);
      toolbox.off("split-console", this._onChangeSplitConsoleState);
      toolbox.off("select", this._onChangeSplitConsoleState);
    }

    this.window = this.hud = this.wrapper = null;

    const onDestroy = () => {
      this._destroyer.resolve(null);
    };
    if (this.proxy) {
      this.proxy.disconnect().then(onDestroy);
      this.proxy = null;
    } else {
      onDestroy();
    }

    return this._destroyer.promise;
  }
add_task(async function setup_blank_panel() {
  // Create a blank custom tool so that we don't need to wait the webconsole
  // to be fully loaded/unloaded to prevent intermittent failures (related
  // to a webconsole that is still loading when the test has been completed).
  const testBlankPanel = {
    id: "testBlankPanel",
    url: "about:blank",
    label: "Blank Tool",
    isTargetSupported() {
      return true;
    },
    build(iframeWindow, toolbox) {
      return Promise.resolve({
        target: toolbox.target,
        toolbox: toolbox,
        isReady: true,
        panelDoc: iframeWindow.document,
        destroy() {},
      });
    },
  };

  registerCleanupFunction(() => {
    gDevTools.unregisterTool(testBlankPanel.id);
  });

  gDevTools.registerTool(testBlankPanel);
});
    Promise.all(loadEvents).then(() => {
      // Unload all stylesheets and classes from the old theme.
      if (oldThemeDef) {
        for (let name of oldThemeDef.classList) {
          documentElement.classList.remove(name);
        }

        for (let sheet of devtoolsStyleSheets.get(oldThemeDef) || []) {
          sheet.remove();
        }

        if (oldThemeDef.onUnapply) {
          oldThemeDef.onUnapply(window, newTheme);
        }
      }

      // Load all stylesheets and classes from the new theme.
      for (let name of newThemeDef.classList) {
        documentElement.classList.add(name);
      }

      if (newThemeDef.onApply) {
        newThemeDef.onApply(window, oldTheme);
      }

      // Final notification for further theme-switching related logic.
      gDevTools.emit("theme-switched", window, newTheme, oldTheme);
      notifyWindow();
    }, console.error.bind(console));
  initialize: Task.async(function* () {
    this._telemetry = new PerformanceTelemetry(this);
    this.startRecording = this.startRecording.bind(this);
    this.stopRecording = this.stopRecording.bind(this);
    this.importRecording = this.importRecording.bind(this);
    this.exportRecording = this.exportRecording.bind(this);
    this.clearRecordings = this.clearRecordings.bind(this);
    this._onRecordingSelectFromView = this._onRecordingSelectFromView.bind(this);
    this._onPrefChanged = this._onPrefChanged.bind(this);
    this._onThemeChanged = this._onThemeChanged.bind(this);
    this._onFrontEvent = this._onFrontEvent.bind(this);
    this._pipe = this._pipe.bind(this);

    // Store data regarding if e10s is enabled.
    this._e10s = Services.appinfo.browserTabsRemoteAutostart;
    this._setMultiprocessAttributes();

    this._prefs = require("devtools/client/performance/modules/global").PREFS;
    this._prefs.registerObserver();
    this._prefs.on("pref-changed", this._onPrefChanged);

    ToolbarView.on(EVENTS.UI_PREF_CHANGED, this._onPrefChanged);
    PerformanceView.on(EVENTS.UI_START_RECORDING, this.startRecording);
    PerformanceView.on(EVENTS.UI_STOP_RECORDING, this.stopRecording);
    PerformanceView.on(EVENTS.UI_IMPORT_RECORDING, this.importRecording);
    PerformanceView.on(EVENTS.UI_CLEAR_RECORDINGS, this.clearRecordings);
    RecordingsView.on(EVENTS.UI_EXPORT_RECORDING, this.exportRecording);
    RecordingsView.on(EVENTS.UI_RECORDING_SELECTED, this._onRecordingSelectFromView);
    DetailsView.on(EVENTS.UI_DETAILS_VIEW_SELECTED, this._pipe);

    gDevTools.on("pref-changed", this._onThemeChanged);
  }),
Beispiel #14
0
 handleDevToolsFlag: function (window) {
   const require = this.initDevTools("CommandLine");
   const {gDevTools} = require("devtools/client/framework/devtools");
   const {TargetFactory} = require("devtools/client/framework/target");
   let target = TargetFactory.forTab(window.gBrowser.selectedTab);
   gDevTools.showToolbox(target);
 },
Beispiel #15
0
 openWorkerToolbox: async function(worker) {
   const [response, workerTargetFront] =
     await this.toolbox.target.client.attachWorker(worker.actor);
   const workerTarget = TargetFactory.forWorker(workerTargetFront);
   const toolbox = await gDevTools.showToolbox(workerTarget, "jsdebugger", Toolbox.HostType.WINDOW);
   toolbox.once("destroy", () => workerTargetFront.detach());
 },
Beispiel #16
0
exports.viewSourceInScratchpad = async function(sourceURL, sourceLine) {
  // Check for matching top level scratchpad window.
  let wins = Services.wm.getEnumerator("devtools:scratchpad");

  while (wins.hasMoreElements()) {
    let win = wins.getNext();

    if (!win.closed && win.Scratchpad.uniqueName === sourceURL) {
      win.focus();
      win.Scratchpad.editor.setCursor({ line: sourceLine, ch: 0 });
      return;
    }
  }

  // For scratchpads within toolbox
  for (let toolbox of gDevTools.getToolboxes()) {
    let scratchpadPanel = toolbox.getPanel("scratchpad");
    if (scratchpadPanel) {
      let { scratchpad } = scratchpadPanel;
      if (scratchpad.uniqueName === sourceURL) {
        toolbox.selectTool("scratchpad");
        toolbox.raise();
        scratchpad.editor.focus();
        scratchpad.editor.setCursor({ line: sourceLine, ch: 0 });
        return;
      }
    }
  }
};
Beispiel #17
0
 exec: function(args, context) {
   if (!getPanel(context, "jsdebugger")) {
     return;
   }
   let target = context.environment.target;
   return gDevTools.closeToolbox(target).then(() => null);
 }
Beispiel #18
0
  setupThemeList: function () {
    let themeBox = this.panelDoc.getElementById("devtools-theme-box");
    let themeLabels = themeBox.querySelectorAll("label");
    for (let label of themeLabels) {
      label.remove();
    }

    let createThemeOption = theme => {
      let inputLabel = this.panelDoc.createElement("label");
      let inputRadio = this.panelDoc.createElement("input");
      inputRadio.setAttribute("type", "radio");
      inputRadio.setAttribute("value", theme.id);
      inputRadio.setAttribute("name", "devtools-theme-item");
      inputRadio.addEventListener("change", function (e) {
        SetPref(themeBox.getAttribute("data-pref"),
          e.target.value);
      });

      let inputSpanLabel = this.panelDoc.createElement("span");
      inputSpanLabel.textContent = theme.label;
      inputLabel.appendChild(inputRadio);
      inputLabel.appendChild(inputSpanLabel);

      return inputLabel;
    };

    // Populating the default theme list
    let themes = gDevTools.getThemeDefinitionArray();
    for (let theme of themes) {
      themeBox.appendChild(createThemeOption(theme));
    }

    this.updateCurrentTheme();
  },
Beispiel #19
0
  init() {
    if (!this.inspector) {
      return;
    }

    const fontsApp = FontsApp({
      fontEditorEnabled: Services.prefs.getBoolPref(PREF_FONT_EDITOR),
      onInstanceChange: this.onInstanceChange,
      onToggleFontHighlight: this.onToggleFontHighlight,
      onPreviewFonts: this.onPreviewFonts,
      onPropertyChange: this.onPropertyChange,
    });

    const provider = createElement(Provider, {
      id: "fontinspector",
      key: "fontinspector",
      store: this.store,
      title: INSPECTOR_L10N.getStr("inspector.sidebar.fontInspectorTitle"),
    }, fontsApp);

    // Expose the provider to let inspector.js use it in setupSidebar.
    this.provider = provider;

    this.inspector.selection.on("new-node-front", this.onNewNode);
    // @see ToolSidebar.onSidebarTabSelected()
    this.inspector.sidebar.on("fontinspector-selected", this.onNewNode);

    // Listen for theme changes as the color of the previews depend on the theme
    gDevTools.on("theme-switched", this.onThemeChanged);
  }
Beispiel #20
0
  openStyleEditor: function () {
    let inspector = this.tree.inspector;
    let rule = this.selectorInfo.rule;

    // The style editor can only display stylesheets coming from content because
    // chrome stylesheets are not listed in the editor's stylesheet selector.
    //
    // If the stylesheet is a content stylesheet we send it to the style
    // editor else we display it in the view source window.
    let parentStyleSheet = rule.parentStyleSheet;
    if (!parentStyleSheet || parentStyleSheet.isSystem) {
      let toolbox = gDevTools.getToolbox(inspector.target);
      toolbox.viewSource(rule.href, rule.line);
      return;
    }

    let location = promise.resolve(rule.location);
    if (Services.prefs.getBoolPref(PREF_ORIG_SOURCES)) {
      location = rule.getOriginalLocation();
    }

    location.then(({source, href, line, column}) => {
      let target = inspector.target;
      if (ToolDefinitions.styleEditor.isTargetSupported(target)) {
        gDevTools.showToolbox(target, "styleeditor").then(function (toolbox) {
          let sheet = source || href;
          toolbox.getCurrentPanel().selectStyleSheet(sheet, line, column);
        });
      }
    });
  }
Beispiel #21
0
  return Task.spawn(function* () {
    let tab = yield addTab(aUrl);
    info("Net tab added successfully: " + aUrl);

    let target = TargetFactory.forTab(tab);

    yield target.makeRemote();
    info("Target remoted.");

    if (!aEnableCache) {
      yield toggleCache(target, true);
      info("Cache disabled when the current and all future toolboxes are open.");
      // Remove any requests generated by the reload while toggling the cache to
      // avoid interfering with the test.
      isnot([...target.activeConsole.getNetworkEvents()].length, 0,
         "Request to reconfigure the tab was recorded.");
      target.activeConsole.clearNetworkRequests();
    }

    let toolbox = yield gDevTools.showToolbox(target, "netmonitor");
    info("Netork monitor pane shown successfully.");

    let debuggee = tab.linkedBrowser.contentWindow.wrappedJSObject;
    let monitor = toolbox.getCurrentPanel();
    return [tab, debuggee, monitor];
  });
Beispiel #22
0
  destroy: function() {
    this.viewedElement = null;
    this._outputParser = null;

    gDevTools.off("pref-changed", this._handlePrefChange);

    this._prefObserver.off(PREF_ORIG_SOURCES, this._onSourcePrefChanged);
    this._prefObserver.destroy();

    // Cancel tree construction
    if (this._createViewsProcess) {
      this._createViewsProcess.cancel();
    }
    if (this._refreshProcess) {
      this._refreshProcess.cancel();
    }

    // Remove context menu
    if (this._contextmenu) {
      this._contextmenu.destroy();
      this._contextmenu = null;
    }

    this.tooltips.destroy();
    this.highlighters.destroy();

    // Remove bound listeners
    this.styleDocument.removeEventListener("mousedown", this.focusWindow);
    this.element.removeEventListener("click", this._onClick);
    this.element.removeEventListener("copy", this._onCopy);
    this.element.removeEventListener("contextmenu", this._onContextMenu);
    this.searchField.removeEventListener("input", this._onFilterStyles);
    this.searchField.removeEventListener("keypress", this._onFilterKeyPress);
    this.searchField.removeEventListener("contextmenu",
                                         this._onFilterTextboxContextMenu);
    this.searchClearButton.removeEventListener("click", this._onClearSearch);
    this.includeBrowserStylesCheckbox.removeEventListener("command",
      this.includeBrowserStylesChanged);

    // Nodes used in templating
    this.root = null;
    this.element = null;
    this.panel = null;
    this.searchField = null;
    this.searchClearButton = null;
    this.includeBrowserStylesCheckbox = null;

    // Property views
    for (let propView of this.propertyViews) {
      propView.destroy();
    }
    this.propertyViews = null;

    this.inspector = null;
    this.styleDocument = null;
    this.styleWindow = null;

    this._isDestroyed = true;
  }
Beispiel #23
0
var closeTabAndToolbox = Task.async(function* (tab = gBrowser.selectedTab) {
  let target = TargetFactory.forTab(gBrowser.selectedTab);
  if (target) {
    yield gDevTools.closeToolbox(target);
  }

  yield removeTab(gBrowser.selectedTab);
});
Beispiel #24
0
var closeTabAndToolbox = async function(tab = gBrowser.selectedTab) {
  const target = await TargetFactory.forTab(tab);
  if (target) {
    await gDevTools.closeToolbox(target);
  }

  await removeTab(tab);
};
Beispiel #25
0
function teardown({target}) {
  info("Destroying the specified canvas debugger.");

  let {tab} = target;
  return gDevTools.closeToolbox(target).then(() => {
    removeTab(tab);
  });
}
Beispiel #26
0
registerCleanupFunction(function* cleanup() {
  let target = TargetFactory.forTab(gBrowser.selectedTab);
  yield gDevTools.closeToolbox(target);

  while (gBrowser.tabs.length > 1) {
    gBrowser.removeCurrentTab();
  }
});
Beispiel #27
0
 (response, workerClient) => {
   const workerTarget = TargetFactory.forWorker(workerClient);
   gDevTools
     .showToolbox(workerTarget, "jsdebugger", Toolbox.HostType.WINDOW)
     .then(toolbox => {
       toolbox.once("destroy", () => workerClient.detach());
     });
 }
Beispiel #28
0
 location.then(({source, href, line, column}) => {
   let target = inspector.target;
   if (ToolDefinitions.styleEditor.isTargetSupported(target)) {
     gDevTools.showToolbox(target, "styleeditor").then(function (toolbox) {
       let sheet = source || href;
       toolbox.getCurrentPanel().selectStyleSheet(sheet, line, column);
     });
   }
 });
Beispiel #29
0
 TargetFactory.forRemoteTab(options).then((target) => {
   let hostType = Toolbox.HostType.WINDOW;
   gDevTools.showToolbox(target, tool, hostType).then((toolbox) => {
     toolbox.once("destroyed", function () {
       gClient.close();
     });
   }, console.error.bind(console));
   window.close();
 }, console.error.bind(console));
Beispiel #30
0
  /**
   * Destruction function called when the inspector is destroyed. Removes event listeners
   * and cleans up references.
   */
  destroy() {
    this.inspector.selection.off("new-node-front", this.onNewNode);
    this.inspector.sidebar.off("fontinspector-selected", this.onNewNode);
    gDevTools.off("theme-switched", this.onThemeChanged);

    this.document = null;
    this.inspector = null;
    this.pageStyle = null;
    this.store = null;
  }