@softwear/latestcollectioncore 1.0.176 → 1.0.178
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/dist/pdf.d.ts +2 -0
- package/dist/reports.js +38 -11
- package/package.json +1 -1
- package/src/pdf.ts +2 -0
- package/src/reports.ts +49 -13
- package/test/reports.spec.ts +140 -2
package/dist/pdf.d.ts
CHANGED
|
@@ -54,6 +54,8 @@ export interface ContainerLayoutObject extends BaseLayoutObject {
|
|
|
54
54
|
minHeightBeforeBreak?: number;
|
|
55
55
|
/** When true, container and children are drawn only once at the end of the report, not on every page */
|
|
56
56
|
printOnlyAtEnd?: boolean;
|
|
57
|
+
/** Only effective on top-level `layout.objects` (PDF engine ignores this flag on nested containers). */
|
|
58
|
+
printOnlyAtStart?: boolean;
|
|
57
59
|
}
|
|
58
60
|
export type LayoutObject = TextLayoutObject | FieldLayoutObject | RectangleLayoutObject | ImageLayoutObject | ContainerLayoutObject;
|
|
59
61
|
export interface Layout {
|
package/dist/reports.js
CHANGED
|
@@ -43,6 +43,12 @@ function getProperty(propertyName, object) {
|
|
|
43
43
|
}
|
|
44
44
|
return property;
|
|
45
45
|
}
|
|
46
|
+
/** Repeat once over the current buffer when the container is only a visual group (no `source` binding). */
|
|
47
|
+
function containerLoopSource(container, printBuffer) {
|
|
48
|
+
if (!container.source || container.source === '')
|
|
49
|
+
return [printBuffer];
|
|
50
|
+
return getProperty(container.source, printBuffer);
|
|
51
|
+
}
|
|
46
52
|
/** jsPDF font style strings. fontStyle bitmask: 0=normal, 1=bold, 2=italic, 3=bold+italic */
|
|
47
53
|
const FONT_STYLES = ['normal', 'bold', 'italic', 'bolditalic'];
|
|
48
54
|
/** Recursively collect used custom fonts from layout objects (text/field with fontFamily) and layout default. */
|
|
@@ -160,7 +166,7 @@ function collectImageUrlsFromLayout(layout, printBuffer) {
|
|
|
160
166
|
}
|
|
161
167
|
if (object.type !== 'container')
|
|
162
168
|
return;
|
|
163
|
-
const source =
|
|
169
|
+
const source = containerLoopSource(object, currentPrintBuffer);
|
|
164
170
|
if (!Array.isArray(source))
|
|
165
171
|
return;
|
|
166
172
|
source.forEach((containerPrintBuffer) => walk(object.children, containerPrintBuffer));
|
|
@@ -450,8 +456,7 @@ addObjectToPDF = function (originX, originY, doc, object, printBuffer, paperSize
|
|
|
450
456
|
// Recursively draw all child objects from a container object
|
|
451
457
|
if (object.type == 'container') {
|
|
452
458
|
let originX = x * 10, originY = y * 10;
|
|
453
|
-
const
|
|
454
|
-
const source = isPrintOnlyAtEnd && (!object.source || object.source === '') ? [printBuffer] : getProperty(object.source, printBuffer);
|
|
459
|
+
const source = containerLoopSource(object, printBuffer);
|
|
455
460
|
if (source === undefined) {
|
|
456
461
|
(_a = options.onAlert) === null || _a === void 0 ? void 0 : _a.call(options, { header: 'containernotfound', body: object.source, type: 'warning', timeout: 10000 });
|
|
457
462
|
return absoluteLowerRightHandSide;
|
|
@@ -657,16 +662,27 @@ function genPDF(layout, printBuffer, options = {}) {
|
|
|
657
662
|
yield embedFontsInDoc(measurementDoc, usedFonts, options);
|
|
658
663
|
}
|
|
659
664
|
drawStaticPartOfPage(measurementDoc, layout, printBuffer, paperSize, options, measurementContext);
|
|
660
|
-
// Draw containers in measurement mode (same order as render
|
|
665
|
+
// Draw containers in measurement mode (same order as render)
|
|
666
|
+
let measurementTopPrintedStartBottomTenths = 0;
|
|
667
|
+
layout.objects
|
|
668
|
+
.filter((object) => object.type == 'container' && object.printOnlyAtStart)
|
|
669
|
+
.forEach((object) => {
|
|
670
|
+
const lh = addObjectToPDF(0, 0, measurementDoc, object, printBuffer, paperSize, layout, options, printBuffer, [], measurementContext);
|
|
671
|
+
measurementTopPrintedStartBottomTenths = Math.max(measurementTopPrintedStartBottomTenths, lh.y * 10);
|
|
672
|
+
});
|
|
661
673
|
layout.objects
|
|
662
|
-
.filter((object) => object.type == 'container' &&
|
|
674
|
+
.filter((object) => object.type == 'container' &&
|
|
675
|
+
!object.printOnlyAtEnd &&
|
|
676
|
+
!object.printOnlyAtStart)
|
|
663
677
|
.forEach((object) => {
|
|
664
|
-
|
|
678
|
+
const bump = Math.max(0, measurementTopPrintedStartBottomTenths - object.y);
|
|
679
|
+
addObjectToPDF(0, bump, measurementDoc, object, printBuffer, paperSize, layout, options, printBuffer, [], measurementContext);
|
|
665
680
|
});
|
|
666
681
|
layout.objects
|
|
667
682
|
.filter((object) => object.type == 'container' && object.printOnlyAtEnd)
|
|
668
683
|
.forEach((object) => {
|
|
669
|
-
|
|
684
|
+
const bump = Math.max(0, measurementTopPrintedStartBottomTenths - object.y);
|
|
685
|
+
addObjectToPDF(0, bump, measurementDoc, object, printBuffer, paperSize, layout, options, printBuffer, [], measurementContext);
|
|
670
686
|
});
|
|
671
687
|
// Get total page count from measurement pass
|
|
672
688
|
const totalPageCount = measurementContext.currentPageCount || 1;
|
|
@@ -685,16 +701,27 @@ function genPDF(layout, printBuffer, options = {}) {
|
|
|
685
701
|
defaultFontFamily: layout.defaultFontFamily,
|
|
686
702
|
};
|
|
687
703
|
drawStaticPartOfPage(doc, layout, printBuffer, paperSize, options, renderContext);
|
|
688
|
-
|
|
704
|
+
let renderTopPrintedStartBottomTenths = 0;
|
|
705
|
+
layout.objects
|
|
706
|
+
.filter((object) => object.type == 'container' && object.printOnlyAtStart)
|
|
707
|
+
.forEach((object) => {
|
|
708
|
+
const lh = addObjectToPDF(0, 0, doc, object, printBuffer, paperSize, layout, options, printBuffer, [], renderContext);
|
|
709
|
+
renderTopPrintedStartBottomTenths = Math.max(renderTopPrintedStartBottomTenths, lh.y * 10);
|
|
710
|
+
});
|
|
711
|
+
// Draw containers in rendering mode (body containers after printOnlyAtStart)
|
|
689
712
|
layout.objects
|
|
690
|
-
.filter((object) => object.type == 'container' &&
|
|
713
|
+
.filter((object) => object.type == 'container' &&
|
|
714
|
+
!object.printOnlyAtEnd &&
|
|
715
|
+
!object.printOnlyAtStart)
|
|
691
716
|
.forEach((object) => {
|
|
692
|
-
|
|
717
|
+
const bump = Math.max(0, renderTopPrintedStartBottomTenths - object.y);
|
|
718
|
+
addObjectToPDF(0, bump, doc, object, printBuffer, paperSize, layout, options, printBuffer, [], renderContext);
|
|
693
719
|
});
|
|
694
720
|
// Draw printOnlyAtEnd containers once at the end (at their layout coordinates on current page)
|
|
695
721
|
const printOnlyAtEndContainers = layout.objects.filter((object) => object.type == 'container' && object.printOnlyAtEnd);
|
|
696
722
|
printOnlyAtEndContainers.forEach((object) => {
|
|
697
|
-
|
|
723
|
+
const bump = Math.max(0, renderTopPrintedStartBottomTenths - object.y);
|
|
724
|
+
addObjectToPDF(0, bump, doc, object, printBuffer, paperSize, layout, options, printBuffer, [], renderContext);
|
|
698
725
|
});
|
|
699
726
|
return doc;
|
|
700
727
|
});
|
package/package.json
CHANGED
package/src/pdf.ts
CHANGED
|
@@ -61,6 +61,8 @@ export interface ContainerLayoutObject extends BaseLayoutObject {
|
|
|
61
61
|
minHeightBeforeBreak?: number
|
|
62
62
|
/** When true, container and children are drawn only once at the end of the report, not on every page */
|
|
63
63
|
printOnlyAtEnd?: boolean
|
|
64
|
+
/** Only effective on top-level `layout.objects` (PDF engine ignores this flag on nested containers). */
|
|
65
|
+
printOnlyAtStart?: boolean
|
|
64
66
|
}
|
|
65
67
|
|
|
66
68
|
export type LayoutObject = TextLayoutObject | FieldLayoutObject | RectangleLayoutObject | ImageLayoutObject | ContainerLayoutObject
|
package/src/reports.ts
CHANGED
|
@@ -92,6 +92,12 @@ function getProperty(propertyName: string, object: any): any {
|
|
|
92
92
|
return property
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/** Repeat once over the current buffer when the container is only a visual group (no `source` binding). */
|
|
96
|
+
function containerLoopSource(container: ContainerLayoutObject, printBuffer: any): any {
|
|
97
|
+
if (!container.source || container.source === '') return [printBuffer]
|
|
98
|
+
return getProperty(container.source, printBuffer)
|
|
99
|
+
}
|
|
100
|
+
|
|
95
101
|
/** jsPDF font style strings. fontStyle bitmask: 0=normal, 1=bold, 2=italic, 3=bold+italic */
|
|
96
102
|
const FONT_STYLES = ['normal', 'bold', 'italic', 'bolditalic'] as const
|
|
97
103
|
|
|
@@ -222,7 +228,7 @@ function collectImageUrlsFromLayout(layout: Layout, printBuffer: any): string[]
|
|
|
222
228
|
|
|
223
229
|
if (object.type !== 'container') return
|
|
224
230
|
|
|
225
|
-
const source = (object as
|
|
231
|
+
const source = containerLoopSource(object as ContainerLayoutObject, currentPrintBuffer)
|
|
226
232
|
if (!Array.isArray(source)) return
|
|
227
233
|
source.forEach((containerPrintBuffer) => walk(object.children, containerPrintBuffer))
|
|
228
234
|
})
|
|
@@ -539,8 +545,7 @@ addObjectToPDF = function (
|
|
|
539
545
|
let originX = x * 10,
|
|
540
546
|
originY = y * 10
|
|
541
547
|
|
|
542
|
-
const
|
|
543
|
-
const source = isPrintOnlyAtEnd && (!object.source || object.source === '') ? [printBuffer] : getProperty(object.source, printBuffer)
|
|
548
|
+
const source = containerLoopSource(object as ContainerLayoutObject, printBuffer)
|
|
544
549
|
if (source === undefined) {
|
|
545
550
|
options.onAlert?.({ header: 'containernotfound', body: object.source, type: 'warning', timeout: 10000 })
|
|
546
551
|
return absoluteLowerRightHandSide
|
|
@@ -780,16 +785,30 @@ export async function genPDF(layout: Layout, printBuffer: any, options: GenPdfOp
|
|
|
780
785
|
}
|
|
781
786
|
drawStaticPartOfPage(measurementDoc, layout, printBuffer, paperSize, options, measurementContext)
|
|
782
787
|
|
|
783
|
-
// Draw containers in measurement mode (same order as render
|
|
788
|
+
// Draw containers in measurement mode (same order as render)
|
|
789
|
+
let measurementTopPrintedStartBottomTenths = 0
|
|
790
|
+
layout.objects
|
|
791
|
+
.filter((object) => object.type == 'container' && (object as ContainerLayoutObject).printOnlyAtStart)
|
|
792
|
+
.forEach((object) => {
|
|
793
|
+
const lh = addObjectToPDF(0, 0, measurementDoc, object, printBuffer, paperSize, layout, options, printBuffer, [], measurementContext)
|
|
794
|
+
measurementTopPrintedStartBottomTenths = Math.max(measurementTopPrintedStartBottomTenths, lh.y * 10)
|
|
795
|
+
})
|
|
784
796
|
layout.objects
|
|
785
|
-
.filter(
|
|
797
|
+
.filter(
|
|
798
|
+
(object) =>
|
|
799
|
+
object.type == 'container' &&
|
|
800
|
+
!(object as ContainerLayoutObject).printOnlyAtEnd &&
|
|
801
|
+
!(object as ContainerLayoutObject).printOnlyAtStart
|
|
802
|
+
)
|
|
786
803
|
.forEach((object) => {
|
|
787
|
-
|
|
804
|
+
const bump = Math.max(0, measurementTopPrintedStartBottomTenths - object.y)
|
|
805
|
+
addObjectToPDF(0, bump, measurementDoc, object, printBuffer, paperSize, layout, options, printBuffer, [], measurementContext)
|
|
788
806
|
})
|
|
789
807
|
layout.objects
|
|
790
|
-
.filter((object) => object.type == 'container' && (object as
|
|
808
|
+
.filter((object) => object.type == 'container' && (object as ContainerLayoutObject).printOnlyAtEnd)
|
|
791
809
|
.forEach((object) => {
|
|
792
|
-
|
|
810
|
+
const bump = Math.max(0, measurementTopPrintedStartBottomTenths - object.y)
|
|
811
|
+
addObjectToPDF(0, bump, measurementDoc, object, printBuffer, paperSize, layout, options, printBuffer, [], measurementContext)
|
|
793
812
|
})
|
|
794
813
|
|
|
795
814
|
// Get total page count from measurement pass
|
|
@@ -811,17 +830,34 @@ export async function genPDF(layout: Layout, printBuffer: any, options: GenPdfOp
|
|
|
811
830
|
}
|
|
812
831
|
drawStaticPartOfPage(doc, layout, printBuffer, paperSize, options, renderContext)
|
|
813
832
|
|
|
814
|
-
|
|
833
|
+
let renderTopPrintedStartBottomTenths = 0
|
|
815
834
|
layout.objects
|
|
816
|
-
.filter((object) => object.type == 'container' &&
|
|
835
|
+
.filter((object) => object.type == 'container' && (object as ContainerLayoutObject).printOnlyAtStart)
|
|
817
836
|
.forEach((object) => {
|
|
818
|
-
addObjectToPDF(0, 0, doc, object, printBuffer, paperSize, layout, options, printBuffer, [], renderContext)
|
|
837
|
+
const lh = addObjectToPDF(0, 0, doc, object, printBuffer, paperSize, layout, options, printBuffer, [], renderContext)
|
|
838
|
+
renderTopPrintedStartBottomTenths = Math.max(renderTopPrintedStartBottomTenths, lh.y * 10)
|
|
839
|
+
})
|
|
840
|
+
|
|
841
|
+
// Draw containers in rendering mode (body containers after printOnlyAtStart)
|
|
842
|
+
layout.objects
|
|
843
|
+
.filter(
|
|
844
|
+
(object) =>
|
|
845
|
+
object.type == 'container' &&
|
|
846
|
+
!(object as ContainerLayoutObject).printOnlyAtEnd &&
|
|
847
|
+
!(object as ContainerLayoutObject).printOnlyAtStart
|
|
848
|
+
)
|
|
849
|
+
.forEach((object) => {
|
|
850
|
+
const bump = Math.max(0, renderTopPrintedStartBottomTenths - object.y)
|
|
851
|
+
addObjectToPDF(0, bump, doc, object, printBuffer, paperSize, layout, options, printBuffer, [], renderContext)
|
|
819
852
|
})
|
|
820
853
|
|
|
821
854
|
// Draw printOnlyAtEnd containers once at the end (at their layout coordinates on current page)
|
|
822
|
-
const printOnlyAtEndContainers = layout.objects.filter(
|
|
855
|
+
const printOnlyAtEndContainers = layout.objects.filter(
|
|
856
|
+
(object) => object.type == 'container' && (object as ContainerLayoutObject).printOnlyAtEnd
|
|
857
|
+
)
|
|
823
858
|
printOnlyAtEndContainers.forEach((object) => {
|
|
824
|
-
|
|
859
|
+
const bump = Math.max(0, renderTopPrintedStartBottomTenths - object.y)
|
|
860
|
+
addObjectToPDF(0, bump, doc, object, printBuffer, paperSize, layout, options, printBuffer, [], renderContext)
|
|
825
861
|
})
|
|
826
862
|
return doc
|
|
827
863
|
}
|
package/test/reports.spec.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
import { genPDF } from '../src/reports'
|
|
3
3
|
import type { Layout } from '../src/pdf'
|
|
4
|
-
// import fs from 'fs'
|
|
5
4
|
|
|
5
|
+
/** Tiny valid JPEG as data URL — avoids flaky network-dependent image fetch in CI/sandbox. */
|
|
6
|
+
function offlineJpegFixture(): string {
|
|
7
|
+
const b64 =
|
|
8
|
+
'/9j/4AAQSkZJRgABAQIAASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAAKAAoDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAb/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIQAxAAAAHhAP/EABQQAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQEAAQkCf//EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAIAQMBAT8B/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAgBAgMBPwF//8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAgBAQYPAj//xAAVEAEAAAAAAAAAAAAAAAAAAAAAAP/aAAgBAQBPCQ//Z'
|
|
9
|
+
return `data:image/jpeg;base64,${b64}`
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// URL still used so collectImageUrlsFromLayout resolves the layout object
|
|
6
13
|
const imageUrl = 'https://upload.wikimedia.org/wikipedia/commons/thumb/7/79/Phillips_PM5538.jpg/500px-Phillips_PM5538.jpg'
|
|
7
14
|
|
|
8
15
|
describe('genPDF', () => {
|
|
@@ -59,7 +66,14 @@ describe('genPDF', () => {
|
|
|
59
66
|
title: 'Minimal PDF',
|
|
60
67
|
}
|
|
61
68
|
|
|
62
|
-
const doc = await genPDF(layout, printBuffer
|
|
69
|
+
const doc = await genPDF(layout, printBuffer, {
|
|
70
|
+
loadImage: async () => ({
|
|
71
|
+
dataUrl: offlineJpegFixture(),
|
|
72
|
+
format: 'JPEG',
|
|
73
|
+
width: 500,
|
|
74
|
+
height: 375,
|
|
75
|
+
}),
|
|
76
|
+
})
|
|
63
77
|
const pdf = doc.output('arraybuffer')
|
|
64
78
|
const pdfText = Buffer.from(pdf).toString('latin1')
|
|
65
79
|
|
|
@@ -71,4 +85,128 @@ describe('genPDF', () => {
|
|
|
71
85
|
expect(pdfText).toContain(printBuffer.title)
|
|
72
86
|
// fs.writeFileSync('test.pdf', Buffer.from(pdf))
|
|
73
87
|
})
|
|
88
|
+
|
|
89
|
+
it('draws printOnlyAtStart before body containers and printOnlyAtEnd after', async () => {
|
|
90
|
+
const textChild = (name: string, y: number, label: string) =>
|
|
91
|
+
({
|
|
92
|
+
type: 'text' as const,
|
|
93
|
+
name,
|
|
94
|
+
x: 20,
|
|
95
|
+
y,
|
|
96
|
+
width: 400,
|
|
97
|
+
height: 40,
|
|
98
|
+
active: true,
|
|
99
|
+
text: label,
|
|
100
|
+
textAlign: 1 as const,
|
|
101
|
+
fontFamily: 'Helvetica',
|
|
102
|
+
fontSize: 24,
|
|
103
|
+
fontStyle: 0,
|
|
104
|
+
}) as const
|
|
105
|
+
|
|
106
|
+
const layout: Layout = {
|
|
107
|
+
name: 'order-test',
|
|
108
|
+
paperSize: { width: 210, height: 297, footerHeight: 20 },
|
|
109
|
+
objects: [
|
|
110
|
+
{
|
|
111
|
+
type: 'container',
|
|
112
|
+
x: 0,
|
|
113
|
+
y: 40,
|
|
114
|
+
width: 500,
|
|
115
|
+
height: 80,
|
|
116
|
+
active: true,
|
|
117
|
+
source: '',
|
|
118
|
+
printOnlyAtStart: true,
|
|
119
|
+
children: [textChild('start', 0, 'START_ONLY')],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
type: 'container',
|
|
123
|
+
x: 0,
|
|
124
|
+
y: 120,
|
|
125
|
+
width: 500,
|
|
126
|
+
height: 80,
|
|
127
|
+
active: true,
|
|
128
|
+
source: '',
|
|
129
|
+
children: [textChild('mid', 0, 'BODY_MIDDLE')],
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
type: 'container',
|
|
133
|
+
x: 0,
|
|
134
|
+
y: 200,
|
|
135
|
+
width: 500,
|
|
136
|
+
height: 80,
|
|
137
|
+
active: true,
|
|
138
|
+
source: '',
|
|
139
|
+
printOnlyAtEnd: true,
|
|
140
|
+
children: [textChild('end', 0, 'END_ONLY')],
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
}
|
|
144
|
+
const doc = await genPDF(layout, {})
|
|
145
|
+
const pdfText = Buffer.from(doc.output('arraybuffer')).toString('latin1')
|
|
146
|
+
const iStart = pdfText.indexOf('(START_ONLY)')
|
|
147
|
+
const iMid = pdfText.indexOf('(BODY_MIDDLE)')
|
|
148
|
+
const iEnd = pdfText.indexOf('(END_ONLY)')
|
|
149
|
+
expect(iStart).toBeGreaterThanOrEqual(0)
|
|
150
|
+
expect(iMid).toBeGreaterThanOrEqual(0)
|
|
151
|
+
expect(iEnd).toBeGreaterThanOrEqual(0)
|
|
152
|
+
expect(iStart).toBeLessThan(iMid)
|
|
153
|
+
expect(iMid).toBeLessThan(iEnd)
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('stacks top-level body containers below printOnlyAtStart when they share the same layout y', async () => {
|
|
157
|
+
const text = (name: string, label: string, y = 0, fontSize = 80) =>
|
|
158
|
+
({
|
|
159
|
+
type: 'text' as const,
|
|
160
|
+
name,
|
|
161
|
+
x: 20,
|
|
162
|
+
y,
|
|
163
|
+
width: 900,
|
|
164
|
+
height: 400,
|
|
165
|
+
active: true,
|
|
166
|
+
text: label,
|
|
167
|
+
textAlign: 1 as const,
|
|
168
|
+
fontFamily: 'Helvetica',
|
|
169
|
+
fontSize,
|
|
170
|
+
fontStyle: 0,
|
|
171
|
+
}) as const
|
|
172
|
+
|
|
173
|
+
const sharedY = 400
|
|
174
|
+
const layout: Layout = {
|
|
175
|
+
name: 'same-y-stack',
|
|
176
|
+
paperSize: { width: 210, height: 297, footerHeight: 20 },
|
|
177
|
+
objects: [
|
|
178
|
+
{
|
|
179
|
+
type: 'container',
|
|
180
|
+
x: 0,
|
|
181
|
+
y: sharedY,
|
|
182
|
+
width: 1000,
|
|
183
|
+
height: 900,
|
|
184
|
+
active: true,
|
|
185
|
+
source: '',
|
|
186
|
+
printOnlyAtStart: true,
|
|
187
|
+
children: [text('h', 'PAGE1_HEADER_BLOCK')],
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
type: 'container',
|
|
191
|
+
x: 0,
|
|
192
|
+
y: sharedY,
|
|
193
|
+
width: 1000,
|
|
194
|
+
height: 500,
|
|
195
|
+
active: true,
|
|
196
|
+
source: '',
|
|
197
|
+
children: [text('b', 'BODY_AFTER_STACK', 0, 32)],
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const doc = await genPDF(layout, {})
|
|
203
|
+
const pdfText = Buffer.from(doc.output('arraybuffer')).toString('latin1')
|
|
204
|
+
expect(pdfText).toContain('(PAGE1_HEADER_BLOCK)')
|
|
205
|
+
expect(pdfText).toContain('(BODY_AFTER_STACK)')
|
|
206
|
+
const iH = pdfText.indexOf('(PAGE1_HEADER_BLOCK)')
|
|
207
|
+
const iB = pdfText.indexOf('(BODY_AFTER_STACK)')
|
|
208
|
+
expect(iH).toBeGreaterThanOrEqual(0)
|
|
209
|
+
expect(iB).toBeGreaterThanOrEqual(0)
|
|
210
|
+
expect(iH).toBeLessThan(iB)
|
|
211
|
+
})
|
|
74
212
|
})
|