ngx-print 22.1.0 → 22.1.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 (42) hide show
  1. package/fesm2022/ngx-print.mjs +493 -0
  2. package/fesm2022/ngx-print.mjs.map +1 -0
  3. package/package.json +44 -60
  4. package/types/ngx-print.d.ts +187 -0
  5. package/types/ngx-print.d.ts.map +1 -0
  6. package/.editorconfig +0 -13
  7. package/.eslintrc.json +0 -50
  8. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
  9. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -19
  10. package/.github/dependabot.yml +0 -17
  11. package/.github/workflows/PullRequest.yml +0 -32
  12. package/.github/workflows/stale.yml +0 -25
  13. package/.prettierignore +0 -42
  14. package/.prettierrc.json +0 -14
  15. package/CHANGELOG.md +0 -126
  16. package/_config.yml +0 -1
  17. package/angular.json +0 -132
  18. package/eslint.config.js +0 -32
  19. package/ng-package.json +0 -7
  20. package/projects/demo/public/favicon.ico +0 -0
  21. package/projects/demo/src/app/app.config.ts +0 -11
  22. package/projects/demo/src/app/app.routes.ts +0 -3
  23. package/projects/demo/src/app/demo.component.html +0 -83
  24. package/projects/demo/src/app/demo.component.scss +0 -54
  25. package/projects/demo/src/app/demo.component.ts +0 -73
  26. package/projects/demo/src/index.html +0 -13
  27. package/projects/demo/src/main.ts +0 -5
  28. package/projects/demo/src/styles.scss +0 -1
  29. package/projects/demo/tsconfig.app.json +0 -19
  30. package/projects/demo/tsconfig.spec.json +0 -15
  31. package/src/lib/ngx-print.base.ts +0 -381
  32. package/src/lib/ngx-print.directive.spec.ts +0 -232
  33. package/src/lib/ngx-print.directive.ts +0 -72
  34. package/src/lib/ngx-print.module.ts +0 -8
  35. package/src/lib/ngx-print.service.spec.ts +0 -276
  36. package/src/lib/ngx-print.service.ts +0 -50
  37. package/src/lib/print-options.ts +0 -16
  38. package/src/public_api.ts +0 -8
  39. package/tsconfig.json +0 -38
  40. package/tsconfig.lib.json +0 -19
  41. package/tsconfig.spec.json +0 -10
  42. package/tslint.json +0 -17
