Printing iframe shows only a small viewport - javascript

I'm using an iframe to prevent the CSS of user-provided content (converted .doc files) from bleeding out of an AJAX panel in my single-page application. It's the last item displayed, usually about 5 pages following 1 page.
It works visually in the screen application, where I have a parent-relative height and width to leverage, but I realized I couldn't actually get the iframe to print its entire contents with #media print declarations.
I've seen about 5 related questions answered 'not possible', but I'm more flexible than those askers. I'm willing to:
use javascript if it can format the print view without affecting the screen view. can you point me to an example?
I currently directly insert the iframe's html, so I also have a lot of control over its content.
to print the parent and iframe contents separately, if they'll queue seamlessly in major browsers' print managers - especially if there's a way to handle browser print events in this case?
as a last resort, I will probably print ONLY the iframe content, using the following. still would like to handle print events if it's possible cross-browser.
javascript:
window.frames["OverlayDis"].focus();
window.frames["OverlayDis"].print();

Related

PDF.js How do you print a multi-page pdf?

I'm trying to add print functionality to a multi-page PDF embedded in a web page that is using the PDF.js library. It's problematic because I only have one page rendered at a time when a user is viewing it and the page is really rendered as an image in a canvas element.
This question does not help in this case because it is for a single page PDF where printing the current contents of the canvas are acceptable. Same with this question. I also want to avoid just opening the PDF in another tab/window and telling the user to print it themselves, which defeats the purpose of embedding it into the page.
Looking through the documentation from Mozilla, I haven't found any native functions that will just print the PDF, however, I will start playing around with the renderingIntent which seems like it can be set to 'print'.
EDIT:
redingIntent doesn't seem to affect anything and the PDF stills renders the same way whether it is set to 'display' or 'print'.
Remember PDF.js is just another web page. ATM, at least not in the standard HTML5 APIs, there is no way for a web page push random information directly to printers (but you can push it to the cloud printing service) -- you can print only what you "see". "See" means what's in the DOM, and currently CSS can be used to hide information for the screen or printer. The DOM can also be changed the beforeprint/afterprint events.
In you case, since your PDF view in embedded, you need to fake DOM to have all PDF's pages/canvases on the main web page, make them visible for print and hide for screen (see e.g. [4]). Few different problems needs to be solved too that might be off-topic here: removing margins and non-rasterizing canvas. Firefox is dealing with those via moznomarginboxes [1] and mozPrintCallback [2] -- both are created in support of PDF.js and not supported by other browsers. (See also polyfill for the latter [3])
[1] https://bugzilla.mozilla.org/show_bug.cgi?id=743252
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=745025
[3] https://github.com/mozilla/pdf.js/blob/master/web/mozPrintCallback_polyfill.js
[4] https://github.com/mozilla/pdf.js/blob/master/web/viewer.css#L1759

How can I structure the HTML for these requirements

I am developing a system where I will display content in a browser in an embedded application. The normal browser navigation controls cannot be used but instead will have javascript running in a wrapper round the page. The content will be coming from the same domain but I cannot pre-process the content. Needs to be compliant with IE8+ and latest of FF and chrome.
The things the javascript needs to do are..
Load in new content
Detect when the content has fully loaded
Set focus to elements
Detect which link currently has focus
Retrieve lists of links on the page
Trigger links
What is the best way to place the content html pages within the wrapper page? eg
frames
iframe
div
Both iframes and divs could work. The final choice will depend on the details of your implementation, and is also a matter of personal taste.
With divs, the html becomes part of your wrapper page. The risk is to have conflicts between the inserted content and the rest of the page (css, html ids for example).
An iframe creates a sandbox and avoids conflicts. The downside is that the layout is not easy to adjust as the content lives in its own document. html5 introduces new iframe attributes like "seamless", but they won't work in IE8.
As above, Iframes may be best; however they are deprecated and don't always give the best results. An alternative would be to set a div for the content, and Ajax the content into the frame. You can then access it through the dom to get links etc.
To decide which would be best I would consider what content is being loaded - full HTML documents (with doctype, head, metadata etc) will be problematic without I frames.
If the content being loaded is just plain text, maybe with a few basic HTML elements, I would ajax it into a div

PhantomJS cutting off content in header/footer with PDFs

