diff --git a/jspdf.plugin.from_html.js b/jspdf.plugin.from_html.js index f7dc9d921..9b0d6aee2 100644 --- a/jspdf.plugin.from_html.js +++ b/jspdf.plugin.from_html.js @@ -3,6 +3,7 @@ * Copyright (c) 2012 Willow Systems Corporation, willow-systems.com * 2014 Juan Pablo Gaviria, https://github.com/juanpgaviria * 2014 Diego Casorran, https://github.com/diegocr + * 2014 Daniel Husar, https://github.com/danielhusar * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -85,6 +86,16 @@ return name; }; ResolveUnitedNumber = function(css_line_height_string) { + + //IE8 issues + css_line_height_string = css_line_height_string === "auto" ? "0px" : css_line_height_string; + if (css_line_height_string.indexOf("em") > -1 && !isNaN(Number(css_line_height_string.replace("em", "")))) { + css_line_height_string = Number(css_line_height_string.replace("em", "")) * 18.719 + "px"; + } + if (css_line_height_string.indexOf("pt") > -1 && !isNaN(Number(css_line_height_string.replace("pt", "")))) { + css_line_height_string = Number(css_line_height_string.replace("pt", "")) * 1.333 + "px"; + } + var normal, undef, value; undef = void 0; normal = 16.00; @@ -237,8 +248,9 @@ OBJECT : 1, EMBED : 1 }; + var listCount = 1; DrillForContent = function(element, renderer, elementHandlers) { - var cn, cns, fragmentCSS, i, isBlock, l, px2pt, table2json; + var cn, cns, fragmentCSS, i, isBlock, l, px2pt, table2json, cb; cns = element.childNodes; cn = void 0; fragmentCSS = GetCSS(element); @@ -275,21 +287,51 @@ margins: renderer.pdf.margins_doc }); renderer.y = renderer.pdf.lastCellPos.y + renderer.pdf.lastCellPos.h + 20; + } else if (cn.nodeName === "OL" || cn.nodeName === "UL") { + listCount = 1; + if (!elementHandledElsewhere(cn, renderer, elementHandlers)) { + DrillForContent(cn, renderer, elementHandlers); + } + renderer.y += 10; + } else if (cn.nodeName === "LI") { + var temp = renderer.x; + renderer.x += cn.parentNode.nodeName === "UL" ? 22 : 10; + renderer.y += 3; + if (!elementHandledElsewhere(cn, renderer, elementHandlers)) { + DrillForContent(cn, renderer, elementHandlers); + } + renderer.x = temp; } else { if (!elementHandledElsewhere(cn, renderer, elementHandlers)) { DrillForContent(cn, renderer, elementHandlers); } } } else if (cn.nodeType === 3) { - renderer.addText(cn.nodeValue, fragmentCSS); + var value = cn.nodeValue; + if (cn.nodeValue && cn.parentNode.nodeName === "LI") { + if (cn.parentNode.parentNode.nodeName === "OL") { + value = listCount++ + '. ' + value; + } else { + var fontPx = fragmentCSS["font-size"] * 16; + var radius = 2; + if(fontPx > 20){ + radius = 3; + } + cb = function(x, y){ + this.pdf.circle(x, y, radius, 'FD'); + }; + } + } + renderer.addText(value, fragmentCSS); } else if (typeof cn === "string") { renderer.addText(cn, fragmentCSS); } } i++; } + if (isBlock) { - return renderer.setBlockBoundary(); + return renderer.setBlockBoundary(cb); } }; images = {}; @@ -413,8 +455,8 @@ font = this.pdf.internal.getFont(style["font-family"], style["font-style"]); return this.pdf.internal.write("/" + font.id, (defaultFontSize * style["font-size"]).toFixed(2), "Tf", "(" + this.pdf.internal.pdfEscape(text) + ") Tj"); }; - Renderer.prototype.renderParagraph = function() { - var blockstyle, defaultFontSize, fontToUnitRatio, fragments, i, l, line, lines, maxLineHeight, out, paragraphspacing_after, paragraphspacing_before, priorblockstype, styles; + Renderer.prototype.renderParagraph = function(cb) { + var blockstyle, defaultFontSize, fontToUnitRatio, fragments, i, l, line, lines, maxLineHeight, out, paragraphspacing_after, paragraphspacing_before, priorblockstype, styles, fontSize; fragments = PurgeWhiteSpace(this.paragraph.text); styles = this.paragraph.style; blockstyle = this.paragraph.blockstyle; @@ -448,6 +490,7 @@ while (i !== l) { if (line[i][0].trim()) { maxLineHeight = Math.max(maxLineHeight, line[i][1]["line-height"], line[i][1]["font-size"]); + fontSize = line[i][1]["font-size"] * 7; } i++; } @@ -462,11 +505,14 @@ } this.y += maxLineHeight * fontToUnitRatio; } + if (cb && typeof cb === "function") { + cb.call(this, this.x - 9, this.y - fontSize/2); + } out("ET", "Q"); return this.y += paragraphspacing_after; }; - Renderer.prototype.setBlockBoundary = function() { - return this.renderParagraph(); + Renderer.prototype.setBlockBoundary = function(cb) { + return this.renderParagraph(cb); }; Renderer.prototype.setBlockStyle = function(css) { return this.paragraph.blockstyle = css; diff --git a/libs/polyfill.js b/libs/polyfill.js index 748014a2e..fb6605689 100644 --- a/libs/polyfill.js +++ b/libs/polyfill.js @@ -99,26 +99,33 @@ return dec; }; } - - if (!Array.prototype.map) { - Array.prototype.map = function(fun /*, thisArg */) { - if (this === void 0 || this === null || typeof fun !== "function") + + if (!Array.prototype.map) { + Array.prototype.map = function(fun /*, thisArg */) { + if (this === void 0 || this === null || typeof fun !== "function") throw new TypeError(); - - var t = Object(this), len = t.length >>> 0, res = new Array(len); - var thisArg = arguments.length > 1 ? arguments[1] : void 0; - for (var i = 0; i < len; i++) { - // NOTE: Absolute correctness would demand Object.defineProperty - // be used. But this method is fairly new, and failure is - // possible only if Object.prototype or Array.prototype - // has a property |i| (very unlikely), so use a less-correct - // but more portable alternative. - if (i in t) - res[i] = fun.call(thisArg, t[i], i, t); + + var t = Object(this), len = t.length >>> 0, res = new Array(len); + var thisArg = arguments.length > 1 ? arguments[1] : void 0; + for (var i = 0; i < len; i++) { + // NOTE: Absolute correctness would demand Object.defineProperty + // be used. But this method is fairly new, and failure is + // possible only if Object.prototype or Array.prototype + // has a property |i| (very unlikely), so use a less-correct + // but more portable alternative. + if (i in t) + res[i] = fun.call(thisArg, t[i], i, t); } - - return res; - }; + + return res; + }; + } + + + if(!Array.isArray) { + Array.isArray = function(arg) { + return Object.prototype.toString.call(arg) === '[object Array]'; + }; } if (!Array.prototype.forEach) { @@ -135,55 +142,55 @@ } }; } - - if (!Object.keys) { - Object.keys = (function () { + + if (!Object.keys) { + Object.keys = (function () { 'use strict'; - - var hasOwnProperty = Object.prototype.hasOwnProperty, - hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), - dontEnums = ['toString','toLocaleString','valueOf','hasOwnProperty', - 'isPrototypeOf','propertyIsEnumerable','constructor'], + + var hasOwnProperty = Object.prototype.hasOwnProperty, + hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), + dontEnums = ['toString','toLocaleString','valueOf','hasOwnProperty', + 'isPrototypeOf','propertyIsEnumerable','constructor'], dontEnumsLength = dontEnums.length; - - return function (obj) { - if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { - throw new TypeError(); - } + + return function (obj) { + if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { + throw new TypeError(); + } var result = [], prop, i; - - for (prop in obj) { - if (hasOwnProperty.call(obj, prop)) { - result.push(prop); - } + + for (prop in obj) { + if (hasOwnProperty.call(obj, prop)) { + result.push(prop); + } + } + + if (hasDontEnumBug) { + for (i = 0; i < dontEnumsLength; i++) { + if (hasOwnProperty.call(obj, dontEnums[i])) { + result.push(dontEnums[i]); + } + } } - - if (hasDontEnumBug) { - for (i = 0; i < dontEnumsLength; i++) { - if (hasOwnProperty.call(obj, dontEnums[i])) { - result.push(dontEnums[i]); - } - } - } - return result; - }; - }()); + return result; + }; + }()); } - if (!String.prototype.trim) { - String.prototype.trim = function () { - return this.replace(/^\s+|\s+$/g, ''); - }; - } - if (!String.prototype.trimLeft) { - String.prototype.trimLeft = function() { - return this.replace(/^\s+/g, ""); - }; - } - if (!String.prototype.trimRight) { - String.prototype.trimRight = function() { - return this.replace(/\s+$/g, ""); - }; + if (!String.prototype.trim) { + String.prototype.trim = function () { + return this.replace(/^\s+|\s+$/g, ''); + }; + } + if (!String.prototype.trimLeft) { + String.prototype.trimLeft = function() { + return this.replace(/^\s+/g, ""); + }; } - + if (!String.prototype.trimRight) { + String.prototype.trimRight = function() { + return this.replace(/\s+$/g, ""); + }; + } + })(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this);