mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Prefer native svg rendering if available
This commit is contained in:
parent
b5923fc04b
commit
74988da29e
@ -11,3 +11,4 @@ addons:
|
|||||||
sauce_connect: true
|
sauce_connect: true
|
||||||
before_script:
|
before_script:
|
||||||
- npm install -g grunt-cli
|
- npm install -g grunt-cli
|
||||||
|
- npm install -g uglify-js
|
||||||
|
19
Gruntfile.js
19
Gruntfile.js
@ -1,5 +1,5 @@
|
|||||||
/*global module:false*/
|
/*global module:false*/
|
||||||
var _ = require('lodash');
|
var _ = require('lodash'), path = require('path');
|
||||||
|
|
||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
|
|
||||||
@ -78,6 +78,16 @@ module.exports = function(grunt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
execute: {
|
||||||
|
fabric: {
|
||||||
|
options: {
|
||||||
|
args: ['modules=' + ['text','serialization',
|
||||||
|
'parser', 'gradient', 'pattern', 'shadow', 'freedrawing',
|
||||||
|
'image_filters', 'serialization'].join(","), 'no-es5-compat', 'dest=' + path.resolve(__dirname, 'src/fabric/dist/') + '/']
|
||||||
|
},
|
||||||
|
src: ['src/fabric/build.js']
|
||||||
|
}
|
||||||
|
},
|
||||||
uglify: {
|
uglify: {
|
||||||
dist: {
|
dist: {
|
||||||
src: ['<%= concat.dist.dest %>'],
|
src: ['<%= concat.dist.dest %>'],
|
||||||
@ -92,7 +102,7 @@ module.exports = function(grunt) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
files: 'src/**/*',
|
files: ['src/**/*', '!src/fabric/**/*'],
|
||||||
tasks: ['jshint', 'build']
|
tasks: ['jshint', 'build']
|
||||||
},
|
},
|
||||||
jshint: {
|
jshint: {
|
||||||
@ -150,17 +160,16 @@ module.exports = function(grunt) {
|
|||||||
selenium.tests(browsers, test).onValue(done);
|
selenium.tests(browsers, test).onValue(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load tasks
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||||
grunt.loadNpmTasks('grunt-contrib-qunit');
|
grunt.loadNpmTasks('grunt-contrib-qunit');
|
||||||
grunt.loadNpmTasks('grunt-contrib-connect');
|
grunt.loadNpmTasks('grunt-contrib-connect');
|
||||||
|
grunt.loadNpmTasks('grunt-execute');
|
||||||
|
|
||||||
// Default task.
|
|
||||||
grunt.registerTask('server', ['connect:cors', 'connect']);
|
grunt.registerTask('server', ['connect:cors', 'connect']);
|
||||||
grunt.registerTask('build', ['concat', 'uglify']);
|
grunt.registerTask('build', ['execute', 'concat', 'uglify']);
|
||||||
grunt.registerTask('default', ['jshint', 'concat', 'qunit', 'uglify']);
|
grunt.registerTask('default', ['jshint', 'concat', 'qunit', 'uglify']);
|
||||||
grunt.registerTask('travis', ['jshint', 'concat','qunit', 'uglify', 'connect:ci', 'connect:cors', 'webdriver']);
|
grunt.registerTask('travis', ['jshint', 'concat','qunit', 'uglify', 'connect:ci', 'connect:cors', 'webdriver']);
|
||||||
|
|
||||||
|
31
dist/html2canvas.js
vendored
31
dist/html2canvas.js
vendored
@ -52,6 +52,7 @@ window.html2canvas = function(nodeList, options) {
|
|||||||
|
|
||||||
var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];
|
var node = ((nodeList === undefined) ? [document.documentElement] : ((nodeList.length) ? nodeList : [nodeList]))[0];
|
||||||
node.setAttribute(html2canvasNodeAttribute, "true");
|
node.setAttribute(html2canvasNodeAttribute, "true");
|
||||||
|
|
||||||
return renderDocument(node.ownerDocument, options, window.innerWidth, window.innerHeight).then(function(canvas) {
|
return renderDocument(node.ownerDocument, options, window.innerWidth, window.innerHeight).then(function(canvas) {
|
||||||
if (typeof(options.onrendered) === "function") {
|
if (typeof(options.onrendered) === "function") {
|
||||||
log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
|
log("options.onrendered is deprecated, html2canvas returns a Promise containing the canvas");
|
||||||
@ -323,7 +324,7 @@ ImageLoader.prototype.loadImage = function(imageData) {
|
|||||||
var src = imageData.args[0];
|
var src = imageData.args[0];
|
||||||
if (src.match(/data:image\/.*;base64,/i)) {
|
if (src.match(/data:image\/.*;base64,/i)) {
|
||||||
return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false);
|
return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false);
|
||||||
} else if (/(.+).svg$/i.test(src)) {
|
} else if (/(.+).svg$/i.test(src) && !this.support.svg) {
|
||||||
return new SVGContainer(src);
|
return new SVGContainer(src);
|
||||||
} else if (this.isSameOrigin(src) || this.options.allowTaint === true) {
|
} else if (this.isSameOrigin(src) || this.options.allowTaint === true) {
|
||||||
return new ImageContainer(src, false);
|
return new ImageContainer(src, false);
|
||||||
@ -1696,6 +1697,7 @@ StackingContext.prototype.getParentStack = function(context) {
|
|||||||
function Support(document) {
|
function Support(document) {
|
||||||
this.rangeBounds = this.testRangeBounds(document);
|
this.rangeBounds = this.testRangeBounds(document);
|
||||||
this.cors = this.testCORS();
|
this.cors = this.testCORS();
|
||||||
|
this.svg = this.testSVG();
|
||||||
}
|
}
|
||||||
|
|
||||||
Support.prototype.testRangeBounds = function(document) {
|
Support.prototype.testRangeBounds = function(document) {
|
||||||
@ -1727,12 +1729,31 @@ Support.prototype.testCORS = function() {
|
|||||||
return typeof((new Image()).crossOrigin) !== "undefined";
|
return typeof((new Image()).crossOrigin) !== "undefined";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Support.prototype.testSVG = function() {
|
||||||
|
var img = new Image();
|
||||||
|
var canvas = document.createElement("canvas");
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
img.src = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";
|
||||||
|
|
||||||
|
try {
|
||||||
|
ctx.drawImage(img, 0, 0);
|
||||||
|
canvas.toDataURL();
|
||||||
|
} catch(e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
function SVGContainer(src) {
|
function SVGContainer(src) {
|
||||||
this.src = src;
|
this.src = src;
|
||||||
this.image = null;
|
this.image = null;
|
||||||
var self = this;
|
var self = this;
|
||||||
this.promise = XHR(src).then(function(svg) {
|
this.promise = XHR(src).then(function(svg) {
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
if (!html2canvas.fabric) {
|
||||||
|
return reject(new Error("html2canvas.svg.js is not loaded, cannot render svg"));
|
||||||
|
}
|
||||||
|
|
||||||
html2canvas.fabric.loadSVGFromString(svg, function (objects, options) {
|
html2canvas.fabric.loadSVGFromString(svg, function (objects, options) {
|
||||||
var canvas = new html2canvas.fabric.StaticCanvas('c');
|
var canvas = new html2canvas.fabric.StaticCanvas('c');
|
||||||
self.image = canvas.lowerCanvasEl;
|
self.image = canvas.lowerCanvasEl;
|
||||||
@ -1791,14 +1812,14 @@ function XHR(url) {
|
|||||||
|
|
||||||
xhr.onload = function() {
|
xhr.onload = function() {
|
||||||
if (xhr.status === 200) {
|
if (xhr.status === 200) {
|
||||||
resolve(xhr.response);
|
resolve(xhr.responseText);
|
||||||
} else {
|
} else {
|
||||||
reject(Error(xhr.statusText));
|
reject(new Error(xhr.statusText));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.onerror = function() {
|
xhr.onerror = function() {
|
||||||
reject(Error("Network Error"));
|
reject(new Error("Network Error"));
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.send();
|
xhr.send();
|
||||||
|
4
dist/html2canvas.min.js
vendored
4
dist/html2canvas.min.js
vendored
File diff suppressed because one or more lines are too long
8663
dist/html2canvas.svg.js
vendored
8663
dist/html2canvas.svg.js
vendored
File diff suppressed because it is too large
Load Diff
13
dist/html2canvas.svg.min.js
vendored
13
dist/html2canvas.svg.min.js
vendored
File diff suppressed because one or more lines are too long
@ -29,6 +29,7 @@
|
|||||||
"grunt-contrib-qunit": "*",
|
"grunt-contrib-qunit": "*",
|
||||||
"grunt-contrib-uglify": "*",
|
"grunt-contrib-uglify": "*",
|
||||||
"grunt-contrib-watch": "~0.5.1",
|
"grunt-contrib-watch": "~0.5.1",
|
||||||
|
"grunt-execute": "^0.2.2",
|
||||||
"lodash": "^2.4.1",
|
"lodash": "^2.4.1",
|
||||||
"png-js": ">= 0.1.1",
|
"png-js": ">= 0.1.1",
|
||||||
"wd": "^0.2.21"
|
"wd": "^0.2.21"
|
||||||
|
@ -1 +0,0 @@
|
|||||||
Subproject commit 791c74a82ef0d838fd0bd81bf942f8630a9a4a8f
|
|
@ -34,7 +34,7 @@ ImageLoader.prototype.loadImage = function(imageData) {
|
|||||||
var src = imageData.args[0];
|
var src = imageData.args[0];
|
||||||
if (src.match(/data:image\/.*;base64,/i)) {
|
if (src.match(/data:image\/.*;base64,/i)) {
|
||||||
return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false);
|
return new ImageContainer(src.replace(/url\(['"]{0,}|['"]{0,}\)$/ig, ''), false);
|
||||||
} else if (/(.+).svg$/i.test(src)) {
|
} else if (/(.+).svg$/i.test(src) && !this.support.svg) {
|
||||||
return new SVGContainer(src);
|
return new SVGContainer(src);
|
||||||
} else if (this.isSameOrigin(src) || this.options.allowTaint === true) {
|
} else if (this.isSameOrigin(src) || this.options.allowTaint === true) {
|
||||||
return new ImageContainer(src, false);
|
return new ImageContainer(src, false);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
function Support(document) {
|
function Support(document) {
|
||||||
this.rangeBounds = this.testRangeBounds(document);
|
this.rangeBounds = this.testRangeBounds(document);
|
||||||
this.cors = this.testCORS();
|
this.cors = this.testCORS();
|
||||||
|
this.svg = this.testSVG();
|
||||||
}
|
}
|
||||||
|
|
||||||
Support.prototype.testRangeBounds = function(document) {
|
Support.prototype.testRangeBounds = function(document) {
|
||||||
@ -31,3 +32,18 @@ Support.prototype.testRangeBounds = function(document) {
|
|||||||
Support.prototype.testCORS = function() {
|
Support.prototype.testCORS = function() {
|
||||||
return typeof((new Image()).crossOrigin) !== "undefined";
|
return typeof((new Image()).crossOrigin) !== "undefined";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Support.prototype.testSVG = function() {
|
||||||
|
var img = new Image();
|
||||||
|
var canvas = document.createElement("canvas");
|
||||||
|
var ctx = canvas.getContext("2d");
|
||||||
|
img.src = "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg'></svg>";
|
||||||
|
|
||||||
|
try {
|
||||||
|
ctx.drawImage(img, 0, 0);
|
||||||
|
canvas.toDataURL();
|
||||||
|
} catch(e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
@ -3,7 +3,11 @@ function SVGContainer(src) {
|
|||||||
this.image = null;
|
this.image = null;
|
||||||
var self = this;
|
var self = this;
|
||||||
this.promise = XHR(src).then(function(svg) {
|
this.promise = XHR(src).then(function(svg) {
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
if (!html2canvas.fabric) {
|
||||||
|
return reject(new Error("html2canvas.svg.js is not loaded, cannot render svg"));
|
||||||
|
}
|
||||||
|
|
||||||
html2canvas.fabric.loadSVGFromString(svg, function (objects, options) {
|
html2canvas.fabric.loadSVGFromString(svg, function (objects, options) {
|
||||||
var canvas = new html2canvas.fabric.StaticCanvas('c');
|
var canvas = new html2canvas.fabric.StaticCanvas('c');
|
||||||
self.image = canvas.lowerCanvasEl;
|
self.image = canvas.lowerCanvasEl;
|
||||||
|
@ -5,14 +5,14 @@ function XHR(url) {
|
|||||||
|
|
||||||
xhr.onload = function() {
|
xhr.onload = function() {
|
||||||
if (xhr.status === 200) {
|
if (xhr.status === 200) {
|
||||||
resolve(xhr.response);
|
resolve(xhr.responseText);
|
||||||
} else {
|
} else {
|
||||||
reject(Error(xhr.statusText));
|
reject(new Error(xhr.statusText));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.onerror = function() {
|
xhr.onerror = function() {
|
||||||
reject(Error("Network Error"));
|
reject(new Error("Network Error"));
|
||||||
};
|
};
|
||||||
|
|
||||||
xhr.send();
|
xhr.send();
|
||||||
|
@ -3,10 +3,10 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>Image tests</title>
|
<title>Image tests</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
<script type="text/javascript" src="../../test.js"></script>
|
<script type="text/javascript" src="../../../test.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
SVG taints image:<br /> <!-- http://fi.wikipedia.org/wiki/Tiedosto:Svg.svg -->
|
SVG taints image:<br /> <!-- http://fi.wikipedia.org/wiki/Tiedosto:Svg.svg -->
|
||||||
<img src="../../assets/image.svg" />
|
<img src="../../../assets/image.svg" />
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
x
Reference in New Issue
Block a user