Infrequently Noted

Alex Russell on browsers, standards, and the process of progress.

On Browser WYSIWYG

The state of in-browser WYSIWYG is somewhere between pitiful and mind-numbingly painful. Opera and Safari have pulled themselves up by the bootstraps and soon all the major browsers will be at the same level of awful, more or less. This area of DHTML doesn't get much love from browser vendors in part because only the heartiest souls ever venture into these deep, shark-infested waters so there aren't many people clamoring for fixes to the underlying capabilities. Everyone sane just picks up the Dojo Editor, TinyMCE, or one of the other good editing packages that are available.

Since recently delving back into the Dojo editor for the 0.9 release I've been chewing on the problem some more, and I think the solution is fairly simple in terms of the APIs which toolkit authors should expect of browser vendors. The goals of editing generally boil down to:

The current contentEditable/designMode systems fail in the undo case because (particularly on IE) it's not possible to denote what is and isn't an "action" that the user is doing, nor can you be informed by the browser when it pickles off a new state to the undo stack. This means that the undo stack captures things which aren't changes in your editing area and may appear to be "broken" by UI feedback that you provide to users in other ways.

Further, the existing system's dependence on pseudo-magical "commands" makes nearly zero sense. Every editing component worth its salt today has to build its own ways of executing DOM manipulation and then rolling back from change sets. Browsers half-coddle editing system authors when it would be better if they just got out of the way and gave us APIs which are suited to the "build the entire UI in javascript" path which everyone already takes anyway.

Since it's not really reasonable to expect that browsers will remove contentEditable, here are my proposed APi additions to it which would allow any sane editing UI to ditch the entire command structure which can slowly fade into the background over time.

These APIs added to elements with contentEditable set will allow us to use regular-old DOM methods of manipulating user selections and adding complex content from user input without fighting for control of the undo stack or inventing our own (which has so many problems that I don't want to begin to address them). Additionally, this method of manipulation will allow toolkit authors to deliver editors which operate on the semantics of the markup more easily.

Note that we suppose the current uneven level of Range and DOM APIs will persist over time, and some things may get easier over time in conjunction with these APIs as those problems are slowly alleviated. Additionally, interaction with the global undo stack for the browser is as-yet unspecified. I'm inclined to suggest that unless the editable element has focus, undo should not affect it but my unfamiliarity with the implementation of the global undo stacks in browsers may nix that and require a broader solution. There may also need to be methods for ignoring a particular set of DOM operations (say, from event handlers) to prevent browsers from taking snapshots at bad times, but I think we can ignore that for now.

Lastly, there is probably room for an API to register interest in any undo operation and to push things onto the browser's undo stack for non-editing elements, but this API solves the problem where it is most accute today.