@flowaccount/pdfmake 1.0.7-staging.0 → 1.0.7-staging.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowaccount/pdfmake",
3
- "version": "1.0.7-staging.0",
3
+ "version": "1.0.7-staging.3",
4
4
  "description": "Client/server side PDF printing in pure JavaScript",
5
5
  "main": "src/printer.js",
6
6
  "browser": "build/pdfmake.js",
@@ -538,7 +538,8 @@ LayoutBuilder.prototype.processNode = function (node) {
538
538
  startY: ctx.y,
539
539
  startPage: ctx.page,
540
540
  availableHeight: ctx.availableHeight,
541
- itemCount: currentPage ? currentPage.items.length : 0
541
+ itemCount: currentPage ? currentPage.items.length : 0,
542
+ x: ctx.x
542
543
  };
543
544
  }
544
545
 
@@ -683,6 +684,129 @@ LayoutBuilder.prototype.processNode = function (node) {
683
684
  // Intermediate pages (remark only) should not be repositioned
684
685
  var pageIdx = ctx.page;
685
686
  if (pageIdx > preRenderState.startPage) {
687
+ // Also reposition items on the START page (where summary might be)
688
+ var startPage = pages[preRenderState.startPage];
689
+ if (startPage && startPage.items && startPage.items.length > 0) {
690
+ var startPageHeight = startPage.pageSize.height;
691
+ var startPageBottom = startPageHeight - pageMargins.bottom;
692
+
693
+ // Find content bottom on start page
694
+ var startContentBottom = 0;
695
+ for (var si = 0; si < startPage.items.length; si++) {
696
+ var sItem = startPage.items[si];
697
+ var sItemBottom = 0;
698
+ if (sItem.item) {
699
+ if (typeof sItem.item.y === 'number') {
700
+ var sh = 0;
701
+ // Line items have getHeight() method
702
+ if (sItem.type === 'line' && typeof sItem.item.getHeight === 'function') {
703
+ sh = sItem.item.getHeight();
704
+ } else {
705
+ sh = sItem.item.h || sItem.item.height || 0;
706
+ }
707
+ sItemBottom = sItem.item.y + sh;
708
+ }
709
+ if (typeof sItem.item.y2 === 'number' && sItem.item.y2 > sItemBottom) {
710
+ sItemBottom = sItem.item.y2;
711
+ }
712
+ }
713
+ if (sItemBottom > startContentBottom) {
714
+ startContentBottom = sItemBottom;
715
+ }
716
+ }
717
+
718
+ // Calculate gap and move items on start page
719
+ var startGapHeight = startPageBottom - startContentBottom;
720
+ if (startGapHeight > 0) {
721
+ var startStackStartY = preRenderState.startY;
722
+ for (var si = 0; si < startPage.items.length; si++) {
723
+ var sItem = startPage.items[si];
724
+ var sItemY = null;
725
+ if (sItem.item && typeof sItem.item.y1 === 'number') {
726
+ sItemY = sItem.item.y1;
727
+ } else if (sItem.item && typeof sItem.item.y === 'number') {
728
+ sItemY = sItem.item.y;
729
+ }
730
+
731
+ // Skip items fully above footer start
732
+ if (sItemY === null || sItemY < startStackStartY) continue;
733
+
734
+ // Move item down
735
+ if (sItem.item && typeof sItem.item.y === 'number') {
736
+ sItem.item.y += startGapHeight;
737
+ }
738
+ if (sItem.item && typeof sItem.item.y1 === 'number') {
739
+ sItem.item.y1 += startGapHeight;
740
+ }
741
+ if (sItem.item && typeof sItem.item.y2 === 'number') {
742
+ sItem.item.y2 += startGapHeight;
743
+ }
744
+ // Handle polylines (points array)
745
+ if (sItem.item && sItem.item.points && Array.isArray(sItem.item.points)) {
746
+ for (var spi = 0; spi < sItem.item.points.length; spi++) {
747
+ if (typeof sItem.item.points[spi].y === 'number') {
748
+ sItem.item.points[spi].y += startGapHeight;
749
+ }
750
+ }
751
+ }
752
+ }
753
+
754
+ // MULTI-PAGE: Draw guide lines in the gap area (same as single-page)
755
+ var colSpec = node._footerGapOption && node._footerGapOption.columns ? node._footerGapOption.columns : (self._footerGapOption && self._footerGapOption.columns);
756
+ if (colSpec) {
757
+ var rawWidths = colSpec.content && colSpec.content.vLines ? colSpec.content.vLines : [];
758
+ if (rawWidths && rawWidths.length > 1) {
759
+ var style = (colSpec.style || {});
760
+ var lw = style.lineWidth != null ? style.lineWidth : 0.5;
761
+ var lc = style.color || '#000000';
762
+ var dashCfg = style.dash;
763
+ var includeOuter = colSpec.includeOuter !== false;
764
+ var startIndex = includeOuter ? 0 : 1;
765
+ var endIndex = includeOuter ? rawWidths.length : rawWidths.length - 1;
766
+ var pageX = preRenderState.x || pageMargins.left;
767
+
768
+ for (var ci = startIndex; ci < endIndex; ci++) {
769
+ var xGuide = pageX + rawWidths[ci] - 0.25;
770
+ // Extend first and last vertical lines to content bottom after moving
771
+ var isFirstOrLast = (ci === 0) || (ci === rawWidths.length - 1);
772
+ var vLineY2 = isFirstOrLast ? (startContentBottom + startGapHeight) : (startStackStartY + startGapHeight);
773
+ startPage.items.push({
774
+ type: 'vector',
775
+ item: {
776
+ type: 'line',
777
+ x1: xGuide,
778
+ y1: startStackStartY,
779
+ x2: xGuide,
780
+ y2: vLineY2,
781
+ lineWidth: lw,
782
+ lineColor: lc,
783
+ dash: dashCfg ? {
784
+ length: dashCfg.length,
785
+ space: dashCfg.space != null ? dashCfg.space : dashCfg.gap
786
+ } : undefined,
787
+ _footerGuideLine: true
788
+ }
789
+ });
790
+ }
791
+
792
+ // Remove existing horizontal line at startStackStartY (drawn by tableProcessor)
793
+ // It's at wrong position now - we'll draw new one at bottom of gap
794
+ for (var ri = startPage.items.length - 1; ri >= 0; ri--) {
795
+ var rItem = startPage.items[ri];
796
+ if (rItem.type === 'vector' && rItem.item && rItem.item.type === 'line') {
797
+ // Check if it's a horizontal line at startStackStartY
798
+ if (Math.abs(rItem.item.y1 - startStackStartY) < 1 &&
799
+ Math.abs(rItem.item.y2 - startStackStartY) < 1) {
800
+ startPage.items.splice(ri, 1);
801
+ break;
802
+ }
803
+ }
804
+ }
805
+ }
806
+ }
807
+ }
808
+ }
809
+
686
810
  var page = pages[pageIdx];
687
811
  if (page && page.items && page.items.length > 0) {
688
812
  var pageHeight = page.pageSize.height;
@@ -44,10 +44,12 @@ TableProcessor.prototype.beginTable = function (writer) {
44
44
  var headerRows = tableNode.table.headerRows;
45
45
 
46
46
  if (isPositiveInteger(headerRows)) {
47
- this.headerRows = headerRows;
48
-
49
- if (this.headerRows > tableNode.table.body.length) {
50
- throw new Error(`Too few rows in the table. Property headerRows requires at least ${this.headerRows}, contains only ${tableNode.table.body.length}`);
47
+ // Fix: If headerRows exceeds available rows, adjust to match body length
48
+ // This prevents errors when tables have empty bodies
49
+ if (headerRows > tableNode.table.body.length) {
50
+ this.headerRows = tableNode.table.body.length;
51
+ } else {
52
+ this.headerRows = headerRows;
51
53
  }
52
54
 
53
55
  this.rowsWithoutPageBreak = this.headerRows;
@@ -558,11 +560,13 @@ TableProcessor.prototype.endRow = function (rowIndex, writer, pageBreaks, nextRo
558
560
  var ctx = writer.context();
559
561
  var currentPage = ctx.getCurrentPage && ctx.getCurrentPage();
560
562
  var pageHeight = currentPage ? (currentPage.pageSize.height - ctx.pageMargins.bottom) : 0;
561
-
563
+ var footerGapOptBreak = ctx._footerGapOption;
564
+ var hLineY = (footerGapOptBreak && footerGapOptBreak.enabled) ? pageHeight - 0.25 : y2;
562
565
  if (willBreak && this.layout.hLineWhenBroken !== false) {
563
566
  // Check if we're at the true page bottom
564
567
  var isAtTruePageBottom = (pageHeight - y2) <= nearBottomThreshold;
565
- this.drawHorizontalLine(rowIndex + 1, writer, y2, true, null, isAtTruePageBottom);
568
+ // Use pageHeight for footer gap tables, y2 for normal tables
569
+ this.drawHorizontalLine(rowIndex + 1, writer, hLineY, true, null, isAtTruePageBottom);
566
570
  }
567
571
  if (rowBreakWithoutHeader && this.layout.hLineWhenBroken !== false) {
568
572
  // Check if previous segment ended at true page bottom
@@ -571,6 +575,10 @@ TableProcessor.prototype.endRow = function (rowIndex, writer, pageBreaks, nextRo
571
575
  this.drawHorizontalLine(rowIndex, writer, y1, true, null, prevWasAtPageBottom);
572
576
  }
573
577
 
578
+ // vLineY: ONLY use hLineY when BOTH willBreak AND footerGapOptBreak.enabled are true
579
+ // Otherwise use y2 (original behavior) to avoid NaN errors
580
+ var vLineY = (willBreak && footerGapOptBreak && footerGapOptBreak.enabled) ? hLineY : y2;
581
+
574
582
  for (i = 0, l = xs.length; i < l; i++) {
575
583
  var leftCellBorder = false;
576
584
  var rightCellBorder = false;
@@ -597,7 +605,7 @@ TableProcessor.prototype.endRow = function (rowIndex, writer, pageBreaks, nextRo
597
605
  }
598
606
 
599
607
  if (leftCellBorder) {
600
- this.drawVerticalLine(xs[i].x, y1 - hzLineOffset, y2 + this.bottomLineWidth, xs[i].index, writer, rowIndex, xs[i - 1] ? xs[i - 1].index : null);
608
+ this.drawVerticalLine(xs[i].x, y1 - hzLineOffset, vLineY + this.bottomLineWidth, xs[i].index, writer, rowIndex, xs[i - 1] ? xs[i - 1].index : null);
601
609
  }
602
610
 
603
611
  if (i < l - 1) {
package/src/textTools.js CHANGED
@@ -316,6 +316,10 @@ function getStyleProperty(item, styleContextStack, property, defaultValue) {
316
316
  value = styleContextStack.getProperty(property);
317
317
  }
318
318
 
319
+ if(property === 'bold' && (item.text === '' || item.text === '\u200B')) {
320
+ return false;
321
+ }
322
+
319
323
  if (value !== null && value !== undefined) {
320
324
  return value;
321
325
  } else {