summaryrefslogtreecommitdiffstats
path: root/devtools/client/framework/attach-thread.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/framework/attach-thread.js')
-rw-r--r--devtools/client/framework/attach-thread.js115
1 files changed, 115 insertions, 0 deletions
diff --git a/devtools/client/framework/attach-thread.js b/devtools/client/framework/attach-thread.js
new file mode 100644
index 000000000..db445ce23
--- /dev/null
+++ b/devtools/client/framework/attach-thread.js
@@ -0,0 +1,115 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 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/. */
+
+const {Cc, Ci, Cu} = require("chrome");
+const Services = require("Services");
+const defer = require("devtools/shared/defer");
+
+const {LocalizationHelper} = require("devtools/shared/l10n");
+const L10N = new LocalizationHelper("devtools/client/locales/toolbox.properties");
+
+function handleThreadState(toolbox, event, packet) {
+ // Suppress interrupted events by default because the thread is
+ // paused/resumed a lot for various actions.
+ if (event !== "paused" || packet.why.type !== "interrupted") {
+ // TODO: Bug 1225492, we continue emitting events on the target
+ // like we used to, but we should emit these only on the
+ // threadClient now.
+ toolbox.target.emit("thread-" + event);
+ }
+
+ if (event === "paused") {
+ toolbox.highlightTool("jsdebugger");
+
+ if (packet.why.type === "debuggerStatement" ||
+ packet.why.type === "breakpoint" ||
+ packet.why.type === "exception") {
+ toolbox.raise();
+ toolbox.selectTool("jsdebugger");
+ }
+ } else if (event === "resumed") {
+ toolbox.unhighlightTool("jsdebugger");
+ }
+}
+
+function attachThread(toolbox) {
+ let deferred = defer();
+
+ let target = toolbox.target;
+ let { form: { chromeDebugger, actor } } = target;
+
+ // Sourcemaps are always turned off when using the new debugger
+ // frontend. This is because it does sourcemapping on the
+ // client-side, so the server should not do it. It also does not support
+ // blackboxing yet.
+ let useSourceMaps = false;
+ let autoBlackBox = false;
+ if(!Services.prefs.getBoolPref("devtools.debugger.new-debugger-frontend")) {
+ useSourceMaps = Services.prefs.getBoolPref("devtools.debugger.source-maps-enabled");
+ autoBlackBox = Services.prefs.getBoolPref("devtools.debugger.auto-black-box");
+ }
+ let threadOptions = { useSourceMaps, autoBlackBox };
+
+ let handleResponse = (res, threadClient) => {
+ if (res.error) {
+ deferred.reject(new Error("Couldn't attach to thread: " + res.error));
+ return;
+ }
+ threadClient.addListener("paused", handleThreadState.bind(null, toolbox));
+ threadClient.addListener("resumed", handleThreadState.bind(null, toolbox));
+
+ if (!threadClient.paused) {
+ deferred.reject(
+ new Error("Thread in wrong state when starting up, should be paused")
+ );
+ }
+
+ // These flags need to be set here because the client sends them
+ // with the `resume` request. We make sure to do this before
+ // resuming to avoid another interrupt. We can't pass it in with
+ // `threadOptions` because the resume request will override them.
+ threadClient.pauseOnExceptions(
+ Services.prefs.getBoolPref("devtools.debugger.pause-on-exceptions"),
+ Services.prefs.getBoolPref("devtools.debugger.ignore-caught-exceptions")
+ );
+
+ threadClient.resume(res => {
+ if (res.error === "wrongOrder") {
+ const box = toolbox.getNotificationBox();
+ box.appendNotification(
+ L10N.getStr("toolbox.resumeOrderWarning"),
+ "wrong-resume-order",
+ "",
+ box.PRIORITY_WARNING_HIGH
+ );
+ }
+
+ deferred.resolve(threadClient);
+ });
+ };
+
+ if (target.isTabActor) {
+ // Attaching a tab, a browser process, or a WebExtensions add-on.
+ target.activeTab.attachThread(threadOptions, handleResponse);
+ } else if (target.isAddon) {
+ // Attaching a legacy addon.
+ target.client.attachAddon(actor, res => {
+ target.client.attachThread(res.threadActor, handleResponse);
+ });
+ } else {
+ // Attaching an old browser debugger or a content process.
+ target.client.attachThread(chromeDebugger, handleResponse);
+ }
+
+ return deferred.promise;
+}
+
+function detachThread(threadClient) {
+ threadClient.removeListener("paused");
+ threadClient.removeListener("resumed");
+}
+
+module.exports = { attachThread, detachThread };