From 6aa73c3b93702cda418d400c22de8a47c237af79 Mon Sep 17 00:00:00 2001
From: MoyuScript <i@moyu.moe>
Date: Tue, 6 Aug 2013 18:55:04 +0300
Subject: [PATCH] Refactoring logging and gradients

---
 src/Core.js             |  15 +++---
 src/Generate.js         | 107 +++++++++++++++++-----------------------
 src/Parse.js            |   8 +--
 src/Preload.js          |  30 ++++++-----
 src/Support.js          |   2 +-
 src/Util.js             |   4 +-
 src/renderers/Canvas.js |   4 +-
 src/renderers/SVG.js    |   2 +-
 8 files changed, 77 insertions(+), 95 deletions(-)

diff --git a/src/Core.js b/src/Core.js
index 5e6016b..5148497 100644
--- a/src/Core.js
+++ b/src/Core.js
@@ -5,18 +5,17 @@ previousElement,
 computedCSS,
 html2canvas;
 
-function h2clog(a) {
+_html2canvas.Util = {};
+
+_html2canvas.Util.log = function(a) {
   if (_html2canvas.logging && window.console && window.console.log) {
     window.console.log(a);
   }
-}
-
-_html2canvas.Util = {};
+};
 
 _html2canvas.Util.trimText = (function(isNative){
-  return function(input){
-    if(isNative) { return isNative.apply( input ); }
-    else { return ((input || '') + '').replace( /^\s+|\s+$/g , '' ); }
+  return function(input) {
+    return isNative ? isNative.apply(input) : ((input || '') + '').replace( /^\s+|\s+$/g , '' );
   };
 })(String.prototype.trim);
 
@@ -386,7 +385,7 @@ _html2canvas.Util.Children = function( elem ) {
     })(elem.childNodes);
 
   } catch (ex) {
-    h2clog("html2canvas.Util.Children failed with exception: " + ex.message);
+    _html2canvas.Util.log("html2canvas.Util.Children failed with exception: " + ex.message);
     children = [];
   }
   return children;
