/* global jsPDF, rasterizeHTML, html2canvas */
/**
* jsPDF addHTML PlugIn
* Copyright (c) 2014 Diego Casorran
*
* Licensed under the MIT License.
* http://opensource.org/licenses/mit-license
*/
(function(jsPDFAPI) {
"use strict";
/**
* Renders an HTML element to canvas object which added to the PDF
*
* This feature requires [html2canvas](https://github.com/niklasvh/html2canvas)
* or [rasterizeHTML](https://github.com/cburgmer/rasterizeHTML.js)
*
* @returns {jsPDF}
* @name addHTML
* @param element {Mixed} HTML Element, or anything supported by html2canvas.
* @param x {Number} starting X coordinate in jsPDF instance's declared units.
* @param y {Number} starting Y coordinate in jsPDF instance's declared units.
* @param options {Object} Additional options, check the code below.
* @param callback {Function} to call when the rendering has finished.
* NOTE: Every parameter is optional except 'element' and 'callback', in such
* case the image is positioned at 0x0 covering the whole PDF document
* size. Ie, to easily take screenshots of webpages saving them to PDF.
* @deprecated This is being replace with a vector-supporting API. See
* [this link](https://cdn.rawgit.com/MrRio/jsPDF/master/examples/html2pdf/showcase_supported_html.html)
*/
jsPDFAPI.addHTML = function(element, x, y, options, callback) {
"use strict";
if (
typeof html2canvas === "undefined" &&
typeof rasterizeHTML === "undefined"
)
throw new Error(
"You need either " +
"https://github.com/niklasvh/html2canvas" +
" or https://github.com/cburgmer/rasterizeHTML.js"
);
if (typeof x !== "number") {
options = x;
callback = y;
}
if (typeof options === "function") {
callback = options;
options = null;
}
if (typeof callback !== "function") {
callback = function() {};
}
var I = this.internal,
K = I.scaleFactor,
W = I.pageSize.getWidth(),
H = I.pageSize.getHeight();
options = options || {};
options.onrendered = function(obj) {
x = parseInt(x) || 0;
y = parseInt(y) || 0;
var dim = options.dim || {};
var margin = Object.assign(
{ top: 0, right: 0, bottom: 0, left: 0, useFor: "content" },
options.margin
);
var h = dim.h || Math.min(H, obj.height / K);
var w = dim.w || Math.min(W, obj.width / K) - x;
var format = options.format || "JPEG";
var imageCompression = options.imageCompression || "SLOW";
var notFittingHeight = obj.height > H - margin.top - margin.bottom;
if (notFittingHeight && options.pagesplit) {
var cropArea = function(parmObj, parmX, parmY, parmWidth, parmHeight) {
var canvas = document.createElement("canvas");
canvas.height = parmHeight;
canvas.width = parmWidth;
var ctx = canvas.getContext("2d");
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
ctx.fillStyle = options.backgroundColor || "#ffffff";
ctx.fillRect(0, 0, parmWidth, parmHeight);
ctx.drawImage(
parmObj,
parmX,
parmY,
parmWidth,
parmHeight,
0,
0,
parmWidth,
parmHeight
);
return canvas;
};
var crop = function() {
var cy = 0;
var cx = 0;
var position = {};
var isOverWide = false;
var width;
var height;
var canvas;
var args;
while (1) {
cx = 0;
position.top = cy !== 0 ? margin.top : y;
position.left = cy !== 0 ? margin.left : x;
isOverWide = (W - margin.left - margin.right) * K < obj.width;
if (margin.useFor === "content") {
if (cy === 0) {
width = Math.min((W - margin.left) * K, obj.width);
height = Math.min((H - margin.top) * K, obj.height - cy);
} else {
width = Math.min(W * K, obj.width);
height = Math.min(H * K, obj.height - cy);
position.top = 0;
}
} else {
width = Math.min((W - margin.left - margin.right) * K, obj.width);
height = Math.min(
(H - margin.bottom - margin.top) * K,
obj.height - cy
);
}
if (isOverWide) {
while (1) {
if (margin.useFor === "content") {
if (cx === 0) {
width = Math.min((W - margin.left) * K, obj.width);
} else {
width = Math.min(W * K, obj.width - cx);
position.left = 0;
}
}
canvas = cropArea(obj, cx, cy, width, height);
args = [
canvas,
position.left,
position.top,
canvas.width / K,
canvas.height / K,
format,
null,
imageCompression
];
this.addImage.apply(this, args);
cx += width;
if (cx >= obj.width) {
break;
}
this.addPage();
}
} else {
canvas = cropArea(obj, 0, cy, width, height);
args = [
canvas,
position.left,
position.top,
canvas.width / K,
canvas.height / K,
format,
null,
imageCompression
];
this.addImage.apply(this, args);
}
cy += height;
if (cy >= obj.height) {
break;
}
this.addPage();
}
callback(w, cy, null, args);
}.bind(this);
if (obj.nodeName === "CANVAS") {
var img = new Image();
img.onload = crop;
img.src = obj.toDataURL("image/png");
obj = img;
} else {
crop();
}
} else {
var alias = Math.random().toString(35);
var args = [obj, x, y, w, h, format, alias, imageCompression];
this.addImage.apply(this, args);
callback(w, h, alias, args);
}
}.bind(this);
if (typeof html2canvas !== "undefined" && !options.rstz) {
return html2canvas(element, options);
}
if (typeof rasterizeHTML !== "undefined") {
var meth = "drawDocument";
if (typeof element === "string") {
meth = /^http/.test(element) ? "drawURL" : "drawHTML";
}
options.width = options.width || W * K;
return rasterizeHTML[meth](element, void 0, options).then(
function(r) {
options.onrendered(r.image);
},
function(e) {
callback(null, e);
}
);
}
return null;
};
})(jsPDF.API);