Home > Uncategorized > Rich Text Editor in the HTML Canvas – Part 1: Introducing CAROTA

Rich Text Editor in the HTML Canvas – Part 1: Introducing CAROTA

I’m developing a rich text editor from scratch in JavaScript, atop the HTML5 canvas. It’s called Carota (Latin for carrot, which sounds like “caret”, and I like carrots).

Here is the demo page, which is very self-explanatory, in that it presents a bunch of information about the editor, inside the editor itself, so you can fiddle with it and instantly see how it persists the text in JSON. As you can see, it’s quite far along. In fact I suspect it is already good enough for every way I currently make use of rich text in browser applications. If your browser is old, it will not work. (Hint: IE8 is way old.)

So… Why? What a crazy waste of time when browsers already have the marvellous contentEditable feature, right?

A quick survey of the state-of-the-art suggests otherwise. Google Docs uses its own text layout and rendering system, only using the DOM as low-level display mechanism (the details on that link are very relevant and interesting). Go to Apple’s iCloud which now has a beta of their Pages word processor, and use your browser to look at how they do it: the text is rendered using absolute, meticulously positioned SVG elements, so they too perform their own layout.

And having tried for the last year to get contentEditable to serve my purposes, in the same way on all browsers (actually, even one browser would be something), I can understand why the Twin Behemoths of the Cloud have taken control of their own text layout. So I’m going to do the same thing, but with Canvas. (My previous plan was to do a plugin for Windows so I’d be able to use the Win32 Rich Edit control, but that kind of plugin is about to die out.)

Before I got as far as drawing any text on screen, I had to be very careful to build up a fundamental model of how flowing text actually works. I wanted to end up with beautiful components that each do something extremely simple, and plug together into a working editor. That way it’s easier to change stuff to meet future needs. I’ve designed it from the ground up to be hacked by other people to do whatever they want.

So, hopefully I’ll be back soon to start describing how it works. In the meantime, fork me on github and you can also get the development set-up via the usual:

npm install carota

For a really quick minimal demo, try this jsfiddle, which just creates an editor in an empty DIV and then uses load and save for persistence.

  1. April 25, 2014 at 9:58 am

    This is awesome.

    I explored the same vision a while ago. My shot was porting the Text Layout Framework from the Flash/Flex (https://github.com/apache/flex-tlf) to JS + HTML5 Canvas. TLF is written in ActionScript 3, which is quite similar to ECMAScript. Turned out that TLF is too closely related to the Flash Player API to be ported successfully to a canvas based renderer, but it is otherwise a great inspiration starting point.

    • earwicker
      April 25, 2014 at 4:58 pm

      Thanks. The major sticking point is my lack of understanding of all the complex rules for Unicode bidirectional text and how UIs work for that. I only know English and never use those UIs.

  2. June 3, 2014 at 9:52 am

    Hi Daniel,

    I just stumbled across your project and it looks great. There aren’t many options for text editors out there, and yours offers something different to the competition. It also happens that your technology stack is the same as mine. So I’m very interested and might start playing with integration soon.

    One concern that strikes me is performance. I tried to copy 18k words of plain text into your demo page, and the performance was unusable. A lot of the code editors out there can handle it – its only 600 lines. I guess they use custom renderers, too (I tried with Orion which only ever renders a single page of content using native HTML).

    I appreciate that Carota is a work in progress and otherwise wouldn’t think much of it, but I’ve also noticed performance problems in Google Docs in pretty small documents (15 pages or so) with heavy formatting. Its worth noting that Docs supports my 18k words (38 pages) without too much trouble, so maybe I’ve experienced a different problem in the past.

    In any case, I can’t help but wonder whether this is an innate Canvas problem – too much content for Canvas to handle efficiently – or whether it’s simply an optimisation problem for Carota. I notice that my 18k words were parsed into a single JSON model object. Is the problem simply that maintaining cursor positions within this huge string is too slow? Would you expect Carota to scale to large documents?



    • earwicker
      June 24, 2014 at 9:31 pm

      Apologies for the delay in replying (gives you some idea of the time I can devote to this…) My plan with Carota was to use it as an editor for small chunks of text embedded inside an editor, not as a full-blown word processor. But there are lots of optimisation opportunities I never exploited, so it could be made much faster.

      Canvas should not have any inherent limitation. The whole document doesn’t get rendered – only the stuff on screen. But Ubuntu+Firefox users have reported that something is badly wrong on that stack. Maybe someone will be sufficiently interested to find out what! 🙂

      At the moment Carota re-lays out the entire document every time you type a character. It really only needs to look at the current paragraph and (if necessary) apply offsets to the stuff below. That would make a massive difference if you wanted to investigate further.

      Unfortunately my plan to use it hit a big problem: I am not even slightly competent at how right-to-left and complex scripts work, but I need an editor that “just works” for users in those languages/scripts. So I’m stuck with my existing approach: contentEditable plus a biggish layer of hackery to try and tame the behaviour across browsers and fill in the gaps (e.g. font size is just broken).

      • September 26, 2014 at 8:53 am

        Hi Dan – return apologies now for my delayed response. I’ve got e-mail alerts on now (I hope) so I should be a little quicker.

        I’d quite like to pick your brains about editors for this project I’m working on. You’ve got a wealth of experience which I’d like to exploit =) Would you be open to an e-mail conversation about it? You can DM me a suitable address through Twitter. Cheers!

      • September 26, 2014 at 7:46 pm

        In fact, having looked over the codebase (which looks lovely and tidy and I instantly understand) I think I’d be interested in contributing some changes back (although I’m not sure I can help with the right/left problem). Please do get in touch!

  3. Amandeep Singh
    August 11, 2014 at 12:55 pm

    Thanks for the wonderful editor. I have just one concern! why it is too slow in Ubuntu/firefox?

    • earwicker
      August 11, 2014 at 6:20 pm

      I don’t know, but it would be great if you have any time to investigate why! If you figure out a way to solve it, please send me a pull request on github.

  4. Amandeep Singh
    August 18, 2014 at 5:28 am

    Could you please add bullets and numbering option in this editor…

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: