This was a research and development project for Atlassian Fedex Day 8. It is not currently shipping in any release and the source code is not available. |
A few years ago, I was a frequent computer game player. One of the neatest features of some computer games was an in-built console, launched from anywhere within the game by hitting the tilde ('~') character. For this Fedex day, I thought I'd add similar functionality to Confluence, including the godmode command that was a necessity for me to win any of the games.
There's no audio on my screencast because Jing doesn't support post-production of audio yet. Instead, you can read the narrative notes below while watching.
Technical notes on the implementation are included below the narration.
Launching and commands
You hit '~' to launch the console. It drops down from the top of the screen on any page in Confluence. Hit '~' to hide it again.
Typing 'help' gives you a list of functions available. I type 'help search' to find out how to use the search command.
Searching
Typing 'search octagon' gives you a list of numbered search results for the word 'octagon'.
You can enter the number of one of the search results to go there. In this case, I'll type '5' to go directly to the fifth search result.
Just go
Okay, the page has loaded. But why bother searching, if you know exactly what you are looking for? To go directly to the first hit of a search, just type 'go' followed by what you want to see.
I type 'go gallery' to go to the top hit for gallery. In this case, it's the Thumbnail gallery page.
You can also use 'go SPACEKEY' to go to a space, or 'go dashboard' to go to the dashboard.
Console features
Just like a Unix terminal, the console has a full history, accessible with the cursor keys. The history is persisted on the server, so it lasts across page reloads and even if you go to another computer.
You can type history to see the previous commands you've typed. You can clear the history with 'clear'.
The console is a fixed pane at the top of your viewport, and you can scroll the page up and down underneath.
All built on RPC
The functionality provided with commands is actually built on the Confluence remote API. The Javascript console creates an XML-RPC message, sends it to the server, converts the response back into Javascript objects and handles it.
The actual commands in the terminal, 'search', 'go', 'home', etc., were written in just a few minutes, using the powerful underlying RPC functionality. The server-side history persistence is also implemented with an RPC interface on the server provided by the console plugin.
To demonstrate the RPC functionality, I use the 'rpc' command to pull down the page 'index' in the 'ds' space. You could just as easily run any command in the Confluence remote API, even commands such as 'removeSpace' or 'removeUser'.
<end of presentation>
Technical details
Several people have asked me about the implementation, so I thought I'd give a brief coverage of the technical details.
The terminal itself is built from a text input (the command line), and an ordered list. Both of these are wrapped in a container, and the container is positioned at the bottom of the console drop-down pane. You can see this a bit better in the following two screenshots:

Command line is an input

History and command line are positioned at the bottom of the pane
The transparency and backgrounds are done with normal CSS properties, and the hide/show animation changes the 'top' CSS attribute of the panel and decreases the opacity.
The '~' trigger is done by attaching a keypress event handler to the document (not the body, which doesn't work in Safari!), and there is also a keypress handler on the text input to process the commands when the user hits return.
The Confluence RPC interface was already available but hooking into from JavaScript took some effort. First, I had to change the RPC authenticator to allow the normal web-based login method. Currently, it only accepts a token authentication which isn't very useful from the front end. (I'm not sure of the reason for not accepting cookies and sessions as valid authentication for RPC methods, or of the consequences of enabling it. This is probably the most significant barrier to implementation.)
To send the commands to the server, I found an existing library on the web that generated them. I wrote the required AJAX POST calls with JQuery. To parse the response from the server, though, I couldn't find any helpful JS libraries. Instead, I wrote an XML-RPC parser in JS to parse the responses into native JS objects. The parser handles string and numeric basic types as well as arrays and structs (maps). It uses JQuery for DOM access to the response XML.
Future
The console is written primarily as a plugin, with only two core changes:
- adding an '#include' of console to the main decorator so it appears on (almost) every page
- modifying the RPC authentication process to accept requests from clients with an existing cookie or session.
The former could be fixed by allowing plugins to add some content to a place on every page. The latter could be simply be changed, although it might need some thought put into whether there are any security ramifications.
There's very little restriction on what functionality could be provided by this console, especially given the huge variety of functionality available from the Confluence remote API. JavaScript's string handling abilities mean that the entire console JS is just over 200 lines. And that includes a lot of really simple command-line 'if' statements and several lines of the online help.
Extending the console further as a terminal emulator would be quite fun, I think. In particular, the addition of variables, JS object handling and command chaining would be useful.

1 Comment
Hide/Show CommentsJul 01, 2008
huasoon
Cool. It's definitely very fun to have this for geeks