PageSourceSearch

https://www.quebec.ca/_assets/f8330c6d2feed73af50f38ae981823a4/JavaScript/Vendor/printThis.js?1790171122

js quebec.ca collected 2026-09-24 07:03:41 UTC 14,764 bytes, 350 lines download raw bytes

1/*
2 * printThis 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").printThis({
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.printThis = function(options) {
93        opt = $.extend({}, $.fn.printThis.defaults, options);
94        var $element = this instanceof jQuery ? this : $(this);
95
96        var strFrameName = "printThis-" + (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.printThis.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);

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.