html2canvas/build/html2canvas.min.js
Niklas von Hertzen 8b8c080841 0.5.0 rewrite
2014-01-19 18:04:27 +02:00

7 lines
12 KiB
JavaScript

/*
html2canvas 0.5.0-rc1 <http://html2canvas.hertzen.com>
Copyright (c) 2014 Niklas von Hertzen
Released under MIT License
*/
(function(t,e,n){function o(t,e,n){var o=t.documentElement.cloneNode(!0),r=t.createElement("iframe");r.style.display="hidden",r.style.position="absolute",r.style.width=e+"px",r.style.height=n+"px",t.body.appendChild(r);var i=r.contentWindow.document;return i.replaceChild(i.adoptNode(o),i.documentElement),r}function r(t,e,n){this.renderer=e,this.options=n,this.support=new S,this.range=null,this.stack=new StackingContext(!0,1,t.ownerDocument,null);var o=new NodeContainer(t,null);o.blockFormattingContext=o,this.nodes=[o].concat(this.getChildren(o)).filter(function(t){return t.visible=t.isElementVisible()}),this.createStackingContexts(),this.sortStackingContexts(this.stack),this.parse(this.stack)}function i(t){return 0>t.cssInt("zIndex")}function s(t){return t.cssInt("zIndex")>0}function c(t){return 0===t.cssInt("zIndex")}function a(t){return-1!==["inline","inline-block","inline-table"].indexOf(t.css("display"))}function h(t){return t instanceof StackingContext}function d(t){return t.node.data.trim().length>0}function p(t){return/^(normal|none|0px)$/.test(t.parent.css("letterSpacing"))}function u(t,e,n,o,r,i,s){e[0]>0||e[1]>0?(t.push(["line",o[0].start.x,o[0].start.y]),o[0].curveTo(t),o[1].curveTo(t)):t.push(["line",i,s]),(n[0]>0||n[1]>0)&&t.push(["line",r[0].start.x,r[0].start.y])}function l(t){return["TopLeft","TopRight","BottomRight","BottomLeft"].map(function(e){var n=t.css("border"+e+"Radius"),o=n.split(" ");return 1>=o.length&&(o[1]=o[0]),o.map(f)})}function f(t){return parseInt(t,10)}function g(t,e,n,o){var r=4*((Math.sqrt(2)-1)/3),i=n*r,s=o*r,c=t+n,a=e+o;return{topLeft:x({x:t,y:a},{x:t,y:a-s},{x:c-i,y:e},{x:c,y:e}),topRight:x({x:t,y:e},{x:t+i,y:e},{x:c,y:a-s},{x:c,y:a}),bottomRight:x({x:c,y:e},{x:c,y:e+s},{x:t+i,y:a},{x:t,y:a}),bottomLeft:x({x:c,y:a},{x:c-i,y:a},{x:t,y:e+s},{x:t,y:e})}}function y(t,e,n){var o=t.left,r=t.top,i=t.width,s=t.height,c=e[0][0],a=e[0][1],h=e[1][0],d=e[1][1],p=e[2][0],u=e[2][1],l=e[3][0],f=e[3][1],y=i-h,x=s-u,m=i-p,w=s-f;return{topLeftOuter:g(o,r,c,a).topLeft.subdivide(.5),topLeftInner:g(o+n[3].width,r+n[0].width,Math.max(0,c-n[3].width),Math.max(0,a-n[0].width)).topLeft.subdivide(.5),topRightOuter:g(o+y,r,h,d).topRight.subdivide(.5),topRightInner:g(o+Math.min(y,i+n[3].width),r+n[0].width,y>i+n[3].width?0:h-n[3].width,d-n[0].width).topRight.subdivide(.5),bottomRightOuter:g(o+m,r+x,p,u).bottomRight.subdivide(.5),bottomRightInner:g(o+Math.min(m,i+n[3].width),r+Math.min(x,s+n[0].width),Math.max(0,p-n[1].width),Math.max(0,u-n[2].width)).bottomRight.subdivide(.5),bottomLeftOuter:g(o,r+w,l,f).bottomLeft.subdivide(.5),bottomLeftInner:g(o+n[3].width,r+w,Math.max(0,l-n[3].width),Math.max(0,f-n[2].width)).bottomLeft.subdivide(.5)}}function x(t,e,n,o){var r=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:o,subdivide:function(i){var s=r(t,e,i),c=r(e,n,i),a=r(n,o,i),h=r(s,c,i),d=r(c,a,i),p=r(h,d,i);return[x(t,s,h,p),x(p,d,a,o)]},curveTo:function(t){t.push(["bezierCurve",e.x,e.y,n.x,n.y,o.x,o.y])},curveToReversed:function(o){o.push(["bezierCurve",n.x,n.y,e.x,e.y,t.x,t.y])}}}function m(t,e,n,o,r,i,s){var c=[];return e[0]>0||e[1]>0?(c.push(["line",o[1].start.x,o[1].start.y]),o[1].curveTo(c)):c.push(["line",t.c1[0],t.c1[1]]),n[0]>0||n[1]>0?(c.push(["line",i[0].start.x,i[0].start.y]),i[0].curveTo(c),c.push(["line",s[0].end.x,s[0].end.y]),s[0].curveToReversed(c)):(c.push(["line",t.c2[0],t.c2[1]]),c.push(["line",t.c3[0],t.c3[1]])),e[0]>0||e[1]>0?(c.push(["line",r[1].end.x,r[1].end.y]),r[1].curveToReversed(c)):c.push(["line",t.c4[0],t.c4[1]]),c}function w(t){return t.node.nodeType!==Node.ELEMENT_NODE||-1===["SCRIPT","HEAD","TITLE","OBJECT","BR"].indexOf(t.node.nodeName)}function b(t){return[].concat.apply([],t)}function v(t){return t.nodeType===Node.TEXT_NODE||t.nodeType===Node.ELEMENT_NODE}function R(t){var e=t.css("position"),n="absolute"===e||"relative"===e?t.css("zIndex"):"auto";return"auto"!==n}function T(t){return"static"!==t.css("position")}function C(t){return"none"!==t.css("float")}function E(t){var e=this;return function(){return!t.apply(e,arguments)}}function B(t){return t.node.nodeType===Node.ELEMENT_NODE}function k(t){return t.node.nodeType===Node.TEXT_NODE}function I(t,e){return t.cssInt("zIndex")-e.cssInt("zIndex")}function L(t){return 1>t.css("opacity")}function O(){}function N(){return function(){throw Error("Render function not implemented")}}function S(){this.rangeBounds=this.testRangeBounds()}function M(){O.call(this),this.canvas=e.createElement("canvas"),this.canvas.width=t.innerWidth,this.canvas.height=t.innerHeight,this.ctx=this.canvas.getContext("2d"),this.ctx.textBaseline="bottom",e.body.appendChild(this.canvas)}t.html2canvas=function(i,s){var c=o(e,t.innerWidth,t.innerHeight),a=c.contentWindow;i===n?e.body:i[0];var h=new M,d=new r(a.document.documentElement,h,s||{});t.console.log(d),s.onrendered(h.canvas)},r.prototype.getChildren=function(t){return b([].filter.call(t.node.childNodes,v).map(function(e){var n=[e.nodeType===Node.TEXT_NODE?new TextContainer(e,t):new NodeContainer(e,t)].filter(w);return e.nodeType===Node.ELEMENT_NODE&&n.length?n.concat(this.getChildren(n[0])):n},this))},r.prototype.newStackingContext=function(t,e){var n=new StackingContext(e,t.cssFloat("opacity"),t.node,t.parent),o=n.getParentStack(this);o.contexts.push(n),t.stack=n},r.prototype.createStackingContexts=function(){this.nodes.forEach(function(t){B(t)&&(this.isRootElement(t)||L(t)||R(t)||this.isBodyWithTransparentRoot(t))?this.newStackingContext(t,!0):B(t)&&T(t)?this.newStackingContext(t,!1):t.assignStack(t.parent.stack)},this)},r.prototype.isBodyWithTransparentRoot=function(t){return"BODY"===t.node.nodeName&&this.renderer.isTransparent(t.parent.css("backgroundColor"))},r.prototype.isRootElement=function(t){return"HTML"===t.node.nodeName},r.prototype.sortStackingContexts=function(t){t.contexts.sort(I),t.contexts.forEach(this.sortStackingContexts,this)},r.prototype.parseBounds=function(t){return t.bounds=this.getBounds(t.node)},r.prototype.getBounds=function(t){if(t.getBoundingClientRect){var e=t.getBoundingClientRect();return{top:e.top,bottom:e.bottom||e.top+e.height,left:e.left,width:t.offsetWidth,height:t.offsetHeight}}return{}},r.prototype.parseTextBounds=function(t){return function(e,n,o){if("none"!==t.parent.css("textDecoration")||0!==e.trim().length){var r=o.slice(0,n).join("").length;if(this.support.rangeBounds)return this.getRangeBounds(t.node,r,e.length);if(t.node&&"string"==typeof t.node.data){var i=t.node.splitText(e.length),s=this.getWrapperBounds(t.node);return t.node=i,s}}}},r.prototype.getWrapperBounds=function(t){var e=t.ownerDocument.createElement("wrapper"),n=t.parentNode,o=t.cloneNode(!0);e.appendChild(t.cloneNode(!0)),n.replaceChild(e,t);var r=this.getBounds(e);return n.replaceChild(o,e),r},r.prototype.getRangeBounds=function(t,e,n){var o=this.range||(this.range=t.ownerDocument.createRange());return o.setStart(t,e),o.setEnd(t,e+n),o.getBoundingClientRect()},r.prototype.parse=function(e){var n=e.contexts.filter(i),o=e.children.filter(B).filter(E(C)),r=o.filter(E(T)).filter(E(a)),p=o.filter(E(T)).filter(C),u=o.filter(E(T)).filter(a),l=e.contexts.concat(o.filter(T)).filter(c),f=e.children.filter(k).filter(d),g=e.contexts.filter(s),y=[];n.concat(r).concat(p).concat(u).concat(l).concat(f).concat(g).forEach(function(e){if(this.paint(e),-1!==y.indexOf(e.node))throw t.console.log(e,e.node),Error("rendering twice");y.push(e.node),h(e)&&this.parse(e)},this)},r.prototype.paint=function(t){k(t)?this.paintText(t):this.paintNode(t)},r.prototype.paintNode=function(t){h(t)&&this.renderer.setOpacity(t.opacity);var e=this.parseBounds(t),n=this.parseBorders(t);this.renderer.clip(n.clip,function(){this.renderer.renderBackground(t,e)},this),this.renderer.renderBorders(n.borders)},r.prototype.paintText=function(t){t.applyTextTransform();var e=t.node.data.split(!this.options.letterRendering||p(t)?/(\b| )/:""),n=t.parent.fontWeight(),o=t.parent.css("fontSize"),r=t.parent.css("fontFamily");this.renderer.font(t.parent.css("color"),t.parent.css("fontStyle"),t.parent.css("fontVariant"),n,o,r),e.map(this.parseTextBounds(t),this).forEach(function(t,n){t&&this.renderer.text(e[n],t.left,t.bottom)},this)},r.prototype.parseBorders=function(t){var e=t.bounds,n=l(t),o=["Top","Right","Bottom","Left"].map(function(e){return{width:t.cssInt("border"+e+"Width"),color:t.css("border"+e+"Color"),args:null}}),r=y(e,n,o);return{clip:this.parseBackgroundClip(t,r,o,n,e),borders:o.map(function(t,i){if(t.width>0){var s=e.left,c=e.top,a=e.width,h=e.height-o[2].width;switch(i){case 0:h=o[0].width,t.args=m({c1:[s,c],c2:[s+a,c],c3:[s+a-o[1].width,c+h],c4:[s+o[3].width,c+h]},n[0],n[1],r.topLeftOuter,r.topLeftInner,r.topRightOuter,r.topRightInner);break;case 1:s=e.left+e.width-o[1].width,a=o[1].width,t.args=m({c1:[s+a,c],c2:[s+a,c+h+o[2].width],c3:[s,c+h],c4:[s,c+o[0].width]},n[1],n[2],r.topRightOuter,r.topRightInner,r.bottomRightOuter,r.bottomRightInner);break;case 2:c=c+e.height-o[2].width,h=o[2].width,t.args=m({c1:[s+a,c+h],c2:[s,c+h],c3:[s+o[3].width,c],c4:[s+a-o[3].width,c]},n[2],n[3],r.bottomRightOuter,r.bottomRightInner,r.bottomLeftOuter,r.bottomLeftInner);break;case 3:a=o[3].width,t.args=m({c1:[s,c+h+o[2].width],c2:[s,c],c3:[s+a,c+o[0].width],c4:[s+a,c+h]},n[3],n[0],r.bottomLeftOuter,r.bottomLeftInner,r.topLeftOuter,r.topLeftInner)}}return t})}},r.prototype.parseBackgroundClip=function(t,e,n,o,r){var i=t.css("backgroundClip"),s=[];switch(i){case"content-box":case"padding-box":u(s,o[0],o[1],e.topLeftInner,e.topRightInner,r.left+n[3].width,r.top+n[0].width),u(s,o[1],o[2],e.topRightInner,e.bottomRightInner,r.left+r.width-n[1].width,r.top+n[0].width),u(s,o[2],o[3],e.bottomRightInner,e.bottomLeftInner,r.left+r.width-n[1].width,r.top+r.height-n[2].width),u(s,o[3],o[0],e.bottomLeftInner,e.topLeftInner,r.left+n[3].width,r.top+r.height-n[2].width);break;default:u(s,o[0],o[1],e.topLeftOuter,e.topRightOuter,r.left,r.top),u(s,o[1],o[2],e.topRightOuter,e.bottomRightOuter,r.left+r.width,r.top),u(s,o[2],o[3],e.bottomRightOuter,e.bottomLeftOuter,r.left+r.width,r.top+r.height),u(s,o[3],o[0],e.bottomLeftOuter,e.topLeftOuter,r.left,r.top+r.height)}return s},O.prototype.renderBackground=function(t,e){e.height>0&&e.width>0&&(this.renderBackgroundColor(t,e),this.renderBackgroundImage(t,e))},O.prototype.renderBackgroundColor=function(t,e){var n=t.css("backgroundColor");this.isTransparent(n)||this.rectangle(e.left,e.top,e.width,e.height,t.css("backgroundColor"))},O.prototype.renderBorders=function(t){t.forEach(this.renderBorder,this)},O.prototype.renderBorder=function(t){this.isTransparent(t.color)||null===t.args||this.drawShape(t.args,t.color)},O.prototype.renderBackgroundImage=function(){},O.prototype.isTransparent=function(t){return!t||"transparent"===t||"rgba(0, 0, 0, 0)"===t},O.prototype.clip=N(),O.prototype.rectangle=N(),O.prototype.shape=N(),S.prototype.testRangeBounds=function(){var t,n,o,r,i=!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),o=t.getBoundingClientRect(),r=o.height,123===r&&(i=!0),e.body.removeChild(n))),i},M.prototype=Object.create(O.prototype),M.prototype.setFillStyle=function(t){return this.ctx.fillStyle=t,this.ctx},M.prototype.rectangle=function(t,e,n,o,r){this.setFillStyle(r).fillRect(t,e,n,o)},M.prototype.drawShape=function(t,e){this.shape(t),this.setFillStyle(e).fill()},M.prototype.clip=function(t,e,n){this.ctx.save(),this.shape(t).clip(),e.call(n),this.ctx.restore()},M.prototype.shape=function(t){return this.ctx.beginPath(),t.forEach(function(t,e){this.ctx[0===e?"moveTo":t[0]+"To"].apply(this.ctx,t.slice(1))},this),this.ctx.closePath(),this.ctx},M.prototype.font=function(t,e,n,o,r,i){this.setFillStyle(t).font=[e,n,o,r,i].join(" ")},M.prototype.setOpacity=function(t){this.ctx.globalAlpha=t},M.prototype.text=function(t,e,n){this.ctx.fillText(t,e,n)}})(window,document);