Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

html-to-pdfmake

Package Overview
Dependencies
Maintainers
1
Versions
110
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

html-to-pdfmake - npm Package Compare versions

Comparing version 1.3.6 to 2.0.0

2

docs/browser.js

@@ -1,1 +0,1 @@

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.htmlToPdfmake=f()}})(function(){var define,module,exports;return function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r}()({1:[function(require,module,exports){module.exports=function(htmlText,options){var wndw=options&&options.window?options.window:window;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:{fontSize:22,bold:true,marginBottom:5},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]},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"];function changeDefaultStyles(){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]}}}}}if(options&&options.defaultStyles){changeDefaultStyles()}var convertHtml=function(htmlText){var docDef=[];var parser=new wndw.DOMParser;var parsedHtml=parser.parseFromString(htmlText,"text/html");[].forEach.call(parsedHtml.body.childNodes,function(child){var ret=parseElement(child);if(ret){if(Array.isArray(ret)&&ret.length===1)ret=ret[0];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,hasStackTags;parents=parents||[];switch(element.nodeType){case 3:{if(element.textContent){text=element.textContent.replace(/\n(\s+)?/g,"");if(text){if(/^\s+$/.test(text)&&["table","thead","tbody","tr"].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:{ret=[];parents.push(nodeName);if(element.childNodes.length===0&&(parents.indexOf("th")>-1||parents.indexOf("td")>-1)){var ancestor=element;var allEmpty=true;while(ancestor.nodeName!=="TH"&&ancestor.nodeName!=="TD"){if(ancestor.textContent!==""){allEmpty=false;break}ancestor=ancestor.parentNode}if(allEmpty)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"hr":{var styleHR={width:514,type:"line",margin:[0,12,0,12],thickness:.5,color:"#000000",left:0};if(element.dataset&&element.dataset.pdfmake){dataset=JSON.parse(element.dataset.pdfmake);for(key in dataset){styleHR[key]=dataset[key]}}ret={margin:styleHR.margin,canvas:[{type:styleHR.type,x1:styleHR.left,y1:0,x2:styleHR.width,y2:0,lineWidth:styleHR.thickness,lineColor:styleHR.color}]};break}case"ol":case"ul":{ret={_:ret};ret[nodeName]=ret._;delete ret._;ret.style=["html-"+nodeName];cssClass=element.getAttribute("class");if(cssClass){ret.style=ret.style.concat(cssClass.split(" "))}setComputedStyle(ret,element);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);var insertBreakLine=function(content,prevContent,firstStyleOnly){var breakLine=false,i;if(prevContent&&Array.isArray(content.style)){for(i=0;i<content.style.length;i++){if(firstStyleOnly&&i>0)break;if(content.style[i]==="html-p"||content.style[i]==="html-div"){breakLine=true;break}else if(content.style[i]==="html-td")break}if(breakLine){if(typeof prevContent.text==="string"){prevContent.text+="\n"}else if(Array.isArray(prevContent.text)){prevContent.text.push({text:"\n"})}}else if(!firstStyleOnly&&Array.isArray(prevContent.style)){for(i=0;i<prevContent.style.length;i++){if(prevContent.style[i]==="html-p"||prevContent.style[i]==="html-div"){breakLine=true;break}else if(prevContent.style[i]==="html-td")break}if(breakLine){if(typeof prevContent.text==="string"){prevContent.text+="\n"}else if(Array.isArray(prevContent.text)){prevContent.text.push({text:"\n"})}}}}if(Array.isArray(content.text)){for(i=0;i<content.text.length;i++){insertBreakLine(content.text[i],content.text[i-1],true)}}};ret.table.body.forEach(function(row){row.forEach(function(cell){if(Array.isArray(cell.text)){for(var i=0;i<cell.text.length;i++){insertBreakLine(cell.text[i],cell.text[i-1])}}})});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);break}case"h1":case"h2":case"h3":case"h4":case"h5":case"h6":{ret={stack:[{text:ret}]};ret.stack[0].style=["html-"+nodeName];cssClass=element.getAttribute("class");if(cssClass){ret.stack[0].style=ret.stack[0].style.concat(cssClass.split(" "))}applyDefaultStyle(ret.stack[0],nodeName);setComputedStyle(ret.stack[0],element);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)}ret.style=(ret.style||[]).concat(["html-"+nodeName]);if(nodeName==="td"||nodeName==="th")ret.style.push("html-tr")}else{isInlineTag=inlineTags.indexOf(nodeName)>-1;hasStackTags=/{"(stack|table|ol|ul|image)"/.test(JSON.stringify(ret));if(nodeName==="div"&&!hasStackTags)ret={text:ret};else if(isInlineTag&&hasStackTags)ret={stack:ret};else if(!isInlineTag)ret={stack:ret};else ret={text:ret};if(isInlineTag){applyDefaultStyle(ret,nodeName)}ret.style=["html-"+nodeName]}applyParentsStyle(ret,element);if(nodeName==="td"||nodeName==="th"){if(element.getAttribute("rowspan"))ret.rowSpan=element.getAttribute("rowspan")*1;if(element.getAttribute("colspan"))ret.colSpan=element.getAttribute("colspan")*1}cssClass=element.getAttribute("class");if(cssClass){ret.style=(ret.style||[]).concat(cssClass.split(" "))}if(ret.text){setComputedStyle(ret,element)}}else if(ret.table||ret.ol||ret.ul){ret.style=["html-"+nodeName];cssClass=element.getAttribute("class");if(cssClass){ret.style=ret.style.concat(cssClass.split(" "))}applyDefaultStyle(ret,nodeName)}if(element.dataset&&element.dataset.pdfmake){dataset=JSON.parse(element.dataset.pdfmake);dist=ret[nodeName]||ret;for(key in dataset){dist[key]=dataset[key]}}cssClass=element.getAttribute("class");if(cssClass&&typeof ret==="object"){ret.style=(ret.style||[]).concat(cssClass.split(" "))}if(typeof ret==="object"&&Array.isArray(ret.style)){ret.style=ret.style.filter(function(value,index,self){return self.indexOf(value)===index})}}return ret}}return""};var applyDefaultStyle=function(ret,nodeName){if(defaultStyles[nodeName]){for(var style in defaultStyles[nodeName]){if(defaultStyles[nodeName].hasOwnProperty(style)){ret[style]=defaultStyles[nodeName][style]}}}};var applyParentsStyle=function(ret,node){var classes=[],defaultStyles=[],cssClass,cssStyles=[];var parentNode=node.parentNode;var inlineParentNode=node.parentNode;while(inlineParentNode){var defaultStyle={};var inlineParentNodeName=inlineParentNode.nodeName.toLowerCase();if(inlineTags.indexOf(inlineParentNodeName)>-1){cssClass=inlineParentNode.getAttribute("class");classes=classes.concat(["html-"+inlineParentNodeName],cssClass||[]);applyDefaultStyle(defaultStyle,inlineParentNodeName);defaultStyles.push(defaultStyle);inlineParentNode=inlineParentNode.parentNode}else break}ret.style=(ret.style||[]).concat(classes);defaultStyles.forEach(function(defaultStyle){for(var key in defaultStyle){if(key.indexOf("margin")===-1&&ret[key]===undefined)ret[key]=defaultStyle[key]}});while(parentNode.nodeType===1){cssStyles=cssStyles.concat(computeStyle(parentNode.getAttribute("style"),parentNode));parentNode=parentNode.parentNode}cssStyles.reverse();cssStyles.forEach(function(stl){ret[stl.key]=stl.value});if(ret.style.length===0)delete ret.style};var computeStyle=function(style,element){if(!style)return[];var styleDefs=style.split(";").map(function(style){return style.toLowerCase().split(":")});var ret=[];var borders=[];var nodeName=element.nodeName.toUpperCase();styleDefs.forEach(function(styleDef){if(styleDef.length===2){var key=styleDef[0].trim();var value=styleDef[1].trim();switch(key){case"margin":{value=value.replace(/(\d+)(\.\d+)?([^\d]+)/g,"$1$2 ").trim().split(" ");if(value.length===1)value=+value[0];else if(value.length===2)value=[+value[1],+value[0]];else if(value.length===3)value=[+value[1],+value[0],+value[1],+value[2]];else if(value.length===4)value=[+value[3],+value[0],+value[1],+value[2]];ret.push({key:key,value:value});break}case"text-align":{ret.push({key:"alignment",value:value});break}case"font-weight":{if(value==="bold")ret.push({key:"bold",value:true});break}case"text-decoration":{ret.push({key:"decoration",value:toCamelCase(value)});break}case"font-style":{if(value==="italic")ret.push({key:"italics",value:true});break}case"font-family":{ret.push({key:"font",value:value.replace(/"|^'|'$/g,"")});break}case"color":{ret.push({key:"color",value:parseColor(value)});break}case"background-color":{ret.push({key:nodeName==="TD"||nodeName==="TH"?"fillColor":"background",value:parseColor(value)});break}default:{if(key==="border"||key.indexOf("border-left")===0||key.indexOf("border-top")===0||key.indexOf("border-right")===0||key.indexOf("border-bottom")===0){borders.push({key:key,value:value})}else{if(key.indexOf("-")>-1)key=toCamelCase(key);if(value){value=value.replace(/(\d+)(\.\d+)?([^\d]+)/g,"$1$2 ").trim();if(!isNaN(value))value=+value;ret.push({key:key,value:value})}}}}}});if(borders.length>0){var border=[];var borderColor=[];borders.forEach(function(b){var properties=b.value.split(" ");var width=properties[0].replace(/(\d+)(\.\d+)?([^\d]+)/g,"$1$2 ").trim();var index=-1,i;if(b.key.indexOf("-left")>-1)index=0;else if(b.key.indexOf("-top")>-1)index=1;else if(b.key.indexOf("-right")>-1)index=2;else if(b.key.indexOf("-bottom")>-1)index=3;if(index>-1){border[index]=width>0}else{for(i=0;i<4;i++)border[i]=width>0}if(properties.length>2){var color=properties.slice(2).join(" ");if(index>-1){borderColor[index]=parseColor(color)}else{for(i=0;i<4;i++)borderColor[i]=parseColor(color)}}});for(var i=0;i<4;i++){if(border.length>0&&typeof border[i]==="undefined")border[i]=true;if(borderColor.length>0&&typeof borderColor[i]==="undefined")borderColor[i]="#000000"}if(border.length>0)ret.push({key:"border",value:border});if(borderColor.length>0)ret.push({key:"borderColor",value:borderColor})}return ret};var setComputedStyle=function(ret,element){var cssStyle=element.getAttribute("style");if(cssStyle){cssStyle=computeStyle(cssStyle,element);cssStyle.forEach(function(style){ret[style.key]=style.value})}};var toCamelCase=function(str){return str.replace(/-([a-z])/g,function(g){return g[1].toUpperCase()})};var parseColor=function(color){var haxRegex=new RegExp("^#([0-9a-f]{3}|[0-9a-f]{6})$");var rgbRegex=new RegExp("^rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)$");var nameRegex=new RegExp("^[a-z]+$");if(haxRegex.test(color)){return color}else if(rgbRegex.test(color)){var decimalColors=rgbRegex.exec(color).slice(1);for(var i=0;i<3;i++){var decimalValue=+decimalColors[i];if(decimalValue>255){decimalValue=255}var hexString="0"+decimalValue.toString(16);hexString=hexString.slice(-2);decimalColors[i]=hexString}return"#"+decimalColors.join("")}else if(nameRegex.test(color)){return color}else{console.error('Could not parse color "'+color+'"');return color}};return convertHtml(htmlText)}},{}]},{},[1])(1)});
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.htmlToPdfmake=f()}})(function(){var define,module,exports;return function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r}()({1:[function(require,module,exports){module.exports=function(htmlText,options){var wndw=options&&options.window?options.window:window;var tableAutoSize=options&&typeof options.tableAutoSize==="boolean"?options.tableAutoSize:false;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:{fontSize:22,bold:true,marginBottom:5},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]},ul:{marginBottom:5,marginLeft:5},table:{marginBottom:5},th:{bold:true,fillColor:"#EEEEEE"}};function changeDefaultStyles(){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]}}}}}if(options&&options.defaultStyles){changeDefaultStyles()}var convertHtml=function(htmlText){var parser=new wndw.DOMParser;var parsedHtml=parser.parseFromString(htmlText,"text/html");var docDef=parseElement(parsedHtml.body,[]);return docDef.stack||docDef.text};var parseElement=function(element,parents){var nodeName=element.nodeName.toUpperCase();var nodeNameLowerCase=nodeName.toLowerCase();var ret={text:[]};var text,needStack=false;var dataset,i,key;if(["COLGROUP","COL"].indexOf(nodeName)>-1)return"";switch(element.nodeType){case 3:{if(element.textContent){text=element.textContent.replace(/\n(\s+)?/g,"");if(text){ret={text:text};ret=applyStyle({ret:ret,parents:parents});return ret}}return""}case 1:{ret.nodeName=nodeName;parents.push(element);if(element.childNodes&&element.childNodes.length>0){[].forEach.call(element.childNodes,function(child){var res=parseElement(child,parents);if(res){if(Array.isArray(res.text)&&res.text.length===0)res.text="";ret.text.push(res)}});needStack=searchForStack(ret);if(needStack){ret.stack=ret.text.slice(0);delete ret.text}else{ret=applyStyle({ret:ret,parents:parents})}}parents.pop();switch(nodeName){case"TABLE":{var rowIndex,cellIndex;ret.table={body:[]};rowIndex=0;(ret.stack||ret.text).forEach(function(tbody){var rows=tbody.stack||tbody.text;rows.forEach(function(row){ret.table.body[rowIndex]=[];var cells=row.stack||row.text;cellIndex=0;cells.forEach(function(cell){ret.table.body[rowIndex].push(cell);if(cell.colSpan){i=cell.colSpan;setRowSpan({rows:rows,cell:cell,rowIndex:rowIndex,cellIndex:cellIndex});while(--i>0){ret.table.body[rowIndex].push({text:""});setRowSpan({rows:rows,cell:cell,rowIndex:rowIndex,cellIndex:cellIndex});cellIndex++}}else{setRowSpan({rows:rows,cell:cell,rowIndex:rowIndex,cellIndex:cellIndex})}cellIndex++});rowIndex++})});delete ret.stack;delete ret.text;ret=applyStyle({ret:ret,parents:parents.concat([element])});if(tableAutoSize){var cellsWidths=[];var cellsHeights=[];var tableWidths=[];var tableHeights=[];ret.table.body.forEach(function(row,rowIndex){cellsWidths.push([]);cellsHeights.push([]);row.forEach(function(cell){var width=typeof cell.width!=="undefined"?cell.width:"auto";var height=typeof cell.height!=="undefined"?cell.height:"auto";if(width!=="auto"&&cell.colSpan)width/=cell.colSpan;if(height!=="auto"&&cell.rowSpan)height/=cell.colSpan;cellsWidths[rowIndex].push(width);cellsHeights[rowIndex].push(height)})});cellsWidths.forEach(function(row){row.forEach(function(cellWidth,cellIndex){var type=typeof tableWidths[cellIndex];if(type==="undefined"||cellWidth!=="auto"&&type==="number"&&cellWidth>tableWidths[cellIndex]||cellWidth!=="auto"&&tableWidths[cellIndex]==="auto"){tableWidths[cellIndex]=cellWidth}})});cellsHeights.forEach(function(row,rowIndex){row.forEach(function(cellHeight){var type=typeof tableHeights[rowIndex];if(type==="undefined"||cellHeight!=="auto"&&type==="number"&&cellHeight>tableHeights[rowIndex]||cellHeight!=="auto"&&tableHeights[rowIndex]==="auto"){tableHeights[rowIndex]=cellHeight}})});if(tableWidths.length>0)ret.table.widths=tableWidths;if(tableHeights.length>0)ret.table.heights=tableHeights}if(element.dataset&&element.dataset.pdfmake){dataset=JSON.parse(element.dataset.pdfmake);for(key in dataset){ret.table[key]=dataset[key]}}break}case"TH":case"TD":{if(element.getAttribute("rowspan"))ret.rowSpan=element.getAttribute("rowspan")*1;if(element.getAttribute("colspan"))ret.colSpan=element.getAttribute("colspan")*1;ret=applyStyle({ret:ret,parents:parents.concat([element])});break}case"SVG":{ret.svg=element.outerHTML.replace(/\n(\s+)?/g,"");delete ret.stack;delete ret.text;ret=applyStyle({ret:ret,parents:parents.concat([element])});break}case"BR":{ret.text=[{text:"\n"}];break}case"HR":{var styleHR={width:514,type:"line",margin:[0,12,0,12],thickness:.5,color:"#000000",left:0};if(element.dataset&&element.dataset.pdfmake){dataset=JSON.parse(element.dataset.pdfmake);for(key in dataset){styleHR[key]=dataset[key]}}ret.margin=styleHR.margin;ret.canvas=[{type:styleHR.type,x1:styleHR.left,y1:0,x2:styleHR.width,y2:0,lineWidth:styleHR.thickness,lineColor:styleHR.color}];delete ret.text;break}case"OL":case"UL":{ret[nodeNameLowerCase]=(ret.stack||ret.text).slice(0);delete ret.stack;delete ret.text;ret=applyStyle({ret:ret,parents:parents.concat([element])});break}case"IMG":{ret.image=element.getAttribute("src");delete ret.stack;delete ret.text;ret=applyStyle({ret:ret,parents:parents.concat([element])});break}case"A":{ret.link=element.getAttribute("href");break}}if(Array.isArray(ret.text)&&ret.text.length===1&&ret.text[0].text&&!ret.text[0].nodeName){ret.text=ret.text[0].text}if(nodeName!=="HR"&&nodeName!=="TABLE"&&element.dataset&&element.dataset.pdfmake){dataset=JSON.parse(element.dataset.pdfmake);for(key in dataset){ret[key]=dataset[key]}}return ret}}};var searchForStack=function(ret){if(Array.isArray(ret.text)){for(var i=0;i<ret.text.length;i++){if(ret.text[i].stack||["P","DIV","TABLE","SVG","UL","OL","IMG","H1","H2","H3","H4","H5","H6"].indexOf(ret.text[i].nodeName)>-1)return true;if(searchForStack(ret.text[i])===true)return true}}return false};var setRowSpan=function(params){var cells;if(params.cell.rowSpan){for(var i=1;i<=params.cell.rowSpan-1;i++){cells=params.rows[params.rowIndex+i].text||params.rows[params.rowIndex+i].stack;cells.splice(params.cellIndex,0,{text:""})}}};var applyStyle=function(params){var cssClass=[];var lastIndex=params.parents.length-1;params.parents.forEach(function(parent,parentIndex){var parentNodeName=parent.nodeName.toLowerCase();var htmlClass="html-"+parentNodeName;if(htmlClass!=="html-body"&&cssClass.indexOf(htmlClass)===-1)cssClass.unshift(htmlClass);var parentClass=(parent.getAttribute("class")||"").split(" ");parentClass.forEach(function(p){if(p)cssClass.push(p)});var style;var ignoreNonDescendentProperties=parentIndex!==lastIndex;if(defaultStyles[parentNodeName]){for(style in defaultStyles[parentNodeName]){if(defaultStyles[parentNodeName].hasOwnProperty(style)){if(!ignoreNonDescendentProperties||ignoreNonDescendentProperties&&style.indexOf("margin")===-1&&style.indexOf("border")===-1)params.ret[style]=defaultStyles[parentNodeName][style]}}}if(parentNodeName==="tr")ignoreNonDescendentProperties=false;style=parseStyle(parent,ignoreNonDescendentProperties);style.forEach(function(stl){params.ret[stl.key]=stl.value})});params.ret.style=cssClass;return params.ret};var parseStyle=function(element,ignoreProperties){var style=element.getAttribute("style");if(!style)return[];style=style.split(";");if(element.getAttribute("width")){style.unshift("width:"+element.getAttribute("width")+"px")}if(element.getAttribute("height")){style.unshift("height:"+element.getAttribute("height")+"px")}var styleDefs=style.map(function(style){return style.toLowerCase().split(":")});var ret=[];var borders=[];var nodeName=element.nodeName.toUpperCase();styleDefs.forEach(function(styleDef){if(styleDef.length===2){var key=styleDef[0].trim();var value=styleDef[1].trim();switch(key){case"margin":{if(ignoreProperties)break;value=value.split(" ");if(value.length===1)value=[value[0],value[0],value[0],value[0]];else if(value.length===2)value=[value[1],value[0]];else if(value.length===3)value=[value[1],value[0],value[1],value[2]];else if(value.length===4)value=[value[3],value[0],value[1],value[2]];value.forEach(function(val,i){value[i]=convertToUnit(val)});if(value.indexOf(false)===-1)ret.push({key:key,value:value});break}case"text-align":{ret.push({key:"alignment",value:value});break}case"font-weight":{if(value==="bold")ret.push({key:"bold",value:true});break}case"text-decoration":{ret.push({key:"decoration",value:toCamelCase(value)});break}case"font-style":{if(value==="italic")ret.push({key:"italics",value:true});break}case"font-family":{ret.push({key:"font",value:value.replace(/"|^'|'$/g,"")});break}case"color":{ret.push({key:"color",value:parseColor(value)});break}case"background-color":{ret.push({key:nodeName==="TD"||nodeName==="TH"?"fillColor":"background",value:parseColor(value)});break}default:{if(key==="border"||key.indexOf("border-left")===0||key.indexOf("border-top")===0||key.indexOf("border-right")===0||key.indexOf("border-bottom")===0){if(!ignoreProperties)borders.push({key:key,value:value})}else{if(ignoreProperties&&(key.indexOf("margin-")===0||key==="width"||key==="height"))break;if(key.indexOf("padding")===0)break;if(key.indexOf("-")>-1)key=toCamelCase(key);if(value){var parsedValue=convertToUnit(value);ret.push({key:key,value:parsedValue===false?value:parsedValue})}}}}}});if(borders.length>0){var border=[];var borderColor=[];borders.forEach(function(b){var properties=b.value.split(" ");var width=properties[0].replace(/(\d+)(\.\d+)?([^\d]+)/g,"$1$2 ").trim();var index=-1,i;if(b.key.indexOf("-left")>-1)index=0;else if(b.key.indexOf("-top")>-1)index=1;else if(b.key.indexOf("-right")>-1)index=2;else if(b.key.indexOf("-bottom")>-1)index=3;if(index>-1){border[index]=width>0}else{for(i=0;i<4;i++)border[i]=width>0}if(properties.length>2){var color=properties.slice(2).join(" ");if(index>-1){borderColor[index]=parseColor(color)}else{for(i=0;i<4;i++)borderColor[i]=parseColor(color)}}});for(var i=0;i<4;i++){if(border.length>0&&typeof border[i]==="undefined")border[i]=true;if(borderColor.length>0&&typeof borderColor[i]==="undefined")borderColor[i]="#000000"}if(border.length>0)ret.push({key:"border",value:border});if(borderColor.length>0)ret.push({key:"borderColor",value:borderColor})}return ret};var toCamelCase=function(str){return str.replace(/-([a-z])/g,function(g){return g[1].toUpperCase()})};var parseColor=function(color){var haxRegex=new RegExp("^#([0-9a-f]{3}|[0-9a-f]{6})$");var rgbRegex=new RegExp("^rgb\\((\\d+),\\s*(\\d+),\\s*(\\d+)\\)$");var nameRegex=new RegExp("^[a-z]+$");if(haxRegex.test(color)){return color}else if(rgbRegex.test(color)){var decimalColors=rgbRegex.exec(color).slice(1);for(var i=0;i<3;i++){var decimalValue=+decimalColors[i];if(decimalValue>255){decimalValue=255}var hexString="0"+decimalValue.toString(16);hexString=hexString.slice(-2);decimalColors[i]=hexString}return"#"+decimalColors.join("")}else if(nameRegex.test(color)){return color}else{console.error('Could not parse color "'+color+'"');return color}};var convertToUnit=function(val){if(!isNaN(parseFloat(val))&&isFinite(val))return val;var mtch=(val+"").trim().match(/^(\d+(\.\d+)?)(pt|px|rem)$/);if(!mtch)return false;val=mtch[1];switch(mtch[3]){case"px":{val=Math.round(val*.75292857248934);break}case"rem":{val*=12;break}}return val*1};return convertHtml(htmlText)}},{}]},{},[1])(1)});

@@ -153,8 +153,8 @@ var pdfMake = require("pdfmake/build/pdfmake");

<tr>
<td colspan="3">Table with <b>widths=[100,"*","auto"]</b> and <b>heights=40</b></th>
<td colspan="3">Table with <b>widths=[100,"*","auto"]</b> and <b>heights=40</b> using "data-pdfmake" attribute</th>
</tr>
<tr>
<td>Cell1</td>
<td>Cell2</td>
<td>Cell3</td>
<td style="text-align:center">Cell2</td>
<td style="text-align:right">Cell3</td>
</tr>

@@ -171,2 +171,14 @@ </table>

<p>Table autosized based on style "height" and "width" using "tableAutoSize:true" option:</p>
<table>
<tr style="height:100px">
<td style="width:250px">height:100px / width:250px</td>
<td>height:100px / width:'auto'</td>
</tr>
<tr>
<td style="width:100px">Here "&lt;td width="100"&gt;" will use 250px for the width because we have to use the largest col's width</td>
<td style="height:200px">height:200px / width:'auto'</td>
</tr>
</table>
<svg version="1.1" baseProfile="full" width="300" height="200" xmlns="http://www.w3.org/2000/svg">

@@ -185,4 +197,12 @@ <rect width="100%" height="100%" fill="red" />

<span class="a">text "bold" <span class="b">text "bold & italic" <span class="c">text "bold & italic & red"</span> text "bold & italic"</span> text "bold"</span>
`, {window:window});
<div style="margin-top:20px">
Below we preserve the spaces:
<p class="with-spaces"> this is just an example.</p>
</div>
`, {window:window, tableAutoSize:true});
//var html = htmlToPdfMake(``, {window:window, tableAutoSize:true});
//console.log(JSON.stringify(html))
var docDefinition = {

@@ -193,4 +213,4 @@ content: [

pageBreakBefore: function(currentNode) {
// we add a page break before elements with the classname "pdf-pagebreak-before"
return currentNode.style && currentNode.style.indexOf('pdf-pagebreak-before') > -1;
// we add a page break before TABLE with the classname "pdf-pagebreak-before"
return currentNode.table && currentNode.style && currentNode.style.indexOf('pdf-pagebreak-before') > -1;
},

@@ -201,2 +221,5 @@ styles:{

},
blue:{
color:'blue'
},
bold:{

@@ -220,2 +243,5 @@ bold:true

italics: false
},
'with-spaces':{
preserveLeadingSpaces: true
}

@@ -222,0 +248,0 @@ }

@@ -15,3 +15,4 @@ // source: https://github.com/OpenSlides/OpenSlides/blob/f4f8b8422f9b3fbab58e35ac3f8f870d35813b7d/client/src/app/core/ui-services/html-to-pdf.service.ts

* @param {Object} [defaultStyles] An object with the default styles for each elements
* @param {Object} [window] The `window` object (only used for the tests)
* @param {Boolean} [tableAutoSize=false] It permits to use the width/height defined in styles for a table's cells and rows
* @param {Object} [window] The `window` object (required for NodeJS server side use)
* @return {Object} it returns a PdfMake object

@@ -38,2 +39,3 @@ *

var wndw = (options && options.window ? options.window : window);
var tableAutoSize = (options && typeof options.tableAutoSize === "boolean" ? options.tableAutoSize : false);

@@ -57,4 +59,3 @@ // set default styles

p: {margin:[0, 5, 0, 10]},
ul: {marginBottom:5},
li: {marginLeft:5},
ul: {marginBottom:5,marginLeft:5},
table: {marginBottom:5},

@@ -64,7 +65,4 @@ th: {bold:true, fillColor:'#EEEEEE'}

var inlineTags = [ 'p', 'li', 'span', 'strong', 'em', 'b', 'i', 'u', 'th', 'td' ];
/**
* Permit to change the default styles based on the options
* @return {[type]} [description]
*/

@@ -100,4 +98,2 @@ function changeDefaultStyles () {

var convertHtml = function(htmlText) {
var docDef = [];
// Create a HTML DOM tree out of html string

@@ -107,14 +103,5 @@ var parser = new wndw.DOMParser();

// 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 docDef = parseElement(parsedHtml.body, []);
// remove first level
return docDef.stack || docDef.text;
}

@@ -130,9 +117,12 @@

*/
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, hasStackTags;
parents = parents || [];
var parseElement = function(element, parents) {
var nodeName = element.nodeName.toUpperCase();
var nodeNameLowerCase = nodeName.toLowerCase();
var ret = {text:[]};
var text, needStack=false;
var dataset, i, key;
// check the node type
// ignore some HTML tags
if (['COLGROUP','COL'].indexOf(nodeName) > -1) return '';
switch(element.nodeType) {

@@ -142,69 +132,158 @@ case 3: { // TEXT_NODE

text = element.textContent.replace(/\n(\s+)?/g, "");
if (text) {
// if 'text' is just blank and parentNodeName is a TABLE/THEAD/TBODY/TR, then ignore it
if (/^\s+$/.test(text) && ['table','thead','tbody','tr'].indexOf(parentNodeName) > -1) return ret;
ret = {'text': text};
if (parentNodeName) {
// check if we have inherent styles to apply when a text is inside several <tag>
applyParentsStyle(ret, element);
// for links
if (parentNodeName === "a") {
ret.link = parentNode.getAttribute("href");
}
} else {
ret = text;
}
ret = {'text':text};
ret = applyStyle({ret:ret, parents:parents});
return ret;
}
}
return ret;
return '';
}
case 1: { // ELEMENT_NODE
ret = [];
parents.push(nodeName);
// check children
// if it's a table cell (TH/TD) with an empty content
if (element.childNodes.length === 0 && (parents.indexOf('th') > -1 || parents.indexOf('td') > -1)) {
// if one of the parents is a TH or a TD, then we go up until them to see if all ancestors are empty too
var ancestor = element;
var allEmpty = true;
while (ancestor.nodeName !== "TH" && ancestor.nodeName !== "TD") {
if (ancestor.textContent !== '') {
allEmpty=false;
break;
}
ancestor = ancestor.parentNode;
}
// if empty, we need to add it
if (allEmpty) ret.push({text:''});
}
else {
ret.nodeName = nodeName;
parents.push(element);
if (element.childNodes && element.childNodes.length>0) {
[].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);
var res = parseElement(child, parents);
if (res) {
if (Array.isArray(res.text) && res.text.length===0) res.text='';
ret.text.push(res);
}
});
parents.pop();
//console.log(nodeName,'=>',util.inspect(ret.text, {showHidden: false, depth: null})); // to debug
// find if we need a 'stack' instead of a 'text'
needStack = searchForStack(ret);
if (needStack) {
ret.stack = ret.text.slice(0);
delete ret.text;
} else {
// apply all the inhirent classes and styles from the parents
ret = applyStyle({ret:ret, parents:parents});
}
}
parents.pop();
if (ret.length===0) ret="";
switch(nodeName) {
case "TABLE":{
var rowIndex, cellIndex;
// the format for the table is table.body[[], [], …]
ret.table = {body:[]};
rowIndex = 0;
// for each THEAD / TBODY
(ret.stack || ret.text).forEach(function(tbody) {
// for each row
var rows = (tbody.stack || tbody.text);
rows.forEach(function(row) {
ret.table.body[rowIndex] = [];
var cells = (row.stack || row.text);
// for each cell
cellIndex = 0;
cells.forEach(function(cell) {
ret.table.body[rowIndex].push(cell);
// check which kind of tag we have
switch (nodeName) {
case "svg": {
ret = {
svg: element.outerHTML
// do we have a colSpan?
// if yes, insert empty cells due to colspan
if (cell.colSpan) {
i = cell.colSpan;
// do we have a rowSpan in addition of the colSpan?
setRowSpan({rows:rows, cell:cell, rowIndex:rowIndex, cellIndex:cellIndex});
while (--i > 0) {
ret.table.body[rowIndex].push({text:''});
// keep adding empty cell due to rowspan
setRowSpan({rows:rows, cell:cell, rowIndex:rowIndex, cellIndex:cellIndex});
cellIndex++;
}
} else {
// do we have a rowSpan ?
setRowSpan({rows:rows, cell:cell, rowIndex:rowIndex, cellIndex:cellIndex});
}
cellIndex++;
});
rowIndex++;
});
});
delete ret.stack;
delete ret.text;
// apply all the inhirent classes and styles from the parents, or for the current element
ret = applyStyle({ret:ret, parents:parents.concat([element])});
// if option tableAutoSize, then we try to apply the correct width/height on the table
if (tableAutoSize) {
var cellsWidths = [];
var cellsHeights = [];
var tableWidths = [];
var tableHeights = [];
ret.table.body.forEach(function(row, rowIndex) {
cellsWidths.push([]);
cellsHeights.push([]);
row.forEach(function(cell) {
// we want to remember the different sizes
var width = typeof cell.width !== 'undefined' ? cell.width : 'auto';
var height = typeof cell.height !== 'undefined' ? cell.height : 'auto';
// check if we have colspan or rowspan
if (width !== 'auto' && cell.colSpan) width /= cell.colSpan;
if (height !== 'auto' && cell.rowSpan) height /= cell.colSpan;
cellsWidths[rowIndex].push(width);
cellsHeights[rowIndex].push(height);
});
});
// determine the max width for each cell
cellsWidths.forEach(function(row) {
row.forEach(function(cellWidth, cellIndex) {
var type = typeof tableWidths[cellIndex];
if (type === "undefined" || (cellWidth !== 'auto' && type === "number" && cellWidth > tableWidths[cellIndex]) || (cellWidth !== 'auto' && tableWidths[cellIndex] === 'auto')) {
tableWidths[cellIndex] = cellWidth;
}
});
});
// determine the max height for each row
cellsHeights.forEach(function(row, rowIndex) {
row.forEach(function(cellHeight) {
var type = typeof tableHeights[rowIndex];
if (type === "undefined" || (cellHeight !== 'auto' && type === "number" && cellHeight > tableHeights[rowIndex]) || (cellHeight !== 'auto' && tableHeights[rowIndex] === 'auto')) {
tableHeights[rowIndex] = cellHeight;
}
});
});
if (tableWidths.length > 0) ret.table.widths = tableWidths;
if (tableHeights.length > 0) ret.table.heights = tableHeights;
}
ret.style = ['html-'+nodeName];
// check if we have some data-pdfmake to apply
if (element.dataset && element.dataset.pdfmake) {
dataset = JSON.parse(element.dataset.pdfmake);
for (key in dataset) {
ret.table[key] = dataset[key];
}
}
break;
}
case "br": {
case "TH":
case "TD":{
if (element.getAttribute("rowspan")) ret.rowSpan = element.getAttribute("rowspan")*1;
if (element.getAttribute("colspan")) ret.colSpan = element.getAttribute("colspan")*1;
// apply all the inhirent classes and styles from the parents, or for the current element
ret = applyStyle({ret:ret, parents:parents.concat([element])});
break;
}
case "SVG": {
ret.svg = element.outerHTML.replace(/\n(\s+)?/g, "");
delete ret.stack;
delete ret.text;
// apply all the inhirent classes and styles from the parents, or for the current element
ret = applyStyle({ret:ret, parents:parents.concat([element])});
break;
}
case "BR": {
// for BR we return '\n'
ret = '\n';
ret.text = [{text:'\n'}];
break;
}
case "hr": {
case "HR": {
// default style for the HR

@@ -219,2 +298,3 @@ var styleHR = {

};
// we can override the default HR style with "data-pdfmake"
if (element.dataset && element.dataset.pdfmake) {

@@ -227,275 +307,50 @@ dataset = JSON.parse(element.dataset.pdfmake);

ret = {
margin: styleHR.margin,
canvas: [
{
type: styleHR.type,
x1: styleHR.left,
y1: 0,
x2: styleHR.width,
y2: 0,
lineWidth: styleHR.thickness,
lineColor: styleHR.color
}
]
};
ret.margin = styleHR.margin;
ret.canvas = [
{
type: styleHR.type,
x1: styleHR.left,
y1: 0,
x2: styleHR.width,
y2: 0,
lineWidth: styleHR.thickness,
lineColor: styleHR.color
}
];
delete ret.text;
break;
}
case "ol":
case "ul": {
ret = {"_":ret};
ret[nodeName] = ret._;
delete ret._;
// add a custom class to let the user customize the element
ret.style = ['html-'+nodeName];
// is there any class to this element?
cssClass = element.getAttribute("class");
if (cssClass) {
ret.style = ret.style.concat(cssClass.split(' '));
}
// check if the element has a "style" attribute
setComputedStyle(ret, element);
case "OL":
case "UL": {
ret[nodeNameLowerCase] = (ret.stack || ret.text).slice(0);
delete ret.stack;
delete ret.text;
// apply all the inhirent classes and styles from the parents, or for the current element
ret = applyStyle({ret:ret, parents:parents.concat([element])});
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) {
// do we have a rowspan to apply from previous rows?
if (rowspan[indexRow]) {
// insert empty cell due to rowspan
rowspan[indexRow].forEach(function(cell) {
r.stack.splice(cell.index, 0, {text:'', style: ['html-td', 'html-tr'], colSpan:cell.colspan});
});
}
// insert empty cells due to 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++;
}
// check rowspan for the current row in order to then apply it to the next ones
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] = [];
// we also remember the colSpan for cells with both rowspan and colspan
rowspan[indexRow+i].push({index:indexCell, colspan:cell.colSpan||1});
}
}
indexCell += cell.colSpan || 1;
});
ret.table.body.push(r.stack)
} else {
td.push(r);
// insert empty cells due to colspan
if (r.colSpan > 1) {
for (i=0; i<r.colSpan-1; i++) {
td.push("");
}
}
}
});
if (td.length>0) ret.table.body.push(td);
} else {
// only one row
ret.table.body.push([re]);
}
});
delete ret._;
// check if the element has a "style" attribute
setComputedStyle(ret, element);
// if we have P or DIV in a table cell TD or TH, then we need to add \n
var insertBreakLine = function(content, prevContent, firstStyleOnly) {
var breakLine=false, i;
// if the previous content was not P or DIV, then we need to add a \n too
if (prevContent && Array.isArray(content.style)) {
for (i=0; i<content.style.length; i++) {
if (firstStyleOnly && i>0) break;
if (content.style[i] === 'html-p' || content.style[i] === 'html-div') {
breakLine=true;
break;
}
else if (content.style[i] === 'html-td') break;
}
if (breakLine) {
if (typeof prevContent.text === 'string') {
prevContent.text += "\n";
}
else if (Array.isArray(prevContent.text)) {
prevContent.text.push({text:"\n"});
}
} else if (!firstStyleOnly && Array.isArray(prevContent.style)) {
for (i=0; i<prevContent.style.length; i++) {
if (prevContent.style[i] === 'html-p' || prevContent.style[i] === 'html-div') {
breakLine=true;
break;
}
else if (prevContent.style[i] === 'html-td') break;
}
if (breakLine) {
if (typeof prevContent.text === 'string') {
prevContent.text += "\n";
}
else if (Array.isArray(prevContent.text)) {
prevContent.text.push({text:"\n"});
}
}
}
}
if (Array.isArray(content.text)) {
for (i=0; i<content.text.length; i++) {
insertBreakLine(content.text[i], content.text[i-1], true)
}
}
}
ret.table.body.forEach(function(row) {
row.forEach(function(cell) {
if (Array.isArray(cell.text)) {
for (var i=0; i<cell.text.length; i++) {
insertBreakLine(cell.text[i], cell.text[i-1]);
}
}
})
})
case "IMG": {
ret.image = element.getAttribute("src");
delete ret.stack;
delete ret.text;
// apply all the inhirent classes and styles from the parents, or for the current element
ret = applyStyle({ret:ret, parents:parents.concat([element])});
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(' '));
}
// check if we have 'width' and 'height'
if (element.getAttribute("width")) {
ret.width = parseFloat(element.getAttribute("width"))
}
if (element.getAttribute("height")) {
ret.height = parseFloat(element.getAttribute("height"))
}
// check if the element has a "style" attribute
setComputedStyle(ret, element);
case "A": {
ret.link = element.getAttribute("href");
break;
}
case "h1":
case "h2":
case "h3":
case "h4":
case "h5":
case "h6": {
// encapsule in a stack
ret = {stack:[{text:ret}]};
ret.stack[0].style = ['html-'+nodeName];
cssClass = element.getAttribute("class");
if (cssClass) {
ret.stack[0].style = ret.stack[0].style.concat(cssClass.split(' '));
}
// apply default style
applyDefaultStyle(ret.stack[0], nodeName);
// check if the element has a "style" attribute
setComputedStyle(ret.stack[0], element);
break;
}
}
// add a custom class to let the user customize the element
if (ret) {
if (Array.isArray(ret)) {
// "tr" elements should always contain an array
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);
}
if (Array.isArray(ret.text) && ret.text.length === 1 && ret.text[0].text && !ret.text[0].nodeName) {
ret.text = ret.text[0].text;
}
ret.style = (ret.style||[]).concat(['html-'+nodeName]);
// for TD and TH we want to include the style from TR
if (nodeName === "td" || nodeName === "th") ret.style.push('html-tr');
} else {
isInlineTag = (inlineTags.indexOf(nodeName) > -1);
hasStackTags = /{"(stack|table|ol|ul|image)"/.test(JSON.stringify(ret));
// if it's a DIV and only inline tags in its section, then we want to use 'text' instead of 'stack'
if (nodeName === 'div' && !hasStackTags) ret = {text:ret};
// if we have an inline tag with stack tags in its section, then we want to use 'stack'
else if (isInlineTag && hasStackTags) ret = {stack:ret};
// if it's not an inline tag, then we use 'stack'
else if (!isInlineTag) ret = {stack:ret};
// otherwise, for inline tags, we use 'text'
else ret = {text:ret};
// we apply the default style for the inline tags
if (isInlineTag) {
applyDefaultStyle(ret, nodeName);
}
ret.style = ['html-'+nodeName];
}
// check if we have inherent styles to apply when a text is inside several <tag>
applyParentsStyle(ret, element);
// for 'td' and 'th' we check if we have "rowspan" or "colspan"
if (nodeName === "td" || nodeName === "th") {
if (element.getAttribute("rowspan")) ret.rowSpan = element.getAttribute("rowspan")*1;
if (element.getAttribute("colspan")) ret.colSpan = element.getAttribute("colspan")*1;
}
// is there any class to this element?
cssClass = element.getAttribute("class");
if (cssClass) {
ret.style = (ret.style||[]).concat(cssClass.split(' '));
}
// check if the element has a "style" attribute
if (ret.text) {
setComputedStyle(ret, element);
}
} else if (ret.table || ret.ol || ret.ul) { // for TABLE / UL / OL
ret.style = ['html-'+nodeName];
// is there any class to this element?
cssClass = element.getAttribute("class");
if (cssClass) {
ret.style = ret.style.concat(cssClass.split(' '));
}
// do we have a default style to apply?
applyDefaultStyle(ret, nodeName);
// chekck if we have some data-pdfmake to apply
if (nodeName !== 'HR' && nodeName !== 'TABLE' && element.dataset && element.dataset.pdfmake) {
dataset = JSON.parse(element.dataset.pdfmake);
for (key in dataset) {
ret[key] = dataset[key];
}
if (element.dataset && element.dataset.pdfmake) {
dataset = JSON.parse(element.dataset.pdfmake);
dist = ret[nodeName] || ret;
for (key in dataset) {
dist[key] = dataset[key];
}
}
// retrieve the class from the parent
cssClass = element.getAttribute("class");
if (cssClass && typeof ret === 'object') {
ret.style = (ret.style || [])
.concat(cssClass.split(' '))
}
// remove doublon in classes
if (typeof ret === 'object' && Array.isArray(ret.style)) {
ret.style = ret.style
.filter(function (value, index, self) {
return self.indexOf(value) === index;
});
}
}

@@ -506,48 +361,81 @@

}
return "";
}
var applyDefaultStyle = function(ret, nodeName) {
if (defaultStyles[nodeName]) {
for (var style in defaultStyles[nodeName]) {
if (defaultStyles[nodeName].hasOwnProperty(style)) {
ret[style] = defaultStyles[nodeName][style];
}
var searchForStack = function(ret) {
if (Array.isArray(ret.text)) {
for (var i=0; i<ret.text.length; i++) {
if (ret.text[i].stack || ['P','DIV','TABLE','SVG','UL','OL','IMG','H1','H2','H3','H4','H5','H6'].indexOf(ret.text[i].nodeName) > -1) return true;
if (searchForStack(ret.text[i]) === true) return true;
}
}
return false;
}
var applyParentsStyle = function(ret, node) {
// while the parents are an inline tag, we want to apply the default style and the class to the children too
var classes = [], defaultStyles = [], cssClass, cssStyles=[];
var parentNode=node.parentNode;
var inlineParentNode=node.parentNode;
while (inlineParentNode) {
var defaultStyle = {};
var inlineParentNodeName=inlineParentNode.nodeName.toLowerCase();
if (inlineTags.indexOf(inlineParentNodeName) > -1) {
cssClass = inlineParentNode.getAttribute("class");
classes = classes.concat(['html-'+inlineParentNodeName], cssClass||[]);
applyDefaultStyle(defaultStyle, inlineParentNodeName);
defaultStyles.push(defaultStyle);
/**
* Add empty cells due to rowspan
*
* @param {Object} params
* @param {Array} rows
* @param {Object} cell
* @param {Number} rowIndex Current row index
* @param {Number} cellIndex Current cell index
*/
var setRowSpan = function(params) {
var cells;
if (params.cell.rowSpan) {
for (var i=1; i <= params.cell.rowSpan-1; i++) {
cells = (params.rows[params.rowIndex+i].text || params.rows[params.rowIndex+i].stack);
cells.splice(params.cellIndex, 0, {text:''});
}
}
}
inlineParentNode=inlineParentNode.parentNode;
} else break;
}
ret.style = (ret.style||[]).concat(classes);
defaultStyles.forEach(function(defaultStyle) {
for (var key in defaultStyle) {
if (key.indexOf("margin") === -1 && ret[key] === undefined) ret[key] = defaultStyle[key];
/**
* Apply style and classes from all the parents
*
* @param {Object} params
* @param {Object} ret The object that will receive the 'style' and other properties
* @param {Array} parents Array of node elements
* @return {Object} the modified 'ret'
*/
var applyStyle = function(params) {
var cssClass = [];
var lastIndex = params.parents.length-1;
params.parents.forEach(function(parent, parentIndex) {
// classes
var parentNodeName = parent.nodeName.toLowerCase();
var htmlClass = 'html-' + parentNodeName;
if (htmlClass !== 'html-body' && cssClass.indexOf(htmlClass) === -1) cssClass.unshift(htmlClass);
var parentClass = (parent.getAttribute("class")||"").split(' ');
parentClass.forEach(function(p) {
if (p) cssClass.push(p);
});
// styles
var style;
// not all the CSS properties should be inhirent
var ignoreNonDescendentProperties = (parentIndex!==lastIndex);
// 1) the default styles
if (defaultStyles[parentNodeName]) {
for (style in defaultStyles[parentNodeName]) {
if (defaultStyles[parentNodeName].hasOwnProperty(style)) {
if (!ignoreNonDescendentProperties ||
(ignoreNonDescendentProperties &&
style.indexOf('margin') === -1 &&
style.indexOf('border') === -1
)
)
params.ret[style] = defaultStyles[parentNodeName][style];
}
}
}
// 2) element's style
// we want TD/TH to receive descendent properties from TR
if (parentNodeName === 'tr') ignoreNonDescendentProperties=false;
style = parseStyle(parent, ignoreNonDescendentProperties);
style.forEach(function(stl) {
params.ret[stl.key] = stl.value;
});
});
// all the css 'style' of the parents must be transferred to the children
while (parentNode.nodeType === 1) {
cssStyles = cssStyles.concat(computeStyle(parentNode.getAttribute('style'), parentNode));
parentNode = parentNode.parentNode;
}
cssStyles.reverse();
cssStyles.forEach(function(stl) {
ret[stl.key] = stl.value;
})
if (ret.style.length===0) delete ret.style;
params.ret.style = cssClass;
return params.ret;
}

@@ -560,7 +448,17 @@

* @param {DOMElement} element
* @param {Boolean} ignoreProperties TRUE when we have to ignore some properties, like border, padding, margin
* @returns {Array} array of {key, value}
*/
var computeStyle = function(style, element) {
var parseStyle = function(element, ignoreProperties) {
var style = element.getAttribute("style");
if (!style) return [];
var styleDefs = style.split(';').map(function(style) { return style.toLowerCase().split(':') });
style = style.split(';');
// check if we have "width" or "height"
if (element.getAttribute("width")) {
style.unshift("width:" + element.getAttribute("width") + "px");
}
if (element.getAttribute("height")) {
style.unshift("height:" + element.getAttribute("height") + "px");
}
var styleDefs = style.map(function(style) { return style.toLowerCase().split(':') });
var ret = [];

@@ -575,13 +473,20 @@ var borders = []; // special treatment for borders

case "margin": {
value = value.replace(/(\d+)(\.\d+)?([^\d]+)/g,"$1$2 ").trim().split(' ');
if (ignoreProperties) break;
// pdfMake uses a different order than CSS
if (value.length===1) value=+value[0]; // single value
else if (value.length===2) value=[+value[1], +value[0]]; // vertical | horizontal ==> horizontal | vertical
else if (value.length===3) value=[+value[1], +value[0], +value[1], +value[2]]; // top | horizontal | bottom ==> left | top | right | bottom
else if (value.length===4) value=[+value[3], +value[0], +value[1], +value[2]]; // top | right | bottom | left ==> left | top | right | bottom
ret.push({key:key, value:value});
value = value.split(' ');
if (value.length===1) value=[value[0], value[0], value[0], value[0]];
else if (value.length===2) value=[value[1], value[0]]; // vertical | horizontal ==> horizontal | vertical
else if (value.length===3) value=[value[1], value[0], value[1], value[2]]; // top | horizontal | bottom ==> left | top | right | bottom
else if (value.length===4) value=[value[3], value[0], value[1], value[2]]; // top | right | bottom | left ==> left | top | right | bottom
// we now need to convert to PT
value.forEach(function(val, i) {
value[i] = convertToUnit(val);
});
// ignore if we have a FALSE in the table
if (value.indexOf(false) === -1) ret.push({key:key, value:value});
break;
}
case "text-align": {
ret.push({key:"alignment", value:value})
ret.push({key:"alignment", value:value});
break;

@@ -617,9 +522,13 @@ }

if (key === 'border' || key.indexOf('border-left') === 0 || key.indexOf('border-top') === 0 || key.indexOf('border-right') === 0 || key.indexOf('border-bottom') === 0) {
borders.push({key:key, value:value});
if (!ignoreProperties) borders.push({key:key, value:value});
} else {
// ignore some properties
if (ignoreProperties && (key.indexOf("margin-") === 0 || key === 'width' || key === 'height')) break;
// padding is not supported by PDFMake
if (key.indexOf("padding") === 0) break;
if (key.indexOf("-") > -1) key=toCamelCase(key);
if (value) {
value = value.replace(/(\d+)(\.\d+)?([^\d]+)/g,"$1$2 ").trim();
if (!isNaN(value)) value=+value; // turn it into a number
ret.push({key:key, value:value});
// convert value to a 'pt' when possible
var parsedValue = convertToUnit(value);
ret.push({key:key, value:(parsedValue === false ? value : parsedValue)});
}

@@ -672,17 +581,2 @@ }

/**
* Go throught the CSS styles for the element and apply them
* @param {Object} ret Our pdfmake object
* @param {DOMElement} element The DOM elemnet
*/
var setComputedStyle = function(ret, element) {
var cssStyle = element.getAttribute("style");
if (cssStyle) {
cssStyle = computeStyle(cssStyle, element);
cssStyle.forEach(function(style) {
ret[style.key] = style.value;
})
}
}
var toCamelCase = function(str) {

@@ -730,3 +624,29 @@ return str.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase() });

/**
* Convert 'px'/'rem' to 'pt', and return false for the other ones. If it's only a number, it will just return it
*
* @param {String} val The value with units (e.g. 12px)
* @return {Number|Boolean} Return the pt value, or false
*/
var convertToUnit = function(val) {
// if it's just a number, then return it
if (!isNaN(parseFloat(val)) && isFinite(val)) return val;
var mtch = (val+"").trim().match(/^(\d+(\.\d+)?)(pt|px|rem)$/);
// if we don't have a number with supported units, then return false
if (!mtch) return false;
val = mtch[1];
switch(mtch[3]) {
case 'px':{
val = Math.round(val * 0.75292857248934); // 1px => 0.75292857248934pt
break;
}
case 'rem':{
val *= 12; // default font-size is 12pt
break;
}
}
return val*1;
}
return convertHtml(htmlText)
}
{
"name": "html-to-pdfmake",
"version": "1.3.6",
"version": "2.0.0",
"description": "Convert HTML code to PDFMake",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -101,2 +101,34 @@ # html-to-pdfmake

### Options
Some options can be passed to `htmlToPdfmake` function as a second argument.
#### `window`
If you use Node, then you'll have to pass the `window` object ([see below](https://github.com/Aymkdn/html-to-pdfmake#use-with-node)).
#### `defaultStyles`
You can overwrite the default stles using `defaultStyles` ([see below](https://github.com/Aymkdn/html-to-pdfmake#default-styles)).
#### `tableAutoSize`
By pass `tableAutoSize` with `true`, then the program will try to define `widths` and `heights` for the tables, based on CSS properties `width` and `height` that have been provided to `TH` or `TD`.
Example:
```javascript
var html = htmlToPdfmake(`<table>
<tr style="height:100px">
<td style="width:250px">height:100px / width:250px</td>
<td>height:100px / width:'auto'</td>
</tr>
<tr>
<td style="width:100px">Here it will use 250px for the width because we have to use the largest col's width</td>
<td style="height:200px">height:200px / width:'auto'</td>
</tr>
</table>`, {
tableAutoSize:true
});
```
### HTML tags supported

@@ -103,0 +135,0 @@

@@ -6,6 +6,7 @@ var htmlToPdfMake = require('../index.js');

var { window } = new JSDOM("");
var debug = false;
// { text: 'bold word', bold: true, style: [ 'html-b' ] }
test("b",function(t) {
var ret = htmlToPdfMake("<b>bold word</b>", window);
var ret = htmlToPdfMake("<b>bold word</b>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -24,3 +25,4 @@ ret = ret[0];

test("strong",function(t) {
var ret = htmlToPdfMake("<strong>bold word</strong>", window);
var ret = htmlToPdfMake("<strong>bold word</strong>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -38,5 +40,5 @@ ret = ret[0];

// { text: 'underline word', decoration: 'underline', style: [ 'html-u' ] }
test("u",function(t) {
var ret = htmlToPdfMake("<u>underline word</u>", window);
var ret = htmlToPdfMake("<u>underline word</u>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -55,3 +57,4 @@ ret = ret[0];

test("em",function(t) {
var ret = htmlToPdfMake("<em>italic word</em>", window);
var ret = htmlToPdfMake("<em>italic word</em>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -70,3 +73,4 @@ ret = ret[0];

test("i",function(t) {
var ret = htmlToPdfMake("<i>italic word</i>", window);
var ret = htmlToPdfMake("<i>italic word</i>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -84,10 +88,9 @@ ret = ret[0];

// [{stack:[{text:[{text:'level 1'}],style:[ 'html-h1' ],fontSize:24,bold:true,marginBottom:5}]]
test("h1",function(t) {
var ret = htmlToPdfMake("<h1>level 1</h1>", window);
t.check(Array.isArray(ret) && ret[0].stack && Array.isArray(ret[0].stack), "return is OK");
ret = ret[0].stack[0];
var ret = htmlToPdfMake("<h1>level 1</h1>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret), "return is OK");
ret = ret[0];
t.check(
Array.isArray(ret.text) &&
ret.text[0].text === "level 1" &&
ret.text === "level 1" &&
ret.fontSize === 24 &&

@@ -104,8 +107,8 @@ ret.bold === true &&

test("h2",function(t) {
var ret = htmlToPdfMake("<h2>level 2</h2>", window);
t.check(Array.isArray(ret) && ret[0].stack && Array.isArray(ret[0].stack), "return is OK");
ret = ret[0].stack[0];
var ret = htmlToPdfMake("<h2>level 2</h2>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret), "return is OK");
ret = ret[0];
t.check(
Array.isArray(ret.text) &&
ret.text[0].text === "level 2" &&
ret.text === "level 2" &&
ret.fontSize === 22 &&

@@ -122,8 +125,8 @@ ret.bold === true &&

test("h3",function(t) {
var ret = htmlToPdfMake("<h3>level 3</h3>", window);
t.check(Array.isArray(ret) && ret[0].stack && Array.isArray(ret[0].stack), "return is OK");
ret = ret[0].stack[0];
var ret = htmlToPdfMake("<h3>level 3</h3>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret), "return is OK");
ret = ret[0];
t.check(
Array.isArray(ret.text) &&
ret.text[0].text === "level 3" &&
ret.text === "level 3" &&
ret.fontSize === 20 &&

@@ -140,8 +143,8 @@ ret.bold === true &&

test("h4",function(t) {
var ret = htmlToPdfMake("<h4>level 4</h4>", window);
t.check(Array.isArray(ret) && ret[0].stack && Array.isArray(ret[0].stack), "return is OK");
ret = ret[0].stack[0];
var ret = htmlToPdfMake("<h4>level 4</h4>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret), "return is OK");
ret = ret[0];
t.check(
Array.isArray(ret.text) &&
ret.text[0].text === "level 4" &&
ret.text === "level 4" &&
ret.fontSize === 18 &&

@@ -158,8 +161,8 @@ ret.bold === true &&

test("h5",function(t) {
var ret = htmlToPdfMake("<h5>level 5</h5>", window);
t.check(Array.isArray(ret) && ret[0].stack && Array.isArray(ret[0].stack), "return is OK");
ret = ret[0].stack[0];
var ret = htmlToPdfMake("<h5>level 5</h5>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret), "return is OK");
ret = ret[0];
t.check(
Array.isArray(ret.text) &&
ret.text[0].text === "level 5" &&
ret.text === "level 5" &&
ret.fontSize === 16 &&

@@ -176,8 +179,8 @@ ret.bold === true &&

test("h6",function(t) {
var ret = htmlToPdfMake("<h6>level 6</h6>", window);
t.check(Array.isArray(ret) && ret[0].stack && Array.isArray(ret[0].stack), "return is OK");
ret = ret[0].stack[0];
var ret = htmlToPdfMake("<h6>level 6</h6>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret), "return is OK");
ret = ret[0];
t.check(
Array.isArray(ret.text) &&
ret.text[0].text === "level 6" &&
ret.text === "level 6" &&
ret.fontSize === 14 &&

@@ -193,5 +196,5 @@ ret.bold === true &&

// { text: 'link', color: 'blue', decoration: 'underline', link: 'https://www.somewhere.com', style: [ 'html-a' ] }
test("a",function(t) {
var ret = htmlToPdfMake('<a href="https://www.somewhere.com">link</a>', window);
var ret = htmlToPdfMake('<a href="https://www.somewhere.com">link</a>', {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -211,5 +214,5 @@ ret = ret[0];

// { text: 'strike', decoration: 'lineThrough', style: [ 'html-strike' ] }
test("strike",function(t) {
var ret = htmlToPdfMake("<strike>strike</strike>", window);
var ret = htmlToPdfMake("<strike>strike</strike>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -247,3 +250,4 @@ ret = ret[0];

</table>`;
var ret = htmlToPdfMake(html, window);
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -275,3 +279,4 @@ ret = ret[0];

</table>`;
var ret = htmlToPdfMake(html, window);
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -299,3 +304,4 @@ ret = ret[0];

</table>`;
var ret = htmlToPdfMake(html, window);
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -329,3 +335,4 @@ ret = ret[0];

</table>`;
var ret = htmlToPdfMake(html, window);
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -387,3 +394,4 @@ ret = ret[0];

</table>`;
var ret = htmlToPdfMake(html, window);
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -412,13 +420,13 @@ ret = ret[0];

ret.table.body[3][1].text === "Cell B3 & C3" &&
ret.table.body[3][2] === "" &&
ret.table.body[3][2].text === "" &&
ret.table.body[3][3].text === "Cell D3", "row 4");
t.check(
ret.table.body[4][0].text === "Cell A4 & A5 & B4 & B5 & C4 & C5" &&
ret.table.body[4][1] === "" &&
ret.table.body[4][2] === "" &&
ret.table.body[4][1].text === "" &&
ret.table.body[4][2].text === "" &&
ret.table.body[4][3].text === "Cell D4", "row 5");
t.check(
ret.table.body[5][0].text === "" &&
ret.table.body[5][1] === "" &&
ret.table.body[5][2] === "" &&
ret.table.body[5][1].text === "" &&
ret.table.body[5][2].text === "" &&
ret.table.body[5][3].text === "Cell D5", "row 6");

@@ -450,3 +458,4 @@ t.check(

</table>`;
var ret = htmlToPdfMake(html, window);
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -480,3 +489,4 @@ ret = ret[0];

test("img",function(t) {
var ret = htmlToPdfMake('<img width="10" style="height:10px" src="data:image/jpeg;base64,...encodedContent...">', window);
var ret = htmlToPdfMake('<img width="10" style="height:10px" src="data:image/jpeg;base64,...encodedContent...">', {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -486,3 +496,3 @@ ret = ret[0];

ret.image === "data:image/jpeg;base64,...encodedContent..." &&
ret.width === 10 && ret.height === 10 &&
ret.width === 8 && ret.height === 8 &&
Array.isArray(ret.style) &&

@@ -501,3 +511,4 @@ ret.style[0] === 'html-img',

<text x="150" y="125" font-size="60" text-anchor="middle" fill="white">SVG</text>
</svg>`, window);
</svg>`, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -520,5 +531,6 @@ ret = ret[0];

test("cascade_tags", function(t) {
var ret = htmlToPdfMake('<p style="text-align: center;"><span style="font-size: 14px;"><em><strong>test</strong></em></span></p>', window);
var ret = htmlToPdfMake('<p style="text-align: center;"><span style="font-size: 14px;"><em><strong>test</strong></em></span></p>', {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");
ret = ret[0];
ret = ret[0].text[0].text[0].text[0];
t.check(

@@ -528,3 +540,3 @@ ret.text === "test" &&

ret.italics &&
ret.fontSize === 14 &&
ret.fontSize === 11 &&
ret.alignment === 'center' &&

@@ -542,3 +554,4 @@ Array.isArray(ret.style) &&

test("hr", function(t) {
var ret = htmlToPdfMake("<hr>", window);
var ret = htmlToPdfMake("<hr>", {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length === 1, "return is OK");

@@ -574,3 +587,4 @@ ret = ret[0];

</table>`;
var ret = htmlToPdfMake(html, window);
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -606,3 +620,4 @@ ret = ret[0];

</table>`;
var ret = htmlToPdfMake(html, window);
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -621,3 +636,4 @@ ret = ret[0];

var html = `<div style="color:red;"><span style="color:blue">blue<strong style="color:green">green</strong>blue</span><span>red</span></div>`;
var ret = htmlToPdfMake(html, window);
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -648,3 +664,4 @@ ret = ret[0];

var html = `<table><tr><td style="border-top-width: 0; border-right: 1pt solid #0080C0; border-bottom: 0; border-left: 1px solid #0080C0;">Cell with border left and right in blue</td></tr></table>`;
var ret = htmlToPdfMake(html, window);
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");

@@ -669,161 +686,54 @@ ret = ret[0];

/*[
{
"table": {
"body": [
[
{
"text": [
{
"text": "some text\n",
"style": [
"html-td"
]
},
{
"text": [
{
"text": "p1",
"style": [
"html-p",
"html-td"
]
},
{
"text": "span1",
"style": [
"html-span",
"html-p",
"html-td"
]
},
{
"text": "span2",
"style": [
"html-span",
"html-p",
"html-td"
]
},
{
"text": "\n"
}
],
"margin": [
0,
5,
0,
10
],
"style": [
"html-p",
"html-td"
]
},
{
"text": "p2\n",
"style": [
"html-p",
"html-td"
],
"margin": [
0,
5,
0,
10
]
},
{
"text": "span3\n",
"style": [
"html-span",
"html-td"
]
},
{
"text": "p3span4\n",
"style": [
"html-span",
"html-p",
"html-td"
],
"margin": [
0,
5,
0,
10
]
},
{
"text": [
{
"text": "span5\n",
"style": [
"html-span"
]
},
{
"text": "p4",
"style": [
"html-p"
],
"margin": [
0,
5,
0,
10
]
},
{
"text": "\n"
}
],
"style": [
"html-div",
"html-td"
]
},
{
"text": "strong",
"style": [
"html-strong",
"html-td"
],
"bold": true
}
],
"style": [
"html-td"
]
}
]
]
},
"style": [
"html-table"
],
"marginBottom": 5
}
]*/
test("cell with P and DIV", function(t) {
var html = `<table><tr><td>some text<p>p1<span>span1</span><span>span2</span></p><p>p2</p><span>span3</span><p><span>p3span4</span></p><div><span>span5</span><p>p4</p></div><strong>strong</strong></td></tr></table>`;
var ret = htmlToPdfMake(html, window);
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");
ret = ret[0].table.body[0][0];
t.check(ret.stack[0].text === "some text", "some text");
t.check(ret.stack[1].text[0].text === "p1", "p1");
t.check(ret.stack[1].text[1].text === "span1", "span1");
t.check(ret.stack[1].text[2].text === "span2", "span2");
t.check(ret.stack[2].text === "p2", "p2");
t.check(ret.stack[3].text === "span3", "span3");
t.check(ret.stack[4].text[0].text === "p3span4", "p3span4");
t.check(ret.stack[5].stack[0].text === "span5", "span5");
t.check(ret.stack[5].stack[1].text === "p4", "p4");
t.check(ret.stack[6].text === "strong", "strong");
t.finish();
})
test("tableAutoSize", function(t) {
var html = `<table><tr style="height:100px"><td style="width:350px"></td><td></td></tr><tr><td style="width:100px"></td><td style="height:200px"></td></tr></table>`;
var ret = htmlToPdfMake(html, {window:window, tableAutoSize:true});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");
ret = ret[0];
t.check(
ret.table.body[0][0].text[0].text === "some text\n" &&
ret.table.body[0][0].text[1].text[0].text === "p1" &&
ret.table.body[0][0].text[1].text[1].text === "span1" &&
ret.table.body[0][0].text[1].text[2].text === "span2" &&
ret.table.body[0][0].text[1].text[3].text === "\n" &&
ret.table.body[0][0].text[2].text === "p2\n" &&
ret.table.body[0][0].text[3].text === "span3\n" &&
ret.table.body[0][0].text[4].text === "p3span4\n" &&
ret.table.body[0][0].text[5].text[0].text === "span5\n" &&
ret.table.body[0][0].text[5].text[1].text === "p4" &&
ret.table.body[0][0].text[5].text[2].text === "\n" &&
ret.table.body[0][0].text[6].text === "strong",
"cell with P and DIV");
Array.isArray(ret.table.widths) &&
ret.table.widths.length === 2 &&
ret.table.widths[0] === 264 &&
ret.table.widths[1] === 'auto' &&
ret.table.heights.length === 2 &&
ret.table.heights[0] === 75 &&
ret.table.heights[1] === 151
, "tableAutoSize");
t.finish();
})
test("convertUnit and stack", function(t) {
var html = `<div><div style="font-size:16px;margin-left:12pt">points</div><div style="margin-left:1rem">points</div></div>`;
var ret = htmlToPdfMake(html, {window:window});
if (debug) console.log(JSON.stringify(ret));
t.check(Array.isArray(ret) && ret.length===1, "return is OK");
ret = ret[0];
t.check(Array.isArray(ret.stack), "stack");
t.check(
ret.stack[0].marginLeft===12 &&
ret.stack[0].fontSize===12 &&
ret.stack[1].marginLeft===12
, "convertUnit");
t.finish();
})

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc