@openui5/sap.ui.documentation 1.125.0 → 1.126.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/.reuse/dep5 +4 -4
  2. package/THIRDPARTY.txt +6 -6
  3. package/package.json +7 -7
  4. package/src/sap/ui/documentation/.library +7 -7
  5. package/src/sap/ui/documentation/library.js +2 -2
  6. package/src/sap/ui/documentation/messagebundle_ar.properties +2 -2
  7. package/src/sap/ui/documentation/sdk/Component.js +18 -14
  8. package/src/sap/ui/documentation/sdk/blocks/IndexEntry.js +1 -4
  9. package/src/sap/ui/documentation/sdk/blocks/IndexEntry.view.xml +1 -1
  10. package/src/sap/ui/documentation/sdk/blocks/IndexEntryController.controller.js +15 -0
  11. package/src/sap/ui/documentation/sdk/controller/ApiDetailIndexDeprecatedExperimental.controller.js +7 -6
  12. package/src/sap/ui/documentation/sdk/controller/ApiMaster.controller.js +17 -9
  13. package/src/sap/ui/documentation/sdk/controller/App.controller.js +1 -0
  14. package/src/sap/ui/documentation/sdk/controller/MasterTreeBaseController.js +1 -3
  15. package/src/sap/ui/documentation/sdk/controller/TopicDetail.controller.js +16 -12
  16. package/src/sap/ui/documentation/sdk/controller/config/datatable.js +1 -3
  17. package/src/sap/ui/documentation/sdk/controller/util/XML2JSONUtils.js +1 -1
  18. package/src/sap/ui/documentation/sdk/css/style.css +4 -0
  19. package/src/sap/ui/documentation/sdk/manifest.json +1 -1
  20. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/Buttons-3.0.0/css/buttons.dataTables.css +559 -0
  21. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/Buttons-3.0.0/css/buttons.jqueryui.css +414 -0
  22. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/Buttons-3.0.0/js/buttons.colVis.js +261 -0
  23. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/Buttons-3.0.0/js/buttons.html5.js +1687 -0
  24. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/Buttons-3.0.0/js/buttons.jqueryui.js +98 -0
  25. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/Buttons-3.0.0/js/dataTables.buttons.js +2750 -0
  26. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/DataTables-2.0.1/css/dataTables.jqueryui.css +1636 -0
  27. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/DataTables-2.0.1/js/dataTables.jqueryui.js +106 -0
  28. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/DataTables-2.0.1/js/dataTables.js +13429 -0
  29. package/src/sap/ui/documentation/sdk/thirdparty/highlight.js/highlight.js +3 -3
  30. package/src/sap/ui/documentation/sdk/view/ControlsMaster.view.xml +1 -1
  31. package/src/sap/ui/documentation/sdk/view/Footer.fragment.xml +11 -3
  32. package/src/sap/ui/documentation/themes/base/Documentation.less +36 -4
  33. package/src/sap/ui/documentation/themes/sap_belize/library.source.less +7 -7
  34. package/src/sap/ui/documentation/themes/sap_belize_hcb/library.source.less +7 -7
  35. package/src/sap/ui/documentation/themes/sap_belize_hcw/library.source.less +7 -7
  36. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/Buttons-1.4.0/css/buttons.jqueryui.css +0 -218
  37. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/Buttons-1.4.0/js/buttons.colVis.js +0 -206
  38. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/Buttons-1.4.0/js/buttons.html5.js +0 -1385
  39. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/Buttons-1.4.0/js/buttons.jqueryui.js +0 -62
  40. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/Buttons-1.4.0/js/dataTables.buttons.js +0 -1804
  41. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/DataTables-1.10.15/css/dataTables.jqueryui.css +0 -482
  42. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/DataTables-1.10.15/js/dataTables.jqueryui.js +0 -164
  43. package/src/sap/ui/documentation/sdk/thirdparty/DataTables/DataTables-1.10.15/js/jquery.dataTables.js +0 -15002
