Skip to content

Commit 37f0cbd

Browse files
committed
2.5.22
Better support for 'border' styles
1 parent 8555c60 commit 37f0cbd

File tree

7 files changed

+114
-23
lines changed

7 files changed

+114
-23
lines changed

browser.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/browser-2.5.21.js renamed to docs/browser-2.5.22.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ <h1>HTML to PDFMake convertor</h1>
116116
<div id="pdf_ie" style="display:none;padding:3em">The PDF file is sent to you for download. Use a modern browser (like Chrome or Firefox) to display the PDF in this page.</div>
117117
</div>
118118
</div>
119-
<script src="browser-2.5.21.js"></script>
119+
<script src="browser-2.5.22.js"></script>
120120
<script src="https://cdn.jsdelivr.net/npm/pdfmake@latest/build/pdfmake.min.js"></script>
121121
<script src="https://cdn.jsdelivr.net/npm/pdfmake@latest/build/vfs_fonts.js"></script>
122122
<script>

example.pdf

0 Bytes
Binary file not shown.

index.js

Lines changed: 91 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -849,8 +849,8 @@ function htmlToPdfMake(htmlText, options) {
849849
break;
850850
}
851851
default: {
852-
// for borders
853-
if (key === 'border' || key.indexOf('border-left') === 0 || key.indexOf('border-top') === 0 || key.indexOf('border-right') === 0 || key.indexOf('border-bottom') === 0) {
852+
// do we have borders properties?
853+
if (key.indexOf('border') === 0) {
854854
if (!ignoreProperties) borders.push({key:key, value:value});
855855
} else {
856856
// ignore some properties
@@ -894,35 +894,62 @@ function htmlToPdfMake(htmlText, options) {
894894
}
895895
}
896896
});
897-
// for borders
897+
// deal with the borders
898898
if (borders.length > 0) {
899-
// we have to merge together the borders in two properties
899+
// pdfmake supports only 2 properties:
900+
// - "border" (true/false) to indicate if the border should be visible
901+
// - "borderColor" (string) to indicate the color of the border
900902
var border = []; // array of boolean
901903
var borderColor = []; // array of colors
902904
borders.forEach(function(b) {
903-
// we have 3 properties: width style color
904-
b.value = _this.borderValueRearrange(b.value);
905-
var properties = b.value.split(' ');
906-
var width = properties[0].replace(/(\d*)(\.\d+)?([^\d]+)/g,"$1$2 ").trim();
907905
var index = -1, i;
906+
// determine if the current property is for 'border-left', or 'border-right', or 'border-top', or 'border-bottom'
908907
if (b.key.indexOf('-left') > -1) index=0;
909908
else if (b.key.indexOf('-top') > -1) index=1;
910909
else if (b.key.indexOf('-right') > -1) index=2;
911910
else if (b.key.indexOf('-bottom') > -1) index=3;
912-
// for the width
913-
if (index > -1) {
914-
border[index] = (width > 0);
915-
} else {
916-
for (i=0; i<4; i++) border[i] = (width > 0);
917-
}
918-
// for the color
919-
if (properties.length > 2) {
920-
var color = properties.slice(2).join(' ');
911+
912+
// for 'border', 'border-left', 'border-right', 'border-top', and 'border-bottom', then we should have three values: width style color
913+
// so we try to find them
914+
var splitKey = b.key.split('-'), properties, width;
915+
if (splitKey.length === 1 /* border */ || (splitKey.length === 2 && index >= 0 /* border-left|right|top|bottom */)) {
916+
b.value = _this.borderValueRearrange(b.value);
917+
properties = b.value.split(' ');
918+
width = properties[0].replace(/(\d*)(\.\d+)?([^\d]+)/g,"$1$2 ").trim();
919+
920+
// for the width
921921
if (index > -1) {
922-
borderColor[index] = _this.parseColor(color).color;
922+
border[index] = (width > 0);
923923
} else {
924-
for (i=0; i<4; i++) borderColor[i] = _this.parseColor(color).color;
924+
for (i=0; i<4; i++) border[i] = (width > 0);
925925
}
926+
// for the color
927+
if (properties.length > 2) {
928+
var color = properties.slice(2).join(' ');
929+
if (index > -1) {
930+
borderColor[index] = _this.parseColor(color).color;
931+
} else {
932+
for (i=0; i<4; i++) borderColor[i] = _this.parseColor(color).color;
933+
}
934+
}
935+
}
936+
// otherwise it means we could have a specific value for a specific property
937+
// e.g. 'border-left-color' or 'border-top-width'
938+
// only 'color' and 'width' are supported
939+
else if (index >= 0 && splitKey[2] === 'color') {
940+
borderColor[index] = _this.parseColor(b.value).color;
941+
}
942+
else if (index >= 0 && splitKey[2] === 'width') {
943+
border[index] = !/^0[a-z%]*$/.test(String(b.value));
944+
}
945+
// otherwise we could have 'border-color' or 'border-width'
946+
else if (b.key === 'border-color') {
947+
properties = _this.topRightBottomLeftToObject(b.value);
948+
borderColor = [ properties.left, properties.top, properties.right, properties.bottom ];
949+
}
950+
else if (b.key === 'border-width') {
951+
properties = _this.topRightBottomLeftToObject(b.value);
952+
border = [ !/^0[a-z%]*$/.test(properties.left), !/^0[a-z%]*$/.test(properties.top), !/^0[a-z%]*$/.test(properties.right), !/^0[a-z%]*$/.test(properties.bottom) ];
926953
}
927954
});
928955
// fill the gaps
@@ -940,6 +967,51 @@ function htmlToPdfMake(htmlText, options) {
940967
return str.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase() });
941968
}
942969

