1/* @license 2 * jQuery.print, version 1.5.0 3 * (c) Sathvik Ponangi, Doers' Guild 4 * Licence: CC-By (http://creativecommons.org/licenses/by/3.0/) 5 *--------------------------------------------------------------------------*/ 6(function ($) { 7 "use strict"; 8 // A nice closure for our definitions 9 function getjQueryObject(string) { 10 // Make string a vaild jQuery thing 11 var jqObj = $(""); 12 try { 13 jqObj = $(string) 14 .clone(); 15 } catch (e) { 16 jqObj = $("<span />") 17 .html(string); 18 } 19 return jqObj; 20 } 21 22 function printFrame(frameWindow, content, options) { 23 // Print the selected window/iframe 24 var def = $.Deferred(); 25 try { 26 frameWindow = frameWindow.contentWindow || frameWindow.contentDocument || frameWindow; 27 var wdoc = frameWindow.document || frameWindow.contentDocument || frameWindow; 28 if(options.doctype) { 29 wdoc.write(options.doctype); 30 } 31 wdoc.write(content); 32 wdoc.close(); 33 var printed = false; 34 function callPrint() { 35 if(printed) { 36 return; 37 } 38 // Fix for IE : Allow it to render the iframe 39 frameWindow.focus(); 40 try { 41 // Fix for IE11 - printng the whole page instead of the iframe content 42 if (!frameWindow.document.execCommand('print', false, null)) { 43 // document.execCommand returns false if it failed -http://stackoverflow.com/a/21336448/937891 44 frameWindow.print(); 45 } 46 } catch (e) { 47 frameWindow.print(); 48 } 49 frameWindow.close(); 50 printed = true; 51 def.resolve(); 52 } 53 // Print once the frame window loads - seems to work for the new-window option but unreliable for the iframe 54 $(frameWindow).on("load", callPrint); 55 // Fallback to printing directly if the frame doesn't fire the load event for whatever reason 56 setTimeout(callPrint, options.timeout); 57 } catch (err) { 58 def.reject(err); 59 } 60 return def; 61 } 62 63 function printContentInIFrame(content, options) { 64 var $iframe = $(options.iframe + ""); 65 var iframeCount = $iframe.length; 66 if (iframeCount === 0) { 67 // Create a new iFrame if none is given 68 $iframe = $('<iframe height="0" width="0" border="0" wmode="Opaque"/>') 69 .prependTo('body') 70 .css({ 71 "position": "absolute", 72 "top": -999, 73 "left": -999 74 }); 75 } 76 var frameWindow = $iframe.get(0); 77 return printFrame(frameWindow, content, options) 78 .done(function () { 79 // Success 80 setTimeout(function () { 81 // Wait for IE 82 if (iframeCount === 0) { 83 // Destroy the iframe if created here 84 $iframe.remove(); 85 } 86 }, 100); 87 }) 88 .fail(function (err) { 89 // Use the pop-up method if iframe fails for some reason 90 console.error("Failed to print from iframe", err); 91 printContentInNewWindow(content, options); 92 }) 93 .always(function () { 94 try { 95 options.deferred.resolve(); 96 } catch (err) { 97 console.warn('Error notifying deferred', err); 98 } 99 }); 100 } 101 102 function printContentInNewWindow(content, options) { 103 // Open a new window and print selected content 104 var frameWindow = window.open(); 105 return printFrame(frameWindow, content, options) 106 .always(function () { 107 try { 108 options.deferred.resolve(); 109 } catch (err) { 110 console.warn('Error notifying deferred', err); 111 } 112 }); 113 } 114 115 function isNode(o) { 116 /* http://stackoverflow.com/a/384380/937891 */ 117 return !!(typeof Node === "object" ? o instanceof Node : o && typeof o === "object" && typeof o.nodeType === "number" && typeof o.nodeName === "string"); 118 } 119 $.print = $.fn.print = function () { 120 // Print a given set of elements 121 var options, $this, self = this; 122 // console.log("Printing", this, arguments); 123 if (self instanceof $) { 124 // Get the node if it is a jQuery object 125 self = self.get(0); 126 } 127 if (isNode(self)) { 128 // If `this` is a HTML element, i.e. for 129 // $(selector).print() 130 $this = $(self); 131 if (arguments.length > 0) { 132 options = arguments[0]; 133 } 134 } else { 135 if (arguments.length > 0) { 136 // $.print(selector,options) 137 $this = $(arguments[0]); 138 if (isNode($this[0])) { 139 if (arguments.length > 1) { 140 options = arguments[1]; 141 } 142 } else { 143 // $.print(options) 144 options = arguments[0]; 145 $this = $("html"); 146 } 147 } else { 148 // $.print() 149 $this = $("html"); 150 } 151 } 152 // Default options 153 var defaults = { 154 globalStyles: true, 155 mediaPrint: false, 156 stylesheet: null, 157 noPrintSelector: ".no-print", 158 iframe: true, 159 append: null, 160 prepend: null, 161 manuallyCopyFormValues: true, 162 deferred: $.Deferred(), 163 timeout: 750, 164 title: null, 165 doctype: '<!doctype html>' 166 }; 167 // Merge with user-options 168 options = $.extend({}, defaults, (options || {})); 169 var $styles = $(""); 170 if (options.globalStyles) { 171 // Apply the stlyes from the current sheet to the printed page 172 $styles = $("style, link, meta, base, title"); 173 } else if (options.mediaPrint) { 174 // Apply the media-print stylesheet 175 $styles = $("link[media=print]"); 176 } 177 if (options.stylesheet) { 178 // Add a custom stylesheet if given 179 $styles = $.merge($styles, $('<link rel="stylesheet" href="' + options.stylesheet + '">')); 180 } 181 // Create a copy of the element to print 182 var copy = $this.clone(); 183 // Wrap it in a span to get the HTML markup string 184 copy = $("<span/>") 185 .append(copy); 186 // Remove unwanted elements 187 copy.find(options.noPrintSelector) 188 .remove(); 189 // Add in the styles 190 copy.append($styles.clone()); 191 // Update title 192 if (options.title) { 193 var title = $("title", copy); 194 if (title.length === 0) { 195 title = $("<title />"); 196 copy.append(title); 197 }
198 title.text(options.title); 199 } 200 // Appedned content 201 copy.append(getjQueryObject(options.append)); 202 // Prepended content 203 copy.prepend(getjQueryObject(options.prepend)); 204 if (options.manuallyCopyFormValues) { 205 // Manually copy form values into the HTML for printing user-modified input fields 206 // http://stackoverflow.com/a/26707753 207 copy.find("input") 208 .each(function () { 209 var $field = $(this); 210 if ($field.is("[type='radio']") || $field.is("[type='checkbox']")) { 211 if ($field.prop("checked")) { 212 $field.attr("checked", "checked"); 213 } 214 } else { 215 $field.attr("value", $field.val()); 216 } 217 }); 218 copy.find("select").each(function () { 219 var $field = $(this); 220 $field.find(":selected").attr("selected", "selected"); 221 }); 222 copy.find("textarea").each(function () { 223 // Fix for https://github.com/DoersGuild/jQuery.print/issues/18#issuecomment-96451589 224 var $field = $(this); 225 $field.text($field.val()); 226 }); 227 } 228 // Get the HTML markup string 229 var content = copy.html(); 230 // Notify with generated markup & cloned elements - useful for logging, etc 231 try { 232 options.deferred.notify('generated_markup', content, copy); 233 } catch (err) { 234 console.warn('Error notifying deferred', err); 235 } 236 // Destroy the copy 237 copy.remove(); 238 if (options.iframe) { 239 // Use an iframe for printing 240 try { 241 printContentInIFrame(content, options); 242 } catch (e) { 243 // Use the pop-up method if iframe fails for some reason 244 console.error("Failed to print from iframe", e.stack, e.message); 245 printContentInNewWindow(content, options); 246 } 247 } else { 248 // Use a new window for printing 249 printContentInNewWindow(content, options); 250 } 251 return this; 252 }; 253})(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.