@softwear/latestcollectioncore 1.0.178 → 1.0.179
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/reports.js +28 -14
- package/package.json +1 -1
- package/src/reports.ts +29 -13
- package/test/reports.spec.ts +54 -0
package/dist/reports.js
CHANGED
|
@@ -43,9 +43,21 @@ function getProperty(propertyName, object) {
|
|
|
43
43
|
}
|
|
44
44
|
return property;
|
|
45
45
|
}
|
|
46
|
-
/** Repeat once
|
|
46
|
+
/** Repeat once when the container has no data binding (`source` empty / whitespace-only). */
|
|
47
|
+
function dummyLayoutSource(source) {
|
|
48
|
+
return source === undefined || String(source).trim() === '';
|
|
49
|
+
}
|
|
50
|
+
/** Like repeatOnOverflow: redraw after a page break so nested overflowing content can proceed. */
|
|
51
|
+
function containerRedrawsAfterContinuationPage(child) {
|
|
52
|
+
if (child.type !== 'container')
|
|
53
|
+
return false;
|
|
54
|
+
const c = child;
|
|
55
|
+
if (c.repeatOnOverflow)
|
|
56
|
+
return true;
|
|
57
|
+
return dummyLayoutSource(c.source);
|
|
58
|
+
}
|
|
47
59
|
function containerLoopSource(container, printBuffer) {
|
|
48
|
-
if (
|
|
60
|
+
if (dummyLayoutSource(container.source))
|
|
49
61
|
return [printBuffer];
|
|
50
62
|
return getProperty(container.source, printBuffer);
|
|
51
63
|
}
|
|
@@ -368,6 +380,7 @@ function drawSimpleObject(x, y, doc, object, printBuffer, width, height, options
|
|
|
368
380
|
}
|
|
369
381
|
}
|
|
370
382
|
function addPage(originX, originY, doc, layout, rootPrintBuffer, paperSize, options, containerChain, context) {
|
|
383
|
+
context.pendingRootStartBumpTenths = 0;
|
|
371
384
|
if (context.mode === 'measurement') {
|
|
372
385
|
// Track page count in measurement mode
|
|
373
386
|
if (context.currentPageCount === undefined) {
|
|
@@ -392,7 +405,7 @@ function addPage(originX, originY, doc, layout, rootPrintBuffer, paperSize, opti
|
|
|
392
405
|
absoluteLowerRightHandSide.y = originY / 10;
|
|
393
406
|
containerChain.forEach((link) => {
|
|
394
407
|
link.object.children.forEach((child) => {
|
|
395
|
-
if (!child.snapToBottom && (child.type != 'container' || child
|
|
408
|
+
if (!child.snapToBottom && (child.type != 'container' || containerRedrawsAfterContinuationPage(child))) {
|
|
396
409
|
const childLowerRightHandSide = addObjectToPDF(originX, originY, doc, child, link.printBuffer, paperSize, layout, options, rootPrintBuffer, [], context);
|
|
397
410
|
absoluteLowerRightHandSide.x = Math.max(absoluteLowerRightHandSide.x, childLowerRightHandSide.x);
|
|
398
411
|
absoluteLowerRightHandSide.y = Math.max(absoluteLowerRightHandSide.y, childLowerRightHandSide.y);
|
|
@@ -441,9 +454,10 @@ function drawBottomDwellers(object, originX, originY, absoluteLowerRightHandSide
|
|
|
441
454
|
* Use originX,originY as origin to displace the object's own x,y coordinates
|
|
442
455
|
*/
|
|
443
456
|
addObjectToPDF = function (originX, originY, doc, object, printBuffer, paperSize, layout, options, rootPrintBuffer, containerChain, context) {
|
|
444
|
-
var _a;
|
|
457
|
+
var _a, _b;
|
|
458
|
+
const rootBump = containerChain.length === 0 ? (_a = context.pendingRootStartBumpTenths) !== null && _a !== void 0 ? _a : 0 : 0;
|
|
445
459
|
const x = (originX + object.x) / 10;
|
|
446
|
-
const y = (originY + object.y) / 10;
|
|
460
|
+
const y = (originY + object.y + rootBump) / 10;
|
|
447
461
|
const width = object.width / 10;
|
|
448
462
|
const height = object.height / 10;
|
|
449
463
|
// Keep track of the lower righthandside of all objects in this container
|
|
@@ -458,7 +472,7 @@ addObjectToPDF = function (originX, originY, doc, object, printBuffer, paperSize
|
|
|
458
472
|
let originX = x * 10, originY = y * 10;
|
|
459
473
|
const source = containerLoopSource(object, printBuffer);
|
|
460
474
|
if (source === undefined) {
|
|
461
|
-
(
|
|
475
|
+
(_b = options.onAlert) === null || _b === void 0 ? void 0 : _b.call(options, { header: 'containernotfound', body: object.source, type: 'warning', timeout: 10000 });
|
|
462
476
|
return absoluteLowerRightHandSide;
|
|
463
477
|
}
|
|
464
478
|
const nrContainers = source.length;
|
|
@@ -675,14 +689,14 @@ function genPDF(layout, printBuffer, options = {}) {
|
|
|
675
689
|
!object.printOnlyAtEnd &&
|
|
676
690
|
!object.printOnlyAtStart)
|
|
677
691
|
.forEach((object) => {
|
|
678
|
-
|
|
679
|
-
addObjectToPDF(0,
|
|
692
|
+
measurementContext.pendingRootStartBumpTenths = Math.max(0, measurementTopPrintedStartBottomTenths - object.y);
|
|
693
|
+
addObjectToPDF(0, 0, measurementDoc, object, printBuffer, paperSize, layout, options, printBuffer, [], measurementContext);
|
|
680
694
|
});
|
|
681
695
|
layout.objects
|
|
682
696
|
.filter((object) => object.type == 'container' && object.printOnlyAtEnd)
|
|
683
697
|
.forEach((object) => {
|
|
684
|
-
|
|
685
|
-
addObjectToPDF(0,
|
|
698
|
+
measurementContext.pendingRootStartBumpTenths = Math.max(0, measurementTopPrintedStartBottomTenths - object.y);
|
|
699
|
+
addObjectToPDF(0, 0, measurementDoc, object, printBuffer, paperSize, layout, options, printBuffer, [], measurementContext);
|
|
686
700
|
});
|
|
687
701
|
// Get total page count from measurement pass
|
|
688
702
|
const totalPageCount = measurementContext.currentPageCount || 1;
|
|
@@ -714,14 +728,14 @@ function genPDF(layout, printBuffer, options = {}) {
|
|
|
714
728
|
!object.printOnlyAtEnd &&
|
|
715
729
|
!object.printOnlyAtStart)
|
|
716
730
|
.forEach((object) => {
|
|
717
|
-
|
|
718
|
-
addObjectToPDF(0,
|
|
731
|
+
renderContext.pendingRootStartBumpTenths = Math.max(0, renderTopPrintedStartBottomTenths - object.y);
|
|
732
|
+
addObjectToPDF(0, 0, doc, object, printBuffer, paperSize, layout, options, printBuffer, [], renderContext);
|
|
719
733
|
});
|
|
720
734
|
// Draw printOnlyAtEnd containers once at the end (at their layout coordinates on current page)
|
|
721
735
|
const printOnlyAtEndContainers = layout.objects.filter((object) => object.type == 'container' && object.printOnlyAtEnd);
|
|
722
736
|
printOnlyAtEndContainers.forEach((object) => {
|
|
723
|
-
|
|
724
|
-
addObjectToPDF(0,
|
|
737
|
+
renderContext.pendingRootStartBumpTenths = Math.max(0, renderTopPrintedStartBottomTenths - object.y);
|
|
738
|
+
addObjectToPDF(0, 0, doc, object, printBuffer, paperSize, layout, options, printBuffer, [], renderContext);
|
|
725
739
|
});
|
|
726
740
|
return doc;
|
|
727
741
|
});
|
package/package.json
CHANGED
package/src/reports.ts
CHANGED
|
@@ -46,6 +46,8 @@ interface RenderContext {
|
|
|
46
46
|
imageAssets?: Map<string, PdfImageAsset>
|
|
47
47
|
/** Layout default font used when object.fontFamily is undefined */
|
|
48
48
|
defaultFontFamily?: string
|
|
49
|
+
/** Vertical pad for root draws after printOnlyAtStart; set per root container; addPage resets to 0 after each page break. */
|
|
50
|
+
pendingRootStartBumpTenths?: number
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
// We have to declare some functions that will be called by other functions but also have to call those other functions
|
|
@@ -92,10 +94,22 @@ function getProperty(propertyName: string, object: any): any {
|
|
|
92
94
|
return property
|
|
93
95
|
}
|
|
94
96
|
|
|
95
|
-
/** Repeat once
|
|
97
|
+
/** Repeat once when the container has no data binding (`source` empty / whitespace-only). */
|
|
98
|
+
function dummyLayoutSource(source?: string): boolean {
|
|
99
|
+
return source === undefined || String(source).trim() === ''
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** Like repeatOnOverflow: redraw after a page break so nested overflowing content can proceed. */
|
|
103
|
+
function containerRedrawsAfterContinuationPage(child: LayoutObject): boolean {
|
|
104
|
+
if (child.type !== 'container') return false
|
|
105
|
+
const c = child as ContainerLayoutObject
|
|
106
|
+
if (c.repeatOnOverflow) return true
|
|
107
|
+
return dummyLayoutSource(c.source)
|
|
108
|
+
}
|
|
109
|
+
|
|
96
110
|
function containerLoopSource(container: ContainerLayoutObject, printBuffer: any): any {
|
|
97
|
-
if (
|
|
98
|
-
return getProperty(container.source, printBuffer)
|
|
111
|
+
if (dummyLayoutSource(container.source)) return [printBuffer]
|
|
112
|
+
return getProperty(container.source as string, printBuffer)
|
|
99
113
|
}
|
|
100
114
|
|
|
101
115
|
/** jsPDF font style strings. fontStyle bitmask: 0=normal, 1=bold, 2=italic, 3=bold+italic */
|
|
@@ -433,6 +447,7 @@ function addPage(
|
|
|
433
447
|
containerChain: { object: ContainerLayoutObject; printBuffer: any }[],
|
|
434
448
|
context: RenderContext
|
|
435
449
|
): { originX: number; originY: number; x: number; y: number } {
|
|
450
|
+
context.pendingRootStartBumpTenths = 0
|
|
436
451
|
if (context.mode === 'measurement') {
|
|
437
452
|
// Track page count in measurement mode
|
|
438
453
|
if (context.currentPageCount === undefined) {
|
|
@@ -456,7 +471,7 @@ function addPage(
|
|
|
456
471
|
absoluteLowerRightHandSide.y = originY / 10
|
|
457
472
|
containerChain.forEach((link) => {
|
|
458
473
|
link.object.children.forEach((child) => {
|
|
459
|
-
if (!child.snapToBottom && (child.type != 'container' || child
|
|
474
|
+
if (!child.snapToBottom && (child.type != 'container' || containerRedrawsAfterContinuationPage(child))) {
|
|
460
475
|
const childLowerRightHandSide = addObjectToPDF(originX, originY, doc, child, link.printBuffer, paperSize, layout, options, rootPrintBuffer, [], context)
|
|
461
476
|
absoluteLowerRightHandSide.x = Math.max(absoluteLowerRightHandSide.x, childLowerRightHandSide.x)
|
|
462
477
|
absoluteLowerRightHandSide.y = Math.max(absoluteLowerRightHandSide.y, childLowerRightHandSide.y)
|
|
@@ -529,8 +544,9 @@ addObjectToPDF = function (
|
|
|
529
544
|
containerChain: { object: ContainerLayoutObject; printBuffer: any }[],
|
|
530
545
|
context: RenderContext
|
|
531
546
|
): { x: number; y: number } {
|
|
547
|
+
const rootBump = containerChain.length === 0 ? context.pendingRootStartBumpTenths ?? 0 : 0
|
|
532
548
|
const x = (originX + object.x) / 10
|
|
533
|
-
const y = (originY + object.y) / 10
|
|
549
|
+
const y = (originY + object.y + rootBump) / 10
|
|
534
550
|
const width = object.width / 10
|
|
535
551
|
const height = object.height / 10
|
|
536
552
|
// Keep track of the lower righthandside of all objects in this container
|
|
@@ -801,14 +817,14 @@ export async function genPDF(layout: Layout, printBuffer: any, options: GenPdfOp
|
|
|
801
817
|
!(object as ContainerLayoutObject).printOnlyAtStart
|
|
802
818
|
)
|
|
803
819
|
.forEach((object) => {
|
|
804
|
-
|
|
805
|
-
addObjectToPDF(0,
|
|
820
|
+
measurementContext.pendingRootStartBumpTenths = Math.max(0, measurementTopPrintedStartBottomTenths - object.y)
|
|
821
|
+
addObjectToPDF(0, 0, measurementDoc, object, printBuffer, paperSize, layout, options, printBuffer, [], measurementContext)
|
|
806
822
|
})
|
|
807
823
|
layout.objects
|
|
808
824
|
.filter((object) => object.type == 'container' && (object as ContainerLayoutObject).printOnlyAtEnd)
|
|
809
825
|
.forEach((object) => {
|
|
810
|
-
|
|
811
|
-
addObjectToPDF(0,
|
|
826
|
+
measurementContext.pendingRootStartBumpTenths = Math.max(0, measurementTopPrintedStartBottomTenths - object.y)
|
|
827
|
+
addObjectToPDF(0, 0, measurementDoc, object, printBuffer, paperSize, layout, options, printBuffer, [], measurementContext)
|
|
812
828
|
})
|
|
813
829
|
|
|
814
830
|
// Get total page count from measurement pass
|
|
@@ -847,8 +863,8 @@ export async function genPDF(layout: Layout, printBuffer: any, options: GenPdfOp
|
|
|
847
863
|
!(object as ContainerLayoutObject).printOnlyAtStart
|
|
848
864
|
)
|
|
849
865
|
.forEach((object) => {
|
|
850
|
-
|
|
851
|
-
addObjectToPDF(0,
|
|
866
|
+
renderContext.pendingRootStartBumpTenths = Math.max(0, renderTopPrintedStartBottomTenths - object.y)
|
|
867
|
+
addObjectToPDF(0, 0, doc, object, printBuffer, paperSize, layout, options, printBuffer, [], renderContext)
|
|
852
868
|
})
|
|
853
869
|
|
|
854
870
|
// Draw printOnlyAtEnd containers once at the end (at their layout coordinates on current page)
|
|
@@ -856,8 +872,8 @@ export async function genPDF(layout: Layout, printBuffer: any, options: GenPdfOp
|
|
|
856
872
|
(object) => object.type == 'container' && (object as ContainerLayoutObject).printOnlyAtEnd
|
|
857
873
|
)
|
|
858
874
|
printOnlyAtEndContainers.forEach((object) => {
|
|
859
|
-
|
|
860
|
-
addObjectToPDF(0,
|
|
875
|
+
renderContext.pendingRootStartBumpTenths = Math.max(0, renderTopPrintedStartBottomTenths - object.y)
|
|
876
|
+
addObjectToPDF(0, 0, doc, object, printBuffer, paperSize, layout, options, printBuffer, [], renderContext)
|
|
861
877
|
})
|
|
862
878
|
return doc
|
|
863
879
|
}
|
package/test/reports.spec.ts
CHANGED
|
@@ -209,4 +209,58 @@ describe('genPDF', () => {
|
|
|
209
209
|
expect(iB).toBeGreaterThanOrEqual(0)
|
|
210
210
|
expect(iH).toBeLessThan(iB)
|
|
211
211
|
})
|
|
212
|
+
|
|
213
|
+
it('redraws empty-source wrapper so inner vertical repeat spans multiple pages', async () => {
|
|
214
|
+
const rowField = {
|
|
215
|
+
type: 'field' as const,
|
|
216
|
+
name: 'ln',
|
|
217
|
+
x: 0,
|
|
218
|
+
y: 0,
|
|
219
|
+
width: 1600,
|
|
220
|
+
height: 80,
|
|
221
|
+
active: true,
|
|
222
|
+
source: 'line',
|
|
223
|
+
textAlign: 1 as const,
|
|
224
|
+
fontFamily: 'Helvetica',
|
|
225
|
+
fontSize: 36,
|
|
226
|
+
fontStyle: 0,
|
|
227
|
+
}
|
|
228
|
+
const ROWS = Array.from({ length: 40 }, (_, i) => ({ line: `ROW_${i}_MARK` }))
|
|
229
|
+
const layout: Layout = {
|
|
230
|
+
name: 'wrapper-overflow',
|
|
231
|
+
paperSize: { width: 210, height: 297, footerHeight: 20 },
|
|
232
|
+
objects: [
|
|
233
|
+
{
|
|
234
|
+
type: 'container',
|
|
235
|
+
name: 'wrap',
|
|
236
|
+
x: 50,
|
|
237
|
+
y: 100,
|
|
238
|
+
width: 1900,
|
|
239
|
+
height: 2800,
|
|
240
|
+
active: true,
|
|
241
|
+
source: '',
|
|
242
|
+
children: [
|
|
243
|
+
{
|
|
244
|
+
type: 'container',
|
|
245
|
+
name: 'rows',
|
|
246
|
+
x: 0,
|
|
247
|
+
y: 0,
|
|
248
|
+
width: 1800,
|
|
249
|
+
height: 120,
|
|
250
|
+
active: true,
|
|
251
|
+
source: 'ROWS',
|
|
252
|
+
repeatContainer: 'vertical' as const,
|
|
253
|
+
children: [rowField],
|
|
254
|
+
},
|
|
255
|
+
],
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const doc = await genPDF(layout, { ROWS })
|
|
261
|
+
expect(doc.getNumberOfPages()).toBeGreaterThanOrEqual(2)
|
|
262
|
+
const pdfText = Buffer.from(doc.output('arraybuffer')).toString('latin1')
|
|
263
|
+
expect(pdfText).toContain('ROW_0_MARK')
|
|
264
|
+
expect(pdfText).toContain('ROW_35_MARK')
|
|
265
|
+
})
|
|
212
266
|
})
|