@flowaccount/pdfmake 0.2.20-staging.2
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.
- package/LICENSE +21 -0
- package/README.md +297 -0
- package/build/pdfmake.js +94091 -0
- package/build/pdfmake.min.js +3 -0
- package/build/pdfmake.min.js.map +1 -0
- package/build/vfs_fonts.js +7 -0
- package/package.json +110 -0
- package/src/3rd-party/svg-to-pdfkit/LICENSE +9 -0
- package/src/3rd-party/svg-to-pdfkit/source.js +2552 -0
- package/src/3rd-party/svg-to-pdfkit.js +3 -0
- package/src/browser-extensions/URLBrowserResolver.js +96 -0
- package/src/browser-extensions/pdfMake.js +361 -0
- package/src/browser-extensions/tokenizer-shim.js +16 -0
- package/src/browser-extensions/virtual-fs.js +55 -0
- package/src/columnCalculator.js +157 -0
- package/src/docMeasure.js +831 -0
- package/src/docPreprocessor.js +277 -0
- package/src/documentContext.js +383 -0
- package/src/elementWriter.js +434 -0
- package/src/fontProvider.js +68 -0
- package/src/helpers.js +138 -0
- package/src/imageMeasure.js +70 -0
- package/src/layoutBuilder.js +1537 -0
- package/src/line.js +91 -0
- package/src/pageElementWriter.js +355 -0
- package/src/pdfKitEngine.js +21 -0
- package/src/printer.js +1086 -0
- package/src/qrEnc.js +791 -0
- package/src/standardPageSizes.js +54 -0
- package/src/styleContextStack.js +138 -0
- package/src/svgMeasure.js +70 -0
- package/src/tableProcessor.js +648 -0
- package/src/textDecorator.js +157 -0
- package/src/textTools.js +543 -0
- package/src/traversalTracker.js +47 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Internet Explorer polyfills
|
|
4
|
+
if (typeof window !== 'undefined' && !window.Promise) {
|
|
5
|
+
require('core-js/features/promise');
|
|
6
|
+
}
|
|
7
|
+
require('core-js/es/object/values');
|
|
8
|
+
|
|
9
|
+
var fetchUrl = function (url, headers) {
|
|
10
|
+
return new Promise(function (resolve, reject) {
|
|
11
|
+
var xhr = new XMLHttpRequest();
|
|
12
|
+
xhr.open('GET', url, true);
|
|
13
|
+
for (var headerName in headers) {
|
|
14
|
+
xhr.setRequestHeader(headerName, headers[headerName]);
|
|
15
|
+
}
|
|
16
|
+
xhr.responseType = 'arraybuffer';
|
|
17
|
+
|
|
18
|
+
xhr.onreadystatechange = function () {
|
|
19
|
+
if (xhr.readyState !== 4) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var ok = xhr.status >= 200 && xhr.status < 300;
|
|
24
|
+
if (!ok) {
|
|
25
|
+
setTimeout(function () {
|
|
26
|
+
reject(new TypeError('Failed to fetch (url: "' + url + '")'));
|
|
27
|
+
}, 0);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
xhr.onload = function () {
|
|
32
|
+
var ok = xhr.status >= 200 && xhr.status < 300;
|
|
33
|
+
if (ok) {
|
|
34
|
+
resolve(xhr.response);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
xhr.onerror = function () {
|
|
39
|
+
setTimeout(function () {
|
|
40
|
+
reject(new TypeError('Network request failed (url: "' + url + '")'));
|
|
41
|
+
}, 0);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
xhr.ontimeout = function () {
|
|
45
|
+
setTimeout(function () {
|
|
46
|
+
reject(new TypeError('Network request failed (url: "' + url + '")'));
|
|
47
|
+
}, 0);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
xhr.send();
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
function URLBrowserResolver(fs) {
|
|
55
|
+
this.fs = fs;
|
|
56
|
+
this.resolving = {};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
URLBrowserResolver.prototype.resolve = function (url, headers) {
|
|
60
|
+
if (!this.resolving[url]) {
|
|
61
|
+
var _this = this;
|
|
62
|
+
this.resolving[url] = new Promise(function (resolve, reject) {
|
|
63
|
+
if (url.toLowerCase().indexOf('https://') === 0 || url.toLowerCase().indexOf('http://') === 0) {
|
|
64
|
+
if (_this.fs.existsSync(url)) {
|
|
65
|
+
// url was downloaded earlier
|
|
66
|
+
resolve();
|
|
67
|
+
} else {
|
|
68
|
+
fetchUrl(url, headers).then(function (buffer) {
|
|
69
|
+
_this.fs.writeFileSync(url, buffer);
|
|
70
|
+
resolve();
|
|
71
|
+
}, function (result) {
|
|
72
|
+
reject(result);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
// cannot be resolved
|
|
77
|
+
resolve();
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return this.resolving[url];
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
URLBrowserResolver.prototype.resolved = function () {
|
|
86
|
+
var _this = this;
|
|
87
|
+
return new Promise(function (resolve, reject) {
|
|
88
|
+
Promise.all(Object.values(_this.resolving)).then(function () {
|
|
89
|
+
resolve();
|
|
90
|
+
}, function (result) {
|
|
91
|
+
reject(result);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
module.exports = URLBrowserResolver;
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var isFunction = require('../helpers').isFunction;
|
|
4
|
+
var isUndefined = require('../helpers').isUndefined;
|
|
5
|
+
//var isNull = require('../helpers').isNull;
|
|
6
|
+
var pack = require('../helpers').pack;
|
|
7
|
+
var FileSaver = require('file-saver');
|
|
8
|
+
var saveAs = FileSaver.saveAs;
|
|
9
|
+
|
|
10
|
+
var defaultClientFonts = {
|
|
11
|
+
Roboto: {
|
|
12
|
+
normal: 'Roboto-Regular.ttf',
|
|
13
|
+
bold: 'Roboto-Medium.ttf',
|
|
14
|
+
italics: 'Roboto-Italic.ttf',
|
|
15
|
+
bolditalics: 'Roboto-MediumItalic.ttf'
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
var globalVfs;
|
|
20
|
+
var globalFonts;
|
|
21
|
+
var globalTableLayouts;
|
|
22
|
+
|
|
23
|
+
function Document(docDefinition, tableLayouts, fonts, vfs) {
|
|
24
|
+
this.docDefinition = docDefinition;
|
|
25
|
+
this.tableLayouts = tableLayouts || null;
|
|
26
|
+
this.fonts = fonts || defaultClientFonts;
|
|
27
|
+
this.vfs = vfs;
|
|
28
|
+
this._remoteImagesPrefetched = false;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function canCreatePdf() {
|
|
32
|
+
// Ensure the browser provides the level of support needed
|
|
33
|
+
try {
|
|
34
|
+
var arr = new Uint8Array(1);
|
|
35
|
+
var proto = { foo: function () { return 42; } };
|
|
36
|
+
Object.setPrototypeOf(proto, Uint8Array.prototype);
|
|
37
|
+
Object.setPrototypeOf(arr, proto);
|
|
38
|
+
return arr.foo() === 42;
|
|
39
|
+
} catch (e) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
Document.prototype._createDoc = function (options, cb) {
|
|
45
|
+
var getExtendedUrl = function (url) {
|
|
46
|
+
if (typeof url === 'object') {
|
|
47
|
+
return { url: url.url, headers: url.headers };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return { url: url, headers: {} };
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
options = options || {};
|
|
54
|
+
if (this.tableLayouts) {
|
|
55
|
+
options.tableLayouts = this.tableLayouts;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
var PdfPrinter = require('../printer');
|
|
59
|
+
|
|
60
|
+
var printer = new PdfPrinter(this.fonts);
|
|
61
|
+
require('fs').bindFS(this.vfs); // bind virtual file system to file system
|
|
62
|
+
|
|
63
|
+
if (!isFunction(cb)) {
|
|
64
|
+
var doc = printer.createPdfKitDocument(this.docDefinition, options);
|
|
65
|
+
|
|
66
|
+
return doc;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
var URLBrowserResolver = require('./URLBrowserResolver');
|
|
70
|
+
var urlResolver = new URLBrowserResolver(require('fs'));
|
|
71
|
+
|
|
72
|
+
for (var font in this.fonts) {
|
|
73
|
+
if (this.fonts.hasOwnProperty(font)) {
|
|
74
|
+
if (this.fonts[font].normal) {
|
|
75
|
+
if (Array.isArray(this.fonts[font].normal)) { // TrueType Collection
|
|
76
|
+
var url = getExtendedUrl(this.fonts[font].normal[0]);
|
|
77
|
+
urlResolver.resolve(url.url, url.headers);
|
|
78
|
+
this.fonts[font].normal[0] = url.url;
|
|
79
|
+
} else {
|
|
80
|
+
var url = getExtendedUrl(this.fonts[font].normal);
|
|
81
|
+
urlResolver.resolve(url.url, url.headers);
|
|
82
|
+
this.fonts[font].normal = url.url;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (this.fonts[font].bold) {
|
|
86
|
+
if (Array.isArray(this.fonts[font].bold)) { // TrueType Collection
|
|
87
|
+
var url = getExtendedUrl(this.fonts[font].bold[0]);
|
|
88
|
+
urlResolver.resolve(url.url, url.headers);
|
|
89
|
+
this.fonts[font].bold[0] = url.url;
|
|
90
|
+
} else {
|
|
91
|
+
var url = getExtendedUrl(this.fonts[font].bold);
|
|
92
|
+
urlResolver.resolve(url.url, url.headers);
|
|
93
|
+
this.fonts[font].bold = url.url;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (this.fonts[font].italics) {
|
|
97
|
+
if (Array.isArray(this.fonts[font].italics)) { // TrueType Collection
|
|
98
|
+
var url = getExtendedUrl(this.fonts[font].italics[0]);
|
|
99
|
+
urlResolver.resolve(url.url, url.headers);
|
|
100
|
+
this.fonts[font].italics[0] = url.url;
|
|
101
|
+
} else {
|
|
102
|
+
var url = getExtendedUrl(this.fonts[font].italics);
|
|
103
|
+
urlResolver.resolve(url.url, url.headers);
|
|
104
|
+
this.fonts[font].italics = url.url;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (this.fonts[font].bolditalics) {
|
|
108
|
+
if (Array.isArray(this.fonts[font].bolditalics)) { // TrueType Collection
|
|
109
|
+
var url = getExtendedUrl(this.fonts[font].bolditalics[0]);
|
|
110
|
+
urlResolver.resolve(url.url, url.headers);
|
|
111
|
+
this.fonts[font].bolditalics[0] = url.url;
|
|
112
|
+
} else {
|
|
113
|
+
var url = getExtendedUrl(this.fonts[font].bolditalics);
|
|
114
|
+
urlResolver.resolve(url.url, url.headers);
|
|
115
|
+
this.fonts[font].bolditalics = url.url;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (this.docDefinition.images) {
|
|
122
|
+
for (var image in this.docDefinition.images) {
|
|
123
|
+
if (this.docDefinition.images.hasOwnProperty(image)) {
|
|
124
|
+
var originalVal = this.docDefinition.images[image];
|
|
125
|
+
var urlImg = getExtendedUrl(originalVal);
|
|
126
|
+
if (typeof urlImg.url === 'string' && (urlImg.url.toLowerCase().startsWith('http://') || urlImg.url.toLowerCase().startsWith('https://'))) {
|
|
127
|
+
urlResolver.resolve(urlImg.url, urlImg.headers);
|
|
128
|
+
this.docDefinition.images[image] = urlImg.url;
|
|
129
|
+
} else {
|
|
130
|
+
this.docDefinition.images[image] = urlImg.url;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
var _this = this;
|
|
137
|
+
|
|
138
|
+
urlResolver.resolved().then(function () {
|
|
139
|
+
var doc = printer.createPdfKitDocument(_this.docDefinition, options);
|
|
140
|
+
|
|
141
|
+
cb(doc);
|
|
142
|
+
}, function (result) {
|
|
143
|
+
throw result;
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
Document.prototype._flushDoc = function (doc, callback) {
|
|
148
|
+
var chunks = [];
|
|
149
|
+
var result;
|
|
150
|
+
|
|
151
|
+
doc.on('readable', function () {
|
|
152
|
+
var chunk;
|
|
153
|
+
while ((chunk = doc.read(9007199254740991)) !== null) {
|
|
154
|
+
chunks.push(chunk);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
doc.on('end', function () {
|
|
158
|
+
result = Buffer.concat(chunks);
|
|
159
|
+
callback(result, doc._pdfMakePages);
|
|
160
|
+
});
|
|
161
|
+
doc.end();
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
Document.prototype._getPages = function (options, cb) {
|
|
165
|
+
if (!cb) {
|
|
166
|
+
throw '_getPages is an async method and needs a callback argument';
|
|
167
|
+
}
|
|
168
|
+
var _this = this;
|
|
169
|
+
|
|
170
|
+
this._createDoc(options, function (doc) {
|
|
171
|
+
_this._flushDoc(doc, function (ignoreBuffer, pages) {
|
|
172
|
+
cb(pages);
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
Document.prototype._bufferToBlob = function (buffer) {
|
|
178
|
+
var blob;
|
|
179
|
+
try {
|
|
180
|
+
blob = new Blob([buffer], { type: 'application/pdf' });
|
|
181
|
+
} catch (e) {
|
|
182
|
+
// Old browser which can't handle it without making it an byte array (ie10)
|
|
183
|
+
if (e.name === 'InvalidStateError') {
|
|
184
|
+
var byteArray = new Uint8Array(buffer);
|
|
185
|
+
blob = new Blob([byteArray.buffer], { type: 'application/pdf' });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
if (!blob) {
|
|
190
|
+
throw 'Could not generate blob';
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return blob;
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
Document.prototype._openWindow = function () {
|
|
197
|
+
// we have to open the window immediately and store the reference
|
|
198
|
+
// otherwise popup blockers will stop us
|
|
199
|
+
var win = window.open('', '_blank');
|
|
200
|
+
if (win === null) {
|
|
201
|
+
throw 'Open PDF in new window blocked by browser';
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return win;
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
Document.prototype._openPdf = function (options, win) {
|
|
208
|
+
if (!win) {
|
|
209
|
+
win = this._openWindow();
|
|
210
|
+
}
|
|
211
|
+
try {
|
|
212
|
+
this.getBlob(function (result) {
|
|
213
|
+
var urlCreator = window.URL || window.webkitURL;
|
|
214
|
+
var pdfUrl = urlCreator.createObjectURL(result);
|
|
215
|
+
win.location.href = pdfUrl;
|
|
216
|
+
|
|
217
|
+
/* temporarily disabled
|
|
218
|
+
if (win !== window) {
|
|
219
|
+
setTimeout(function () {
|
|
220
|
+
if (isNull(win.window)) { // is closed by AdBlock
|
|
221
|
+
window.location.href = pdfUrl; // open in actual window
|
|
222
|
+
}
|
|
223
|
+
}, 500);
|
|
224
|
+
}
|
|
225
|
+
*/
|
|
226
|
+
}, options);
|
|
227
|
+
} catch (e) {
|
|
228
|
+
win.close();
|
|
229
|
+
throw e;
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
Document.prototype.open = function (options, win) {
|
|
234
|
+
options = options || {};
|
|
235
|
+
options.autoPrint = false;
|
|
236
|
+
win = win || null;
|
|
237
|
+
|
|
238
|
+
this._openPdf(options, win);
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
Document.prototype.print = function (options, win) {
|
|
243
|
+
options = options || {};
|
|
244
|
+
options.autoPrint = true;
|
|
245
|
+
win = win || null;
|
|
246
|
+
|
|
247
|
+
this._openPdf(options, win);
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* download(defaultFileName = 'file.pdf', cb = null, options = {})
|
|
252
|
+
* or
|
|
253
|
+
* download(cb, options = {})
|
|
254
|
+
*/
|
|
255
|
+
Document.prototype.download = function (defaultFileName, cb, options) {
|
|
256
|
+
if (isFunction(defaultFileName)) {
|
|
257
|
+
if (!isUndefined(cb)) {
|
|
258
|
+
options = cb;
|
|
259
|
+
}
|
|
260
|
+
cb = defaultFileName;
|
|
261
|
+
defaultFileName = null;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
defaultFileName = defaultFileName || 'file.pdf';
|
|
265
|
+
this.getBlob(function (result) {
|
|
266
|
+
saveAs(result, defaultFileName);
|
|
267
|
+
|
|
268
|
+
if (isFunction(cb)) {
|
|
269
|
+
cb();
|
|
270
|
+
}
|
|
271
|
+
}, options);
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
Document.prototype.getBase64 = function (cb, options) {
|
|
275
|
+
if (!cb) {
|
|
276
|
+
throw 'getBase64 is an async method and needs a callback argument';
|
|
277
|
+
}
|
|
278
|
+
this.getBuffer(function (buffer) {
|
|
279
|
+
cb(buffer.toString('base64'));
|
|
280
|
+
}, options);
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
Document.prototype.getDataUrl = function (cb, options) {
|
|
284
|
+
if (!cb) {
|
|
285
|
+
throw 'getDataUrl is an async method and needs a callback argument';
|
|
286
|
+
}
|
|
287
|
+
this.getBuffer(function (buffer) {
|
|
288
|
+
cb('data:application/pdf;base64,' + buffer.toString('base64'));
|
|
289
|
+
}, options);
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
Document.prototype.getBlob = function (cb, options) {
|
|
293
|
+
if (!cb) {
|
|
294
|
+
throw 'getBlob is an async method and needs a callback argument';
|
|
295
|
+
}
|
|
296
|
+
var that = this;
|
|
297
|
+
this.getBuffer(function (result) {
|
|
298
|
+
var blob = that._bufferToBlob(result);
|
|
299
|
+
cb(blob);
|
|
300
|
+
}, options);
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
Document.prototype.getBuffer = function (cb, options) {
|
|
304
|
+
if (!cb) {
|
|
305
|
+
throw 'getBuffer is an async method and needs a callback argument';
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
var _this = this;
|
|
309
|
+
|
|
310
|
+
this._createDoc(options, function (doc) {
|
|
311
|
+
_this._flushDoc(doc, function (buffer) {
|
|
312
|
+
cb(buffer);
|
|
313
|
+
});
|
|
314
|
+
});
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
Document.prototype.getStream = function (options, cb) {
|
|
318
|
+
if (!isFunction(cb)) {
|
|
319
|
+
var doc = this._createDoc(options);
|
|
320
|
+
return doc;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
this._createDoc(options, function (doc) {
|
|
324
|
+
cb(doc);
|
|
325
|
+
});
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
module.exports = {
|
|
329
|
+
createPdf: function (docDefinition, tableLayouts, fonts, vfs) {
|
|
330
|
+
if (!canCreatePdf()) {
|
|
331
|
+
throw 'Your browser does not provide the level of support needed';
|
|
332
|
+
}
|
|
333
|
+
return new Document(
|
|
334
|
+
docDefinition,
|
|
335
|
+
tableLayouts || globalTableLayouts || global.pdfMake.tableLayouts,
|
|
336
|
+
fonts || globalFonts || global.pdfMake.fonts,
|
|
337
|
+
vfs || globalVfs || global.pdfMake.vfs
|
|
338
|
+
);
|
|
339
|
+
},
|
|
340
|
+
addVirtualFileSystem: function (vfs) {
|
|
341
|
+
globalVfs = vfs;
|
|
342
|
+
},
|
|
343
|
+
addFonts: function (fonts) {
|
|
344
|
+
globalFonts = pack(globalFonts, fonts);
|
|
345
|
+
},
|
|
346
|
+
setFonts: function (fonts) {
|
|
347
|
+
globalFonts = fonts;
|
|
348
|
+
},
|
|
349
|
+
clearFonts: function () {
|
|
350
|
+
globalFonts = undefined;
|
|
351
|
+
},
|
|
352
|
+
addTableLayouts: function (tableLayouts) {
|
|
353
|
+
globalTableLayouts = pack(globalTableLayouts, tableLayouts);
|
|
354
|
+
},
|
|
355
|
+
setTableLayouts: function (tableLayouts) {
|
|
356
|
+
globalTableLayouts = tableLayouts;
|
|
357
|
+
},
|
|
358
|
+
clearTableLayouts: function () {
|
|
359
|
+
globalTableLayouts = undefined;
|
|
360
|
+
}
|
|
361
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Browser shim for @flowaccount/node-icu-tokenizer
|
|
2
|
+
// The original package depends on native bindings resolved via 'bindings' which
|
|
3
|
+
// pulls in Node core modules (path) not polyfilled by default in webpack 5.
|
|
4
|
+
// For browser builds we degrade gracefully: tokenize() will produce a single
|
|
5
|
+
// token spanning the whole input so existing logic that iterates tokens still works.
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
class BrowserTokenizer {
|
|
10
|
+
tokenize(str) {
|
|
11
|
+
if (typeof str !== 'string') { return []; }
|
|
12
|
+
return [ { token: str, type: 'TEXT', start: 0, end: str.length } ];
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = BrowserTokenizer;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function VirtualFileSystem() {
|
|
4
|
+
this.fileSystem = {};
|
|
5
|
+
this.dataSystem = {};
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
VirtualFileSystem.prototype.existsSync = function (filename) {
|
|
9
|
+
filename = fixFilename(filename);
|
|
10
|
+
return typeof this.fileSystem[filename] !== 'undefined'
|
|
11
|
+
|| typeof this.dataSystem[filename] !== 'undefined';
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
VirtualFileSystem.prototype.readFileSync = function (filename, options) {
|
|
15
|
+
filename = fixFilename(filename);
|
|
16
|
+
|
|
17
|
+
var dataContent = this.dataSystem[filename];
|
|
18
|
+
if (typeof dataContent === 'string' && options === 'utf8') {
|
|
19
|
+
return dataContent;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (dataContent) {
|
|
23
|
+
return new Buffer(dataContent, typeof dataContent === 'string' ? 'base64' : undefined);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var content = this.fileSystem[filename];
|
|
27
|
+
if (content) {
|
|
28
|
+
return content;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
throw 'File \'' + filename + '\' not found in virtual file system';
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
VirtualFileSystem.prototype.writeFileSync = function (filename, content) {
|
|
35
|
+
this.fileSystem[fixFilename(filename)] = content;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
VirtualFileSystem.prototype.bindFS = function (data) {
|
|
39
|
+
this.dataSystem = data || {};
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
function fixFilename(filename) {
|
|
44
|
+
if (filename.indexOf(__dirname) === 0) {
|
|
45
|
+
filename = filename.substring(__dirname.length);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (filename.indexOf('/') === 0) {
|
|
49
|
+
filename = filename.substring(1);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return filename;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
module.exports = new VirtualFileSystem();
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var isString = require('./helpers').isString;
|
|
4
|
+
|
|
5
|
+
function buildColumnWidths(columns, availableWidth, offsetTotal = 0, tableNode) {
|
|
6
|
+
var autoColumns = [],
|
|
7
|
+
autoMin = 0, autoMax = 0,
|
|
8
|
+
starColumns = [],
|
|
9
|
+
starMaxMin = 0,
|
|
10
|
+
starMaxMax = 0,
|
|
11
|
+
fixedColumns = [],
|
|
12
|
+
initial_availableWidth = availableWidth;
|
|
13
|
+
|
|
14
|
+
columns.forEach(function (column) {
|
|
15
|
+
if (isAutoColumn(column)) {
|
|
16
|
+
autoColumns.push(column);
|
|
17
|
+
autoMin += column._minWidth;
|
|
18
|
+
autoMax += column._maxWidth;
|
|
19
|
+
} else if (isStarColumn(column)) {
|
|
20
|
+
starColumns.push(column);
|
|
21
|
+
starMaxMin = Math.max(starMaxMin, column._minWidth);
|
|
22
|
+
starMaxMax = Math.max(starMaxMax, column._maxWidth);
|
|
23
|
+
} else {
|
|
24
|
+
fixedColumns.push(column);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
fixedColumns.forEach(function (col, colIndex) {
|
|
29
|
+
// width specified as %
|
|
30
|
+
if (isString(col.width) && /\d+%/.test(col.width)) {
|
|
31
|
+
// In tables we have to take into consideration the reserved width for paddings and borders
|
|
32
|
+
var reservedWidth = 0;
|
|
33
|
+
if (tableNode) {
|
|
34
|
+
var paddingLeft = tableNode._layout.paddingLeft(colIndex, tableNode);
|
|
35
|
+
var paddingRight = tableNode._layout.paddingRight(colIndex, tableNode);
|
|
36
|
+
var borderLeft = tableNode._layout.vLineWidth(colIndex, tableNode);
|
|
37
|
+
var borderRight = tableNode._layout.vLineWidth(colIndex + 1, tableNode);
|
|
38
|
+
if (colIndex === 0) {
|
|
39
|
+
// first column assumes whole borderLeft and half of border right
|
|
40
|
+
reservedWidth = paddingLeft + paddingRight + borderLeft + (borderRight / 2);
|
|
41
|
+
|
|
42
|
+
} else if (colIndex === fixedColumns.length - 1) {
|
|
43
|
+
// last column assumes whole borderRight and half of border left
|
|
44
|
+
reservedWidth = paddingLeft + paddingRight + (borderLeft / 2) + borderRight;
|
|
45
|
+
|
|
46
|
+
} else {
|
|
47
|
+
// Columns in the middle assume half of each border
|
|
48
|
+
reservedWidth = paddingLeft + paddingRight + (borderLeft / 2) + (borderRight / 2);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
var totalAvailableWidth = initial_availableWidth + offsetTotal;
|
|
52
|
+
col.width = (parseFloat(col.width) * totalAvailableWidth / 100) - reservedWidth;
|
|
53
|
+
}
|
|
54
|
+
if (col.width < (col._minWidth) && col.elasticWidth) {
|
|
55
|
+
col._calcWidth = col._minWidth;
|
|
56
|
+
} else {
|
|
57
|
+
col._calcWidth = col.width;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
availableWidth -= col._calcWidth;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
// http://www.freesoft.org/CIE/RFC/1942/18.htm
|
|
64
|
+
// http://www.w3.org/TR/CSS2/tables.html#width-layout
|
|
65
|
+
// http://dev.w3.org/csswg/css3-tables-algorithms/Overview.src.htm
|
|
66
|
+
var minW = autoMin + starMaxMin * starColumns.length;
|
|
67
|
+
var maxW = autoMax + starMaxMax * starColumns.length;
|
|
68
|
+
if (minW >= availableWidth) {
|
|
69
|
+
// case 1 - there's no way to fit all columns within available width
|
|
70
|
+
// that's actually pretty bad situation with PDF as we have no horizontal scroll
|
|
71
|
+
// no easy workaround (unless we decide, in the future, to split single words)
|
|
72
|
+
// currently we simply use minWidths for all columns
|
|
73
|
+
autoColumns.forEach(function (col) {
|
|
74
|
+
col._calcWidth = col._minWidth;
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
starColumns.forEach(function (col) {
|
|
78
|
+
col._calcWidth = starMaxMin; // starMaxMin already contains padding
|
|
79
|
+
});
|
|
80
|
+
} else {
|
|
81
|
+
if (maxW < availableWidth) {
|
|
82
|
+
// case 2 - we can fit rest of the table within available space
|
|
83
|
+
autoColumns.forEach(function (col) {
|
|
84
|
+
col._calcWidth = col._maxWidth;
|
|
85
|
+
availableWidth -= col._calcWidth;
|
|
86
|
+
});
|
|
87
|
+
} else {
|
|
88
|
+
// maxW is too large, but minW fits within available width
|
|
89
|
+
var W = availableWidth - minW;
|
|
90
|
+
var D = maxW - minW;
|
|
91
|
+
|
|
92
|
+
autoColumns.forEach(function (col) {
|
|
93
|
+
var d = col._maxWidth - col._minWidth;
|
|
94
|
+
col._calcWidth = col._minWidth + d * W / D;
|
|
95
|
+
availableWidth -= col._calcWidth;
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (starColumns.length > 0) {
|
|
100
|
+
var starSize = availableWidth / starColumns.length;
|
|
101
|
+
|
|
102
|
+
starColumns.forEach(function (col) {
|
|
103
|
+
col._calcWidth = starSize;
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function isAutoColumn(column) {
|
|
110
|
+
return column.width === 'auto';
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function isStarColumn(column) {
|
|
114
|
+
return column.width === null || column.width === undefined || column.width === '*' || column.width === 'star';
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
//TODO: refactor and reuse in measureTable
|
|
118
|
+
function measureMinMax(columns) {
|
|
119
|
+
var result = { min: 0, max: 0 };
|
|
120
|
+
|
|
121
|
+
var maxStar = { min: 0, max: 0 };
|
|
122
|
+
var starCount = 0;
|
|
123
|
+
|
|
124
|
+
for (var i = 0, l = columns.length; i < l; i++) {
|
|
125
|
+
var c = columns[i];
|
|
126
|
+
|
|
127
|
+
if (isStarColumn(c)) {
|
|
128
|
+
maxStar.min = Math.max(maxStar.min, c._minWidth);
|
|
129
|
+
maxStar.max = Math.max(maxStar.max, c._maxWidth);
|
|
130
|
+
starCount++;
|
|
131
|
+
} else if (isAutoColumn(c)) {
|
|
132
|
+
result.min += c._minWidth;
|
|
133
|
+
result.max += c._maxWidth;
|
|
134
|
+
} else {
|
|
135
|
+
result.min += ((c.width !== undefined && c.width) || c._minWidth);
|
|
136
|
+
result.max += ((c.width !== undefined && c.width) || c._maxWidth);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (starCount) {
|
|
141
|
+
result.min += starCount * maxStar.min;
|
|
142
|
+
result.max += starCount * maxStar.max;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Calculates column widths
|
|
150
|
+
* @private
|
|
151
|
+
*/
|
|
152
|
+
module.exports = {
|
|
153
|
+
buildColumnWidths: buildColumnWidths,
|
|
154
|
+
measureMinMax: measureMinMax,
|
|
155
|
+
isAutoColumn: isAutoColumn,
|
|
156
|
+
isStarColumn: isStarColumn
|
|
157
|
+
};
|