970+
// Convert the CSS properties like:
971+
// - top right bottom left
972+
// - top (left/right) bottom
973+
// - (top/bottom) (left/right)
974+
// - (top/bottom/left/right)
975+
//
976+
// to an object that gives {top, right, bottom, left}
977+
this.topRightBottomLeftToObject = function(props) {
978+
var splitProps = String(props).split(' ');
979+
switch (splitProps.length) {
980+
case 4: {
981+
return {
982+
top:splitProps[0],
983+
right:splitProps[1],
984+
bottom:splitProps[2],
985+
left:splitProps[3]
986+
}
987+
}
988+
case 3: {
989+
return {
990+
top:splitProps[0],
991+
right:splitProps[1],
992+
left:splitProps[1],
993+
bottom:splitProps[2],
994+
}
995+
}
996+
case 2: {
997+
return {
998+
top:splitProps[0],
999+
bottom:splitProps[0],
1000+
right:splitProps[1],
1001+
left:splitProps[1]
1002+
}
1003+
}
1004+
case 1: {
1005+
return {
1006+
top:splitProps[0],
1007+
right:splitProps[0],
1008+
bottom:splitProps[0],
1009+
left:splitProps[0]
1010+
}
1011+
}
1012+
}
1013+
}
1014+
9431015
// input: h in [0,360] and s,v in [0,1] - output: "rgb(0–255,0–255,0–255)""
9441016
// source: https://stackoverflow.com/a/54014428/1134119 + https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion#comment58413965_9493060
9451017
this.hsl2rgb = function(h,s,l) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "html-to-pdfmake",
3-
"version": "2.5.21",
3+
"version": "2.5.22",
44
"description": "Convert HTML code to PDFMake",
55
"main": "index.js",
66
"scripts": {

test/unit.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,5 +1249,24 @@ test("unit tests", function(t) {
12491249
t.finish();
12501250
});
12511251

1252+
t.test("borders",function(t) {
1253+
var html = `<table><tr><td style="border:1px solid red">border:1px solid red</td><td style="border-bottom:1px solid blue">border-bottom:1px solid blue</td><td style="border-top-color:green">border-top-color:green</td><td style="border-right-width:0px">border-right-width:0px</td></tr></table>`;
1254+
var ret = htmlToPdfMake(html, {
1255+
window:window
1256+
});
1257+
if (debug) console.log(JSON.stringify(ret));
1258+
t.check(Array.isArray(ret) && ret.length===1, "return is OK");
1259+
ret = ret[0];
1260+
t.check(Array.isArray(ret.table.body) && ret.table.body[0].length === 4, "table array OK");
1261+
ret = ret.table.body[0];
1262+
t.check(ret[0].text === "border:1px solid red" && JSON.stringify(ret[0].border) === '[true,true,true,true]' && JSON.stringify(ret[0].borderColor) === '["red","red","red","red"]', "border:1px solid red");
1263+
t.check(ret[1].text === "border-bottom:1px solid blue" && JSON.stringify(ret[1].border) === '[true,true,true,true]' && JSON.stringify(ret[1].borderColor) === '["#000000","#000000","#000000","blue"]', "border-bottom:1px solid blue");
1264+
t.check(ret[2].text === "border-top-color:green" && JSON.stringify(ret[2].borderColor) === '["#000000","green","#000000","#000000"]', "border-top-color:green");
1265+
t.check(ret[3].text === "border-right-width:0px" && JSON.stringify(ret[3].border) === '[true,true,false,true]', "border-right-width:0px");
1266+
1267+
t.finish();
1268+
});
1269+
1270+
12521271
t.finish();
12531272
})

0 commit comments

Comments
 (0)