Community

Looking for a better solution for a fix to the print anything module

I wrote a module called Print Anything and I've since come across an issue with it. Specifically, it doesn't play well with panels. The module currently uses javascript to capture the innerHTML of DOM objects, specified by ID and display it on a dedicated printer-friendly template. A simple example best illustrates the problem.

If you insert a node title into a panel pane, panels inserts it as straight text inside a div. No tag or anything like that. It looks like this...

<div id="content-top-headline" class="panel-pane pane-token pane-node-title">
<div class="pane-content">Node Title is Here</div>
</div>

Panels allows you to specify classes and an ID on the main wrapper. So my module can capture it. But innerHTML takes only the inner content. So what I end up with in the printer page is...

<div class="pane-content">Node Title is Here</div>

All the styles from the originating page are lost and there's no useful hook to make new ones.

So I started looking into a way to pass the entire object, main wrapper an all with all it's attributes. I found several ways to do it that works in Firefox, Chrome and Safari. But of course none of them work in IE. I devised a rather hackneyed approach to make it work in IE. But I'm fishing for a more elegant solution before I post an update to the module page. Here's what I did. The following code is called repeatedly inside a loop for every CSS ID passed by the module. "#print-friendly-doc-body" is the main content wrapper in the print-friendly template.

var passedContent = $(window.opener.document).find('#id').clone();
$('#print-friendly-doc-body').append(passedContent);

Works great except in IE where the error "SCRIPT5022: DOM Exception: HIERARCHY_REQUEST_ERR (3)" get's thrown. This error supposedly means that append() is trying to combine two different types of objects. But as far as I can tell, they're both legitimate jquery objects. I tried all sorts of ways to get this to work and they all failed. I finally came up with this wacky thing. This actually runs inside a php loop to build as many as necessary, but this illustrates the javascript approach.

if (!$.support.cssFloat) {
  var passedContent1;
  var passedContent2;
  var classes;
  var tag;
  var subwrapper;
  passedContent1 = $(window.opener.document).find('#id').html();
  passedContent2 = $(window.opener.document).find('#id').clone();
  classes = passedContent2.attr('class');
  tag = passedContent2.get(0).tagName.toLowerCase();
  subwrapper = '<' + tag + ' id="id" class=\"' + classes + '\"></' + tag + '>';
  $('#print-friendly-doc-body').append(subwrapper);
  $('#print-friendly-doc-body #id').append(passedContent1);
}

Line 7: captures the content from the opener in a form the .append() can handle.
Line 8: clones the opener object into a jquery object.
Lines 9 through 11: pulls some properties from the object and creates a new inner wrapper with those attributes.
Lines 12 and 13: appends the innerHTML content to that inner wrapper.

This works, but I'm wondering if anyone can think of a way to make the simpler 1st version work in IE.

nobody click here