Modules (188)



Inspector manages the connection to Chrome/Chromium's remote debugger. See inspector.html for the documentation of the remote debugger.


To enable remote debugging in Chrome or Chromium open either application with the following parameters:

--enable-remote-debugger --remote-debugging-port=9222

This will open an HTTP server on the specified port, which can be used to browse the available remote debugger sessions. In general, every open browser tab can host an individual remote debugger session. The available interfaces can be exported by requesting:

The response is a JSON-formatted array that specifies all available remote debugger sessions including the remote debugging web sockets.

Inspector can connect directly to a web socket via connect(socketURL), or it can find the web socket that corresponds to the tab at the given URL and connect to it via connectToURL(url). The later returns a promise. To disconnect use disconnect().


Inspector dispatches several connectivity-related events + all remote debugger events (see below). Event handlers are attached via on(event, function) and detached via off(event, function).

connect Inspector did successfully connect to the remote debugger disconnect Inspector did disconnect from the remote debugger error Inspector encountered an error message Inspector received a message from the remote debugger - this provides a low-level entry point to remote debugger events


Commands are executed by calling {Domain}.{Command}() with the parameters specified in the order of the remote debugger documentation. These command functions are generated automatically at runtime from Inspector.json. The actual implementation of these functions is found in _send(method, signature, varargs), which verifies, serializes, and transmits the command to the remote debugger. If the last parameter of any command function call is a function, it will be used as the callback.


Debugger events are dispatched as regular events using {Domain}.{Event} as the event name. The handler function will be called with a single parameter that stores all returned values as an object.





Map message IDs to the callback function and original JSON message

Object.<number, {callback: function, message: Object}
    var _messageCallbacks = {};

    var _messageId = 1,     // id used for remote method calls, auto-incrementing
        _socket,            // remote debugger WebSocket
        _connectDeferred,   // The deferred connect
        _userAgent = "";    // user agent string




