From 44023015b663b86c17b72c3893666deb7b6ffaa9 Mon Sep 17 00:00:00 2001 From: Niklas von Hertzen Date: Sun, 25 Nov 2012 23:05:30 +0200 Subject: [PATCH] Refactoring --- src/Parse.js | 311 +++++++-------------------------------------------- 1 file changed, 42 insertions(+), 269 deletions(-) diff --git a/src/Parse.js b/src/Parse.js index f346183..c94f325 100644 --- a/src/Parse.js +++ b/src/Parse.js @@ -34,7 +34,6 @@ _html2canvas.Parse = function ( images, options ) { })() }, element = (( options.elements === undefined ) ? document.body : options.elements[0]), // select body by default - needReorder = false, numDraws = 0, fontData = {}, doc = element.ownerDocument, @@ -92,14 +91,10 @@ _html2canvas.Parse = function ( images, options ) { support.rangeBounds = true; } body.removeChild(testElement); - - } } - - var getCSS = _html2canvas.Util.getCSS; function getCSSInt(element, attribute) { var val = parseInt(getCSS(element, attribute), 10); @@ -108,14 +103,13 @@ _html2canvas.Parse = function ( images, options ) { // Drawing a rectangle function renderRect (ctx, x, y, w, h, bgcolor) { - if ( bgcolor !== "transparent" ){ + if (bgcolor !== "transparent"){ ctx.setVariable("fillStyle", bgcolor); ctx.fillRect (x, y, w, h); numDraws+=1; } } - function textTransform (text, transform) { switch(transform){ case "lowercase": @@ -135,7 +129,10 @@ _html2canvas.Parse = function ( images, options ) { return text; } + } + function noLetterSpacing(letter_spacing) { + return (/^(normal|none|0px)$/.test(letter_spacing)); } function trimText (text) { @@ -148,7 +145,6 @@ _html2canvas.Parse = function ( images, options ) { return fontData[font + "-" + fontSize]; } - var container = doc.createElement('div'), img = doc.createElement('img'), span = doc.createElement('span'), @@ -156,7 +152,6 @@ _html2canvas.Parse = function ( images, options ) { middle, metricsObj; - container.style.visibility = "hidden"; container.style.fontFamily = font; container.style.fontSize = fontSize; @@ -165,8 +160,6 @@ _html2canvas.Parse = function ( images, options ) { body.appendChild(container); - - // http://probablyprogramming.com/2009/03/15/the-tiniest-gif-ever (handtinywhite.gif) img.src = "data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACwAAAAAAQABAAACAkQBADs="; img.width = 1; @@ -181,9 +174,6 @@ _html2canvas.Parse = function ( images, options ) { span.style.margin = 0; span.style.padding = 0; - - - span.appendChild(doc.createTextNode('Hidden Text')); container.appendChild(span); container.appendChild(img); @@ -202,24 +192,20 @@ _html2canvas.Parse = function ( images, options ) { middle: middle }; - fontData[font + "-" + fontSize] = metricsObj; body.removeChild(container); return metricsObj; - } - function drawText(currentText, x, y, ctx){ - if (trimText(currentText).length>0) { - ctx.fillText(currentText,x,y); + if (trimText(currentText).length > 0) { + ctx.fillText(currentText, x, y); numDraws+=1; } } - function renderText(el, textNode, stack) { var ctx = stack.ctx, family = getCSS(el, "fontFamily"), @@ -247,10 +233,6 @@ _html2canvas.Parse = function ( images, options ) { wrapElement, backupText; - // apply text-transform:ation to the text - - - textNode.nodeValue = textTransform(textNode.nodeValue, getCSS(el, "textTransform")); text = trimText(textNode.nodeValue); @@ -262,14 +244,7 @@ _html2canvas.Parse = function ( images, options ) { text_align = text_align.replace(["-webkit-auto"],["auto"]); - if (options.letterRendering === false && /^(left|right|justify|auto)$/.test(text_align) && /^(normal|none|0px)$/.test(letter_spacing)){ - // this.setContextVariable(ctx,"textAlign",text_align); - renderList = textNode.nodeValue.split(/(\b| )/); - - }else{ - // this.setContextVariable(ctx,"textAlign","left"); - renderList = textNode.nodeValue.split(""); - } + renderList = (!options.letterRendering && /^(left|right|justify|auto)$/.test(text_align) && noLetterSpacing(letter_spacing)) ? textNode.nodeValue.split(/(\b| )/) : textNode.nodeValue.split(""); switch(parseInt(bold, 10)){ case 401: @@ -281,36 +256,14 @@ _html2canvas.Parse = function ( images, options ) { } ctx.setVariable("fillStyle", color); - - /* - need to be defined in the order as defined in http://www.w3.org/TR/CSS21/fonts.html#font-shorthand - to properly work in Firefox - */ ctx.setVariable("font", font_style+ " " + font_variant + " " + bold + " " + size + " " + family); - - if (align){ - ctx.setVariable("textAlign", "right"); - }else{ - ctx.setVariable("textAlign", "left"); - } - - - /* - if (stack.clip){ - ctx.rect (stack.clip.left, stack.clip.top, stack.clip.width, stack.clip.height); - ctx.clip(); - } - */ - + ctx.setVariable("textAlign", (align) ? "right" : "left"); oldTextNode = textNode; - for ( c=0, listLen = renderList.length; c < listLen; c+=1 ) { textValue = null; - - if (support.rangeBounds){ // getBoundingClientRect is supported for ranges if (text_decoration !== "none" || trimText(renderList[c]).length !== 0) { @@ -356,7 +309,6 @@ _html2canvas.Parse = function ( images, options ) { oldTextNode = newTextNode; parent.replaceChild(backupText, wrapElement); - } if (textValue !== null){ @@ -376,19 +328,12 @@ _html2canvas.Parse = function ( images, options ) { // TODO try and find exact position for line-through renderRect(ctx, bounds.left, Math.ceil(bounds.top + metrics.middle + metrics.lineWidth), bounds.width, 1, color); break; - } - - - - textOffset += renderList[c].length; } - - } } @@ -399,23 +344,18 @@ _html2canvas.Parse = function ( images, options ) { bounds; boundElement.style.display = "inline"; - //boundElement.style.width = "1px"; - //boundElement.style.height = "1px"; type = element.style.listStyleType; element.style.listStyleType = "none"; boundElement.appendChild( doc.createTextNode( val ) ); - element.insertBefore(boundElement, element.firstChild); - bounds = _html2canvas.Util.Bounds( boundElement ); element.removeChild( boundElement ); element.style.listStyleType = type; return bounds; - } @@ -439,8 +379,6 @@ _html2canvas.Parse = function ( images, options ) { } function renderListItem(element, stack, elBounds) { - - var position = getCSS(element, "listStylePosition"), x, y, @@ -479,12 +417,9 @@ _html2canvas.Parse = function ( images, options ) { break; } - text += ". "; listBounds = listPosition(element, text); - - switch(bold){ case 401: bold = "bold"; @@ -494,40 +429,21 @@ _html2canvas.Parse = function ( images, options ) { break; } - - - ctx.setVariable( "fillStyle", getCSS(element, "color") ); ctx.setVariable( "font", getCSS(element, "fontVariant") + " " + bold + " " + getCSS(element, "fontStyle") + " " + getCSS(element, "fontSize") + " " + getCSS(element, "fontFamily") ); - if ( position === "inside" ) { ctx.setVariable("textAlign", "left"); // this.setFont(stack.ctx, element, false); x = elBounds.left; - - }else{ + } else { return; - /* - TODO really need to figure out some more accurate way to try and find the position. - as defined in http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-position, it does not even have a specified "correct" position, so each browser - may display it whatever way it feels like. - "The position of the list-item marker adjacent to floats is undefined in CSS 2.1. CSS 2.1 does not specify the precise location of the marker box or its position in the painting order" - - ctx.setVariable("textAlign", "right"); - // this.setFont(stack.ctx, element, true); - x = elBounds.left - 10; - */ } y = listBounds.bottom; drawText(text, x, y, ctx); - - } - - } function loadImage (src){ @@ -539,13 +455,7 @@ _html2canvas.Parse = function ( images, options ) { } } - - - - - function clipBounds(src, dst){ - var x = Math.max(src.left, dst.left), y = Math.max(src.top, dst.top), x2 = Math.min((src.left + src.width), (dst.left + dst.width)), @@ -557,7 +467,6 @@ _html2canvas.Parse = function ( images, options ) { width:x2-x, height:y2-y }; - } function setZ(zIndex, parentZ){ @@ -569,7 +478,6 @@ _html2canvas.Parse = function ( images, options ) { } if (zIndex !== "auto"){ - needReorder = true; newContext = h2czContext(zIndex); parentZ.children.push(newContext); return newContext; @@ -577,15 +485,9 @@ _html2canvas.Parse = function ( images, options ) { } return parentZ; - } function renderBorders(el, ctx, bounds, clip){ - - /* - * TODO add support for different border-style's than solid - */ - var x = bounds.left, y = bounds.top, w = bounds.width, @@ -667,7 +569,6 @@ _html2canvas.Parse = function ( images, options ) { by = (by + h) - (borders[2].width); bh = borders[2].width; - i = 0; borderArgs[ i++ ] = [ "line", bx + borders[ 3 ].width, by ]; // top left borderArgs[ i++ ] = [ "line", bx + bw - borders[ 2 ].width, by ]; // top right @@ -715,10 +616,6 @@ _html2canvas.Parse = function ( images, options ) { numDraws+=1; } - - - - // renderRect(ctx, bx, by, borderBounds.width, borderBounds.height, borderData.color); } @@ -751,7 +648,6 @@ _html2canvas.Parse = function ( images, options ) { } } - valueWrap.style.borderColor = "black"; valueWrap.style.borderStyle = "solid"; valueWrap.style.display = "block"; @@ -760,50 +656,24 @@ _html2canvas.Parse = function ( images, options ) { valueWrap.style.lineHeight = getCSS(el, "height"); } - valueWrap.style.top = bounds.top + "px"; valueWrap.style.left = bounds.left + "px"; - if (el.nodeName === "SELECT"){ - // TODO increase accuracy of text position - textValue = el.options[el.selectedIndex].text; - } else{ - textValue = el.value; - } + textValue = (el.nodeName === "SELECT") ? el.options[el.selectedIndex].text : el.value; textNode = doc.createTextNode(textValue); valueWrap.appendChild(textNode); body.appendChild(valueWrap); - renderText(el, textNode, stack); body.removeChild(valueWrap); - - - } - - - - - function renderImage (ctx, image, sx, sy, sw, sh, dx, dy, dw, dh) { - ctx.drawImage( - image, - sx, //sx - sy, //sy - sw, //sw - sh, //sh - dx, //dx - dy, // dy - dw, //dw - dh //dh - ); + function renderImage (ctx) { + ctx.drawImage.apply(ctx, Array.prototype.slice.call(arguments,1)); numDraws+=1; - } - function renderBackgroundRepeat (ctx, image, x, y, width, height, elx, ely){ var sourceX = 0, sourceY=0; @@ -831,50 +701,30 @@ _html2canvas.Parse = function ( images, options ) { function renderBackgroundRepeatY (ctx, image, bgp, x, y, w, h){ - var height, - width = Math.min(image.width,w),bgy; + width = Math.min(image.width, w), + bgy; - bgp.top = bgp.top-Math.ceil(bgp.top/image.height)*image.height; - - - for(bgy=(y+bgp.top);bgyh+y){ - height = (h+y)-bgy; - }else{ - height = image.height; - } - renderBackgroundRepeat(ctx,image,x+bgp.left,bgy,width,height,x,y); - - bgy = Math.floor(bgy+image.height); + bgp.top -= Math.ceil(bgp.top / image.height) * image.height; + for(bgy=(y + bgp.top);bgy < h + y;){ + height = (Math.floor(bgy + image.height) > h + y) ? (h+y) - bgy : image.height; + renderBackgroundRepeat(ctx, image, x+bgp.left, bgy,width, height, x, y); + bgy = Math.floor(bgy + image.height); } } function renderBackgroundRepeatX(ctx, image, bgp, x, y, w, h){ + var height = Math.min(image.height, h), + width, + bgx; - var height = Math.min(image.height,h), - width,bgx; - - - bgp.left = bgp.left-Math.ceil(bgp.left/image.width)*image.width; - - - for (bgx=(x+bgp.left);bgxw+x){ - width = (w+x)-bgx; - }else{ - width = image.width; - } - - renderBackgroundRepeat(ctx,image,bgx,(y+bgp.top),width,height,x,y); - - bgx = Math.floor(bgx+image.width); - + bgp.left -= Math.ceil(bgp.left / image.width) * image.width; + for (bgx=(x + bgp.left); bgx < w + x;) { + width = (Math.floor(bgx + image.width) > w + x) ? (w + x) - bgx : image.width; + renderBackgroundRepeat(ctx, image, bgx,(y + bgp.top), width, height, x, y); + bgx = Math.floor(bgx + image.width); } } @@ -912,7 +762,6 @@ _html2canvas.Parse = function ( images, options ) { // TODO add support for background-origin if ( image ){ switch ( background_repeat ) { - case "repeat-x": renderBackgroundRepeatX( ctx, image, bgp, bounds.left, bounds.top, bounds.width, bounds.height ); break; @@ -922,20 +771,6 @@ _html2canvas.Parse = function ( images, options ) { break; case "no-repeat": - /* - this.drawBackgroundRepeat( - ctx, - image, - bgp.left+bounds.left, // sx - bgp.top+bounds.top, // sy - Math.min(bounds.width,image.width), - Math.min(bounds.height,image.height), - bounds.left, - bounds.top - );*/ - - - bgw = bounds.width - bgp.left; bgh = bounds.height - bgp.top; bgsx = bgp.left; @@ -943,10 +778,6 @@ _html2canvas.Parse = function ( images, options ) { bgdx = bgp.left+bounds.left; bgdy = bgp.top+bounds.top; - // - // bgw = Math.min(bgw,image.width); - // bgh = Math.min(bgh,image.height); - if (bgsx<0){ bgsx = Math.abs(bgsx); bgdx += bgsx; @@ -966,7 +797,6 @@ _html2canvas.Parse = function ( images, options ) { bgsy = 0; } - if (bgh>0 && bgw > 0){ renderImage( ctx, @@ -984,35 +814,19 @@ _html2canvas.Parse = function ( images, options ) { } break; default: - - - bgp.top = bgp.top-Math.ceil(bgp.top/image.height)*image.height; - - for(bgy=(bounds.top+bgp.top);bgyh+bgy){ - height = (h+bgy)-bgy; - }else{ - height = image.height; - } - // console.log(height); - + height = (Math.floor(bgy+image.height) > h + bgy) ? (h+bgy)-bgy : image.height; if (bgy0){ bgp.top += add; } @@ -1020,11 +834,9 @@ _html2canvas.Parse = function ( images, options ) { } break; - } }else{ h2clog("html2canvas: Error loading background:" + background_image); - //console.log(images); } } @@ -1064,9 +876,6 @@ _html2canvas.Parse = function ( images, options ) { docDim = {}; } - - //var zindex = this.formatZ(this.getCSS(el,"zIndex"),cssPosition,parentStack.zIndex,el.parentNode); - zindex = setZ( getCSS( el, "zIndex"), parentStack.zIndex ); @@ -1084,20 +893,12 @@ _html2canvas.Parse = function ( images, options ) { if (parentStack.clip){ stack.clip = _html2canvas.Util.Extend( {}, parentStack.clip ); - //stack.clip = parentStack.clip; - // stack.clip.height = stack.clip.height - parentStack.borders[2].width; } - - if ( options.useOverflow === true && /(hidden|scroll|auto)/.test(getCSS(el, "overflow")) === true && /(BODY)/i.test(el.nodeName) === false ){ - if (stack.clip){ - stack.clip = clipBounds(stack.clip, bounds); - }else{ - stack.clip = bounds; - } + if (options.useOverflow === true && /(hidden|scroll|auto)/.test(getCSS(el, "overflow")) === true && /(BODY)/i.test(el.nodeName) === false){ + stack.clip = (stack.clip) ? clipBounds(stack.clip, bounds) : bounds; } - stackLength = zindex.children.push(stack); ctx = zindex.children[stackLength-1].ctx; @@ -1111,18 +912,8 @@ _html2canvas.Parse = function ( images, options ) { // let's modify clip area for child elements, so borders dont get overwritten - /* - if (stack.clip){ - stack.clip.width = stack.clip.width-(borders[1].width); - stack.clip.height = stack.clip.height-(borders[2].width); - } - */ if (ignoreElementsRegExp.test(el.nodeName) && options.iframeDefault !== "transparent"){ - if (options.iframeDefault === "default"){ - bgcolor = "#efefef"; - }else{ - bgcolor = options.iframeDefault; - } + bgcolor = (options.iframeDefault === "default") ? "#efefef" : options.iframeDefault; } // draw base element bgcolor @@ -1134,13 +925,9 @@ _html2canvas.Parse = function ( images, options ) { height: h - (borders[0].width + borders[2].width) }; - //if (this.withinBounds(stack.clip,bgbounds)){ if (stack.clip){ bgbounds = clipBounds(bgbounds, stack.clip); - - //} - } @@ -1190,21 +977,7 @@ _html2canvas.Parse = function ( images, options ) { // TODO add all relevant type's, i.e. HTML5 new stuff // todo add support for placeholder attribute for browsers which support it if (/^(text|url|email|submit|button|reset)$/.test(el.type) && el.value.length > 0){ - renderFormValue(el, bounds, stack); - - - /* - this just doesn't work well enough - - this.newText(el,{ - nodeValue:el.value, - splitText: function(){ - return this; - }, - formValue:true - },stack); - */ } break; case "TEXTAREA": @@ -1228,14 +1001,14 @@ _html2canvas.Parse = function ( images, options ) { renderImage( ctx, el, - 0, //sx - 0, //sy - el.width, //sw - el.height, //sh - x + paddingLeft + borders[3].width, //dx - y + paddingTop + borders[0].width, // dy - bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight), //dw - bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom) //dh + 0, + 0, + el.width, + el.height, + x + paddingLeft + borders[3].width, + y + paddingTop + borders[0].width, + bounds.width - (borders[1].width + borders[3].width + paddingLeft + paddingRight), + bounds.height - (borders[0].width + borders[2].width + paddingTop + paddingBottom) ); break; } @@ -1369,4 +1142,4 @@ function h2czContext(zindex) { zindex: zindex, children: [] }; -} +} \ No newline at end of file