Default plugin for “PDFMake” has error while display PDF bullet list.
Solution / Recommendation
To fix it go to path:
C:\Program Files\PHPRunner10.91\source\include\common\pdfmake
Open file:
html2make.js
opy paste this code and replace the current code:
window.htmlToPdfMake = function(htmlText, options) {
var wndw = (options && options.window ? options.window : window);
// set default styles
var defaultStyles = {
b: {bold:true},
strong: {bold:true},
u: {decoration:’underline’},
s: {decoration: ‘lineThrough’},
em: {italics:true},
i: {italics:true},
h1: {fontSize:24, bold:true, marginBottom:5},
h2:{lineHeight:1.0,alignment:’center’,color:’white’,fontSize:8},
h3: {fontSize:20, bold:true, marginBottom:5},
h4: {fontSize:18, bold:true, marginBottom:5},
h5: {fontSize:16, bold:true, marginBottom:5},
h6: {fontSize:14, bold:true, marginBottom:5},
a: {color:’blue’, decoration:’underline’},
strike: {decoration: ‘lineThrough’},
p: {margin:[0, 5, 0, 10],lineHeight: 1.5,fontSize:14},
ul: {marginBottom:5},
li: {marginLeft:5},
table: {marginBottom:5},
th: {bold:true, fillColor:’#EEEEEE’}
}
var inlineTags = [ ‘p’, ‘li’, ‘span’, ‘strong’, ’em’, ‘b’, ‘i’, ‘u’, ‘th’, ‘td’ ];
if (options && options.defaultStyles) {
for (var keyStyle in options.defaultStyles) {
if (defaultStyles.hasOwnProperty(keyStyle)) {
if (options.defaultStyles.hasOwnProperty(keyStyle) && !options.defaultStyles[keyStyle]) {
delete defaultStyles[keyStyle];
} else {
for (var k in options.defaultStyles[keyStyle]) {
if (!options.defaultStyles[keyStyle][k]) delete defaultStyles[keyStyle][k];
else defaultStyles[keyStyle][k] = options.defaultStyles[keyStyle][k];
}
}
}
}
}
var convertHtml = function(htmlText) {
var docDef = [];
// Create a HTML DOM tree out of html string
var parser = new wndw.DOMParser();
var parsedHtml = parser.parseFromString(‘<div style=”text-align:justify”>’ + htmlText + ‘</div>’, ‘text/html’);
// Go thru each child
[].forEach.call(parsedHtml.body.childNodes, function(child) {
var ret = parseElement(child);
if (ret) {
// to reduce the amount of code
if (Array.isArray(ret) && ret.length === 1) ret=ret[0];
//console.log(util.inspect(ret, {showHidden: false, depth: null})); // to debug
docDef.push(ret);
}
});
return docDef;
}
var parseElement = function(element, parentNode, parents) {
var nodeName = element.nodeName.toLowerCase();
var parentNodeName = (parentNode ? parentNode.nodeName.toLowerCase() : ”);
var ret, text, cssClass, dataset, key, dist, isInlineTag;
parents = parents || [];
switch (element.nodeType) {
case 3: // Text node
if (element.textContent) {
text = element.textContent.replace(/\n(\s+)?/g, “”);
if (text) {
if (/^\s+$/.test(text) && [‘table’, ‘thead’, ‘tbody’, ‘tr’, ‘div’].indexOf(parentNodeName) > -1) return ret;
ret = {‘text’: text};
if (parentNodeName) {
applyParentsStyle(ret, element);
if (parentNodeName === “a”) {
ret.link = parentNode.getAttribute(“href”);
}
} else {
ret = text;
}
}
}
return ret;
case 1: // Element node
ret = [];
parents.push(nodeName);
if (element.childNodes.length === 0 && (nodeName === “th” || nodeName === “td”)) ret.push({text: ”});
else {
[].forEach.call(element.childNodes, function(child) {
child = parseElement(child, element, parents);
if (child) {
if (Array.isArray(child) && child.length === 1) child = child[0];
ret.push(child);
}
});
parents.pop();
}
if (ret.length === 0) ret = “”;
switch (nodeName) {
case “svg”:
ret = {
svg: element.outerHTML
};
ret.style = [‘html-‘ + nodeName];
break;
case “br”:
ret = ‘\n’;
break;
case “ol”:
case “ul”:
var listType = nodeName === “ol” ? ‘ol’ : ‘ul’;
ret = {[listType]: []};
ret.style = [‘html-‘ + listType];
cssClass = element.getAttribute(“class”);
if (cssClass) {
ret.style = ret.style.concat(cssClass.split(‘ ‘));
}
setComputedStyle(ret, element.getAttribute(“style”));
if (listType === ‘ol’) {
var type = element.getAttribute(“type”);
if (type) {
switch (type) {
case ‘A’:
ret.type = ‘upper-alpha’;
break;
case ‘a’:
ret.type = ‘lower-alpha’;
break;
case ‘I’:
ret.type = ‘upper-roman’;
break;
case ‘i’:
ret.type = ‘lower-roman’;
break;
default:
ret.type = ‘lower-alpha’;
}
}
}
for (var child = element.firstChild; child; child = child.nextSibling) {
if (child.nodeName.toLowerCase() === ‘li’) {
var li = parseElement(child);
ret[listType].push(li);
}
}
break;
case “table”:
ret = {“_”: ret, table: {body: []}};
ret._.forEach(function(re) {
if (re.stack) {
var td = [], rowspan = {};
re.stack.forEach(function(r, indexRow) {
var c, cell, i, indexCell;
if (r.stack) {
if (rowspan[indexRow]) {
rowspan[indexRow].forEach(function(cell) {
r.stack.splice(cell.index, 0, {text: ”, style: [‘html-td’, ‘html-tr’], colSpan: cell.colspan});
});
}
for (c = 0, cell; c < r.stack.length;) {
cell = r.stack[c];
if (cell.colSpan > 1) {
for (i = 0; i < cell.colSpan – 1; i++) {
r.stack.splice(c + 1, 0, “”);
}
c += cell.colSpan;
} else c++;
}
indexCell = 0;
r.stack.forEach(function(cell) {
if (cell.rowSpan) {
for (var i = 0; i < cell.rowSpan; i++) {
if (!rowspan[indexRow + i]) rowspan[indexRow + i] = [];
rowspan[indexRow + i].push({index: indexCell, colspan: cell.colSpan || 1});
}
}
indexCell += cell.colSpan || 1;
});
ret.table.body.push(r.stack);
} else {
td.push(r);
if (r.colSpan > 1) {
for (i = 0; i < r.colSpan – 1; i++) {
td.push(“”);
}
}
}
});
if (td.length > 0) ret.table.body.push(td);
} else {
ret.table.body.push([re]);
}
});
delete ret._;
setComputedStyle(ret, element.getAttribute(“style”));
break;
case “img”:
ret = {image: element.getAttribute(“src”)};
ret.style = [‘html-img’];
cssClass = element.getAttribute(“class”);
if (cssClass) {
ret.style = ret.style.concat(cssClass.split(‘ ‘));
}
if (element.getAttribute(“width”)) {
ret.width = parseFloat(element.getAttribute(“width”));
}
if (element.getAttribute(“height”)) {
ret.height = parseFloat(element.getAttribute(“height”));
}
setComputedStyle(ret, element.getAttribute(“style”));
break;
}
if (ret) {
if (Array.isArray(ret)) {
if (ret.length === 1 && nodeName !== “tr”) {
ret = ret[0];
if (typeof ret === “string”) ret = {text: ret};
if (ret.text) {
applyDefaultStyle(ret, nodeName);
setComputedStyle(ret, element.getAttribute(“style”));
}
ret.style = (ret.style || []).concat([‘html-‘ + nodeName]);
if (nodeName === “td” || nodeName === “th”) ret.style.push(‘html-tr’);
} else {
isInlineTag = (inlineTags.indexOf(nodeName) > -1);
ret = (!isInlineTag || /{“(stack|table|ul|ol)”:/.test(JSON.stringify(ret))) ? {stack: ret} : {text: ret};
ret.style = [‘html-‘ + nodeName];
cssClass = element.getAttribute(“class”);
if (cssClass) {
ret.style = ret.style.concat(cssClass.split(‘ ‘));
}
setComputedStyle(ret, element.getAttribute(“style”));
}
} else if (typeof ret === “string”) {
ret = {text: ret};
applyDefaultStyle(ret, nodeName);
cssClass = element.getAttribute(“class”);
if (cssClass) {
ret.style = ret.style.concat(cssClass.split(‘ ‘));
}
setComputedStyle(ret, element.getAttribute(“style”));
} else if (typeof ret === “object” && !ret.image) {
applyDefaultStyle(ret, nodeName);
setComputedStyle(ret, element.getAttribute(“style”));
ret.style = (ret.style || []).concat([‘html-‘ + nodeName]);
cssClass = element.getAttribute(“class”);
if (cssClass) {
ret.style = ret.style.concat(cssClass.split(‘ ‘));
}
}
dataset = element.dataset;
if (dataset && ret.text) {
for (key in dataset) {
ret[key] = dataset[key];
}
}
}
return ret;
}
};
var applyDefaultStyle = function(ret, nodeName) {
if (defaultStyles.hasOwnProperty(nodeName)) {
for (var style in defaultStyles[nodeName]) {
if (!ret.hasOwnProperty(style)) ret[style] = defaultStyles[nodeName][style];
}
}
};
var computeStyle = function(css) {
var style = {}, kv, k, v;
if (css) {
css.split(‘;’).forEach(function(kv) {
kv = kv.split(‘:’);
k = kv[0] ? kv[0].trim() : “”;
v = kv[1] ? kv[1].trim() : “”;
if (k && v) {
style[k] = v;
}
});
}
return style;
};
var setComputedStyle = function(ret, css) {
if (!ret || !css) return;
var style = computeStyle(css);
var size;
for (var k in style) {
var v = style[k];
switch (k) {
case “margin”: {
v = v.split(‘ ‘);
if (v.length === 1) v = parseInt(v[0]);
else if (v.length === 2) v = [parseInt(v[1]), parseInt(v[0])];
else if (v.length === 3) v = [parseInt(v[1]), parseInt(v[0]), parseInt(v[1]), parseInt(v[2])];
else if (v.length === 4) v = [parseInt(v[3]), parseInt(v[0]), parseInt(v[1]), parseInt(v[2])];
ret.margin = v;
break;
}
case “margin-top”: {
if (!ret.margin) ret.margin = [0, 0, 0, 0];
ret.margin[1] = parseInt(v);
break;
}
case “margin-right”: {
if (!ret.margin) ret.margin = [0, 0, 0, 0];
ret.margin[2] = parseInt(v);
break;
}
case “margin-bottom”: {
if (!ret.margin) ret.margin = [0, 0, 0, 0];
ret.margin[3] = parseInt(v);
break;
}
case “margin-left”: {
if (!ret.margin) ret.margin = [0, 0, 0, 0];
ret.margin[0] = parseInt(v);
break;
}
case “text-align”: {
ret.alignment = v;
break;
}
case “font-weight”: {
ret.bold = (v === “bold” || parseInt(v) >= 700);
break;
}
case “font-style”: {
ret.italics = (v === “italic” || v === “oblique”);
break;
}
case “text-decoration”: {
if (v === “underline” || v === “line-through”) ret.decoration = v;
break;
}
case “color”: {
ret.color = parseColor(v);
break;
}
case “background-color”: {
ret.background = parseColor(v);
break;
}
case “font-family”: {
ret.font = v;
break;
}
case “font-size”: {
ret.fontSize = parseInt(v);
break;
}
case “line-height”: {
ret.lineHeight = parseFloat(v);
break;
}
case “width”: {
size = parseFloat(v);
if (v.indexOf(“%”) !== -1) {
ret.width = size / 100;
} else {
ret.width = size;
}
break;
}
case “height”: {
size = parseFloat(v);
if (v.indexOf(“%”) !== -1) {
ret.height = size / 100;
} else {
ret.height = size;
}
break;
}
}
}
};
var applyParentsStyle = function(ret, element) {
var parents = [];
var parent = element.parentNode;
while (parent) {
parents.push(parent);
parent = parent.parentNode;
}
parents.reverse();
parents.forEach(function(parent) {
if (parent.nodeType === 1) {
applyDefaultStyle(ret, parent.nodeName.toLowerCase());
setComputedStyle(ret, parent.getAttribute(“style”));
}
});
};
var parseColor = function(color) {
var h = (color[0] === “#”) ? color : “”;
if (!h) {
var d = document.createElement(“div”);
d.style.color = color;
document.body.appendChild(d);
h = wndw.getComputedStyle(d).color;
document.body.removeChild(d);
}
if (/^rgb/.test(h)) {
var m = h.match(/(\d+), (\d+), (\d+)/);
h = (m) ? “#” + (1 << 24 | m[1] << 16 | m[2] << 8 | m[3]).toString(16).slice(1) : h;
}
return h;
};
return convertHtml(htmlText);
};