mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Add simpler api for rendering external urls
This commit is contained in:
parent
1e19832171
commit
19777c6623
@ -15,5 +15,5 @@
|
||||
"jQuery": true
|
||||
},
|
||||
"predef": ["NodeParser", "NodeContainer", "StackingContext", "TextContainer", "ImageLoader", "CanvasRenderer", "Renderer", "Support", "bind", "Promise", "getBounds", "offsetBounds", "XHR",
|
||||
"ImageContainer", "ProxyImageContainer", "DummyImageContainer", "Font", "FontMetrics", "GradientContainer", "LinearGradientContainer", "WebkitGradientContainer", "SVGContainer", "SVGNodeContainer", "FrameContainer", "html2canvas", "log", "smallImage", "parseBackgrounds", "createWindowClone", "decode64", "Proxy", "ProxyURL"]
|
||||
"ImageContainer", "ProxyImageContainer", "DummyImageContainer", "Font", "FontMetrics", "GradientContainer", "LinearGradientContainer", "WebkitGradientContainer", "SVGContainer", "SVGNodeContainer", "FrameContainer", "html2canvas", "log", "smallImage", "parseBackgrounds", "loadUrlDocument", "decode64", "Proxy", "ProxyURL"]
|
||||
}
|
||||
|
117
dist/html2canvas.js
vendored
117
dist/html2canvas.js
vendored
@ -580,6 +580,16 @@ window.html2canvas = function(nodeList, options) {
|
||||
options.async = typeof(options.async) === "undefined" ? true : options.async;
|
||||
options.allowTaint = typeof(options.allowTaint) === "undefined" ? false : options.allowTaint;
|
||||
options.removeContainer = typeof(options.removeContainer) === "undefined" ? true : options.removeContainer;
|
||||
options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
|
||||
|
||||
if (typeof(nodeList) === "string") {
|
||||
if (typeof(options.proxy) !== "string") {
|
||||
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) {
|
||||
return renderWindow(container.contentWindow.document.documentElement, container, options, window.innerWidth, window.innerHeight);
|
||||
});
|
||||
}
|
||||
|
||||
var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];
|
||||
node.setAttribute(html2canvasNodeAttribute, "true");
|
||||
@ -602,25 +612,34 @@ function renderDocument(document, options, windowWidth, windowHeight) {
|
||||
document.querySelector(selector).removeAttribute(html2canvasNodeAttribute);
|
||||
var clonedWindow = container.contentWindow;
|
||||
var node = clonedWindow.document.querySelector(selector);
|
||||
var support = new Support(clonedWindow.document);
|
||||
var imageLoader = new ImageLoader(options, support);
|
||||
var bounds = getBounds(node);
|
||||
var width = options.width != null ? options.width : options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth(clonedWindow.document);
|
||||
var height = options.height != null ? options.height : options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight(clonedWindow.document);
|
||||
var renderer = new CanvasRenderer(width, height, imageLoader, options, document);
|
||||
var parser = new NodeParser(node, renderer, support, imageLoader, options);
|
||||
return parser.ready.then(function() {
|
||||
log("Finished rendering");
|
||||
var canvas = (options.type !== "view" && (node === clonedWindow.document.body || node === clonedWindow.document.documentElement)) ? renderer.canvas : crop(renderer.canvas, bounds);
|
||||
if (options.removeContainer) {
|
||||
container.parentNode.removeChild(container);
|
||||
log("Cleaned up container");
|
||||
}
|
||||
return canvas;
|
||||
});
|
||||
return renderWindow(node, container, options, windowWidth, windowHeight);
|
||||
});
|
||||
}
|
||||
|
||||
function renderWindow(node, container, options, windowWidth, windowHeight) {
|
||||
var clonedWindow = container.contentWindow;
|
||||
var support = new Support(clonedWindow.document);
|
||||
var imageLoader = new ImageLoader(options, support);
|
||||
var bounds = getBounds(node);
|
||||
var width = options.width != null ? options.width : options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth(clonedWindow.document);
|
||||
var height = options.height != null ? options.height : options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight(clonedWindow.document);
|
||||
var renderer = new CanvasRenderer(width, height, imageLoader, options, document);
|
||||
var parser = new NodeParser(node, renderer, support, imageLoader, options);
|
||||
return parser.ready.then(function() {
|
||||
log("Finished rendering");
|
||||
var canvas = (options.type !== "view" && (node === clonedWindow.document.body || node === clonedWindow.document.documentElement)) ? renderer.canvas : crop(renderer.canvas, bounds);
|
||||
cleanupContainer(container, options);
|
||||
return canvas;
|
||||
});
|
||||
}
|
||||
|
||||
function cleanupContainer(container, options) {
|
||||
if (options.removeContainer) {
|
||||
container.parentNode.removeChild(container);
|
||||
log("Cleaned up container");
|
||||
}
|
||||
}
|
||||
|
||||
function crop(canvas, bounds) {
|
||||
var croppedCanvas = document.createElement("canvas");
|
||||
var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left));
|
||||
@ -684,13 +703,38 @@ function createWindowClone(ownerDocument, containerDocument, width, height, opti
|
||||
documentClone.write("<!DOCTYPE html>");
|
||||
documentClone.close();
|
||||
|
||||
documentClone.replaceChild(removeScriptNodes(documentClone.adoptNode(documentElement)), documentClone.documentElement);
|
||||
documentClone.replaceChild(options.javascriptEnabled === true ? documentClone.adoptNode(documentElement) : removeScriptNodes(documentClone.adoptNode(documentElement)), documentClone.documentElement);
|
||||
if (options.type === "view") {
|
||||
container.contentWindow.scrollTo(window.pageXOffset, window.pageYOffset);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadUrlDocument(src, proxy, document, width, height, options) {
|
||||
return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {
|
||||
return createWindowClone(doc, document, width, height, options);
|
||||
});
|
||||
}
|
||||
|
||||
function documentFromHTML(src) {
|
||||
return function(html) {
|
||||
var doc = document.implementation.createHTMLDocument("");
|
||||
doc.open();
|
||||
doc.write(html);
|
||||
doc.close();
|
||||
|
||||
var b = doc.querySelector("base");
|
||||
if (!b || !b.href.host) {
|
||||
var base = doc.createElement("base");
|
||||
base.href = src;
|
||||
doc.head.insertBefore(base, doc.head.firstChild);
|
||||
}
|
||||
|
||||
return doc;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function labelCanvasElements(ownerDocument) {
|
||||
[].slice.call(ownerDocument.querySelectorAll("canvas"), 0).forEach(function(canvas) {
|
||||
canvas.setAttribute(html2canvasCanvasCloneAttribute, "canvas-" + html2canvasCanvasCloneIndex++);
|
||||
@ -728,6 +772,13 @@ function isElementNode(node) {
|
||||
return node.nodeType === Node.ELEMENT_NODE;
|
||||
}
|
||||
|
||||
function absoluteUrl(url) {
|
||||
var link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.href = link.href;
|
||||
return link;
|
||||
}
|
||||
|
||||
function DummyImageContainer(src) {
|
||||
this.src = src;
|
||||
log("DummyImageContainer for", src);
|
||||
@ -806,12 +857,12 @@ FontMetrics.prototype.getMetrics = function(family, size) {
|
||||
return this.data[family + "-" + size];
|
||||
};
|
||||
|
||||
function FrameContainer(container, sameOrigin, proxy) {
|
||||
function FrameContainer(container, sameOrigin, options) {
|
||||
this.image = null;
|
||||
this.src = container;
|
||||
var self = this;
|
||||
var bounds = getBounds(container);
|
||||
this.promise = (!sameOrigin ? this.proxyLoad(proxy, bounds) : new Promise(function(resolve) {
|
||||
this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) {
|
||||
if (container.contentWindow.document.URL === "about:blank" || container.contentWindow.document.documentElement == null) {
|
||||
container.contentWindow.onload = container.onload = function() {
|
||||
resolve(container);
|
||||
@ -820,37 +871,17 @@ function FrameContainer(container, sameOrigin, proxy) {
|
||||
resolve(container);
|
||||
}
|
||||
})).then(function(container) {
|
||||
return html2canvas(container.contentWindow.document.documentElement, {type: 'view', proxy: proxy});
|
||||
return html2canvas(container.contentWindow.document.documentElement, {type: 'view', proxy: options.proxy, javascriptEnabled: options.javascriptEnabled, removeContainer: options.removeContainer});
|
||||
}).then(function(canvas) {
|
||||
return self.image = canvas;
|
||||
});
|
||||
}
|
||||
|
||||
FrameContainer.prototype.proxyLoad = function(proxy, bounds) {
|
||||
FrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {
|
||||
var container = this.src;
|
||||
return new Proxy(container.src, proxy, window.document).then(documentFromHTML(container)).then(function(doc) {
|
||||
return createWindowClone(doc, container.ownerDocument, bounds.width, bounds.height, {});
|
||||
});
|
||||
return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);
|
||||
};
|
||||
|
||||
function documentFromHTML(container) {
|
||||
return function(html) {
|
||||
var doc = document.implementation.createHTMLDocument("");
|
||||
doc.open();
|
||||
doc.write(html);
|
||||
doc.close();
|
||||
|
||||
var b = doc.querySelector("base");
|
||||
if (!b || !b.href.host) {
|
||||
var base = doc.createElement("base");
|
||||
base.href = container.src;
|
||||
doc.head.insertBefore(base, doc.head.firstChild);
|
||||
}
|
||||
|
||||
return doc;
|
||||
};
|
||||
}
|
||||
|
||||
function GradientContainer(imageData) {
|
||||
this.src = imageData.value;
|
||||
this.colorStops = [];
|
||||
@ -956,7 +987,7 @@ ImageLoader.prototype.loadImage = function(imageData) {
|
||||
} else if (imageData.method === "svg") {
|
||||
return new SVGNodeContainer(imageData.args[0], this.support.svg);
|
||||
} else if (imageData.method === "IFRAME") {
|
||||
return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options.proxy);
|
||||
return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options);
|
||||
} else {
|
||||
return new DummyImageContainer(imageData);
|
||||
}
|
||||
|
4
dist/html2canvas.min.js
vendored
4
dist/html2canvas.min.js
vendored
File diff suppressed because one or more lines are too long
85
src/core.js
85
src/core.js
@ -12,6 +12,16 @@ window.html2canvas = function(nodeList, options) {
|
||||
options.async = typeof(options.async) === "undefined" ? true : options.async;
|
||||
options.allowTaint = typeof(options.allowTaint) === "undefined" ? false : options.allowTaint;
|
||||
options.removeContainer = typeof(options.removeContainer) === "undefined" ? true : options.removeContainer;
|
||||
options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
|
||||
|
||||
if (typeof(nodeList) === "string") {
|
||||
if (typeof(options.proxy) !== "string") {
|
||||
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) {
|
||||
return renderWindow(container.contentWindow.document.documentElement, container, options, window.innerWidth, window.innerHeight);
|
||||
});
|
||||
}
|
||||
|
||||
var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];
|
||||
node.setAttribute(html2canvasNodeAttribute, "true");
|
||||
@ -34,25 +44,34 @@ function renderDocument(document, options, windowWidth, windowHeight) {
|
||||
document.querySelector(selector).removeAttribute(html2canvasNodeAttribute);
|
||||
var clonedWindow = container.contentWindow;
|
||||
var node = clonedWindow.document.querySelector(selector);
|
||||
var support = new Support(clonedWindow.document);
|
||||
var imageLoader = new ImageLoader(options, support);
|
||||
var bounds = getBounds(node);
|
||||
var width = options.width != null ? options.width : options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth(clonedWindow.document);
|
||||
var height = options.height != null ? options.height : options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight(clonedWindow.document);
|
||||
var renderer = new CanvasRenderer(width, height, imageLoader, options, document);
|
||||
var parser = new NodeParser(node, renderer, support, imageLoader, options);
|
||||
return parser.ready.then(function() {
|
||||
log("Finished rendering");
|
||||
var canvas = (options.type !== "view" && (node === clonedWindow.document.body || node === clonedWindow.document.documentElement)) ? renderer.canvas : crop(renderer.canvas, bounds);
|
||||
if (options.removeContainer) {
|
||||
container.parentNode.removeChild(container);
|
||||
log("Cleaned up container");
|
||||
}
|
||||
return canvas;
|
||||
});
|
||||
return renderWindow(node, container, options, windowWidth, windowHeight);
|
||||
});
|
||||
}
|
||||
|
||||
function renderWindow(node, container, options, windowWidth, windowHeight) {
|
||||
var clonedWindow = container.contentWindow;
|
||||
var support = new Support(clonedWindow.document);
|
||||
var imageLoader = new ImageLoader(options, support);
|
||||
var bounds = getBounds(node);
|
||||
var width = options.width != null ? options.width : options.type === "view" ? Math.min(bounds.width, windowWidth) : documentWidth(clonedWindow.document);
|
||||
var height = options.height != null ? options.height : options.type === "view" ? Math.min(bounds.height, windowHeight) : documentHeight(clonedWindow.document);
|
||||
var renderer = new CanvasRenderer(width, height, imageLoader, options, document);
|
||||
var parser = new NodeParser(node, renderer, support, imageLoader, options);
|
||||
return parser.ready.then(function() {
|
||||
log("Finished rendering");
|
||||
var canvas = (options.type !== "view" && (node === clonedWindow.document.body || node === clonedWindow.document.documentElement)) ? renderer.canvas : crop(renderer.canvas, bounds);
|
||||
cleanupContainer(container, options);
|
||||
return canvas;
|
||||
});
|
||||
}
|
||||
|
||||
function cleanupContainer(container, options) {
|
||||
if (options.removeContainer) {
|
||||
container.parentNode.removeChild(container);
|
||||
log("Cleaned up container");
|
||||
}
|
||||
}
|
||||
|
||||
function crop(canvas, bounds) {
|
||||
var croppedCanvas = document.createElement("canvas");
|
||||
var x1 = Math.min(canvas.width - 1, Math.max(0, bounds.left));
|
||||
@ -116,13 +135,38 @@ function createWindowClone(ownerDocument, containerDocument, width, height, opti
|
||||
documentClone.write("<!DOCTYPE html>");
|
||||
documentClone.close();
|
||||
|
||||
documentClone.replaceChild(removeScriptNodes(documentClone.adoptNode(documentElement)), documentClone.documentElement);
|
||||
documentClone.replaceChild(options.javascriptEnabled === true ? documentClone.adoptNode(documentElement) : removeScriptNodes(documentClone.adoptNode(documentElement)), documentClone.documentElement);
|
||||
if (options.type === "view") {
|
||||
container.contentWindow.scrollTo(window.pageXOffset, window.pageYOffset);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadUrlDocument(src, proxy, document, width, height, options) {
|
||||
return new Proxy(src, proxy, window.document).then(documentFromHTML(src)).then(function(doc) {
|
||||
return createWindowClone(doc, document, width, height, options);
|
||||
});
|
||||
}
|
||||
|
||||
function documentFromHTML(src) {
|
||||
return function(html) {
|
||||
var doc = document.implementation.createHTMLDocument("");
|
||||
doc.open();
|
||||
doc.write(html);
|
||||
doc.close();
|
||||
|
||||
var b = doc.querySelector("base");
|
||||
if (!b || !b.href.host) {
|
||||
var base = doc.createElement("base");
|
||||
base.href = src;
|
||||
doc.head.insertBefore(base, doc.head.firstChild);
|
||||
}
|
||||
|
||||
return doc;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function labelCanvasElements(ownerDocument) {
|
||||
[].slice.call(ownerDocument.querySelectorAll("canvas"), 0).forEach(function(canvas) {
|
||||
canvas.setAttribute(html2canvasCanvasCloneAttribute, "canvas-" + html2canvasCanvasCloneIndex++);
|
||||
@ -159,3 +203,10 @@ function removeScriptNodes(parent) {
|
||||
function isElementNode(node) {
|
||||
return node.nodeType === Node.ELEMENT_NODE;
|
||||
}
|
||||
|
||||
function absoluteUrl(url) {
|
||||
var link = document.createElement("a");
|
||||
link.href = url;
|
||||
link.href = link.href;
|
||||
return link;
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
function FrameContainer(container, sameOrigin, proxy) {
|
||||
function FrameContainer(container, sameOrigin, options) {
|
||||
this.image = null;
|
||||
this.src = container;
|
||||
var self = this;
|
||||
var bounds = getBounds(container);
|
||||
this.promise = (!sameOrigin ? this.proxyLoad(proxy, bounds) : new Promise(function(resolve) {
|
||||
this.promise = (!sameOrigin ? this.proxyLoad(options.proxy, bounds, options) : new Promise(function(resolve) {
|
||||
if (container.contentWindow.document.URL === "about:blank" || container.contentWindow.document.documentElement == null) {
|
||||
container.contentWindow.onload = container.onload = function() {
|
||||
resolve(container);
|
||||
@ -12,33 +12,13 @@ function FrameContainer(container, sameOrigin, proxy) {
|
||||
resolve(container);
|
||||
}
|
||||
})).then(function(container) {
|
||||
return html2canvas(container.contentWindow.document.documentElement, {type: 'view', proxy: proxy});
|
||||
return html2canvas(container.contentWindow.document.documentElement, {type: 'view', proxy: options.proxy, javascriptEnabled: options.javascriptEnabled, removeContainer: options.removeContainer});
|
||||
}).then(function(canvas) {
|
||||
return self.image = canvas;
|
||||
});
|
||||
}
|
||||
|
||||
FrameContainer.prototype.proxyLoad = function(proxy, bounds) {
|
||||
FrameContainer.prototype.proxyLoad = function(proxy, bounds, options) {
|
||||
var container = this.src;
|
||||
return new Proxy(container.src, proxy, window.document).then(documentFromHTML(container)).then(function(doc) {
|
||||
return createWindowClone(doc, container.ownerDocument, bounds.width, bounds.height, {});
|
||||
});
|
||||
return loadUrlDocument(container.src, proxy, container.ownerDocument, bounds.width, bounds.height, options);
|
||||
};
|
||||
|
||||
function documentFromHTML(container) {
|
||||
return function(html) {
|
||||
var doc = document.implementation.createHTMLDocument("");
|
||||
doc.open();
|
||||
doc.write(html);
|
||||
doc.close();
|
||||
|
||||
var b = doc.querySelector("base");
|
||||
if (!b || !b.href.host) {
|
||||
var base = doc.createElement("base");
|
||||
base.href = container.src;
|
||||
doc.head.insertBefore(base, doc.head.firstChild);
|
||||
}
|
||||
|
||||
return doc;
|
||||
};
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ ImageLoader.prototype.loadImage = function(imageData) {
|
||||
} else if (imageData.method === "svg") {
|
||||
return new SVGNodeContainer(imageData.args[0], this.support.svg);
|
||||
} else if (imageData.method === "IFRAME") {
|
||||
return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options.proxy);
|
||||
return new FrameContainer(imageData.args[0], this.isSameOrigin(imageData.args[0].src), this.options);
|
||||
} else {
|
||||
return new DummyImageContainer(imageData);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user