diff --git a/src/Generate.js b/src/Generate.js
index eff6b0b..bf3c7cc 100644
--- a/src/Generate.js
+++ b/src/Generate.js
@@ -1,6 +1,8 @@
 (function(){
+  var Util = _html2canvas.Util,
+    Generate = {};
 
-  _html2canvas.Generate = {};
+  _html2canvas.Generate = Generate;
 
   var reGradients = [
   /^(-webkit-linear-gradient)\(([a-z\s]+)([\w\d\.\s,%\(\)]+)\)$/,
@@ -18,7 +20,7 @@
  * TODO: Add old Webkit -webkit-gradient(radial, ...) support
  * TODO: Maybe some RegExp optimizations are possible ;o)
  */
-  _html2canvas.Generate.parseGradient = function(css, bounds) {
+  Generate.parseGradient = function(css, bounds) {
     var gradient, i, len = reGradients.length, m1, stop, m2, m2Len, step, m3, tl,tr,br,bl;
 
     for(i = 0; i < len; i+=1){
@@ -320,14 +322,25 @@
     return gradient;
   };
 
-  _html2canvas.Generate.Gradient = function(src, bounds) {
+  function addScrollStops(grad) {
+    return function(colorStop) {
+      try {
+        grad.addColorStop(colorStop.stop, colorStop.color);
+      }
+      catch(e) {
+        Util.log(['failed to add color stop: ', e, '; tried to add: ', colorStop]);
+      }
+    };
+  }
+
+  Generate.Gradient = function(src, bounds) {
     if(bounds.width === 0 || bounds.height === 0) {
       return;
     }
 
     var canvas = document.createElement('canvas'),
     ctx = canvas.getContext('2d'),
-    gradient, grad, i, len;
+    gradient, grad;
 
     canvas.width = bounds.width;
     canvas.height = bounds.height;
@@ -336,72 +349,46 @@
     gradient = _html2canvas.Generate.parseGradient(src, bounds);
 
     if(gradient) {
-      if(gradient.type === 'linear') {
-        grad = ctx.createLinearGradient(gradient.x0, gradient.y0, gradient.x1, gradient.y1);
+      switch(gradient.type) {
+        case 'linear':
+          grad = ctx.createLinearGradient(gradient.x0, gradient.y0, gradient.x1, gradient.y1);
+          gradient.colorStops.forEach(addScrollStops(grad));
+          ctx.fillStyle = grad;
+          ctx.fillRect(0, 0, bounds.width, bounds.height);
+          break;
 
-        for (i = 0, len = gradient.colorStops.length; i < len; i+=1) {
-          try {
-            grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color);
-          }
-          catch(e) {
-            h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]);
-          }
-        }
+        case 'circle':
+          grad = ctx.createRadialGradient(gradient.cx, gradient.cy, 0, gradient.cx, gradient.cy, gradient.rx);
+          gradient.colorStops.forEach(addScrollStops(grad));
+          ctx.fillStyle = grad;
+          ctx.fillRect(0, 0, bounds.width, bounds.height);
+          break;
 
-        ctx.fillStyle = grad;
-        ctx.fillRect(0, 0, bounds.width, bounds.height);
+        case 'ellipse':
+          var canvasRadial = document.createElement('canvas'),
+            ctxRadial = canvasRadial.getContext('2d'),
+            ri = Math.max(gradient.rx, gradient.ry),
+            di = ri * 2;
 
-      } else if(gradient.type === 'circle') {
+          canvasRadial.width = canvasRadial.height = di;
 
-        grad = ctx.createRadialGradient(gradient.cx, gradient.cy, 0, gradient.cx, gradient.cy, gradient.rx);
+          grad = ctxRadial.createRadialGradient(gradient.rx, gradient.ry, 0, gradient.rx, gradient.ry, ri);
+          gradient.colorStops.forEach(addScrollStops(grad));
 
-        for (i = 0, len = gradient.colorStops.length; i < len; i+=1) {
-          try {
-            grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color);
-          }
-          catch(e) {
-            h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]);
-          }
-        }
-
-        ctx.fillStyle = grad;
-        ctx.fillRect(0, 0, bounds.width, bounds.height);
-
-      } else if(gradient.type === 'ellipse') {
-
-        // draw circle
-        var canvasRadial = document.createElement('canvas'),
-        ctxRadial = canvasRadial.getContext('2d'),
-        ri = Math.max(gradient.rx, gradient.ry),
-        di = ri * 2, imgRadial;
-
-        canvasRadial.width = canvasRadial.height = di;
-
-        grad = ctxRadial.createRadialGradient(gradient.rx, gradient.ry, 0, gradient.rx, gradient.ry, ri);
-
-        for (i = 0, len = gradient.colorStops.length; i < len; i+=1) {
-          try {
-            grad.addColorStop(gradient.colorStops[i].stop, gradient.colorStops[i].color);
-          }
-          catch(e) {
-            h2clog(['failed to add color stop: ', e, '; tried to add: ', gradient.colorStops[i], '; stop: ', i, '; in: ', src]);
-          }
-        }
-
-        ctxRadial.fillStyle = grad;
-        ctxRadial.fillRect(0, 0, di, di);
-
-        ctx.fillStyle = gradient.colorStops[i - 1].color;
-        ctx.fillRect(0, 0, canvas.width, canvas.height);
-        ctx.drawImage(canvasRadial, gradient.cx - gradient.rx, gradient.cy - gradient.ry, 2 * gradient.rx, 2 * gradient.ry);
+          ctxRadial.fillStyle = grad;
+          ctxRadial.fillRect(0, 0, di, di);
 
+          ctx.fillStyle = gradient.colorStops[gradient.colorStops.length - 1].color;
+          ctx.fillRect(0, 0, canvas.width, canvas.height);
+          ctx.drawImage(canvasRadial, gradient.cx - gradient.rx, gradient.cy - gradient.ry, 2 * gradient.rx, 2 * gradient.ry);
+          break;
       }
     }
 
     return canvas;
   };
 
-  _html2canvas.Generate.ListAlpha = function(number) {
+  Generate.ListAlpha = function(number) {
     var tmp = "",
     modulus;
 
@@ -414,7 +401,7 @@
     return tmp;
   };
 
-  _html2canvas.Generate.ListRoman = function(number) {
+  Generate.ListRoman = function(number) {
     var romanArray = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"],
     decimal = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1],
     roman = "",
@@ -433,7 +420,5 @@
     }
 
     return roman;
-
   };
-
 })();