WebSocket did open

    function _onConnect() {
        if (_connectDeferred) {
            _connectDeferred = null;


WebSocket did close

    function _onDisconnect() {
        _socket = undefined;


WebSocket reported an error

    function _onError(error) {
        if (_connectDeferred) {
            _connectDeferred = null;
        exports.trigger("error", error);


Received message from the WebSocket A message can be one of three things:

  1. an error -> report it
  2. the response to a previous command -> run the stored callback
  3. an event -> trigger an event handler method
message object
    function _onMessage(message) {
        var response    = JSON.parse(,
            msgRecord   = _messageCallbacks[],
            callback    = msgRecord && msgRecord.callback,
            msgText     = (msgRecord && msgRecord.message) || "No message";

        if (msgRecord) {
            // Messages with an ID are a response to a command, fire callback
            callback(response.result, response.error);
            delete _messageCallbacks[];
        } else if (response.method) {
            // Messages with a method are an event, trigger event handlers
            var domainAndMethod = response.method.split("."),
                domain = domainAndMethod[0],
                method = domainAndMethod[1];

            EventDispatcher.triggerWithArray(exports[domain], method, response.params);

        // Always fire event handlers for all messages/errors
        exports.trigger("message", response);

        if (response.error) {
            exports.trigger("error", response.error, msgText);


Send a message to the remote debugger All passed arguments after the signature are passed on as parameters. If the last argument is a function, it is used as the callback function.

remote string
the object
method signature
    function _send(method, signature, varargs) {
        if (!_socket) {
            console.log("You must connect to the WebSocket before sending messages.");

            // FUTURE: Our current implementation closes and re-opens an inspector connection whenever
            // a new HTML file is selected. If done quickly enough, pending requests from the previous
            // connection could come in before the new socket connection is established. For now we
            // simply ignore this condition.
            // This race condition will go away once we support multiple inspector connections and turn
            // off auto re-opening when a new HTML file is selected.
            return (new $.Deferred()).reject().promise();

        var id, callback, args, i, params = {}, promise, msg;

        // extract the parameters, the callback function, and the message id
        args =, 2);
        if (typeof args[args.length - 1] === "function") {
            callback = args.pop();
        } else {
            var deferred = new $.Deferred();
            promise = deferred.promise();
            callback = function (result, error) {
                if (error) {
                } else {

        id = _messageId++;

        // verify the parameters against the method signature
        // this also constructs the params object of type {name -> value}
        if (signature) {
            for (i in signature) {
                if (_verifySignature(args[i], signature[i])) {
                    params[signature[i].name] = args[i];

        // Store message callback and send message
        msg = { method: method, id: id, params: params };
        _messageCallbacks[id] = { callback: callback, message: msg };

        return promise;


Check a parameter value against the given signature This only checks for optional parameters, not types Type checking is complex because of $ref and done on the remote end anyways

    function _verifySignature(signature, value) {
        if (value === undefined) {
            console.assert(signature.optional === true, "Missing argument: " +;
        return true;
Public API


Connect to the remote debugger WebSocket at the given URL. Clients must listen for the connect event.

WebSocket string
    function connect(socketURL) {
        disconnect().done(function () {
            _socket = new WebSocket(socketURL);
            _socket.onmessage = _onMessage;
            _socket.onopen = _onConnect;
            _socket.onclose = _onDisconnect;
            _socket.onerror = _onError;
Public API


Connect to the remote debugger of the page that is at the given URL

url string
    function connectToURL(url) {
        if (_connectDeferred) {
            // reject an existing connection attempt
        var deferred = new $.Deferred();
        _connectDeferred = deferred;
        var promise = getDebuggableWindows();
        promise.done(function onGetAvailableSockets(response) {
            var i, page;
            for (i in response) {
                page = response[i];
                if (page.webSocketDebuggerUrl && page.url.indexOf(url) === 0) {
                    // _connectDeferred may be resolved by onConnect or rejected by onError
            deferred.reject(FileError.ERR_NOT_FOUND); // Reject with a "not found" error
        }); onFail(err) {
        return deferred.promise();
Public API


Check if the inspector is connected

    function connected() {
        return _socket !== undefined && _socket.readyState === WebSocket.OPEN;
Public API


Disconnect from the remote debugger WebSocket

Returns: jQuery.Promise
Promise that is resolved immediately if not currently connected or asynchronously when the socket is closed.
    function disconnect() {
        var deferred = new $.Deferred(),
            promise = deferred.promise();

        if (_socket && (_socket.readyState === WebSocket.OPEN)) {
            _socket.onclose = function () {
                // trigger disconnect event


            promise = Async.withTimeout(promise, 5000);

        } else {
            if (_socket) {
                delete _socket.onmessage;
                delete _socket.onopen;
                delete _socket.onclose;
                delete _socket.onerror;

                _socket = undefined;


        return promise;
Public API


Get a list of the available windows/tabs/extensions that are remote-debuggable

host string
IP or name
debugger integer
    function getDebuggableWindows(host, port) {
        if (!host) {
            host = "";
        if (!port) {
            port = 9222;
        var def = new $.Deferred();
        var request = new XMLHttpRequest();"GET", "http://" + host + ":" + port + "/json");
        request.onload = function onLoad() {
            var sockets = JSON.parse(request.response);
        request.onerror = function onError() {


        return def.promise();
Public API


Get user agent string

Returns: string
    function getUserAgent() {
        return _userAgent;
Public API


Initialize the Inspector Read the Inspector.json configuration and define the command objects -> Inspector.domain.command()

    function init(theConfig) {
        exports.config = theConfig;

        var InspectorText = require("text!LiveDevelopment/Inspector/Inspector.json"),
            InspectorJSON = JSON.parse(InspectorText);

        var i, j, domain, command;
        for (i in {
            domain =[i];
            var exportedDomain = {};
            exports[domain.domain] = exportedDomain;
            for (j in domain.commands) {
                command = domain.commands[j];
                exportedDomain[] = _send.bind(undefined, domain.domain + "." +, command.parameters);


    // Export public functions
    exports.connect              = connect;
    exports.connected            = connected;
    exports.connectToURL         = connectToURL;
    exports.disconnect           = disconnect;
    exports.getDebuggableWindows = getDebuggableWindows;
    exports.getUserAgent         = getUserAgent;
    exports.init                 = init;
    exports.send                 = send;
    exports.setUserAgent         = setUserAgent;
Public API


Manually send a message to the remote debugger All passed arguments after the command are passed on as parameters. If the last argument is a function, it is used as the callback function.

domain string
command string
    function send(domain, command, varargs) {
        return _send(domain + "." + command, null, varargs);
Public API


Set user agent string

userAgent string
User agent string returned from Chrome
    function setUserAgent(userAgent) {
        _userAgent = userAgent;