mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Add preliminary support for same-origin iframes
This commit is contained in:
parent
6347e7f043
commit
d4c9a41873
@ -15,5 +15,5 @@
|
|||||||
"jQuery": true
|
"jQuery": true
|
||||||
},
|
},
|
||||||
"predef": ["NodeParser", "NodeContainer", "StackingContext", "TextContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise", "getBounds", "offsetBounds", "XHR",
|
"predef": ["NodeParser", "NodeContainer", "StackingContext", "TextContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise", "getBounds", "offsetBounds", "XHR",
|
||||||
"ImageContainer", "ProxyImageContainer", "DummyImageContainer", "Font", "FontMetrics", "GradientContainer", "LinearGradientContainer", "WebkitGradientContainer", "SVGContainer", "SVGNodeContainer", "html2canvas", "log", "smallImage", "parseBackgrounds"]
|
"ImageContainer", "ProxyImageContainer", "DummyImageContainer", "Font", "FontMetrics", "GradientContainer", "LinearGradientContainer", "WebkitGradientContainer", "SVGContainer", "SVGNodeContainer", "FrameContainer", "html2canvas", "log", "smallImage", "parseBackgrounds"]
|
||||||
}
|
}
|
||||||
|
57
dist/html2canvas.js
vendored
57
dist/html2canvas.js
vendored
@ -602,8 +602,8 @@ function renderDocument(document, options, windowWidth, windowHeight) {
|
|||||||
var support = new Support(clonedWindow.document);
|
var support = new Support(clonedWindow.document);
|
||||||
var imageLoader = new ImageLoader(options, support);
|
var imageLoader = new ImageLoader(options, support);
|
||||||
var bounds = getBounds(node);
|
var bounds = getBounds(node);
|
||||||
var width = options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth();
|
var width = options.width != null ? options.width : options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth();
|
||||||
var height = options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight();
|
var height = options.height != null ? options.height : options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight();
|
||||||
var renderer = new CanvasRenderer(width, height, imageLoader, options, document);
|
var renderer = new CanvasRenderer(width, height, imageLoader, options, document);
|
||||||
var parser = new NodeParser(node, renderer, support, imageLoader, options);
|
var parser = new NodeParser(node, renderer, support, imageLoader, options);
|
||||||
return parser.ready.then(function() {
|
return parser.ready.then(function() {
|
||||||
@ -777,6 +777,30 @@ FontMetrics.prototype.getMetrics = function(family, size) {
|
|||||||
return this.data[family + "-" + size];
|
return this.data[family + "-" + size];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function FrameContainer(container) {
|
||||||
|
this.image = null;
|
||||||
|
this.src = container;
|
||||||
|
var self = this;
|
||||||
|
var bounds = getBounds(container);
|
||||||
|
this.promise = new Promise(function(resolve) {
|
||||||
|
if (container.contentWindow.document.URL === "about:blank" || container.contentWindow.document.documentElement == null) {
|
||||||
|
container.contentWindow.onload = container.onload = function() {
|
||||||
|
resolve(container);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
resolve(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
}).then(function(container) {
|
||||||
|
return html2canvas(container.contentWindow.document.documentElement, {
|
||||||
|
width: bounds.width,
|
||||||
|
height: bounds.height
|
||||||
|
});
|
||||||
|
}).then(function(canvas) {
|
||||||
|
return self.image = canvas;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function GradientContainer(imageData) {
|
function GradientContainer(imageData) {
|
||||||
this.src = imageData.value;
|
this.src = imageData.value;
|
||||||
this.colorStops = [];
|
this.colorStops = [];
|
||||||
@ -827,8 +851,22 @@ function ImageLoader(options, support) {
|
|||||||
|
|
||||||
ImageLoader.prototype.findImages = function(nodes) {
|
ImageLoader.prototype.findImages = function(nodes) {
|
||||||
var images = [];
|
var images = [];
|
||||||
nodes.filter(isImage).map(urlImage).forEach(this.addImage(images, this.loadImage), this);
|
nodes.reduce(function(imageNodes, container) {
|
||||||
nodes.filter(isSVGNode).map(svgImage).forEach(this.addImage(images, this.loadImage), this);
|
switch(container.node.nodeName) {
|
||||||
|
case "IMG":
|
||||||
|
return imageNodes.concat([{
|
||||||
|
args: [container.node.src],
|
||||||
|
method: "url"
|
||||||
|
}]);
|
||||||
|
case "svg":
|
||||||
|
case "IFRAME":
|
||||||
|
return imageNodes.concat([{
|
||||||
|
args: [container.node],
|
||||||
|
method: container.node.nodeName
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
return imageNodes;
|
||||||
|
}, []).forEach(this.addImage(images, this.loadImage), this);
|
||||||
return images;
|
return images;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -874,6 +912,8 @@ ImageLoader.prototype.loadImage = function(imageData) {
|
|||||||
return new WebkitGradientContainer(imageData);
|
return new WebkitGradientContainer(imageData);
|
||||||
} else if (imageData.method === "svg") {
|
} else if (imageData.method === "svg") {
|
||||||
return new SVGNodeContainer(imageData.args[0]);
|
return new SVGNodeContainer(imageData.args[0]);
|
||||||
|
} else if (imageData.method === "IFRAME") {
|
||||||
|
return new FrameContainer(imageData.args[0]);
|
||||||
} else {
|
} else {
|
||||||
return new DummyImageContainer(imageData);
|
return new DummyImageContainer(imageData);
|
||||||
}
|
}
|
||||||
@ -1670,11 +1710,12 @@ NodeParser.prototype.paintNode = function(container) {
|
|||||||
this.renderer.renderBorders(borderData.borders);
|
this.renderer.renderBorders(borderData.borders);
|
||||||
switch(container.node.nodeName) {
|
switch(container.node.nodeName) {
|
||||||
case "svg":
|
case "svg":
|
||||||
var svgContainer = this.images.get(container.node);
|
case "IFRAME":
|
||||||
if (svgContainer) {
|
var imgContainer = this.images.get(container.node);
|
||||||
this.renderer.renderImage(container, bounds, borderData, svgContainer);
|
if (imgContainer) {
|
||||||
|
this.renderer.renderImage(container, bounds, borderData, imgContainer);
|
||||||
} else {
|
} else {
|
||||||
log("Error loading <svg>", container.node);
|
log("Error loading <" + container.node.nodeName + ">", container.node);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "IMG":
|
case "IMG":
|
||||||
|
4
dist/html2canvas.min.js
vendored
4
dist/html2canvas.min.js
vendored
File diff suppressed because one or more lines are too long
@ -34,8 +34,8 @@ function renderDocument(document, options, windowWidth, windowHeight) {
|
|||||||
var support = new Support(clonedWindow.document);
|
var support = new Support(clonedWindow.document);
|
||||||
var imageLoader = new ImageLoader(options, support);
|
var imageLoader = new ImageLoader(options, support);
|
||||||
var bounds = getBounds(node);
|
var bounds = getBounds(node);
|
||||||
var width = options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth();
|
var width = options.width != null ? options.width : options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth();
|
||||||
var height = options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight();
|
var height = options.height != null ? options.height : options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight();
|
||||||
var renderer = new CanvasRenderer(width, height, imageLoader, options, document);
|
var renderer = new CanvasRenderer(width, height, imageLoader, options, document);
|
||||||
var parser = new NodeParser(node, renderer, support, imageLoader, options);
|
var parser = new NodeParser(node, renderer, support, imageLoader, options);
|
||||||
return parser.ready.then(function() {
|
return parser.ready.then(function() {
|
||||||
|
23
src/framecontainer.js
Normal file
23
src/framecontainer.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
function FrameContainer(container) {
|
||||||
|
this.image = null;
|
||||||
|
this.src = container;
|
||||||
|
var self = this;
|
||||||
|
var bounds = getBounds(container);
|
||||||
|
this.promise = new Promise(function(resolve) {
|
||||||
|
if (container.contentWindow.document.URL === "about:blank" || container.contentWindow.document.documentElement == null) {
|
||||||
|
container.contentWindow.onload = container.onload = function() {
|
||||||
|
resolve(container);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
resolve(container);
|
||||||
|
}
|
||||||
|
|
||||||
|
}).then(function(container) {
|
||||||
|
return html2canvas(container.contentWindow.document.documentElement, {
|
||||||
|
width: bounds.width,
|
||||||
|
height: bounds.height
|
||||||
|
});
|
||||||
|
}).then(function(canvas) {
|
||||||
|
return self.image = canvas;
|
||||||
|
});
|
||||||
|
}
|
@ -7,8 +7,22 @@ function ImageLoader(options, support) {
|
|||||||
|
|
||||||
ImageLoader.prototype.findImages = function(nodes) {
|
ImageLoader.prototype.findImages = function(nodes) {
|
||||||
var images = [];
|
var images = [];
|
||||||
nodes.filter(isImage).map(urlImage).forEach(this.addImage(images, this.loadImage), this);
|
nodes.reduce(function(imageNodes, container) {
|
||||||
nodes.filter(isSVGNode).map(svgImage).forEach(this.addImage(images, this.loadImage), this);
|
switch(container.node.nodeName) {
|
||||||
|
case "IMG":
|
||||||
|
return imageNodes.concat([{
|
||||||
|
args: [container.node.src],
|
||||||
|
method: "url"
|
||||||
|
}]);
|
||||||
|
case "svg":
|
||||||
|
case "IFRAME":
|
||||||
|
return imageNodes.concat([{
|
||||||
|
args: [container.node],
|
||||||
|
method: container.node.nodeName
|
||||||
|
}]);
|
||||||
|
}
|
||||||
|
return imageNodes;
|
||||||
|
}, []).forEach(this.addImage(images, this.loadImage), this);
|
||||||
return images;
|
return images;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -54,6 +68,8 @@ ImageLoader.prototype.loadImage = function(imageData) {
|
|||||||
return new WebkitGradientContainer(imageData);
|
return new WebkitGradientContainer(imageData);
|
||||||
} else if (imageData.method === "svg") {
|
} else if (imageData.method === "svg") {
|
||||||
return new SVGNodeContainer(imageData.args[0]);
|
return new SVGNodeContainer(imageData.args[0]);
|
||||||
|
} else if (imageData.method === "IFRAME") {
|
||||||
|
return new FrameContainer(imageData.args[0]);
|
||||||
} else {
|
} else {
|
||||||
return new DummyImageContainer(imageData);
|
return new DummyImageContainer(imageData);
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,6 @@ NodeParser.prototype.getPseudoElement = function(container, type) {
|
|||||||
var pseudoNode = document.createElement(isImage ? 'img' : 'html2canvaspseudoelement');
|
var pseudoNode = document.createElement(isImage ? 'img' : 'html2canvaspseudoelement');
|
||||||
var pseudoContainer = new NodeContainer(pseudoNode, container);
|
var pseudoContainer = new NodeContainer(pseudoNode, container);
|
||||||
|
|
||||||
|
|
||||||
for (var i = style.length-1; i >= 0; i--) {
|
for (var i = style.length-1; i >= 0; i--) {
|
||||||
var property = toCamelCase(style.item(i));
|
var property = toCamelCase(style.item(i));
|
||||||
pseudoNode.style[property] = style[property];
|
pseudoNode.style[property] = style[property];
|
||||||
@ -251,11 +250,12 @@ NodeParser.prototype.paintNode = function(container) {
|
|||||||
this.renderer.renderBorders(borderData.borders);
|
this.renderer.renderBorders(borderData.borders);
|
||||||
switch(container.node.nodeName) {
|
switch(container.node.nodeName) {
|
||||||
case "svg":
|
case "svg":
|
||||||
var svgContainer = this.images.get(container.node);
|
case "IFRAME":
|
||||||
if (svgContainer) {
|
var imgContainer = this.images.get(container.node);
|
||||||
this.renderer.renderImage(container, bounds, borderData, svgContainer);
|
if (imgContainer) {
|
||||||
|
this.renderer.renderImage(container, bounds, borderData, imgContainer);
|
||||||
} else {
|
} else {
|
||||||
log("Error loading <svg>", container.node);
|
log("Error loading <" + container.node.nodeName + ">", container.node);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "IMG":
|
case "IMG":
|
||||||
|
16
tests/assets/iframe/frame1.html
Normal file
16
tests/assets/iframe/frame1.html
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head lang="en">
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>frame 1</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: green;
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
this is the content of frame1
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -5,6 +5,6 @@
|
|||||||
<script type="text/javascript" src="../test.js"></script>
|
<script type="text/javascript" src="../test.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<iframe src="http://experiments.hertzen.com/csstree/" width="500"></iframe>
|
<iframe src="/tests/assets/iframe/frame1.html" width="500" height="500"></iframe>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -12,7 +12,7 @@ var h2cSelector, h2cOptions;
|
|||||||
}
|
}
|
||||||
|
|
||||||
var sources = ['log', 'punycode/punycode', 'core', 'nodecontainer', 'stackingcontext', 'textcontainer', 'support', 'imagecontainer', 'dummyimagecontainer', 'proxyimagecontainer', 'gradientcontainer',
|
var sources = ['log', 'punycode/punycode', 'core', 'nodecontainer', 'stackingcontext', 'textcontainer', 'support', 'imagecontainer', 'dummyimagecontainer', 'proxyimagecontainer', 'gradientcontainer',
|
||||||
'lineargradientcontainer', 'webkitgradientcontainer', 'svgcontainer', 'svgnodecontainer', 'imageloader', 'nodeparser', 'font', 'fontmetrics', 'renderer', 'promise', 'xhr', 'renderers/canvas'];
|
'lineargradientcontainer', 'webkitgradientcontainer', 'svgcontainer', 'svgnodecontainer', 'imageloader', 'nodeparser', 'font', 'fontmetrics', 'renderer', 'promise', 'xhr', 'framecontainer', 'renderers/canvas'];
|
||||||
|
|
||||||
['/tests/assets/jquery-1.6.2'].concat(window.location.search === "?selenium" ? ['/dist/html2canvas'] : sources.map(function(src) { return '/src/' + src; })).forEach(appendScript);
|
['/tests/assets/jquery-1.6.2'].concat(window.location.search === "?selenium" ? ['/dist/html2canvas'] : sources.map(function(src) { return '/src/' + src; })).forEach(appendScript);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user