pdfmake 0.3.0-beta.17 → 0.3.0-beta.19
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/CHANGELOG.md +14 -0
- package/README.md +2 -7
- package/build/pdfmake.js +33324 -33106
- package/build/pdfmake.js.map +1 -1
- package/build/pdfmake.min.js +2 -2
- package/build/pdfmake.min.js.map +1 -1
- package/build/vfs_fonts.js +4 -4
- package/fonts/Roboto/Roboto-Italic.ttf +0 -0
- package/fonts/Roboto/Roboto-Medium.ttf +0 -0
- package/fonts/Roboto/Roboto-MediumItalic.ttf +0 -0
- package/fonts/Roboto/Roboto-Regular.ttf +0 -0
- package/js/DocMeasure.js +12 -1
- package/js/DocPreprocessor.js +21 -6
- package/js/DocumentContext.js +5 -4
- package/js/LayoutBuilder.js +137 -34
- package/js/OutputDocument.js +22 -34
- package/js/OutputDocumentServer.js +6 -11
- package/js/PageElementWriter.js +2 -2
- package/js/Printer.js +132 -145
- package/js/StyleContextStack.js +4 -0
- package/js/TextBreaker.js +30 -3
- package/js/URLResolver.js +23 -62
- package/js/browser-extensions/OutputDocumentBrowser.js +35 -72
- package/js/browser-extensions/index.js +2 -2
- package/package.json +18 -18
- package/src/DocMeasure.js +15 -1
- package/src/DocPreprocessor.js +25 -6
- package/src/DocumentContext.js +4 -4
- package/src/LayoutBuilder.js +169 -39
- package/src/OutputDocument.js +23 -37
- package/src/OutputDocumentServer.js +6 -11
- package/src/PageElementWriter.js +2 -2
- package/src/Printer.js +131 -143
- package/src/StyleContextStack.js +4 -0
- package/src/TextBreaker.js +23 -4
- package/src/URLResolver.js +23 -68
- package/src/browser-extensions/OutputDocumentBrowser.js +33 -71
- package/src/browser-extensions/index.js +2 -2
- package/js/browser-extensions/URLBrowserResolver.js +0 -81
- package/src/browser-extensions/URLBrowserResolver.js +0 -89
package/src/Printer.js
CHANGED
|
@@ -43,89 +43,83 @@ class PdfPrinter {
|
|
|
43
43
|
* @param {object} options
|
|
44
44
|
* @returns {Promise<PDFDocument>} resolved promise return a pdfkit document
|
|
45
45
|
*/
|
|
46
|
-
createPdfKitDocument(docDefinition, options = {}) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
46
|
+
async createPdfKitDocument(docDefinition, options = {}) {
|
|
47
|
+
await this.resolveUrls(docDefinition);
|
|
48
|
+
|
|
49
|
+
docDefinition.version = docDefinition.version || '1.3';
|
|
50
|
+
docDefinition.subset = docDefinition.subset || undefined;
|
|
51
|
+
docDefinition.tagged = typeof docDefinition.tagged === 'boolean' ? docDefinition.tagged : false;
|
|
52
|
+
docDefinition.displayTitle = typeof docDefinition.displayTitle === 'boolean' ? docDefinition.displayTitle : false;
|
|
53
|
+
docDefinition.compress = typeof docDefinition.compress === 'boolean' ? docDefinition.compress : true;
|
|
54
|
+
docDefinition.images = docDefinition.images || {};
|
|
55
|
+
docDefinition.attachments = docDefinition.attachments || {};
|
|
56
|
+
docDefinition.pageMargins = isValue(docDefinition.pageMargins) ? docDefinition.pageMargins : 40;
|
|
57
|
+
docDefinition.patterns = docDefinition.patterns || {};
|
|
58
|
+
|
|
59
|
+
if (docDefinition.header && typeof docDefinition.header !== 'function') {
|
|
60
|
+
docDefinition.header = convertToDynamicContent(docDefinition.header);
|
|
61
|
+
}
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
if (docDefinition.footer && typeof docDefinition.footer !== 'function') {
|
|
64
|
+
docDefinition.footer = convertToDynamicContent(docDefinition.footer);
|
|
65
|
+
}
|
|
67
66
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
this.pdfKitDoc = new PDFDocument(this.fontDescriptors, docDefinition.images, docDefinition.patterns, docDefinition.attachments, pdfOptions, this.virtualfs);
|
|
89
|
-
embedFiles(docDefinition, this.pdfKitDoc);
|
|
90
|
-
|
|
91
|
-
const builder = new LayoutBuilder(pageSize, normalizePageMargin(docDefinition.pageMargins), new SVGMeasure());
|
|
92
|
-
|
|
93
|
-
builder.registerTableLayouts(tableLayouts);
|
|
94
|
-
if (options.tableLayouts) {
|
|
95
|
-
builder.registerTableLayouts(options.tableLayouts);
|
|
96
|
-
}
|
|
67
|
+
let pageSize = normalizePageSize(docDefinition.pageSize, docDefinition.pageOrientation);
|
|
68
|
+
|
|
69
|
+
let pdfOptions = {
|
|
70
|
+
size: [pageSize.width, pageSize.height],
|
|
71
|
+
pdfVersion: docDefinition.version,
|
|
72
|
+
subset: docDefinition.subset,
|
|
73
|
+
tagged: docDefinition.tagged,
|
|
74
|
+
displayTitle: docDefinition.displayTitle,
|
|
75
|
+
compress: docDefinition.compress,
|
|
76
|
+
userPassword: docDefinition.userPassword,
|
|
77
|
+
ownerPassword: docDefinition.ownerPassword,
|
|
78
|
+
permissions: docDefinition.permissions,
|
|
79
|
+
lang: docDefinition.language,
|
|
80
|
+
fontLayoutCache: typeof options.fontLayoutCache === 'boolean' ? options.fontLayoutCache : true,
|
|
81
|
+
bufferPages: options.bufferPages || false,
|
|
82
|
+
autoFirstPage: false,
|
|
83
|
+
info: createMetadata(docDefinition),
|
|
84
|
+
font: null
|
|
85
|
+
};
|
|
97
86
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
if (isNumber(maxNumberPages) && maxNumberPages > -1) {
|
|
101
|
-
pages = pages.slice(0, maxNumberPages);
|
|
102
|
-
}
|
|
87
|
+
this.pdfKitDoc = new PDFDocument(this.fontDescriptors, docDefinition.images, docDefinition.patterns, docDefinition.attachments, pdfOptions, this.virtualfs);
|
|
88
|
+
embedFiles(docDefinition, this.pdfKitDoc);
|
|
103
89
|
|
|
104
|
-
|
|
105
|
-
// was laid out using the height of each of the items in the page.
|
|
106
|
-
if (pageSize.height === Infinity) {
|
|
107
|
-
let pageHeight = calculatePageHeight(pages, docDefinition.pageMargins);
|
|
108
|
-
this.pdfKitDoc.options.size = [pageSize.width, pageHeight];
|
|
109
|
-
}
|
|
90
|
+
const builder = new LayoutBuilder(pageSize, normalizePageMargin(docDefinition.pageMargins), new SVGMeasure());
|
|
110
91
|
|
|
111
|
-
|
|
112
|
-
|
|
92
|
+
builder.registerTableLayouts(tableLayouts);
|
|
93
|
+
if (options.tableLayouts) {
|
|
94
|
+
builder.registerTableLayouts(options.tableLayouts);
|
|
95
|
+
}
|
|
113
96
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
97
|
+
let pages = builder.layoutDocument(docDefinition.content, this.pdfKitDoc, docDefinition.styles || {}, docDefinition.defaultStyle || { fontSize: 12, font: 'Roboto' }, docDefinition.background, docDefinition.header, docDefinition.footer, docDefinition.watermark, docDefinition.pageBreakBefore);
|
|
98
|
+
let maxNumberPages = docDefinition.maxPagesNumber || -1;
|
|
99
|
+
if (isNumber(maxNumberPages) && maxNumberPages > -1) {
|
|
100
|
+
pages = pages.slice(0, maxNumberPages);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// if pageSize.height is set to Infinity, calculate the actual height of the page that
|
|
104
|
+
// was laid out using the height of each of the items in the page.
|
|
105
|
+
if (pageSize.height === Infinity) {
|
|
106
|
+
let pageHeight = calculatePageHeight(pages, docDefinition.pageMargins);
|
|
107
|
+
pages.forEach(page => {
|
|
108
|
+
page.pageSize.height = pageHeight;
|
|
120
109
|
});
|
|
121
|
-
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const renderer = new Renderer(this.pdfKitDoc, options.progressCallback);
|
|
113
|
+
renderer.renderPages(pages);
|
|
114
|
+
|
|
115
|
+
return this.pdfKitDoc;
|
|
122
116
|
}
|
|
123
117
|
|
|
124
118
|
/**
|
|
125
119
|
* @param {object} docDefinition
|
|
126
120
|
* @returns {Promise}
|
|
127
121
|
*/
|
|
128
|
-
resolveUrls(docDefinition) {
|
|
122
|
+
async resolveUrls(docDefinition) {
|
|
129
123
|
const getExtendedUrl = url => {
|
|
130
124
|
if (typeof url === 'object') {
|
|
131
125
|
return { url: url.url, headers: url.headers };
|
|
@@ -134,96 +128,90 @@ class PdfPrinter {
|
|
|
134
128
|
return { url: url, headers: {} };
|
|
135
129
|
};
|
|
136
130
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
131
|
+
if (this.urlResolver === null) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
141
134
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
135
|
+
for (let font in this.fontDescriptors) {
|
|
136
|
+
if (this.fontDescriptors.hasOwnProperty(font)) {
|
|
137
|
+
if (this.fontDescriptors[font].normal) {
|
|
138
|
+
if (Array.isArray(this.fontDescriptors[font].normal)) { // TrueType Collection
|
|
139
|
+
let url = getExtendedUrl(this.fontDescriptors[font].normal[0]);
|
|
140
|
+
this.urlResolver.resolve(url.url, url.headers);
|
|
141
|
+
this.fontDescriptors[font].normal[0] = url.url;
|
|
142
|
+
} else {
|
|
143
|
+
let url = getExtendedUrl(this.fontDescriptors[font].normal);
|
|
144
|
+
this.urlResolver.resolve(url.url, url.headers);
|
|
145
|
+
this.fontDescriptors[font].normal = url.url;
|
|
154
146
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
147
|
+
}
|
|
148
|
+
if (this.fontDescriptors[font].bold) {
|
|
149
|
+
if (Array.isArray(this.fontDescriptors[font].bold)) { // TrueType Collection
|
|
150
|
+
let url = getExtendedUrl(this.fontDescriptors[font].bold[0]);
|
|
151
|
+
this.urlResolver.resolve(url.url, url.headers);
|
|
152
|
+
this.fontDescriptors[font].bold[0] = url.url;
|
|
153
|
+
} else {
|
|
154
|
+
let url = getExtendedUrl(this.fontDescriptors[font].bold);
|
|
155
|
+
this.urlResolver.resolve(url.url, url.headers);
|
|
156
|
+
this.fontDescriptors[font].bold = url.url;
|
|
165
157
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
158
|
+
}
|
|
159
|
+
if (this.fontDescriptors[font].italics) {
|
|
160
|
+
if (Array.isArray(this.fontDescriptors[font].italics)) { // TrueType Collection
|
|
161
|
+
let url = getExtendedUrl(this.fontDescriptors[font].italics[0]);
|
|
162
|
+
this.urlResolver.resolve(url.url, url.headers);
|
|
163
|
+
this.fontDescriptors[font].italics[0] = url.url;
|
|
164
|
+
} else {
|
|
165
|
+
let url = getExtendedUrl(this.fontDescriptors[font].italics);
|
|
166
|
+
this.urlResolver.resolve(url.url, url.headers);
|
|
167
|
+
this.fontDescriptors[font].italics = url.url;
|
|
176
168
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
169
|
+
}
|
|
170
|
+
if (this.fontDescriptors[font].bolditalics) {
|
|
171
|
+
if (Array.isArray(this.fontDescriptors[font].bolditalics)) { // TrueType Collection
|
|
172
|
+
let url = getExtendedUrl(this.fontDescriptors[font].bolditalics[0]);
|
|
173
|
+
this.urlResolver.resolve(url.url, url.headers);
|
|
174
|
+
this.fontDescriptors[font].bolditalics[0] = url.url;
|
|
175
|
+
} else {
|
|
176
|
+
let url = getExtendedUrl(this.fontDescriptors[font].bolditalics);
|
|
177
|
+
this.urlResolver.resolve(url.url, url.headers);
|
|
178
|
+
this.fontDescriptors[font].bolditalics = url.url;
|
|
187
179
|
}
|
|
188
180
|
}
|
|
189
181
|
}
|
|
182
|
+
}
|
|
190
183
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
184
|
+
if (docDefinition.images) {
|
|
185
|
+
for (let image in docDefinition.images) {
|
|
186
|
+
if (docDefinition.images.hasOwnProperty(image)) {
|
|
187
|
+
let url = getExtendedUrl(docDefinition.images[image]);
|
|
188
|
+
this.urlResolver.resolve(url.url, url.headers);
|
|
189
|
+
docDefinition.images[image] = url.url;
|
|
198
190
|
}
|
|
199
191
|
}
|
|
192
|
+
}
|
|
200
193
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
}
|
|
194
|
+
if (docDefinition.attachments) {
|
|
195
|
+
for (let attachment in docDefinition.attachments) {
|
|
196
|
+
if (docDefinition.attachments.hasOwnProperty(attachment) && docDefinition.attachments[attachment].src) {
|
|
197
|
+
let url = getExtendedUrl(docDefinition.attachments[attachment].src);
|
|
198
|
+
this.urlResolver.resolve(url.url, url.headers);
|
|
199
|
+
docDefinition.attachments[attachment].src = url.url;
|
|
208
200
|
}
|
|
209
201
|
}
|
|
202
|
+
}
|
|
210
203
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
204
|
+
if (docDefinition.files) {
|
|
205
|
+
for (let file in docDefinition.files) {
|
|
206
|
+
if (docDefinition.files.hasOwnProperty(file) && docDefinition.files[file].src) {
|
|
207
|
+
let url = getExtendedUrl(docDefinition.files[file].src);
|
|
208
|
+
this.urlResolver.resolve(url.url, url.headers);
|
|
209
|
+
docDefinition.files[file].src = url.url;
|
|
218
210
|
}
|
|
219
211
|
}
|
|
212
|
+
}
|
|
220
213
|
|
|
221
|
-
|
|
222
|
-
resolve();
|
|
223
|
-
}, result => {
|
|
224
|
-
reject(result);
|
|
225
|
-
});
|
|
226
|
-
});
|
|
214
|
+
await this.urlResolver.resolved();
|
|
227
215
|
}
|
|
228
216
|
}
|
|
229
217
|
|
package/src/StyleContextStack.js
CHANGED
package/src/TextBreaker.js
CHANGED
|
@@ -5,15 +5,34 @@ import StyleContextStack from './StyleContextStack';
|
|
|
5
5
|
/**
|
|
6
6
|
* @param {string} text
|
|
7
7
|
* @param {boolean} noWrap
|
|
8
|
+
* @param {boolean} breakAll
|
|
8
9
|
* @returns {Array}
|
|
9
10
|
*/
|
|
10
|
-
const splitWords = (text, noWrap) => {
|
|
11
|
+
const splitWords = (text, noWrap, breakAll = false) => {
|
|
11
12
|
let words = [];
|
|
13
|
+
if (text === undefined || text === null) {
|
|
14
|
+
text = '';
|
|
15
|
+
} else {
|
|
16
|
+
text = String(text);
|
|
17
|
+
}
|
|
12
18
|
|
|
13
19
|
if (noWrap) {
|
|
14
20
|
words.push({ text: text });
|
|
15
21
|
return words;
|
|
16
22
|
}
|
|
23
|
+
if (breakAll) {
|
|
24
|
+
return text.split('').map(c => {
|
|
25
|
+
if(c.match(/^\n$|^\r$/)) { // new line
|
|
26
|
+
return { text: '', lineEnd: true };
|
|
27
|
+
}
|
|
28
|
+
return { text: c };
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (text.length === 0) {
|
|
33
|
+
words.push({ text: '' });
|
|
34
|
+
return words;
|
|
35
|
+
}
|
|
17
36
|
|
|
18
37
|
let breaker = new LineBreaker(text);
|
|
19
38
|
let last = 0;
|
|
@@ -101,16 +120,16 @@ class TextBreaker {
|
|
|
101
120
|
let item = texts[i];
|
|
102
121
|
let style = null;
|
|
103
122
|
let words;
|
|
104
|
-
|
|
123
|
+
let breakAll = StyleContextStack.getStyleProperty(item || {}, styleContextStack, 'wordBreak', 'normal') === 'break-all';
|
|
105
124
|
let noWrap = StyleContextStack.getStyleProperty(item || {}, styleContextStack, 'noWrap', false);
|
|
106
125
|
if (isObject(item)) {
|
|
107
126
|
if (item._textRef && item._textRef._textNodeRef.text) {
|
|
108
127
|
item.text = item._textRef._textNodeRef.text;
|
|
109
128
|
}
|
|
110
|
-
words = splitWords(item.text, noWrap);
|
|
129
|
+
words = splitWords(item.text, noWrap, breakAll);
|
|
111
130
|
style = StyleContextStack.copyStyle(item);
|
|
112
131
|
} else {
|
|
113
|
-
words = splitWords(item, noWrap);
|
|
132
|
+
words = splitWords(item, noWrap, breakAll);
|
|
114
133
|
}
|
|
115
134
|
|
|
116
135
|
if (lastWord && words.length) {
|
package/src/URLResolver.js
CHANGED
|
@@ -1,46 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
});
|
|
1
|
+
async function fetchUrl(url, headers = {}) {
|
|
2
|
+
try {
|
|
3
|
+
const response = await fetch(url, { headers });
|
|
4
|
+
if (!response.ok) {
|
|
5
|
+
throw new Error(`Failed to fetch (status code: ${response.status}, url: "${url}")`);
|
|
6
|
+
}
|
|
7
|
+
return await response.arrayBuffer();
|
|
8
|
+
} catch (error) {
|
|
9
|
+
throw new Error(`Network request failed (url: "${url}", error: ${error.message})`);
|
|
11
10
|
}
|
|
12
|
-
|
|
13
|
-
const parsedUrl = new URL(url);
|
|
14
|
-
const h = (parsedUrl.protocol === 'https:') ? https : http;
|
|
15
|
-
let options = {
|
|
16
|
-
headers: headers
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
h.get(url, options, res => {
|
|
20
|
-
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) { // redirect url
|
|
21
|
-
res.resume();
|
|
22
|
-
|
|
23
|
-
fetchUrl(res.headers.location, {}, redirectCount + 1).then(buffer => {
|
|
24
|
-
resolve(buffer);
|
|
25
|
-
}, result => {
|
|
26
|
-
reject(result);
|
|
27
|
-
});
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const ok = res.statusCode >= 200 && res.statusCode < 300;
|
|
32
|
-
if (!ok) {
|
|
33
|
-
reject(new TypeError(`Failed to fetch (status code: ${res.statusCode}, url: "${url}")`));
|
|
34
|
-
res.resume();
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const chunks = [];
|
|
39
|
-
res.on('end', () => resolve(Buffer.concat(chunks)));
|
|
40
|
-
res.on('data', d => chunks.push(d));
|
|
41
|
-
}).on('error', reject);
|
|
42
|
-
});
|
|
43
|
-
};
|
|
11
|
+
}
|
|
44
12
|
|
|
45
13
|
class URLResolver {
|
|
46
14
|
constructor(fs) {
|
|
@@ -49,38 +17,25 @@ class URLResolver {
|
|
|
49
17
|
}
|
|
50
18
|
|
|
51
19
|
resolve(url, headers = {}) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
|
|
56
|
-
// url was downloaded earlier
|
|
57
|
-
resolve();
|
|
58
|
-
} else {
|
|
59
|
-
fetchUrl(url, headers).then(buffer => {
|
|
60
|
-
this.fs.writeFileSync(url, buffer);
|
|
61
|
-
resolve();
|
|
62
|
-
}, result => {
|
|
63
|
-
reject(result);
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
} else {
|
|
67
|
-
// cannot be resolved
|
|
68
|
-
resolve();
|
|
20
|
+
const resolveUrlInternal = async () => {
|
|
21
|
+
if (url.toLowerCase().startsWith('https://') || url.toLowerCase().startsWith('http://')) {
|
|
22
|
+
if (this.fs.existsSync(url)) {
|
|
23
|
+
return; // url was downloaded earlier
|
|
69
24
|
}
|
|
70
|
-
|
|
71
|
-
|
|
25
|
+
const buffer = await fetchUrl(url, headers);
|
|
26
|
+
this.fs.writeFileSync(url, buffer);
|
|
27
|
+
}
|
|
28
|
+
// else cannot be resolved
|
|
29
|
+
};
|
|
72
30
|
|
|
31
|
+
if (!this.resolving[url]) {
|
|
32
|
+
this.resolving[url] = resolveUrlInternal();
|
|
33
|
+
}
|
|
73
34
|
return this.resolving[url];
|
|
74
35
|
}
|
|
75
36
|
|
|
76
37
|
resolved() {
|
|
77
|
-
return
|
|
78
|
-
Promise.all(Object.values(this.resolving)).then(() => {
|
|
79
|
-
resolve();
|
|
80
|
-
}, result => {
|
|
81
|
-
reject(result);
|
|
82
|
-
});
|
|
83
|
-
});
|
|
38
|
+
return Promise.all(Object.values(this.resolving));
|
|
84
39
|
}
|
|
85
40
|
|
|
86
41
|
}
|
|
@@ -20,98 +20,60 @@ class OutputDocumentBrowser extends OutputDocument {
|
|
|
20
20
|
/**
|
|
21
21
|
* @returns {Promise<Blob>}
|
|
22
22
|
*/
|
|
23
|
-
getBlob() {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
let blob = new Blob([buffer], { type: 'application/pdf' });
|
|
28
|
-
resolve(blob);
|
|
29
|
-
} catch (e) {
|
|
30
|
-
reject(e);
|
|
31
|
-
}
|
|
32
|
-
}, result => {
|
|
33
|
-
reject(result);
|
|
34
|
-
});
|
|
35
|
-
});
|
|
23
|
+
async getBlob() {
|
|
24
|
+
const buffer = await this.getBuffer();
|
|
25
|
+
return new Blob([buffer], { type: 'application/pdf' });
|
|
36
26
|
}
|
|
37
27
|
|
|
38
28
|
/**
|
|
39
29
|
* @param {string} filename
|
|
40
30
|
* @returns {Promise}
|
|
41
31
|
*/
|
|
42
|
-
download(filename = 'file.pdf') {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
try {
|
|
46
|
-
saveAs(blob, filename);
|
|
47
|
-
resolve();
|
|
48
|
-
} catch (e) {
|
|
49
|
-
reject(e);
|
|
50
|
-
}
|
|
51
|
-
}, result => {
|
|
52
|
-
reject(result);
|
|
53
|
-
});
|
|
54
|
-
});
|
|
32
|
+
async download(filename = 'file.pdf') {
|
|
33
|
+
const blob = await this.getBlob();
|
|
34
|
+
saveAs(blob, filename);
|
|
55
35
|
}
|
|
56
36
|
|
|
57
37
|
/**
|
|
58
38
|
* @param {Window} win
|
|
59
39
|
* @returns {Promise}
|
|
60
40
|
*/
|
|
61
|
-
open(win = null) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
win.location.href = pdfUrl;
|
|
41
|
+
async open(win = null) {
|
|
42
|
+
if (!win) {
|
|
43
|
+
win = openWindow();
|
|
44
|
+
}
|
|
45
|
+
const blob = await this.getBlob();
|
|
46
|
+
try {
|
|
47
|
+
let urlCreator = window.URL || window.webkitURL;
|
|
48
|
+
let pdfUrl = urlCreator.createObjectURL(blob);
|
|
49
|
+
win.location.href = pdfUrl;
|
|
71
50
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (win.window === null) { // is closed by AdBlock
|
|
80
|
-
window.location.href = pdfUrl; // open in actual window
|
|
81
|
-
}
|
|
82
|
-
resolve();
|
|
83
|
-
}, 500);
|
|
51
|
+
/* temporarily disabled
|
|
52
|
+
if (win === window) {
|
|
53
|
+
return;
|
|
54
|
+
} else {
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
if (win.window === null) { // is closed by AdBlock
|
|
57
|
+
window.location.href = pdfUrl; // open in actual window
|
|
84
58
|
}
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
});
|
|
93
|
-
});
|
|
59
|
+
return;
|
|
60
|
+
}, 500);
|
|
61
|
+
}
|
|
62
|
+
*/
|
|
63
|
+
} finally {
|
|
64
|
+
win.close();
|
|
65
|
+
}
|
|
94
66
|
}
|
|
95
67
|
|
|
96
68
|
/**
|
|
97
69
|
* @param {Window} win
|
|
98
70
|
* @returns {Promise}
|
|
99
71
|
*/
|
|
100
|
-
print(win = null) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
return this.open(win).then(() => {
|
|
105
|
-
resolve();
|
|
106
|
-
}, result => {
|
|
107
|
-
reject(result);
|
|
108
|
-
});
|
|
109
|
-
}, result => {
|
|
110
|
-
reject(result);
|
|
111
|
-
});
|
|
112
|
-
});
|
|
72
|
+
async print(win = null) {
|
|
73
|
+
const stream = await this.getStream();
|
|
74
|
+
stream.setOpenActionAsPrint();
|
|
75
|
+
await this.open(win);
|
|
113
76
|
}
|
|
114
|
-
|
|
115
77
|
}
|
|
116
78
|
|
|
117
79
|
export default OutputDocumentBrowser;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pdfmakeBase from '../base';
|
|
2
2
|
import OutputDocumentBrowser from './OutputDocumentBrowser';
|
|
3
|
-
import
|
|
3
|
+
import URLResolver from '../URLResolver';
|
|
4
4
|
import fs from 'fs';
|
|
5
5
|
import configurator from 'core-js/configurator';
|
|
6
6
|
|
|
@@ -21,7 +21,7 @@ let defaultClientFonts = {
|
|
|
21
21
|
class pdfmake extends pdfmakeBase {
|
|
22
22
|
constructor() {
|
|
23
23
|
super();
|
|
24
|
-
this.urlResolver = () => new
|
|
24
|
+
this.urlResolver = () => new URLResolver(this.virtualfs);
|
|
25
25
|
this.fonts = defaultClientFonts;
|
|
26
26
|
}
|
|
27
27
|
|