\ No newline at end of file
diff --git a/src/Parse.js b/src/Parse.js
index 5ee38e4..5b9405c 100644
--- a/src/Parse.js
+++ b/src/Parse.js
@@ -734,7 +734,7 @@ _html2canvas.Parse = function (images, options) {
         valueWrap.style[property] = getCSS(el, property);
       } catch(e) {
         // Older IE has issues with "border"
-        h2clog("html2canvas: Parse: Exception caught in renderFormValue: " + e.message);
+        Util.log("html2canvas: Parse: Exception caught in renderFormValue: " + e.message);
       }
     });
 
@@ -791,7 +791,7 @@ _html2canvas.Parse = function (images, options) {
       try {
         elps.style[prop] = elStyle[prop];
       } catch (e) {
-        h2clog(['Tried to assign readonly property ', prop, 'Error:', e]);
+        Util.log(['Tried to assign readonly property ', prop, 'Error:', e]);
       }
     });
 
@@ -925,7 +925,7 @@ _html2canvas.Parse = function (images, options) {
       if (image) {
         renderBackgroundRepeating(element, bounds, ctx, image, imageIndex);
       } else {
-        h2clog("html2canvas: Error loading background:", backgroundImage);
+        Util.log("html2canvas: Error loading background:", backgroundImage);
       }
     }
   }
