jsSlime (jss for short) is designed for emacs users who program web based javascript applications.
- Connects directly to your browser. Does not require injecting js into pages nor using some kind of middle man / proxy (well, the browser itself is the middle man or proxy). This means that any page can be debugged without having to change the page itself.
- Has debugger buffers with exceptions and per call-frame code evaluation and source code navigation.
- Implements ‘resume points’ to automatically skip exceptions in code we don’t control or aren’t interested in debugging.
- Quickly see the raw http request/response headers sent over the network.
- Customizable pretty printing of server responses (currently has syntax highlighting for html, css and js, and parsing/reindenting of json data)
- HTTP repl mode for testing and debugging ajax apis.
- Since its emacs the debugger and your editing environment are the same.
- Emacs 24 (emacs 23 probably works as well, but I haven’t tested it and eieio is a big complicated chunk ‘o code which may or may not work the same on emacs23).
- js2-mode - (not strictly required, but strongly recomended) Required for the prompt’s syntax checker, and is the default mode for js script buffers.
- emacs-websocket - Required for the webkit protocol (but not firefox):
jss
needs to be able to communicate, over a network connection, with
the browser. Both webkit and mozilla browsers require special setup
and configuration to make this happen (fwiw: the debugger protocol is
an open socket which gives complete and total control over your
browser, making it too easy to open up is a huge security risk).
Just pass the argument --remote-debugging-port=9222
at startup.
So, for chromium on linux this means:
chromium --remote-debugging-port=9222
and for chrome on macs it’s:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
NB: IN PROGESS. The Firefox protocol is still a work in progress, current we only support connecting to a tab and simple evaluation (no debugger, no network io tracking).
In order to startup the debugger as a network server we have to run some javascript code in the browser, there’s no simple command line argument to do this for us.
- Make sure the following prefs are set:
user_pref("devtools.chrome.enabled", true); user_pref("devtools.debugger.remote-enabled", true);
Do this either by visiting
about:config
or by editing prefs.js in your profile directory, and then restarting firefox. - Startup the debugger server
Once firefox has started up go to
Tools/Web Developer/Scratchpad
, then choose the menu optionEnvironment/Browser
. Either either of these two menus items don’t exist then your prefrences have not been properly set.In the scratchpad window paste the following code snippet:
Components.utils.import("resource://gre/modules/devtools/dbg-server.jsm"); DebuggerServer.init(function () { return true; }); DebuggerServer.addBrowserActors(); DebuggerServer.openListener(6000);
That will start up a new debugger server listening on port
6000
.
Assuming the browser and emacs are running on the same machine just
call jss-connect
and specify the browser type (either webkit
or
firefox
), the host should be 127.0.0.1
and the port is either
9222
or 6000
if you’ve followed the above instructions literally.
If the browser is running on a remote machine you’ll need to create a tunnel from the machine with emacs to the browser (this may not be totally true, but given the totally unencrypted nature of the conneciton, it’s not a bad idea, if you’re attaching to a mobile device, figure it out and let me know…):
ssh -L<port>:127.0.0.1:<port> user@machine_with_browser
Where <port>
is 9222 or 6000 or whatever.
After running M-x jss-connect
and successfully connecting you’ll
have *JSS Browser*
buffer with a list of debuggable tabs. Note that,
since we’re taking over the browser’s debugger, tabs that already have
an inspector or console or whatnot on them can not be debugged via
jss
.
Hit RET
on an open console
link to jump to a console/logger in
that particular tab.
As much as possible jss
tries to have a discoverable UI. Everything
that is not just text, but is hides more data or a button to some
action, uses emacs’ standard button-face
. Hitting TAB
in any jss
buffer wil jump between the available buttons in the buffer. Hitting
RET
on a button wil invoke its primary aciton (which is usually
“show this thing completly” or “jump to the buffer for this thing”),
while SPC
will invoke its secondary action (which is usually “show a
preview of this thing” or “jump to this but in another window and
don’t move point”)
Note: See the manual for more details.
- the console - a live (constantly updated) buffer showing network io, log messages, exceptions, etc.
- the debugger - a buffer for inspecting and working with exceptions. will pop-up automatically whenever the browser encounters an exception.
- the io inspector - viewing requests and response (normal and xhr/ajax ones). whenever the browser sends out a request, or gets a response, and network monitoring is on (the default) a line is sent to the console buffer with the target url. the url is a button which will open up an io inspector.
- the prompt - in consoles, and in the frames of debugger, we have a prompt where we can send javascript to the server and get the results back.
- remote values - often we’ll have to work with, either in the
console as the result of some code or in the debugger, an complex
object whose value lives inside the browser.
jss
will insert buttons, which can be expanded, for this values.
Webkit does not always provide an id for a tab. If a given is not currently being debugged then jss is passed a, globally unique, url where we can connect the debugger; however if a given tab is being debugged (either via jss or in browser) then all we get back in the title and url, neither of which are guaranteed to be unique.
For this reason tabs that are being debugged, either in browser or via jss, do not show up in the browser’s buffer. Suggestion for how to deal with this are welcome.
For a list of things that are todo, see TODO.org.