From 81c22866bc804fbbd790e7e9f0a36f3e8995574f Mon Sep 17 00:00:00 2001 From: Niklas von Hertzen Date: Sat, 15 Mar 2014 13:20:05 +0200 Subject: [PATCH] Don't fail on broken images --- src/dummyimagecontainer.js | 17 +++++++++++++++++ src/imagecontainer.js | 19 ++++++++++++------- src/proxyimagecontainer.js | 13 +++++++++---- tests/cases/images/empty.html | 3 +++ tests/test.js | 2 +- 5 files changed, 42 insertions(+), 12 deletions(-) create mode 100644 src/dummyimagecontainer.js diff --git a/src/dummyimagecontainer.js b/src/dummyimagecontainer.js new file mode 100644 index 0000000..5a3a64c --- /dev/null +++ b/src/dummyimagecontainer.js @@ -0,0 +1,17 @@ +function DummyImageContainer(src) { + this.src = src; + log("DummyImageContainer for", src); + if (!this.promise || !this.image) { + log("Initiating DummyImageContainer"); + DummyImageContainer.prototype.image = new Image(); + var image = this.image; + DummyImageContainer.prototype.promise = new Promise(function(resolve, reject) { + image.onload = resolve; + image.onerror = reject; + image.src = smallImage(); + if (image.complete === true) { + resolve(image); + } + }); + } +} diff --git a/src/imagecontainer.js b/src/imagecontainer.js index 07bb26a..ac99bcd 100644 --- a/src/imagecontainer.js +++ b/src/imagecontainer.js @@ -1,16 +1,21 @@ function ImageContainer(src, cors) { this.src = src; this.image = new Image(); - var image = this.image; + var self = this; this.promise = new Promise(function(resolve, reject) { - image.onload = resolve; - image.onerror = reject; + self.image.onload = resolve; + self.image.onerror = reject; if (cors) { - image.crossOrigin = "anonymous"; + self.image.crossOrigin = "anonymous"; } - image.src = src; - if (image.complete === true) { - resolve(image); + self.image.src = src; + if (self.image.complete === true) { + resolve(self.image); } + })['catch'](function() { + var dummy = new DummyImageContainer(src); + return dummy.promise.then(function(image) { + self.image = image; + }); }); } diff --git a/src/proxyimagecontainer.js b/src/proxyimagecontainer.js index 88954a8..c0bad47 100644 --- a/src/proxyimagecontainer.js +++ b/src/proxyimagecontainer.js @@ -7,16 +7,16 @@ function ProxyImageContainer(src, proxy) { var requestUrl = proxy + ((proxy.indexOf("?") > -1) ? "&" : "?" ) + 'url=' + encodeURIComponent(src) + '&callback=' + callbackName; this.src = src; this.image = new Image(); - var image = this.image; + var self = this; this.promise = new Promise(function(resolve, reject) { - image.onload = resolve; - image.onerror = reject; + self.image.onload = resolve; + self.image.onerror = reject; window[callbackName] = function(a){ if (a.substring(0,6) === "error:"){ reject(); } else { - image.src = a; + self.image.src = a; } window[callbackName] = undefined; // to work with IE<9 // NOTE: that the undefined callback property-name still exists on the window object (for IE<9) try { @@ -27,6 +27,11 @@ function ProxyImageContainer(src, proxy) { script.setAttribute("type", "text/javascript"); script.setAttribute("src", requestUrl); document.body.appendChild(script); + })['catch'](function() { + var dummy = new DummyImageContainer(src); + return dummy.promise.then(function(image) { + self.image = image; + }); }); } diff --git a/tests/cases/images/empty.html b/tests/cases/images/empty.html index a559161..b22cf79 100644 --- a/tests/cases/images/empty.html +++ b/tests/cases/images/empty.html @@ -8,6 +8,9 @@ Image without src attribute, should not crash: + Image with broken src attribute, should not crash: + + diff --git a/tests/test.js b/tests/test.js index a35d07c..0a09a33 100644 --- a/tests/test.js +++ b/tests/test.js @@ -11,7 +11,7 @@ var h2cSelector, h2cOptions; document.write(srcStart + '/tests/assets/jquery-1.6.2.js' + scrEnd); document.write(srcStart + '/tests/assets/jquery.plugin.html2canvas.js' + scrEnd); - var html2canvas = ['log', 'nodecontainer', 'stackingcontext', 'textcontainer', 'support', 'imagecontainer', 'proxyimagecontainer', 'gradientcontainer', 'lineargradientcontainer', 'webkitgradientcontainer', + var html2canvas = ['log', 'nodecontainer', 'stackingcontext', 'textcontainer', 'support', 'imagecontainer', 'dummyimagecontainer', 'proxyimagecontainer', 'gradientcontainer', 'lineargradientcontainer', 'webkitgradientcontainer', 'imageloader', 'nodeparser', 'font', 'fontmetrics', 'core', 'renderer', 'promise', 'renderers/canvas'], i; for (i = 0; i < html2canvas.length; ++i) { document.write(srcStart + '/src/' + html2canvas[i] + '.js?' + Math.random() + scrEnd);