IE origin fix

This commit is contained in:
Niklas von Hertzen 2011-11-26 21:29:46 +02:00
commit 1c6469d29b

View File

@ -1,338 +1,340 @@
/* /*
html2canvas @VERSION@ <http://html2canvas.hertzen.com> html2canvas @VERSION@ <http://html2canvas.hertzen.com>
Copyright (c) 2011 Niklas von Hertzen. All rights reserved. Copyright (c) 2011 Niklas von Hertzen. All rights reserved.
http://www.twitter.com/niklasvh http://www.twitter.com/niklasvh
Released under MIT License Released under MIT License
*/ */
html2canvas.Preload = function(element, opts){ html2canvas.Preload = function(element, opts){
var options = { var options = {
proxy: "http://html2canvas.appspot.com/", proxy: "http://html2canvas.appspot.com/",
timeout: 0 // no timeout timeout: 0 // no timeout
}, },
images = { images = {
numLoaded: 0, // also failed are counted here numLoaded: 0, // also failed are counted here
numFailed: 0, numFailed: 0,
numTotal: 0, numTotal: 0,
cleanupDone: false cleanupDone: false
}, },
pageOrigin = window.location.protocol + window.location.host, pageOrigin = window.location.protocol + window.location.host,
methods, methods,
i, i,
count = 0, count = 0,
doc = element.ownerDocument, doc = element.ownerDocument,
domImages = doc.images, // TODO probably should limit it to images present in the element only domImages = doc.images, // TODO probably should limit it to images present in the element only
imgLen = domImages.length, imgLen = domImages.length,
link = doc.createElement("a"); link = doc.createElement("a");
opts = opts || {}; link.href = window.location.href;
pageOrigin = link.protocol + link.host;
options = html2canvas.Util.Extend(opts, options); opts = opts || {};
options = html2canvas.Util.Extend(opts, options);
element = element || doc.body;
function isSameOrigin(url){ element = element || doc.body;
link.href = url;
return ((link.protocol + link.host) === pageOrigin); function isSameOrigin(url){
link.href = url;
} var origin = link.protocol + link.host;
return ":" === origin || (origin === pageOrigin);
function start(){ }
html2canvas.log("html2canvas: start: images: " + images.numLoaded + " / " + images.numTotal + " (failed: " + images.numFailed + ")");
if (!images.firstRun && images.numLoaded >= images.numTotal){ function start(){
html2canvas.log("html2canvas: start: images: " + images.numLoaded + " / " + images.numTotal + " (failed: " + images.numFailed + ")");
/* if (!images.firstRun && images.numLoaded >= images.numTotal){
this.log('Finished loading '+this.imagesLoaded+' images, Started parsing');
this.bodyOverflow = document.getElementsByTagName('body')[0].style.overflow; /*
document.getElementsByTagName('body')[0].style.overflow = "hidden"; this.log('Finished loading '+this.imagesLoaded+' images, Started parsing');
*/ this.bodyOverflow = document.getElementsByTagName('body')[0].style.overflow;
if (typeof options.complete === "function"){ document.getElementsByTagName('body')[0].style.overflow = "hidden";
options.complete(images); */
} if (typeof options.complete === "function"){
options.complete(images);
html2canvas.log("Finished loading images: # " + images.numTotal + " (failed: " + images.numFailed + ")"); }
}
} html2canvas.log("Finished loading images: # " + images.numTotal + " (failed: " + images.numFailed + ")");
}
function proxyGetImage(url, img){ }
var callback_name,
scriptUrl = options.proxy, function proxyGetImage(url, img){
script, var callback_name,
imgObj = images[url]; scriptUrl = options.proxy,
script,
link.href = url; imgObj = images[url];
url = link.href; // work around for pages with base href="" set - WARNING: this may change the url -> so access imgObj from images map before changing that url!
link.href = url;
callback_name = 'html2canvas_' + count; url = link.href; // work around for pages with base href="" set - WARNING: this may change the url -> so access imgObj from images map before changing that url!
imgObj.callbackname = callback_name;
callback_name = 'html2canvas_' + count;
if (scriptUrl.indexOf("?") > -1) { imgObj.callbackname = callback_name;
scriptUrl += "&";
} else { if (scriptUrl.indexOf("?") > -1) {
scriptUrl += "?"; scriptUrl += "&";
} } else {
scriptUrl += 'url=' + encodeURIComponent(url) + '&callback=' + callback_name; scriptUrl += "?";
}
window[callback_name] = function(a){ scriptUrl += 'url=' + encodeURIComponent(url) + '&callback=' + callback_name;
if (a.substring(0,6) === "error:"){
imgObj.succeeded = false; window[callback_name] = function(a){
images.numLoaded++; if (a.substring(0,6) === "error:"){
images.numFailed++; imgObj.succeeded = false;
start(); images.numLoaded++;
} else { images.numFailed++;
img.onload = function(){ start();
imgObj.succeeded = true; } else {
images.numLoaded++; img.onload = function(){
start(); imgObj.succeeded = true;
}; images.numLoaded++;
img.src = a; start();
} };
window[callback_name] = undefined; // to work with IE<9 // NOTE: that the undefined callback property-name still exists on the window object (for IE<9) img.src = a;
try { }
delete window[callback_name]; // for all browser that support this window[callback_name] = undefined; // to work with IE<9 // NOTE: that the undefined callback property-name still exists on the window object (for IE<9)
} catch(ex) {} try {
script.parentNode.removeChild(script); delete window[callback_name]; // for all browser that support this
script = null; } catch(ex) {}
imgObj.callbackname = undefined; script.parentNode.removeChild(script);
}; script = null;
imgObj.callbackname = undefined;
count += 1; };
script = doc.createElement("script"); count += 1;
script.setAttribute("src", scriptUrl);
script.setAttribute("type", "text/javascript"); script = doc.createElement("script");
imgObj.script = script; script.setAttribute("src", scriptUrl);
window.document.body.appendChild(script); script.setAttribute("type", "text/javascript");
imgObj.script = script;
/* window.document.body.appendChild(script);
// enable xhr2 requests where available (no need for base64 / json) /*
$.ajax({ // enable xhr2 requests where available (no need for base64 / json)
data:{
xhr2:false, $.ajax({
url:url data:{
}, xhr2:false,
url: options.proxy, url:url
dataType: "jsonp", },
success: function(a){ url: options.proxy,
dataType: "jsonp",
if (a.substring(0,6) === "error:"){ success: function(a){
images.splice(getIndex(images, url), 2);
start(); if (a.substring(0,6) === "error:"){
}else{ images.splice(getIndex(images, url), 2);
img.onload = function(){ start();
imagesLoaded+=1; }else{
start(); img.onload = function(){
imagesLoaded+=1;
}; start();
img.src = a;
} };
img.src = a;
}
},
error: function(){
images.splice(getIndex(images, url), 2); },
start(); error: function(){
} images.splice(getIndex(images, url), 2);
start();
}
});
*/
} });
*/
function getImages (el) { }
function getImages (el) {
// if (!this.ignoreRe.test(el.nodeName)){
//
// if (!this.ignoreRe.test(el.nodeName)){
var contents = html2canvas.Util.Children(el), //
i,
contentsLen = contents.length, var contents = html2canvas.Util.Children(el),
background_image, i,
src, contentsLen = contents.length,
img, background_image,
elNodeType = false; src,
img,
for (i = 0; i < contentsLen; i+=1 ){ elNodeType = false;
// var ignRe = new RegExp("("+this.ignoreElements+")");
// if (!ignRe.test(element.nodeName)){ for (i = 0; i < contentsLen; i+=1 ){
getImages(contents[i]); // var ignRe = new RegExp("("+this.ignoreElements+")");
// } // if (!ignRe.test(element.nodeName)){
} getImages(contents[i]);
// }
// } }
try {
elNodeType = el.nodeType; // }
} catch (ex) { try {
elNodeType = false; elNodeType = el.nodeType;
html2canvas.log("html2canvas: failed to access some element's nodeType - Exception: " + ex.message); } catch (ex) {
} elNodeType = false;
html2canvas.log("html2canvas: failed to access some element's nodeType - Exception: " + ex.message);
if (elNodeType === 1 || elNodeType === undefined){ }
background_image = html2canvas.Util.getCSS(el, 'backgroundImage'); if (elNodeType === 1 || elNodeType === undefined){
if ( background_image && background_image !== "1" && background_image !== "none" ) { background_image = html2canvas.Util.getCSS(el, 'backgroundImage');
// TODO add multi image background support if ( background_image && background_image !== "1" && background_image !== "none" ) {
if (background_image.substring(0,7) === "-webkit" || background_image.substring(0,3) === "-o-" || background_image.substring(0,4) === "-moz") { // TODO add multi image background support
img = html2canvas.Generate.Gradient( background_image, html2canvas.Util.Bounds( el ) ); if (background_image.substring(0,7) === "-webkit" || background_image.substring(0,3) === "-o-" || background_image.substring(0,4) === "-moz") {
if ( img !== undefined ){ img = html2canvas.Generate.Gradient( background_image, html2canvas.Util.Bounds( el ) );
images[background_image] = { img: img, succeeded: true };
images.numTotal++; if ( img !== undefined ){
images.numLoaded++; images[background_image] = { img: img, succeeded: true };
start(); images.numTotal++;
images.numLoaded++;
} start();
} else { }
src = html2canvas.Util.backgroundImage(background_image.match(/data:image\/.*;base64,/i) ? background_image : background_image.split(",")[0]);
methods.loadImage(src); } else {
} src = html2canvas.Util.backgroundImage(background_image.match(/data:image\/.*;base64,/i) ? background_image : background_image.split(",")[0]);
methods.loadImage(src);
/* }
if (background_image && background_image !== "1" && background_image !== "none" && background_image.substring(0,7) !== "-webkit" && background_image.substring(0,3)!== "-o-" && background_image.substring(0,4) !== "-moz"){
// TODO add multi image background support /*
src = html2canvas.Util.backgroundImage(background_image.split(",")[0]); if (background_image && background_image !== "1" && background_image !== "none" && background_image.substring(0,7) !== "-webkit" && background_image.substring(0,3)!== "-o-" && background_image.substring(0,4) !== "-moz"){
methods.loadImage(src); */ // TODO add multi image background support
} src = html2canvas.Util.backgroundImage(background_image.split(",")[0]);
} methods.loadImage(src); */
} }
}
methods = { }
loadImage: function( src ) {
var img; methods = {
if ( images[src] === undefined ) { loadImage: function( src ) {
if ( src.match(/data:image\/.*;base64,/i) ) { var img;
if ( images[src] === undefined ) {
//Base64 src if ( src.match(/data:image\/.*;base64,/i) ) {
img = new Image();
img.src = src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''); //Base64 src
images[src] = { img: img, succeeded: true }; img = new Image();
images.numTotal++; img.src = src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, '');
images.numLoaded++; images[src] = { img: img, succeeded: true };
start(); images.numTotal++;
images.numLoaded++;
}else if ( isSameOrigin( src ) ) { start();
img = new Image(); }else if ( isSameOrigin( src ) ) {
images[src] = { img: img };
images.numTotal++; img = new Image();
images[src] = { img: img };
img.onload = function() { images.numTotal++;
images.numLoaded++;
images[src].succeeded = true; img.onload = function() {
start(); images.numLoaded++;
}; images[src].succeeded = true;
start();
img.onerror = function() { };
images.numLoaded++;
images.numFailed++; img.onerror = function() {
images[src].succeeded = false; images.numLoaded++;
start(); images.numFailed++;
}; images[src].succeeded = false;
start();
img.src = src; };
}else if ( options.proxy ){ img.src = src;
// console.log('b'+src);
img = new Image(); }else if ( options.proxy ){
images[src] = { img: img }; // console.log('b'+src);
images.numTotal++; img = new Image();
proxyGetImage( src, img ); images[src] = { img: img };
} images.numTotal++;
} proxyGetImage( src, img );
}
}, }
cleanupDOM: function(cause) {
var img; },
if (!images.cleanupDone) { cleanupDOM: function(cause) {
if (cause && typeof cause === "string") { var img;
html2canvas.log("html2canvas: Cleanup because: " + cause); if (!images.cleanupDone) {
} else { if (cause && typeof cause === "string") {
html2canvas.log("html2canvas: Cleanup after timeout: " + options.timeout + " ms."); html2canvas.log("html2canvas: Cleanup because: " + cause);
} } else {
html2canvas.log("html2canvas: Cleanup after timeout: " + options.timeout + " ms.");
for (src in images) { }
if (images.hasOwnProperty(src)) {
img = images[src]; for (src in images) {
if (typeof img === "object" && img.callbackname && img.succeeded === undefined) { if (images.hasOwnProperty(src)) {
// cancel proxy image request img = images[src];
window[img.callbackname] = undefined; // to work with IE<9 // NOTE: that the undefined callback property-name still exists on the window object (for IE<9) if (typeof img === "object" && img.callbackname && img.succeeded === undefined) {
try { // cancel proxy image request
delete window[img.callbackname]; // for all browser that support this window[img.callbackname] = undefined; // to work with IE<9 // NOTE: that the undefined callback property-name still exists on the window object (for IE<9)
} catch(ex) {} try {
if (img.script && img.script.parentNode) { delete window[img.callbackname]; // for all browser that support this
img.script.setAttribute("src", "about:blank"); // try to cancel running request } catch(ex) {}
img.script.parentNode.removeChild(img.script); if (img.script && img.script.parentNode) {
} img.script.setAttribute("src", "about:blank"); // try to cancel running request
images.numLoaded++; img.script.parentNode.removeChild(img.script);
images.numFailed++; }
html2canvas.log("html2canvas: Cleaned up failed img: '" + src + "' Steps: " + images.numLoaded + " / " + images.numTotal); images.numLoaded++;
} images.numFailed++;
} html2canvas.log("html2canvas: Cleaned up failed img: '" + src + "' Steps: " + images.numLoaded + " / " + images.numTotal);
} }
}
// cancel any pending requests }
if(window.stop !== undefined) {
window.stop(); // cancel any pending requests
} else if(document.execCommand !== undefined) { if(window.stop !== undefined) {
document.execCommand("Stop", false); window.stop();
} } else if(document.execCommand !== undefined) {
if (document.close !== undefined) { document.execCommand("Stop", false);
document.close(); }
} if (document.close !== undefined) {
images.cleanupDone = true; document.close();
if (!(cause && typeof cause === "string")) { }
start(); images.cleanupDone = true;
} if (!(cause && typeof cause === "string")) {
} start();
}, }
renderingDone: function() { }
if (timeoutTimer) { },
window.clearTimeout(timeoutTimer); renderingDone: function() {
} if (timeoutTimer) {
} window.clearTimeout(timeoutTimer);
}
}; }
if (options.timeout > 0) { };
timeoutTimer = window.setTimeout(methods.cleanupDOM, options.timeout);
} if (options.timeout > 0) {
var startTime = (new Date()).getTime(); timeoutTimer = window.setTimeout(methods.cleanupDOM, options.timeout);
this.log('html2canvas: Preload starts: finding background-images'); }
images.firstRun = true; var startTime = (new Date()).getTime();
this.log('html2canvas: Preload starts: finding background-images');
getImages( element ); images.firstRun = true;
this.log('html2canvas: Preload: Finding images'); getImages( element );
// load <img> images
for (i = 0; i < imgLen; i+=1){ this.log('html2canvas: Preload: Finding images');
var imgSrc = domImages[i].getAttribute( "src" ); // load <img> images
if ( imgSrc ) { for (i = 0; i < imgLen; i+=1){
methods.loadImage( imgSrc ); var imgSrc = domImages[i].getAttribute( "src" );
} if ( imgSrc ) {
} methods.loadImage( imgSrc );
}
images.firstRun = false; }
this.log('html2canvas: Preload: Done.');
if ( images.numTotal === images.numLoaded ) { images.firstRun = false;
start(); this.log('html2canvas: Preload: Done.');
} if ( images.numTotal === images.numLoaded ) {
start();
return methods; }
}; return methods;
};