@@ -1041,7 +1041,7 @@ _html2canvas.Parse = function (images, options) {
         if ((image = loadImage(element.getAttribute('src')))) {
           renderImage(ctx, element, image, bounds, borders);
         } else {
-          h2clog("html2canvas: Error loading <img>:" + element.getAttribute('src'));
+          Util.log("html2canvas: Error loading <img>:" + element.getAttribute('src'));
         }
         break;
       case "INPUT":
diff --git a/src/Preload.js b/src/Preload.js
index 9fb176a..e826057 100644
--- a/src/Preload.js
+++ b/src/Preload.js
@@ -7,6 +7,7 @@ _html2canvas.Preload = function( options ) {
     cleanupDone: false
   },
   pageOrigin,
+  Util = _html2canvas.Util,
   methods,
   i,
   count = 0,
@@ -31,9 +32,9 @@ _html2canvas.Preload = function( options ) {
   }
 
   function start(){
-    h2clog("html2canvas: start: images: " + images.numLoaded + " / " + images.numTotal + " (failed: " + images.numFailed + ")");
+    Util.log("html2canvas: start: images: " + images.numLoaded + " / " + images.numTotal + " (failed: " + images.numFailed + ")");
     if (!images.firstRun && images.numLoaded >= images.numTotal){
-      h2clog("Finished loading images: # " + images.numTotal + " (failed: " + images.numFailed + ")");
+      Util.log("Finished loading images: # " + images.numTotal + " (failed: " + images.numFailed + ")");
 
       if (typeof options.complete === "function"){
         options.complete(images);
@@ -141,9 +142,7 @@ _html2canvas.Preload = function( options ) {
 
     // Firefox fails with permission denied on pages with iframes
     try {
-      _html2canvas.Util.Children(el).forEach(function(img) {
-        getImages(img);
-      });
+      Util.Children(el).forEach(getImages);
     }
     catch( e ) {}
 
@@ -151,15 +150,15 @@ _html2canvas.Preload = function( options ) {
       elNodeType = el.nodeType;
     } catch (ex) {
       elNodeType = false;
-      h2clog("html2canvas: failed to access some element's nodeType - Exception: " + ex.message);
+      Util.log("html2canvas: failed to access some element's nodeType - Exception: " + ex.message);
     }
 
     if (elNodeType === 1 || elNodeType === undefined) {
       loadPseudoElementImages(el);
       try {
-        loadBackgroundImages(_html2canvas.Util.getCSS(el, 'backgroundImage'), el);
+        loadBackgroundImages(Util.getCSS(el, 'backgroundImage'), el);
       } catch(e) {
-        h2clog("html2canvas: failed to get background-image - Exception: " + e.message);
+        Util.log("html2canvas: failed to get background-image - Exception: " + e.message);
       }
       loadBackgroundImages(el);
     }
@@ -256,9 +255,9 @@ _html2canvas.Preload = function( options ) {
       var img, src;
       if (!images.cleanupDone) {
         if (cause && typeof cause === "string") {
-          h2clog("html2canvas: Cleanup because: " + cause);
+          Util.log("html2canvas: Cleanup because: " + cause);
         } else {
-          h2clog("html2canvas: Cleanup after timeout: " + options.timeout + " ms.");
+          Util.log("html2canvas: Cleanup after timeout: " + options.timeout + " ms.");
         }
 
         for (src in images) {
@@ -276,7 +275,7 @@ _html2canvas.Preload = function( options ) {
               }
               images.numLoaded++;
               images.numFailed++;
-              h2clog("html2canvas: Cleaned up failed img: '" + src + "' Steps: " + images.numLoaded + " / " + images.numTotal);
+              Util.log("html2canvas: Cleaned up failed img: '" + src + "' Steps: " + images.numLoaded + " / " + images.numTotal);
             }
           }
         }
@@ -308,23 +307,22 @@ _html2canvas.Preload = function( options ) {
     timeoutTimer = window.setTimeout(methods.cleanupDOM, options.timeout);
   }
 
-  h2clog('html2canvas: Preload starts: finding background-images');
+  Util.log('html2canvas: Preload starts: finding background-images');
   images.firstRun = true;
 
   getImages(element);
 
-  h2clog('html2canvas: Preload: Finding images');
+  Util.log('html2canvas: Preload: Finding images');
   // load <img> images
   for (i = 0; i < imgLen; i+=1){
     methods.loadImage( domImages[i].getAttribute( "src" ) );
   }
 
   images.firstRun = false;
-  h2clog('html2canvas: Preload: Done.');
-  if ( images.numTotal === images.numLoaded ) {
+  Util.log('html2canvas: Preload: Done.');
+  if (images.numTotal === images.numLoaded) {
     start();
   }
 
   return methods;
-
 };
diff --git a/src/Support.js b/src/Support.js
index c2db49d..34e2622 100644
--- a/src/Support.js
+++ b/src/Support.js
@@ -24,7 +24,7 @@ _html2canvas.Util.Support = function (options, doc) {
     } catch(e) {
       return false;
     }
-    h2clog('html2canvas: Parse: SVG powered rendering available');
+    _html2canvas.Util.log('html2canvas: Parse: SVG powered rendering available');
     return true;
   }
 
diff --git a/src/Util.js b/src/Util.js
index baa0325..861402b 100644
--- a/src/Util.js
+++ b/src/Util.js
@@ -71,11 +71,11 @@ window.html2canvas = function(elements, opts) {
     preload: function( opts ) {
       return _html2canvas.Preload( _html2canvas.Util.Extend(opts, options) );
     },
-    log: h2clog
+    log: _html2canvas.Util.log
   };
 };
 
-window.html2canvas.log = h2clog; // for renderers
+window.html2canvas.log = _html2canvas.Util.log; // for renderers
 window.html2canvas.Renderer = {
   Canvas: undefined // We are assuming this will be used
 };
\ No newline at end of file
diff --git a/src/renderers/Canvas.js b/src/renderers/Canvas.js
index ad1ccc9..1a6045b 100644
--- a/src/renderers/Canvas.js
+++ b/src/renderers/Canvas.js
@@ -46,7 +46,7 @@ _html2canvas.Renderer.Canvas = function(options) {
               ctx.fillStyle = ctx.createPattern(item['arguments'][0], "repeat");
             }
             catch(e) {
-              h2clog("html2canvas: Renderer: Error creating pattern", e.message);
+              _html2canvas.Util.log("html2canvas: Renderer: Error creating pattern", e.message);
             }
           }
         } else if (item.name === "drawShape") {
@@ -101,7 +101,7 @@ _html2canvas.Renderer.Canvas = function(options) {
       ctx.restore();
     });
 
-    h2clog("html2canvas: Renderer: Canvas renderer done - returning canvas obj");
+    _html2canvas.Util.log("html2canvas: Renderer: Canvas renderer done - returning canvas obj");
 
     if (options.elements.length === 1) {
       if (typeof options.elements[0] === "object" && options.elements[0].nodeName !== "BODY") {
diff --git a/src/renderers/SVG.js b/src/renderers/SVG.js
index 747e045..e635077 100644
--- a/src/renderers/SVG.js
+++ b/src/renderers/SVG.js
@@ -194,7 +194,7 @@ _html2canvas.Renderer.SVG = function( options ) {
 
 
 
-            h2clog("html2canvas: Renderer: SVG Renderer done - returning SVG DOM obj");
+          _html2canvas.Util.log("html2canvas: Renderer: SVG Renderer done - returning SVG DOM obj");
 
             return svg;
         }