diff --git a/build/html2canvas.js b/build/html2canvas.js
index 3a44bc3..99e2a5f 100644
--- a/build/html2canvas.js
+++ b/build/html2canvas.js
@@ -1029,7 +1029,7 @@ function h2cRenderContext(width, height) {
}
};
}
-_html2canvas.Parse = function (images, options) {
+_html2canvas.Parse = function (images, options, cb) {
window.scroll(0,0);
var element = (( options.elements === undefined ) ? document.body : options.elements[0]), // select body by default
@@ -1041,15 +1041,163 @@ _html2canvas.Parse = function (images, options) {
body = doc.body,
getCSS = Util.getCSS,
pseudoHide = "___html2canvas___pseudoelement",
- hidePseudoElements = doc.createElement('style');
+ hidePseudoElementsStyles = doc.createElement('style');
- hidePseudoElements.innerHTML = '.' + pseudoHide + '-before:before { content: "" !important; display: none !important; }' +
- '.' + pseudoHide + '-after:after { content: "" !important; display: none !important; }';
+ hidePseudoElementsStyles.innerHTML = '.' + pseudoHide +
+ '-parent:before { content: "" !important; display: none !important; }' +
+ '.' + pseudoHide + '-parent:after { content: "" !important; display: none !important; }';
- body.appendChild(hidePseudoElements);
+ body.appendChild(hidePseudoElementsStyles);
images = images || {};
+ init();
+
+ function init() {
+ var background = getCSS(document.documentElement, "backgroundColor"),
+ transparentBackground = (Util.isTransparent(background) && element === document.body),
+ stack = renderElement(element, null, false, transparentBackground);
+
+ // create pseudo elements in a single pass to prevent synchronous layouts
+ addPseudoElements(element);
+
+ parseChildren(element, stack, function() {
+ if (transparentBackground) {
+ background = stack.backgroundColor;
+ }
+
+ removePseudoElements();
+
+ Util.log('Done parsing, moving to Render.');
+
+ cb({
+ backgroundColor: background,
+ stack: stack
+ });
+ });
+ }
+
+ // Given a root element, find all pseudo elements below, create elements mocking pseudo element styles
+ // so we can process them as normal elements, and hide the original pseudo elements so they don't interfere
+ // with layout.
+ function addPseudoElements(el) {
+ // These are done in discrete steps to prevent a relayout loop caused by addClass() invalidating
+ // layouts & getPseudoElement calling getComputedStyle.
+ var jobs = [], classes = [];
+ getPseudoElementClasses();
+ findPseudoElements(el);
+ runJobs();
+
+ function getPseudoElementClasses(){
+ var findPsuedoEls = /:before|:after/;
+ var sheets = document.styleSheets;
+ for (var i = 0, j = sheets.length; i < j; i++) {
+ try {
+ var rules = sheets[i].cssRules;
+ for (var k = 0, l = rules.length; k < l; k++) {
+ if(findPsuedoEls.test(rules[k].selectorText)) {
+ classes.push(rules[k].selectorText);
+ }
+ }
+ }
+ catch(e) { // will throw security exception for style sheets loaded from external domains
+ }
+ }
+
+ // Trim off the :after and :before (or ::after and ::before)
+ for (i = 0, j = classes.length; i < j; i++) {
+ classes[i] = classes[i].match(/(^[^:]*)/)[1];
+ }
+ }
+
+ // Using the list of elements we know how pseudo el styles, create fake pseudo elements.
+ function findPseudoElements(el) {
+ var els = document.querySelectorAll(classes.join(','));
+ for(var i = 0, j = els.length; i < j; i++) {
+ createPseudoElements(els[i]);
+ }
+ }
+
+ // Create pseudo elements & add them to a job queue.
+ function createPseudoElements(el) {
+ var before = getPseudoElement(el, ':before'),
+ after = getPseudoElement(el, ':after');
+
+ if(before) {
+ jobs.push({type: 'before', pseudo: before, el: el});
+ }
+
+ if (after) {
+ jobs.push({type: 'after', pseudo: after, el: el});
+ }
+ }
+
+ // Adds a class to the pseudo's parent to prevent the original before/after from messing
+ // with layouts.
+ // Execute the inserts & addClass() calls in a batch to prevent relayouts.
+ function runJobs() {
+ // Add Class
+ jobs.forEach(function(job){
+ addClass(job.el, pseudoHide + "-parent");
+ });
+
+ // Insert el
+ jobs.forEach(function(job){
+ if(job.type === 'before'){
+ job.el.insertBefore(job.pseudo, job.el.firstChild);
+ } else {
+ job.el.appendChild(job.pseudo);
+ }
+ });
+ }
+ }
+
+
+
+ // Delete our fake pseudo elements from the DOM. This will remove those actual elements
+ // and the classes on their parents that hide the actual pseudo elements.
+ // Note that NodeLists are 'live' collections so you can't use a for loop here. They are
+ // actually deleted from the NodeList after each iteration.
+ function removePseudoElements(){
+ // delete pseudo elements
+ body.removeChild(hidePseudoElementsStyles);
+ var pseudos = document.getElementsByClassName(pseudoHide + "-element");
+ while (pseudos.length) {
+ pseudos[0].parentNode.removeChild(pseudos[0]);
+ }
+
+ // Remove pseudo hiding classes
+ var parents = document.getElementsByClassName(pseudoHide + "-parent");
+ while(parents.length) {
+ removeClass(parents[0], pseudoHide + "-parent");
+ }
+ }
+
+ function addClass (el, className) {
+ if (el.classList) {
+ el.classList.add(className);
+ } else {
+ el.className = el.className + " " + className;
+ }
+ }
+
+ function removeClass (el, className) {
+ if (el.classList) {
+ el.classList.remove(className);
+ } else {
+ el.className = el.className.replace(className, "").trim();
+ }
+ }
+
+ function hasClass (el, className) {
+ return el.className.indexOf(className) > -1;
+ }
+
+ // Note that this doesn't work in < IE8, but we don't support that anyhow
+ function nodeListToArray (nodeList) {
+ return Array.prototype.slice.call(nodeList);
+ }
+
function documentWidth () {
return Math.max(
Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth),
@@ -1367,6 +1515,13 @@ _html2canvas.Parse = function (images, options) {
}
}
+ function h2czContext(zindex) {
+ return {
+ zindex: zindex,
+ children: []
+ };
+ }
+
function renderImage(ctx, element, image, bounds, borders) {
var paddingLeft = getCSSInt(element, 'paddingLeft'),
@@ -1403,69 +1558,67 @@ _html2canvas.Parse = function (images, options) {
});
}
- var getCurvePoints = (function(kappa) {
-
- return function(x, y, r1, r2) {
- var ox = (r1) * kappa, // control point offset horizontal
- oy = (r2) * kappa, // control point offset vertical
- xm = x + r1, // x-middle
- ym = y + r2; // y-middle
- return {
- topLeft: bezierCurve({
- x:x,
- y:ym
- }, {
- x:x,
- y:ym - oy
- }, {
- x:xm - ox,
- y:y
- }, {
- x:xm,
- y:y
- }),
- topRight: bezierCurve({
- x:x,
- y:y
- }, {
- x:x + ox,
- y:y
- }, {
- x:xm,
- y:ym - oy
- }, {
- x:xm,
- y:ym
- }),
- bottomRight: bezierCurve({
- x:xm,
- y:y
- }, {
- x:xm,
- y:y + oy
- }, {
- x:x + ox,
- y:ym
- }, {
- x:x,
- y:ym
- }),
- bottomLeft: bezierCurve({
- x:xm,
- y:ym
- }, {
- x:xm - ox,
- y:ym
- }, {
- x:x,
- y:y + oy
- }, {
- x:x,
- y:y
- })
- };
+ function getCurvePoints(x, y, r1, r2) {
+ var kappa = 4 * ((Math.sqrt(2) - 1) / 3);
+ var ox = (r1) * kappa, // control point offset horizontal
+ oy = (r2) * kappa, // control point offset vertical
+ xm = x + r1, // x-middle
+ ym = y + r2; // y-middle
+ return {
+ topLeft: bezierCurve({
+ x:x,
+ y:ym
+ }, {
+ x:x,
+ y:ym - oy
+ }, {
+ x:xm - ox,
+ y:y
+ }, {
+ x:xm,
+ y:y
+ }),
+ topRight: bezierCurve({
+ x:x,
+ y:y
+ }, {
+ x:x + ox,
+ y:y
+ }, {
+ x:xm,
+ y:ym - oy
+ }, {
+ x:xm,
+ y:ym
+ }),
+ bottomRight: bezierCurve({
+ x:xm,
+ y:y
+ }, {
+ x:xm,
+ y:y + oy
+ }, {
+ x:x + ox,
+ y:ym
+ }, {
+ x:x,
+ y:ym
+ }),
+ bottomLeft: bezierCurve({
+ x:xm,
+ y:ym
+ }, {
+ x:xm - ox,
+ y:ym
+ }, {
+ x:x,
+ y:y + oy
+ }, {
+ x:x,
+ y:y
+ })
};
- })(4 * ((Math.sqrt(2) - 1) / 3));
+ }
function bezierCurve(start, startControl, endControl, end) {
@@ -1804,20 +1957,25 @@ _html2canvas.Parse = function (images, options) {
function getPseudoElement(el, which) {
var elStyle = window.getComputedStyle(el, which);
- if(!elStyle || !elStyle.content || elStyle.content === "none" || elStyle.content === "-moz-alt-content" || elStyle.display === "none") {
+ var parentStyle = window.getComputedStyle(el);
+ // If no content attribute is present, the pseudo element is hidden,
+ // or the parent has a content property equal to the content on the pseudo element,
+ // move along.
+ if(!elStyle || !elStyle.content || elStyle.content === "none" || elStyle.content === "-moz-alt-content" ||
+ elStyle.display === "none" || parentStyle.content === elStyle.content) {
return;
}
- var content = elStyle.content + '',
- first = content.substr( 0, 1 );
- //strips quotes
- if(first === content.substr( content.length - 1 ) && first.match(/'|"/)) {
- content = content.substr( 1, content.length - 2 );
+ var content = elStyle.content + '';
+
+ // Strip inner quotes
+ if(content[0] === "'" || content[0] === "\"") {
+ content = content.replace(/(^['"])|(['"]$)/g, '');
}
var isImage = content.substr( 0, 3 ) === 'url',
elps = document.createElement( isImage ? 'img' : 'span' );
- elps.className = pseudoHide + "-before " + pseudoHide + "-after";
+ elps.className = pseudoHide + "-element ";
Object.keys(elStyle).filter(indexedProperty).forEach(function(prop) {
// Prevent assigning of read only CSS Rules, ex. length, parentRule
@@ -1840,31 +1998,6 @@ _html2canvas.Parse = function (images, options) {
return (isNaN(window.parseInt(property, 10)));
}
- function injectPseudoElements(el, stack) {
- var before = getPseudoElement(el, ':before'),
- after = getPseudoElement(el, ':after');
- if(!before && !after) {
- return;
- }
-
- if(before) {
- el.className += " " + pseudoHide + "-before";
- el.parentNode.insertBefore(before, el);
- parseElement(before, stack, true);
- el.parentNode.removeChild(before);
- el.className = el.className.replace(pseudoHide + "-before", "").trim();
- }
-
- if (after) {
- el.className += " " + pseudoHide + "-after";
- el.appendChild(after);
- parseElement(after, stack, true);
- el.removeChild(after);
- el.className = el.className.replace(pseudoHide + "-after", "").trim();
- }
-
- }
-
function renderBackgroundRepeat(ctx, image, backgroundPosition, bounds) {
var offsetX = Math.round(bounds.left + backgroundPosition.left),
offsetY = Math.round(bounds.top + backgroundPosition.top);
@@ -1984,9 +2117,8 @@ _html2canvas.Parse = function (images, options) {
return str.replace("px", "");
}
- var transformRegExp = /(matrix)\((.+)\)/;
-
function getTransform(element, parentStack) {
+ var transformRegExp = /(matrix)\((.+)\)/;
var transform = getCSS(element, "transform") || getCSS(element, "-webkit-transform") || getCSS(element, "-moz-transform") || getCSS(element, "-ms-transform") || getCSS(element, "-o-transform");
var transformOrigin = getCSS(element, "transform-origin") || getCSS(element, "-webkit-transform-origin") || getCSS(element, "-moz-transform-origin") || getCSS(element, "-ms-transform-origin") || getCSS(element, "-o-transform-origin") || "0px 0px";
@@ -2053,7 +2185,7 @@ _html2canvas.Parse = function (images, options) {
return bounds;
}
- function renderElement(element, parentStack, pseudoElement, ignoreBackground) {
+ function renderElement(element, parentStack, ignoreBackground) {
var transform = getTransform(element, parentStack),
bounds = getBounds(element, transform),
image,
@@ -2083,10 +2215,6 @@ _html2canvas.Parse = function (images, options) {
renderBorders(ctx, border.args, border.color);
});
- if (!pseudoElement) {
- injectPseudoElements(element, stack);
- }
-
switch(element.nodeName){
case "IMG":
if ((image = loadImage(element.getAttribute('src')))) {
@@ -2127,52 +2255,54 @@ _html2canvas.Parse = function (images, options) {
return (getCSS(element, 'display') !== "none" && getCSS(element, 'visibility') !== "hidden" && !element.hasAttribute("data-html2canvas-ignore"));
}
- function parseElement (element, stack, pseudoElement) {
+ function parseElement (element, stack, cb) {
+ if (!cb) {
+ cb = function(){};
+ }
if (isElementVisible(element)) {
- stack = renderElement(element, stack, pseudoElement, false) || stack;
+ stack = renderElement(element, stack, false) || stack;
if (!ignoreElementsRegExp.test(element.nodeName)) {
- parseChildren(element, stack, pseudoElement);
+ return parseChildren(element, stack, cb);
}
}
+ cb();
}
- function parseChildren(element, stack, pseudoElement) {
- Util.Children(element).forEach(function(node) {
+ function parseChildren(element, stack, cb) {
+ var children = Util.Children(element);
+ // After all nodes have processed, finished() will call the cb.
+ // We add one and kick it off so this will still work when children.length === 0.
+ // Note that unless async is true, this will happen synchronously, just will callbacks.
+ var jobs = children.length + 1;
+ finished();
+
+ if (options.async) {
+ children.forEach(function(node) {
+ // Don't block the page from rendering
+ setTimeout(function(){ parseNode(node); }, 0);
+ });
+ } else {
+ children.forEach(parseNode);
+ }
+
+ function parseNode(node) {
if (node.nodeType === node.ELEMENT_NODE) {
- parseElement(node, stack, pseudoElement);
+ parseElement(node, stack, finished);
} else if (node.nodeType === node.TEXT_NODE) {
renderText(element, node, stack);
+ finished();
+ } else {
+ finished();
+ }
+ }
+ function finished(el) {
+ if (--jobs <= 0){
+ Util.log("finished rendering " + children.length + " children.");
+ cb();
}
- });
- }
-
- function init() {
- var background = getCSS(document.documentElement, "backgroundColor"),
- transparentBackground = (Util.isTransparent(background) && element === document.body),
- stack = renderElement(element, null, false, transparentBackground);
- parseChildren(element, stack);
-
- if (transparentBackground) {
- background = stack.backgroundColor;
}
-
- body.removeChild(hidePseudoElements);
- return {
- backgroundColor: background,
- stack: stack
- };
}
-
- return init();
};
-
-function h2czContext(zindex) {
- return {
- zindex: zindex,
- children: []
- };
-}
-
_html2canvas.Preload = function( options ) {
var images = {
@@ -2678,9 +2808,9 @@ window.html2canvas = function(elements, opts) {
useOverflow: true,
letterRendering: false,
chinese: false,
+ async: false, // If true, parsing will not block, but if the user scrolls during parse the image can get weird
// render options
-
width: null,
height: null,
taintTest: true, // do a taint test with all images before applying to canvas
@@ -2697,21 +2827,19 @@ window.html2canvas = function(elements, opts) {
return;
}
}
- queue = _html2canvas.Parse( images, options );
-
- if (typeof options.onparsed === "function") {
- if ( options.onparsed( queue ) === false ) {
- return;
+ _html2canvas.Parse( images, options, function(queue) {
+ if (typeof options.onparsed === "function") {
+ if ( options.onparsed( queue ) === false ) {
+ return;
+ }
}
- }
-
- canvas = _html2canvas.Renderer( queue, options );
-
- if (typeof options.onrendered === "function") {
- options.onrendered( canvas );
- }
+ canvas = _html2canvas.Renderer( queue, options );
+ if (typeof options.onrendered === "function") {
+ options.onrendered( canvas );
+ }
+ });
};
// for pages without images, we still want this to be async, i.e. return methods before executing
diff --git a/build/html2canvas.min.js b/build/html2canvas.min.js
index 2ea032d..ccbaa18 100644
--- a/build/html2canvas.min.js
+++ b/build/html2canvas.min.js
@@ -4,5 +4,5 @@
Released under MIT License
*/
-(function(t,e,n){"use strict";function r(t,e,n){var r,a=t.runtimeStyle&&t.runtimeStyle[e],o=t.style;return!/^-?[0-9]+\.?[0-9]*(?:px)?$/i.test(n)&&/^-?\d/.test(n)&&(r=o.left,a&&(t.runtimeStyle.left=t.currentStyle.left),o.left="fontSize"===e?"1em":n||0,n=o.pixelLeft+"px",o.left=r,a&&(t.runtimeStyle.left=a)),/^(thin|medium|thick)$/i.test(n)?n:Math.round(parseFloat(n))+"px"}function a(t){return parseInt(t,10)}function o(t,e,a,o){if(t=(t||"").split(","),t=t[o||0]||t[0]||"auto",t=u.Util.trimText(t).split(" "),"backgroundSize"!==a||t[0]&&!t[0].match(/cover|contain|auto/)){if(t[0]=-1===t[0].indexOf("%")?r(e,a+"X",t[0]):t[0],t[1]===n){if("backgroundSize"===a)return t[1]="auto",t;t[1]=t[0]}t[1]=-1===t[1].indexOf("%")?r(e,a+"Y",t[1]):t[1]}else;return t}function i(t,e,n,r,a,o){var i,l,s,c,d=u.Util.getCSS(e,t,a);if(1===d.length&&(c=d[0],d=[],d[0]=c,d[1]=c),-1!==(""+d[0]).indexOf("%"))s=parseFloat(d[0])/100,l=n.width*s,"backgroundSize"!==t&&(l-=(o||r).width*s);else if("backgroundSize"===t)if("auto"===d[0])l=r.width;else if(/contain|cover/.test(d[0])){var h=u.Util.resizeBounds(r.width,r.height,n.width,n.height,d[0]);l=h.width,i=h.height}else l=parseInt(d[0],10);else l=parseInt(d[0],10);return"auto"===d[1]?i=l/r.width*r.height:-1!==(""+d[1]).indexOf("%")?(s=parseFloat(d[1])/100,i=n.height*s,"backgroundSize"!==t&&(i-=(o||r).height*s)):i=parseInt(d[1],10),[l,i]}function l(t,e){var n=[];return{storage:n,width:t,height:e,clip:function(){n.push({type:"function",name:"clip",arguments:arguments})},translate:function(){n.push({type:"function",name:"translate",arguments:arguments})},fill:function(){n.push({type:"function",name:"fill",arguments:arguments})},save:function(){n.push({type:"function",name:"save",arguments:arguments})},restore:function(){n.push({type:"function",name:"restore",arguments:arguments})},fillRect:function(){n.push({type:"function",name:"fillRect",arguments:arguments})},createPattern:function(){n.push({type:"function",name:"createPattern",arguments:arguments})},drawShape:function(){var t=[];return n.push({type:"function",name:"drawShape",arguments:t}),{moveTo:function(){t.push({name:"moveTo",arguments:arguments})},lineTo:function(){t.push({name:"lineTo",arguments:arguments})},arcTo:function(){t.push({name:"arcTo",arguments:arguments})},bezierCurveTo:function(){t.push({name:"bezierCurveTo",arguments:arguments})},quadraticCurveTo:function(){t.push({name:"quadraticCurveTo",arguments:arguments})}}},drawImage:function(){n.push({type:"function",name:"drawImage",arguments:arguments})},fillText:function(){n.push({type:"function",name:"fillText",arguments:arguments})},setVariable:function(t,e){return n.push({type:"variable",name:t,arguments:e}),e}}}function s(t){return{zindex:t,children:[]}}var c,d,u={};u.Util={},u.Util.log=function(e){u.logging&&t.console&&t.console.log&&t.console.log(e)},u.Util.trimText=function(t){return function(e){return t?t.apply(e):((e||"")+"").replace(/^\s+|\s+$/g,"")}}(String.prototype.trim),u.Util.asFloat=function(t){return parseFloat(t)},function(){var t=/((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g,e=/(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g;u.Util.parseTextShadows=function(n){if(!n||"none"===n)return[];for(var r=n.match(t),a=[],o=0;r&&r.length>o;o++){var i=r[o].match(e);a.push({color:i[0],offsetX:i[1]?i[1].replace("px",""):0,offsetY:i[2]?i[2].replace("px",""):0,blur:i[3]?i[3].replace("px",""):0})}return a}}(),u.Util.parseBackgroundImage=function(t){var e,n,r,a,o,i,l,s,c=" \r\n ",d=[],u=0,h=0,f=function(){e&&('"'===n.substr(0,1)&&(n=n.substr(1,n.length-2)),n&&s.push(n),"-"===e.substr(0,1)&&(a=e.indexOf("-",1)+1)>0&&(r=e.substr(0,a),e=e.substr(a)),d.push({prefix:r,method:e.toLowerCase(),value:o,args:s})),s=[],e=r=n=o=""};f();for(var p=0,g=t.length;g>p;p++)if(i=t[p],!(0===u&&c.indexOf(i)>-1)){switch(i){case'"':l?l===i&&(l=null):l=i;break;case"(":if(l)break;if(0===u){u=1,o+=i;continue}h++;break;case")":if(l)break;if(1===u){if(0===h){u=0,o+=i,f();continue}h--}break;case",":if(l)break;if(0===u){f();continue}if(1===u&&0===h&&!e.match(/^url$/i)){s.push(n),n="",o+=i;continue}}o+=i,0===u?e+=i:n+=i}return f(),d},u.Util.Bounds=function(t){var e,n={};return t.getBoundingClientRect&&(e=t.getBoundingClientRect(),n.top=e.top,n.bottom=e.bottom||e.top+e.height,n.left=e.left,n.width=t.offsetWidth,n.height=t.offsetHeight),n},u.Util.OffsetBounds=function(t){var e=t.offsetParent?u.Util.OffsetBounds(t.offsetParent):{top:0,left:0};return{top:t.offsetTop+e.top,bottom:t.offsetTop+t.offsetHeight+e.top,left:t.offsetLeft+e.left,width:t.offsetWidth,height:t.offsetHeight}},u.Util.getCSS=function(t,n,r){c!==t&&(d=e.defaultView.getComputedStyle(t,null));var i=d[n];if(/^background(Size|Position)$/.test(n))return o(i,t,n,r);if(/border(Top|Bottom)(Left|Right)Radius/.test(n)){var l=i.split(" ");return 1>=l.length&&(l[1]=l[0]),l.map(a)}return i},u.Util.resizeBounds=function(t,e,n,r,a){var o,i,l=n/r,s=t/e;return a&&"auto"!==a?s>l^"contain"===a?(i=r,o=r*s):(o=n,i=n/s):(o=n,i=r),{width:o,height:i}},u.Util.BackgroundPosition=function(t,e,n,r,a){var o=i("backgroundPosition",t,e,n,r,a);return{left:o[0],top:o[1]}},u.Util.BackgroundSize=function(t,e,n,r){var a=i("backgroundSize",t,e,n,r);return{width:a[0],height:a[1]}},u.Util.Extend=function(t,e){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e},u.Util.Children=function(t){var e;try{e=t.nodeName&&"IFRAME"===t.nodeName.toUpperCase()?t.contentDocument||t.contentWindow.document:function(t){var e=[];return null!==t&&function(t,e){var r=t.length,a=0;if("number"==typeof e.length)for(var o=e.length;o>a;a++)t[r++]=e[a];else for(;e[a]!==n;)t[r++]=e[a++];return t.length=r,t}(e,t),e}(t.childNodes)}catch(r){u.Util.log("html2canvas.Util.Children failed with exception: "+r.message),e=[]}return e},u.Util.isTransparent=function(t){return"transparent"===t||"rgba(0, 0, 0, 0)"===t},u.Util.Font=function(){var t={};return function(e,r,a){if(t[e+"-"+r]!==n)return t[e+"-"+r];var o,i,l,s=a.createElement("div"),c=a.createElement("img"),d=a.createElement("span"),u="Hidden Text";return s.style.visibility="hidden",s.style.fontFamily=e,s.style.fontSize=r,s.style.margin=0,s.style.padding=0,a.body.appendChild(s),c.src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBADs=",c.width=1,c.height=1,c.style.margin=0,c.style.padding=0,c.style.verticalAlign="baseline",d.style.fontFamily=e,d.style.fontSize=r,d.style.margin=0,d.style.padding=0,d.appendChild(a.createTextNode(u)),s.appendChild(d),s.appendChild(c),o=c.offsetTop-d.offsetTop+1,s.removeChild(d),s.appendChild(a.createTextNode(u)),s.style.lineHeight="normal",c.style.verticalAlign="super",i=c.offsetTop-s.offsetTop+1,l={baseline:o,lineWidth:1,middle:i},t[e+"-"+r]=l,a.body.removeChild(s),l}}(),function(){function t(t){return function(e){try{t.addColorStop(e.stop,e.color)}catch(r){n.log(["failed to add color stop: ",r,"; tried to add: ",e])}}}var n=u.Util,r={};u.Generate=r;var a=[/^(-webkit-linear-gradient)\(([a-z\s]+)([\w\d\.\s,%\(\)]+)\)$/,/^(-o-linear-gradient)\(([a-z\s]+)([\w\d\.\s,%\(\)]+)\)$/,/^(-webkit-gradient)\((linear|radial),\s((?:\d{1,3}%?)\s(?:\d{1,3}%?),\s(?:\d{1,3}%?)\s(?:\d{1,3}%?))([\w\d\.\s,%\(\)\-]+)\)$/,/^(-moz-linear-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?))([\w\d\.\s,%\(\)]+)\)$/,/^(-webkit-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s([a-z\-]+)([\w\d\.\s,%\(\)]+)\)$/,/^(-moz-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s?([a-z\-]*)([\w\d\.\s,%\(\)]+)\)$/,/^(-o-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s([a-z\-]+)([\w\d\.\s,%\(\)]+)\)$/];r.parseGradient=function(t,e){var n,r,o,i,l,s,c,d,u,h,f,p,g=a.length;for(r=0;g>r&&!(o=t.match(a[r]));r+=1);if(o)switch(o[1]){case"-webkit-linear-gradient":case"-o-linear-gradient":if(n={type:"linear",x0:null,y0:null,x1:null,y1:null,colorStops:[]},l=o[2].match(/\w+/g))for(s=l.length,r=0;s>r;r+=1)switch(l[r]){case"top":n.y0=0,n.y1=e.height;break;case"right":n.x0=e.width,n.x1=0;break;case"bottom":n.y0=e.height,n.y1=0;break;case"left":n.x0=0,n.x1=e.width}if(null===n.x0&&null===n.x1&&(n.x0=n.x1=e.width/2),null===n.y0&&null===n.y1&&(n.y0=n.y1=e.height/2),l=o[3].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}(?:%|px))?)+/g))for(s=l.length,c=1/Math.max(s-1,1),r=0;s>r;r+=1)d=l[r].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/),d[2]?(i=parseFloat(d[2]),i/="%"===d[3]?100:e.width):i=r*c,n.colorStops.push({color:d[1],stop:i});break;case"-webkit-gradient":if(n={type:"radial"===o[2]?"circle":o[2],x0:0,y0:0,x1:0,y1:0,colorStops:[]},l=o[3].match(/(\d{1,3})%?\s(\d{1,3})%?,\s(\d{1,3})%?\s(\d{1,3})%?/),l&&(n.x0=l[1]*e.width/100,n.y0=l[2]*e.height/100,n.x1=l[3]*e.width/100,n.y1=l[4]*e.height/100),l=o[4].match(/((?:from|to|color-stop)\((?:[0-9\.]+,\s)?(?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)\))+/g))for(s=l.length,r=0;s>r;r+=1)d=l[r].match(/(from|to|color-stop)\(([0-9\.]+)?(?:,\s)?((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\)/),i=parseFloat(d[2]),"from"===d[1]&&(i=0),"to"===d[1]&&(i=1),n.colorStops.push({color:d[3],stop:i});break;case"-moz-linear-gradient":if(n={type:"linear",x0:0,y0:0,x1:0,y1:0,colorStops:[]},l=o[2].match(/(\d{1,3})%?\s(\d{1,3})%?/),l&&(n.x0=l[1]*e.width/100,n.y0=l[2]*e.height/100,n.x1=e.width-n.x0,n.y1=e.height-n.y0),l=o[3].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}%)?)+/g))for(s=l.length,c=1/Math.max(s-1,1),r=0;s>r;r+=1)d=l[r].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%)?/),d[2]?(i=parseFloat(d[2]),d[3]&&(i/=100)):i=r*c,n.colorStops.push({color:d[1],stop:i});break;case"-webkit-radial-gradient":case"-moz-radial-gradient":case"-o-radial-gradient":if(n={type:"circle",x0:0,y0:0,x1:e.width,y1:e.height,cx:0,cy:0,rx:0,ry:0,colorStops:[]},l=o[2].match(/(\d{1,3})%?\s(\d{1,3})%?/),l&&(n.cx=l[1]*e.width/100,n.cy=l[2]*e.height/100),l=o[3].match(/\w+/),d=o[4].match(/[a-z\-]*/),l&&d)switch(d[0]){case"farthest-corner":case"cover":case"":u=Math.sqrt(Math.pow(n.cx,2)+Math.pow(n.cy,2)),h=Math.sqrt(Math.pow(n.cx,2)+Math.pow(n.y1-n.cy,2)),f=Math.sqrt(Math.pow(n.x1-n.cx,2)+Math.pow(n.y1-n.cy,2)),p=Math.sqrt(Math.pow(n.x1-n.cx,2)+Math.pow(n.cy,2)),n.rx=n.ry=Math.max(u,h,f,p);break;case"closest-corner":u=Math.sqrt(Math.pow(n.cx,2)+Math.pow(n.cy,2)),h=Math.sqrt(Math.pow(n.cx,2)+Math.pow(n.y1-n.cy,2)),f=Math.sqrt(Math.pow(n.x1-n.cx,2)+Math.pow(n.y1-n.cy,2)),p=Math.sqrt(Math.pow(n.x1-n.cx,2)+Math.pow(n.cy,2)),n.rx=n.ry=Math.min(u,h,f,p);break;case"farthest-side":"circle"===l[0]?n.rx=n.ry=Math.max(n.cx,n.cy,n.x1-n.cx,n.y1-n.cy):(n.type=l[0],n.rx=Math.max(n.cx,n.x1-n.cx),n.ry=Math.max(n.cy,n.y1-n.cy));break;case"closest-side":case"contain":"circle"===l[0]?n.rx=n.ry=Math.min(n.cx,n.cy,n.x1-n.cx,n.y1-n.cy):(n.type=l[0],n.rx=Math.min(n.cx,n.x1-n.cx),n.ry=Math.min(n.cy,n.y1-n.cy))}if(l=o[5].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}(?:%|px))?)+/g))for(s=l.length,c=1/Math.max(s-1,1),r=0;s>r;r+=1)d=l[r].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/),d[2]?(i=parseFloat(d[2]),i/="%"===d[3]?100:e.width):i=r*c,n.colorStops.push({color:d[1],stop:i})}return n},r.Gradient=function(n,r){if(0!==r.width&&0!==r.height){var a,o,i=e.createElement("canvas"),l=i.getContext("2d");if(i.width=r.width,i.height=r.height,a=u.Generate.parseGradient(n,r))switch(a.type){case"linear":o=l.createLinearGradient(a.x0,a.y0,a.x1,a.y1),a.colorStops.forEach(t(o)),l.fillStyle=o,l.fillRect(0,0,r.width,r.height);break;case"circle":o=l.createRadialGradient(a.cx,a.cy,0,a.cx,a.cy,a.rx),a.colorStops.forEach(t(o)),l.fillStyle=o,l.fillRect(0,0,r.width,r.height);break;case"ellipse":var s=e.createElement("canvas"),c=s.getContext("2d"),d=Math.max(a.rx,a.ry),h=2*d;s.width=s.height=h,o=c.createRadialGradient(a.rx,a.ry,0,a.rx,a.ry,d),a.colorStops.forEach(t(o)),c.fillStyle=o,c.fillRect(0,0,h,h),l.fillStyle=a.colorStops[a.colorStops.length-1].color,l.fillRect(0,0,i.width,i.height),l.drawImage(s,a.cx-a.rx,a.cy-a.ry,2*a.rx,2*a.ry)}return i}},r.ListAlpha=function(t){var e,n="";do e=t%26,n=String.fromCharCode(e+64)+n,t/=26;while(26*t>26);return n},r.ListRoman=function(t){var e,n=["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"],r=[1e3,900,500,400,100,90,50,40,10,9,5,4,1],a="",o=n.length;if(0>=t||t>=4e3)return t;for(e=0;o>e;e+=1)for(;t>=r[e];)t-=r[e],a+=n[e];return a}}(),u.Parse=function(r,a){function o(){return Math.max(Math.max(de.body.scrollWidth,de.documentElement.scrollWidth),Math.max(de.body.offsetWidth,de.documentElement.offsetWidth),Math.max(de.body.clientWidth,de.documentElement.clientWidth))}function i(){return Math.max(Math.max(de.body.scrollHeight,de.documentElement.scrollHeight),Math.max(de.body.offsetHeight,de.documentElement.offsetHeight),Math.max(de.body.clientHeight,de.documentElement.clientHeight))}function c(t,e){var n=parseInt(ge(t,e),10);return isNaN(n)?0:n}function d(t,e,n,r,a,o){"transparent"!==o&&(t.setVariable("fillStyle",o),t.fillRect(e,n,r,a),ce+=1)}function h(t,e,r){return t.length>0?e+r.toUpperCase():n}function f(t,e){switch(e){case"lowercase":return t.toLowerCase();case"capitalize":return t.replace(/(^|\s|:|-|\(|\))([a-z])/g,h);case"uppercase":return t.toUpperCase();default:return t}}function p(t){return/^(normal|none|0px)$/.test(t)}function g(t,e,n,r){null!==t&&ue.trimText(t).length>0&&(r.fillText(t,e,n),ce+=1)}function m(t,e,r,a){var o=!1,i=ge(e,"fontWeight"),l=ge(e,"fontFamily"),s=ge(e,"fontSize"),c=ue.parseTextShadows(ge(e,"textShadow"));switch(parseInt(i,10)){case 401:i="bold";break;case 400:i="normal"}return t.setVariable("fillStyle",a),t.setVariable("font",[ge(e,"fontStyle"),ge(e,"fontVariant"),i,s,l].join(" ")),t.setVariable("textAlign",o?"right":"left"),c.length&&(t.setVariable("shadowColor",c[0].color),t.setVariable("shadowOffsetX",c[0].offsetX),t.setVariable("shadowOffsetY",c[0].offsetY),t.setVariable("shadowBlur",c[0].blur)),"none"!==r?ue.Font(l,s,de):n}function y(t,e,n,r,a){switch(e){case"underline":d(t,n.left,Math.round(n.top+r.baseline+r.lineWidth),n.width,1,a);break;case"overline":d(t,n.left,Math.round(n.top),n.width,1,a);break;case"line-through":d(t,n.left,Math.ceil(n.top+r.middle+r.lineWidth),n.width,1,a)}}function b(t,e,n,r,a){var o;if(he.rangeBounds&&!a)("none"!==n||0!==ue.trimText(e).length)&&(o=w(e,t.node,t.textOffset)),t.textOffset+=e.length;else if(t.node&&"string"==typeof t.node.nodeValue){var i=r?t.node.splitText(e.length):null;o=x(t.node,a),t.node=i}return o}function w(t,e,n){var r=de.createRange();return r.setStart(e,n),r.setEnd(e,n+t.length),r.getBoundingClientRect()}function x(t,e){var n=t.parentNode,r=de.createElement("wrapper"),a=t.cloneNode(!0);r.appendChild(t.cloneNode(!0)),n.replaceChild(r,t);var o=e?ue.OffsetBounds(r):ue.Bounds(r);return n.replaceChild(a,r),o}function v(t,e,n){var r,o,i=n.ctx,l=ge(t,"color"),s=ge(t,"textDecoration"),c=ge(t,"textAlign"),d={node:e,textOffset:0};ue.trimText(e.nodeValue).length>0&&(e.nodeValue=f(e.nodeValue,ge(t,"textTransform")),c=c.replace(["-webkit-auto"],["auto"]),o=!a.letterRendering&&/^(left|right|justify|auto)$/.test(c)&&p(ge(t,"letterSpacing"))?e.nodeValue.split(/(\b| )/):e.nodeValue.split(""),r=m(i,t,s,l),a.chinese&&o.forEach(function(t,e){/.*[\u4E00-\u9FA5].*$/.test(t)&&(t=t.split(""),t.unshift(e,1),o.splice.apply(o,t))}),o.forEach(function(t,e){var a=b(d,t,s,o.length-1>e,n.transform.matrix);a&&(g(t,a.left,a.bottom,i),y(i,s,a,r,l))}))}function k(t,e){var n,r,a=de.createElement("boundelement");return a.style.display="inline",n=t.style.listStyleType,t.style.listStyleType="none",a.appendChild(de.createTextNode(e)),t.insertBefore(a,t.firstChild),r=ue.Bounds(a),t.removeChild(a),t.style.listStyleType=n,r}function C(t){var e=-1,n=1,r=t.parentNode.childNodes;if(t.parentNode){for(;r[++e]!==t;)1===r[e].nodeType&&n++;return n}return-1}function T(t,e){var n,r=C(t);switch(e){case"decimal":n=r;break;case"decimal-leading-zero":n=1===(""+r).length?r="0"+(""+r):""+r;break;case"upper-roman":n=u.Generate.ListRoman(r);break;case"lower-roman":n=u.Generate.ListRoman(r).toLowerCase();break;case"lower-alpha":n=u.Generate.ListAlpha(r).toLowerCase();break;case"upper-alpha":n=u.Generate.ListAlpha(r)}return n+". "}function S(t,e,n){var r,a,o,i=e.ctx,l=ge(t,"listStyleType");if(/^(decimal|decimal-leading-zero|upper-alpha|upper-latin|upper-roman|lower-alpha|lower-greek|lower-latin|lower-roman)$/i.test(l)){if(a=T(t,l),o=k(t,a),m(i,t,"none",ge(t,"color")),"inside"!==ge(t,"listStylePosition"))return;i.setVariable("textAlign","left"),r=n.left,g(a,r,o.bottom,i)}}function M(t){var e=r[t];return e&&e.succeeded===!0?e.img:!1}function R(t,e){var n=Math.max(t.left,e.left),r=Math.max(t.top,e.top),a=Math.min(t.left+t.width,e.left+e.width),o=Math.min(t.top+t.height,e.top+e.height);return{left:n,top:r,width:a-n,height:o-r}}function E(t,e,n){var r,a="static"!==e.cssPosition,o=a?ge(t,"zIndex"):"auto",i=ge(t,"opacity"),l="none"!==ge(t,"cssFloat");e.zIndex=r=s(o),r.isPositioned=a,r.isFloated=l,r.opacity=i,r.ownStacking="auto"!==o||1>i,n&&n.zIndex.children.push(e)}function I(t,e,n,r,a){var o=c(e,"paddingLeft"),i=c(e,"paddingTop"),l=c(e,"paddingRight"),s=c(e,"paddingBottom");$(t,n,0,0,n.width,n.height,r.left+o+a[3].width,r.top+i+a[0].width,r.width-(a[1].width+a[3].width+o+l),r.height-(a[0].width+a[2].width+i+s))}function L(t){return["Top","Right","Bottom","Left"].map(function(e){return{width:c(t,"border"+e+"Width"),color:ge(t,"border"+e+"Color")}})}function O(t){return["TopLeft","TopRight","BottomRight","BottomLeft"].map(function(e){return ge(t,"border"+e+"Radius")})}function z(t,e,n,r){var a=function(t,e,n){return{x:t.x+(e.x-t.x)*n,y:t.y+(e.y-t.y)*n}};return{start:t,startControl:e,endControl:n,end:r,subdivide:function(o){var i=a(t,e,o),l=a(e,n,o),s=a(n,r,o),c=a(i,l,o),d=a(l,s,o),u=a(c,d,o);return[z(t,i,c,u),z(u,d,s,r)]},curveTo:function(t){t.push(["bezierCurve",e.x,e.y,n.x,n.y,r.x,r.y])},curveToReversed:function(r){r.push(["bezierCurve",n.x,n.y,e.x,e.y,t.x,t.y])}}}function A(t,e,n,r,a,o,i){e[0]>0||e[1]>0?(t.push(["line",r[0].start.x,r[0].start.y]),r[0].curveTo(t),r[1].curveTo(t)):t.push(["line",o,i]),(n[0]>0||n[1]>0)&&t.push(["line",a[0].start.x,a[0].start.y])}function B(t,e,n,r,a,o,i){var l=[];return e[0]>0||e[1]>0?(l.push(["line",r[1].start.x,r[1].start.y]),r[1].curveTo(l)):l.push(["line",t.c1[0],t.c1[1]]),n[0]>0||n[1]>0?(l.push(["line",o[0].start.x,o[0].start.y]),o[0].curveTo(l),l.push(["line",i[0].end.x,i[0].end.y]),i[0].curveToReversed(l)):(l.push(["line",t.c2[0],t.c2[1]]),l.push(["line",t.c3[0],t.c3[1]])),e[0]>0||e[1]>0?(l.push(["line",a[1].end.x,a[1].end.y]),a[1].curveToReversed(l)):l.push(["line",t.c4[0],t.c4[1]]),l}function U(t,e,n){var r=t.left,a=t.top,o=t.width,i=t.height,l=e[0][0],s=e[0][1],c=e[1][0],d=e[1][1],u=e[2][0],h=e[2][1],f=e[3][0],p=e[3][1],g=o-c,m=i-h,y=o-u,b=i-p;return{topLeftOuter:be(r,a,l,s).topLeft.subdivide(.5),topLeftInner:be(r+n[3].width,a+n[0].width,Math.max(0,l-n[3].width),Math.max(0,s-n[0].width)).topLeft.subdivide(.5),topRightOuter:be(r+g,a,c,d).topRight.subdivide(.5),topRightInner:be(r+Math.min(g,o+n[3].width),a+n[0].width,g>o+n[3].width?0:c-n[3].width,d-n[0].width).topRight.subdivide(.5),bottomRightOuter:be(r+y,a+m,u,h).bottomRight.subdivide(.5),bottomRightInner:be(r+Math.min(y,o+n[3].width),a+Math.min(m,i+n[0].width),Math.max(0,u-n[1].width),Math.max(0,h-n[2].width)).bottomRight.subdivide(.5),bottomLeftOuter:be(r,a+b,f,p).bottomLeft.subdivide(.5),bottomLeftInner:be(r+n[3].width,a+b,Math.max(0,f-n[3].width),Math.max(0,p-n[2].width)).bottomLeft.subdivide(.5)}}function N(t,e,n,r,a){var o=ge(t,"backgroundClip"),i=[];switch(o){case"content-box":case"padding-box":A(i,r[0],r[1],e.topLeftInner,e.topRightInner,a.left+n[3].width,a.top+n[0].width),A(i,r[1],r[2],e.topRightInner,e.bottomRightInner,a.left+a.width-n[1].width,a.top+n[0].width),A(i,r[2],r[3],e.bottomRightInner,e.bottomLeftInner,a.left+a.width-n[1].width,a.top+a.height-n[2].width),A(i,r[3],r[0],e.bottomLeftInner,e.topLeftInner,a.left+n[3].width,a.top+a.height-n[2].width);break;default:A(i,r[0],r[1],e.topLeftOuter,e.topRightOuter,a.left,a.top),A(i,r[1],r[2],e.topRightOuter,e.bottomRightOuter,a.left+a.width,a.top),A(i,r[2],r[3],e.bottomRightOuter,e.bottomLeftOuter,a.left+a.width,a.top+a.height),A(i,r[3],r[0],e.bottomLeftOuter,e.topLeftOuter,a.left,a.top+a.height)}return i}function P(t,e,n){var r,a,o,i,l,s,c=e.left,d=e.top,u=e.width,h=e.height,f=O(t),p=U(e,f,n),g={clip:N(t,p,n,f,e),borders:[]};for(r=0;4>r;r++)if(n[r].width>0){switch(a=c,o=d,i=u,l=h-n[2].width,r){case 0:l=n[0].width,s=B({c1:[a,o],c2:[a+i,o],c3:[a+i-n[1].width,o+l],c4:[a+n[3].width,o+l]},f[0],f[1],p.topLeftOuter,p.topLeftInner,p.topRightOuter,p.topRightInner);break;case 1:a=c+u-n[1].width,i=n[1].width,s=B({c1:[a+i,o],c2:[a+i,o+l+n[2].width],c3:[a,o+l],c4:[a,o+n[0].width]},f[1],f[2],p.topRightOuter,p.topRightInner,p.bottomRightOuter,p.bottomRightInner);break;case 2:o=o+h-n[2].width,l=n[2].width,s=B({c1:[a+i,o+l],c2:[a,o+l],c3:[a+n[3].width,o],c4:[a+i-n[3].width,o]},f[2],f[3],p.bottomRightOuter,p.bottomRightInner,p.bottomLeftOuter,p.bottomLeftInner);break;case 3:i=n[3].width,s=B({c1:[a,o+l+n[2].width],c2:[a,o],c3:[a+i,o+n[0].width],c4:[a+i,o+l]},f[3],f[0],p.bottomLeftOuter,p.bottomLeftInner,p.topLeftOuter,p.topLeftInner)}g.borders.push({args:s,color:n[r].color})}return g}function F(t,e){var n=t.drawShape();return e.forEach(function(t,e){n[0===e?"moveTo":t[0]+"To"].apply(null,t.slice(1))}),n}function V(t,e,n){"transparent"!==n&&(t.setVariable("fillStyle",n),F(t,e),t.fill(),ce+=1)}function D(t,e,n){var r,a,o=de.createElement("valuewrap"),i=["lineHeight","textAlign","fontFamily","color","fontSize","paddingLeft","paddingTop","width","height","border","borderLeftWidth","borderTopWidth"];i.forEach(function(e){try{o.style[e]=ge(t,e)}catch(n){ue.log("html2canvas: Parse: Exception caught in renderFormValue: "+n.message)}}),o.style.borderColor="black",o.style.borderStyle="solid",o.style.display="block",o.style.position="absolute",(/^(submit|reset|button|text|password)$/.test(t.type)||"SELECT"===t.nodeName)&&(o.style.lineHeight=ge(t,"height")),o.style.top=e.top+"px",o.style.left=e.left+"px",r="SELECT"===t.nodeName?(t.options[t.selectedIndex]||0).text:t.value,r||(r=t.placeholder),a=de.createTextNode(r),o.appendChild(a),pe.appendChild(o),v(t,a,n),pe.removeChild(o)}function $(t){t.drawImage.apply(t,Array.prototype.slice.call(arguments,1)),ce+=1}function G(n,r){var a=t.getComputedStyle(n,r);if(a&&a.content&&"none"!==a.content&&"-moz-alt-content"!==a.content&&"none"!==a.display){var o=a.content+"",i=o.substr(0,1);i===o.substr(o.length-1)&&i.match(/'|"/)&&(o=o.substr(1,o.length-2));var l="url"===o.substr(0,3),s=e.createElement(l?"img":"span");return s.className=me+"-before "+me+"-after",Object.keys(a).filter(W).forEach(function(t){try{s.style[t]=a[t]}catch(e){ue.log(["Tried to assign readonly property ",t,"Error:",e])}}),l?s.src=ue.parseBackgroundImage(o)[0].args[0]:s.innerHTML=o,s}}function W(e){return isNaN(t.parseInt(e,10))}function H(t,e){var n=G(t,":before"),r=G(t,":after");(n||r)&&(n&&(t.className+=" "+me+"-before",t.parentNode.insertBefore(n,t),oe(n,e,!0),t.parentNode.removeChild(n),t.className=t.className.replace(me+"-before","").trim()),r&&(t.className+=" "+me+"-after",t.appendChild(r),oe(r,e,!0),t.removeChild(r),t.className=t.className.replace(me+"-after","").trim()))}function j(t,e,n,r){var a=Math.round(r.left+n.left),o=Math.round(r.top+n.top);t.createPattern(e),t.translate(a,o),t.fill(),t.translate(-a,-o)}function q(t,e,n,r,a,o,i,l){var s=[];s.push(["line",Math.round(a),Math.round(o)]),s.push(["line",Math.round(a+i),Math.round(o)]),s.push(["line",Math.round(a+i),Math.round(l+o)]),s.push(["line",Math.round(a),Math.round(l+o)]),F(t,s),t.save(),t.clip(),j(t,e,n,r),t.restore()}function X(t,e,n){d(t,e.left,e.top,e.width,e.height,n)}function _(t,e,n,r,a){var o=ue.BackgroundSize(t,e,r,a),i=ue.BackgroundPosition(t,e,r,a,o),l=ge(t,"backgroundRepeat").split(",").map(ue.trimText);switch(r=Q(r,o),l=l[a]||l[0]){case"repeat-x":q(n,r,i,e,e.left,e.top+i.top,99999,r.height);break;case"repeat-y":q(n,r,i,e,e.left+i.left,e.top,r.width,99999);break;case"no-repeat":q(n,r,i,e,e.left+i.left,e.top+i.top,r.width,r.height);break;default:j(n,r,i,{top:e.top,left:e.left,width:r.width,height:r.height})}}function Y(t,e,n){for(var r,a=ge(t,"backgroundImage"),o=ue.parseBackgroundImage(a),i=o.length;i--;)if(a=o[i],a.args&&0!==a.args.length){var l="url"===a.method?a.args[0]:a.value;r=M(l),r?_(t,e,n,r,i):ue.log("html2canvas: Error loading background:",a)}}function Q(t,e){if(t.width===e.width&&t.height===e.height)return t;var n,r=de.createElement("canvas");return r.width=e.width,r.height=e.height,n=r.getContext("2d"),$(n,t,0,0,t.width,t.height,0,0,e.width,e.height),r}function J(t,e,n){return t.setVariable("globalAlpha",ge(e,"opacity")*(n?n.opacity:1))}function K(t){return t.replace("px","")}function Z(t){var e=ge(t,"transform")||ge(t,"-webkit-transform")||ge(t,"-moz-transform")||ge(t,"-ms-transform")||ge(t,"-o-transform"),n=ge(t,"transform-origin")||ge(t,"-webkit-transform-origin")||ge(t,"-moz-transform-origin")||ge(t,"-ms-transform-origin")||ge(t,"-o-transform-origin")||"0px 0px";n=n.split(" ").map(K).map(ue.asFloat);var r;if(e&&"none"!==e){var a=e.match(we);if(a)switch(a[1]){case"matrix":r=a[2].split(",").map(ue.trimText).map(ue.asFloat)}}return{origin:n,matrix:r}}function te(t,e,n,r){var s=l(e?n.width:o(),e?n.height:i()),c={ctx:s,opacity:J(s,t,e),cssPosition:ge(t,"position"),borders:L(t),transform:r,clip:e&&e.clip?ue.Extend({},e.clip):null};return E(t,c,e),a.useOverflow===!0&&/(hidden|scroll|auto)/.test(ge(t,"overflow"))===!0&&/(BODY)/i.test(t.nodeName)===!1&&(c.clip=c.clip?R(c.clip,n):n),c}function ee(t,e,n){var r={left:e.left+t[3].width,top:e.top+t[0].width,width:e.width-(t[1].width+t[3].width),height:e.height-(t[0].width+t[2].width)};return n&&(r=R(r,n)),r}function ne(t,e){var n=e.matrix?ue.OffsetBounds(t):ue.Bounds(t);return e.origin[0]+=n.left,e.origin[1]+=n.top,n}function re(t,e,n,r){var a,o=Z(t,e),i=ne(t,o),l=te(t,e,i,o),s=l.borders,c=l.ctx,d=ee(s,i,l.clip),u=P(t,i,s),h=fe.test(t.nodeName)?"#efefef":ge(t,"backgroundColor");switch(F(c,u.clip),c.save(),c.clip(),d.height>0&&d.width>0&&!r?(X(c,i,h),Y(t,d,c)):r&&(l.backgroundColor=h),c.restore(),u.borders.forEach(function(t){V(c,t.args,t.color)}),n||H(t,l),t.nodeName){case"IMG":(a=M(t.getAttribute("src")))?I(c,t,a,i,s):ue.log("html2canvas: Error loading
:"+t.getAttribute("src"));break;case"INPUT":/^(text|url|email|submit|button|reset)$/.test(t.type)&&(t.value||t.placeholder||"").length>0&&D(t,i,l);break;case"TEXTAREA":(t.value||t.placeholder||"").length>0&&D(t,i,l);break;case"SELECT":(t.options||t.placeholder||"").length>0&&D(t,i,l);break;case"LI":S(t,l,d);break;case"CANVAS":I(c,t,t,i,s)}return l}function ae(t){return"none"!==ge(t,"display")&&"hidden"!==ge(t,"visibility")&&!t.hasAttribute("data-html2canvas-ignore")}function oe(t,e,n){ae(t)&&(e=re(t,e,n,!1)||e,fe.test(t.nodeName)||ie(t,e,n))}function ie(t,e,n){ue.Children(t).forEach(function(r){r.nodeType===r.ELEMENT_NODE?oe(r,e,n):r.nodeType===r.TEXT_NODE&&v(t,r,e)})}function le(){var t=ge(e.documentElement,"backgroundColor"),n=ue.isTransparent(t)&&se===e.body,r=re(se,null,!1,n);return ie(se,r),n&&(t=r.backgroundColor),pe.removeChild(ye),{backgroundColor:t,stack:r}}t.scroll(0,0);var se=a.elements===n?e.body:a.elements[0],ce=0,de=se.ownerDocument,ue=u.Util,he=ue.Support(a,de),fe=RegExp("("+a.ignoreElements+")"),pe=de.body,ge=ue.getCSS,me="___html2canvas___pseudoelement",ye=de.createElement("style");ye.innerHTML="."+me+'-before:before { content: "" !important; display: none !important; }'+"."+me+'-after:after { content: "" !important; display: none !important; }',pe.appendChild(ye),r=r||{};var be=function(t){return function(e,n,r,a){var o=r*t,i=a*t,l=e+r,s=n+a;return{topLeft:z({x:e,y:s},{x:e,y:s-i},{x:l-o,y:n},{x:l,y:n}),topRight:z({x:e,y:n},{x:e+o,y:n},{x:l,y:s-i},{x:l,y:s}),bottomRight:z({x:l,y:n},{x:l,y:n+i},{x:e+o,y:s},{x:e,y:s}),bottomLeft:z({x:l,y:s},{x:l-o,y:s},{x:e,y:n+i},{x:e,y:n})}}}(4*((Math.sqrt(2)-1)/3)),we=/(matrix)\((.+)\)/;return le()},u.Preload=function(r){function a(t){M.href=t,M.href=M.href;var e=M.protocol+M.host;return e===g}function o(){x.log("html2canvas: start: images: "+w.numLoaded+" / "+w.numTotal+" (failed: "+w.numFailed+")"),!w.firstRun&&w.numLoaded>=w.numTotal&&(x.log("Finished loading images: # "+w.numTotal+" (failed: "+w.numFailed+")"),"function"==typeof r.complete&&r.complete(w))}function i(e,a,i){var l,s,c=r.proxy;M.href=e,e=M.href,l="html2canvas_"+v++,i.callbackname=l,c+=c.indexOf("?")>-1?"&":"?",c+="url="+encodeURIComponent(e)+"&callback="+l,s=C.createElement("script"),t[l]=function(e){"error:"===e.substring(0,6)?(i.succeeded=!1,w.numLoaded++,w.numFailed++,o()):(p(a,i),a.src=e),t[l]=n;try{delete t[l]}catch(r){}s.parentNode.removeChild(s),s=null,delete i.script,delete i.callbackname},s.setAttribute("type","text/javascript"),s.setAttribute("src",c),i.script=s,t.document.body.appendChild(s)}function l(e,n){var r=t.getComputedStyle(e,n),a=r.content;"url"===a.substr(0,3)&&m.loadImage(u.Util.parseBackgroundImage(a)[0].args[0]),h(r.backgroundImage,e)}function s(t){l(t,":before"),l(t,":after")}function c(t,e){var r=u.Generate.Gradient(t,e);r!==n&&(w[t]={img:r,succeeded:!0},w.numTotal++,w.numLoaded++,o())}function d(t){return t&&t.method&&t.args&&t.args.length>0}function h(t,e){var r;u.Util.parseBackgroundImage(t).filter(d).forEach(function(t){"url"===t.method?m.loadImage(t.args[0]):t.method.match(/\-?gradient$/)&&(r===n&&(r=u.Util.Bounds(e)),c(t.value,r))})}function f(t){var e=!1;try{x.Children(t).forEach(f)}catch(r){}try{e=t.nodeType}catch(a){e=!1,x.log("html2canvas: failed to access some element's nodeType - Exception: "+a.message)}if(1===e||e===n){s(t);try{h(x.getCSS(t,"backgroundImage"),t)}catch(r){x.log("html2canvas: failed to get background-image - Exception: "+r.message)}h(t)}}function p(e,a){e.onload=function(){a.timer!==n&&t.clearTimeout(a.timer),w.numLoaded++,a.succeeded=!0,e.onerror=e.onload=null,o()},e.onerror=function(){if("anonymous"===e.crossOrigin&&(t.clearTimeout(a.timer),r.proxy)){var l=e.src;return e=new Image,a.img=e,e.src=l,i(e.src,e,a),n}w.numLoaded++,w.numFailed++,a.succeeded=!1,e.onerror=e.onload=null,o()}}var g,m,y,b,w={numLoaded:0,numFailed:0,numTotal:0,cleanupDone:!1},x=u.Util,v=0,k=r.elements[0]||e.body,C=k.ownerDocument,T=k.getElementsByTagName("img"),S=T.length,M=C.createElement("a"),R=function(t){return t.crossOrigin!==n}(new Image);for(M.href=t.location.href,g=M.protocol+M.host,m={loadImage:function(t){var e,o;t&&w[t]===n&&(e=new Image,t.match(/data:image\/.*;base64,/i)?(e.src=t.replace(/url\(['"]{0,}|['"]{0,}\)$/gi,""),o=w[t]={img:e},w.numTotal++,p(e,o)):a(t)||r.allowTaint===!0?(o=w[t]={img:e},w.numTotal++,p(e,o),e.src=t):R&&!r.allowTaint&&r.useCORS?(e.crossOrigin="anonymous",o=w[t]={img:e},w.numTotal++,p(e,o),e.src=t):r.proxy&&(o=w[t]={img:e},w.numTotal++,i(t,e,o)))},cleanupDOM:function(a){var i,l;if(!w.cleanupDone){a&&"string"==typeof a?x.log("html2canvas: Cleanup because: "+a):x.log("html2canvas: Cleanup after timeout: "+r.timeout+" ms.");for(l in w)if(w.hasOwnProperty(l)&&(i=w[l],"object"==typeof i&&i.callbackname&&i.succeeded===n)){t[i.callbackname]=n;try{delete t[i.callbackname]}catch(s){}i.script&&i.script.parentNode&&(i.script.setAttribute("src","about:blank"),i.script.parentNode.removeChild(i.script)),w.numLoaded++,w.numFailed++,x.log("html2canvas: Cleaned up failed img: '"+l+"' Steps: "+w.numLoaded+" / "+w.numTotal)}t.stop!==n?t.stop():e.execCommand!==n&&e.execCommand("Stop",!1),e.close!==n&&e.close(),w.cleanupDone=!0,a&&"string"==typeof a||o()}},renderingDone:function(){b&&t.clearTimeout(b)}},r.timeout>0&&(b=t.setTimeout(m.cleanupDOM,r.timeout)),x.log("html2canvas: Preload starts: finding background-images"),w.firstRun=!0,f(k),x.log("html2canvas: Preload: Finding images"),y=0;S>y;y+=1)m.loadImage(T[y].getAttribute("src"));return w.firstRun=!1,x.log("html2canvas: Preload: Done."),w.numTotal===w.numLoaded&&o(),m},u.Renderer=function(t,r){function a(t){function e(t){Object.keys(t).sort().forEach(function(n){var r=[],o=[],i=[],l=[];
-t[n].forEach(function(t){t.node.zIndex.isPositioned||1>t.node.zIndex.opacity?i.push(t):t.node.zIndex.isFloated?o.push(t):r.push(t)}),function s(t){t.forEach(function(t){l.push(t),t.children&&s(t.children)})}(r.concat(o,i)),l.forEach(function(t){t.context?e(t.context):a.push(t.node)})})}var r,a=[];return r=function(t){function e(t,r,a){var o="auto"===r.zIndex.zindex?0:Number(r.zIndex.zindex),i=t,l=r.zIndex.isPositioned,s=r.zIndex.isFloated,c={node:r},d=a;r.zIndex.ownStacking?(i=c.context={"!":[{node:r,children:[]}]},d=n):(l||s)&&(d=c.children=[]),0===o&&a?a.push(c):(t[o]||(t[o]=[]),t[o].push(c)),r.zIndex.children.forEach(function(t){e(i,t,d)})}var r={};return e(r,t),r}(t),e(r),a}function o(t){var e;if("string"==typeof r.renderer&&u.Renderer[t]!==n)e=u.Renderer[t](r);else{if("function"!=typeof t)throw Error("Unknown renderer");e=t(r)}if("function"!=typeof e)throw Error("Invalid renderer defined");return e}return o(r.renderer)(t,r,e,a(t.stack),u)},u.Util.Support=function(t,e){function r(){var t=new Image,r=e.createElement("canvas"),a=r.getContext===n?!1:r.getContext("2d");if(a===!1)return!1;r.width=r.height=10,t.src=["data:image/svg+xml,",""].join("");try{a.drawImage(t,0,0),r.toDataURL()}catch(o){return!1}return u.Util.log("html2canvas: Parse: SVG powered rendering available"),!0}function a(){var t,n,r,a,o=!1;return e.createRange&&(t=e.createRange(),t.getBoundingClientRect&&(n=e.createElement("boundtest"),n.style.height="123px",n.style.display="block",e.body.appendChild(n),t.selectNode(n),r=t.getBoundingClientRect(),a=r.height,123===a&&(o=!0),e.body.removeChild(n))),o}return{rangeBounds:a(),svgRendering:t.svgRendering&&r()}},t.html2canvas=function(e,n){e=e.length?e:[e];var r,a,o={logging:!1,elements:e,background:"#fff",proxy:null,timeout:0,useCORS:!1,allowTaint:!1,svgRendering:!1,ignoreElements:"IFRAME|OBJECT|PARAM",useOverflow:!0,letterRendering:!1,chinese:!1,width:null,height:null,taintTest:!0,renderer:"Canvas"};return o=u.Util.Extend(n,o),u.logging=o.logging,o.complete=function(t){("function"!=typeof o.onpreloaded||o.onpreloaded(t)!==!1)&&(r=u.Parse(t,o),("function"!=typeof o.onparsed||o.onparsed(r)!==!1)&&(a=u.Renderer(r,o),"function"==typeof o.onrendered&&o.onrendered(a)))},t.setTimeout(function(){u.Preload(o)},0),{render:function(t,e){return u.Renderer(t,u.Util.Extend(e,o))},parse:function(t,e){return u.Parse(t,u.Util.Extend(e,o))},preload:function(t){return u.Preload(u.Util.Extend(t,o))},log:u.Util.log}},t.html2canvas.log=u.Util.log,t.html2canvas.Renderer={Canvas:n},u.Renderer.Canvas=function(t){function r(t,e){t.beginPath(),e.forEach(function(e){t[e.name].apply(t,e.arguments)}),t.closePath()}function a(t){if(-1===l.indexOf(t.arguments[0].src)){c.drawImage(t.arguments[0],0,0);try{c.getImageData(0,0,1,1)}catch(e){return s=i.createElement("canvas"),c=s.getContext("2d"),!1}l.push(t.arguments[0].src)}return!0}function o(e,n){switch(n.type){case"variable":e[n.name]=n.arguments;break;case"function":switch(n.name){case"createPattern":if(n.arguments[0].width>0&&n.arguments[0].height>0)try{e.fillStyle=e.createPattern(n.arguments[0],"repeat")}catch(o){d.log("html2canvas: Renderer: Error creating pattern",o.message)}break;case"drawShape":r(e,n.arguments);break;case"drawImage":n.arguments[8]>0&&n.arguments[7]>0&&(!t.taintTest||t.taintTest&&a(n))&&e.drawImage.apply(e,n.arguments);break;default:e[n.name].apply(e,n.arguments)}}}t=t||{};var i=e,l=[],s=e.createElement("canvas"),c=s.getContext("2d"),d=u.Util,h=t.canvas||i.createElement("canvas");return function(t,e,r,a,i){var l,s,c,u=h.getContext("2d"),f=t.stack;return h.width=h.style.width=e.width||f.ctx.width,h.height=h.style.height=e.height||f.ctx.height,c=u.fillStyle,u.fillStyle=d.isTransparent(f.backgroundColor)&&e.background!==n?e.background:t.backgroundColor,u.fillRect(0,0,h.width,h.height),u.fillStyle=c,a.forEach(function(t){u.textBaseline="bottom",u.save(),t.transform.matrix&&(u.translate(t.transform.origin[0],t.transform.origin[1]),u.transform.apply(u,t.transform.matrix),u.translate(-t.transform.origin[0],-t.transform.origin[1])),t.clip&&(u.beginPath(),u.rect(t.clip.left,t.clip.top,t.clip.width,t.clip.height),u.clip()),t.ctx.storage&&t.ctx.storage.forEach(function(t){o(u,t)}),u.restore()}),d.log("html2canvas: Renderer: Canvas renderer done - returning canvas obj"),1===e.elements.length&&"object"==typeof e.elements[0]&&"BODY"!==e.elements[0].nodeName?(s=i.Util.Bounds(e.elements[0]),l=r.createElement("canvas"),l.width=Math.ceil(s.width),l.height=Math.ceil(s.height),u=l.getContext("2d"),u.drawImage(h,s.left,s.top,s.width,s.height,0,0,s.width,s.height),h=null,l):h}}})(window,document);
\ No newline at end of file
+!function(a,b,c){"use strict";function d(a,b,c){var d,e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;return!/^-?[0-9]+\.?[0-9]*(?:px)?$/i.test(c)&&/^-?\d/.test(c)&&(d=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left="fontSize"===b?"1em":c||0,c=f.pixelLeft+"px",f.left=d,e&&(a.runtimeStyle.left=e)),/^(thin|medium|thick)$/i.test(c)?c:Math.round(parseFloat(c))+"px"}function e(a){return parseInt(a,10)}function f(a,b,e,f){if(a=(a||"").split(","),a=a[f||0]||a[0]||"auto",a=k.Util.trimText(a).split(" "),"backgroundSize"!==e||a[0]&&!a[0].match(/cover|contain|auto/)){if(a[0]=-1===a[0].indexOf("%")?d(b,e+"X",a[0]):a[0],a[1]===c){if("backgroundSize"===e)return a[1]="auto",a;a[1]=a[0]}a[1]=-1===a[1].indexOf("%")?d(b,e+"Y",a[1]):a[1]}else;return a}function g(a,b,c,d,e,f){var g,h,i,j,l=k.Util.getCSS(b,a,e);if(1===l.length&&(j=l[0],l=[],l[0]=j,l[1]=j),-1!==l[0].toString().indexOf("%"))i=parseFloat(l[0])/100,h=c.width*i,"backgroundSize"!==a&&(h-=(f||d).width*i);else if("backgroundSize"===a)if("auto"===l[0])h=d.width;else if(/contain|cover/.test(l[0])){var m=k.Util.resizeBounds(d.width,d.height,c.width,c.height,l[0]);h=m.width,g=m.height}else h=parseInt(l[0],10);else h=parseInt(l[0],10);return"auto"===l[1]?g=h/d.width*d.height:-1!==l[1].toString().indexOf("%")?(i=parseFloat(l[1])/100,g=c.height*i,"backgroundSize"!==a&&(g-=(f||d).height*i)):g=parseInt(l[1],10),[h,g]}function h(a,b){var c=[];return{storage:c,width:a,height:b,clip:function(){c.push({type:"function",name:"clip",arguments:arguments})},translate:function(){c.push({type:"function",name:"translate",arguments:arguments})},fill:function(){c.push({type:"function",name:"fill",arguments:arguments})},save:function(){c.push({type:"function",name:"save",arguments:arguments})},restore:function(){c.push({type:"function",name:"restore",arguments:arguments})},fillRect:function(){c.push({type:"function",name:"fillRect",arguments:arguments})},createPattern:function(){c.push({type:"function",name:"createPattern",arguments:arguments})},drawShape:function(){var a=[];return c.push({type:"function",name:"drawShape",arguments:a}),{moveTo:function(){a.push({name:"moveTo",arguments:arguments})},lineTo:function(){a.push({name:"lineTo",arguments:arguments})},arcTo:function(){a.push({name:"arcTo",arguments:arguments})},bezierCurveTo:function(){a.push({name:"bezierCurveTo",arguments:arguments})},quadraticCurveTo:function(){a.push({name:"quadraticCurveTo",arguments:arguments})}}},drawImage:function(){c.push({type:"function",name:"drawImage",arguments:arguments})},fillText:function(){c.push({type:"function",name:"fillText",arguments:arguments})},setVariable:function(a,b){return c.push({type:"variable",name:a,arguments:b}),b}}}var i,j,k={};k.Util={},k.Util.log=function(b){k.logging&&a.console&&a.console.log&&a.console.log(b)},k.Util.trimText=function(a){return function(b){return a?a.apply(b):((b||"")+"").replace(/^\s+|\s+$/g,"")}}(String.prototype.trim),k.Util.asFloat=function(a){return parseFloat(a)},function(){var a=/((rgba|rgb)\([^\)]+\)(\s-?\d+px){0,})/g,b=/(-?\d+px)|(#.+)|(rgb\(.+\))|(rgba\(.+\))/g;k.Util.parseTextShadows=function(c){if(!c||"none"===c)return[];for(var d=c.match(a),e=[],f=0;d&&f0&&(d=b.substr(0,e),b=b.substr(e)),k.push({prefix:d,method:b.toLowerCase(),value:f,args:i})),i=[],b=d=c=f=""};n();for(var o=0,p=a.length;p>o;o++)if(g=a[o],!(0===l&&j.indexOf(g)>-1)){switch(g){case'"':h?h===g&&(h=null):h=g;break;case"(":if(h)break;if(0===l){l=1,f+=g;continue}m++;break;case")":if(h)break;if(1===l){if(0===m){l=0,f+=g,n();continue}m--}break;case",":if(h)break;if(0===l){n();continue}if(1===l&&0===m&&!b.match(/^url$/i)){i.push(c),c="",f+=g;continue}}f+=g,0===l?b+=g:c+=g}return n(),k},k.Util.Bounds=function(a){var b,c={};return a.getBoundingClientRect&&(b=a.getBoundingClientRect(),c.top=b.top,c.bottom=b.bottom||b.top+b.height,c.left=b.left,c.width=a.offsetWidth,c.height=a.offsetHeight),c},k.Util.OffsetBounds=function(a){var b=a.offsetParent?k.Util.OffsetBounds(a.offsetParent):{top:0,left:0};return{top:a.offsetTop+b.top,bottom:a.offsetTop+a.offsetHeight+b.top,left:a.offsetLeft+b.left,width:a.offsetWidth,height:a.offsetHeight}},k.Util.getCSS=function(a,c,d){i!==a&&(j=b.defaultView.getComputedStyle(a,null));var g=j[c];if(/^background(Size|Position)$/.test(c))return f(g,a,c,d);if(/border(Top|Bottom)(Left|Right)Radius/.test(c)){var h=g.split(" ");return h.length<=1&&(h[1]=h[0]),h.map(e)}return g},k.Util.resizeBounds=function(a,b,c,d,e){var f,g,h=c/d,i=a/b;return e&&"auto"!==e?i>h^"contain"===e?(g=d,f=d*i):(f=c,g=c/i):(f=c,g=d),{width:f,height:g}},k.Util.BackgroundPosition=function(a,b,c,d,e){var f=g("backgroundPosition",a,b,c,d,e);return{left:f[0],top:f[1]}},k.Util.BackgroundSize=function(a,b,c,d){var e=g("backgroundSize",a,b,c,d);return{width:e[0],height:e[1]}},k.Util.Extend=function(a,b){for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b},k.Util.Children=function(a){var b;try{b=a.nodeName&&"IFRAME"===a.nodeName.toUpperCase()?a.contentDocument||a.contentWindow.document:function(a){var b=[];return null!==a&&!function(a,b){var d=a.length,e=0;if("number"==typeof b.length)for(var f=b.length;f>e;e++)a[d++]=b[e];else for(;b[e]!==c;)a[d++]=b[e++];return a.length=d,a}(b,a),b}(a.childNodes)}catch(d){k.Util.log("html2canvas.Util.Children failed with exception: "+d.message),b=[]}return b},k.Util.isTransparent=function(a){return"transparent"===a||"rgba(0, 0, 0, 0)"===a},k.Util.Font=function(){var a={};return function(b,d,e){if(a[b+"-"+d]!==c)return a[b+"-"+d];var f,g,h,i=e.createElement("div"),j=e.createElement("img"),k=e.createElement("span"),l="Hidden Text";return i.style.visibility="hidden",i.style.fontFamily=b,i.style.fontSize=d,i.style.margin=0,i.style.padding=0,e.body.appendChild(i),j.src="data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBADs=",j.width=1,j.height=1,j.style.margin=0,j.style.padding=0,j.style.verticalAlign="baseline",k.style.fontFamily=b,k.style.fontSize=d,k.style.margin=0,k.style.padding=0,k.appendChild(e.createTextNode(l)),i.appendChild(k),i.appendChild(j),f=j.offsetTop-k.offsetTop+1,i.removeChild(k),i.appendChild(e.createTextNode(l)),i.style.lineHeight="normal",j.style.verticalAlign="super",g=j.offsetTop-i.offsetTop+1,h={baseline:f,lineWidth:1,middle:g},a[b+"-"+d]=h,e.body.removeChild(i),h}}(),function(){function a(a){return function(b){try{a.addColorStop(b.stop,b.color)}catch(d){c.log(["failed to add color stop: ",d,"; tried to add: ",b])}}}var c=k.Util,d={};k.Generate=d;var e=[/^(-webkit-linear-gradient)\(([a-z\s]+)([\w\d\.\s,%\(\)]+)\)$/,/^(-o-linear-gradient)\(([a-z\s]+)([\w\d\.\s,%\(\)]+)\)$/,/^(-webkit-gradient)\((linear|radial),\s((?:\d{1,3}%?)\s(?:\d{1,3}%?),\s(?:\d{1,3}%?)\s(?:\d{1,3}%?))([\w\d\.\s,%\(\)\-]+)\)$/,/^(-moz-linear-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?))([\w\d\.\s,%\(\)]+)\)$/,/^(-webkit-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s([a-z\-]+)([\w\d\.\s,%\(\)]+)\)$/,/^(-moz-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s?([a-z\-]*)([\w\d\.\s,%\(\)]+)\)$/,/^(-o-radial-gradient)\(((?:\d{1,3}%?)\s(?:\d{1,3}%?)),\s(\w+)\s([a-z\-]+)([\w\d\.\s,%\(\)]+)\)$/];d.parseGradient=function(a,b){var c,d,f,g,h,i,j,k,l,m,n,o,p=e.length;for(d=0;p>d&&!(f=a.match(e[d]));d+=1);if(f)switch(f[1]){case"-webkit-linear-gradient":case"-o-linear-gradient":if(c={type:"linear",x0:null,y0:null,x1:null,y1:null,colorStops:[]},h=f[2].match(/\w+/g))for(i=h.length,d=0;i>d;d+=1)switch(h[d]){case"top":c.y0=0,c.y1=b.height;break;case"right":c.x0=b.width,c.x1=0;break;case"bottom":c.y0=b.height,c.y1=0;break;case"left":c.x0=0,c.x1=b.width}if(null===c.x0&&null===c.x1&&(c.x0=c.x1=b.width/2),null===c.y0&&null===c.y1&&(c.y0=c.y1=b.height/2),h=f[3].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}(?:%|px))?)+/g))for(i=h.length,j=1/Math.max(i-1,1),d=0;i>d;d+=1)k=h[d].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/),k[2]?(g=parseFloat(k[2]),g/="%"===k[3]?100:b.width):g=d*j,c.colorStops.push({color:k[1],stop:g});break;case"-webkit-gradient":if(c={type:"radial"===f[2]?"circle":f[2],x0:0,y0:0,x1:0,y1:0,colorStops:[]},h=f[3].match(/(\d{1,3})%?\s(\d{1,3})%?,\s(\d{1,3})%?\s(\d{1,3})%?/),h&&(c.x0=h[1]*b.width/100,c.y0=h[2]*b.height/100,c.x1=h[3]*b.width/100,c.y1=h[4]*b.height/100),h=f[4].match(/((?:from|to|color-stop)\((?:[0-9\.]+,\s)?(?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)\))+/g))for(i=h.length,d=0;i>d;d+=1)k=h[d].match(/(from|to|color-stop)\(([0-9\.]+)?(?:,\s)?((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\)/),g=parseFloat(k[2]),"from"===k[1]&&(g=0),"to"===k[1]&&(g=1),c.colorStops.push({color:k[3],stop:g});break;case"-moz-linear-gradient":if(c={type:"linear",x0:0,y0:0,x1:0,y1:0,colorStops:[]},h=f[2].match(/(\d{1,3})%?\s(\d{1,3})%?/),h&&(c.x0=h[1]*b.width/100,c.y0=h[2]*b.height/100,c.x1=b.width-c.x0,c.y1=b.height-c.y0),h=f[3].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}%)?)+/g))for(i=h.length,j=1/Math.max(i-1,1),d=0;i>d;d+=1)k=h[d].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%)?/),k[2]?(g=parseFloat(k[2]),k[3]&&(g/=100)):g=d*j,c.colorStops.push({color:k[1],stop:g});break;case"-webkit-radial-gradient":case"-moz-radial-gradient":case"-o-radial-gradient":if(c={type:"circle",x0:0,y0:0,x1:b.width,y1:b.height,cx:0,cy:0,rx:0,ry:0,colorStops:[]},h=f[2].match(/(\d{1,3})%?\s(\d{1,3})%?/),h&&(c.cx=h[1]*b.width/100,c.cy=h[2]*b.height/100),h=f[3].match(/\w+/),k=f[4].match(/[a-z\-]*/),h&&k)switch(k[0]){case"farthest-corner":case"cover":case"":l=Math.sqrt(Math.pow(c.cx,2)+Math.pow(c.cy,2)),m=Math.sqrt(Math.pow(c.cx,2)+Math.pow(c.y1-c.cy,2)),n=Math.sqrt(Math.pow(c.x1-c.cx,2)+Math.pow(c.y1-c.cy,2)),o=Math.sqrt(Math.pow(c.x1-c.cx,2)+Math.pow(c.cy,2)),c.rx=c.ry=Math.max(l,m,n,o);break;case"closest-corner":l=Math.sqrt(Math.pow(c.cx,2)+Math.pow(c.cy,2)),m=Math.sqrt(Math.pow(c.cx,2)+Math.pow(c.y1-c.cy,2)),n=Math.sqrt(Math.pow(c.x1-c.cx,2)+Math.pow(c.y1-c.cy,2)),o=Math.sqrt(Math.pow(c.x1-c.cx,2)+Math.pow(c.cy,2)),c.rx=c.ry=Math.min(l,m,n,o);break;case"farthest-side":"circle"===h[0]?c.rx=c.ry=Math.max(c.cx,c.cy,c.x1-c.cx,c.y1-c.cy):(c.type=h[0],c.rx=Math.max(c.cx,c.x1-c.cx),c.ry=Math.max(c.cy,c.y1-c.cy));break;case"closest-side":case"contain":"circle"===h[0]?c.rx=c.ry=Math.min(c.cx,c.cy,c.x1-c.cx,c.y1-c.cy):(c.type=h[0],c.rx=Math.min(c.cx,c.x1-c.cx),c.ry=Math.min(c.cy,c.y1-c.cy))}if(h=f[5].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\)(?:\s\d{1,3}(?:%|px))?)+/g))for(i=h.length,j=1/Math.max(i-1,1),d=0;i>d;d+=1)k=h[d].match(/((?:rgb|rgba)\(\d{1,3},\s\d{1,3},\s\d{1,3}(?:,\s[0-9\.]+)?\))\s*(\d{1,3})?(%|px)?/),k[2]?(g=parseFloat(k[2]),g/="%"===k[3]?100:b.width):g=d*j,c.colorStops.push({color:k[1],stop:g})}return c},d.Gradient=function(c,d){if(0!==d.width&&0!==d.height){var e,f,g=b.createElement("canvas"),h=g.getContext("2d");if(g.width=d.width,g.height=d.height,e=k.Generate.parseGradient(c,d))switch(e.type){case"linear":f=h.createLinearGradient(e.x0,e.y0,e.x1,e.y1),e.colorStops.forEach(a(f)),h.fillStyle=f,h.fillRect(0,0,d.width,d.height);break;case"circle":f=h.createRadialGradient(e.cx,e.cy,0,e.cx,e.cy,e.rx),e.colorStops.forEach(a(f)),h.fillStyle=f,h.fillRect(0,0,d.width,d.height);break;case"ellipse":var i=b.createElement("canvas"),j=i.getContext("2d"),l=Math.max(e.rx,e.ry),m=2*l;i.width=i.height=m,f=j.createRadialGradient(e.rx,e.ry,0,e.rx,e.ry,l),e.colorStops.forEach(a(f)),j.fillStyle=f,j.fillRect(0,0,m,m),h.fillStyle=e.colorStops[e.colorStops.length-1].color,h.fillRect(0,0,g.width,g.height),h.drawImage(i,e.cx-e.rx,e.cy-e.ry,2*e.rx,2*e.ry)}return g}},d.ListAlpha=function(a){var b,c="";do b=a%26,c=String.fromCharCode(b+64)+c,a/=26;while(26*a>26);return c},d.ListRoman=function(a){var b,c=["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"],d=[1e3,900,500,400,100,90,50,40,10,9,5,4,1],e="",f=c.length;if(0>=a||a>=4e3)return a;for(b=0;f>b;b+=1)for(;a>=d[b];)a-=d[b],e+=c[b];return e}}(),k.Parse=function(d,e,f){function g(){var a=ub(b.documentElement,"backgroundColor"),c=qb.isTransparent(a)&&nb===b.body,d=jb(nb,null,!1,c);i(nb),mb(nb,d,function(){c&&(a=d.backgroundColor),j(),qb.log("Done parsing, moving to Render."),f({backgroundColor:a,stack:d})})}function i(a){function c(){for(var a=/:before|:after/,c=b.styleSheets,d=0,e=c.length;e>d;d++)try{for(var f=c[d].cssRules,g=0,i=f.length;i>g;g++)a.test(f[g].selectorText)&&h.push(f[g].selectorText)}catch(j){}for(d=0,e=h.length;e>d;d++)h[d]=h[d].match(/(^[^:]*)/)[1]}function d(){for(var a=b.querySelectorAll(h.join(",")),c=0,d=a.length;d>c;c++)e(a[c])}function e(a){var b=X(a,":before"),c=X(a,":after");b&&g.push({type:"before",pseudo:b,el:a}),c&&g.push({type:"after",pseudo:c,el:a})}function f(){g.forEach(function(a){l(a.el,vb+"-parent")}),g.forEach(function(a){"before"===a.type?a.el.insertBefore(a.pseudo,a.el.firstChild):a.el.appendChild(a.pseudo)})}var g=[],h=[];c(),d(a),f()}function j(){tb.removeChild(wb);for(var a=b.getElementsByClassName(vb+"-element");a.length;)a[0].parentNode.removeChild(a[0]);for(var c=b.getElementsByClassName(vb+"-parent");c.length;)m(c[0],vb+"-parent")}function l(a,b){a.classList?a.classList.add(b):a.className=a.className+" "+b}function m(a,b){a.classList?a.classList.remove(b):a.className=a.className.replace(b,"").trim()}function n(){return Math.max(Math.max(pb.body.scrollWidth,pb.documentElement.scrollWidth),Math.max(pb.body.offsetWidth,pb.documentElement.offsetWidth),Math.max(pb.body.clientWidth,pb.documentElement.clientWidth))}function o(){return Math.max(Math.max(pb.body.scrollHeight,pb.documentElement.scrollHeight),Math.max(pb.body.offsetHeight,pb.documentElement.offsetHeight),Math.max(pb.body.clientHeight,pb.documentElement.clientHeight))}function p(a,b){var c=parseInt(ub(a,b),10);return isNaN(c)?0:c}function q(a,b,c,d,e,f){"transparent"!==f&&(a.setVariable("fillStyle",f),a.fillRect(b,c,d,e),ob+=1)}function r(a,b,c){return a.length>0?b+c.toUpperCase():void 0}function s(a,b){switch(b){case"lowercase":return a.toLowerCase();case"capitalize":return a.replace(/(^|\s|:|-|\(|\))([a-z])/g,r);case"uppercase":return a.toUpperCase();default:return a}}function t(a){return/^(normal|none|0px)$/.test(a)}function u(a,b,c,d){null!==a&&qb.trimText(a).length>0&&(d.fillText(a,b,c),ob+=1)}function v(a,b,c,d){var e=!1,f=ub(b,"fontWeight"),g=ub(b,"fontFamily"),h=ub(b,"fontSize"),i=qb.parseTextShadows(ub(b,"textShadow"));switch(parseInt(f,10)){case 401:f="bold";break;case 400:f="normal"}return a.setVariable("fillStyle",d),a.setVariable("font",[ub(b,"fontStyle"),ub(b,"fontVariant"),f,h,g].join(" ")),a.setVariable("textAlign",e?"right":"left"),i.length&&(a.setVariable("shadowColor",i[0].color),a.setVariable("shadowOffsetX",i[0].offsetX),a.setVariable("shadowOffsetY",i[0].offsetY),a.setVariable("shadowBlur",i[0].blur)),"none"!==c?qb.Font(g,h,pb):void 0}function w(a,b,c,d,e){switch(b){case"underline":q(a,c.left,Math.round(c.top+d.baseline+d.lineWidth),c.width,1,e);break;case"overline":q(a,c.left,Math.round(c.top),c.width,1,e);break;case"line-through":q(a,c.left,Math.ceil(c.top+d.middle+d.lineWidth),c.width,1,e)}}function x(a,b,c,d,e){var f;if(rb.rangeBounds&&!e)("none"!==c||0!==qb.trimText(b).length)&&(f=y(b,a.node,a.textOffset)),a.textOffset+=b.length;else if(a.node&&"string"==typeof a.node.nodeValue){var g=d?a.node.splitText(b.length):null;f=z(a.node,e),a.node=g}return f}function y(a,b,c){var d=pb.createRange();return d.setStart(b,c),d.setEnd(b,c+a.length),d.getBoundingClientRect()}function z(a,b){var c=a.parentNode,d=pb.createElement("wrapper"),e=a.cloneNode(!0);d.appendChild(a.cloneNode(!0)),c.replaceChild(d,a);var f=b?qb.OffsetBounds(d):qb.Bounds(d);return c.replaceChild(e,d),f}function A(a,b,c){var d,f,g=c.ctx,h=ub(a,"color"),i=ub(a,"textDecoration"),j=ub(a,"textAlign"),k={node:b,textOffset:0};qb.trimText(b.nodeValue).length>0&&(b.nodeValue=s(b.nodeValue,ub(a,"textTransform")),j=j.replace(["-webkit-auto"],["auto"]),f=!e.letterRendering&&/^(left|right|justify|auto)$/.test(j)&&t(ub(a,"letterSpacing"))?b.nodeValue.split(/(\b| )/):b.nodeValue.split(""),d=v(g,a,i,h),e.chinese&&f.forEach(function(a,b){/.*[\u4E00-\u9FA5].*$/.test(a)&&(a=a.split(""),a.unshift(b,1),f.splice.apply(f,a))}),f.forEach(function(a,b){var e=x(k,a,i,bg,c&&c.zIndex.children.push(b)}function I(a){return{zindex:a,children:[]}}function J(a,b,c,d,e){var f=p(b,"paddingLeft"),g=p(b,"paddingTop"),h=p(b,"paddingRight"),i=p(b,"paddingBottom");W(a,c,0,0,c.width,c.height,d.left+f+e[3].width,d.top+g+e[0].width,d.width-(e[1].width+e[3].width+f+h),d.height-(e[0].width+e[2].width+g+i))}function K(a){return["Top","Right","Bottom","Left"].map(function(b){return{width:p(a,"border"+b+"Width"),color:ub(a,"border"+b+"Color")}})}function L(a){return["TopLeft","TopRight","BottomRight","BottomLeft"].map(function(b){return ub(a,"border"+b+"Radius")})}function M(a,b,c,d){var e=4*((Math.sqrt(2)-1)/3),f=c*e,g=d*e,h=a+c,i=b+d;return{topLeft:N({x:a,y:i},{x:a,y:i-g},{x:h-f,y:b},{x:h,y:b}),topRight:N({x:a,y:b},{x:a+f,y:b},{x:h,y:i-g},{x:h,y:i}),bottomRight:N({x:h,y:b},{x:h,y:b+g},{x:a+f,y:i},{x:a,y:i}),bottomLeft:N({x:h,y:i},{x:h-f,y:i},{x:a,y:b+g},{x:a,y:b})}}function N(a,b,c,d){var e=function(a,b,c){return{x:a.x+(b.x-a.x)*c,y:a.y+(b.y-a.y)*c}};return{start:a,startControl:b,endControl:c,end:d,subdivide:function(f){var g=e(a,b,f),h=e(b,c,f),i=e(c,d,f),j=e(g,h,f),k=e(h,i,f),l=e(j,k,f);return[N(a,g,j,l),N(l,k,i,d)]},curveTo:function(a){a.push(["bezierCurve",b.x,b.y,c.x,c.y,d.x,d.y])},curveToReversed:function(d){d.push(["bezierCurve",c.x,c.y,b.x,b.y,a.x,a.y])}}}function O(a,b,c,d,e,f,g){b[0]>0||b[1]>0?(a.push(["line",d[0].start.x,d[0].start.y]),d[0].curveTo(a),d[1].curveTo(a)):a.push(["line",f,g]),(c[0]>0||c[1]>0)&&a.push(["line",e[0].start.x,e[0].start.y])}function P(a,b,c,d,e,f,g){var h=[];return b[0]>0||b[1]>0?(h.push(["line",d[1].start.x,d[1].start.y]),d[1].curveTo(h)):h.push(["line",a.c1[0],a.c1[1]]),c[0]>0||c[1]>0?(h.push(["line",f[0].start.x,f[0].start.y]),f[0].curveTo(h),h.push(["line",g[0].end.x,g[0].end.y]),g[0].curveToReversed(h)):(h.push(["line",a.c2[0],a.c2[1]]),h.push(["line",a.c3[0],a.c3[1]])),b[0]>0||b[1]>0?(h.push(["line",e[1].end.x,e[1].end.y]),e[1].curveToReversed(h)):h.push(["line",a.c4[0],a.c4[1]]),h}function Q(a,b,c){var d=a.left,e=a.top,f=a.width,g=a.height,h=b[0][0],i=b[0][1],j=b[1][0],k=b[1][1],l=b[2][0],m=b[2][1],n=b[3][0],o=b[3][1],p=f-j,q=g-m,r=f-l,s=g-o;return{topLeftOuter:M(d,e,h,i).topLeft.subdivide(.5),topLeftInner:M(d+c[3].width,e+c[0].width,Math.max(0,h-c[3].width),Math.max(0,i-c[0].width)).topLeft.subdivide(.5),topRightOuter:M(d+p,e,j,k).topRight.subdivide(.5),topRightInner:M(d+Math.min(p,f+c[3].width),e+c[0].width,p>f+c[3].width?0:j-c[3].width,k-c[0].width).topRight.subdivide(.5),bottomRightOuter:M(d+r,e+q,l,m).bottomRight.subdivide(.5),bottomRightInner:M(d+Math.min(r,f+c[3].width),e+Math.min(q,g+c[0].width),Math.max(0,l-c[1].width),Math.max(0,m-c[2].width)).bottomRight.subdivide(.5),bottomLeftOuter:M(d,e+s,n,o).bottomLeft.subdivide(.5),bottomLeftInner:M(d+c[3].width,e+s,Math.max(0,n-c[3].width),Math.max(0,o-c[2].width)).bottomLeft.subdivide(.5)}}function R(a,b,c,d,e){var f=ub(a,"backgroundClip"),g=[];switch(f){case"content-box":case"padding-box":O(g,d[0],d[1],b.topLeftInner,b.topRightInner,e.left+c[3].width,e.top+c[0].width),O(g,d[1],d[2],b.topRightInner,b.bottomRightInner,e.left+e.width-c[1].width,e.top+c[0].width),O(g,d[2],d[3],b.bottomRightInner,b.bottomLeftInner,e.left+e.width-c[1].width,e.top+e.height-c[2].width),O(g,d[3],d[0],b.bottomLeftInner,b.topLeftInner,e.left+c[3].width,e.top+e.height-c[2].width);break;default:O(g,d[0],d[1],b.topLeftOuter,b.topRightOuter,e.left,e.top),O(g,d[1],d[2],b.topRightOuter,b.bottomRightOuter,e.left+e.width,e.top),O(g,d[2],d[3],b.bottomRightOuter,b.bottomLeftOuter,e.left+e.width,e.top+e.height),O(g,d[3],d[0],b.bottomLeftOuter,b.topLeftOuter,e.left,e.top+e.height)}return g}function S(a,b,c){var d,e,f,g,h,i,j=b.left,k=b.top,l=b.width,m=b.height,n=L(a),o=Q(b,n,c),p={clip:R(a,o,c,n,b),borders:[]};for(d=0;4>d;d++)if(c[d].width>0){switch(e=j,f=k,g=l,h=m-c[2].width,d){case 0:h=c[0].width,i=P({c1:[e,f],c2:[e+g,f],c3:[e+g-c[1].width,f+h],c4:[e+c[3].width,f+h]},n[0],n[1],o.topLeftOuter,o.topLeftInner,o.topRightOuter,o.topRightInner);break;case 1:e=j+l-c[1].width,g=c[1].width,i=P({c1:[e+g,f],c2:[e+g,f+h+c[2].width],c3:[e,f+h],c4:[e,f+c[0].width]},n[1],n[2],o.topRightOuter,o.topRightInner,o.bottomRightOuter,o.bottomRightInner);break;case 2:f=f+m-c[2].width,h=c[2].width,i=P({c1:[e+g,f+h],c2:[e,f+h],c3:[e+c[3].width,f],c4:[e+g-c[3].width,f]},n[2],n[3],o.bottomRightOuter,o.bottomRightInner,o.bottomLeftOuter,o.bottomLeftInner);break;case 3:g=c[3].width,i=P({c1:[e,f+h+c[2].width],c2:[e,f],c3:[e+g,f+c[0].width],c4:[e+g,f+h]},n[3],n[0],o.bottomLeftOuter,o.bottomLeftInner,o.topLeftOuter,o.topLeftInner)}p.borders.push({args:i,color:c[d].color})}return p}function T(a,b){var c=a.drawShape();return b.forEach(function(a,b){c[0===b?"moveTo":a[0]+"To"].apply(null,a.slice(1))}),c}function U(a,b,c){"transparent"!==c&&(a.setVariable("fillStyle",c),T(a,b),a.fill(),ob+=1)}function V(a,b,c){var d,e,f=pb.createElement("valuewrap"),g=["lineHeight","textAlign","fontFamily","color","fontSize","paddingLeft","paddingTop","width","height","border","borderLeftWidth","borderTopWidth"];g.forEach(function(b){try{f.style[b]=ub(a,b)}catch(c){qb.log("html2canvas: Parse: Exception caught in renderFormValue: "+c.message)}}),f.style.borderColor="black",f.style.borderStyle="solid",f.style.display="block",f.style.position="absolute",(/^(submit|reset|button|text|password)$/.test(a.type)||"SELECT"===a.nodeName)&&(f.style.lineHeight=ub(a,"height")),f.style.top=b.top+"px",f.style.left=b.left+"px",d="SELECT"===a.nodeName?(a.options[a.selectedIndex]||0).text:a.value,d||(d=a.placeholder),e=pb.createTextNode(d),f.appendChild(e),tb.appendChild(f),A(a,e,c),tb.removeChild(f)}function W(a){a.drawImage.apply(a,Array.prototype.slice.call(arguments,1)),ob+=1}function X(c,d){var e=a.getComputedStyle(c,d),f=a.getComputedStyle(c);if(e&&e.content&&"none"!==e.content&&"-moz-alt-content"!==e.content&&"none"!==e.display&&f.content!==e.content){var g=e.content+"";("'"===g[0]||'"'===g[0])&&(g=g.replace(/(^['"])|(['"]$)/g,""));var h="url"===g.substr(0,3),i=b.createElement(h?"img":"span");return i.className=vb+"-element ",Object.keys(e).filter(Y).forEach(function(a){try{i.style[a]=e[a]}catch(b){qb.log(["Tried to assign readonly property ",a,"Error:",b])}}),h?i.src=qb.parseBackgroundImage(g)[0].args[0]:i.innerHTML=g,i}}function Y(b){return isNaN(a.parseInt(b,10))}function Z(a,b,c,d){var e=Math.round(d.left+c.left),f=Math.round(d.top+c.top);a.createPattern(b),a.translate(e,f),a.fill(),a.translate(-e,-f)}function $(a,b,c,d,e,f,g,h){var i=[];i.push(["line",Math.round(e),Math.round(f)]),i.push(["line",Math.round(e+g),Math.round(f)]),i.push(["line",Math.round(e+g),Math.round(h+f)]),i.push(["line",Math.round(e),Math.round(h+f)]),T(a,i),a.save(),a.clip(),Z(a,b,c,d),a.restore()}function _(a,b,c){q(a,b.left,b.top,b.width,b.height,c)}function ab(a,b,c,d,e){var f=qb.BackgroundSize(a,b,d,e),g=qb.BackgroundPosition(a,b,d,e,f),h=ub(a,"backgroundRepeat").split(",").map(qb.trimText);switch(d=cb(d,f),h=h[e]||h[0]){case"repeat-x":$(c,d,g,b,b.left,b.top+g.top,99999,d.height);break;case"repeat-y":$(c,d,g,b,b.left+g.left,b.top,d.width,99999);break;case"no-repeat":$(c,d,g,b,b.left+g.left,b.top+g.top,d.width,d.height);break;default:Z(c,d,g,{top:b.top,left:b.left,width:d.width,height:d.height})}}function bb(a,b,c){for(var d,e=ub(a,"backgroundImage"),f=qb.parseBackgroundImage(e),g=f.length;g--;)if(e=f[g],e.args&&0!==e.args.length){var h="url"===e.method?e.args[0]:e.value;d=F(h),d?ab(a,b,c,d,g):qb.log("html2canvas: Error loading background:",e)}}function cb(a,b){if(a.width===b.width&&a.height===b.height)return a;var c,d=pb.createElement("canvas");return d.width=b.width,d.height=b.height,c=d.getContext("2d"),W(c,a,0,0,a.width,a.height,0,0,b.width,b.height),d}function db(a,b,c){return a.setVariable("globalAlpha",ub(b,"opacity")*(c?c.opacity:1))}function eb(a){return a.replace("px","")}function fb(a){var b=/(matrix)\((.+)\)/,c=ub(a,"transform")||ub(a,"-webkit-transform")||ub(a,"-moz-transform")||ub(a,"-ms-transform")||ub(a,"-o-transform"),d=ub(a,"transform-origin")||ub(a,"-webkit-transform-origin")||ub(a,"-moz-transform-origin")||ub(a,"-ms-transform-origin")||ub(a,"-o-transform-origin")||"0px 0px";d=d.split(" ").map(eb).map(qb.asFloat);var e;if(c&&"none"!==c){var f=c.match(b);if(f)switch(f[1]){case"matrix":e=f[2].split(",").map(qb.trimText).map(qb.asFloat)}}return{origin:d,matrix:e}}function gb(a,b,c,d){var f=h(b?c.width:n(),b?c.height:o()),g={ctx:f,opacity:db(f,a,b),cssPosition:ub(a,"position"),borders:K(a),transform:d,clip:b&&b.clip?qb.Extend({},b.clip):null};return H(a,g,b),e.useOverflow===!0&&/(hidden|scroll|auto)/.test(ub(a,"overflow"))===!0&&/(BODY)/i.test(a.nodeName)===!1&&(g.clip=g.clip?G(g.clip,c):c),g}function hb(a,b,c){var d={left:b.left+a[3].width,top:b.top+a[0].width,width:b.width-(a[1].width+a[3].width),height:b.height-(a[0].width+a[2].width)};return c&&(d=G(d,c)),d}function ib(a,b){var c=b.matrix?qb.OffsetBounds(a):qb.Bounds(a);return b.origin[0]+=c.left,b.origin[1]+=c.top,c}function jb(a,b,c){var d,e=fb(a,b),f=ib(a,e),g=gb(a,b,f,e),h=g.borders,i=g.ctx,j=hb(h,f,g.clip),k=S(a,f,h),l=sb.test(a.nodeName)?"#efefef":ub(a,"backgroundColor");switch(T(i,k.clip),i.save(),i.clip(),j.height>0&&j.width>0&&!c?(_(i,f,l),bb(a,j,i)):c&&(g.backgroundColor=l),i.restore(),k.borders.forEach(function(a){U(i,a.args,a.color)}),a.nodeName){case"IMG":(d=F(a.getAttribute("src")))?J(i,a,d,f,h):qb.log("html2canvas: Error loading
:"+a.getAttribute("src"));break;case"INPUT":/^(text|url|email|submit|button|reset)$/.test(a.type)&&(a.value||a.placeholder||"").length>0&&V(a,f,g);break;case"TEXTAREA":(a.value||a.placeholder||"").length>0&&V(a,f,g);break;case"SELECT":(a.options||a.placeholder||"").length>0&&V(a,f,g);break;case"LI":E(a,g,j);break;case"CANVAS":J(i,a,a,f,h)}return g}function kb(a){return"none"!==ub(a,"display")&&"hidden"!==ub(a,"visibility")&&!a.hasAttribute("data-html2canvas-ignore")}function lb(a,b,c){return c||(c=function(){}),kb(a)&&(b=jb(a,b,!1)||b,!sb.test(a.nodeName))?mb(a,b,c):(c(),void 0)}function mb(a,b,c){function d(c){c.nodeType===c.ELEMENT_NODE?lb(c,b,f):c.nodeType===c.TEXT_NODE?(A(a,c,b),f()):f()}function f(){--h<=0&&(qb.log("finished rendering "+g.length+" children."),c())}var g=qb.Children(a),h=g.length+1;f(),e.async?g.forEach(function(a){setTimeout(function(){d(a)},0)}):g.forEach(d)}a.scroll(0,0);var nb=e.elements===c?b.body:e.elements[0],ob=0,pb=nb.ownerDocument,qb=k.Util,rb=qb.Support(e,pb),sb=new RegExp("("+e.ignoreElements+")"),tb=pb.body,ub=qb.getCSS,vb="___html2canvas___pseudoelement",wb=pb.createElement("style");wb.innerHTML="."+vb+'-parent:before { content: "" !important; display: none !important; }'+"."+vb+'-parent:after { content: "" !important; display: none !important; }',tb.appendChild(wb),d=d||{},g()},k.Preload=function(d){function e(a){A.href=a,A.href=A.href;var b=A.protocol+A.host;return b===p}function f(){u.log("html2canvas: start: images: "+t.numLoaded+" / "+t.numTotal+" (failed: "+t.numFailed+")"),!t.firstRun&&t.numLoaded>=t.numTotal&&(u.log("Finished loading images: # "+t.numTotal+" (failed: "+t.numFailed+")"),"function"==typeof d.complete&&d.complete(t))}function g(b,e,g){var h,i,j=d.proxy;A.href=b,b=A.href,h="html2canvas_"+v++,g.callbackname=h,j+=j.indexOf("?")>-1?"&":"?",j+="url="+encodeURIComponent(b)+"&callback="+h,i=x.createElement("script"),a[h]=function(b){"error:"===b.substring(0,6)?(g.succeeded=!1,t.numLoaded++,t.numFailed++,f()):(o(e,g),e.src=b),a[h]=c;try{delete a[h]}catch(d){}i.parentNode.removeChild(i),i=null,delete g.script,delete g.callbackname},i.setAttribute("type","text/javascript"),i.setAttribute("src",j),g.script=i,a.document.body.appendChild(i)}function h(b,c){var d=a.getComputedStyle(b,c),e=d.content;"url"===e.substr(0,3)&&q.loadImage(k.Util.parseBackgroundImage(e)[0].args[0]),m(d.backgroundImage,b)}function i(a){h(a,":before"),h(a,":after")}function j(a,b){var d=k.Generate.Gradient(a,b);d!==c&&(t[a]={img:d,succeeded:!0},t.numTotal++,t.numLoaded++,f())}function l(a){return a&&a.method&&a.args&&a.args.length>0}function m(a,b){var d;k.Util.parseBackgroundImage(a).filter(l).forEach(function(a){"url"===a.method?q.loadImage(a.args[0]):a.method.match(/\-?gradient$/)&&(d===c&&(d=k.Util.Bounds(b)),j(a.value,d))})}function n(a){var b=!1;try{u.Children(a).forEach(n)}catch(d){}try{b=a.nodeType}catch(e){b=!1,u.log("html2canvas: failed to access some element's nodeType - Exception: "+e.message)}if(1===b||b===c){i(a);try{m(u.getCSS(a,"backgroundImage"),a)}catch(d){u.log("html2canvas: failed to get background-image - Exception: "+d.message)}m(a)}}function o(b,e){b.onload=function(){e.timer!==c&&a.clearTimeout(e.timer),t.numLoaded++,e.succeeded=!0,b.onerror=b.onload=null,f()},b.onerror=function(){if("anonymous"===b.crossOrigin&&(a.clearTimeout(e.timer),d.proxy)){var c=b.src;return b=new Image,e.img=b,b.src=c,g(b.src,b,e),void 0}t.numLoaded++,t.numFailed++,e.succeeded=!1,b.onerror=b.onload=null,f()}}var p,q,r,s,t={numLoaded:0,numFailed:0,numTotal:0,cleanupDone:!1},u=k.Util,v=0,w=d.elements[0]||b.body,x=w.ownerDocument,y=w.getElementsByTagName("img"),z=y.length,A=x.createElement("a"),B=function(a){return a.crossOrigin!==c}(new Image);for(A.href=a.location.href,p=A.protocol+A.host,q={loadImage:function(a){var b,f;a&&t[a]===c&&(b=new Image,a.match(/data:image\/.*;base64,/i)?(b.src=a.replace(/url\(['"]{0,}|['"]{0,}\)$/gi,""),f=t[a]={img:b},t.numTotal++,o(b,f)):e(a)||d.allowTaint===!0?(f=t[a]={img:b},t.numTotal++,o(b,f),b.src=a):B&&!d.allowTaint&&d.useCORS?(b.crossOrigin="anonymous",f=t[a]={img:b},t.numTotal++,o(b,f),b.src=a):d.proxy&&(f=t[a]={img:b},t.numTotal++,g(a,b,f)))},cleanupDOM:function(e){var g,h;if(!t.cleanupDone){e&&"string"==typeof e?u.log("html2canvas: Cleanup because: "+e):u.log("html2canvas: Cleanup after timeout: "+d.timeout+" ms.");for(h in t)if(t.hasOwnProperty(h)&&(g=t[h],"object"==typeof g&&g.callbackname&&g.succeeded===c)){a[g.callbackname]=c;
+try{delete a[g.callbackname]}catch(i){}g.script&&g.script.parentNode&&(g.script.setAttribute("src","about:blank"),g.script.parentNode.removeChild(g.script)),t.numLoaded++,t.numFailed++,u.log("html2canvas: Cleaned up failed img: '"+h+"' Steps: "+t.numLoaded+" / "+t.numTotal)}a.stop!==c?a.stop():b.execCommand!==c&&b.execCommand("Stop",!1),b.close!==c&&b.close(),t.cleanupDone=!0,e&&"string"==typeof e||f()}},renderingDone:function(){s&&a.clearTimeout(s)}},d.timeout>0&&(s=a.setTimeout(q.cleanupDOM,d.timeout)),u.log("html2canvas: Preload starts: finding background-images"),t.firstRun=!0,n(w),u.log("html2canvas: Preload: Finding images"),r=0;z>r;r+=1)q.loadImage(y[r].getAttribute("src"));return t.firstRun=!1,u.log("html2canvas: Preload: Done."),t.numTotal===t.numLoaded&&f(),q},k.Renderer=function(a,d){function e(a){function b(a){Object.keys(a).sort().forEach(function(c){var d=[],f=[],g=[],h=[];a[c].forEach(function(a){a.node.zIndex.isPositioned||a.node.zIndex.opacity<1?g.push(a):a.node.zIndex.isFloated?f.push(a):d.push(a)}),function i(a){a.forEach(function(a){h.push(a),a.children&&i(a.children)})}(d.concat(f,g)),h.forEach(function(a){a.context?b(a.context):e.push(a.node)})})}var d,e=[];return d=function(a){function b(a,d,e){var f="auto"===d.zIndex.zindex?0:Number(d.zIndex.zindex),g=a,h=d.zIndex.isPositioned,i=d.zIndex.isFloated,j={node:d},k=e;d.zIndex.ownStacking?(g=j.context={"!":[{node:d,children:[]}]},k=c):(h||i)&&(k=j.children=[]),0===f&&e?e.push(j):(a[f]||(a[f]=[]),a[f].push(j)),d.zIndex.children.forEach(function(a){b(g,a,k)})}var d={};return b(d,a),d}(a),b(d),e}function f(a){var b;if("string"==typeof d.renderer&&k.Renderer[a]!==c)b=k.Renderer[a](d);else{if("function"!=typeof a)throw new Error("Unknown renderer");b=a(d)}if("function"!=typeof b)throw new Error("Invalid renderer defined");return b}return f(d.renderer)(a,d,b,e(a.stack),k)},k.Util.Support=function(a,b){function d(){var a=new Image,d=b.createElement("canvas"),e=d.getContext===c?!1:d.getContext("2d");if(e===!1)return!1;d.width=d.height=10,a.src=["data:image/svg+xml,",""].join("");try{e.drawImage(a,0,0),d.toDataURL()}catch(f){return!1}return k.Util.log("html2canvas: Parse: SVG powered rendering available"),!0}function e(){var a,c,d,e,f=!1;return b.createRange&&(a=b.createRange(),a.getBoundingClientRect&&(c=b.createElement("boundtest"),c.style.height="123px",c.style.display="block",b.body.appendChild(c),a.selectNode(c),d=a.getBoundingClientRect(),e=d.height,123===e&&(f=!0),b.body.removeChild(c))),f}return{rangeBounds:e(),svgRendering:a.svgRendering&&d()}},a.html2canvas=function(b,c){b=b.length?b:[b];var d,e={logging:!1,elements:b,background:"#fff",proxy:null,timeout:0,useCORS:!1,allowTaint:!1,svgRendering:!1,ignoreElements:"IFRAME|OBJECT|PARAM",useOverflow:!0,letterRendering:!1,chinese:!1,async:!1,width:null,height:null,taintTest:!0,renderer:"Canvas"};return e=k.Util.Extend(c,e),k.logging=e.logging,e.complete=function(a){("function"!=typeof e.onpreloaded||e.onpreloaded(a)!==!1)&&k.Parse(a,e,function(a){("function"!=typeof e.onparsed||e.onparsed(a)!==!1)&&(d=k.Renderer(a,e),"function"==typeof e.onrendered&&e.onrendered(d))})},a.setTimeout(function(){k.Preload(e)},0),{render:function(a,b){return k.Renderer(a,k.Util.Extend(b,e))},parse:function(a,b){return k.Parse(a,k.Util.Extend(b,e))},preload:function(a){return k.Preload(k.Util.Extend(a,e))},log:k.Util.log}},a.html2canvas.log=k.Util.log,a.html2canvas.Renderer={Canvas:c},k.Renderer.Canvas=function(a){function d(a,b){a.beginPath(),b.forEach(function(b){a[b.name].apply(a,b.arguments)}),a.closePath()}function e(a){if(-1===h.indexOf(a.arguments[0].src)){j.drawImage(a.arguments[0],0,0);try{j.getImageData(0,0,1,1)}catch(b){return i=g.createElement("canvas"),j=i.getContext("2d"),!1}h.push(a.arguments[0].src)}return!0}function f(b,c){switch(c.type){case"variable":b[c.name]=c.arguments;break;case"function":switch(c.name){case"createPattern":if(c.arguments[0].width>0&&c.arguments[0].height>0)try{b.fillStyle=b.createPattern(c.arguments[0],"repeat")}catch(f){l.log("html2canvas: Renderer: Error creating pattern",f.message)}break;case"drawShape":d(b,c.arguments);break;case"drawImage":c.arguments[8]>0&&c.arguments[7]>0&&(!a.taintTest||a.taintTest&&e(c))&&b.drawImage.apply(b,c.arguments);break;default:b[c.name].apply(b,c.arguments)}}}a=a||{};var g=b,h=[],i=b.createElement("canvas"),j=i.getContext("2d"),l=k.Util,m=a.canvas||g.createElement("canvas");return function(a,b,d,e,g){var h,i,j,k=m.getContext("2d"),n=a.stack;return m.width=m.style.width=b.width||n.ctx.width,m.height=m.style.height=b.height||n.ctx.height,j=k.fillStyle,k.fillStyle=l.isTransparent(n.backgroundColor)&&b.background!==c?b.background:a.backgroundColor,k.fillRect(0,0,m.width,m.height),k.fillStyle=j,e.forEach(function(a){k.textBaseline="bottom",k.save(),a.transform.matrix&&(k.translate(a.transform.origin[0],a.transform.origin[1]),k.transform.apply(k,a.transform.matrix),k.translate(-a.transform.origin[0],-a.transform.origin[1])),a.clip&&(k.beginPath(),k.rect(a.clip.left,a.clip.top,a.clip.width,a.clip.height),k.clip()),a.ctx.storage&&a.ctx.storage.forEach(function(a){f(k,a)}),k.restore()}),l.log("html2canvas: Renderer: Canvas renderer done - returning canvas obj"),1===b.elements.length&&"object"==typeof b.elements[0]&&"BODY"!==b.elements[0].nodeName?(i=g.Util.Bounds(b.elements[0]),h=d.createElement("canvas"),h.width=Math.ceil(i.width),h.height=Math.ceil(i.height),k=h.getContext("2d"),k.drawImage(m,i.left,i.top,i.width,i.height,0,0,i.width,i.height),m=null,h):m}}}(window,document);
\ No newline at end of file
diff --git a/src/Parse.js b/src/Parse.js
index d155789..26064a2 100644
--- a/src/Parse.js
+++ b/src/Parse.js
@@ -1,4 +1,4 @@
-_html2canvas.Parse = function (images, options) {
+_html2canvas.Parse = function (images, options, cb) {
window.scroll(0,0);
var element = (( options.elements === undefined ) ? document.body : options.elements[0]), // select body by default
@@ -10,15 +10,163 @@ _html2canvas.Parse = function (images, options) {
body = doc.body,
getCSS = Util.getCSS,
pseudoHide = "___html2canvas___pseudoelement",
- hidePseudoElements = doc.createElement('style');
+ hidePseudoElementsStyles = doc.createElement('style');
- hidePseudoElements.innerHTML = '.' + pseudoHide + '-before:before { content: "" !important; display: none !important; }' +
- '.' + pseudoHide + '-after:after { content: "" !important; display: none !important; }';
+ hidePseudoElementsStyles.innerHTML = '.' + pseudoHide +
+ '-parent:before { content: "" !important; display: none !important; }' +
+ '.' + pseudoHide + '-parent:after { content: "" !important; display: none !important; }';
- body.appendChild(hidePseudoElements);
+ body.appendChild(hidePseudoElementsStyles);
images = images || {};
+ init();
+
+ function init() {
+ var background = getCSS(document.documentElement, "backgroundColor"),
+ transparentBackground = (Util.isTransparent(background) && element === document.body),
+ stack = renderElement(element, null, false, transparentBackground);
+
+ // create pseudo elements in a single pass to prevent synchronous layouts
+ addPseudoElements(element);
+
+ parseChildren(element, stack, function() {
+ if (transparentBackground) {
+ background = stack.backgroundColor;
+ }
+
+ removePseudoElements();
+
+ Util.log('Done parsing, moving to Render.');
+
+ cb({
+ backgroundColor: background,
+ stack: stack
+ });
+ });
+ }
+
+ // Given a root element, find all pseudo elements below, create elements mocking pseudo element styles
+ // so we can process them as normal elements, and hide the original pseudo elements so they don't interfere
+ // with layout.
+ function addPseudoElements(el) {
+ // These are done in discrete steps to prevent a relayout loop caused by addClass() invalidating
+ // layouts & getPseudoElement calling getComputedStyle.
+ var jobs = [], classes = [];
+ getPseudoElementClasses();
+ findPseudoElements(el);
+ runJobs();
+
+ function getPseudoElementClasses(){
+ var findPsuedoEls = /:before|:after/;
+ var sheets = document.styleSheets;
+ for (var i = 0, j = sheets.length; i < j; i++) {
+ try {
+ var rules = sheets[i].cssRules;
+ for (var k = 0, l = rules.length; k < l; k++) {
+ if(findPsuedoEls.test(rules[k].selectorText)) {
+ classes.push(rules[k].selectorText);
+ }
+ }
+ }
+ catch(e) { // will throw security exception for style sheets loaded from external domains
+ }
+ }
+
+ // Trim off the :after and :before (or ::after and ::before)
+ for (i = 0, j = classes.length; i < j; i++) {
+ classes[i] = classes[i].match(/(^[^:]*)/)[1];
+ }
+ }
+
+ // Using the list of elements we know how pseudo el styles, create fake pseudo elements.
+ function findPseudoElements(el) {
+ var els = document.querySelectorAll(classes.join(','));
+ for(var i = 0, j = els.length; i < j; i++) {
+ createPseudoElements(els[i]);
+ }
+ }
+
+ // Create pseudo elements & add them to a job queue.
+ function createPseudoElements(el) {
+ var before = getPseudoElement(el, ':before'),
+ after = getPseudoElement(el, ':after');
+
+ if(before) {
+ jobs.push({type: 'before', pseudo: before, el: el});
+ }
+
+ if (after) {
+ jobs.push({type: 'after', pseudo: after, el: el});
+ }
+ }
+
+ // Adds a class to the pseudo's parent to prevent the original before/after from messing
+ // with layouts.
+ // Execute the inserts & addClass() calls in a batch to prevent relayouts.
+ function runJobs() {
+ // Add Class
+ jobs.forEach(function(job){
+ addClass(job.el, pseudoHide + "-parent");
+ });
+
+ // Insert el
+ jobs.forEach(function(job){
+ if(job.type === 'before'){
+ job.el.insertBefore(job.pseudo, job.el.firstChild);
+ } else {
+ job.el.appendChild(job.pseudo);
+ }
+ });
+ }
+ }
+
+
+
+ // Delete our fake pseudo elements from the DOM. This will remove those actual elements
+ // and the classes on their parents that hide the actual pseudo elements.
+ // Note that NodeLists are 'live' collections so you can't use a for loop here. They are
+ // actually deleted from the NodeList after each iteration.
+ function removePseudoElements(){
+ // delete pseudo elements
+ body.removeChild(hidePseudoElementsStyles);
+ var pseudos = document.getElementsByClassName(pseudoHide + "-element");
+ while (pseudos.length) {
+ pseudos[0].parentNode.removeChild(pseudos[0]);
+ }
+
+ // Remove pseudo hiding classes
+ var parents = document.getElementsByClassName(pseudoHide + "-parent");
+ while(parents.length) {
+ removeClass(parents[0], pseudoHide + "-parent");
+ }
+ }
+
+ function addClass (el, className) {
+ if (el.classList) {
+ el.classList.add(className);
+ } else {
+ el.className = el.className + " " + className;
+ }
+ }
+
+ function removeClass (el, className) {
+ if (el.classList) {
+ el.classList.remove(className);
+ } else {
+ el.className = el.className.replace(className, "").trim();
+ }
+ }
+
+ function hasClass (el, className) {
+ return el.className.indexOf(className) > -1;
+ }
+
+ // Note that this doesn't work in < IE8, but we don't support that anyhow
+ function nodeListToArray (nodeList) {
+ return Array.prototype.slice.call(nodeList);
+ }
+
function documentWidth () {
return Math.max(
Math.max(doc.body.scrollWidth, doc.documentElement.scrollWidth),
@@ -336,6 +484,13 @@ _html2canvas.Parse = function (images, options) {
}
}
+ function h2czContext(zindex) {
+ return {
+ zindex: zindex,
+ children: []
+ };
+ }
+
function renderImage(ctx, element, image, bounds, borders) {
var paddingLeft = getCSSInt(element, 'paddingLeft'),
@@ -372,69 +527,67 @@ _html2canvas.Parse = function (images, options) {
});
}
- var getCurvePoints = (function(kappa) {
-
- return function(x, y, r1, r2) {
- var ox = (r1) * kappa, // control point offset horizontal
- oy = (r2) * kappa, // control point offset vertical
- xm = x + r1, // x-middle
- ym = y + r2; // y-middle
- return {
- topLeft: bezierCurve({
- x:x,
- y:ym
- }, {
- x:x,
- y:ym - oy
- }, {
- x:xm - ox,
- y:y
- }, {
- x:xm,
- y:y
- }),
- topRight: bezierCurve({
- x:x,
- y:y
- }, {
- x:x + ox,
- y:y
- }, {
- x:xm,
- y:ym - oy
- }, {
- x:xm,
- y:ym
- }),
- bottomRight: bezierCurve({
- x:xm,
- y:y
- }, {
- x:xm,
- y:y + oy
- }, {
- x:x + ox,
- y:ym
- }, {
- x:x,
- y:ym
- }),
- bottomLeft: bezierCurve({
- x:xm,
- y:ym
- }, {
- x:xm - ox,
- y:ym
- }, {
- x:x,
- y:y + oy
- }, {
- x:x,
- y:y
- })
- };
+ function getCurvePoints(x, y, r1, r2) {
+ var kappa = 4 * ((Math.sqrt(2) - 1) / 3);
+ var ox = (r1) * kappa, // control point offset horizontal
+ oy = (r2) * kappa, // control point offset vertical
+ xm = x + r1, // x-middle
+ ym = y + r2; // y-middle
+ return {
+ topLeft: bezierCurve({
+ x:x,
+ y:ym
+ }, {
+ x:x,
+ y:ym - oy
+ }, {
+ x:xm - ox,
+ y:y
+ }, {
+ x:xm,
+ y:y
+ }),
+ topRight: bezierCurve({
+ x:x,
+ y:y
+ }, {
+ x:x + ox,
+ y:y
+ }, {
+ x:xm,
+ y:ym - oy
+ }, {
+ x:xm,
+ y:ym
+ }),
+ bottomRight: bezierCurve({
+ x:xm,
+ y:y
+ }, {
+ x:xm,
+ y:y + oy
+ }, {
+ x:x + ox,
+ y:ym
+ }, {
+ x:x,
+ y:ym
+ }),
+ bottomLeft: bezierCurve({
+ x:xm,
+ y:ym
+ }, {
+ x:xm - ox,
+ y:ym
+ }, {
+ x:x,
+ y:y + oy
+ }, {
+ x:x,
+ y:y
+ })
};
- })(4 * ((Math.sqrt(2) - 1) / 3));
+ }
function bezierCurve(start, startControl, endControl, end) {
@@ -773,20 +926,25 @@ _html2canvas.Parse = function (images, options) {
function getPseudoElement(el, which) {
var elStyle = window.getComputedStyle(el, which);
- if(!elStyle || !elStyle.content || elStyle.content === "none" || elStyle.content === "-moz-alt-content" || elStyle.display === "none") {
+ var parentStyle = window.getComputedStyle(el);
+ // If no content attribute is present, the pseudo element is hidden,
+ // or the parent has a content property equal to the content on the pseudo element,
+ // move along.
+ if(!elStyle || !elStyle.content || elStyle.content === "none" || elStyle.content === "-moz-alt-content" ||
+ elStyle.display === "none" || parentStyle.content === elStyle.content) {
return;
}
- var content = elStyle.content + '',
- first = content.substr( 0, 1 );
- //strips quotes
- if(first === content.substr( content.length - 1 ) && first.match(/'|"/)) {
- content = content.substr( 1, content.length - 2 );
+ var content = elStyle.content + '';
+
+ // Strip inner quotes
+ if(content[0] === "'" || content[0] === "\"") {
+ content = content.replace(/(^['"])|(['"]$)/g, '');
}
var isImage = content.substr( 0, 3 ) === 'url',
elps = document.createElement( isImage ? 'img' : 'span' );
- elps.className = pseudoHide + "-before " + pseudoHide + "-after";
+ elps.className = pseudoHide + "-element ";
Object.keys(elStyle).filter(indexedProperty).forEach(function(prop) {
// Prevent assigning of read only CSS Rules, ex. length, parentRule
@@ -809,31 +967,6 @@ _html2canvas.Parse = function (images, options) {
return (isNaN(window.parseInt(property, 10)));
}
- function injectPseudoElements(el, stack) {
- var before = getPseudoElement(el, ':before'),
- after = getPseudoElement(el, ':after');
- if(!before && !after) {
- return;
- }
-
- if(before) {
- el.className += " " + pseudoHide + "-before";
- el.parentNode.insertBefore(before, el);
- parseElement(before, stack, true);
- el.parentNode.removeChild(before);
- el.className = el.className.replace(pseudoHide + "-before", "").trim();
- }
-
- if (after) {
- el.className += " " + pseudoHide + "-after";
- el.appendChild(after);
- parseElement(after, stack, true);
- el.removeChild(after);
- el.className = el.className.replace(pseudoHide + "-after", "").trim();
- }
-
- }
-
function renderBackgroundRepeat(ctx, image, backgroundPosition, bounds) {
var offsetX = Math.round(bounds.left + backgroundPosition.left),
offsetY = Math.round(bounds.top + backgroundPosition.top);
@@ -953,9 +1086,8 @@ _html2canvas.Parse = function (images, options) {
return str.replace("px", "");
}
- var transformRegExp = /(matrix)\((.+)\)/;
-
function getTransform(element, parentStack) {
+ var transformRegExp = /(matrix)\((.+)\)/;
var transform = getCSS(element, "transform") || getCSS(element, "-webkit-transform") || getCSS(element, "-moz-transform") || getCSS(element, "-ms-transform") || getCSS(element, "-o-transform");
var transformOrigin = getCSS(element, "transform-origin") || getCSS(element, "-webkit-transform-origin") || getCSS(element, "-moz-transform-origin") || getCSS(element, "-ms-transform-origin") || getCSS(element, "-o-transform-origin") || "0px 0px";
@@ -1022,7 +1154,7 @@ _html2canvas.Parse = function (images, options) {
return bounds;
}
- function renderElement(element, parentStack, pseudoElement, ignoreBackground) {
+ function renderElement(element, parentStack, ignoreBackground) {
var transform = getTransform(element, parentStack),
bounds = getBounds(element, transform),
image,
@@ -1052,10 +1184,6 @@ _html2canvas.Parse = function (images, options) {
renderBorders(ctx, border.args, border.color);
});
- if (!pseudoElement) {
- injectPseudoElements(element, stack);
- }
-
switch(element.nodeName){
case "IMG":
if ((image = loadImage(element.getAttribute('src')))) {
@@ -1096,48 +1224,51 @@ _html2canvas.Parse = function (images, options) {
return (getCSS(element, 'display') !== "none" && getCSS(element, 'visibility') !== "hidden" && !element.hasAttribute("data-html2canvas-ignore"));
}
- function parseElement (element, stack, pseudoElement) {
+ function parseElement (element, stack, cb) {
+ if (!cb) {
+ cb = function(){};
+ }
if (isElementVisible(element)) {
- stack = renderElement(element, stack, pseudoElement, false) || stack;
+ stack = renderElement(element, stack, false) || stack;
if (!ignoreElementsRegExp.test(element.nodeName)) {
- parseChildren(element, stack, pseudoElement);
+ return parseChildren(element, stack, cb);
}
}
+ cb();
}
- function parseChildren(element, stack, pseudoElement) {
- Util.Children(element).forEach(function(node) {
+ function parseChildren(element, stack, cb) {
+ var children = Util.Children(element);
+ // After all nodes have processed, finished() will call the cb.
+ // We add one and kick it off so this will still work when children.length === 0.
+ // Note that unless async is true, this will happen synchronously, just will callbacks.
+ var jobs = children.length + 1;
+ finished();
+
+ if (options.async) {
+ children.forEach(function(node) {
+ // Don't block the page from rendering
+ setTimeout(function(){ parseNode(node); }, 0);
+ });
+ } else {
+ children.forEach(parseNode);
+ }
+
+ function parseNode(node) {
if (node.nodeType === node.ELEMENT_NODE) {
- parseElement(node, stack, pseudoElement);
+ parseElement(node, stack, finished);
} else if (node.nodeType === node.TEXT_NODE) {
renderText(element, node, stack);
+ finished();
+ } else {
+ finished();
+ }
+ }
+ function finished(el) {
+ if (--jobs <= 0){
+ Util.log("finished rendering " + children.length + " children.");
+ cb();
}
- });
- }
-
- function init() {
- var background = getCSS(document.documentElement, "backgroundColor"),
- transparentBackground = (Util.isTransparent(background) && element === document.body),
- stack = renderElement(element, null, false, transparentBackground);
- parseChildren(element, stack);
-
- if (transparentBackground) {
- background = stack.backgroundColor;
}
-
- body.removeChild(hidePseudoElements);
- return {
- backgroundColor: background,
- stack: stack
- };
}
-
- return init();
-};
-
-function h2czContext(zindex) {
- return {
- zindex: zindex,
- children: []
- };
-}
+};
\ No newline at end of file
diff --git a/src/Util.js b/src/Util.js
index 861402b..8ea63af 100644
--- a/src/Util.js
+++ b/src/Util.js
@@ -20,9 +20,9 @@ window.html2canvas = function(elements, opts) {
useOverflow: true,
letterRendering: false,
chinese: false,
+ async: false, // If true, parsing will not block, but if the user scrolls during parse the image can get weird
// render options
-
width: null,
height: null,
taintTest: true, // do a taint test with all images before applying to canvas
@@ -39,21 +39,19 @@ window.html2canvas = function(elements, opts) {
return;
}
}
- queue = _html2canvas.Parse( images, options );
-
- if (typeof options.onparsed === "function") {
- if ( options.onparsed( queue ) === false ) {
- return;
+ _html2canvas.Parse( images, options, function(queue) {
+ if (typeof options.onparsed === "function") {
+ if ( options.onparsed( queue ) === false ) {
+ return;
+ }
}
- }
-
- canvas = _html2canvas.Renderer( queue, options );
-
- if (typeof options.onrendered === "function") {
- options.onrendered( canvas );
- }
+ canvas = _html2canvas.Renderer( queue, options );
+ if (typeof options.onrendered === "function") {
+ options.onrendered( canvas );
+ }
+ });
};
// for pages without images, we still want this to be async, i.e. return methods before executing