PluginProbe
Booking Calendar / 11.4.3
Booking Calendar v11.4.3
11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 All 204 releases
booking / vendors / _custom / wpbc_js_print / wpbc_js_print.js

wpbc_js_print.js in Booking Calendar 11.4.3, at vendors/_custom/wpbc_js_print/wpbc_js_print.js

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