You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

304 lines
12 KiB

/*
* printThis v1.10.0
* @desc Printing plug-in for jQuery
* @author Jason Day
*
* Resources (based on) :
* jPrintArea: http://plugins.jquery.com/project/jPrintArea
* jqPrint: https://github.com/permanenttourist/jquery.jqprint
* Ben Nadal: http://www.bennadel.com/blog/1591-Ask-Ben-Print-Part-Of-A-Web-Page-With-jQuery.htm
*
* Licensed under the MIT licence:
* http://www.opensource.org/licenses/mit-license.php
*
* (c) Jason Day 2015
*
* Usage:
*
* $("#mySelector").printThis({
* debug: false, // show the iframe for debugging
* importCSS: true, // import page CSS
* importStyle: false, // import style tags
* printContainer: true, // grab outer container as well as the contents of the selector
* loadCSS: "path/to/my.css", // path to additional css file - us an array [] for multiple
* pageTitle: "", // add title to print page
* removeInline: false, // remove all inline styles from print elements
* printDelay: 333, // variable print delay
* header: null, // prefix to html
* footer: null, // postfix to html
* base: false, // preserve the BASE tag, or accept a string for the URL
* formValues: true, // preserve input/form values
* canvas: false, // copy canvas elements (experimental)
* doctypeString: '...', // enter a different doctype for older markup
* removeScripts: false // remove script tags from print content
* });
*
* Notes:
* - the loadCSS will load additional css (with or without @media print) into the iframe, adjusting layout
*/
;
(function($) {
function appendContent($el, content) {
if (!content) return;
// Simple test for a jQuery element
$el.append(content.jquery ? content.clone() : content);
}
function appendBody($body, $element, opt) {
// Clone for safety and convenience
var $content = $element.clone();
if (opt.removeScripts) {
$content.find('script').remove();
}
if (opt.printContainer) {
// grab $.selector as container
$body.append($("<div/>").html($content).html());
} else {
// otherwise just print interior elements of container
$content.each(function() {
$body.append($(this).html());
});
}
}
var opt;
$.fn.printThis = function(options) {
opt = $.extend({}, $.fn.printThis.defaults, options);
var $element = this instanceof jQuery ? this : $(this);
var strFrameName = "printThis-" + (new Date()).getTime();
if (window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)) {
// Ugly IE hacks due to IE not inheriting document.domain from parent
// checks if document.domain is set by comparing the host name against document.domain
var iframeSrc = "javascript:document.write(\"<head><script>document.domain=\\\"" + document.domain + "\\\";</s" + "cript></head><body></body>\")";
var printI = document.createElement('iframe');
printI.name = "printIframe";
printI.id = strFrameName;
printI.className = "MSIE";
document.body.appendChild(printI);
printI.src = iframeSrc;
} else {
// other browsers inherit document.domain, and IE works if document.domain is not explicitly set
var $frame = $("<iframe id='" + strFrameName + "' name='printIframe' />");
$frame.appendTo("body");
}
var $iframe = $("#" + strFrameName);
// show frame if in debug mode
if (!opt.debug) $iframe.css({
position: "absolute",
width: "0px",
height: "0px",
left: "-600px",
top: "-600px"
});
// $iframe.ready() and $iframe.load were inconsistent between browsers
setTimeout(function() {
// Add doctype to fix the style difference between printing and render
function setDocType($iframe, doctype){
var win, doc;
win = $iframe.get(0);
win = win.contentWindow || win.contentDocument || win;
doc = win.document || win.contentDocument || win;
doc.open();
doc.write(doctype);
doc.close();
}
if (opt.doctypeString){
setDocType($iframe, opt.doctypeString);
}
var $doc = $iframe.contents(),
$head = $doc.find("head"),
$body = $doc.find("body"),
$base = $('base'),
baseURL;
// add base tag to ensure elements use the parent domain
if (opt.base === true && $base.length > 0) {
// take the base tag from the original page
baseURL = $base.attr('href');
} else if (typeof opt.base === 'string') {
// An exact base string is provided
baseURL = opt.base;
} else {
// Use the page URL as the base
baseURL = document.location.protocol + '//' + document.location.host;
}
$head.append('<base href="' + baseURL + '">');
// import page stylesheets
if (opt.importCSS) $("link[rel=stylesheet]").each(function() {
var href = $(this).attr("href");
if (href) {
var media = $(this).attr("media") || "all";
$head.append("<link type='text/css' rel='stylesheet' href='" + href + "' media='" + media + "'>");
}
});
// import style tags
if (opt.importStyle) $("style").each(function() {
$(this).clone().appendTo($head);
});
// add title of the page
if (opt.pageTitle) $head.append("<title>" + opt.pageTitle + "</title>");
// import additional stylesheet(s)
if (opt.loadCSS) {
if ($.isArray(opt.loadCSS)) {
jQuery.each(opt.loadCSS, function(index, value) {
$head.append("<link type='text/css' rel='stylesheet' href='" + this + "'>");
});
} else {
$head.append("<link type='text/css' rel='stylesheet' href='" + opt.loadCSS + "'>");
}
}
// print header
appendContent($body, opt.header);
if (opt.canvas) {
// add canvas data-ids for easy access after cloning.
var canvasId = 0;
$element.find('canvas').each(function(){
$(this).attr('data-printthis', canvasId++);
});
}
appendBody($body, $element, opt);
if (opt.canvas) {
// Re-draw new canvases by referencing the originals
$body.find('canvas').each(function(){
var cid = $(this).data('printthis'),
$src = $('[data-printthis="' + cid + '"]');
this.getContext('2d').drawImage($src[0], 0, 0);
// Remove the markup from the original
$src.removeData('printthis');
});
}
// capture form/field values
if (opt.formValues) {
// loop through inputs
var $input = $element.find('input');
if ($input.length) {
$input.each(function() {
var $this = $(this),
$name = $(this).attr('name'),
$checker = $this.is(':checkbox') || $this.is(':radio'),
$iframeInput = $doc.find('input[name="' + $name + '"]'),
$value = $this.val();
// order matters here
if (!$checker) {
$iframeInput.val($value);
} else if ($this.is(':checked')) {
if ($this.is(':checkbox')) {
$iframeInput.attr('checked', 'checked');
} else if ($this.is(':radio')) {
$doc.find('input[name="' + $name + '"][value="' + $value + '"]').attr('checked', 'checked');
}
}
});
}
// loop through selects
var $select = $element.find('select');
if ($select.length) {
$select.each(function() {
var $this = $(this),
$name = $(this).attr('name'),
$value = $this.val();
$doc.find('select[name="' + $name + '"]').val($value);
});
}
// loop through textareas
var $textarea = $element.find('textarea');
if ($textarea.length) {
$textarea.each(function() {
var $this = $(this),
$name = $(this).attr('name'),
$value = $this.val();
$doc.find('textarea[name="' + $name + '"]').val($value);
});
}
} // end capture form/field values
// remove inline styles
if (opt.removeInline) {
// $.removeAttr available jQuery 1.7+
if ($.isFunction($.removeAttr)) {
$doc.find("body *").removeAttr("style");
} else {
$doc.find("body *").attr("style", "");
}
}
// print "footer"
appendContent($body, opt.footer);
setTimeout(function() {
if ($iframe.hasClass("MSIE")) {
// check if the iframe was created with the ugly hack
// and perform another ugly hack out of neccessity
window.frames["printIframe"].focus();
$head.append("<script> window.print(); </s" + "cript>");
} else {
// proper method
if (document.queryCommandSupported("print")) {
$iframe[0].contentWindow.document.execCommand("print", false, null);
} else {
$iframe[0].contentWindow.focus();
$iframe[0].contentWindow.print();
}
}
// remove iframe after print
if (!opt.debug) {
setTimeout(function() {
$iframe.remove();
}, 1000);
}
}, opt.printDelay);
}, 333);
};
// defaults
$.fn.printThis.defaults = {
debug: false, // show the iframe for debugging
importCSS: true, // import parent page css
importStyle: false, // import style tags
printContainer: true, // print outer container/$.selector
loadCSS: "", // load an additional css file - load multiple stylesheets with an array []
pageTitle: "", // add title to print page
removeInline: false, // remove all inline styles
printDelay: 333, // variable print delay
header: null, // prefix to html
footer: null, // postfix to html
formValues: true, // preserve input/form values
canvas: false, // copy canvas content (experimental)
base: false, // preserve the BASE tag, or accept a string for the URL
doctypeString: '<!DOCTYPE html>', // html doctype
removeScripts: false // remove script tags before appending
};
})(jQuery);