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
- Valence and WebIDE
- Why an add-on?
- Available targets
- But how does it work?
- Actors studio
- Future plans
- 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
Thank You
- Questions, feedback:
- Homework: