1/* 2 * printThis v1.11.0 3 * @desc Printing plug-in for jQuery 4 * @author Jason Day 5 * 6 * Resources (based on) : 7 * jPrintArea: http://plugins.jquery.com/project/jPrintArea 8 * jqPrint: https://github.com/permanenttourist/jquery.jqprint 9 * Ben Nadal: http://www.bennadel.com/blog/1591-Ask-Ben-Print-Part-Of-A-Web-Page-With-jQuery.htm 10 * 11 * Licensed under the MIT licence: 12 * http://www.opensource.org/licenses/mit-license.php 13 * 14 * (c) Jason Day 2015 15 * 16 * Usage: 17 * 18 * $("#mySelector").printThis({ 19 * debug: false, // show the iframe for debugging 20 * importCSS: true, // import page CSS 21 * importStyle: false, // import style tags 22 * printContainer: true, // grab outer container as well as the contents of the selector 23 * loadCSS: "path/to/my.css", // path to additional css file - us an array [] for multiple 24 * pageTitle: "", // add title to print page 25 * removeInline: false, // remove all inline styles from print elements 26 * printDelay: 333, // variable print delay 27 * header: null, // prefix to html 28 * footer: null, // postfix to html 29 * base: false, // preserve the BASE tag, or accept a string for the URL 30 * formValues: true, // preserve input/form values 31 * canvas: false, // copy canvas elements (experimental) 32 * doctypeString: '...', // enter a different doctype for older markup 33 * removeScripts: false, // remove script tags from print content 34 * copyTagClasses: false // copy classes from the html & body tag 35 * }); 36 * 37 * Notes: 38 * - the loadCSS will load additional css (with or without @media print) into the iframe, adjusting layout 39 */ 40; 41 42 43 44(function($) { 45 46 function appendContent($el, content) { 47 if (!content) return; 48 49 // Simple test for a jQuery element 50 $el.append(content.jquery ? content.clone() : content); 51 } 52 53 function appendBody($body, $element, opt) { 54 // Clone for safety and convenience 55 var $content = $element.clone(); 56 57 if (opt.removeScripts) { 58 $content.find('script').remove(); 59 } 60 61 if (opt.printContainer) { 62 // grab $.selector as container 63 $body.append($("<div/>").html($content).html()); 64 } else { 65 // otherwise just print interior elements of container 66 $content.each(function() { 67 $body.append($(this).html()); 68 }); 69 } 70 } 71 72 var opt; 73 $.fn.printThis = function(options) { 74 opt = $.extend({}, $.fn.printThis.defaults, options); 75 var $element = this instanceof jQuery ? this : $(this); 76 77 var strFrameName = "printThis-" + (new Date()).getTime(); 78 79 if (window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)) { 80 // Ugly IE hacks due to IE not inheriting document.domain from parent 81 // checks if document.domain is set by comparing the host name against document.domain 82 var iframeSrc = "javascript:document.write(\"<head><script>document.domain=\\\"" + document.domain + "\\\";</s" + "cript></head><body></body>\")"; 83 var printI = document.createElement('iframe'); 84 printI.name = "printIframe"; 85 printI.id = strFrameName; 86 printI.className = "MSIE"; 87 document.body.appendChild(printI); 88 printI.src = iframeSrc; 89 90 } else { 91 // other browsers inherit document.domain, and IE works if document.domain is not explicitly set 92 var $frame = $("<iframe id='" + strFrameName + "' name='printIframe' />"); 93 $frame.appendTo("body"); 94 } 95 96 var $iframe = $("#" + strFrameName); 97 98 // show frame if in debug mode 99 if (!opt.debug) $iframe.css({ 100 position: "absolute", 101 width: "0px", 102 height: "0px", 103 left: "-600px", 104 top: "-600px" 105 }); 106 107 // $iframe.ready() and $iframe.load were inconsistent between browsers 108 setTimeout(function() { 109 110 // Add doctype to fix the style difference between printing and render 111 function setDocType($iframe, doctype){ 112 var win, doc; 113 win = $iframe.get(0); 114 win = win.contentWindow || win.contentDocument || win; 115 doc = win.document || win.contentDocument || win; 116 doc.open(); 117 doc.write(doctype); 118 doc.close(); 119 } 120 121 if (opt.doctypeString){ 122 setDocType($iframe, opt.doctypeString); 123 } 124 125 var $doc = $iframe.contents(), 126 $head = $doc.find("head"), 127 $body = $doc.find("body"), 128 $base = $('base'), 129 baseURL; 130 131 // add base tag to ensure elements use the parent domain 132 if (opt.base === true && $base.length > 0) { 133 // take the base tag from the original page 134 baseURL = $base.attr('href'); 135 } else if (typeof opt.base === 'string') { 136 // An exact base string is provided 137 baseURL = opt.base; 138 } else { 139 // Use the page URL as the base 140 baseURL = document.location.protocol + '//' + document.location.host; 141 } 142 143 $head.append('<base href="' + baseURL + '">'); 144 145 // import page stylesheets 146 if (opt.importCSS) $("link[rel=stylesheet]").each(function() { 147 var href = $(this).attr("href"); 148 if (href) { 149 var media = $(this).attr("media") || "all"; 150 $head.append("<link type='text/css' rel='stylesheet' href='" + href + "' media='" + media + "'>"); 151 } 152 }); 153 154 // import style tags 155 if (opt.importStyle) $("style").each(function() { 156 $(this).clone().appendTo($head); 157 }); 158 159 // add title of the page 160 if (opt.pageTitle) $head.append("<title>" + opt.pageTitle + "</title>"); 161 162 // import additional stylesheet(s) 163 if (opt.loadCSS) { 164 if ($.isArray(opt.loadCSS)) { 165 jQuery.each(opt.loadCSS, function(index, value) { 166 $head.append("<link type='text/css' rel='stylesheet' href='" + this + "'>"); 167 }); 168 } else { 169 $head.append("<link type='text/css' rel='stylesheet' href='" + opt.loadCSS + "'>"); 170 } 171 } 172 173 // copy 'root' tag classes 174 var tag = opt.copyTagClasses; 175 if (tag) { 176 tag = tag === true ? 'bh' : tag; 177 if (tag.indexOf('b') !== -1) { 178 $body.addClass($('body')[0].className); 179 } 180 if (tag.indexOf('h') !== -1) { 181 $doc.find('html').addClass($('html')[0].className); 182 } 183 } 184 185 // print header 186 appendContent($body, opt.header); 187 188 if (opt.canvas) { 189 // add canvas data-ids for easy access after cloning. 190 var canvasId = 0; 191 $element.find('canvas').each(function(){ 192 $(this).attr('data-printthis', canvasId++); 193 }); 194 } 195 196 appendBody($body, $element, opt); 197 198 if (opt.canvas) { 199 // Re-draw new canvases by referencing the originals 200 $body.find('canvas').each(function(){ 201 var cid = $(this).data('printthis'), 202 $src = $('[data-printthis="' + cid + '"]'); 203 204 this.getContext('2d').drawImage($src[0], 0, 0); 205 206 // Remove the markup from the original 207 $src.removeData('printthis'); 208 }); 209 } 210 211 // capture form/field values 212 if (opt.formValues) { 213 // loop through inputs 214 var $input = $element.find('input'); 215 if ($input.length) { 216 $input.each(function() { 217 var $this = $(this), 218 $name = $(this).attr('name'), 219 $checker = $this.is(':checkbox') || $this.is(':radio'), 220 $iframeInput = $doc.find('input[name="' + $name + '"]'), 221 $value = $this.val(); 222 223 // order matters here 224 if (!$checker) { 225 $iframeInput.val($value); 226 } else if ($this.is(':checked')) { 227 if ($this.is(':checkbox')) { 228 $iframeInput.attr('checked', 'checked'); 229 } else if ($this.is(':radio')) { 230 $doc.find('input[name="' + $name + '"][value="' + $value + '"]').attr('checked', 'checked'); 231 } 232 } 233 234 }); 235 } 236 237 // loop through selects 238 var $select = $element.find('select'); 239 if ($select.length) { 240 $select.each(function() { 241 var $this = $(this), 242 $name = $(this).attr('name'), 243 $value = $this.val(); 244 $doc.find('select[name="' + $name + '"]').val($value); 245 }); 246 } 247 248 // loop through textareas 249 var $textarea = $element.find('textarea'); 250 if ($textarea.length) { 251 $textarea.each(function() { 252 var $this = $(this), 253 $name = $(this).attr('name'), 254 $value = $this.val(); 255 $doc.find('textarea[name="' + $name + '"]').val($value); 256 }); 257 } 258 } // end capture form/field values 259 260 // remove inline styles 261 if (opt.removeInline) { 262 // $.removeAttr available jQuery 1.7+ 263 if ($.isFunction($.removeAttr)) { 264 $doc.find("body *").removeAttr("style"); 265 } else { 266 $doc.find("body *").attr("style", ""); 267 } 268 } 269 270 // print "footer" 271 appendContent($body, opt.footer); 272 273 setTimeout(function() { 274 if ($iframe.hasClass("MSIE")) { 275 // check if the iframe was created with the ugly hack 276 // and perform another ugly hack out of neccessity 277 window.frames["printIframe"].focus(); 278 279 if( navigator.userAgent.indexOf("MSIE") > 0 ){ 280 $head.append("<script> preview_print(); </s" + "cript>"); 281 } else if( navigator.userAgent.indexOf("Chrome") > 0){ 282 $head.append("<script> window.print(); </s" + "cript>"); 283 } 284 285 286 287 $head.append("<script> window.print(); </s" + "cript>"); 288 } else { 289 // proper method 290 if (document.queryCommandSupported("print")) { 291 $iframe[0].contentWindow.document.execCommand("print", false, null); 292 } else { 293 $iframe[0].contentWindow.focus(); 294 $iframe[0].contentWindow.print(); 295 } 296 } 297 298 // remove iframe after print 299 if (!opt.debug) { 300 setTimeout(function() { 301 $iframe.remove(); 302 }, 1000); 303 } 304 305 }, opt.printDelay); 306 307 }, 333); 308 309 }; 310 311 // defaults 312 $.fn.printThis.defaults = { 313 debug: false, // show the iframe for debugging 314 importCSS: true, // import parent page css 315 importStyle: false, // import style tags 316 printContainer: true, // print outer container/$.selector 317 loadCSS: "", // load an additional css file - load multiple stylesheets with an array [] 318 pageTitle: "", // add title to print page 319 removeInline: false, // remove all inline styles 320 printDelay: 333, // variable print delay 321 header: null, // prefix to html 322 footer: null, // postfix to html 323 formValues: true, // preserve input/form values
324 canvas: false, // copy canvas content (experimental) 325 base: false, // preserve the BASE tag, or accept a string for the URL 326 doctypeString: '<!DOCTYPE html>', // html doctype 327 removeScripts: false, // remove script tags before appending 328 copyTagClasses: false // copy classes from the html & body tag 329 }; 330})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.