I have an idea for a web application for which I would require full control over the functionality of the embedded text editors and the text editors must function exactly the same across all browsers. The standard contenteditable
functionality is not sufficient to my needs on this occasion.
So I have been experimenting with various ways to implement a custom text editor. My first approach was to detect mouse clicks for caret insertion (though with no visible caret since there doesn't appear to be a way to achieve this). This worked rather well, but unfortunately there was no way to display the caret (aka flashing I-beam).
This means that my flashing caret must also be custom made. I can only think of two good ways to achieve this in a way which will be compatible across all browsers.
The first (and probably better) option would be to implement a custom layout engine in JavaScript much like Google have done with Google Docs.
The second solution (probably a lot easier) would be to encapsulate each character within its own <span>
element and thus allowing the faux caret to be placed between specific characters. This does mean that there will be a LOT of span elements, but this would certainly achieve what I need whilst taking advantage of the browser layout engine. Another benefit with this approach is that I do not need to rely upon dodgy browser-specific text selection hacks.
So my question, is option #2 a really bad idea? If so, why?
First of all - do you really need to work on your own editor? There are Firepad and Etherpad with their pretty cool collaborative editing and perhaps more open source editors not based on contenteditable
. It's really hard to create such editor, so it does not make sense to waste time on it.
However, if you really want to work on your own solution and you need exactly the same behaviour across all browsers, then you're doomed ;). Even if you'll avoid contenteditable
there are definitely other things that can go wrong.
Anyway, the answer:
First option is very hard and time consuming at the beginning but it gives you a lot more power than the second one. E.g. having completely custom layout engine, you'll be able to implement page breaks without waiting for the CSS3's implementation (on which you will never could rely on, because you want exactly the same behaviour across all browsers). And in fact, you'll be able to bypass most of browsers' rendering differences. But, unless you've got a team of decent JS devs and few months (at least), I wouldn't even start thinking about that.
The second solution - reusing DOM is more realistic. I would perform some performance tests first, but having span per character would be easy to find out where the caret should be placed after mouse click. Without that it requires some trick... Which I don't know. You can try to check how Etherpad and Firepad (which uses Ace code editor) deal with that, but still - wrapping will be the easiest choice and at least on decent browsers it should not cause performance issues, unless you want to edit really long documents (but then you can start some optimizations).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With