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.
If your container have a fixed size you can use the overflow event to detect it.
window.addEventListener ("overflow", yourFunction, false);
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.
Related
I maintain a library, react-to-print. The library provides a React component that at its core has two inputs: a trigger (usually a button), and content. When the trigger is clicked, the library will copy the entire DOM representation of the content and put it into an iframe. It will also copy all style links on the page to ensure the content is styled correctly within the iframe.
A while ago, someone raised an issue (the end of the thread explains the core problem) concerning the library's seaming inability to print content that was horizontally scrolled, in this case, within a table. It turns out that what is actually happening is that a component within the content is virtualizing its render, meaning only content this is visible on the screen is actually being rendered. So the issue is that react-to-print is not maintaining the scroll positions of child elements when it copies them into the iframe.
I know how to scroll the entire page itself inside of an iframe, but do not know how to maintain the scroll of individually scrolled DOM elements that are children of the window. Is there a way to do that?
While an ideal solution would of course be just turn on a setting or something and done, I'm guessing that, if a solution is possible, it will look something like:
Iterate over every element on the page
If the element has a scroll, save its scroll position in a map
Copy over the elements into the iframe (as is currently done)
Iterate over every element in the iframe and apply a scroll if one is found for it in the map
I'd like to style a lengthy HTML document I intend to print (/ convert to a PDF) so that, on a particular physical page, the body is styled in one way, while on every other page, it is styled another way. Specifically, I want the page which contains a particular paragraph (say <p id="dramatic-scene">) to have a different background image from the other pages.
(The document itself is not structured for particular pages - instead of having a div for each page, we have a single container for the full content of the piece. If it were, we could probably just make the div for the page cover the entire dimensions of the page and give it the image - but I'm hoping to avoid having a rigid structure for the pages.)
In Selectors Level 4, there's a :has() pseudo-class (although part of a working draft, so it's not supported anywhere yet). Is there anything similar which could specify a page to apply CSS to? Something like #media print and (page-has: #dramatic-scene) {}. I doubt there is - some quick searching didn't find anything - but I figure it's worth asking here.
More realistically, is there any way I could simulate that with JavaScript? That'd be a fine solution for my use case. I couldn't find any info about that in searching though - any JS discussion related to printing seems to be about making buttons to print, swapping screen for print stylesheet before printing, etc, not making the page style react to the visible content.
(Sorry in advance for the long post)
I'm trying to help an open source CMS project called N2 CMS modernize its drag & drop toolbox. I'm not sure what the best way to do this is, but I basically want to take a floating menu and "dock" it against the left side of a web page, such that the entire body of the page is shrunk in width. However, the functionality of this panel depends on the user's ability to drag something out of the panel and drop it onto the page.
This is what it looks like currently. There is an outer "management" page wrapper (the blue bar that is visible at the top) and an inner iframe which wraps the content page being edited. The drag & drop panel is a floating div that is rendered by including some code in the content page akin to #{ RenderToolbox(); } (it basically just writes the div + some inline CSS out to the page)
This is what I'd like it to look like, ideally. You can see how the toolbox now has the whole left column (so the page isn't obstructed) and the whole width of the page has shrunk.
Is it possible to accomplish this by injecting a <div> into the page? Maybe some kind of jquery that can re-parent the whole body inside of a <div> container? Is this even the best way of going about this sort of thing?
I guess something like this would be possible:
jQuery(function(){
$('body').wrapInner('<div class="wrap" />')
})
However, we are worried that it might be hard to make this look good on all layouts, e.g. layouts that use absolute positioning or html/body margins.
Therefore, we are turning to the larger Stack Overflow community for any advice and thoughts on this problem. Your guidance is much appreciated!
I'm working on a website that would allows users to post advertisements - they are displayed as a table of post-it notes on the board. I'm generating them using JSP's c:forEach tag (advertisements are stored in XML file) - every advertisement is a cell of a table. I added a functionality that allows to see full content of the advertisement after clicking on it (I also change the size of advertisement's div). And here is my question - I would like the bigger versions of advertisements (after clicking on them) to overlap with other advertisements located nearby, instead of moving them along. Is something like that even possible?
PS: Sorry for my English, I hope you understand what I want to achieve.
Or maybe I will change my question - I would like to display full version of the advertisement in new window, but I don't know how to forward a whole bean to the JSP page (the one which I want to open in new window). I will be very grateful for any advice.
Yes, you can have a different css class for an expanded view, then put a div within the table cell, and when the advertisement is displayed, you can set "overflow: visible" for the td to see its contents in full size.
See this link for overflow property
I have a real-time HTML editor, with a textarea on the left for code entry, and a 'preview' DIV on the right to contain the preview of the code entered. At the moment, when editing the code in the left pane, the preview just sits where it is, so often the part of the code you're editing is not in the visible area of the preview (especially when images are involved).
My question is how do I make the preview scroll to show the part of the code that's currently being edited?
Here is the page I have so far:
http://www.caerphoto.com/rtedit.html
You'll notice in the source I have a (currently unused) matchPreview() function that tries to match the scroll position of the preview based on the scroll position of the textarea, but obviously if images or large text are involved the two panes no longer match.
Instead of a div from the clone target try using a tag.
let me decompose your task into 2 subtasks:
get informed when the dom changes
you could listen on changes of the dom like onsubtreemodified.
see
en.wikipedia.org/wiki/DOM_events
scroll the element into view
the answer to this is the scrollintoview method:
see
www.quirksmode.org/dom/tests/scrollintoview.html
however, this might not help you too much, since you are updating the whole html document on every change of the textarea. since you cannot get the position of the cursor inside the textarea, this might be not that easy.
sorry mate, at the end I have no solution, but maybe my rumination helps in some way nevertheless.
good luck!
When I tried this in Firefox. no line-breaks were seen in the preview; is this correct? I may be able to help (done something similsr recently), but not if the line breaks are removed...