Bug 1268134 - Add client and toolbox access to specific windows. r=ochameau
MozReview-Commit-ID: 3IILOc6gZFi
--- a/devtools/client/framework/target-from-url.js
+++ b/devtools/client/framework/target-from-url.js
@@ -1,45 +1,48 @@
/* 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 { Cu, Ci } = require("chrome");
-
const { TargetFactory } = require("devtools/client/framework/target");
const { DebuggerServer } = require("devtools/server/main");
const { DebuggerClient } = require("devtools/shared/client/main");
const { Task } = require("devtools/shared/task");
/**
* Construct a Target for a given URL object having various query parameters:
*
* host:
* {String} The hostname or IP address to connect to.
* port:
* {Number} The TCP port to connect to, to use with `host` argument.
* ws:
* {Boolean} If true, connect via websocket instread of regular TCP connection.
*
- * type: tab, process
- * {String} The type of target to connect to. Currently tabs and processes are supported types.
+ * type: tab, process, window
+ * {String} The type of target to connect to.
*
- * If type="tab":
+ * If type == "tab":
* id:
* {Number} the tab outerWindowID
* chrome: Optional
- * {Boolean} Force the creation of a chrome target. Gives more privileges to the tab
- * actor. Allows chrome execution in the webconsole and see chrome files in
- * the debugger. (handy when contributing to firefox)
+ * {Boolean} Force the creation of a chrome target. Gives more privileges to
+ * the tab actor. Allows chrome execution in the webconsole and see chrome
+ * files in the debugger. (handy when contributing to firefox)
*
- * If type="process":
+ * If type == "process":
* id:
- * {Number} the process id to debug. Default to 0, which is the parent process.
+ * {Number} the process id to debug. Default to 0, which is the parent
+ * process.
+ *
+ * If type == "window":
+ * id:
+ * {Number} the window outerWindowID
*
* @param {URL} url
* The url to fetch query params from.
*
* @return A target object
*/
exports.targetFromURL = Task.async(function* (url) {
let params = url.searchParams;
@@ -88,16 +91,36 @@ exports.targetFromURL = Task.async(funct
isTabActor = false;
}
} catch (ex) {
if (ex.error == "noProcess") {
throw new Error("targetFromURL, process with id:'" + id + "' doesn't exist");
}
throw ex;
}
+ } else if (type == "window") {
+ // Fetch target for a remote window actor
+ DebuggerServer.allowChromeProcess = true;
+ try {
+ id = parseInt(id, 10);
+ if (isNaN(id)) {
+ throw new Error("targetFromURL, window requires id parameter");
+ }
+ let response = yield client.mainRoot.getWindow({
+ outerWindowID: id,
+ });
+ form = response.window;
+ chrome = true;
+ } catch (ex) {
+ if (ex.error == "notFound") {
+ throw new Error(`targetFromURL, window with id:'${id}' ` +
+ "doesn't exist");
+ }
+ throw ex;
+ }
} else {
throw new Error("targetFromURL, unsupported type='" + type + "' parameter");
}
return TargetFactory.forRemoteTab({ client, form, chrome, isTabActor });
});
function* createClient(params) {
--- a/devtools/client/framework/test/browser_target_from_url.js
+++ b/devtools/client/framework/test/browser_target_from_url.js
@@ -31,18 +31,29 @@ add_task(function* () {
info("Test invalid type");
try {
yield targetFromURL(new URL("http://foo?type=x"));
ok(false, "Shouldn't pass");
} catch (e) {
is(e.message, "targetFromURL, unsupported type='x' parameter");
}
+ info("Test browser window");
+ let windowId = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils)
+ .outerWindowID;
+ target = yield targetFromURL(new URL("http://foo?type=window&id=" + windowId));
+ is(target.url, window.location.href);
+ is(target.isLocalTab, false);
+ is(target.chrome, true);
+ is(target.isTabActor, true);
+ is(target.isRemote, true);
+
info("Test tab");
- let windowId = browser.outerWindowID;
+ windowId = browser.outerWindowID;
target = yield targetFromURL(new URL("http://foo?type=tab&id=" + windowId));
assertIsTabTarget(target, TEST_URI);
info("Test tab with chrome privileges");
target = yield targetFromURL(new URL("http://foo?type=tab&id=" + windowId + "&chrome"));
assertIsTabTarget(target, TEST_URI, true);
info("Test invalid tab id");
--- a/devtools/shared/client/main.js
+++ b/devtools/shared/client/main.js
@@ -1737,16 +1737,37 @@ RootClient.prototype = {
throw new Error("Unsupported argument given to getTab request");
}
}
return this.request(packet);
},
/**
+ * Fetch the WindowActor for a specific window, like a browser window in
+ * Firefox, but it can be used to reach any window in the process.
+ *
+ * @param number outerWindowID
+ * The outerWindowID of the top level window you are looking for.
+ */
+ getWindow: function ({ outerWindowID }) {
+ if (!outerWindowID) {
+ throw new Error("Must specify outerWindowID");
+ }
+
+ let packet = {
+ to: this.actor,
+ type: "getWindow",
+ outerWindowID,
+ };
+
+ return this.request(packet);
+ },
+
+ /**
* Description of protocol's actors and methods.
*
* @param function onResponse
* Called with the response packet.
*/
protocolDescription: DebuggerClient.requester({ type: "protocolDescription" }),
/*