jsSlime - An emacs toolkit for developing and debugging in-browser javascript code
Emacs Lisp
Latest commit 4174925 May 8, 2013 @segv Execute the defvar jss-debugger-object-group-count form at eval time …
…as well (not just compile load times)
Failed to load latest commit information.
.gitignore Added .gitignore (*.elc and *~ files) Apr 30, 2013
README.org Update firefox status in README Mar 19, 2013
TODO.org Reorder TODO items based on how easy/hard/useful/useless they are; Ad… Mar 17, 2013
jss-browser-api.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss-browser-firefox.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss-browser-webkit.el Execute the defvar jss-debugger-object-group-count form at eval time … May 8, 2013
jss-browser.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss-console.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss-debugger.el Large refactoring so that the melpa build runs without (too many) war… Apr 30, 2013
jss-deferred.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss-http-repl.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss-io-pretty-printers.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss-io.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss-prompt.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss-remote-value.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss-script.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss-super-mode.el Large refactoring so that the melpa build runs without (too many) war… Apr 30, 2013
jss-utils.el Cleaup up (require 'cl) forms and function names so that emacs will w… May 1, 2013
jss.el Fixup comments in jss.el so the generated readme doesn't have confusi… May 1, 2013

README.org

jsSlime - An emacs interface to webkit and mozilla debuggers

jsSlime (jss for short) is designed for emacs users who program web based javascript applications.

Salient Features

  1. 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.
  2. Has debugger buffers with exceptions and per call-frame code evaluation and source code navigation.
  3. Implements ‘resume points’ to automatically skip exceptions in code we don’t control or aren’t interested in debugging.
  4. Quickly see the raw http request/response headers sent over the network.
  5. Customizable pretty printing of server responses (currently has syntax highlighting for html, css and js, and parsing/reindenting of json data)
  6. HTTP repl mode for testing and debugging ajax apis.
  7. Since its emacs the debugger and your editing environment are the same.

Installation

Requirements

  1. 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).
  2. js2-mode - (not strictly required, but strongly recomended) Required for the prompt’s syntax checker, and is the default mode for js script buffers.
  3. emacs-websocket - Required for the webkit protocol (but not firefox):

Browser Setup

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).

WebKit (Chromium (Google Chrome), Safari, Konqueror)

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

Mozilla (firefox)

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.

  1. 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.

  2. Startup the debugger server

    Once firefox has started up go to Tools/Web Developer/Scratchpad, then choose the menu option Environment/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.

Connecting

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.

Usage

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.

General UI Notes

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”)

The Tools

Note: See the manual for more details.

  1. the console - a live (constantly updated) buffer showing network io, log messages, exceptions, etc.
  2. the debugger - a buffer for inspecting and working with exceptions. will pop-up automatically whenever the browser encounters an exception.
  3. 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.
  4. 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.
  5. 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.

Browser Specific Notes

Tab Listing on Webkit

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.

Hacking

  1. Contributors
  2. Report a bug
  3. Submit a patch

For a list of things that are todo, see TODO.org.