11/*
2- * html2canvas v0.26 <http://html2canvas.hertzen.com>
2+ * html2canvas v0.27 <http://html2canvas.hertzen.com>
33 * Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
44 * http://www.twitter.com/niklasvh
55 *
@@ -737,7 +737,7 @@ html2canvas.prototype.newElement = function(el,parentStack){
737737 stack.clip.width = stack.clip.width-(borders[1].width);
738738 stack.clip.height = stack.clip.height-(borders[2].width);
739739 }
740- */
740+ */
741741 if ( this . ignoreRe . test ( el . nodeName ) && this . opts . iframeDefault != "transparent" ) {
742742 if ( this . opts . iframeDefault == "default" ) {
743743 bgcolor = "#efefef" ;
@@ -780,26 +780,59 @@ html2canvas.prototype.newElement = function(el,parentStack){
780780 this . drawBackground ( el , bgbounds , ctx ) ;
781781 }
782782
783- if ( el . nodeName == "IMG" ) {
784- image = _ . loadImage ( _ . getAttr ( el , 'src' ) ) ;
785- if ( image ) {
786- // console.log(image.width);
787- this . drawImage (
788- ctx ,
789- image ,
790- 0 , //sx
791- 0 , //sy
792- image . width , //sw
793- image . height , //sh
794- x + parseInt ( _ . getCSS ( el , 'padding-left' ) , 10 ) + borders [ 3 ] . width , //dx
795- y + parseInt ( _ . getCSS ( el , 'padding-top' ) , 10 ) + borders [ 0 ] . width , // dy
796- bounds . width - ( borders [ 1 ] . width + borders [ 3 ] . width + parseInt ( _ . getCSS ( el , 'padding-left' ) , 10 ) + parseInt ( _ . getCSS ( el , 'padding-right' ) , 10 ) ) , //dw
797- bounds . height - ( borders [ 0 ] . width + borders [ 2 ] . width + parseInt ( _ . getCSS ( el , 'padding-top' ) , 10 ) + parseInt ( _ . getCSS ( el , 'padding-bottom' ) , 10 ) ) //dh
798- ) ;
783+ switch ( el . nodeName ) {
784+ case "IMG" :
785+ image = _ . loadImage ( _ . getAttr ( el , 'src' ) ) ;
786+ if ( image ) {
787+ // console.log(image.width);
788+ this . drawImage (
789+ ctx ,
790+ image ,
791+ 0 , //sx
792+ 0 , //sy
793+ image . width , //sw
794+ image . height , //sh
795+ x + parseInt ( _ . getCSS ( el , 'padding-left' ) , 10 ) + borders [ 3 ] . width , //dx
796+ y + parseInt ( _ . getCSS ( el , 'padding-top' ) , 10 ) + borders [ 0 ] . width , // dy
797+ bounds . width - ( borders [ 1 ] . width + borders [ 3 ] . width + parseInt ( _ . getCSS ( el , 'padding-left' ) , 10 ) + parseInt ( _ . getCSS ( el , 'padding-right' ) , 10 ) ) , //dw
798+ bounds . height - ( borders [ 0 ] . width + borders [ 2 ] . width + parseInt ( _ . getCSS ( el , 'padding-top' ) , 10 ) + parseInt ( _ . getCSS ( el , 'padding-bottom' ) , 10 ) ) //dh
799+ ) ;
799800
800- } else {
801- this . log ( "Error loading <img>:" + _ . getAttr ( el , 'src' ) ) ;
802- }
801+ } else {
802+ this . log ( "Error loading <img>:" + _ . getAttr ( el , 'src' ) ) ;
803+ }
804+ break ;
805+ case "INPUT" :
806+ // TODO add all relevant type's, i.e. HTML5 new stuff
807+ // todo add support for placeholder attribute for browsers which support it
808+ if ( / ^ ( t e x t | u r l | e m a i l | s u b m i t | b u t t o n | r e s e t ) $ / . test ( el . type ) && el . value . length > 0 ) {
809+
810+ this . renderFormValue ( el , bounds , stack ) ;
811+
812+
813+ /*
814+ this just doesn't work well enough
815+
816+ this.newText(el,{
817+ nodeValue:el.value,
818+ splitText: function(){
819+ return this;
820+ },
821+ formValue:true
822+ },stack);
823+ */
824+ }
825+ break ;
826+ case "TEXTAREA" :
827+ if ( el . value . length > 0 ) {
828+ this . renderFormValue ( el , bounds , stack ) ;
829+ }
830+ break ;
831+ case "SELECT" :
832+ if ( el . options . length > 0 ) {
833+ this . renderFormValue ( el , bounds , stack ) ;
834+ }
835+ break ;
803836 }
804837
805838
@@ -816,8 +849,8 @@ html2canvas.prototype.newElement = function(el,parentStack){
816849
817850
818851/*
819- * Function to draw the text on the canvas
820- */
852+ * Function to draw the text on the canvas
853+ */
821854
822855html2canvas . prototype . printText = function ( currentText , x , y , ctx ) {
823856 if ( this . trim ( currentText ) . length > 0 ) {
@@ -852,6 +885,44 @@ html2canvas.prototype.drawImage = function(ctx,image,sx,sy,sw,sh,dx,dy,dw,dh){
852885 ) ;
853886 this . numDraws ++ ;
854887
888+ }
889+ html2canvas . prototype . renderFormValue = function ( el , bounds , stack ) {
890+
891+ var valueWrap = document . createElement ( 'valuewrap' ) ,
892+ _ = this ;
893+
894+ this . each ( [ 'lineHeight' , 'textAlign' , 'fontFamily' , 'color' , 'fontSize' , 'paddingLeft' , 'paddingTop' , 'width' , 'height' , 'border' , 'borderLeftWidth' , 'borderTopWidth' ] , function ( i , style ) {
895+ valueWrap . style [ style ] = _ . getCSS ( el , style ) ;
896+ } ) ;
897+
898+ valueWrap . style . borderColor = "black" ;
899+ valueWrap . style . borderStyle = "solid" ;
900+ valueWrap . style . display = "block" ;
901+ valueWrap . style . position = "absolute" ;
902+ if ( / ^ ( s u b m i t | r e s e t | b u t t o n | t e x t | p a s s w o r d ) $ / . test ( el . type ) || el . nodeName == "SELECT" ) {
903+ valueWrap . style . lineHeight = _ . getCSS ( el , "height" ) ;
904+ }
905+
906+
907+ valueWrap . style . top = bounds . top + "px" ;
908+ valueWrap . style . left = bounds . left + "px" ;
909+ if ( el . nodeName == "SELECT" ) {
910+ // TODO increase accuracy of text position
911+ var textValue = el . options [ el . selectedIndex ] . text ;
912+ } else {
913+ var textValue = el . value ;
914+
915+ }
916+ var textNode = document . createTextNode ( textValue ) ;
917+
918+ valueWrap . appendChild ( textNode ) ;
919+ $ ( 'body' ) . append ( valueWrap ) ;
920+
921+ this . newText ( el , textNode , stack ) ;
922+
923+ $ ( valueWrap ) . remove ( ) ;
924+
925+
855926}
856927/*
857928 * Function to find all images from <img> and background-image
@@ -1331,7 +1402,7 @@ html2canvas.prototype.setContextVariable = function(ctx,variable,value){
13311402
13321403}
13331404
1334- html2canvas . prototype . newText = function ( el , textNode , stack ) {
1405+ html2canvas . prototype . newText = function ( el , textNode , stack , form ) {
13351406 var ctx = stack . ctx ;
13361407 var family = this . getCSS ( el , "font-family" ) ;
13371408 var size = this . getCSS ( el , "font-size" ) ;
@@ -1346,7 +1417,7 @@ html2canvas.prototype.newText = function(el,textNode,stack){
13461417
13471418
13481419 var letter_spacing = this . getCSS ( el , "letter-spacing" ) ;
1349-
1420+
13501421 // apply text-transform:ation to the text
13511422 textNode . nodeValue = this . textTransform ( textNode . nodeValue , this . getCSS ( el , "text-transform" ) ) ;
13521423 var text = this . trim ( textNode . nodeValue ) ;
@@ -1400,79 +1471,81 @@ html2canvas.prototype.newText = function(el,textNode,stack){
14001471 }
14011472*/
14021473
1403-
14041474
1405-
1406- var oldTextNode = textNode ;
1407- for ( var c = 0 ; c < renderList . length ; c ++ ) {
14081475
1409- // TODO only do the splitting for non-range prints
1410- var newTextNode = oldTextNode . splitText ( renderList [ c ] . length ) ;
1476+
1477+ var oldTextNode = textNode ;
1478+ for ( var c = 0 ; c < renderList . length ; c ++ ) {
1479+
1480+ // TODO only do the splitting for non-range prints
1481+
1482+ var newTextNode = oldTextNode . splitText ( renderList [ c ] . length ) ;
14111483
1412- if ( text_decoration != "none" || this . trim ( oldTextNode . nodeValue ) . length != 0 ) {
1484+ if ( text_decoration != "none" || this . trim ( oldTextNode . nodeValue ) . length != 0 ) {
14131485
14141486
14151487
14161488
1417- if ( this . support . rangeBounds ) {
1418- // getBoundingClientRect is supported for ranges
1419- if ( document . createRange ) {
1420- var range = document . createRange ( ) ;
1421- range . selectNode ( oldTextNode ) ;
1422- } else {
1423- // TODO add IE support
1424- var range = document . body . createTextRange ( ) ;
1425- }
1426- if ( range . getBoundingClientRect ( ) ) {
1427- var bounds = range . getBoundingClientRect ( ) ;
1489+ if ( this . support . rangeBounds ) {
1490+ // getBoundingClientRect is supported for ranges
1491+ if ( document . createRange ) {
1492+ var range = document . createRange ( ) ;
1493+ range . selectNode ( oldTextNode ) ;
1494+ } else {
1495+ // TODO add IE support
1496+ var range = document . body . createTextRange ( ) ;
1497+ }
1498+ if ( range . getBoundingClientRect ( ) ) {
1499+ var bounds = range . getBoundingClientRect ( ) ;
1500+ } else {
1501+ var bounds = { } ;
1502+ }
14281503 } else {
1429- var bounds = { } ;
1430- }
1431- } else {
1432- // it isn't supported, so let's wrap it inside an element instead and the bounds there
1504+ // it isn't supported, so let's wrap it inside an element instead and the bounds there
14331505
1434- var parent = oldTextNode . parentNode ;
1435- var wrapElement = document . createElement ( 'wrapper' ) ;
1436- var backupText = oldTextNode . cloneNode ( true ) ;
1437- wrapElement . appendChild ( oldTextNode . cloneNode ( true ) ) ;
1438- parent . replaceChild ( wrapElement , oldTextNode ) ;
1506+ var parent = oldTextNode . parentNode ;
1507+ var wrapElement = document . createElement ( 'wrapper' ) ;
1508+ var backupText = oldTextNode . cloneNode ( true ) ;
1509+ wrapElement . appendChild ( oldTextNode . cloneNode ( true ) ) ;
1510+ parent . replaceChild ( wrapElement , oldTextNode ) ;
14391511
1440- var bounds = this . getBounds ( wrapElement ) ;
1512+ var bounds = this . getBounds ( wrapElement ) ;
14411513
14421514
1443- parent . replaceChild ( backupText , wrapElement ) ;
1444- }
1515+ parent . replaceChild ( backupText , wrapElement ) ;
1516+ }
14451517
14461518
14471519
14481520
1449- // console.log(range);
1450- // console.log("'"+oldTextNode.nodeValue+"'"+bounds.left)
1451- this . printText ( oldTextNode . nodeValue , bounds . left , bounds . bottom , ctx ) ;
1521+ // console.log(range);
1522+ // console.log("'"+oldTextNode.nodeValue+"'"+bounds.left)
1523+ this . printText ( oldTextNode . nodeValue , bounds . left , bounds . bottom , ctx ) ;
14521524
1453- switch ( text_decoration ) {
1454- case "underline" :
1455- // Draws a line at the baseline of the font
1456- // TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size
1457- this . newRect ( ctx , bounds . left , Math . round ( bounds . top + metrics . baseline + metrics . lineWidth ) , bounds . width , 1 , color ) ;
1458- break ;
1459- case "overline" :
1460- this . newRect ( ctx , bounds . left , bounds . top , bounds . width , 1 , color ) ;
1461- break ;
1462- case "line-through" :
1463- // TODO try and find exact position for line-through
1464- this . newRect ( ctx , bounds . left , Math . ceil ( bounds . top + metrics . middle + metrics . lineWidth ) , bounds . width , 1 , color ) ;
1465- break ;
1525+ switch ( text_decoration ) {
1526+ case "underline" :
1527+ // Draws a line at the baseline of the font
1528+ // TODO As some browsers display the line as more than 1px if the font-size is big, need to take that into account both in position and size
1529+ this . newRect ( ctx , bounds . left , Math . round ( bounds . top + metrics . baseline + metrics . lineWidth ) , bounds . width , 1 , color ) ;
1530+ break ;
1531+ case "overline" :
1532+ this . newRect ( ctx , bounds . left , bounds . top , bounds . width , 1 , color ) ;
1533+ break ;
1534+ case "line-through" :
1535+ // TODO try and find exact position for line-through
1536+ this . newRect ( ctx , bounds . left , Math . ceil ( bounds . top + metrics . middle + metrics . lineWidth ) , bounds . width , 1 , color ) ;
1537+ break ;
14661538
1467- }
1539+ }
14681540
1469- }
1541+ }
14701542
1471- oldTextNode = newTextNode ;
1543+ oldTextNode = newTextNode ;
14721544
14731545
14741546
1475- }
1547+ }
1548+
14761549
14771550
14781551 }
@@ -1663,18 +1736,18 @@ html2canvas.prototype.withinBounds = function(src,dst){
16631736
16641737html2canvas . prototype . clipBounds = function ( src , dst ) {
16651738
1666- var x = Math . max ( src . left , dst . left ) ;
1667- var y = Math . max ( src . top , dst . top ) ;
1739+ var x = Math . max ( src . left , dst . left ) ;
1740+ var y = Math . max ( src . top , dst . top ) ;
16681741
1669- var x2 = Math . min ( ( src . left + src . width ) , ( dst . left + dst . width ) ) ;
1670- var y2 = Math . min ( ( src . top + src . height ) , ( dst . top + dst . height ) ) ;
1742+ var x2 = Math . min ( ( src . left + src . width ) , ( dst . left + dst . width ) ) ;
1743+ var y2 = Math . min ( ( src . top + src . height ) , ( dst . top + dst . height ) ) ;
16711744
1672- return {
1673- left :x ,
1674- top :y ,
1675- width :x2 - x ,
1676- height :y2 - y
1677- } ;
1745+ return {
1746+ left :x ,
1747+ top :y ,
1748+ width :x2 - x ,
1749+ height :y2 - y
1750+ } ;
16781751
16791752}
16801753
@@ -1706,8 +1779,8 @@ html2canvas.prototype.getBounds = function(el){
17061779 var p = $ ( el ) . offset ( ) ;
17071780
17081781 return {
1709- left : p . left + parseInt ( this . getCSS ( el , "border-left-width" ) , 10 ) ,
1710- top : p . top + parseInt ( this . getCSS ( el , "border-top-width" ) , 10 ) ,
1782+ left : p . left + this . getCSS ( el , "border-left-width" , true ) ,
1783+ top : p . top + this . getCSS ( el , "border-top-width" , true ) ,
17111784 width :$ ( el ) . innerWidth ( ) ,
17121785 height :$ ( el ) . innerHeight ( )
17131786 }
@@ -1786,7 +1859,7 @@ html2canvas.prototype.formatZ = function(zindex,position,parentZ,parentNode){
17861859 if ( parentPosition != "static" && typeof parentPosition != "undefined" ) {
17871860 zindex = 0 ;
17881861 }
1789- /*else{
1862+ /*else{
17901863 return parentZ;
17911864 }*/
17921865 }
@@ -1818,8 +1891,12 @@ html2canvas.prototype.getContents = function(el){
18181891 * Function for fetching the css attribute
18191892 * TODO remove jQuery dependancy
18201893 */
1821- html2canvas . prototype . getCSS = function ( el , attribute ) {
1822- return $ ( el ) . css ( attribute ) ;
1894+ html2canvas . prototype . getCSS = function ( el , attribute , intOnly ) {
1895+ if ( intOnly ) {
1896+ return parseInt ( $ ( el ) . css ( attribute ) , 10 ) ;
1897+ } else {
1898+ return $ ( el ) . css ( attribute ) ;
1899+ }
18231900}
18241901
18251902
0 commit comments