зеркало из https://github.com/mozilla/gecko-dev.git
152 строки
4.7 KiB
JavaScript
152 строки
4.7 KiB
JavaScript
/* 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 { TargetFactory } = require("devtools/client/framework/target");
|
|
const { DebuggerServer } = require("devtools/server/main");
|
|
const { DebuggerClient } = require("devtools/shared/client/debugger-client");
|
|
|
|
/**
|
|
* Construct a Target for a given URL object having various query parameters:
|
|
*
|
|
* - host, port & ws: See the documentation for clientFromURL
|
|
*
|
|
* - type: tab, process, window
|
|
* {String} The type of target to connect to.
|
|
*
|
|
* If type == "tab":
|
|
* - id:
|
|
* {Number} the tab outerWindowID
|
|
* - chrome: Optional
|
|
* {Boolean} Force the creation of a chrome target. Gives more privileges to
|
|
* the target actor. Allows chrome execution in the webconsole and see chrome
|
|
* files in the debugger. (handy when contributing to firefox)
|
|
*
|
|
* If type == "process":
|
|
* - id:
|
|
* {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 = async function targetFromURL(url) {
|
|
const client = await clientFromURL(url);
|
|
await client.connect();
|
|
|
|
const params = url.searchParams;
|
|
const type = params.get("type");
|
|
if (!type) {
|
|
throw new Error("targetFromURL, missing type parameter");
|
|
}
|
|
let id = params.get("id");
|
|
// Allows to spawn a chrome enabled target for any context
|
|
// (handy to debug chrome stuff in a content process)
|
|
let chrome = params.has("chrome");
|
|
|
|
let form, isBrowsingContext;
|
|
if (type === "tab") {
|
|
// Fetch target for a remote tab
|
|
id = parseInt(id, 10);
|
|
if (isNaN(id)) {
|
|
throw new Error(`targetFromURL, wrong tab id '${id}', should be a number`);
|
|
}
|
|
try {
|
|
const response = await client.getTab({ outerWindowID: id });
|
|
form = response.tab;
|
|
} catch (ex) {
|
|
if (ex.error == "noTab") {
|
|
throw new Error(`targetFromURL, tab with outerWindowID '${id}' doesn't exist`);
|
|
}
|
|
throw ex;
|
|
}
|
|
} else if (type == "process") {
|
|
// Fetch target for a remote chrome actor
|
|
DebuggerServer.allowChromeProcess = true;
|
|
try {
|
|
id = parseInt(id, 10);
|
|
if (isNaN(id)) {
|
|
id = 0;
|
|
}
|
|
const response = await client.getProcess(id);
|
|
form = response.form;
|
|
chrome = true;
|
|
if (id != 0) {
|
|
// Content processes are not exposing browsing context target actors with the full
|
|
// set of target-scoped actors we would get from a browser tab. Instead, they only
|
|
// support debugger and console.
|
|
isBrowsingContext = 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");
|
|
}
|
|
const response = await 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, isBrowsingContext });
|
|
};
|
|
|
|
/**
|
|
* Create a DebuggerClient 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 instead of regular TCP connection.
|
|
*
|
|
* @param {URL} url
|
|
* The url to fetch query params from.
|
|
* @return a promise that resolves a DebuggerClient object
|
|
*/
|
|
async function clientFromURL(url) {
|
|
const params = url.searchParams;
|
|
const host = params.get("host");
|
|
const port = params.get("port");
|
|
const webSocket = !!params.get("ws");
|
|
|
|
let transport;
|
|
if (port) {
|
|
transport = await DebuggerClient.socketConnect({ host, port, webSocket });
|
|
} else {
|
|
// Setup a server if we don't have one already running
|
|
DebuggerServer.init();
|
|
DebuggerServer.registerAllActors();
|
|
transport = DebuggerServer.connectPipe();
|
|
}
|
|
return new DebuggerClient(transport);
|
|
}
|
|
|
|
exports.clientFromURL = clientFromURL;
|