4

I'm trying to build a word processor web app, similar to Google Docs. I've started using Mercury Editor (which relies on the contentEditable attribute) and I've created an editable div element that looks like a paper page (as Google Docs does).

Now the big problem is how to deal with several pages, i.e., how to detect when text (or other content) overflows the page height and then create a new page with the content split. There are a few scenarios when this could ocurr:

  • A user type a break line at the end of the page. A new page should be created.
  • A user is typing a word and he reaches the end of the page. A new page should be created and that word should be moved to the new page.
  • A user pastes some large text and it doesn't fit totally on the current page. A new page should be created and only the text that doesn't fit should be moved to the new one.
  • A user inserts any other element (an image for instance), that doesn't fit in the current page. A new page should be created with that element.

I've tried to dive into the Google Docs JS code but it's pretty impossible to follow, since it's compressed. There is a standalone version of Google Docs, with the code beautified, however it's old and doesn't handle several pages.

Any hint about how to accomplish this will be appreciated.

jävi
  • 4,571
  • 1
  • 24
  • 32
  • everytime there is a change you may test the height of the current frame and decide if yes or not a new page needs to be happened – vdegenne Feb 28 '12 at 20:33
  • Yes, that's easy to say. Problem then is: what is the right event to listen to? You can't rely on key events. I've tried with DOMSubtreeModified but as far I know it doesn't allow you to stop the propagation and cancel the modifications. – jävi Feb 28 '12 at 20:38
  • actually your question is to vast to be answered, try to cut out your project a little more and ask the head-spinning questions. – vdegenne Feb 28 '12 at 21:20
  • Google Docs does not use contenteditable (at least since may 2010), http://googledocs.blogspot.it/2010/05/whats-different-about-new-google-docs.html – ignis May 29 '12 at 18:36
  • Hi jävi, were you able to solve this problem? I'm trying to do exactly the same. – RainierMallol Nov 19 '14 at 16:07
  • @rainier9 I'm afraid we didn't. We ended up building a document editor without pages, just an infinite editable document. – jävi Nov 20 '14 at 17:27
  • Thank you so much for answering, my team is working on the project, we'll see if we can come up with something good, I'll let you know :) – RainierMallol Nov 21 '14 at 17:57
  • If you come up with a solution, please make it open source :_) – jävi Nov 24 '14 at 14:41
  • @jävi did you found any solution or library for that. I am trying to creating the same thing. Did you found anything ? – Gitesh Purbia Oct 04 '16 at 11:07

2 Answers2

0

If your container have a fixed size you can use the overflow event to detect it.

window.addEventListener ("overflow", yourFunction, false);
Marius
  • 101
  • 7
  • I like the overflow approach, however the "overflow" event only works on FF. In addition there is another problem to solve: how to detect exactly what content is causing the overflow, and move that content to the new page. Any ideas? Thanks! – jävi Feb 29 '12 at 11:43
  • There is plenty of chances: `onPropertyChange, onKeyDown, onKeyUp, onBeforePaste`... in IE there is `onSelectionChange`, which could replace almost all others. I would not try to cancel events, it is easier to let user to do what he wants, and then fix the layout afterwards. – Teemu Feb 29 '12 at 12:07
0

Basically you'd want two divs, like this

<div id='pageWrapper'>
    <div id='page' style='max-height: 600px; overflow: hidden;'>
    </div>
</div>

All #pageWrapper does is sit there and look like a page, all the content that someone adds is added to the #page. Everytime someone adds content, whether through pasting or typing check #page's scrollHeight versus it's offsetHeight. If the scrollHeight is bigger you've overflowed the page, and you can start moving content (word by word, or element by element) to the next page until the scrollHeight is equal to the offsetHeight again.

If the user inserts a page break, just set #page's height to wherever the page break is, so that anything that comes after that will overflow the page. This will get tricky with large documents, since if someone overflows page 1, content will have to be adjusted until page whatever, but I guess that's why Google Docs doesn't have pages.

hobberwickey
  • 6,118
  • 4
  • 28
  • 29
  • "Google Docs doesn't have pages"? What do you mean? It does have pages. – jävi Feb 29 '12 at 11:18
  • weird, my docs have always shown up as one continuous page and I've found it really annoying. I guess I should check my settings. – hobberwickey Feb 29 '12 at 12:23
  • @jävi Accepted answer in this post might help too: http://stackoverflow.com/questions/9457201/auto-resize-child-divs-so-they-equally-share-width-of-parent/9457465#9457465 – Teemu Feb 29 '12 at 12:59