Debugging web apps on any device

Panos Astithas / @pastith

About me

  • Member of the Firefox Developer Tools team
  • Worked on the JS debugger, console, scratchpad, profiler and more
  • Lately focusing on Valence
  • Worked with JavaScript, Java, C/C++, Perl and more in 15+ yrs (seen lots of tools)

Agenda

  1. Valence and WebIDE
  2. Why an add-on?
  3. Available targets
  4. But how does it work?
  5. Actors studio
  6. Future plans
  7. Q & A

Valence and WebIDE

  • "The Web is the platform"
  • The cure for platform fragmentation
  • Develop, Debug & Deploy with WebIDE
    • Create, package, deploy, debug remotely
    • Familiar environment
    • Lightweight, free
  • Use one tool to debug ALL THE THINGS
  • Not a mandatory workflow at all

Available targets

  • Everything Firefox
    • Firefox Desktop
    • Firefox on Android
    • FirefoxOS
    • Firefox embeddings
  • Chrome Desktop
  • Chrome on Android
  • Safari on iOS

Why an add-on?

  • External dependencies
  • Rapid iteration
  • Easier for contributors
  • Minimize devtools footprint

But how does it work?

  • Extends the Firefox Debugger Server
  • Actor adapter for external backends
  • Speaks the WebKit/Blink remote debugging protocol
  • Async ALL THE THINGS
  • ES6 Promises & Generators
  • Includes ios-webkit-debug-proxy

Firefox actor


  onEvaluateJS: function (aRequest)
  {
    let input = aRequest.text;
    let timestamp = Date.now();

    let evalOptions = { ... };

    let evalInfo = this.evalWithDebugger(input, evalOptions);
    let evalResult = ...;
    let helperResult = ...;

    let result, errorMessage, errorGrip = null;
    if (evalResult) {
      if ("return" in evalResult) {
        result = evalResult.return;
      }
      else if ("yield" in evalResult) {
        result = evalResult.yield;
      }
      else if ("throw" in evalResult) {
        let error = evalResult.throw;
        errorGrip = this.createValueGrip(error);
        let errorToString = evalInfo.window.evalInGlobalWithBindings(...);
        if (errorToString && typeof errorToString.return == "string") {
          errorMessage = ...;
        }
      }
    }

    return { ... };
  },
						

Chrome/Safari actor


  evaluateJS: asyncMethod(function*(expression) {
    let response = yield this.rpc.request("Runtime.evaluate", {
      expression: expression,
      includeCommandLineAPI: true,
    });

    yield preview.loadPreview(this.rpc, response.result);

    let result, exception = null, exceptionMessage;
    if (response.wasThrown) {
      result = { type: "undefined" };
      exceptionMessage = response.result.description;
      exception = response.result;
      if (response.exceptionDetails) {
        exception.preview.fileName = ...;
        exception.preview.lineNumber = ...;
        exception.preview.columnNumber = ...;
      }
    } else {
      result = response.result;
    }

    return { ... }
  }),
						

Future plans

  • Better support for developing web sites
  • Debug embedded WebViews
  • Debug Firefox for iOS
  • Debug node.js apps
  • Crazy stuff

Demo - Q & A

WebIDE, Valence, Chrome

Thank You