) keeps track of a HTML rendering tree that represents the rendering of the edited document. The script catches all edit events that occur in the browser (mouse and keyboard) and sends these as commands to the server. The incremental updates that are received from the server are applied to the HTML rendering tree.
sends a command to the server. The syntax of these commands consists of the showed elements of the
datatype declared in
data Command = Metrics ((String,Int,Bool,Bool),(Int,Int,[Int]))
| ContextMenuRequest ((Int,Int),(Int,Int))
| ContextMenuSelect Int
| Key (Int,Modifiers)
| Chr (Int,Modifiers)
| Mouse MouseCommand (Int,Int, Modifiers)
| EditStyle StyleEdit
| Find String
| SetViewedArea CommonTypes.Rectangle
deriving (Show, Read)
data MouseCommand = MouseDown | MouseMove | MouseUp | MouseDragStart | MouseDrop
deriving (Show, Read)
type Modifiers = (Bool,Bool,Bool)
Because edit events may occur in quick succession, the client maintains a queue for edit events (global variable
). When the client is waiting for a server response, any additional events are queued until the result has arrived, after which all queued commands are sent. Communication with the server is performed through an XMLHTTP object, and on a server response, function
updates the status lights and processes the received updates by calling
for each update.
initFont=creates an invisible DIV element with id =font
that contains all characters of the font. The height and widths can be measured from this
element. (Each character is replicated a 1000 times to increase accuracy.) In order to determine the baseline, a single letter is rendered next to an element with height 0. Because the element is aligned at the baseline of the letter, its relative position (which can be queried) is the value for the baseline.
On a font query, the function
applies the queried font and style to the
element and returns the collected metrics, which are sent to the server by function
command with the mouse position and the coordinates of the top-left corner of the screen are sent to the server. The server responds with a list of items that are displayed as a context menu, and when an item is clicked, a
command is sent with the index of the clicked menu item.
The mouse handler (
The mouse handler implements a small finite state machine to handle drag and drop. Its states are:
No button down
Button down, but no drag yet
Drag in progress
Dragging on a non-dragsource, for example when the user extends the selection
The state transitions are straightforward and can be seen in the code. Drag sessions are only started when the element under the cursor has class
. In order to provide an image of the dragged node, a clone is stored in
Network latency may cause a delay between sending the edit event and receiving the update from the server. We tackle this problem by having the client show the predicted effect of an edit operation, until the actual update is obtained from the server.
When a key is entered, = insertCharPredictively= inserts the corresponding character in the HTML rendering tree at the position of the cursor, and the cursor is moved to the right by the width of the character. Furthermore, all right sibling elements in the same row and in parent rows are moved to the right as well, until a parent column is encountered.
Because edit operations are queued if the client is already waiting for a response, we need to keep track of two kinds of predictively inserted characters: characters corresponding to the already sent insert operations (
), and characters corresponding to the currently queued insert operations (
). On arrival of the server response, all predictive inserts are undone with
, to make it possible to apply the received incremental update on the rendering. Subsequently, the queued inserts are sent to the server, and the corresponding predictive updates are performed on the rendering again (by
Because a presentation in Proxima can be complex, it is not always possible to correctly predict the effect of an inserted character. Nevertheless, the algorithm works well for all editors in the quite diverse suite of sample editors, and it provides a massive increase in response time. An area of future research will be to enhance the predictive rendering model for handling cursor movement and navigation, and perhaps extend the presentation language to allow predictive rendering for specialized cases, such as highlighting drop targets during dragging.
- 25 Feb 2010