I'm using PhantomJS to dynamically generate a PDF. However it seems to always cut off some content in between the footer and header.
Relevant files:
HTML content: http://bit.ly/146Ljdp
rasterize.js file: http://bit.ly/12iSC7y
Example PDF file: http://bit.ly/10Aa309
As you can see in the PDF file, the content is cut off between page 5 and 6.
I've looked into the existing Qt and PhantomJS bugs, and am not completely sure on whether I'm not doing something right, or it's simply a bug.
AFAIK the most ideal option is to use page-break-inside:avoid, however Qt doesn't seem to support that yet.
The code content inside the PDF/document uses tables, and apparently there's been issues with that in the past: 927, 989, 1038, 880. I tried removing all of the table elements (table, tr, td, etc) and replaced them with divs. It looked exactly the same in the browser and PDF file, but it was still being cut off.
I tried a javascript hack to check each element if the top position and bottom position were on different pages, and if so, add a page-break-before... however I couldn't properly get the individual page size, to check the relative position from the header on each page. $('element').offset().top returns the position from the top of the entire document, not the current page.
Any ideas on what I'm doing wrong?
The is a tricky, But i solved it using simple logic.
Cast element to display as a Block element and it works.
display:block;
page-break-inside:avoid;

Modifying HTML while document is loading

Assume you have 75 div's that have data-id="{some number}" attribute. The overall page size is unfortunately big, very big.
There are many repetitive HTML snippets in my HTML document like image tags or links. These images/links' only changing portion is the id.
The HTML document is quite long, these snippets contribute to the overall size of the document.
I can run a javascript when dom is ready, but the user experience will be:
- wait the page loads, and start seeing nodes etc,
- page loads,
- extra snippets show.
I can make the top container DIV to hide until the page loads but
- worried that google search bot could realize the div is hidden and skip the content (or does it?)
- the users won't be able to see the content while the page is loading.
What ideal is to load the page in HTML without much extra markup for google search bot, and add extra elements while it's loading with javascript.
Any tricks that I can try that comes to your mind to accomplish this?
Thank you.
The best performance and user experience is to do as much work as possible on the server, then send efficient HTML and allow the browser to display the page as it's received. Sending say a single DIV container, then using script to clone it 70 or 80 times will be slower (probably a lot slower for some users).
Hiding content completely until your script has finished is the worst solution - users are left with a blank (or minimal content) page, waiting for something to happen.
The vast bulk of most pages is script and images, replacing HTML with scripting really is playing at the margins. e.g. this page has 90KB of HTML and 264KB of script, images and css. Apple's home page has 12KB of HTML and around 800KB of script, css and images.
Browsers show content progressively as it's received because that's how they evolved over many years on the web. Users prefer to see something rather than nothing, and to start viewing content while the rest loads (it's all about the content, not about fancy layouts or effects). Try to work with browser behaviour and features rather than against them.
You can greatly help the browser by specifying sizes for images and having an efficient layout. That way the layout won't change much as new content is received.
Depending on other page content, you could run your script on DocumentReady as opposed to onload.
DocumentReady runs after the page downloaded and the DOM rendered, but before images are retrieved.
I believe that there is an official DocumentReady event somewhere, but I still have to support IE6 on my pages, so I use a busy loop to watch the DOM.

Break the HTML file into fixed size pages

I would like to display the content of a HTML file,in the form of book with many pages(not side by side pages, but one after the other, like PDF), when opened in some browser. Say, i define page width=600px and height=800pz, the content should fit into one page and the remaining should overflow to next page and like that. And it should work for any HTML file.
How can i break the content into pages ? In any way XSL helps me to achieve it ?
This should be theoretically possible by putting the document into an iframe that is 800 pixels high, and changing the scroll position inside that iframe (Page 1 = 0px; Page 2 = 800px; Page 3 = 1600px ....)
The HTML page in question would have to be on your domain, though.
There is no proper way to actually display those pages side by side, though. You'd have to clone the whole document for as many times as there are pages, and display as many iframe s with the page scrolled to different positions.
Depending on what you want to do, it might be better to use a different technology for this (e.g. having a browser print out a web page to a PDF file, splitting the content into pages in the process.)
If you want PDF style functionality, convert the html on the fly into a pdf and then embed it in the page. You can specify the width and other params when you are generating the pdf.

Categories

Resources