@@ -0,0 +1,1687 @@
1
+ /*!
2
+ * HTML5 export buttons for Buttons and DataTables.
3
+ * © SpryMedia Ltd - datatables.net/license
4
+ *
5
+ * FileSaver.js (1.3.3) - MIT license
6
+ * Copyright © 2016 Eli Grey - http://eligrey.com
7
+ */
8
+
9
+ (function( factory ){
10
+ if ( typeof define === 'function' && define.amd ) {
11
+ // AMD
12
+ define( ['jquery', 'datatables.net', 'datatables.net-buttons'], function ( $ ) {
13
+ return factory( $, window, document );
14
+ } );
15
+ }
16
+ else if ( typeof exports === 'object' ) {
17
+ // CommonJS
18
+ var jq = require('jquery');
19
+ var cjsRequires = function (root, $) {
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
+
29
+ if (typeof window === 'undefined') {
30
+ module.exports = function (root, $) {
31
+ if ( ! root ) {
32
+ // CommonJS environments without a window global must pass a
33
+ // root. This will give an error otherwise
34
+ root = window;
35
+ }
36
+
37
+ if ( ! $ ) {
38
+ $ = jq( root );
39
+ }
40
+
41
+ cjsRequires( root, $ );
42
+ return factory( $, root, root.document );
43
+ };
44
+ }
45
+ else {
46
+ cjsRequires( window, jq );
47
+ module.exports = factory( jq, window, window.document );
48
+ }
49
+ }
50
+ else {
51
+ // Browser
52
+ factory( jQuery, window, document );
53
+ }
54
+ }(function( $, window, document ) {
55
+ 'use strict';
56
+ var DataTable = $.fn.dataTable;
57
+
58
+
59
+
60
+ // Allow the constructor to pass in JSZip and PDFMake from external requires.
61
+ // Otherwise, use globally defined variables, if they are available.
62
+ var useJszip;
63
+ var usePdfmake;
64
+
65
+ function _jsZip() {
66
+ return useJszip || window.JSZip;
67
+ }
68
+ function _pdfMake() {
69
+ return usePdfmake || window.pdfMake;
70
+ }
71
+
72
+ DataTable.Buttons.pdfMake = function (_) {
73
+ if (!_) {
74
+ return _pdfMake();
75
+ }
76
+ usePdfmake = _;
77
+ };
78
+
79
+ DataTable.Buttons.jszip = function (_) {
80
+ if (!_) {
81
+ return _jsZip();
82
+ }
83
+ useJszip = _;
84
+ };
85
+
86
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
87
+ * FileSaver.js dependency
88
+ */
89
+
90
+ /*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */
91
+
92
+ var _saveAs = (function (view) {
93
+ 'use strict';
94
+ // IE <10 is explicitly unsupported
95
+ if (
96
+ typeof view === 'undefined' ||
97
+ (typeof navigator !== 'undefined' &&
98
+ /MSIE [1-9]\./.test(navigator.userAgent))
99
+ ) {
100
+ return;
101
+ }
102
+ var doc = view.document,
103
+ // only get URL when necessary in case Blob.js hasn't overridden it yet
104
+ get_URL = function () {
105
+ return view.URL || view.webkitURL || view;
106
+ },
107
+ save_link = doc.createElementNS('http://www.w3.org/1999/xhtml', 'a'),
108
+ can_use_save_link = 'download' in save_link,
109
+ click = function (node) {
110
+ var event = new MouseEvent('click');
111
+ node.dispatchEvent(event);
112
+ },
113
+ is_safari = /constructor/i.test(view.HTMLElement) || view.safari,
114
+ is_chrome_ios = /CriOS\/[\d]+/.test(navigator.userAgent),
115
+ throw_outside = function (ex) {
116
+ (view.setImmediate || view.setTimeout)(function () {
117
+ throw ex;
118
+ }, 0);
119
+ },
120
+ force_saveable_type = 'application/octet-stream',
121
+ // the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
122
+ arbitrary_revoke_timeout = 1000 * 40, // in ms
123
+ revoke = function (file) {
124
+ var revoker = function () {
125
+ if (typeof file === 'string') {
126
+ // file is an object URL
127
+ get_URL().revokeObjectURL(file);
128
+ }
129
+ else {
130
+ // file is a File
131
+ file.remove();
132
+ }
133
+ };
134
+ setTimeout(revoker, arbitrary_revoke_timeout);
135
+ },
136
+ dispatch = function (filesaver, event_types, event) {
137
+ event_types = [].concat(event_types);
138
+ var i = event_types.length;
139
+ while (i--) {
140
+ var listener = filesaver['on' + event_types[i]];
141
+ if (typeof listener === 'function') {
142
+ try {
143
+ listener.call(filesaver, event || filesaver);
144
+ } catch (ex) {
145
+ throw_outside(ex);
146
+ }
147
+ }
148
+ }
149
+ },
150
+ auto_bom = function (blob) {
151
+ // prepend BOM for UTF-8 XML and text/* types (including HTML)
152
+ // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
153
+ if (
154
+ /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(
155
+ blob.type
156
+ )
157
+ ) {
158
+ return new Blob([String.fromCharCode(0xfeff), blob], {
159
+ type: blob.type
160
+ });
161
+ }
162
+ return blob;
163
+ },
164
+ FileSaver = function (blob, name, no_auto_bom) {
165
+ if (!no_auto_bom) {
166
+ blob = auto_bom(blob);
167
+ }
168
+ // First try a.download, then web filesystem, then object URLs
169
+ var filesaver = this,
170
+ type = blob.type,
171
+ force = type === force_saveable_type,
172
+ object_url,
173
+ dispatch_all = function () {
174
+ dispatch(
175
+ filesaver,
176
+ 'writestart progress write writeend'.split(' ')
177
+ );
178
+ },
179
+ // on any filesys errors revert to saving with object URLs
180
+ fs_error = function () {
181
+ if (
182
+ (is_chrome_ios || (force && is_safari)) &&
183
+ view.FileReader
184
+ ) {
185
+ // Safari doesn't allow downloading of blob urls
186
+ var reader = new FileReader();
187
+ reader.onloadend = function () {
188
+ var url = is_chrome_ios
189
+ ? reader.result
190
+ : reader.result.replace(
191
+ /^data:[^;]*;/,
192
+ 'data:attachment/file;'
193
+ );
194
+ var popup = view.open(url, '_blank');
195
+ if (!popup) view.location.href = url;
196
+ url = undefined; // release reference before dispatching
197
+ filesaver.readyState = filesaver.DONE;
198
+ dispatch_all();
199
+ };
200
+ reader.readAsDataURL(blob);
201
+ filesaver.readyState = filesaver.INIT;
202
+ return;
203
+ }
204
+ // don't create more object URLs than needed
205
+ if (!object_url) {
206
+ object_url = get_URL().createObjectURL(blob);
207
+ }
208
+ if (force) {
209
+ view.location.href = object_url;
210
+ }
211
+ else {
212
+ var opened = view.open(object_url, '_blank');
213
+ if (!opened) {
214
+ // Apple does not allow window.open, see https://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
215
+ view.location.href = object_url;
216
+ }
217
+ }
218
+ filesaver.readyState = filesaver.DONE;
219
+ dispatch_all();
220
+ revoke(object_url);
221
+ };
222
+ filesaver.readyState = filesaver.INIT;
223
+
224
+ if (can_use_save_link) {
225
+ object_url = get_URL().createObjectURL(blob);
226
+ setTimeout(function () {
227
+ save_link.href = object_url;
228
+ save_link.download = name;
229
+ click(save_link);
230
+ dispatch_all();
231
+ revoke(object_url);
232
+ filesaver.readyState = filesaver.DONE;
233
+ });
234
+ return;
235
+ }
236
+
237
+ fs_error();
238
+ },
239
+ FS_proto = FileSaver.prototype,
240
+ saveAs = function (blob, name, no_auto_bom) {
241
+ return new FileSaver(
242
+ blob,
243
+ name || blob.name || 'download',
244
+ no_auto_bom
245
+ );
246
+ };
247
+ // IE 10+ (native saveAs)
248
+ if (typeof navigator !== 'undefined' && navigator.msSaveOrOpenBlob) {
249
+ return function (blob, name, no_auto_bom) {
250
+ name = name || blob.name || 'download';
251
+
252
+ if (!no_auto_bom) {
253
+ blob = auto_bom(blob);
254
+ }
255
+ return navigator.msSaveOrOpenBlob(blob, name);
256
+ };
257
+ }
258
+
259
+ FS_proto.abort = function () {};
260
+ FS_proto.readyState = FS_proto.INIT = 0;
261
+ FS_proto.WRITING = 1;
262
+ FS_proto.DONE = 2;
263
+
264
+ FS_proto.error =
265
+ FS_proto.onwritestart =
266
+ FS_proto.onprogress =
267
+ FS_proto.onwrite =
268
+ FS_proto.onabort =
269
+ FS_proto.onerror =
270
+ FS_proto.onwriteend =
271
+ null;
272
+
273
+ return saveAs;
274
+ })(
275
+ (typeof self !== 'undefined' && self) ||
276
+ (typeof window !== 'undefined' && window) ||
277
+ this.content
278
+ );
279
+
280
+ // Expose file saver on the DataTables API. Can't attach to `DataTables.Buttons`
281
+ // since this file can be loaded before Button's core!
282
+ DataTable.fileSave = _saveAs;
283
+
284
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
285
+ * Local (private) functions
286
+ */
287
+
288
+ /**
289
+ * Get the sheet name for Excel exports.
290
+ *
291
+ * @param {object} config Button configuration
292
+ */
293
+ var _sheetname = function (config) {
294
+ var sheetName = 'Sheet1';
295
+
296
+ if (config.sheetName) {
297
+ sheetName = config.sheetName.replace(/[\[\]\*\/\\\?\:]/g, '');
298
+ }
299
+
300
+ return sheetName;
301
+ };
302
+
303
+ /**
304
+ * Get the newline character(s)
305
+ *
306
+ * @param {object} config Button configuration
307
+ * @return {string} Newline character
308
+ */
309
+ var _newLine = function (config) {
310
+ return config.newline
311
+ ? config.newline
312
+ : navigator.userAgent.match(/Windows/)
313
+ ? '\r\n'
314
+ : '\n';
315
+ };
316
+
317
+ /**
318
+ * Combine the data from the `buttons.exportData` method into a string that
319
+ * will be used in the export file.
320
+ *
321
+ * @param {DataTable.Api} dt DataTables API instance
322
+ * @param {object} config Button configuration
323
+ * @return {object} The data to export
324
+ */
325
+ var _exportData = function (dt, config) {
326
+ var newLine = _newLine(config);
327
+ var data = dt.buttons.exportData(config.exportOptions);
328
+ var boundary = config.fieldBoundary;
329
+ var separator = config.fieldSeparator;
330
+ var reBoundary = new RegExp(boundary, 'g');
331
+ var escapeChar = config.escapeChar !== undefined ? config.escapeChar : '\\';
332
+ var join = function (a) {
333
+ var s = '';
334
+
335
+ // If there is a field boundary, then we might need to escape it in
336
+ // the source data
337
+ for (var i = 0, ien = a.length; i < ien; i++) {
338
+ if (i > 0) {
339
+ s += separator;
340
+ }
341
+
342
+ s += boundary
343
+ ? boundary +
344
+ ('' + a[i]).replace(reBoundary, escapeChar + boundary) +
345
+ boundary
346
+ : a[i];
347
+ }
348
+
349
+ return s;
350
+ };
351
+
352
+ var header = '';
353
+ var footer = '';
354
+ var body = [];
355
+
356
+ if (config.header) {
357
+ header =
358
+ data.headerStructure
359
+ .map(function (row) {
360
+ return join(
361
+ row.map(function (cell) {
362
+ return cell ? cell.title : '';
363
+ })
364
+ );
365
+ })
366
+ .join(newLine) + newLine;
367
+ }
368
+
369
+ if (config.footer && data.footer) {
370
+ footer =
371
+ data.footerStructure
372
+ .map(function (row) {
373
+ return join(
374
+ row.map(function (cell) {
375
+ return cell ? cell.title : '';
376
+ })
377
+ );
378
+ })
379
+ .join(newLine) + newLine;
380
+ }
381
+
382
+ for (var i = 0, ien = data.body.length; i < ien; i++) {
383
+ body.push(join(data.body[i]));
384
+ }
385
+
386
+ return {
387
+ str: header + body.join(newLine) + footer,
388
+ rows: body.length
389
+ };
390
+ };
391
+
392
+ /**
393
+ * Older versions of Safari (prior to tech preview 18) don't support the
394
+ * download option required.
395
+ *
396
+ * @return {Boolean} `true` if old Safari
397
+ */
398
+ var _isDuffSafari = function () {
399
+ var safari =
400
+ navigator.userAgent.indexOf('Safari') !== -1 &&
401
+ navigator.userAgent.indexOf('Chrome') === -1 &&
402
+ navigator.userAgent.indexOf('Opera') === -1;
403
+
404
+ if (!safari) {
405
+ return false;
406
+ }
407
+
408
+ var version = navigator.userAgent.match(/AppleWebKit\/(\d+\.\d+)/);
409
+ if (version && version.length > 1 && version[1] * 1 < 603.1) {
410
+ return true;
411
+ }
412
+
413
+ return false;
414
+ };
415
+
416
+ /**
417
+ * Convert from numeric position to letter for column names in Excel
418
+ * @param {int} n Column number
419
+ * @return {string} Column letter(s) name
420
+ */
421
+ function createCellPos(n) {
422
+ var ordA = 'A'.charCodeAt(0);
423
+ var ordZ = 'Z'.charCodeAt(0);
424
+ var len = ordZ - ordA + 1;
425
+ var s = '';
426
+
427
+ while (n >= 0) {
428
+ s = String.fromCharCode((n % len) + ordA) + s;
429
+ n = Math.floor(n / len) - 1;
430
+ }
431
+
432
+ return s;
433
+ }
434
+
435
+ try {
436
+ var _serialiser = new XMLSerializer();
437
+ var _ieExcel;
438
+ } catch (t) {
439
+ // noop
440
+ }
441
+
442
+ /**
443
+ * Recursively add XML files from an object's structure to a ZIP file. This
444
+ * allows the XSLX file to be easily defined with an object's structure matching
445
+ * the files structure.
446
+ *
447
+ * @param {JSZip} zip ZIP package
448
+ * @param {object} obj Object to add (recursive)
449
+ */
450
+ function _addToZip(zip, obj) {
451
+ if (_ieExcel === undefined) {
452
+ // Detect if we are dealing with IE's _awful_ serialiser by seeing if it
453
+ // drop attributes
454
+ _ieExcel =
455
+ _serialiser
456
+ .serializeToString(
457
+ new window.DOMParser().parseFromString(
458
+ excelStrings['xl/worksheets/sheet1.xml'],
459
+ 'text/xml'
460
+ )
461
+ )
462
+ .indexOf('xmlns:r') === -1;
463
+ }
464
+
465
+ $.each(obj, function (name, val) {
466
+ if ($.isPlainObject(val)) {
467
+ var newDir = zip.folder(name);
468
+ _addToZip(newDir, val);
469
+ }
470
+ else {
471
+ if (_ieExcel) {
472
+ // IE's XML serialiser will drop some name space attributes from
473
+ // from the root node, so we need to save them. Do this by
474
+ // replacing the namespace nodes with a regular attribute that
475
+ // we convert back when serialised. Edge does not have this
476
+ // issue
477
+ var worksheet = val.childNodes[0];
478
+ var i, ien;
479
+ var attrs = [];
480
+
481
+ for (i = worksheet.attributes.length - 1; i >= 0; i--) {
482
+ var attrName = worksheet.attributes[i].nodeName;
483
+ var attrValue = worksheet.attributes[i].nodeValue;
484
+
485
+ if (attrName.indexOf(':') !== -1) {
486
+ attrs.push({ name: attrName, value: attrValue });
487
+
488
+ worksheet.removeAttribute(attrName);
489
+ }
490
+ }
491
+
492
+ for (i = 0, ien = attrs.length; i < ien; i++) {
493
+ var attr = val.createAttribute(
494
+ attrs[i].name.replace(':', '_dt_b_namespace_token_')
495
+ );
496
+ attr.value = attrs[i].value;
497
+ worksheet.setAttributeNode(attr);
498
+ }
499
+ }
500
+
501
+ var str = _serialiser.serializeToString(val);
502
+
503
+ // Fix IE's XML
504
+ if (_ieExcel) {
505
+ // IE doesn't include the XML declaration
506
+ if (str.indexOf('<?xml') === -1) {
507
+ str =
508
+ '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
509
+ str;
510
+ }
511
+
512
+ // Return namespace attributes to being as such
513
+ str = str.replace(/_dt_b_namespace_token_/g, ':');
514
+
515
+ // Remove testing name space that IE puts into the space preserve attr
516
+ str = str.replace(/xmlns:NS[\d]+="" NS[\d]+:/g, '');
517
+ }
518
+
519
+ // Safari, IE and Edge will put empty name space attributes onto
520
+ // various elements making them useless. This strips them out
521
+ str = str.replace(/<([^<>]*?) xmlns=""([^<>]*?)>/g, '<$1 $2>');
522
+
523
+ zip.file(name, str);
524
+ }
525
+ });
526
+ }
527
+
528
+ /**
529
+ * Create an XML node and add any children, attributes, etc without needing to
530
+ * be verbose in the DOM.
531
+ *
532
+ * @param {object} doc XML document
533
+ * @param {string} nodeName Node name
534
+ * @param {object} opts Options - can be `attr` (attributes), `children`
535
+ * (child nodes) and `text` (text content)
536
+ * @return {node} Created node
537
+ */
538
+ function _createNode(doc, nodeName, opts) {
539
+ var tempNode = doc.createElement(nodeName);
540
+
541
+ if (opts) {
542
+ if (opts.attr) {
543
+ $(tempNode).attr(opts.attr);
544
+ }
545
+
546
+ if (opts.children) {
547
+ $.each(opts.children, function (key, value) {
548
+ tempNode.appendChild(value);
549
+ });
550
+ }
551
+
552
+ if (opts.text !== null && opts.text !== undefined) {
553
+ tempNode.appendChild(doc.createTextNode(opts.text));
554
+ }
555
+ }
556
+
557
+ return tempNode;
558
+ }
559
+
560
+ /**
561
+ * Get the width for an Excel column based on the contents of that column
562
+ * @param {object} data Data for export
563
+ * @param {int} col Column index
564
+ * @return {int} Column width
565
+ */
566
+ function _excelColWidth(data, col) {
567
+ var max = data.header[col].length;
568
+ var len, lineSplit, str;
569
+
570
+ if (data.footer && data.footer[col].length > max) {
571
+ max = data.footer[col].length;
572
+ }
573
+
574
+ for (var i = 0, ien = data.body.length; i < ien; i++) {
575
+ var point = data.body[i][col];
576
+ str = point !== null && point !== undefined ? point.toString() : '';
577
+
578
+ // If there is a newline character, workout the width of the column
579
+ // based on the longest line in the string
580
+ if (str.indexOf('\n') !== -1) {
581
+ lineSplit = str.split('\n');
582
+ lineSplit.sort(function (a, b) {
583
+ return b.length - a.length;
584
+ });
585
+
586
+ len = lineSplit[0].length;
587
+ }
588
+ else {
589
+ len = str.length;
590
+ }
591
+
592
+ if (len > max) {
593
+ max = len;
594
+ }
595
+
596
+ // Max width rather than having potentially massive column widths
597
+ if (max > 40) {
598
+ return 54; // 40 * 1.35
599
+ }
600
+ }
601
+
602
+ max *= 1.35;
603
+
604
+ // And a min width
605
+ return max > 6 ? max : 6;
606
+ }
607
+
608
+ // Excel - Pre-defined strings to build a basic XLSX file
609
+ var excelStrings = {
610
+ '_rels/.rels':
611
+ '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
612
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">' +
613
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/>' +
614
+ '</Relationships>',
615
+
616
+ 'xl/_rels/workbook.xml.rels':
617
+ '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
618
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">' +
619
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/>' +
620
+ '<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/>' +
621
+ '</Relationships>',
622
+
623
+ '[Content_Types].xml':
624
+ '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
625
+ '<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">' +
626
+ '<Default Extension="xml" ContentType="application/xml" />' +
627
+ '<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml" />' +
628
+ '<Default Extension="jpeg" ContentType="image/jpeg" />' +
629
+ '<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml" />' +
630
+ '<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml" />' +
631
+ '<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml" />' +
632
+ '</Types>',
633
+
634
+ 'xl/workbook.xml':
635
+ '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
636
+ '<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">' +
637
+ '<fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="24816"/>' +
638
+ '<workbookPr showInkAnnotation="0" autoCompressPictures="0"/>' +
639
+ '<bookViews>' +
640
+ '<workbookView xWindow="0" yWindow="0" windowWidth="25600" windowHeight="19020" tabRatio="500"/>' +
641
+ '</bookViews>' +
642
+ '<sheets>' +
643
+ '<sheet name="Sheet1" sheetId="1" r:id="rId1"/>' +
644
+ '</sheets>' +
645
+ '<definedNames/>' +
646
+ '</workbook>',
647
+
648
+ 'xl/worksheets/sheet1.xml':
649
+ '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>' +
650
+ '<worksheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">' +
651
+ '<sheetData/>' +
652
+ '<mergeCells count="0"/>' +
653
+ '</worksheet>',
654
+
655
+ 'xl/styles.xml':
656
+ '<?xml version="1.0" encoding="UTF-8"?>' +
657
+ '<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x14ac" xmlns:x14ac="http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac">' +
658
+ '<numFmts count="6">' +
659
+ '<numFmt numFmtId="164" formatCode="[$$-409]#,##0.00;-[$$-409]#,##0.00"/>' +
660
+ '<numFmt numFmtId="165" formatCode="&quot;£&quot;#,##0.00"/>' +
661
+ '<numFmt numFmtId="166" formatCode="[$€-2] #,##0.00"/>' +
662
+ '<numFmt numFmtId="167" formatCode="0.0%"/>' +
663
+ '<numFmt numFmtId="168" formatCode="#,##0;(#,##0)"/>' +
664
+ '<numFmt numFmtId="169" formatCode="#,##0.00;(#,##0.00)"/>' +
665
+ '</numFmts>' +
666
+ '<fonts count="5" x14ac:knownFonts="1">' +
667
+ '<font>' +
668
+ '<sz val="11" />' +
669
+ '<name val="Calibri" />' +
670
+ '</font>' +
671
+ '<font>' +
672
+ '<sz val="11" />' +
673
+ '<name val="Calibri" />' +
674
+ '<color rgb="FFFFFFFF" />' +
675
+ '</font>' +
676
+ '<font>' +
677
+ '<sz val="11" />' +
678
+ '<name val="Calibri" />' +
679
+ '<b />' +
680
+ '</font>' +
681
+ '<font>' +
682
+ '<sz val="11" />' +
683
+ '<name val="Calibri" />' +
684
+ '<i />' +
685
+ '</font>' +
686
+ '<font>' +
687
+ '<sz val="11" />' +
688
+ '<name val="Calibri" />' +
689
+ '<u />' +
690
+ '</font>' +
691
+ '</fonts>' +
692
+ '<fills count="6">' +
693
+ '<fill>' +
694
+ '<patternFill patternType="none" />' +
695
+ '</fill>' +
696
+ '<fill>' + // Excel appears to use this as a dotted background regardless of values but
697
+ '<patternFill patternType="none" />' + // to be valid to the schema, use a patternFill
698
+ '</fill>' +
699
+ '<fill>' +
700
+ '<patternFill patternType="solid">' +
701
+ '<fgColor rgb="FFD9D9D9" />' +
702
+ '<bgColor indexed="64" />' +
703
+ '</patternFill>' +
704
+ '</fill>' +
705
+ '<fill>' +
706
+ '<patternFill patternType="solid">' +
707
+ '<fgColor rgb="FFD99795" />' +
708
+ '<bgColor indexed="64" />' +
709
+ '</patternFill>' +
710
+ '</fill>' +
711
+ '<fill>' +
712
+ '<patternFill patternType="solid">' +
713
+ '<fgColor rgb="ffc6efce" />' +
714
+ '<bgColor indexed="64" />' +
715
+ '</patternFill>' +
716
+ '</fill>' +
717
+ '<fill>' +
718
+ '<patternFill patternType="solid">' +
719
+ '<fgColor rgb="ffc6cfef" />' +
720
+ '<bgColor indexed="64" />' +
721
+ '</patternFill>' +
722
+ '</fill>' +
723
+ '</fills>' +
724
+ '<borders count="2">' +
725
+ '<border>' +
726
+ '<left />' +
727
+ '<right />' +
728
+ '<top />' +
729
+ '<bottom />' +
730
+ '<diagonal />' +
731
+ '</border>' +
732
+ '<border diagonalUp="false" diagonalDown="false">' +
733
+ '<left style="thin">' +
734
+ '<color auto="1" />' +
735
+ '</left>' +
736
+ '<right style="thin">' +
737
+ '<color auto="1" />' +
738
+ '</right>' +
739
+ '<top style="thin">' +
740
+ '<color auto="1" />' +
741
+ '</top>' +
742
+ '<bottom style="thin">' +
743
+ '<color auto="1" />' +
744
+ '</bottom>' +
745
+ '<diagonal />' +
746
+ '</border>' +
747
+ '</borders>' +
748
+ '<cellStyleXfs count="1">' +
749
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" />' +
750
+ '</cellStyleXfs>' +
751
+ '<cellXfs count="68">' +
752
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
753
+ '<xf numFmtId="0" fontId="1" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
754
+ '<xf numFmtId="0" fontId="2" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
755
+ '<xf numFmtId="0" fontId="3" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
756
+ '<xf numFmtId="0" fontId="4" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
757
+ '<xf numFmtId="0" fontId="0" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
758
+ '<xf numFmtId="0" fontId="1" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
759
+ '<xf numFmtId="0" fontId="2" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
760
+ '<xf numFmtId="0" fontId="3" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
761
+ '<xf numFmtId="0" fontId="4" fillId="2" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
762
+ '<xf numFmtId="0" fontId="0" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
763
+ '<xf numFmtId="0" fontId="1" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
764
+ '<xf numFmtId="0" fontId="2" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
765
+ '<xf numFmtId="0" fontId="3" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
766
+ '<xf numFmtId="0" fontId="4" fillId="3" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
767
+ '<xf numFmtId="0" fontId="0" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
768
+ '<xf numFmtId="0" fontId="1" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
769
+ '<xf numFmtId="0" fontId="2" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
770
+ '<xf numFmtId="0" fontId="3" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
771
+ '<xf numFmtId="0" fontId="4" fillId="4" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
772
+ '<xf numFmtId="0" fontId="0" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
773
+ '<xf numFmtId="0" fontId="1" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
774
+ '<xf numFmtId="0" fontId="2" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
775
+ '<xf numFmtId="0" fontId="3" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
776
+ '<xf numFmtId="0" fontId="4" fillId="5" borderId="0" applyFont="1" applyFill="1" applyBorder="1"/>' +
777
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
778
+ '<xf numFmtId="0" fontId="1" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
779
+ '<xf numFmtId="0" fontId="2" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
780
+ '<xf numFmtId="0" fontId="3" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
781
+ '<xf numFmtId="0" fontId="4" fillId="0" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
782
+ '<xf numFmtId="0" fontId="0" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
783
+ '<xf numFmtId="0" fontId="1" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
784
+ '<xf numFmtId="0" fontId="2" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
785
+ '<xf numFmtId="0" fontId="3" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
786
+ '<xf numFmtId="0" fontId="4" fillId="2" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
787
+ '<xf numFmtId="0" fontId="0" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
788
+ '<xf numFmtId="0" fontId="1" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
789
+ '<xf numFmtId="0" fontId="2" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
790
+ '<xf numFmtId="0" fontId="3" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
791
+ '<xf numFmtId="0" fontId="4" fillId="3" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
792
+ '<xf numFmtId="0" fontId="0" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
793
+ '<xf numFmtId="0" fontId="1" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
794
+ '<xf numFmtId="0" fontId="2" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
795
+ '<xf numFmtId="0" fontId="3" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
796
+ '<xf numFmtId="0" fontId="4" fillId="4" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
797
+ '<xf numFmtId="0" fontId="0" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
798
+ '<xf numFmtId="0" fontId="1" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
799
+ '<xf numFmtId="0" fontId="2" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
800
+ '<xf numFmtId="0" fontId="3" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
801
+ '<xf numFmtId="0" fontId="4" fillId="5" borderId="1" applyFont="1" applyFill="1" applyBorder="1"/>' +
802
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">' +
803
+ '<alignment horizontal="left"/>' +
804
+ '</xf>' +
805
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">' +
806
+ '<alignment horizontal="center"/>' +
807
+ '</xf>' +
808
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">' +
809
+ '<alignment horizontal="right"/>' +
810
+ '</xf>' +
811
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">' +
812
+ '<alignment horizontal="fill"/>' +
813
+ '</xf>' +
814
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">' +
815
+ '<alignment textRotation="90"/>' +
816
+ '</xf>' +
817
+ '<xf numFmtId="0" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyAlignment="1">' +
818
+ '<alignment wrapText="1"/>' +
819
+ '</xf>' +
820
+ '<xf numFmtId="9" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
821
+ '<xf numFmtId="164" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
822
+ '<xf numFmtId="165" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
823
+ '<xf numFmtId="166" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
824
+ '<xf numFmtId="167" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
825
+ '<xf numFmtId="168" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
826
+ '<xf numFmtId="169" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
827
+ '<xf numFmtId="3" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
828
+ '<xf numFmtId="4" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
829
+ '<xf numFmtId="1" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
830
+ '<xf numFmtId="2" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
831
+ '<xf numFmtId="14" fontId="0" fillId="0" borderId="0" applyFont="1" applyFill="1" applyBorder="1" xfId="0" applyNumberFormat="1"/>' +
832
+ '</cellXfs>' +
833
+ '<cellStyles count="1">' +
834
+ '<cellStyle name="Normal" xfId="0" builtinId="0" />' +
835
+ '</cellStyles>' +
836
+ '<dxfs count="0" />' +
837
+ '<tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4" />' +
838
+ '</styleSheet>'
839
+ };
840
+ // Note we could use 3 `for` loops for the styles, but when gzipped there is
841
+ // virtually no difference in size, since the above can be easily compressed
842
+
843
+ // Pattern matching for special number formats. Perhaps this should be exposed
844
+ // via an API in future?
845
+ // Ref: section 3.8.30 - built in formatters in open spreadsheet
846
+ // https://www.ecma-international.org/news/TC45_current_work/Office%20Open%20XML%20Part%204%20-%20Markup%20Language%20Reference.pdf
847
+ var _excelSpecials = [
848
+ {
849
+ match: /^\-?\d+\.\d%$/,
850
+ style: 60,
851
+ fmt: function (d) {
852
+ return d / 100;
853
+ }
854
+ }, // Percent with d.p.
855
+ {
856
+ match: /^\-?\d+\.?\d*%$/,
857
+ style: 56,
858
+ fmt: function (d) {
859
+ return d / 100;
860
+ }
861
+ }, // Percent
862
+ { match: /^\-?\$[\d,]+.?\d*$/, style: 57 }, // Dollars
863
+ { match: /^\-?£[\d,]+.?\d*$/, style: 58 }, // Pounds
864
+ { match: /^\-?€[\d,]+.?\d*$/, style: 59 }, // Euros
865
+ { match: /^\-?\d+$/, style: 65 }, // Numbers without thousand separators
866
+ { match: /^\-?\d+\.\d{2}$/, style: 66 }, // Numbers 2 d.p. without thousands separators
867
+ {
868
+ match: /^\([\d,]+\)$/,
869
+ style: 61,
870
+ fmt: function (d) {
871
+ return -1 * d.replace(/[\(\)]/g, '');
872
+ }
873
+ }, // Negative numbers indicated by brackets
874
+ {
875
+ match: /^\([\d,]+\.\d{2}\)$/,
876
+ style: 62,
877
+ fmt: function (d) {
878
+ return -1 * d.replace(/[\(\)]/g, '');
879
+ }
880
+ }, // Negative numbers indicated by brackets - 2d.p.
881
+ { match: /^\-?[\d,]+$/, style: 63 }, // Numbers with thousand separators
882
+ { match: /^\-?[\d,]+\.\d{2}$/, style: 64 },
883
+ {
884
+ match: /^[\d]{4}\-[01][\d]\-[0123][\d]$/,
885
+ style: 67,
886
+ fmt: function (d) {
887
+ return Math.round(25569 + Date.parse(d) / (86400 * 1000));
888
+ }
889
+ } //Date yyyy-mm-dd
890
+ ];
891
+
892
+ var _excelMergeCells = function (rels, row, column, rowspan, colspan) {
893
+ var mergeCells = $('mergeCells', rels);
894
+
895
+ mergeCells[0].appendChild(
896
+ _createNode(rels, 'mergeCell', {
897
+ attr: {
898
+ ref:
899
+ createCellPos(column) +
900
+ row +
901
+ ':' +
902
+ createCellPos(column + colspan - 1) +
903
+ (row + rowspan - 1)
904
+ }
905
+ })
906
+ );
907
+
908
+ mergeCells.attr('count', parseFloat(mergeCells.attr('count')) + 1);
909
+ };
910
+
911
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
912
+ * Buttons
913
+ */
914
+
915
+ //
916
+ // Copy to clipboard
917
+ //
918
+ DataTable.ext.buttons.copyHtml5 = {
919
+ className: 'buttons-copy buttons-html5',
920
+
921
+ text: function (dt) {
922
+ return dt.i18n('buttons.copy', 'Copy');
923
+ },
924
+
925
+ action: function (e, dt, button, config, cb) {
926
+ var exportData = _exportData(dt, config);
927
+ var info = dt.buttons.exportInfo(config);
928
+ var newline = _newLine(config);
929
+ var output = exportData.str;
930
+ var hiddenDiv = $('<div/>').css({
931
+ height: 1,
932
+ width: 1,
933
+ overflow: 'hidden',
934
+ position: 'fixed',
935
+ top: 0,
936
+ left: 0
937
+ });
938
+
939
+ if (info.title) {
940
+ output = info.title + newline + newline + output;
941
+ }
942
+
943
+ if (info.messageTop) {
944
+ output = info.messageTop + newline + newline + output;
945
+ }
946
+
947
+ if (info.messageBottom) {
948
+ output = output + newline + newline + info.messageBottom;
949
+ }
950
+
951
+ if (config.customize) {
952
+ output = config.customize(output, config, dt);
953
+ }
954
+
955
+ var textarea = $('<textarea readonly/>')
956
+ .val(output)
957
+ .appendTo(hiddenDiv);
958
+
959
+ // For browsers that support the copy execCommand, try to use it
960
+ if (document.queryCommandSupported('copy')) {
961
+ hiddenDiv.appendTo(dt.table().container());
962
+ textarea[0].focus();
963
+ textarea[0].select();
964
+
965
+ try {
966
+ var successful = document.execCommand('copy');
967
+ hiddenDiv.remove();
968
+
969
+ if (successful) {
970
+ dt.buttons.info(
971
+ dt.i18n('buttons.copyTitle', 'Copy to clipboard'),
972
+ dt.i18n(
973
+ 'buttons.copySuccess',
974
+ {
975
+ 1: 'Copied one row to clipboard',
976
+ _: 'Copied %d rows to clipboard'
977
+ },
978
+ exportData.rows
979
+ ),
980
+ 2000
981
+ );
982
+
983
+ cb();
984
+ return;
985
+ }
986
+ } catch (t) {
987
+ // noop
988
+ }
989
+ }
990
+
991
+ // Otherwise we show the text box and instruct the user to use it
992
+ var message = $(
993
+ '<span>' +
994
+ dt.i18n(
995
+ 'buttons.copyKeys',
996
+ 'Press <i>ctrl</i> or <i>\u2318</i> + <i>C</i> to copy the table data<br>to your system clipboard.<br><br>' +
997
+ 'To cancel, click this message or press escape.'
998
+ ) +
999
+ '</span>'
1000
+ ).append(hiddenDiv);
1001
+
1002
+ dt.buttons.info(
1003
+ dt.i18n('buttons.copyTitle', 'Copy to clipboard'),
1004
+ message,
1005
+ 0
1006
+ );
1007
+
1008
+ // Select the text so when the user activates their system clipboard
1009
+ // it will copy that text
1010
+ textarea[0].focus();
1011
+ textarea[0].select();
1012
+
1013
+ // Event to hide the message when the user is done
1014
+ var container = $(message).closest('.dt-button-info');
1015
+ var close = function () {
1016
+ container.off('click.buttons-copy');
1017
+ $(document).off('.buttons-copy');
1018
+ dt.buttons.info(false);
1019
+ };
1020
+
1021
+ container.on('click.buttons-copy', close);
1022
+ $(document)
1023
+ .on('keydown.buttons-copy', function (e) {
1024
+ if (e.keyCode === 27) {
1025
+ // esc
1026
+ close();
1027
+ cb();
1028
+ }
1029
+ })
1030
+ .on('copy.buttons-copy cut.buttons-copy', function () {
1031
+ close();
1032
+ cb();
1033
+ });
1034
+ },
1035
+
1036
+ async: 100,
1037
+
1038
+ exportOptions: {},
1039
+
1040
+ fieldSeparator: '\t',
1041
+
1042
+ fieldBoundary: '',
1043
+
1044
+ header: true,
1045
+
1046
+ footer: false,
1047
+
1048
+ title: '*',
1049
+
1050
+ messageTop: '*',
1051
+
1052
+ messageBottom: '*'
1053
+ };
1054
+
1055
+ //
1056
+ // CSV export
1057
+ //
1058
+ DataTable.ext.buttons.csvHtml5 = {
1059
+ bom: false,
1060
+
1061
+ className: 'buttons-csv buttons-html5',
1062
+
1063
+ available: function () {
1064
+ return window.FileReader !== undefined && window.Blob;
1065
+ },
1066
+
1067
+ text: function (dt) {
1068
+ return dt.i18n('buttons.csv', 'CSV');
1069
+ },
1070
+
1071
+ action: function (e, dt, button, config, cb) {
1072
+ // Set the text
1073
+ var output = _exportData(dt, config).str;
1074
+ var info = dt.buttons.exportInfo(config);
1075
+ var charset = config.charset;
1076
+
1077
+ if (config.customize) {
1078
+ output = config.customize(output, config, dt);
1079
+ }
1080
+
1081
+ if (charset !== false) {
1082
+ if (!charset) {
1083
+ charset = document.characterSet || document.charset;
1084
+ }
1085
+
1086
+ if (charset) {
1087
+ charset = ';charset=' + charset;
1088
+ }
1089
+ }
1090
+ else {
1091
+ charset = '';
1092
+ }
1093
+
1094
+ if (config.bom) {
1095
+ output = String.fromCharCode(0xfeff) + output;
1096
+ }
1097
+
1098
+ _saveAs(
1099
+ new Blob([output], { type: 'text/csv' + charset }),
1100
+ info.filename,
1101
+ true
1102
+ );
1103
+
1104
+ cb();
1105
+ },
1106
+
1107
+ async: 100,
1108
+
1109
+ filename: '*',
1110
+
1111
+ extension: '.csv',
1112
+
1113
+ exportOptions: {},
1114
+
1115
+ fieldSeparator: ',',
1116
+
1117
+ fieldBoundary: '"',
1118
+
1119
+ escapeChar: '"',
1120
+
1121
+ charset: null,
1122
+
1123
+ header: true,
1124
+
1125
+ footer: false
1126
+ };
1127
+
1128
+ //
1129
+ // Excel (xlsx) export
1130
+ //
1131
+ DataTable.ext.buttons.excelHtml5 = {
1132
+ className: 'buttons-excel buttons-html5',
1133
+
1134
+ available: function () {
1135
+ return (
1136
+ window.FileReader !== undefined &&
1137
+ _jsZip() !== undefined &&
1138
+ !_isDuffSafari() &&
1139
+ _serialiser
1140
+ );
1141
+ },
1142
+
1143
+ text: function (dt) {
1144
+ return dt.i18n('buttons.excel', 'Excel');
1145
+ },
1146
+
1147
+ action: function (e, dt, button, config, cb) {
1148
+ var rowPos = 0;
1149
+ var dataStartRow, dataEndRow;
1150
+ var getXml = function (type) {
1151
+ var str = excelStrings[type];
1152
+
1153
+ //str = str.replace( /xmlns:/g, 'xmlns_' ).replace( /mc:/g, 'mc_' );
1154
+
1155
+ return $.parseXML(str);
1156
+ };
1157
+ var rels = getXml('xl/worksheets/sheet1.xml');
1158
+ var relsGet = rels.getElementsByTagName('sheetData')[0];
1159
+
1160
+ var xlsx = {
1161
+ _rels: {
1162
+ '.rels': getXml('_rels/.rels')
1163
+ },
1164
+ xl: {
1165
+ _rels: {
1166
+ 'workbook.xml.rels': getXml('xl/_rels/workbook.xml.rels')
1167
+ },
1168
+ 'workbook.xml': getXml('xl/workbook.xml'),
1169
+ 'styles.xml': getXml('xl/styles.xml'),
1170
+ worksheets: {
1171
+ 'sheet1.xml': rels
1172
+ }
1173
+ },
1174
+ '[Content_Types].xml': getXml('[Content_Types].xml')
1175
+ };
1176
+
1177
+ var data = dt.buttons.exportData(config.exportOptions);
1178
+ var currentRow, rowNode;
1179
+ var addRow = function (row) {
1180
+ currentRow = rowPos + 1;
1181
+ rowNode = _createNode(rels, 'row', { attr: { r: currentRow } });
1182
+
1183
+ for (var i = 0, ien = row.length; i < ien; i++) {
1184
+ // Concat both the Cell Columns as a letter and the Row of the cell.
1185
+ var cellId = createCellPos(i) + '' + currentRow;
1186
+ var cell = null;
1187
+
1188
+ // For null, undefined of blank cell, continue so it doesn't create the _createNode
1189
+ if (row[i] === null || row[i] === undefined || row[i] === '') {
1190
+ if (config.createEmptyCells === true) {
1191
+ row[i] = '';
1192
+ }
1193
+ else {
1194
+ continue;
1195
+ }
1196
+ }
1197
+
1198
+ var originalContent = row[i];
1199
+ row[i] =
1200
+ typeof row[i].trim === 'function' ? row[i].trim() : row[i];
1201
+
1202
+ // Special number formatting options
1203
+ for (var j = 0, jen = _excelSpecials.length; j < jen; j++) {
1204
+ var special = _excelSpecials[j];
1205
+
1206
+ // TODO Need to provide the ability for the specials to say
1207
+ // if they are returning a string, since at the moment it is
1208
+ // assumed to be a number
1209
+ if (
1210
+ row[i].match &&
1211
+ !row[i].match(/^0\d+/) &&
1212
+ row[i].match(special.match)
1213
+ ) {
1214
+ var val = row[i].replace(/[^\d\.\-]/g, '');
1215
+
1216
+ if (special.fmt) {
1217
+ val = special.fmt(val);
1218
+ }
1219
+
1220
+ cell = _createNode(rels, 'c', {
1221
+ attr: {
1222
+ r: cellId,
1223
+ s: special.style
1224
+ },
1225
+ children: [_createNode(rels, 'v', { text: val })]
1226
+ });
1227
+
1228
+ break;
1229
+ }
1230
+ }
1231
+
1232
+ if (!cell) {
1233
+ if (
1234
+ typeof row[i] === 'number' ||
1235
+ (row[i].match &&
1236
+ row[i].match(/^-?\d+(\.\d+)?([eE]\-?\d+)?$/) && // Includes exponential format
1237
+ !row[i].match(/^0\d+/))
1238
+ ) {
1239
+ // Detect numbers - don't match numbers with leading zeros
1240
+ // or a negative anywhere but the start
1241
+ cell = _createNode(rels, 'c', {
1242
+ attr: {
1243
+ t: 'n',
1244
+ r: cellId
1245
+ },
1246
+ children: [_createNode(rels, 'v', { text: row[i] })]
1247
+ });
1248
+ }
1249
+ else {
1250
+ // String output - replace non standard characters for text output
1251
+ /*eslint no-control-regex: "off"*/
1252
+ var text = !originalContent.replace
1253
+ ? originalContent
1254
+ : originalContent.replace(
1255
+ /[\x00-\x09\x0B\x0C\x0E-\x1F\x7F-\x9F]/g,
1256
+ ''
1257
+ );
1258
+
1259
+ cell = _createNode(rels, 'c', {
1260
+ attr: {
1261
+ t: 'inlineStr',
1262
+ r: cellId
1263
+ },
1264
+ children: {
1265
+ row: _createNode(rels, 'is', {
1266
+ children: {
1267
+ row: _createNode(rels, 't', {
1268
+ text: text,
1269
+ attr: {
1270
+ 'xml:space': 'preserve'
1271
+ }
1272
+ })
1273
+ }
1274
+ })
1275
+ }
1276
+ });
1277
+ }
1278
+ }
1279
+
1280
+ rowNode.appendChild(cell);
1281
+ }
1282
+
1283
+ relsGet.appendChild(rowNode);
1284
+ rowPos++;
1285
+ };
1286
+
1287
+ var addHeader = function (structure) {
1288
+ structure.forEach(function (row) {
1289
+ addRow(
1290
+ row.map(function (cell) {
1291
+ return cell ? cell.title : '';
1292
+ }),
1293
+ rowPos
1294
+ );
1295
+ $('row:last c', rels).attr('s', '2'); // bold
1296
+
1297
+ // Add any merge cells
1298
+ row.forEach(function (cell, columnCounter) {
1299
+ if (cell && (cell.colSpan > 1 || cell.rowSpan > 1)) {
1300
+ _excelMergeCells(
1301
+ rels,
1302
+ rowPos,
1303
+ columnCounter,
1304
+ cell.rowSpan,
1305
+ cell.colSpan
1306
+ );
1307
+ }
1308
+ });
1309
+ });
1310
+ };
1311
+
1312
+ if (config.customizeData) {
1313
+ config.customizeData(data);
1314
+ }
1315
+
1316
+ // Title and top messages
1317
+ var exportInfo = dt.buttons.exportInfo(config);
1318
+ if (exportInfo.title) {
1319
+ addRow([exportInfo.title], rowPos);
1320
+ _excelMergeCells(rels, rowPos, 0, 1, data.header.length);
1321
+ $('row:last c', rels).attr('s', '51'); // centre
1322
+ }
1323
+
1324
+ if (exportInfo.messageTop) {
1325
+ addRow([exportInfo.messageTop], rowPos);
1326
+ _excelMergeCells(rels, rowPos, 0, 1, data.header.length);
1327
+ }
1328
+
1329
+ // Table header
1330
+ if (config.header) {
1331
+ addHeader(data.headerStructure);
1332
+ }
1333
+
1334
+ dataStartRow = rowPos;
1335
+
1336
+ // Table body
1337
+ for (var n = 0, ie = data.body.length; n < ie; n++) {
1338
+ addRow(data.body[n], rowPos);
1339
+ }
1340
+
1341
+ dataEndRow = rowPos;
1342
+
1343
+ // Table footer
1344
+ if (config.footer && data.footer) {
1345
+ addHeader(data.footerStructure);
1346
+ }
1347
+
1348
+ // Below the table
1349
+ if (exportInfo.messageBottom) {
1350
+ addRow([exportInfo.messageBottom], rowPos);
1351
+ _excelMergeCells(rels, rowPos, 0, 1, data.header.length);
1352
+ }
1353
+
1354
+ // Set column widths
1355
+ var cols = _createNode(rels, 'cols');
1356
+ $('worksheet', rels).prepend(cols);
1357
+
1358
+ for (var i = 0, ien = data.header.length; i < ien; i++) {
1359
+ cols.appendChild(
1360
+ _createNode(rels, 'col', {
1361
+ attr: {
1362
+ min: i + 1,
1363
+ max: i + 1,
1364
+ width: _excelColWidth(data, i),
1365
+ customWidth: 1
1366
+ }
1367
+ })
1368
+ );
1369
+ }
1370
+
1371
+ // Workbook modifications
1372
+ var workbook = xlsx.xl['workbook.xml'];
1373
+
1374
+ $('sheets sheet', workbook).attr('name', _sheetname(config));
1375
+
1376
+ // Auto filter for columns
1377
+ if (config.autoFilter) {
1378
+ $('mergeCells', rels).before(
1379
+ _createNode(rels, 'autoFilter', {
1380
+ attr: {
1381
+ ref:
1382
+ 'A' +
1383
+ dataStartRow +
1384
+ ':' +
1385
+ createCellPos(data.header.length - 1) +
1386
+ dataEndRow
1387
+ }
1388
+ })
1389
+ );
1390
+
1391
+ $('definedNames', workbook).append(
1392
+ _createNode(workbook, 'definedName', {
1393
+ attr: {
1394
+ name: '_xlnm._FilterDatabase',
1395
+ localSheetId: '0',
1396
+ hidden: 1
1397
+ },
1398
+ text:
1399
+ _sheetname(config) +
1400
+ '!$A$' +
1401
+ dataStartRow +
1402
+ ':' +
1403
+ createCellPos(data.header.length - 1) +
1404
+ dataEndRow
1405
+ })
1406
+ );
1407
+ }
1408
+
1409
+ // Let the developer customise the document if they want to
1410
+ if (config.customize) {
1411
+ config.customize(xlsx, config, dt);
1412
+ }
1413
+
1414
+ // Excel doesn't like an empty mergeCells tag
1415
+ if ($('mergeCells', rels).children().length === 0) {
1416
+ $('mergeCells', rels).remove();
1417
+ }
1418
+
1419
+ var jszip = _jsZip();
1420
+ var zip = new jszip();
1421
+ var zipConfig = {
1422
+ compression: 'DEFLATE',
1423
+ type: 'blob',
1424
+ mimeType:
1425
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
1426
+ };
1427
+
1428
+ _addToZip(zip, xlsx);
1429
+
1430
+ // Modern Excel has a 218 character limit on the file name + path of the file (why!?)
1431
+ // https://support.microsoft.com/en-us/office/excel-specifications-and-limits-1672b34d-7043-467e-8e27-269d656771c3
1432
+ // So we truncate to allow for this.
1433
+ var filename = exportInfo.filename;
1434
+
1435
+ if (filename > 175) {
1436
+ filename = filename.substr(0, 175);
1437
+ }
1438
+
1439
+ if (zip.generateAsync) {
1440
+ // JSZip 3+
1441
+ zip.generateAsync(zipConfig).then(function (blob) {
1442
+ _saveAs(blob, filename);
1443
+ cb();
1444
+ });
1445
+ }
1446
+ else {
1447
+ // JSZip 2.5
1448
+ _saveAs(zip.generate(zipConfig), filename);
1449
+ cb();
1450
+ }
1451
+ },
1452
+
1453
+ async: 100,
1454
+
1455
+ filename: '*',
1456
+
1457
+ extension: '.xlsx',
1458
+
1459
+ exportOptions: {},
1460
+
1461
+ header: true,
1462
+
1463
+ footer: true,
1464
+
1465
+ title: '*',
1466
+
1467
+ messageTop: '*',
1468
+
1469
+ messageBottom: '*',
1470
+
1471
+ createEmptyCells: false,
1472
+
1473
+ autoFilter: false,
1474
+
1475
+ sheetName: ''
1476
+ };
1477
+
1478
+ //
1479
+ // PDF export - using pdfMake - http://pdfmake.org
1480
+ //
1481
+ DataTable.ext.buttons.pdfHtml5 = {
1482
+ className: 'buttons-pdf buttons-html5',
1483
+
1484
+ available: function () {
1485
+ return window.FileReader !== undefined && _pdfMake();
1486
+ },
1487
+
1488
+ text: function (dt) {
1489
+ return dt.i18n('buttons.pdf', 'PDF');
1490
+ },
1491
+
1492
+ action: function (e, dt, button, config, cb) {
1493
+ var data = dt.buttons.exportData(config.exportOptions);
1494
+ var info = dt.buttons.exportInfo(config);
1495
+ var rows = [];
1496
+
1497
+ if (config.header) {
1498
+ data.headerStructure.forEach(function (row) {
1499
+ rows.push(
1500
+ row.map(function (cell) {
1501
+ return cell
1502
+ ? {
1503
+ text: cell.title,
1504
+ colSpan: cell.colspan,
1505
+ rowSpan: cell.rowspan,
1506
+ style: 'tableHeader'
1507
+ }
1508
+ : {};
1509
+ })
1510
+ );
1511
+ });
1512
+ }
1513
+
1514
+ for (var i = 0, ien = data.body.length; i < ien; i++) {
1515
+ rows.push(
1516
+ data.body[i].map(function (d) {
1517
+ return {
1518
+ text:
1519
+ d === null || d === undefined
1520
+ ? ''
1521
+ : typeof d === 'string'
1522
+ ? d
1523
+ : d.toString()
1524
+ };
1525
+ })
1526
+ );
1527
+ }
1528
+
1529
+ if (config.footer) {
1530
+ data.footerStructure.forEach(function (row) {
1531
+ rows.push(
1532
+ row.map(function (cell) {
1533
+ return cell
1534
+ ? {
1535
+ text: cell.title,
1536
+ colSpan: cell.colspan,
1537
+ rowSpan: cell.rowspan,
1538
+ style: 'tableHeader'
1539
+ }
1540
+ : {};
1541
+ })
1542
+ );
1543
+ });
1544
+ }
1545
+
1546
+ var doc = {
1547
+ pageSize: config.pageSize,
1548
+ pageOrientation: config.orientation,
1549
+ content: [
1550
+ {
1551
+ style: 'table',
1552
+ table: {
1553
+ headerRows: data.headerStructure.length,
1554
+ footerRows: data.footerStructure.length, // Used for styling, doesn't do anything in pdfmake
1555
+ body: rows
1556
+ },
1557
+ layout: {
1558
+ hLineWidth: function (i, node) {
1559
+ if (i === 0 || i === node.table.body.length) {
1560
+ return 0;
1561
+ }
1562
+ return 0.5;
1563
+ },
1564
+ vLineWidth: function () {
1565
+ return 0;
1566
+ },
1567
+ hLineColor: function (i, node) {
1568
+ return i === node.table.headerRows ||
1569
+ i ===
1570
+ node.table.body.length -
1571
+ node.table.footerRows
1572
+ ? '#333'
1573
+ : '#ddd';
1574
+ },
1575
+ fillColor: function (rowIndex) {
1576
+ if (rowIndex < data.headerStructure.length) {
1577
+ return '#fff';
1578
+ }
1579
+ return rowIndex % 2 === 0 ? '#f3f3f3' : null;
1580
+ },
1581
+ paddingTop: function () {
1582
+ return 5;
1583
+ },
1584
+ paddingBottom: function () {
1585
+ return 5;
1586
+ }
1587
+ }
1588
+ }
1589
+ ],
1590
+ styles: {
1591
+ tableHeader: {
1592
+ bold: true,
1593
+ fontSize: 11,
1594
+ alignment: 'center'
1595
+ },
1596
+ tableFooter: {
1597
+ bold: true,
1598
+ fontSize: 11
1599
+ },
1600
+ table: {
1601
+ margin: [0, 5, 0, 5]
1602
+ },
1603
+ title: {
1604
+ alignment: 'center',
1605
+ fontSize: 13
1606
+ },
1607
+ message: {}
1608
+ },
1609
+ defaultStyle: {
1610
+ fontSize: 10
1611
+ }
1612
+ };
1613
+
1614
+ if (info.messageTop) {
1615
+ doc.content.unshift({
1616
+ text: info.messageTop,
1617
+ style: 'message',
1618
+ margin: [0, 0, 0, 12]
1619
+ });
1620
+ }
1621
+
1622
+ if (info.messageBottom) {
1623
+ doc.content.push({
1624
+ text: info.messageBottom,
1625
+ style: 'message',
1626
+ margin: [0, 0, 0, 12]
1627
+ });
1628
+ }
1629
+
1630
+ if (info.title) {
1631
+ doc.content.unshift({
1632
+ text: info.title,
1633
+ style: 'title',
1634
+ margin: [0, 0, 0, 12]
1635
+ });
1636
+ }
1637
+
1638
+ if (config.customize) {
1639
+ config.customize(doc, config, dt);
1640
+ }
1641
+
1642
+ var pdf = _pdfMake().createPdf(doc);
1643
+
1644
+ if (config.download === 'open' && !_isDuffSafari()) {
1645
+ pdf.open();
1646
+ }
1647
+ else {
1648
+ pdf.download(info.filename);
1649
+ }
1650
+
1651
+ cb();
1652
+ },
1653
+
1654
+ async: 100,
1655
+
1656
+ title: '*',
1657
+
1658
+ filename: '*',
1659
+
1660
+ extension: '.pdf',
1661
+
1662
+ exportOptions: {},
1663
+
1664
+ orientation: 'portrait',
1665
+
1666
+ // This isn't perfect, but it is close
1667
+ pageSize:
1668
+ navigator.language === 'en-US' || navigator.language === 'en-CA'
1669
+ ? 'LETTER'
1670
+ : 'A4',
1671
+
1672
+ header: true,
1673
+
1674
+ footer: true,
1675
+
1676
+ messageTop: '*',
1677
+
1678
+ messageBottom: '*',
1679
+
1680
+ customize: null,
1681
+
1682
+ download: 'download'
1683
+ };
1684
+
1685
+
1686
+ return DataTable;
1687
+ }));