mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Correctly clone <select> and <textarea> value property
This commit is contained in:
parent
a7a719f864
commit
a532b6004c
19
dist/html2canvas.js
vendored
19
dist/html2canvas.js
vendored
@ -581,6 +581,7 @@ window.html2canvas = function(nodeList, options) {
|
|||||||
options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
|
options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
|
||||||
options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout;
|
options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout;
|
||||||
options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer;
|
options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer;
|
||||||
|
options.strict = !!options.strict;
|
||||||
|
|
||||||
if (typeof(nodeList) === "string") {
|
if (typeof(nodeList) === "string") {
|
||||||
if (typeof(options.proxy) !== "string") {
|
if (typeof(options.proxy) !== "string") {
|
||||||
@ -705,6 +706,10 @@ function createWindowClone(ownerDocument, containerDocument, width, height, opti
|
|||||||
|
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
var documentClone = container.contentWindow.document;
|
var documentClone = container.contentWindow.document;
|
||||||
|
|
||||||
|
cloneNodeValues(ownerDocument.documentElement, documentElement, "textarea");
|
||||||
|
cloneNodeValues(ownerDocument.documentElement, documentElement, "select");
|
||||||
|
|
||||||
/* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle
|
/* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle
|
||||||
if window url is about:blank, we can assign the url to current by writing onto the document
|
if window url is about:blank, we can assign the url to current by writing onto the document
|
||||||
*/
|
*/
|
||||||
@ -733,6 +738,15 @@ function createWindowClone(ownerDocument, containerDocument, width, height, opti
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cloneNodeValues(document, clone, nodeName) {
|
||||||
|
var originalNodes = document.getElementsByTagName(nodeName);
|
||||||
|
var clonedNodes = clone.getElementsByTagName(nodeName);
|
||||||
|
var count = originalNodes.length;
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
clonedNodes[i].value = originalNodes[i].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function restoreOwnerScroll(ownerDocument, x, y) {
|
function restoreOwnerScroll(ownerDocument, x, y) {
|
||||||
if (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset) {
|
if (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset) {
|
||||||
ownerDocument.defaultView.scrollTo(x, y);
|
ownerDocument.defaultView.scrollTo(x, y);
|
||||||
@ -2245,7 +2259,8 @@ NodeParser.prototype.paintRadio = function(container) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
NodeParser.prototype.paintFormValue = function(container) {
|
NodeParser.prototype.paintFormValue = function(container) {
|
||||||
if (container.getValue().length > 0) {
|
var value = container.getValue();
|
||||||
|
if (value.length > 0) {
|
||||||
var document = container.node.ownerDocument;
|
var document = container.node.ownerDocument;
|
||||||
var wrapper = document.createElement('html2canvaswrapper');
|
var wrapper = document.createElement('html2canvaswrapper');
|
||||||
var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',
|
var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',
|
||||||
@ -2265,7 +2280,7 @@ NodeParser.prototype.paintFormValue = function(container) {
|
|||||||
wrapper.style.position = "fixed";
|
wrapper.style.position = "fixed";
|
||||||
wrapper.style.left = bounds.left + "px";
|
wrapper.style.left = bounds.left + "px";
|
||||||
wrapper.style.top = bounds.top + "px";
|
wrapper.style.top = bounds.top + "px";
|
||||||
wrapper.textContent = container.getValue();
|
wrapper.textContent = value;
|
||||||
document.body.appendChild(wrapper);
|
document.body.appendChild(wrapper);
|
||||||
this.paintText(new TextContainer(wrapper.firstChild, container));
|
this.paintText(new TextContainer(wrapper.firstChild, container));
|
||||||
document.body.removeChild(wrapper);
|
document.body.removeChild(wrapper);
|
||||||
|
4
dist/html2canvas.min.js
vendored
4
dist/html2canvas.min.js
vendored
File diff suppressed because one or more lines are too long
14
src/core.js
14
src/core.js
@ -17,6 +17,7 @@ window.html2canvas = function(nodeList, options) {
|
|||||||
options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
|
options.javascriptEnabled = typeof(options.javascriptEnabled) === "undefined" ? false : options.javascriptEnabled;
|
||||||
options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout;
|
options.imageTimeout = typeof(options.imageTimeout) === "undefined" ? 10000 : options.imageTimeout;
|
||||||
options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer;
|
options.renderer = typeof(options.renderer) === "function" ? options.renderer : CanvasRenderer;
|
||||||
|
options.strict = !!options.strict;
|
||||||
|
|
||||||
if (typeof(nodeList) === "string") {
|
if (typeof(nodeList) === "string") {
|
||||||
if (typeof(options.proxy) !== "string") {
|
if (typeof(options.proxy) !== "string") {
|
||||||
@ -141,6 +142,10 @@ function createWindowClone(ownerDocument, containerDocument, width, height, opti
|
|||||||
|
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
var documentClone = container.contentWindow.document;
|
var documentClone = container.contentWindow.document;
|
||||||
|
|
||||||
|
cloneNodeValues(ownerDocument.documentElement, documentElement, "textarea");
|
||||||
|
cloneNodeValues(ownerDocument.documentElement, documentElement, "select");
|
||||||
|
|
||||||
/* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle
|
/* Chrome doesn't detect relative background-images assigned in inline <style> sheets when fetched through getComputedStyle
|
||||||
if window url is about:blank, we can assign the url to current by writing onto the document
|
if window url is about:blank, we can assign the url to current by writing onto the document
|
||||||
*/
|
*/
|
||||||
@ -169,6 +174,15 @@ function createWindowClone(ownerDocument, containerDocument, width, height, opti
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function cloneNodeValues(document, clone, nodeName) {
|
||||||
|
var originalNodes = document.getElementsByTagName(nodeName);
|
||||||
|
var clonedNodes = clone.getElementsByTagName(nodeName);
|
||||||
|
var count = originalNodes.length;
|
||||||
|
for (var i = 0; i < count; i++) {
|
||||||
|
clonedNodes[i].value = originalNodes[i].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function restoreOwnerScroll(ownerDocument, x, y) {
|
function restoreOwnerScroll(ownerDocument, x, y) {
|
||||||
if (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset) {
|
if (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset) {
|
||||||
ownerDocument.defaultView.scrollTo(x, y);
|
ownerDocument.defaultView.scrollTo(x, y);
|
||||||
|
@ -388,7 +388,8 @@ NodeParser.prototype.paintRadio = function(container) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
NodeParser.prototype.paintFormValue = function(container) {
|
NodeParser.prototype.paintFormValue = function(container) {
|
||||||
if (container.getValue().length > 0) {
|
var value = container.getValue();
|
||||||
|
if (value.length > 0) {
|
||||||
var document = container.node.ownerDocument;
|
var document = container.node.ownerDocument;
|
||||||
var wrapper = document.createElement('html2canvaswrapper');
|
var wrapper = document.createElement('html2canvaswrapper');
|
||||||
var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',
|
var properties = ['lineHeight', 'textAlign', 'fontFamily', 'fontWeight', 'fontSize', 'color',
|
||||||
@ -408,7 +409,7 @@ NodeParser.prototype.paintFormValue = function(container) {
|
|||||||
wrapper.style.position = "fixed";
|
wrapper.style.position = "fixed";
|
||||||
wrapper.style.left = bounds.left + "px";
|
wrapper.style.left = bounds.left + "px";
|
||||||
wrapper.style.top = bounds.top + "px";
|
wrapper.style.top = bounds.top + "px";
|
||||||
wrapper.textContent = container.getValue();
|
wrapper.textContent = value;
|
||||||
document.body.appendChild(wrapper);
|
document.body.appendChild(wrapper);
|
||||||
this.paintText(new TextContainer(wrapper.firstChild, container));
|
this.paintText(new TextContainer(wrapper.firstChild, container));
|
||||||
document.body.removeChild(wrapper);
|
document.body.removeChild(wrapper);
|
||||||
|
163
tests/mocha/form-rendering.html
Normal file
163
tests/mocha/form-rendering.html
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Mocha Tests</title>
|
||||||
|
<link rel="stylesheet" href="lib/mocha.css" />
|
||||||
|
<script src="../../dist/html2canvas.js"></script>
|
||||||
|
<script src="../../src/log.js"></script>
|
||||||
|
<script src="../../src/renderer.js"></script>
|
||||||
|
<script src="../../src/renderers/canvas.js"></script>
|
||||||
|
<script src="../assets/jquery-1.6.2.js"></script>
|
||||||
|
<script src="lib/expect.js"></script>
|
||||||
|
<script src="lib/mocha.js"></script>
|
||||||
|
<style>
|
||||||
|
.block {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="mocha"></div>
|
||||||
|
<script>mocha.setup('bdd')</script>
|
||||||
|
<div id="block1" class="block">
|
||||||
|
<input type="text" value="text" />
|
||||||
|
</div>
|
||||||
|
<div id="block2" class="block">
|
||||||
|
<input type="password" value="password" />
|
||||||
|
</div>
|
||||||
|
<div id="block3" class="block">
|
||||||
|
<input type="text" value="text" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="block4" class="block">
|
||||||
|
<textarea>text</textarea>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="block5" class="block">
|
||||||
|
<select>
|
||||||
|
<option value="1">1</option>
|
||||||
|
<option value="2" selected>2</option>
|
||||||
|
<option value="3">3</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="green-block"></div>
|
||||||
|
<script>
|
||||||
|
describe("Rendering input values", function() {
|
||||||
|
it("uses default value for input[type='text']", function(done) {
|
||||||
|
CanvasRenderer.prototype.text = function(text) {
|
||||||
|
expect(text).to.equal('text');
|
||||||
|
};
|
||||||
|
html2canvas(document.querySelector("#block1"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||||
|
expect(canvas.width).to.equal(200);
|
||||||
|
expect(canvas.height).to.equal(200);
|
||||||
|
done();
|
||||||
|
}).catch(function(error) {
|
||||||
|
done(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("uses transformed value for input[type='password']", function(done) {
|
||||||
|
var count = 0;
|
||||||
|
CanvasRenderer.prototype.text = function(text) {
|
||||||
|
expect(text).to.equal('•');
|
||||||
|
count++;
|
||||||
|
};
|
||||||
|
html2canvas(document.querySelector("#block2"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||||
|
expect(canvas.width).to.equal(200);
|
||||||
|
expect(canvas.height).to.equal(200);
|
||||||
|
expect(count).to.equal("password".length);
|
||||||
|
done();
|
||||||
|
}).catch(function(error) {
|
||||||
|
done(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("used property and not attribute for rendering", function(done) {
|
||||||
|
document.querySelector("#block3 input").value = 'updated';
|
||||||
|
|
||||||
|
CanvasRenderer.prototype.text = function(text) {
|
||||||
|
expect(text).to.equal('updated');
|
||||||
|
};
|
||||||
|
html2canvas(document.querySelector("#block3"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||||
|
expect(canvas.width).to.equal(200);
|
||||||
|
expect(canvas.height).to.equal(200);
|
||||||
|
done();
|
||||||
|
}).catch(function(error) {
|
||||||
|
done(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Rendering textarea values", function() {
|
||||||
|
it("uses default value correctly", function(done) {
|
||||||
|
CanvasRenderer.prototype.text = function(text) {
|
||||||
|
expect(text).to.equal('text');
|
||||||
|
};
|
||||||
|
html2canvas(document.querySelector("#block4"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||||
|
expect(canvas.width).to.equal(200);
|
||||||
|
expect(canvas.height).to.equal(200);
|
||||||
|
done();
|
||||||
|
}).catch(function(error) {
|
||||||
|
done(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("used property and not attribute for rendering", function(done) {
|
||||||
|
document.querySelector("#block4 textarea").value = 'updated';
|
||||||
|
|
||||||
|
CanvasRenderer.prototype.text = function(text) {
|
||||||
|
expect(text).to.equal('updated');
|
||||||
|
};
|
||||||
|
html2canvas(document.querySelector("#block4"), {renderer: CanvasRenderer, strict: true, logging: true, removeContainer: false}).then(function(canvas) {
|
||||||
|
expect(canvas.width).to.equal(200);
|
||||||
|
expect(canvas.height).to.equal(200);
|
||||||
|
done();
|
||||||
|
}).catch(function(error) {
|
||||||
|
done(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("Select values", function() {
|
||||||
|
it("uses default value correctly", function(done) {
|
||||||
|
CanvasRenderer.prototype.text = function(text) {
|
||||||
|
expect(text).to.equal('2');
|
||||||
|
};
|
||||||
|
html2canvas(document.querySelector("#block5"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
||||||
|
expect(canvas.width).to.equal(200);
|
||||||
|
expect(canvas.height).to.equal(200);
|
||||||
|
done();
|
||||||
|
}).catch(function(error) {
|
||||||
|
done(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("used property and not attribute for rendering", function(done) {
|
||||||
|
document.querySelector("#block5 select").value = '3';
|
||||||
|
|
||||||
|
CanvasRenderer.prototype.text = function(text) {
|
||||||
|
expect(text).to.equal('3');
|
||||||
|
};
|
||||||
|
html2canvas(document.querySelector("#block5"), {renderer: CanvasRenderer, strict: true, logging: true, removeContainer: false}).then(function(canvas) {
|
||||||
|
expect(canvas.width).to.equal(200);
|
||||||
|
expect(canvas.height).to.equal(200);
|
||||||
|
done();
|
||||||
|
}).catch(function(error) {
|
||||||
|
done(error);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
mocha.checkLeaks();
|
||||||
|
mocha.globals(['jQuery']);
|
||||||
|
if (window.mochaPhantomJS) {
|
||||||
|
mochaPhantomJS.run();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mocha.run();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -1,72 +0,0 @@
|
|||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>Mocha Tests</title>
|
|
||||||
<link rel="stylesheet" href="lib/mocha.css" />
|
|
||||||
<script src="../../dist/html2canvas.js"></script>
|
|
||||||
<script src="../../src/log.js"></script>
|
|
||||||
<script src="../../src/renderer.js"></script>
|
|
||||||
<script src="../../src/renderers/canvas.js"></script>
|
|
||||||
<script src="../assets/jquery-1.6.2.js"></script>
|
|
||||||
<script src="lib/expect.js"></script>
|
|
||||||
<script src="lib/mocha.js"></script>
|
|
||||||
<style>
|
|
||||||
.block {
|
|
||||||
width: 200px;
|
|
||||||
height: 200px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="mocha"></div>
|
|
||||||
<script>mocha.setup('bdd')</script>
|
|
||||||
<div id="block1" class="block">
|
|
||||||
<input type="text" value="text" />
|
|
||||||
</div>
|
|
||||||
<div id="block2" class="block">
|
|
||||||
<input type="password" value="password" />
|
|
||||||
</div>
|
|
||||||
<div id="green-block"></div>
|
|
||||||
<script>
|
|
||||||
describe("Rendering input values", function() {
|
|
||||||
it("uses default value for input[type='text']", function(done) {
|
|
||||||
CanvasRenderer.prototype.text = function(text) {
|
|
||||||
expect(text).to.equal('text');
|
|
||||||
};
|
|
||||||
html2canvas(document.querySelector("#block1"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
|
||||||
expect(canvas.width).to.equal(200);
|
|
||||||
expect(canvas.height).to.equal(200);
|
|
||||||
done();
|
|
||||||
}).catch(function(error) {
|
|
||||||
done(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("uses transformed value for input[type='password']", function(done) {
|
|
||||||
var count = 0;
|
|
||||||
CanvasRenderer.prototype.text = function(text) {
|
|
||||||
expect(text).to.equal('•');
|
|
||||||
count++;
|
|
||||||
};
|
|
||||||
html2canvas(document.querySelector("#block2"), {renderer: CanvasRenderer, strict: true}).then(function(canvas) {
|
|
||||||
expect(canvas.width).to.equal(200);
|
|
||||||
expect(canvas.height).to.equal(200);
|
|
||||||
expect(count).to.equal("password".length);
|
|
||||||
done();
|
|
||||||
}).catch(function(error) {
|
|
||||||
done(error);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
mocha.checkLeaks();
|
|
||||||
mocha.globals(['jQuery']);
|
|
||||||
if (window.mochaPhantomJS) {
|
|
||||||
mochaPhantomJS.run();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mocha.run();
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Loading…
x
Reference in New Issue
Block a user