@@ -0,0 +1,493 @@
1
+ import * as i0 from '@angular/core';
2
+ import { inject, DOCUMENT, CSP_NONCE, Service, input, output, Directive, NgModule } from '@angular/core';
3
+ import { Subject, take } from 'rxjs';
4
+
5
+ class PrintOptions {
6
+ printSectionId = '';
7
+ printTitle = '';
8
+ useExistingCss = false;
9
+ bodyClass = '';
10
+ printMethod = 'window';
11
+ previewOnly = false;
12
+ closeWindow = true;
13
+ printDelay = 0;
14
+ constructor(options) {
15
+ if (options) {
16
+ Object.assign(this, options);
17
+ }
18
+ }
19
+ }
20
+
21
+ class PrintBase {
22
+ document = inject(DOCUMENT);
23
+ nonce = inject(CSP_NONCE, { optional: true });
24
+ _iframeElement;
25
+ _printStyle = [];
26
+ _styleSheetFile = '';
27
+ printComplete = new Subject();
28
+ //#region Getters and Setters
29
+ /**
30
+ * Sets the print styles based on the provided values.
31
+ *
32
+ * @param values - Either a key-value pairs object representing print styles, or a raw CSS string.
33
+ * @protected
34
+ */
35
+ setPrintStyle(values) {
36
+ if (typeof values === 'string') {
37
+ this._printStyle = values ? [values] : [];
38
+ return;
39
+ }
40
+ this._printStyle = [];
41
+ for (const [selector, declarations] of Object.entries(values)) {
42
+ // Built declaration-by-declaration (rather than via JSON.stringify + a quote-stripping
43
+ // regex) so that quotes and commas that are part of a CSS value (e.g. quoted font names,
44
+ // comma-separated font-family fallback lists) survive instead of being stripped/mangled.
45
+ const body = Object.entries(declarations)
46
+ .map(([property, value]) => `${property}:${value}`)
47
+ .join(';');
48
+ this._printStyle.push(`${selector}{${body}}`);
49
+ }
50
+ }
51
+ /**
52
+ * @returns the string that create the stylesheet which will be injected
53
+ * later within <style></style> tag.
54
+ */
55
+ returnStyleValues() {
56
+ const styleNonce = this.nonce ? ` nonce="${this.nonce}"` : '';
57
+ return `<style${styleNonce}> ${this._printStyle.join(' ')} </style>`;
58
+ }
59
+ /**
60
+ * @returns string which contains the link tags containing the css which will
61
+ * be injected later within <head></head> tag.
62
+ *
63
+ */
64
+ returnStyleSheetLinkTags() {
65
+ return this._styleSheetFile;
66
+ }
67
+ /**
68
+ * Sets the style sheet file based on the provided CSS list.
69
+ *
70
+ * @param {string} cssList - CSS file or list of CSS files.
71
+ * @protected
72
+ */
73
+ // prettier-ignore
74
+ setStyleSheetFile(cssList) {
75
+ if (!cssList) {
76
+ this._styleSheetFile = '';
77
+ return;
78
+ }
79
+ const files = cssList.split(',').map(f => f.trim());
80
+ const nonceAttr = this.nonce ? ` nonce="${this.nonce}"` : '';
81
+ this._styleSheetFile = files
82
+ .map(url => `<link${nonceAttr} rel="stylesheet" type="text/css" href="${url}">`)
83
+ .join('');
84
+ }
85
+ //#endregion
86
+ //#region Private methods used by PrintBase
87
+ syncFormValues(source, clone) {
88
+ // Select all form elements
89
+ const selector = 'input, select, textarea';
90
+ const sourceEls = source.querySelectorAll(selector);
91
+ const cloneEls = clone.querySelectorAll(selector);
92
+ for (let i = 0; i < sourceEls.length; i++) {
93
+ const srcNode = sourceEls[i];
94
+ const cloneNode = cloneEls[i];
95
+ if (srcNode instanceof HTMLInputElement) {
96
+ if (srcNode.type === 'checkbox' || srcNode.type === 'radio') {
97
+ if (srcNode.checked)
98
+ cloneNode.setAttribute('checked', '');
99
+ else
100
+ cloneNode.removeAttribute('checked'); // Remove if unchecked
101
+ }
102
+ else if (srcNode.type === 'file') {
103
+ // File inputs can't be set programmatically for security
104
+ continue;
105
+ }
106
+ else {
107
+ cloneNode.setAttribute('value', srcNode.value);
108
+ }
109
+ }
110
+ else if (srcNode instanceof HTMLTextAreaElement) {
111
+ cloneNode.textContent = srcNode.value; // Use textContent, not innerHTML
112
+ }
113
+ else if (srcNode instanceof HTMLSelectElement) {
114
+ Array.from(cloneNode.options).forEach((opt, idx) => {
115
+ if (idx === srcNode.selectedIndex) {
116
+ opt.setAttribute('selected', '');
117
+ }
118
+ else {
119
+ opt.removeAttribute('selected'); // Remove from non-selected
120
+ }
121
+ });
122
+ }
123
+ }
124
+ }
125
+ /**
126
+ * Converts a canvas element to an image and returns its HTML string.
127
+ *
128
+ * @param {HTMLCanvasElement} canvasElm - The canvas element to convert.
129
+ * @returns {HTMLImageElement | null} - HTML Element of the image.
130
+ * @private
131
+ */
132
+ canvasToImageHtml(canvasElm) {
133
+ try {
134
+ const dataUrl = canvasElm.toDataURL(); // may throw if canvas is tainted
135
+ const img = this.document.createElement('img');
136
+ img.src = dataUrl;
137
+ img.style.maxWidth = '100%';
138
+ // Preserve displayed size (not just bitmap size)
139
+ const rect = canvasElm.getBoundingClientRect();
140
+ if (rect.width)
141
+ img.style.width = `${rect.width}px`;
142
+ if (rect.height)
143
+ img.style.height = `${rect.height}px`;
144
+ return img;
145
+ }
146
+ catch (err) {
147
+ console.warn(`Canvas conversion failed for ${canvasElm}. Likely the canvas is tainted:`, err);
148
+ // If toDataURL() fails (e.g., tainted canvas), keep canvas as-is in print output
149
+ return null;
150
+ }
151
+ }
152
+ /**
153
+ * Includes canvas contents in the print section via img tags.
154
+ *
155
+ * @private
156
+ * @param source
157
+ * @param clone
158
+ */
159
+ updateCanvasToImage(source, clone) {
160
+ const sourceCanvases = source.querySelectorAll('canvas');
161
+ const cloneCanvases = clone.querySelectorAll('canvas');
162
+ for (let i = 0; i < sourceCanvases.length; i++) {
163
+ const srcCanvas = sourceCanvases[i];
164
+ const cloneCanvas = cloneCanvases[i];
165
+ const img = this.canvasToImageHtml(srcCanvas);
166
+ if (img) {
167
+ cloneCanvas.replaceWith(img);
168
+ }
169
+ }
170
+ }
171
+ /**
172
+ * Retrieves the HTML content of a specified printing section.
173
+ *
174
+ * @param {string} printSectionId - Id of the printing section.
175
+ * @returns {string | null} - HTML content of the printing section, or null if not found.
176
+ * @private
177
+ */
178
+ getHtmlContents(printSectionId) {
179
+ const sourceElm = this.document.getElementById(printSectionId);
180
+ if (!sourceElm)
181
+ return null;
182
+ const cloneElm = sourceElm.cloneNode(true); // cloneNode(true) deep clones subtree
183
+ this.syncFormValues(sourceElm, cloneElm);
184
+ this.updateCanvasToImage(sourceElm, cloneElm);
185
+ return cloneElm.outerHTML;
186
+ }
187
+ /**
188
+ * Retrieves the HTML content of elements with the specified tag.
189
+ *
190
+ * @param {keyof HTMLElementTagNameMap} tag - HTML tag name.
191
+ * @returns {string} - Concatenated outerHTML of elements with the specified tag.
192
+ * @private
193
+ */
194
+ getElementTag(tag) {
195
+ const html = [];
196
+ const elements = this.document.getElementsByTagName(tag);
197
+ for (const el of Array.from(elements)) {
198
+ html.push(el.outerHTML);
199
+ }
200
+ return html.join('\r\n');
201
+ }
202
+ //#endregion
203
+ notifyPrintComplete() {
204
+ this.printComplete.next();
205
+ }
206
+ /**
207
+ * Prints the specified content using the provided print options.
208
+ *
209
+ * @public
210
+ * @param printOptionInput - Options for printing.
211
+ */
212
+ print(printOptionInput) {
213
+ const printOptions = new PrintOptions(printOptionInput);
214
+ if (printOptions.printMethod === 'iframe') {
215
+ this.printWithIframe(printOptions);
216
+ }
217
+ else {
218
+ this.printWithWindow(printOptions);
219
+ }
220
+ }
221
+ printWithWindow(printOptions) {
222
+ // If the openNewTab option is set to true, then set the popOut option to an empty string
223
+ // This will cause the print dialog to open in a new tab.
224
+ const popOut = printOptions.printMethod === 'tab' ? '' : 'top=0,left=0,height=auto,width=auto';
225
+ const popupWin = window.open('', '_blank', popOut);
226
+ if (!popupWin) {
227
+ // the popup window could not be opened.
228
+ console.error('Could not open print window.');
229
+ return;
230
+ }
231
+ popupWin.document.open();
232
+ // Create the HTML structure
233
+ this.buildPrintDocument(popupWin.document, printOptions);
234
+ popupWin.document.close();
235
+ // Listen for the window closing
236
+ const checkClosedInterval = setInterval(() => {
237
+ if (popupWin.closed) {
238
+ clearInterval(checkClosedInterval);
239
+ this.notifyPrintComplete();
240
+ }
241
+ }, 500);
242
+ popupWin.addEventListener('load', () => {
243
+ if (!printOptions.previewOnly) {
244
+ setTimeout(() => {
245
+ popupWin.print();
246
+ if (printOptions.closeWindow)
247
+ popupWin.close();
248
+ }, printOptions.printDelay || 0);
249
+ }
250
+ });
251
+ }
252
+ printWithIframe(printOptions) {
253
+ if (this._iframeElement) {
254
+ this._iframeElement.remove();
255
+ }
256
+ this._iframeElement = this.document.createElement('iframe');
257
+ const iframe = this._iframeElement;
258
+ iframe.id = 'print-iframe-' + new Date().getTime();
259
+ iframe.style.position = 'absolute';
260
+ iframe.style.left = '-9999px';
261
+ iframe.style.top = '-9999px';
262
+ iframe.style.width = '0px';
263
+ iframe.style.height = '0px';
264
+ iframe.ariaHidden = 'true';
265
+ this.document.body.appendChild(iframe);
266
+ const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;
267
+ if (!iframeDoc) {
268
+ console.error('Could not access iframe document.');
269
+ this.document.body.removeChild(iframe);
270
+ return;
271
+ }
272
+ iframeDoc.open();
273
+ const success = this.buildPrintDocument(iframeDoc, printOptions);
274
+ if (!success) {
275
+ iframeDoc.close();
276
+ this.document.body.removeChild(iframe);
277
+ return;
278
+ }
279
+ iframeDoc.close();
280
+ iframe.onload = () => {
281
+ const printWindow = iframe.contentWindow;
282
+ if (!printWindow) {
283
+ console.error('Could not access iframe window.');
284
+ this.document.body.removeChild(iframe);
285
+ return;
286
+ }
287
+ setTimeout(() => {
288
+ if (printOptions.previewOnly) {
289
+ return;
290
+ }
291
+ printWindow.focus();
292
+ printWindow.print();
293
+ const mediaQueryList = printWindow.matchMedia('print');
294
+ const listener = (mql) => {
295
+ if (!mql.matches) {
296
+ this.notifyPrintComplete();
297
+ mediaQueryList.removeEventListener('change', listener);
298
+ }
299
+ };
300
+ mediaQueryList.addEventListener('change', listener);
301
+ }, printOptions.printDelay || 0);
302
+ };
303
+ }
304
+ prepareDocumentComponents(printOptions) {
305
+ let styles = '';
306
+ let links = '';
307
+ const baseTag = this.getElementTag('base');
308
+ if (printOptions.useExistingCss) {
309
+ styles = this.getElementTag('style');
310
+ links = this.getElementTag('link');
311
+ }
312
+ const printContents = this.getHtmlContents(printOptions.printSectionId);
313
+ return { styles, links, baseTag, printContents };
314
+ }
315
+ buildPrintDocument(doc, printOptions) {
316
+ const components = this.prepareDocumentComponents(printOptions);
317
+ if (!components.printContents) {
318
+ console.error(`Print section with id "${printOptions.printSectionId}" not found.`);
319
+ return false;
320
+ }
321
+ const html = doc.createElement('html');
322
+ const head = doc.createElement('head');
323
+ const body = doc.createElement('body');
324
+ // Set title
325
+ const title = doc.createElement('title');
326
+ title.textContent = printOptions.printTitle || '';
327
+ head.appendChild(title);
328
+ // Add all head content
329
+ if (components.baseTag) {
330
+ head.innerHTML += components.baseTag;
331
+ }
332
+ head.innerHTML += this.returnStyleValues();
333
+ head.innerHTML += this.returnStyleSheetLinkTags();
334
+ head.innerHTML += components.styles;
335
+ head.innerHTML += components.links;
336
+ // Set body class and content
337
+ if (printOptions.bodyClass)
338
+ body.className = printOptions.bodyClass;
339
+ body.innerHTML += components.printContents;
340
+ // Assemble document
341
+ html.appendChild(head);
342
+ html.appendChild(body);
343
+ doc.appendChild(html);
344
+ return true;
345
+ }
346
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PrintBase, deps: [], target: i0.ɵɵFactoryTarget.Service });
347
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.2", ngImport: i0, type: PrintBase });
348
+ }
349
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: PrintBase, decorators: [{
350
+ type: Service
351
+ }] });
352
+
353
+ class NgxPrintDirective extends PrintBase {
354
+ /**
355
+ * Prevents the print dialog from opening on the window
356
+ */
357
+ previewOnly = input(false, /* @ts-ignore */
358
+ ...(ngDevMode ? [{ debugName: "previewOnly" }] : /* istanbul ignore next */ []));
359
+ printSectionId = input('', /* @ts-ignore */
360
+ ...(ngDevMode ? [{ debugName: "printSectionId" }] : /* istanbul ignore next */ []));
361
+ printTitle = input('', /* @ts-ignore */
362
+ ...(ngDevMode ? [{ debugName: "printTitle" }] : /* istanbul ignore next */ []));
363
+ useExistingCss = input(false, /* @ts-ignore */
364
+ ...(ngDevMode ? [{ debugName: "useExistingCss" }] : /* istanbul ignore next */ []));
365
+ /**
366
+ * A delay in milliseconds to force the print dialog to wait before opened. Default: 0
367
+ */
368
+ printDelay = input(0, /* @ts-ignore */
369
+ ...(ngDevMode ? [{ debugName: "printDelay" }] : /* istanbul ignore next */ []));
370
+ /**
371
+ * Whether to close the window after print() returns.
372
+ */
373
+ closeWindow = input(true, /* @ts-ignore */
374
+ ...(ngDevMode ? [{ debugName: "closeWindow" }] : /* istanbul ignore next */ []));
375
+ /**
376
+ * Class attribute to apply to the body element.
377
+ */
378
+ bodyClass = input('', /* @ts-ignore */
379
+ ...(ngDevMode ? [{ debugName: "bodyClass" }] : /* istanbul ignore next */ []));
380
+ /**
381
+ * Which PrintMethod (iframe/window/tab) to use.
382
+ */
383
+ printMethod = input('window', /* @ts-ignore */
384
+ ...(ngDevMode ? [{ debugName: "printMethod" }] : /* istanbul ignore next */ []));
385
+ printStyle = input({}, /* @ts-ignore */
386
+ ...(ngDevMode ? [{ debugName: "printStyle" }] : /* istanbul ignore next */ []));
387
+ styleSheetFile = input('', /* @ts-ignore */
388
+ ...(ngDevMode ? [{ debugName: "styleSheetFile" }] : /* istanbul ignore next */ []));
389
+ printCompleted = output();
390
+ print() {
391
+ // Inputs carry side effects on PrintBase's internal style state, so they're applied
392
+ // synchronously here rather than via effect() (effects shouldn't propagate state).
393
+ super.setPrintStyle(this.printStyle());
394
+ super.setStyleSheetFile(this.styleSheetFile());
395
+ super.print({
396
+ printSectionId: this.printSectionId(),
397
+ printTitle: this.printTitle(),
398
+ useExistingCss: this.useExistingCss(),
399
+ bodyClass: this.bodyClass(),
400
+ printMethod: this.printMethod(),
401
+ previewOnly: this.previewOnly(),
402
+ closeWindow: this.closeWindow(),
403
+ printDelay: this.printDelay(),
404
+ });
405
+ this.printComplete.pipe(take(1)).subscribe(() => {
406
+ this.printCompleted.emit();
407
+ });
408
+ }
409
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: NgxPrintDirective, deps: null, target: i0.ɵɵFactoryTarget.Directive });
410
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: NgxPrintDirective, isStandalone: true, selector: "[ngxPrint]", inputs: { previewOnly: { classPropertyName: "previewOnly", publicName: "previewOnly", isSignal: true, isRequired: false, transformFunction: null }, printSectionId: { classPropertyName: "printSectionId", publicName: "printSectionId", isSignal: true, isRequired: false, transformFunction: null }, printTitle: { classPropertyName: "printTitle", publicName: "printTitle", isSignal: true, isRequired: false, transformFunction: null }, useExistingCss: { classPropertyName: "useExistingCss", publicName: "useExistingCss", isSignal: true, isRequired: false, transformFunction: null }, printDelay: { classPropertyName: "printDelay", publicName: "printDelay", isSignal: true, isRequired: false, transformFunction: null }, closeWindow: { classPropertyName: "closeWindow", publicName: "closeWindow", isSignal: true, isRequired: false, transformFunction: null }, bodyClass: { classPropertyName: "bodyClass", publicName: "bodyClass", isSignal: true, isRequired: false, transformFunction: null }, printMethod: { classPropertyName: "printMethod", publicName: "printMethod", isSignal: true, isRequired: false, transformFunction: null }, printStyle: { classPropertyName: "printStyle", publicName: "printStyle", isSignal: true, isRequired: false, transformFunction: null }, styleSheetFile: { classPropertyName: "styleSheetFile", publicName: "styleSheetFile", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { printCompleted: "printCompleted" }, host: { listeners: { "click": "print()" } }, usesInheritance: true, ngImport: i0 });
411
+ }
412
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: NgxPrintDirective, decorators: [{
413
+ type: Directive,
414
+ args: [{
415
+ selector: '[ngxPrint]',
416
+ standalone: true,
417
+ host: {
418
+ '(click)': 'print()',
419
+ },
420
+ }]
421
+ }], propDecorators: { previewOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "previewOnly", required: false }] }], printSectionId: [{ type: i0.Input, args: [{ isSignal: true, alias: "printSectionId", required: false }] }], printTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "printTitle", required: false }] }], useExistingCss: [{ type: i0.Input, args: [{ isSignal: true, alias: "useExistingCss", required: false }] }], printDelay: [{ type: i0.Input, args: [{ isSignal: true, alias: "printDelay", required: false }] }], closeWindow: [{ type: i0.Input, args: [{ isSignal: true, alias: "closeWindow", required: false }] }], bodyClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "bodyClass", required: false }] }], printMethod: [{ type: i0.Input, args: [{ isSignal: true, alias: "printMethod", required: false }] }], printStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "printStyle", required: false }] }], styleSheetFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "styleSheetFile", required: false }] }], printCompleted: [{ type: i0.Output, args: ["printCompleted"] }] } });
422
+
423
+ class NgxPrintModule {
424
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: NgxPrintModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
425
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.2", ngImport: i0, type: NgxPrintModule, imports: [NgxPrintDirective], exports: [NgxPrintDirective] });
426
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: NgxPrintModule });
427
+ }
428
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: NgxPrintModule, decorators: [{
429
+ type: NgModule,
430
+ args: [{
431
+ imports: [NgxPrintDirective],
432
+ exports: [NgxPrintDirective],
433
+ }]
434
+ }] });
435
+
436
+ /**
437
+ * Service for handling printing functionality in Angular applications.
438
+ * Extends the base printing class (PrintBase).
439
+ *
440
+ * @export
441
+ * @class NgxPrintService
442
+ * @extends {PrintBase}
443
+ */
444
+ class NgxPrintService extends PrintBase {
445
+ printComplete$ = this.printComplete.asObservable();
446
+ /**
447
+ * Initiates the printing process using the provided print options.
448
+ *
449
+ * @param {PrintOptions} printOptions - Options for configuring the printing process.
450
+ * @memberof NgxPrintService
451
+ * @returns {void}
452
+ */
453
+ print(printOptions) {
454
+ // Call the print method in the parent class
455
+ super.print(printOptions);
456
+ }
457
+ /**
458
+ * Sets the print style for the printing process.
459
+ *
460
+ * @param values - Either a dictionary representing the print styles, or a raw CSS string.
461
+ * @memberof NgxPrintService
462
+ * @setter
463
+ */
464
+ set printStyle(values) {
465
+ super.setPrintStyle(values);
466
+ }
467
+ /**
468
+ * Sets the stylesheet file for the printing process.
469
+ *
470
+ * @param {string} cssList - A string representing the path to the stylesheet file.
471
+ * @memberof NgxPrintService
472
+ * @setter
473
+ */
474
+ set styleSheetFile(cssList) {
475
+ super.setStyleSheetFile(cssList);
476
+ }
477
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: NgxPrintService, deps: [], target: i0.ɵɵFactoryTarget.Service });
478
+ static ɵprov = i0.ɵɵngDeclareService({ minVersion: "22.0.0", version: "22.0.2", ngImport: i0, type: NgxPrintService });
479
+ }
480
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: NgxPrintService, decorators: [{
481
+ type: Service
482
+ }] });
483
+
484
+ /*
485
+ * Public API Surface of ngx-print
486
+ */
487
+
488
+ /**
489
+ * Generated bundle index. Do not edit.
490
+ */
491
+
492
+ export { NgxPrintDirective, NgxPrintModule, NgxPrintService, PrintOptions };
493
+ //# sourceMappingURL=ngx-print.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ngx-print.mjs","sources":["../../../src/lib/print-options.ts","../../../src/lib/ngx-print.base.ts","../../../src/lib/ngx-print.directive.ts","../../../src/lib/ngx-print.module.ts","../../../src/lib/ngx-print.service.ts","../../../src/public_api.ts","../../../src/ngx-print.ts"],"sourcesContent":["export class PrintOptions {\r\n printSectionId = '';\r\n printTitle = '';\r\n useExistingCss = false;\r\n bodyClass = '';\r\n printMethod: 'window' | 'tab' | 'iframe' = 'window';\r\n previewOnly = false;\r\n closeWindow = true;\r\n printDelay = 0;\r\n\r\n constructor(options?: Partial<PrintOptions>) {\r\n if (options) {\r\n Object.assign(this, options);\r\n }\r\n }\r\n}\r\n","import { CSP_NONCE, DOCUMENT, inject, Service } from '@angular/core';\r\nimport { Subject } from 'rxjs';\r\nimport { PrintOptions } from './print-options';\r\n\r\n/** For example:\r\n * {\r\n * 'h2': { 'border': 'solid 1px' },\r\n * 'h1': { 'color': 'red', 'border': '1px solid' },\r\n * */\r\nexport type PrintStyle = Record<string, Record<string, string>>;\r\n\r\n/**\r\n * Either a {@link PrintStyle} object, or a raw CSS string (e.g. `'h1 { color: red; }'`)\r\n * to be injected into the print document's <style> tag as-is.\r\n */\r\nexport type PrintStyleInput = PrintStyle | string;\r\n\r\n@Service()\r\nexport class PrintBase {\r\n private document = inject(DOCUMENT);\r\n private nonce = inject(CSP_NONCE, { optional: true });\r\n\r\n private _iframeElement: HTMLIFrameElement | undefined;\r\n private _printStyle: string[] = [];\r\n private _styleSheetFile = '';\r\n protected printComplete = new Subject<void>();\r\n\r\n //#region Getters and Setters\r\n /**\r\n * Sets the print styles based on the provided values.\r\n *\r\n * @param values - Either a key-value pairs object representing print styles, or a raw CSS string.\r\n * @protected\r\n */\r\n protected setPrintStyle(values: PrintStyleInput) {\r\n if (typeof values === 'string') {\r\n this._printStyle = values ? [values] : [];\r\n return;\r\n }\r\n\r\n this._printStyle = [];\r\n for (const [selector, declarations] of Object.entries(values)) {\r\n // Built declaration-by-declaration (rather than via JSON.stringify + a quote-stripping\r\n // regex) so that quotes and commas that are part of a CSS value (e.g. quoted font names,\r\n // comma-separated font-family fallback lists) survive instead of being stripped/mangled.\r\n const body = Object.entries(declarations)\r\n .map(([property, value]) => `${property}:${value}`)\r\n .join(';');\r\n this._printStyle.push(`${selector}{${body}}`);\r\n }\r\n }\r\n\r\n /**\r\n * @returns the string that create the stylesheet which will be injected\r\n * later within <style></style> tag.\r\n */\r\n public returnStyleValues(): string {\r\n const styleNonce = this.nonce ? ` nonce=\"${this.nonce}\"` : '';\r\n return `<style${styleNonce}> ${this._printStyle.join(' ')} </style>`;\r\n }\r\n\r\n /**\r\n * @returns string which contains the link tags containing the css which will\r\n * be injected later within <head></head> tag.\r\n *\r\n */\r\n private returnStyleSheetLinkTags(): string {\r\n return this._styleSheetFile;\r\n }\r\n\r\n /**\r\n * Sets the style sheet file based on the provided CSS list.\r\n *\r\n * @param {string} cssList - CSS file or list of CSS files.\r\n * @protected\r\n */\r\n // prettier-ignore\r\n protected setStyleSheetFile(cssList: string): void {\r\n if (!cssList) {\r\n this._styleSheetFile = '';\r\n return;\r\n }\r\n const files = cssList.split(',').map(f => f.trim());\r\n const nonceAttr = this.nonce ? ` nonce=\"${this.nonce}\"` : '';\r\n this._styleSheetFile = files\r\n .map(url => `<link${nonceAttr} rel=\"stylesheet\" type=\"text/css\" href=\"${url}\">`)\r\n .join('');\r\n }\r\n\r\n //#endregion\r\n\r\n //#region Private methods used by PrintBase\r\n\r\n private syncFormValues(source: HTMLElement, clone: HTMLElement): void {\r\n // Select all form elements\r\n const selector = 'input, select, textarea';\r\n const sourceEls = source.querySelectorAll(selector);\r\n const cloneEls = clone.querySelectorAll(selector);\r\n\r\n for (let i = 0; i < sourceEls.length; i++) {\r\n const srcNode = sourceEls[i] as HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;\r\n const cloneNode = cloneEls[i] as typeof srcNode;\r\n\r\n if (srcNode instanceof HTMLInputElement) {\r\n if (srcNode.type === 'checkbox' || srcNode.type === 'radio') {\r\n if (srcNode.checked) cloneNode.setAttribute('checked', '');\r\n else cloneNode.removeAttribute('checked'); // Remove if unchecked\r\n } else if (srcNode.type === 'file') {\r\n // File inputs can't be set programmatically for security\r\n continue;\r\n } else {\r\n cloneNode.setAttribute('value', srcNode.value);\r\n }\r\n } else if (srcNode instanceof HTMLTextAreaElement) {\r\n cloneNode.textContent = srcNode.value; // Use textContent, not innerHTML\r\n } else if (srcNode instanceof HTMLSelectElement) {\r\n Array.from((cloneNode as HTMLSelectElement).options).forEach((opt, idx) => {\r\n if (idx === srcNode.selectedIndex) {\r\n opt.setAttribute('selected', '');\r\n } else {\r\n opt.removeAttribute('selected'); // Remove from non-selected\r\n }\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Converts a canvas element to an image and returns its HTML string.\r\n *\r\n * @param {HTMLCanvasElement} canvasElm - The canvas element to convert.\r\n * @returns {HTMLImageElement | null} - HTML Element of the image.\r\n * @private\r\n */\r\n private canvasToImageHtml(canvasElm: HTMLCanvasElement): HTMLImageElement | null {\r\n try {\r\n const dataUrl = canvasElm.toDataURL(); // may throw if canvas is tainted\r\n const img = this.document.createElement('img');\r\n img.src = dataUrl;\r\n img.style.maxWidth = '100%';\r\n\r\n // Preserve displayed size (not just bitmap size)\r\n const rect = canvasElm.getBoundingClientRect();\r\n if (rect.width) img.style.width = `${rect.width}px`;\r\n if (rect.height) img.style.height = `${rect.height}px`;\r\n\r\n return img;\r\n } catch (err) {\r\n console.warn(`Canvas conversion failed for ${canvasElm}. Likely the canvas is tainted:`, err);\r\n // If toDataURL() fails (e.g., tainted canvas), keep canvas as-is in print output\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Includes canvas contents in the print section via img tags.\r\n *\r\n * @private\r\n * @param source\r\n * @param clone\r\n */\r\n private updateCanvasToImage(source: HTMLElement, clone: HTMLElement): void {\r\n const sourceCanvases = source.querySelectorAll('canvas');\r\n const cloneCanvases = clone.querySelectorAll('canvas');\r\n\r\n for (let i = 0; i < sourceCanvases.length; i++) {\r\n const srcCanvas = sourceCanvases[i];\r\n const cloneCanvas = cloneCanvases[i];\r\n const img = this.canvasToImageHtml(srcCanvas);\r\n if (img) {\r\n cloneCanvas.replaceWith(img);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Retrieves the HTML content of a specified printing section.\r\n *\r\n * @param {string} printSectionId - Id of the printing section.\r\n * @returns {string | null} - HTML content of the printing section, or null if not found.\r\n * @private\r\n */\r\n private getHtmlContents(printSectionId: string): string | null {\r\n const sourceElm = this.document.getElementById(printSectionId);\r\n if (!sourceElm) return null;\r\n\r\n const cloneElm = sourceElm.cloneNode(true) as HTMLElement; // cloneNode(true) deep clones subtree\r\n\r\n this.syncFormValues(sourceElm, cloneElm);\r\n this.updateCanvasToImage(sourceElm, cloneElm);\r\n\r\n return cloneElm.outerHTML;\r\n }\r\n\r\n /**\r\n * Retrieves the HTML content of elements with the specified tag.\r\n *\r\n * @param {keyof HTMLElementTagNameMap} tag - HTML tag name.\r\n * @returns {string} - Concatenated outerHTML of elements with the specified tag.\r\n * @private\r\n */\r\n private getElementTag(tag: keyof HTMLElementTagNameMap): string {\r\n const html: string[] = [];\r\n const elements = this.document.getElementsByTagName(tag);\r\n for (const el of Array.from(elements)) {\r\n html.push((el as Element).outerHTML);\r\n }\r\n return html.join('\\r\\n');\r\n }\r\n\r\n //#endregion\r\n\r\n protected notifyPrintComplete() {\r\n this.printComplete.next();\r\n }\r\n\r\n /**\r\n * Prints the specified content using the provided print options.\r\n *\r\n * @public\r\n * @param printOptionInput - Options for printing.\r\n */\r\n protected print(printOptionInput?: Partial<PrintOptions>): void {\r\n const printOptions = new PrintOptions(printOptionInput);\r\n if (printOptions.printMethod === 'iframe') {\r\n this.printWithIframe(printOptions);\r\n } else {\r\n this.printWithWindow(printOptions);\r\n }\r\n }\r\n\r\n protected printWithWindow(printOptions: PrintOptions) {\r\n // If the openNewTab option is set to true, then set the popOut option to an empty string\r\n // This will cause the print dialog to open in a new tab.\r\n const popOut = printOptions.printMethod === 'tab' ? '' : 'top=0,left=0,height=auto,width=auto';\r\n\r\n const popupWin = window.open('', '_blank', popOut);\r\n\r\n if (!popupWin) {\r\n // the popup window could not be opened.\r\n console.error('Could not open print window.');\r\n return;\r\n }\r\n\r\n popupWin.document.open();\r\n // Create the HTML structure\r\n this.buildPrintDocument(popupWin.document, printOptions);\r\n\r\n popupWin.document.close();\r\n\r\n // Listen for the window closing\r\n const checkClosedInterval = setInterval(() => {\r\n if (popupWin.closed) {\r\n clearInterval(checkClosedInterval);\r\n this.notifyPrintComplete();\r\n }\r\n }, 500);\r\n\r\n popupWin.addEventListener('load', () => {\r\n if (!printOptions.previewOnly) {\r\n setTimeout(() => {\r\n popupWin.print();\r\n if (printOptions.closeWindow) popupWin.close();\r\n }, printOptions.printDelay || 0);\r\n }\r\n });\r\n }\r\n\r\n private printWithIframe(printOptions: PrintOptions): void {\r\n if (this._iframeElement) {\r\n this._iframeElement.remove();\r\n }\r\n this._iframeElement = this.document.createElement('iframe');\r\n const iframe = this._iframeElement;\r\n iframe.id = 'print-iframe-' + new Date().getTime();\r\n iframe.style.position = 'absolute';\r\n iframe.style.left = '-9999px';\r\n iframe.style.top = '-9999px';\r\n iframe.style.width = '0px';\r\n iframe.style.height = '0px';\r\n iframe.ariaHidden = 'true';\r\n\r\n this.document.body.appendChild(iframe);\r\n\r\n const iframeDoc = iframe.contentDocument || iframe.contentWindow?.document;\r\n if (!iframeDoc) {\r\n console.error('Could not access iframe document.');\r\n this.document.body.removeChild(iframe);\r\n return;\r\n }\r\n\r\n iframeDoc.open();\r\n const success = this.buildPrintDocument(iframeDoc, printOptions);\r\n if (!success) {\r\n iframeDoc.close();\r\n this.document.body.removeChild(iframe);\r\n return;\r\n }\r\n iframeDoc.close();\r\n\r\n iframe.onload = () => {\r\n const printWindow = iframe.contentWindow;\r\n if (!printWindow) {\r\n console.error('Could not access iframe window.');\r\n this.document.body.removeChild(iframe);\r\n return;\r\n }\r\n\r\n setTimeout(() => {\r\n if (printOptions.previewOnly) {\r\n return;\r\n }\r\n printWindow.focus();\r\n printWindow.print();\r\n\r\n const mediaQueryList = printWindow.matchMedia('print');\r\n const listener = (mql: MediaQueryListEvent) => {\r\n if (!mql.matches) {\r\n this.notifyPrintComplete();\r\n mediaQueryList.removeEventListener('change', listener);\r\n }\r\n };\r\n\r\n mediaQueryList.addEventListener('change', listener);\r\n }, printOptions.printDelay || 0);\r\n };\r\n }\r\n\r\n private prepareDocumentComponents(printOptions: PrintOptions) {\r\n let styles = '';\r\n let links = '';\r\n const baseTag = this.getElementTag('base');\r\n\r\n if (printOptions.useExistingCss) {\r\n styles = this.getElementTag('style');\r\n links = this.getElementTag('link');\r\n }\r\n\r\n const printContents = this.getHtmlContents(printOptions.printSectionId);\r\n\r\n return { styles, links, baseTag, printContents };\r\n }\r\n\r\n private buildPrintDocument(doc: Document, printOptions: PrintOptions): boolean {\r\n const components = this.prepareDocumentComponents(printOptions);\r\n\r\n if (!components.printContents) {\r\n console.error(`Print section with id \"${printOptions.printSectionId}\" not found.`);\r\n return false;\r\n }\r\n\r\n const html = doc.createElement('html');\r\n const head = doc.createElement('head');\r\n const body = doc.createElement('body');\r\n\r\n // Set title\r\n const title = doc.createElement('title');\r\n title.textContent = printOptions.printTitle || '';\r\n head.appendChild(title);\r\n\r\n // Add all head content\r\n if (components.baseTag) {\r\n head.innerHTML += components.baseTag;\r\n }\r\n head.innerHTML += this.returnStyleValues();\r\n head.innerHTML += this.returnStyleSheetLinkTags();\r\n head.innerHTML += components.styles;\r\n head.innerHTML += components.links;\r\n\r\n // Set body class and content\r\n if (printOptions.bodyClass) body.className = printOptions.bodyClass;\r\n body.innerHTML += components.printContents;\r\n\r\n // Assemble document\r\n html.appendChild(head);\r\n html.appendChild(body);\r\n doc.appendChild(html);\r\n\r\n return true;\r\n }\r\n}\r\n","import { Directive, input, output } from '@angular/core';\r\nimport { PrintBase, PrintStyleInput } from './ngx-print.base';\r\nimport { PrintOptions } from './print-options';\r\nimport { take } from 'rxjs';\r\n\r\n@Directive({\r\n selector: '[ngxPrint]',\r\n standalone: true,\r\n host: {\r\n '(click)': 'print()',\r\n },\r\n})\r\nexport class NgxPrintDirective extends PrintBase {\r\n /**\r\n * Prevents the print dialog from opening on the window\r\n */\r\n readonly previewOnly = input(false);\r\n\r\n readonly printSectionId = input('');\r\n\r\n readonly printTitle = input('');\r\n\r\n readonly useExistingCss = input(false);\r\n\r\n /**\r\n * A delay in milliseconds to force the print dialog to wait before opened. Default: 0\r\n */\r\n readonly printDelay = input(0);\r\n\r\n /**\r\n * Whether to close the window after print() returns.\r\n */\r\n readonly closeWindow = input(true);\r\n\r\n /**\r\n * Class attribute to apply to the body element.\r\n */\r\n readonly bodyClass = input('');\r\n\r\n /**\r\n * Which PrintMethod (iframe/window/tab) to use.\r\n */\r\n readonly printMethod = input<PrintOptions['printMethod']>('window');\r\n\r\n readonly printStyle = input<PrintStyleInput>({});\r\n\r\n readonly styleSheetFile = input('');\r\n\r\n readonly printCompleted = output<void>();\r\n\r\n public override print(): void {\r\n // Inputs carry side effects on PrintBase's internal style state, so they're applied\r\n // synchronously here rather than via effect() (effects shouldn't propagate state).\r\n super.setPrintStyle(this.printStyle());\r\n super.setStyleSheetFile(this.styleSheetFile());\r\n\r\n super.print({\r\n printSectionId: this.printSectionId(),\r\n printTitle: this.printTitle(),\r\n useExistingCss: this.useExistingCss(),\r\n bodyClass: this.bodyClass(),\r\n printMethod: this.printMethod(),\r\n previewOnly: this.previewOnly(),\r\n closeWindow: this.closeWindow(),\r\n printDelay: this.printDelay(),\r\n });\r\n\r\n this.printComplete.pipe(take(1)).subscribe(() => {\r\n this.printCompleted.emit();\r\n });\r\n }\r\n}\r\n","import { NgModule } from '@angular/core';\r\nimport { NgxPrintDirective } from './ngx-print.directive';\r\n\r\n@NgModule({\r\n imports: [NgxPrintDirective],\r\n exports: [NgxPrintDirective],\r\n})\r\nexport class NgxPrintModule {}\r\n","import { Service } from '@angular/core';\r\nimport { PrintBase, PrintStyleInput } from './ngx-print.base';\r\nimport { PrintOptions } from './print-options';\r\n\r\n/**\r\n * Service for handling printing functionality in Angular applications.\r\n * Extends the base printing class (PrintBase).\r\n *\r\n * @export\r\n * @class NgxPrintService\r\n * @extends {PrintBase}\r\n */\r\n@Service()\r\nexport class NgxPrintService extends PrintBase {\r\n printComplete$ = this.printComplete.asObservable();\r\n\r\n /**\r\n * Initiates the printing process using the provided print options.\r\n *\r\n * @param {PrintOptions} printOptions - Options for configuring the printing process.\r\n * @memberof NgxPrintService\r\n * @returns {void}\r\n */\r\n public override print(printOptions?: Partial<PrintOptions>): void {\r\n // Call the print method in the parent class\r\n super.print(printOptions);\r\n }\r\n\r\n /**\r\n * Sets the print style for the printing process.\r\n *\r\n * @param values - Either a dictionary representing the print styles, or a raw CSS string.\r\n * @memberof NgxPrintService\r\n * @setter\r\n */\r\n set printStyle(values: PrintStyleInput) {\r\n super.setPrintStyle(values);\r\n }\r\n\r\n /**\r\n * Sets the stylesheet file for the printing process.\r\n *\r\n * @param {string} cssList - A string representing the path to the stylesheet file.\r\n * @memberof NgxPrintService\r\n * @setter\r\n */\r\n set styleSheetFile(cssList: string) {\r\n super.setStyleSheetFile(cssList);\r\n }\r\n}\r\n","/*\r\n * Public API Surface of ngx-print\r\n */\r\nexport { NgxPrintDirective } from './lib/ngx-print.directive';\r\nexport { NgxPrintModule } from './lib/ngx-print.module';\r\nexport { NgxPrintService } from './lib/ngx-print.service';\r\nexport { PrintOptions } from './lib/print-options';\r\nexport { PrintStyle, PrintStyleInput } from './lib/ngx-print.base';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}