mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Fix iframe proxy
This commit is contained in:
parent
dd697d9569
commit
4783e9dd26
12
Gruntfile.js
12
Gruntfile.js
@ -90,6 +90,12 @@ module.exports = function(grunt) {
|
|||||||
keepalive: true
|
keepalive: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
altServer: {
|
||||||
|
options: {
|
||||||
|
port: 8083,
|
||||||
|
base: './'
|
||||||
|
}
|
||||||
|
},
|
||||||
cors: {
|
cors: {
|
||||||
options: {
|
options: {
|
||||||
port: 8081,
|
port: 8081,
|
||||||
@ -200,9 +206,9 @@ module.exports = function(grunt) {
|
|||||||
grunt.loadNpmTasks('grunt-contrib-connect');
|
grunt.loadNpmTasks('grunt-contrib-connect');
|
||||||
grunt.loadNpmTasks('grunt-execute');
|
grunt.loadNpmTasks('grunt-execute');
|
||||||
|
|
||||||
grunt.registerTask('server', ['connect:cors', 'connect:proxy', 'connect:server']);
|
grunt.registerTask('server', ['connect:cors', 'connect:proxy', 'connect:altServer', 'connect:server']);
|
||||||
grunt.registerTask('build', ['execute', 'concat', 'uglify']);
|
grunt.registerTask('build', ['execute', 'concat', 'uglify']);
|
||||||
grunt.registerTask('default', ['jshint', 'build', 'mocha_phantomjs']);
|
grunt.registerTask('default', ['jshint', 'build', 'connect:altServer', 'mocha_phantomjs']);
|
||||||
grunt.registerTask('travis', ['jshint', 'build','mocha_phantomjs', 'connect:ci', 'connect:proxy', 'connect:cors', 'webdriver']);
|
grunt.registerTask('travis', ['jshint', 'build', 'connect:altServer', 'connect:ci', 'connect:proxy', 'connect:cors', 'mocha_phantomjs', 'webdriver']);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
26
dist/html2canvas.js
vendored
26
dist/html2canvas.js
vendored
@ -587,8 +587,10 @@ window.html2canvas = function(nodeList, options) {
|
|||||||
if (typeof(options.proxy) !== "string") {
|
if (typeof(options.proxy) !== "string") {
|
||||||
return Promise.reject("Proxy must be used when rendering url");
|
return Promise.reject("Proxy must be used when rendering url");
|
||||||
}
|
}
|
||||||
return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, window.innerWidth, window.innerHeight, options).then(function(container) {
|
var width = options.width != null ? options.width : window.innerWidth;
|
||||||
return renderWindow(container.contentWindow.document.documentElement, container, options, window.innerWidth, window.innerHeight);
|
var height = options.height != null ? options.height : window.innerHeight;
|
||||||
|
return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) {
|
||||||
|
return renderWindow(container.contentWindow.document.documentElement, container, options, width, height);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -607,7 +609,7 @@ window.html2canvas.punycode = this.punycode;
|
|||||||
window.html2canvas.proxy = {};
|
window.html2canvas.proxy = {};
|
||||||
|
|
||||||
function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {
|
function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {
|
||||||
return createWindowClone(document, document, windowWidth, windowHeight, options).then(function(container) {
|
return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) {
|
||||||
log("Document cloned");
|
log("Document cloned");
|
||||||
var attributeName = html2canvasNodeAttribute + html2canvasIndex;
|
var attributeName = html2canvasNodeAttribute + html2canvasIndex;
|
||||||
var selector = "[" + attributeName + "='" + html2canvasIndex + "']";
|
var selector = "[" + attributeName + "='" + html2canvasIndex + "']";
|
||||||
@ -688,7 +690,7 @@ function smallImage() {
|
|||||||
return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWindowClone(ownerDocument, containerDocument, width, height, options) {
|
function createWindowClone(ownerDocument, containerDocument, width, height, options, x ,y) {
|
||||||
labelCanvasElements(ownerDocument);
|
labelCanvasElements(ownerDocument);
|
||||||
var documentElement = ownerDocument.documentElement.cloneNode(true),
|
var documentElement = ownerDocument.documentElement.cloneNode(true),
|
||||||
container = containerDocument.createElement("iframe");
|
container = containerDocument.createElement("iframe");
|
||||||
@ -726,9 +728,6 @@ function createWindowClone(ownerDocument, containerDocument, width, height, opti
|
|||||||
}, 50);
|
}, 50);
|
||||||
};
|
};
|
||||||
|
|
||||||
var x = ownerDocument.defaultView.pageXOffset;
|
|
||||||
var y = ownerDocument.defaultView.pageYOffset;
|
|
||||||
|
|
||||||
documentClone.open();
|
documentClone.open();
|
||||||
documentClone.write("<!DOCTYPE html><html></html>");
|
documentClone.write("<!DOCTYPE html><html></html>");
|
||||||
// Chrome scrolls the parent document for some reason after the write to the cloned window???
|
// Chrome scrolls the parent document for some reason after the write to the cloned window???
|
||||||
@ -748,14 +747,14 @@ function cloneNodeValues(document, clone, nodeName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function restoreOwnerScroll(ownerDocument, x, y) {
|
function restoreOwnerScroll(ownerDocument, x, y) {
|
||||||
if (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset) {
|
if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {
|
||||||
ownerDocument.defaultView.scrollTo(x, y);
|
ownerDocument.defaultView.scrollTo(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadUrlDocument(src, proxy, document, width, height, options) {
|
function loadUrlDocument(src, proxy, document, width, height, options) {
|
||||||
return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {
|
return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {
|
||||||
return createWindowClone(doc, document, width, height, options);
|
return createWindowClone(doc, document, width, height, options, 0, 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1371,7 +1370,7 @@ ImageLoader.prototype.fetch = function(nodes) {
|
|||||||
|
|
||||||
ImageLoader.prototype.timeout = function(container, timeout) {
|
ImageLoader.prototype.timeout = function(container, timeout) {
|
||||||
var timer;
|
var timer;
|
||||||
return Promise.race([container.promise, new Promise(function(res, reject) {
|
var promise = Promise.race([container.promise, new Promise(function(res, reject) {
|
||||||
timer = setTimeout(function() {
|
timer = setTimeout(function() {
|
||||||
log("Timed out loading image", container);
|
log("Timed out loading image", container);
|
||||||
reject(container);
|
reject(container);
|
||||||
@ -1380,6 +1379,10 @@ ImageLoader.prototype.timeout = function(container, timeout) {
|
|||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
return container;
|
return container;
|
||||||
});
|
});
|
||||||
|
promise['catch'](function() {
|
||||||
|
clearTimeout(timer);
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
function LinearGradientContainer(imageData) {
|
function LinearGradientContainer(imageData) {
|
||||||
@ -2732,6 +2735,9 @@ function hasUnicode(string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Proxy(src, proxyUrl, document) {
|
function Proxy(src, proxyUrl, document) {
|
||||||
|
if (!proxyUrl) {
|
||||||
|
return Promise.reject("No proxy configured");
|
||||||
|
}
|
||||||
var callback = createCallback(supportsCORS);
|
var callback = createCallback(supportsCORS);
|
||||||
var url = createProxyUrl(proxyUrl, src, callback);
|
var url = createProxyUrl(proxyUrl, src, callback);
|
||||||
|
|
||||||
|
4
dist/html2canvas.min.js
vendored
4
dist/html2canvas.min.js
vendored
File diff suppressed because one or more lines are too long
17
src/core.js
17
src/core.js
@ -23,8 +23,10 @@ window.html2canvas = function(nodeList, options) {
|
|||||||
if (typeof(options.proxy) !== "string") {
|
if (typeof(options.proxy) !== "string") {
|
||||||
return Promise.reject("Proxy must be used when rendering url");
|
return Promise.reject("Proxy must be used when rendering url");
|
||||||
}
|
}
|
||||||
return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, window.innerWidth, window.innerHeight, options).then(function(container) {
|
var width = options.width != null ? options.width : window.innerWidth;
|
||||||
return renderWindow(container.contentWindow.document.documentElement, container, options, window.innerWidth, window.innerHeight);
|
var height = options.height != null ? options.height : window.innerHeight;
|
||||||
|
return loadUrlDocument(absoluteUrl(nodeList), options.proxy, document, width, height, options).then(function(container) {
|
||||||
|
return renderWindow(container.contentWindow.document.documentElement, container, options, width, height);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +45,7 @@ window.html2canvas.punycode = this.punycode;
|
|||||||
window.html2canvas.proxy = {};
|
window.html2canvas.proxy = {};
|
||||||
|
|
||||||
function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {
|
function renderDocument(document, options, windowWidth, windowHeight, html2canvasIndex) {
|
||||||
return createWindowClone(document, document, windowWidth, windowHeight, options).then(function(container) {
|
return createWindowClone(document, document, windowWidth, windowHeight, options, document.defaultView.pageXOffset, document.defaultView.pageYOffset).then(function(container) {
|
||||||
log("Document cloned");
|
log("Document cloned");
|
||||||
var attributeName = html2canvasNodeAttribute + html2canvasIndex;
|
var attributeName = html2canvasNodeAttribute + html2canvasIndex;
|
||||||
var selector = "[" + attributeName + "='" + html2canvasIndex + "']";
|
var selector = "[" + attributeName + "='" + html2canvasIndex + "']";
|
||||||
@ -124,7 +126,7 @@ function smallImage() {
|
|||||||
return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
return "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
||||||
}
|
}
|
||||||
|
|
||||||
function createWindowClone(ownerDocument, containerDocument, width, height, options) {
|
function createWindowClone(ownerDocument, containerDocument, width, height, options, x ,y) {
|
||||||
labelCanvasElements(ownerDocument);
|
labelCanvasElements(ownerDocument);
|
||||||
var documentElement = ownerDocument.documentElement.cloneNode(true),
|
var documentElement = ownerDocument.documentElement.cloneNode(true),
|
||||||
container = containerDocument.createElement("iframe");
|
container = containerDocument.createElement("iframe");
|
||||||
@ -162,9 +164,6 @@ function createWindowClone(ownerDocument, containerDocument, width, height, opti
|
|||||||
}, 50);
|
}, 50);
|
||||||
};
|
};
|
||||||
|
|
||||||
var x = ownerDocument.defaultView.pageXOffset;
|
|
||||||
var y = ownerDocument.defaultView.pageYOffset;
|
|
||||||
|
|
||||||
documentClone.open();
|
documentClone.open();
|
||||||
documentClone.write("<!DOCTYPE html><html></html>");
|
documentClone.write("<!DOCTYPE html><html></html>");
|
||||||
// Chrome scrolls the parent document for some reason after the write to the cloned window???
|
// Chrome scrolls the parent document for some reason after the write to the cloned window???
|
||||||
@ -184,14 +183,14 @@ function cloneNodeValues(document, clone, nodeName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function restoreOwnerScroll(ownerDocument, x, y) {
|
function restoreOwnerScroll(ownerDocument, x, y) {
|
||||||
if (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset) {
|
if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) {
|
||||||
ownerDocument.defaultView.scrollTo(x, y);
|
ownerDocument.defaultView.scrollTo(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadUrlDocument(src, proxy, document, width, height, options) {
|
function loadUrlDocument(src, proxy, document, width, height, options) {
|
||||||
return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {
|
return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {
|
||||||
return createWindowClone(doc, document, width, height, options);
|
return createWindowClone(doc, document, width, height, options, 0, 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ ImageLoader.prototype.fetch = function(nodes) {
|
|||||||
|
|
||||||
ImageLoader.prototype.timeout = function(container, timeout) {
|
ImageLoader.prototype.timeout = function(container, timeout) {
|
||||||
var timer;
|
var timer;
|
||||||
return Promise.race([container.promise, new Promise(function(res, reject) {
|
var promise = Promise.race([container.promise, new Promise(function(res, reject) {
|
||||||
timer = setTimeout(function() {
|
timer = setTimeout(function() {
|
||||||
log("Timed out loading image", container);
|
log("Timed out loading image", container);
|
||||||
reject(container);
|
reject(container);
|
||||||
@ -137,4 +137,8 @@ ImageLoader.prototype.timeout = function(container, timeout) {
|
|||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
return container;
|
return container;
|
||||||
});
|
});
|
||||||
|
promise['catch'](function() {
|
||||||
|
clearTimeout(timer);
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
function Proxy(src, proxyUrl, document) {
|
function Proxy(src, proxyUrl, document) {
|
||||||
|
if (!proxyUrl) {
|
||||||
|
return Promise.reject("No proxy configured");
|
||||||
|
}
|
||||||
var callback = createCallback(supportsCORS);
|
var callback = createCallback(supportsCORS);
|
||||||
var url = createProxyUrl(proxyUrl, src, callback);
|
var url = createProxyUrl(proxyUrl, src, callback);
|
||||||
|
|
||||||
|
21
tests/mocha/iframe3.htm
Normal file
21
tests/mocha/iframe3.htm
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head lang="en">
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title></title>
|
||||||
|
<style>
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
background: red;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.valid {
|
||||||
|
height: 350px;
|
||||||
|
background: green;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body><div class="valid"> </div></body>
|
||||||
|
</html>
|
89
tests/mocha/proxy.htm
Normal file
89
tests/mocha/proxy.htm
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head lang="en">
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Proxy tests</title>
|
||||||
|
<link rel="stylesheet" href="lib/mocha.css" />
|
||||||
|
<script src="../../dist/html2canvas.js"></script>
|
||||||
|
<script src="../assets/jquery-1.6.2.js"></script>
|
||||||
|
<script src="lib/expect.js"></script>
|
||||||
|
<script src="lib/mocha.js"></script>
|
||||||
|
<style>
|
||||||
|
#content {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="mocha"></div>
|
||||||
|
<script>mocha.setup('bdd')</script>
|
||||||
|
<div id="content" style="display: inline-block;background: red;">
|
||||||
|
<iframe src="http://localhost:8083/tests/mocha/iframe3.htm" style="border: 0; width: 200px; height: 200px;" scrolling="no"></iframe>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
describe("Proxy", function() {
|
||||||
|
it("with iframe through proxy", function (done) {
|
||||||
|
this.timeout(10000);
|
||||||
|
html2canvas(document.querySelector("#content"), {proxy: 'http://localhost:8082'}).then(function (canvas) {
|
||||||
|
validCanvasPixels(canvas);
|
||||||
|
done();
|
||||||
|
}).catch(function (error) {
|
||||||
|
done(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("with iframe without proxy", function (done) {
|
||||||
|
html2canvas(document.querySelector("#content")).then(function (canvas) {
|
||||||
|
expect(canvas.width).to.equal(200);
|
||||||
|
expect(canvas.height).to.equal(200);
|
||||||
|
done();
|
||||||
|
}).catch(function (error) {
|
||||||
|
done(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("with url using proxy", function (done) {
|
||||||
|
html2canvas("http://localhost:8083/tests/mocha/iframe3.htm", {proxy: 'http://localhost:8082', width: 200, height: 200, type: 'view'}).then(function (canvas) {
|
||||||
|
expect(canvas.width).to.equal(200);
|
||||||
|
expect(canvas.height).to.equal(200);
|
||||||
|
done();
|
||||||
|
}).catch(function (error) {
|
||||||
|
done(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("with url without proxy", function (done) {
|
||||||
|
html2canvas("http://localhost:8083/tests/mocha/iframe3.htm").then(function () {
|
||||||
|
done("Should throw error");
|
||||||
|
}).catch(function (error) {
|
||||||
|
expect(error).to.equal("Proxy must be used when rendering url");
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function validCanvasPixels(canvas) {
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
||||||
|
for (var i = 0, len = data.length; i < len; i+=4) {
|
||||||
|
if (data[i] !== 0 || data[i+1] !== 128 || data[i+2] !== 0 || data[i+3] !== 255) {
|
||||||
|
expect().fail("Invalid canvas data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mocha.checkLeaks();
|
||||||
|
mocha.globals(['jQuery']);
|
||||||
|
if (window.mochaPhantomJS) {
|
||||||
|
mochaPhantomJS.run();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mocha.run();
|
||||||
|
}
|
||||||
|
mocha.suite.afterAll(function() {
|
||||||
|
document.body.setAttribute('data-complete', 'true');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
x
Reference in New Issue
Block a user