Last week, I met with Aryeh Gregor (the editor of the HTML Editing APIs specification, among other specs), Ryosuke Niwa and Annie Sullivan (both of WebKit editing fame) and Jonas Sicking (prolific Gecko hacker) to discuss the future of HTML editing APIs on the web, and also exchange ideas on how Gecko and WebKit handle editing. The meetings were extremely productive, and we managed to discuss a lot of stuff. I’m trying to provide a summary of everything we discussed. You can see the meeting agenda and minutes for more information.
HTML Editing Specification
We all agreed that Aryeh has been doing a great job in specifying how web browsers should behave in response to editing APIs. The current situation is less than ideal. Currently, every browser engine behaves differently when those APIs are invoked, and because of the complexity of handling editing commands, in a lot of situations, no browser engine gets it right. Aryeh has been doing black-box testing on how browser engines behave, and he’s been designing generic algorithms which behave sanely. Gecko and WebKit are planning to gradually move towards implementing the newly specified behavior for these APIs. This can be tricky in some cases where modifying the engine’s behvior would break web compatibility, but we are planning to try to handle the safer cases first and watch closely for web content which make the wrong assumption about how things are supposed to behave.
The spec itself is not finished yet, but it’s generally in a good shape. We discussed some future improvements to the spec, and we’ll reiterate on the spec to improve it even more as we move ahead.
Mutation Events Replacement, and New Editing Events
Mutation events in their current form behave very badly. They are usually a reason for bad performance, and they are extremely painful to handle correctly, so they are always responsible for a lot of the stability problems that we face in Gecko (and I’m sure other browser engines have been experiencing the same types of problems). Jonas has proposed a replacement for these events. There has been lots of feedback on the proposal, and it’s not yet in a final form, but the discussions seem to be proceeding quite well.
Traditionally one of the reasons that people have needed mutation events have been modifying how browsers handle editing commands. We discussed a possible better alternative for this use case. We could provide two new events, the beforeeditaction and aftereditaction events (note that I’m just using these names as placeholders for better names that we will hopefully think of in the future!). The beforeeditaction event would fire before the browser initiates handling of an editing command. It would be cancelable, so that web applications which do not want certain commands enabled can just cancel the respective events. The aftereditaction event would fire when the browser is done performing the editing action. This event will provide semantic information about the editing operation performed, and will allow web content to alter the DOM generated as a result of the editing action. Think of a web application which wants to use strong tags instead of b tags for bold text generated by the bold command. With aftereditaction, the web application can just fix up the DOM after the browser has modified it to use strong tags.
This idea can even be taken one step further. The browser can fire beforeeditaction and aftereditaction events even for commands which it does not support natively. Handling these events will give web applications a new way of providing custom editing commands! The more we talked about these two events, the more we thought that they are going to be useful!
Ryosuke has been working on the UndoManager specification. It is a new interface which allows web applications to hook into browser’s native undo/redo transaction manager. It is an awesome way to enable web applications to put custom transactions into the browser’s undo/redo stack, and also enable undo/redo for a host of new applications on the web (think of having undo/redo working for a drawing tool built on top of the HTML5 canvas, for example!). We discussed some of the details of the spec, and managed to agree on everything that we discussed.
The good news here is that this is something which is going to come to a browser engine near you really soon! William Chen, an awesome intern at Mozilla is working on implementing it for Gecko, and Ryosuke told me that he’s planning to implement it for WebKit too once he finishes some of the refactoring that needs to be done before this can happen.
We talked about the Selection specification, which is currently part of the DOM Range specification. We agreed that we need a way for web developers to create new selection objects, with the hope that some day we would allow editing commands to operate on parts of the web page that are not visually selected by the user. The selection story is really complicated for Gecko, because we allow multi-range selections, but we fail to handle them correctly everywhere, especially in the case of editable content. I have some plans to address this problem, but those plans probably deserve their own blog/mailing-list post.
Collaborative editing seems to be one of the topics which is currently hot among web developers. Think of web applications like Etherpad which allow several users to edit the same document at the same time. Annie gave us an overview of some of the challenges in developing collaborative editing applications. We then discussed some of the ideas which might make the lives of people developing such applications easier. These ideas included the beforeeditaction and aftereditaction events, an event to fire when the selection changes in a document, and adding a helper method to change the tag for an element in the DOM (which is now being discussed here).
We discussed possible ways to provide clipboard access to web applications. Opera has proposed a Clipboard API specification, which seems like a good starting point. We talked about some of the security implications of allowing web pages to put data on the clipboard (which might be an annoyance, or worse, if the web page puts code to run a malicious command on the terminal hoping that the user would paste it in the terminal), and read data from the clipboard (the possibility of reading important data related to the user from the clipboard). WebKit currently fires the clipboard events for user initiated copy/paste operations, providing access to the clipboard contents to the web application. We would want to support this in Gecko too. But the general problem of how to handle the security implications is mostly a UX issue, and we decided to ask our UX teams for feedback on this.
We also discussed how we could prevent potentially bad content from being pasted into an editable area. One notable example is absolutely positioned elements. There is no good way for us to determine what styles would apply to an element before the actual pasted document fragment gets injected into the target page’s DOM. We concluded that allowing authors to handle this case in their aftereditaction handlers might be the best approach here.
We also spent some time describing the Gecko and WebKit implementation of contentEditable, and tried to get familiar with some of the upsides and downsides of each implementation. One of the interesting things that was discussed here was the possibility of borrowing tests from each other. It seems like WebKit should at least be able to borrow a subset of the crashtests and reftests from Gecko. Borrowing WebKit tests for Gecko might be a bit trickier, since WebKit’s LayoutTests depend on WebKit’s internals. But we all agreed that it would be a very good idea for us to adopt cross-browser unit tests.
We also took some time to go over some future ideas.
IME APIs for the web
Keyboard events interoperability
Currently, there are some interoperability problems with keyboard events. One such category of problems align with the differences between the modifier keys on Mac and Windows/Linux platforms. Another source is some browsers not sending the correct keyCode and charCode in the keyboard events for some keyboard layouts. Determining what needs to be done in all of these cases is tricky, but this was not the area of expertise of any of us.
We might be able to leverage the accessKeyLabel property to inform the web pages about the default keyboard accelerator modifier key on the platform on which the browser runs (but there are some privacy concerns with exposing this information). We agreed that we need a platform independent way to defining shortcut keys, in order to not require authors to handle low level keyboard events to implement keyboard shortcuts. We might be able to use the accesskey attribute on command elements for this purpose. We also would need a way to assign a command element to a certain contentEditable element. We might be able to use the for attribute on the command elements to point to the ID of a contentEditable element. Also, we thought that we should handle the well-known keyboard shortcuts for operations such as undo, redo, select all, bold, italicize, underline, cut, copy and paste automatically.
Spell checking APIs
Exposing editing algorithms to web content
It might be a good idea for us to expose some of the base editing algorithms to web application authors so that they can use them in their own applications. We all agreed that we should probably wait for the editing spec to stabilize a bit before we go ahead and consider exposing some of the base algorithms. We also need feedback from web developers on what kinds of algorithms they would find useful to have access to.
Currently, browser engines do not behave in a consistent way when navigating through editable regions using the keyboard. We need to specify how browsers should move the caret when the user initiates moving commands using the keyboard. While some of this behavior might be platform dependent, we would really prefer the keyboard navigation to work similarly across different platforms, if possible.
Resizing and table editing UI
One of the things that people really want is resizing and table editing UI. Gecko tries to provide this UI, but the existing UI is buggy and may not be the ideal one. WebKit currently doesn’t provide any UI for this, at all. For resizing, we’re currently thinking of using the CSS resize property. Table editing UI is not going to be that easy though, and we agreed that we should discuss that in the future.
Overall, I’m really excited about the direction we’re heading towards in the world of editing on the web. There seems to be a lot of interest in both Gecko and WebKit to try to improve the current situation, and I do hope that in the future we would be able to have this discussion with other browser vendors too.