The server makes use of the HApps
web development library. It will be ported to the better maintained HAppStack
library, but this has no high priority, since only little functionality is needed from the library.
After some initialization, a
server is started in the function
. At the top level a number of handlers take care of serving the main page of the editor (
), several images, and the xml representation of the document for downloading. Any other commands from the client are passed to the
. (Uploading changes the document and therefore needs to be handled inside an editing session.)
handles all events that are specific to a user's editing session. Because Proxima does not support multi-user editing yet, the session handler only allows one user at a time to edit the document, while providing other users with a view-only presentation that is updated automatically to reveal changes. To identify edit sessions, a session id is stored in a cookie on each browser that accesses the editor.
For the first user to access the editor, a primary editing session is created, in which the document is editable. For each user that accesses the editor when a primary session already exists, a secondary editing session is created, which does not allow editing. Each secondary editing session is updated every 5 seconds to show changes made by the primary editing user.
If the primary session is idle for 60 seconds, it expires and turns into an inactive editing session. The oldest secondary editing session will then become the primary editing session. If there are no secondary sessions, an inactive editing session turns into a primary editing session again when the user resumes editing. Otherwise it becomes a secondary editing session.
The session handler makes use of a mutex to ensure only one thread is evaluating, because Proxima is not yet thread safe. If a thread obtains the mutex, it passes control to the handlers declared in
An editing session
commands are handled. The
command initializes Proxima with the XML document that is posted together with the command, after which the client takes care of refreshing the rendering. The
command causes the
function to be called with the arguments in the URL (i.e. a unique id for the request together with the command string) passed as arguments. The request id is passed back to the client in the response, for debugging purposes.
function monadically maps handleCommand on each of the commands in the list to obtain a list of HTML updates. If processing the commanda created any font queries (currently passed stored a bit hacky in a file), instead of the updates, a font query is sent to the client. Otherwise, the HTML updates are sent, together with an HTML rendering of the focus.
To support incremental rendering updates, the arrangement level in Proxima must correspond to the rendering shown by the client. However, when multiple clients are present, Proxima would need to keep track of multiple arrangements as well, which is currently unsupported. A fix for this is that incremental updates are only supported for subsequent edit operations from the same session. When an edit operation from a different session needs to be handled, a fresh arrangement is computed, which leads to a loss of incrementality. However, since there is no multi-user editing yet, only one session is expected to yield frequent edit operations. The other sessions merely send a refresh every 5 seconds.
has a case for each constructor of the
datatype, and calls the Proxima engine to compute the HTML updates.
Keyboard and Mouse events
Keyboard and mouse events are simply translated to Proxima edit operations and fed into the
. The returned HTML is sent back to the client.
When the client sends a
to first parse the presentation, and then computes the context menu item labels and associated edit commands using the
function in the rendering level. The labels are returned to the client in HTML, and the updates are stored in the IORef
When the user selects an item from the context menu, the server receives a
command that contains the selected item's index. With this index, the appropriate update is taken from
and passed to
to compute the rendering updates.
Font queries and metrics
Because the way fonts are rendered depends on user's browser and platform, the server cannot compute the font metrics locally. Therefore, font metrics are requested from the client. If font information turns out to be missing during presentation, the server does not send an updated presentation to the client, but rather a metrics-query command. The client responds with the queried metrics, which are put in the font-metrics table, after which the presentation is computed again and sent to the client.
- 25 Feb 2010