1/*! 2 * Print button for Buttons and DataTables. 3 * 2016 SpryMedia Ltd - datatables.net/license 4 */ 5 6(function( factory ){ 7 if ( typeof define === 'function' && define.amd ) { 8 // AMD 9 define( ['jquery', 'datatables.net', 'datatables.net-buttons'], function ( $ ) { 10 return factory( $, window, document ); 11 } ); 12 } 13 else if ( typeof exports === 'object' ) { 14 // CommonJS 15 module.exports = function (root, $) { 16 if ( ! root ) { 17 root = window; 18 } 19 20 if ( ! $ || ! $.fn.dataTable ) { 21 $ = require('datatables.net')(root, $).$; 22 } 23 24 if ( ! $.fn.dataTable.Buttons ) { 25 require('datatables.net-buttons')(root, $); 26 } 27 28 return factory( $, root, root.document ); 29 }; 30 } 31 else { 32 // Browser 33 factory( jQuery, window, document ); 34 } 35}(function( $, window, document, undefined ) { 36'use strict'; 37var DataTable = $.fn.dataTable; 38 39 40var _link = document.createElement( 'a' ); 41 42/** 43 * Clone link and style tags, taking into account the need to change the source 44 * path. 45 * 46 * @param {node} el Element to convert 47 */ 48var _styleToAbs = function( el ) { 49 var url; 50 var clone = $(el).clone()[0]; 51 var linkHost; 52 53 if ( clone.nodeName.toLowerCase() === 'link' ) { 54 clone.href = _relToAbs( clone.href ); 55 } 56 57 return clone.outerHTML; 58}; 59 60/** 61 * Convert a URL from a relative to an absolute address so it will work 62 * correctly in the popup window which has no base URL. 63 * 64 * @param {string} href URL 65 */ 66var _relToAbs = function( href ) { 67 // Assign to a link on the original page so the browser will do all the 68 // hard work of figuring out where the file actually is 69 _link.href = href; 70 var linkHost = _link.host; 71 72 // IE doesn't have a trailing slash on the host 73 // Chrome has it on the pathname 74 if ( linkHost.indexOf('/') === -1 && _link.pathname.indexOf('/') !== 0) { 75 linkHost += '/'; 76 } 77 78 return _link.protocol+"//"+linkHost+_link.pathname+_link.search; 79}; 80 81 82DataTable.ext.buttons.print = { 83 className: 'buttons-print', 84 85 text: function ( dt ) { 86 return dt.i18n( 'buttons.print', 'Print' ); 87 }, 88 89 action: function ( e, dt, button, config ) { 90 var data = dt.buttons.exportData( 91 $.extend( {decodeEntities: false}, config.exportOptions ) // XSS protection 92 ); 93 var exportInfo = dt.buttons.exportInfo( config ); 94 var columnClasses = dt 95 .columns( config.exportOptions.columns ) 96 .flatten() 97 .map( function (idx) { 98 return dt.settings()[0].aoColumns[dt.column(idx).index()].sClass; 99 } ) 100 .toArray(); 101 102 var addRow = function ( d, tag ) { 103 var str = '<tr>'; 104 105 for ( var i=0, ien=d.length ; i<ien ; i++ ) { 106 // null and undefined aren't useful in the print output 107 var dataOut = d[i] === null || d[i] === undefined ? 108 '' : 109 d[i]; 110 var classAttr = columnClasses[i] ? 111 'class="'+columnClasses[i]+'"' : 112 ''; 113 114 str += '<'+tag+' '+classAttr+'>'+dataOut+'</'+tag+'>'; 115 } 116 117 return str + '</tr>'; 118 }; 119 120 // Construct a table for printing 121 var html = '<table class="'+dt.table().node().className+'">'; 122 123 if ( config.header ) { 124 html += '<thead>'+ addRow( data.header, 'th' ) +'</thead>'; 125 } 126 127 html += '<tbody>'; 128 for ( var i=0, ien=data.body.length ; i<ien ; i++ ) { 129 html += addRow( data.body[i], 'td' ); 130 } 131 html += '</tbody>'; 132 133 if ( config.footer && data.footer ) { 134 html += '<tfoot>'+ addRow( data.footer, 'th' ) +'</tfoot>'; 135 } 136 html += '</table>'; 137 138 // Open a new window for the printable table 139 var win = window.open( '', '' ); 140 141 if (! win) { 142 dt.buttons.info( 143 dt.i18n( 'buttons.printErrorTitle', 'Unable to open print view' ), 144 dt.i18n( 'buttons.printErrorMsg', 'Please allow popups in your browser for this site to be able to view the print view.' ), 145 5000 146 ); 147 148 return; 149 } 150 151 win.document.close(); 152 153 // Inject the title and also a copy of the style and link tags from this 154 // document so the table can retain its base styling. Note that we have 155 // to use string manipulation as IE won't allow elements to be created 156 // in the host document and then appended to the new window. 157 var head = '<title>'+exportInfo.title+'</title>'; 158 $('style, link').each( function () { 159 head += _styleToAbs( this ); 160 } ); 161 162 try { 163 win.document.head.innerHTML = head; // Work around for Edge 164 } 165 catch (e) { 166 $(win.document.head).html( head ); // Old IE 167 } 168 169 // Inject the table and other surrounding information 170 win.document.body.innerHTML = 171 '<h1>'+exportInfo.title+'</h1>'+ 172 '<div>'+(exportInfo.messageTop || '')+'</div>'+ 173 html+ 174 '<div>'+(exportInfo.messageBottom || '')+'</div>'; 175 176 $(win.document.body).addClass('dt-print-view'); 177 178 $('img', win.document.body).each( function ( i, img ) { 179 img.setAttribute( 'src', _relToAbs( img.getAttribute('src') ) ); 180 } ); 181 182 if ( config.customize ) { 183 config.customize( win, config, dt ); 184 } 185 186 // Allow stylesheets time to load 187 var autoPrint = function () { 188 if ( config.autoPrint ) { 189 win.print(); // blocking - so close will not 190 win.close(); // execute until this is done 191 } 192 }; 193 194 if ( navigator.userAgent.match(/Trident\/\d.\d/) ) { // IE needs to call this without a setTimeout 195 autoPrint(); 196 } 197 else { 198 win.setTimeout( autoPrint, 1000 ); 199 } 200 }, 201 202 title: '*', 203 204 messageTop: '*', 205 206 messageBottom: '*', 207 208 exportOptions: {}, 209 210 header: true, 211
212 footer: false, 213 214 autoPrint: true, 215 216 customize: null 217}; 218 219 220return DataTable.Buttons; 221}));
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.